summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>2004-06-23 17:22:50 +0100
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>2004-06-23 17:22:50 +0100
commit35820ceb46695ccaabaa666d65671489d732129b (patch)
tree0f572684d9efae577f6b882efb7e6ea971969197
parente98c260c2e1e231b0453782c71f59be1d82db8af (diff)
parentf4897eb32ff3d6629e53f67e30d88bb8736b7148 (diff)
Merge shinybook.infradead.org:/home/dwmw2/bk/linus-2.5
into shinybook.infradead.org:/home/dwmw2/bk/85xx-2.6
-rw-r--r--Documentation/devices.txt28
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/Kconfig8
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/Makefile2
-rw-r--r--arch/arm/boot/compressed/head-xscale.S3
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/sa1111.c2
-rw-r--r--arch/arm/common/time-acorn.c (renamed from arch/arm/kernel/time-acorn.c)5
-rw-r--r--arch/arm/configs/adi_evb_defconfig678
-rw-r--r--arch/arm/kernel/Makefile3
-rw-r--r--arch/arm/kernel/debug.S26
-rw-r--r--arch/arm/kernel/entry-armv.S2
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/kernel/time.c35
-rw-r--r--arch/arm/mach-adifcc/Makefile11
-rw-r--r--arch/arm/mach-adifcc/arch.c32
-rw-r--r--arch/arm/mach-adifcc/irq.c61
-rw-r--r--arch/arm/mach-adifcc/mm.c23
-rw-r--r--arch/arm/mach-clps711x/autcpu12.c2
-rw-r--r--arch/arm/mach-clps711x/cdb89712.c2
-rw-r--r--arch/arm/mach-clps711x/ceiva.c2
-rw-r--r--arch/arm/mach-clps711x/clep7312.c2
-rw-r--r--arch/arm/mach-clps711x/edb7211-arch.c2
-rw-r--r--arch/arm/mach-clps711x/fortunet.c2
-rw-r--r--arch/arm/mach-clps711x/p720t.c2
-rw-r--r--arch/arm/mach-clps711x/time.c30
-rw-r--r--arch/arm/mach-clps7500/core.c40
-rw-r--r--arch/arm/mach-ebsa110/core.c100
-rw-r--r--arch/arm/mach-ebsa110/time.c (renamed from include/asm-arm/arch-ebsa110/time.h)0
-rw-r--r--arch/arm/mach-epxa10db/arch.c3
-rw-r--r--arch/arm/mach-epxa10db/time.c44
-rw-r--r--arch/arm/mach-footbridge/Makefile2
-rw-r--r--arch/arm/mach-footbridge/arch.c6
-rw-r--r--arch/arm/mach-footbridge/time.c (renamed from include/asm-arm/arch-ebsa285/time.h)47
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c6
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c10
-rw-r--r--arch/arm/mach-integrator/time.c144
-rw-r--r--arch/arm/mach-iop3xx/arch.c2
-rw-r--r--arch/arm/mach-iop3xx/iop321-time.c15
-rw-r--r--arch/arm/mach-ixp4xx/common.c17
-rw-r--r--arch/arm/mach-ixp4xx/coyote-setup.c1
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c3
-rw-r--r--arch/arm/mach-ixp4xx/prpmc1100-setup.c1
-rw-r--r--arch/arm/mach-lh7a40x/Makefile2
-rw-r--r--arch/arm/mach-lh7a40x/arch-kev7a400.c2
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c2
-rw-r--r--arch/arm/mach-lh7a40x/time.c (renamed from include/asm-arm/arch-lh7a40x/time.h)32
-rw-r--r--arch/arm/mach-omap/Makefile2
-rw-r--r--arch/arm/mach-omap/board-generic.c7
-rw-r--r--arch/arm/mach-omap/board-innovator.c1
-rw-r--r--arch/arm/mach-omap/board-osk.c1
-rw-r--r--arch/arm/mach-omap/board-perseus2.c1
-rw-r--r--arch/arm/mach-omap/common.h1
-rw-r--r--arch/arm/mach-omap/time.c (renamed from include/asm-arm/arch-omap/time.h)32
-rw-r--r--arch/arm/mach-pxa/Makefile2
-rw-r--r--arch/arm/mach-pxa/generic.c16
-rw-r--r--arch/arm/mach-pxa/generic.h1
-rw-r--r--arch/arm/mach-pxa/idp.c1
-rw-r--r--arch/arm/mach-pxa/lubbock.c1
-rw-r--r--arch/arm/mach-pxa/mainstone.c1
-rw-r--r--arch/arm/mach-pxa/time.c (renamed from include/asm-arm/arch-pxa/time.h)37
-rw-r--r--arch/arm/mach-rpc/riscpc.c29
-rw-r--r--arch/arm/mach-s3c2410/Makefile2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c6
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.h2
-rw-r--r--arch/arm/mach-s3c2410/time.c (renamed from include/asm-arm/arch-s3c2410/time.h)35
-rw-r--r--arch/arm/mach-sa1100/adsbitsy.c1
-rw-r--r--arch/arm/mach-sa1100/assabet.c1
-rw-r--r--arch/arm/mach-sa1100/badge4.c1
-rw-r--r--arch/arm/mach-sa1100/brutus.c1
-rw-r--r--arch/arm/mach-sa1100/cerf.c1
-rw-r--r--arch/arm/mach-sa1100/empeg.c1
-rw-r--r--arch/arm/mach-sa1100/flexanet.c1
-rw-r--r--arch/arm/mach-sa1100/freebird.c1
-rw-r--r--arch/arm/mach-sa1100/generic.h1
-rw-r--r--arch/arm/mach-sa1100/graphicsclient.c1
-rw-r--r--arch/arm/mach-sa1100/graphicsmaster.c1
-rw-r--r--arch/arm/mach-sa1100/h3600.c3
-rw-r--r--arch/arm/mach-sa1100/hackkit.c1
-rw-r--r--arch/arm/mach-sa1100/huw_webpanel.c1
-rw-r--r--arch/arm/mach-sa1100/itsy.c1
-rw-r--r--arch/arm/mach-sa1100/jornada720.c1
-rw-r--r--arch/arm/mach-sa1100/lart.c1
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c1
-rw-r--r--arch/arm/mach-sa1100/omnimeter.c1
-rw-r--r--arch/arm/mach-sa1100/pangolin.c1
-rw-r--r--arch/arm/mach-sa1100/pfs168.c1
-rw-r--r--arch/arm/mach-sa1100/pleb.c1
-rw-r--r--arch/arm/mach-sa1100/shannon.c1
-rw-r--r--arch/arm/mach-sa1100/sherman.c1
-rw-r--r--arch/arm/mach-sa1100/simpad.c1
-rw-r--r--arch/arm/mach-sa1100/stork.c1
-rw-r--r--arch/arm/mach-sa1100/system3.c1
-rw-r--r--arch/arm/mach-sa1100/time.c (renamed from include/asm-arm/arch-sa1100/time.h)17
-rw-r--r--arch/arm/mach-sa1100/trizeps.c1
-rw-r--r--arch/arm/mach-sa1100/xp860.c1
-rw-r--r--arch/arm/mach-sa1100/yopy.c1
-rw-r--r--arch/arm/mach-shark/core.c38
-rw-r--r--arch/arm/mach-versatile/core.c145
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/i386/kernel/cpuid.c73
-rw-r--r--arch/i386/kernel/mpparse.c26
-rw-r--r--arch/i386/kernel/msr.c71
-rw-r--r--arch/ppc/Kconfig1
-rw-r--r--arch/ppc/Makefile2
-rw-r--r--arch/ppc/kernel/misc.S18
-rw-r--r--arch/ppc/kernel/time.c22
-rw-r--r--arch/ppc/kernel/traps.c53
-rw-r--r--arch/ppc/kernel/vecemu.c3
-rw-r--r--arch/ppc/oprofile/Kconfig23
-rw-r--r--arch/ppc/oprofile/Makefile9
-rw-r--r--arch/ppc/oprofile/init.c23
-rw-r--r--arch/ppc/platforms/pmac_cpufreq.c311
-rw-r--r--arch/ppc/platforms/pmac_feature.c32
-rw-r--r--arch/ppc64/kernel/Makefile2
-rw-r--r--arch/ppc64/kernel/traps.c34
-rw-r--r--arch/ppc64/kernel/vecemu.c346
-rw-r--r--arch/ppc64/kernel/vector.S172
-rw-r--r--arch/x86_64/kernel/mpparse.c20
-rw-r--r--drivers/base/base.h5
-rw-r--r--drivers/base/bus.c194
-rw-r--r--drivers/base/class.c117
-rw-r--r--drivers/base/class_simple.c12
-rw-r--r--drivers/base/core.c48
-rw-r--r--drivers/base/driver.c16
-rw-r--r--drivers/base/firmware.c6
-rw-r--r--drivers/base/firmware_class.c10
-rw-r--r--drivers/base/init.c4
-rw-r--r--drivers/base/interface.c18
-rw-r--r--drivers/base/node.c14
-rw-r--r--drivers/base/platform.c126
-rw-r--r--drivers/base/power/main.c14
-rw-r--r--drivers/base/power/power.h8
-rw-r--r--drivers/base/power/resume.c12
-rw-r--r--drivers/base/power/runtime.c8
-rw-r--r--drivers/base/power/shutdown.c18
-rw-r--r--drivers/base/power/suspend.c42
-rw-r--r--drivers/base/power/sysfs.c18
-rw-r--r--drivers/base/sys.c102
-rw-r--r--drivers/block/Kconfig8
-rw-r--r--drivers/block/Makefile2
-rw-r--r--drivers/block/ll_rw_blk.c2
-rw-r--r--drivers/block/sx8.c (renamed from drivers/block/carmel.c)6
-rw-r--r--drivers/char/raw.c25
-rw-r--r--drivers/char/watchdog/Kconfig11
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c8
-rw-r--r--drivers/firmware/efivars.c2
-rw-r--r--drivers/i2c/busses/i2c-piix4.c2
-rw-r--r--drivers/i2c/chips/asb100.c66
-rw-r--r--drivers/i2c/chips/it87.c72
-rw-r--r--drivers/i2c/chips/lm78.c22
-rw-r--r--drivers/i2c/chips/lm85.c26
-rw-r--r--drivers/i2c/chips/via686a.c18
-rw-r--r--drivers/i2c/chips/w83627hf.c200
-rw-r--r--drivers/i2c/chips/w83781d.c41
-rw-r--r--drivers/i2c/chips/w83l785ts.c4
-rw-r--r--drivers/i2c/i2c-dev.c7
-rw-r--r--drivers/ide/Kconfig20
-rw-r--r--drivers/ide/legacy/hd.c2
-rw-r--r--drivers/ide/pci/amd74xx.c20
-rw-r--r--drivers/ide/pci/generic.c2
-rw-r--r--drivers/ide/pci/piix.c4
-rw-r--r--drivers/ide/pci/siimage.c3
-rw-r--r--drivers/ieee1394/amdtp.c4
-rw-r--r--drivers/ieee1394/dv1394.c11
-rw-r--r--drivers/ieee1394/raw1394-private.h4
-rw-r--r--drivers/ieee1394/raw1394.c89
-rw-r--r--drivers/ieee1394/raw1394.h10
-rw-r--r--drivers/ieee1394/video1394.c19
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c183
-rw-r--r--drivers/isdn/i4l/isdn_ppp.h4
-rw-r--r--drivers/net/loopback.c34
-rw-r--r--drivers/net/ppp_generic.c168
-rw-r--r--drivers/net/sungem.c12
-rw-r--r--drivers/net/sungem.h3
-rw-r--r--drivers/net/tokenring/ibmtr.c1
-rw-r--r--drivers/net/wan/c101.c3
-rw-r--r--drivers/net/wan/cosa.c41
-rw-r--r--drivers/net/wan/cosa.h2
-rw-r--r--drivers/net/wan/dscc4.c2
-rw-r--r--drivers/net/wan/hdlc_cisco.c2
-rw-r--r--drivers/net/wan/hdlc_fr.c2
-rw-r--r--drivers/net/wan/hdlc_raw.c2
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c2
-rw-r--r--drivers/net/wan/lmc/lmc_ioctl.h4
-rw-r--r--drivers/net/wan/n2.c3
-rw-r--r--drivers/net/wan/pci200syn.c3
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--drivers/pci/pci-driver.c1
-rw-r--r--drivers/pci/pci-sysfs.c33
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--drivers/scsi/Kconfig8
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/ata_piix.c29
-rw-r--r--drivers/scsi/libata-core.c410
-rw-r--r--drivers/scsi/libata-scsi.c3
-rw-r--r--drivers/scsi/sata_nv.c353
-rw-r--r--drivers/scsi/sata_promise.c8
-rw-r--r--drivers/scsi/sata_sil.c3
-rw-r--r--drivers/scsi/sata_sis.c2
-rw-r--r--drivers/scsi/sata_svw.c2
-rw-r--r--drivers/scsi/sata_sx4.c9
-rw-r--r--drivers/scsi/sata_via.c2
-rw-r--r--drivers/scsi/sata_vsc.c2
-rw-r--r--drivers/scsi/scsi_debug.c20
-rw-r--r--drivers/scsi/scsi_sysfs.c14
-rw-r--r--drivers/scsi/scsi_transport_spi.c2
-rw-r--r--drivers/serial/Kconfig23
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/pxa.c73
-rw-r--r--drivers/serial/serial_lh7a40x.c708
-rw-r--r--drivers/usb/core/devio.c19
-rw-r--r--drivers/video/aty/radeon_base.c18
-rw-r--r--drivers/video/sa1100fb.c16
-rw-r--r--fs/devfs/base.c3
-rw-r--r--fs/ncpfs/ioctl.c82
-rw-r--r--fs/proc/base.c9
-rw-r--r--fs/quota.c4
-rw-r--r--fs/sysfs/inode.c7
-rw-r--r--include/asm-arm/arch-adifcc/adi_evb.h19
-rw-r--r--include/asm-arm/arch-adifcc/dma.h18
-rw-r--r--include/asm-arm/arch-adifcc/hardware.h27
-rw-r--r--include/asm-arm/arch-adifcc/io.h22
-rw-r--r--include/asm-arm/arch-adifcc/irqs.h20
-rw-r--r--include/asm-arm/arch-adifcc/memory.h27
-rw-r--r--include/asm-arm/arch-adifcc/param.h3
-rw-r--r--include/asm-arm/arch-adifcc/serial.h34
-rw-r--r--include/asm-arm/arch-adifcc/system.h28
-rw-r--r--include/asm-arm/arch-adifcc/time.h9
-rw-r--r--include/asm-arm/arch-adifcc/timex.h10
-rw-r--r--include/asm-arm/arch-adifcc/uncompress.h35
-rw-r--r--include/asm-arm/arch-adifcc/vmalloc.h15
-rw-r--r--include/asm-arm/arch-cl7500/time.h43
-rw-r--r--include/asm-arm/arch-epxa10db/time.h60
-rw-r--r--include/asm-arm/arch-integrator/platform.h4
-rw-r--r--include/asm-arm/arch-iop3xx/time.h12
-rw-r--r--include/asm-arm/arch-ixp4xx/platform.h1
-rw-r--r--include/asm-arm/arch-ixp4xx/time.h7
-rw-r--r--include/asm-arm/arch-rpc/time.h37
-rw-r--r--include/asm-arm/arch-shark/time.h39
-rw-r--r--include/asm-arm/arch-versatile/time.h158
-rw-r--r--include/asm-arm/checksum.h2
-rw-r--r--include/asm-arm/cpu-multi32.h17
-rw-r--r--include/asm-arm/cpu-single.h21
-rw-r--r--include/asm-arm/mach/arch.h4
-rw-r--r--include/asm-arm/mach/time.h20
-rw-r--r--include/asm-arm/proc-fns.h16
-rw-r--r--include/asm-ppc/pmac_feature.h6
-rw-r--r--include/asm-ppc/processor.h2
-rw-r--r--include/asm-ppc/reg.h1
-rw-r--r--include/asm-ppc/uninorth.h6
-rw-r--r--include/asm-ppc64/system.h1
-rw-r--r--include/asm-sparc64/bug.h2
-rw-r--r--include/linux/device.h41
-rw-r--r--include/linux/i2c-id.h12
-rw-r--r--include/linux/if.h14
-rw-r--r--include/linux/isdn_ppp.h5
-rw-r--r--include/linux/libata.h65
-rw-r--r--include/linux/module.h19
-rw-r--r--include/linux/ncp_fs.h6
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h2
-rw-r--r--include/linux/netfilter_ipv4/ipt_addrtype.h11
-rw-r--r--include/linux/netfilter_ipv4/ipt_realm.h10
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/skbuff.h15
-rw-r--r--include/linux/syscalls.h2
-rw-r--r--include/linux/sysfs.h21
-rw-r--r--include/linux/tcp.h5
-rw-r--r--include/net/esp.h5
-rw-r--r--include/net/sock.h44
-rw-r--r--include/net/tcp.h49
-rw-r--r--kernel/module.c100
-rw-r--r--lib/zlib_deflate/deflate.c2
-rw-r--r--mm/swapfile.c2
-rw-r--r--net/core/dev.c7
-rw-r--r--net/core/sock.c3
-rw-r--r--net/core/stream.c149
-rw-r--r--net/ipv4/esp4.c16
-rw-r--r--net/ipv4/ip_gre.c16
-rw-r--r--net/ipv4/ip_input.c6
-rw-r--r--net/ipv4/ipip.c16
-rw-r--r--net/ipv4/ipmr.c15
-rw-r--r--net/ipv4/netfilter/Kconfig24
-rw-r--r--net/ipv4/netfilter/Makefile2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c27
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c2
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c7
-rw-r--r--net/ipv4/netfilter/ip_tables.c11
-rw-r--r--net/ipv4/netfilter/ipt_CLASSIFY.c12
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c6
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c77
-rw-r--r--net/ipv4/netfilter/ipt_helper.c18
-rw-r--r--net/ipv4/netfilter/ipt_owner.c10
-rw-r--r--net/ipv4/netfilter/ipt_realm.c76
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c2
-rw-r--r--net/ipv4/netfilter/iptable_raw.c95
-rw-r--r--net/ipv4/tcp.c177
-rw-r--r--net/ipv4/tcp_input.c45
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c40
-rw-r--r--net/ipv4/tcp_timer.c4
-rw-r--r--net/ipv6/esp6.c16
-rw-r--r--net/ipv6/ip6_tunnel.c8
-rw-r--r--net/ipv6/netfilter/ip6_tables.c11
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c9
-rw-r--r--net/ipv6/sit.c16
-rw-r--r--net/sched/Kconfig4
-rw-r--r--net/sctp/socket.c2
-rw-r--r--sound/ppc/pmac.c7
314 files changed, 5559 insertions, 3505 deletions
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index d5ee998d6317..0257f2566e43 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -2377,16 +2377,16 @@ Your cooperation is appreciated.
1 = /dev/gpib1 Second GPIB bus
...
-160 block Carmel 8-port SATA Disks on First Controller
- 0 = /dev/carmel/0 SATA disk 0 whole disk
- 1 = /dev/carmel/0p1 SATA disk 0 partition 1
+160 block Promise SX8 8-port SATA Disks on First Controller
+ 0 = /dev/sx8/0 SATA disk 0 whole disk
+ 1 = /dev/sx8/0p1 SATA disk 0 partition 1
...
- 31 = /dev/carmel/0p31 SATA disk 0 partition 31
+ 31 = /dev/sx8/0p31 SATA disk 0 partition 31
- 32 = /dev/carmel/1 SATA disk 1 whole disk
- 64 = /dev/carmel/2 SATA disk 2 whole disk
+ 32 = /dev/sx8/1 SATA disk 1 whole disk
+ 64 = /dev/sx8/2 SATA disk 2 whole disk
...
- 224 = /dev/carmel/7 SATA disk 7 whole disk
+ 224 = /dev/sx8/7 SATA disk 7 whole disk
Partitions are handled in the same way as for IDE
disks (see major number 3) except that the limit on
@@ -2400,16 +2400,16 @@ Your cooperation is appreciated.
17 = /dev/irlpt1 Second IrLPT device
...
-161 block Carmel 8-port SATA Disks on Second Controller
- 0 = /dev/carmel/8 SATA disk 8 whole disk
- 1 = /dev/carmel/8p1 SATA disk 8 partition 1
+161 block Promise SX8 8-port SATA Disks on Second Controller
+ 0 = /dev/sx8/8 SATA disk 8 whole disk
+ 1 = /dev/sx8/8p1 SATA disk 8 partition 1
...
- 31 = /dev/carmel/8p31 SATA disk 8 partition 31
+ 31 = /dev/sx8/8p31 SATA disk 8 partition 31
- 32 = /dev/carmel/9 SATA disk 9 whole disk
- 64 = /dev/carmel/10 SATA disk 10 whole disk
+ 32 = /dev/sx8/9 SATA disk 9 whole disk
+ 64 = /dev/sx8/10 SATA disk 10 whole disk
...
- 224 = /dev/carmel/15 SATA disk 15 whole disk
+ 224 = /dev/sx8/15 SATA disk 15 whole disk
Partitions are handled in the same way as for IDE
disks (see major number 3) except that the limit on
diff --git a/MAINTAINERS b/MAINTAINERS
index 1b254cd76b4b..9d6c1955bd14 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -703,6 +703,12 @@ M: jrv@vanzandt.mv.com
L: blinux-list@redhat.com
S: Maintained
+DRIVER CORE, KOBJECTS, AND SYSFS
+P: Greg Kroah-Hartman
+M: greg@kroah.com
+L: linux-kernel@vger.kernel.org
+S: Supported
+
DRM DRIVERS
L: dri-devel@lists.sourceforge.net
S: Supported
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a9a5535fffa9..ae7e19db4e3d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -72,9 +72,6 @@ choice
prompt "ARM system type"
default ARCH_RPC
-config ARCH_ADIFCC
- bool "ADIFCC-based"
-
config ARCH_CLPS7500
bool "Cirrus-CL-PS7500FE"
@@ -191,6 +188,11 @@ config ARCH_ACORN
depends on ARCH_RPC
default y
+config TIMER_ACORN
+ bool
+ depends on ARCH_ACORN || ARCH_CLPS7500
+ default y
+
#####################################################################
# Footbridge support
config FOOTBRIDGE
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 954004064480..d8a4d37287cb 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -88,7 +88,6 @@ textaddr-$(CONFIG_ARCH_CLPS711X) := 0xc0028000
machine-$(CONFIG_ARCH_CLPS711X) := clps711x
textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
machine-$(CONFIG_ARCH_IOP3XX) := iop3xx
- machine-$(CONFIG_ARCH_ADIFCC) := adifcc
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
machine-$(CONFIG_ARCH_OMAP) := omap
machine-$(CONFIG_ARCH_S3C2410) := s3c2410
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 72be85c543ed..8c42a9132ce3 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -49,8 +49,6 @@ initrd_phys-$(CONFIG_ARCH_SA1100) := 0xc0800000
zreladdr-$(CONFIG_ARCH_PXA) := 0xa0008000
zreladdr-$(CONFIG_ARCH_IOP3XX) := 0xa0008000
params_phys-$(CONFIG_ARCH_IOP3XX) := 0xa0000100
- zreladdr-$(CONFIG_ARCH_ADIFCC) := 0xc0008000
-params_phys-$(CONFIG_ARCH_ADIFCC) := 0xc0000100
zreladdr-$(CONFIG_ARCH_IXP4XX) := 0x00008000
params-phys-$(CONFIG_ARCH_IXP4XX) := 0x00000100
zreladdr-$(CONFIG_ARCH_OMAP) := 0x10008000
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index e6656d4ef5c8..f9194499e863 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -66,7 +66,4 @@ __XScale_start:
mov r7, #MACH_TYPE_IQ80310
#endif
-#ifdef CONFIG_ARCH_ADI_EVB
- mov r7, #MACH_TYPE_ADI_EVB
-#endif
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 72a12c24689f..a0648d979d08 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_ICST525) += icst525.o
obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
obj-$(CONFIG_DMABOUNCE) += dmabounce.o
+obj-$(CONFIG_TIMER_ACORN) += time-acorn.o
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ee4b692e1d68..83eee1aa27e7 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -610,7 +610,7 @@ out:
* %-EBUSY physical address already marked in-use.
* %0 successful.
*/
-static int __init
+static int
__sa1111_probe(struct device *me, struct resource *mem, int irq)
{
struct sa1111 *sachip;
diff --git a/arch/arm/kernel/time-acorn.c b/arch/arm/common/time-acorn.c
index a4dd9f0557ff..eb06282962eb 100644
--- a/arch/arm/kernel/time-acorn.c
+++ b/arch/arm/common/time-acorn.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/kernel/time-acorn.c
+ * linux/arch/arm/common/time-acorn.c
*
* Copyright (c) 1996-2000 Russell King.
*
@@ -11,6 +11,7 @@
* 24-Sep-1996 RMK Created
* 10-Oct-1996 RMK Brought up to date with arch-sa110eval
* 04-Dec-1997 RMK Updated for new arch/arm/time.c
+ * 13=Jun-2004 DS Moved to arch/arm/common b/c shared w/CLPS7500
*/
#include <linux/timex.h>
#include <linux/init.h>
@@ -19,7 +20,7 @@
#include <asm/io.h>
#include <asm/hardware/ioc.h>
-extern unsigned long (*gettimeoffset)(void);
+#include <asm/mach/time.h>
static unsigned long ioctime_gettimeoffset(void)
{
diff --git a/arch/arm/configs/adi_evb_defconfig b/arch/arm/configs/adi_evb_defconfig
deleted file mode 100644
index bae486663bb4..000000000000
--- a/arch/arm/configs/adi_evb_defconfig
+++ /dev/null
@@ -1,678 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-
-#
-# System Type
-#
-CONFIG_ARCH_ADIFCC=y
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP310 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-CONFIG_ARCH_ADI_EVB=y
-CONFIG_XSCALE_PMU_TIMER=y
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v4=y
-CONFIG_CPU_XSCALE=y
-CONFIG_ARM_THUMB=y
-# CONFIG_XSCALE_TOOLS is not set
-CONFIG_XSCALE_WRITE_ALLOC=y
-CONFIG_XSCALE_PMU=y
-CONFIG_ARM_THUMB=y
-# CONFIG_DISCONTIGMEM is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/mtdblock1 mem=32M initrd=0xc0800000,3M"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_BOOTLDR_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-CONFIG_MTD_ADI_EVB=y
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-CONFIG_NETLINK=y
-CONFIG_RTNETLINK=y
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_CMS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_FREEVXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_V3 is not set
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MSDOS_PARTITION is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_ID75 is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BT is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_SLAB=y
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 991c219b347c..1a85e39d79be 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -11,8 +11,7 @@ obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \
time.o traps.o
obj-$(CONFIG_APM) += apm.o
-obj-$(CONFIG_ARCH_ACORN) += ecard.o time-acorn.o
-obj-$(CONFIG_ARCH_CLPS7500) += time-acorn.o
+obj-$(CONFIG_ARCH_ACORN) += ecard.o
obj-$(CONFIG_FOOTBRIDGE) += isa.o
obj-$(CONFIG_FIQ) += fiq.o
obj-$(CONFIG_MODULES) += armksyms.o module.o
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index 22b78368d0cc..822dbde5af8c 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -439,32 +439,6 @@
#endif
.endm
-#elif defined(CONFIG_ARCH_ADI_EVB)
-
- .macro addruart,rx
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- mov \rx, #0x00400000 @ physical base address
- orrne \rx, \rx, #0xff000000 @ virtual base
- .endm
-
- .macro senduart,rd,rx
- strb \rd, [\rx]
- .endm
-
- .macro busyuart,rd,rx
-1002: ldrb \rd, [\rx, #0x5]
- and \rd, \rd, #0x60
- teq \rd, #0x60
- bne 1002b
- .endm
-
- .macro waituart,rd,rx
-1001: ldrb \rd, [\rx, #0x6]
- tst \rd, #0x10
- beq 1001b
- .endm
-
#elif defined(CONFIG_ARCH_IXP4XX)
.macro addruart,rx
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index c8a5e0f87bf8..e483bc9b00c4 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -562,7 +562,7 @@ ENTRY(soft_irq_mask)
.macro irq_prio_table
.endm
-#elif defined(CONFIG_ARCH_IOP310) || defined(CONFIG_ARCH_ADIFCC)
+#elif defined(CONFIG_ARCH_IOP310)
.macro disable_fiq
.endm
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 1cff09a5537a..d159659677b0 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
+#include <linux/interrupt.h>
#include <asm/elf.h>
#include <asm/hardware.h>
@@ -34,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
#ifndef MEM_SIZE
#define MEM_SIZE (16*1024*1024)
@@ -727,6 +729,7 @@ void __init setup_arch(char **cmdline_p)
* Set up various architecture-specific pointers
*/
init_arch_irq = mdesc->init_irq;
+ init_arch_time = mdesc->init_time;
init_machine = mdesc->init_machine;
#ifdef CONFIG_VT
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index bfed0f453304..efcb44a9e6ab 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -27,12 +27,15 @@
#include <linux/errno.h>
#include <linux/profile.h>
#include <linux/sysdev.h>
+#include <linux/timer.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/leds.h>
+#include <asm/mach/time.h>
+
u64 jiffies_64 = INITIAL_JIFFIES;
EXPORT_SYMBOL(jiffies_64);
@@ -49,15 +52,11 @@ EXPORT_SYMBOL(rtc_lock);
/* change this if you have some constant time drift */
#define USECS_PER_JIFFY (1000000/HZ)
-static int dummy_set_rtc(void)
-{
- return 0;
-}
/*
* hook for setting the RTC's idea of the current time.
*/
-int (*set_rtc)(void) = dummy_set_rtc;
+int (*set_rtc)(void);
static unsigned long dummy_gettimeoffset(void)
{
@@ -238,7 +237,7 @@ EXPORT_SYMBOL(leds_event);
#endif
#ifdef CONFIG_LEDS_TIMER
-static void do_leds(void)
+static inline void do_leds(void)
{
static unsigned int count = 50;
@@ -248,7 +247,7 @@ static void do_leds(void)
}
}
#else
-#define do_leds()
+#define do_leds()
#endif
void do_gettimeofday(struct timeval *tv)
@@ -316,12 +315,18 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
-static struct irqaction timer_irq = {
- .name = "timer",
- .flags = SA_INTERRUPT,
-};
+void timer_tick(struct pt_regs *regs)
+{
+ do_profile(regs);
+ do_leds();
+ do_set_rtc();
+ do_timer(regs);
+}
+
+void (*init_arch_time)(void);
+
+void __init time_init(void)
+{
+ init_arch_time();
+}
-/*
- * Include architecture specific code
- */
-#include <asm/arch/time.h>
diff --git a/arch/arm/mach-adifcc/Makefile b/arch/arm/mach-adifcc/Makefile
deleted file mode 100644
index d8c1959e9483..000000000000
--- a/arch/arm/mach-adifcc/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y := arch.o irq.o mm.o
-obj-m :=
-obj-n :=
-obj- :=
-
diff --git a/arch/arm/mach-adifcc/arch.c b/arch/arm/mach-adifcc/arch.c
deleted file mode 100644
index bfc59556d9da..000000000000
--- a/arch/arm/mach-adifcc/arch.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * linux/arch/arm/mach-adifcc/arch.c
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-extern void adifcc_map_io(void);
-extern void adifcc_init_irq(void);
-
-#ifdef CONFIG_ARCH_ADI_EVB
-MACHINE_START(ADI_EVB, "ADI 80200FCC Evaluation Board")
- MAINTAINER("MontaVista Software Inc.")
- BOOT_MEM(0xc0000000, 0x00400000, 0xff400000)
- MAPIO(adifcc_map_io)
- INITIRQ(adifcc_init_irq)
-MACHINE_END
-#endif
-
diff --git a/arch/arm/mach-adifcc/irq.c b/arch/arm/mach-adifcc/irq.c
deleted file mode 100644
index 4163c602dc2f..000000000000
--- a/arch/arm/mach-adifcc/irq.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * linux/arch/arm/mach-xscale/irq.c
- *
- * Author: Deepak Saxena
- * Copyright: (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Based on IOP80310 code. Currently there's nothing more than the
- * 80200 on chip interrupts. That'll change once the hardware adds
- * support for PCI though.
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-
-static void xs80200_irq_mask (unsigned int irq)
-{
- long INTCTL;
- asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL));
- switch (irq) {
- case IRQ_XS80200_BCU: INTCTL &= ~(1<<3); break;
- case IRQ_XS80200_PMU: INTCTL &= ~(1<<2); break;
- case IRQ_XS80200_EXTIRQ: INTCTL &= ~(1<<1); break;
- case IRQ_XS80200_EXTFIQ: INTCTL &= ~(1<<0); break;
- }
- asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL));
-}
-
-static void xs80200_irq_unmask (unsigned int irq)
-{
- long INTCTL;
- asm ("mrc p13, 0, %0, c0, c0, 0" : "=r" (INTCTL));
- switch (irq) {
- case IRQ_XS80200_BCU: INTCTL |= (1<<3); break;
- case IRQ_XS80200_PMU: INTCTL |= (1<<2); break;
- case IRQ_XS80200_EXTIRQ: INTCTL |= (1<<1); break;
- case IRQ_XS80200_EXTFIQ: INTCTL |= (1<<0); break;
- }
- asm ("mcr p13, 0, %0, c0, c0, 0" : : "r" (INTCTL));
-}
-
-void __init adifcc_init_irq(void)
-{
- int i;
-
- for (i = 0; i < NR_XS80200_IRQS; i++) {
- irq_desc[i].valid = 1;
- irq_desc[i].probe_ok = 0;
- irq_desc[i].mask_ack = xs80200_irq_mask;
- irq_desc[i].mask = xs80200_irq_mask;
- irq_desc[i].unmask = xs80200_irq_unmask;
- }
-}
-
-
diff --git a/arch/arm/mach-adifcc/mm.c b/arch/arm/mach-adifcc/mm.c
deleted file mode 100644
index a81a9794ff10..000000000000
--- a/arch/arm/mach-adifcc/mm.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/arch/arm/mach-xscale/mm.c
- */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-
-#include <asm/mach/map.h>
-
-
-static struct map_desc adifcc_io_desc[] __initdata = {
- /* on-board devices */
- { 0xff400000, 0x00400000, 0x00300000, MT_DEVICE }
-};
-
-void __init adifcc_map_io(void)
-{
- iotable_init(adifcc_io_desc, ARRAY_SIZE(adifcc_io_desc));
-}
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index e05549a1bd25..f79b05fa5d29 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -37,6 +37,7 @@
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
+extern void clps711x_init_time(void);
/*
* The on-chip registers are given a size of 1MB so that a section can
@@ -65,5 +66,6 @@ MACHINE_START(AUTCPU12, "autronix autcpu12")
BOOT_PARAMS(0xc0020000)
MAPIO(autcpu12_map_io)
INITIRQ(clps711x_init_irq)
+ INITTIME(clp711x_init_time)
MACHINE_END
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
index d51668d267fa..3da47264430f 100644
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -34,6 +34,7 @@
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
+extern void clps711x-init_time(void);
/*
* Map the CS89712 Ethernet port. That should be moved to the
@@ -55,6 +56,7 @@ MACHINE_START(CDB89712, "Cirrus-CDB89712")
BOOT_PARAMS(0xc0000100)
MAPIO(cdb89712_map_io)
INITIRQ(clps711x_init_irq)
+ INITTIME(clps711x_init_time)
MACHINE_END
static int cdb89712_hw_init(void)
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
index e9ef76e18544..44d4e5b8d04b 100644
--- a/arch/arm/mach-clps711x/ceiva.c
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -35,6 +35,7 @@
#include <asm/mach/map.h>
extern void clps711x_init_irq(void);
+extern void clps711x_init_time(void);
static struct map_desc ceiva_io_desc[] __initdata = {
/* virtual, physical, length, type */
@@ -58,4 +59,5 @@ MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
BOOT_PARAMS(0xc0000100)
MAPIO(ceiva_map_io)
INITIRQ(clps711x_init_irq)
+ INITTIME(clps711x_init_time)
MACHINE_END
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
index f74f43583c9a..14fb9788cdd1 100644
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -25,6 +25,7 @@
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
+extern void clps711x_init_time(void);
static void __init
fixup_clep7312(struct machine_desc *desc, struct tag *tags,
@@ -44,5 +45,6 @@ MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
FIXUP(fixup_clep7312)
MAPIO(clps711x_map_io)
INITIRQ(clps711x_init_irq)
+ INITTIME(clps711x_init_time)
MACHINE_END
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index 1402447a8ad5..11aa05c24924 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -27,6 +27,7 @@
extern void clps711x_init_irq(void);
extern void edb7211_map_io(void);
+extern void clps711x_init_time(void);
static void __init
fixup_edb7211(struct machine_desc *desc, struct tag *tags,
@@ -56,4 +57,5 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
FIXUP(fixup_edb7211)
MAPIO(edb7211_map_io)
INITIRQ(clps711x_init_irq)
+ INITTIME(clps711x_init_time)
MACHINE_END
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
index 268e42baa66a..7a4ba27df7b8 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -33,6 +33,7 @@
extern void clps711x_map_io(void);
extern void clps711x_init_irq(void);
+extern void clps711x_init_time(void);
struct meminfo memmap = {
.nr_banks = 1,
@@ -82,4 +83,5 @@ MACHINE_START(FORTUNET, "ARM-FortuNet")
FIXUP(fortunet_fixup)
MAPIO(clps711x_map_io)
INITIRQ(clps711x_init_irq)
+ INITTIME(clps711x_init_time)
MACHINE_END
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index b99cccfb773b..eb75ae6678ef 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -36,6 +36,7 @@
extern void clps711x_init_irq(void);
extern void clps711x_map_io(void);
+extern void clps711x_init_time(void);
/*
* Map the P720T system PLD. It occupies two address spaces:
@@ -86,6 +87,7 @@ MACHINE_START(P720T, "ARM-Prospector720T")
FIXUP(fixup_p720t)
MAPIO(p720t_map_io)
INITIRQ(clps711x_init_irq)
+ INITTIME(clps711x_init_time)
MACHINE_END
static int p720t_hw_init(void)
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
index 8a02e18a899a..58da84effd5e 100644
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -18,12 +18,17 @@
*/
#include <linux/timex.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
#include <asm/io.h>
#include <asm/hardware/clps7111.h>
-extern unsigned long (*gettimeoffset)(void);
+#include <asm/mach/time.h>
+
/*
* gettimeoffset() returns time since last timer tick, in usecs.
@@ -38,19 +43,36 @@ static unsigned long clps711x_gettimeoffset(void)
return (hwticks * (tick_nsec / 1000)) / LATCH;
}
-void __init clps711x_setup_timer(void)
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+p720t_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ timer_tick(regs);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction clps711x_timer_irq = {
+ .name = "CLPS711x Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = p720t_timer_interrupt
+};
+
+void __init clps711x_init_time(void)
{
struct timespec tv;
unsigned int syscon;
- gettimeoffset = clps711x_gettimeoffset;
-
syscon = clps_readl(SYSCON1);
syscon |= SYSCON1_TC2S | SYSCON1_TC2M;
clps_writel(syscon, SYSCON1);
clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
+ setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
+ gettimeoffset = clps711x_gettimeoffset;
+
tv.tv_nsec = 0;
tv.tv_sec = clps_readl(RTCDR);
do_settimeofday(&tv);
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
index 628264bf50bc..ee1a3192ad7b 100644
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -10,12 +10,13 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
-#include <linux/timer.h>
+#include <linux/sched.h>
#include <linux/init.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
#include <asm/hardware.h>
#include <asm/hardware/iomd.h>
@@ -265,10 +266,47 @@ static void __init clps7500_map_io(void)
iotable_init(cl7500_io_desc, ARRAY_SIZE(cl7500_io_desc));
}
+extern void ioctime_init(void);
+
+static irqreturn_t
+clps7500_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ timer_tick(regs);
+
+ /* Why not using do_leds interface?? */
+ {
+ /* Twinkle the lights. */
+ static int count, state = 0xff00;
+ if (count-- == 0) {
+ state ^= 0x100;
+ count = 25;
+ *((volatile unsigned int *)LED_ADDRESS) = state;
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static struct irqaction clps7500_timer_irq = {
+ .name = "CLPS7500 Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = clps7500_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt.
+ */
+void __init clps7500_init_time(void)
+{
+ ioctime_init();
+
+ setup_irq(IRQ_TIMER, &clps7500_timer_irq);
+}
+
MACHINE_START(CLPS7500, "CL-PS7500")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
MAPIO(clps7500_map_io)
INITIRQ(clps7500_init_irq)
+ INITTIME(clps7500_init_time)
MACHINE_END
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 5c14e04eae1b..6f20b86a69c4 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -26,6 +26,8 @@
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
#define IRQ_MASK 0xfe000000 /* read */
#define IRQ_MSET 0xfe000000 /* write */
#define IRQ_STAT 0xff000000 /* read */
@@ -89,6 +91,103 @@ static void __init ebsa110_map_io(void)
iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc));
}
+
+#define PIT_CTRL (PIT_BASE + 0x0d)
+#define PIT_T2 (PIT_BASE + 0x09)
+#define PIT_T1 (PIT_BASE + 0x05)
+#define PIT_T0 (PIT_BASE + 0x01)
+
+/*
+ * This is the rate at which your MCLK signal toggles (in Hz)
+ * This was measured on a 10 digit frequency counter sampling
+ * over 1 second.
+ */
+#define MCLK 47894000
+
+/*
+ * This is the rate at which the PIT timers get clocked
+ */
+#define CLKBY7 (MCLK / 7)
+
+/*
+ * This is the counter value. We tick at 200Hz on this platform.
+ */
+#define COUNT ((CLKBY7 + (HZ / 2)) / HZ)
+
+/*
+ * Get the time offset from the system PIT. Note that if we have missed an
+ * interrupt, then the PIT counter will roll over (ie, be negative).
+ * This actually works out to be convenient.
+ */
+static unsigned long ebsa110_gettimeoffset(void)
+{
+ unsigned long offset, count;
+
+ __raw_writeb(0x40, PIT_CTRL);
+ count = __raw_readb(PIT_T1);
+ count |= __raw_readb(PIT_T1) << 8;
+
+ /*
+ * If count > COUNT, make the number negative.
+ */
+ if (count > COUNT)
+ count |= 0xffff0000;
+
+ offset = COUNT;
+ offset -= count;
+
+ /*
+ * `offset' is in units of timer counts. Convert
+ * offset to units of microseconds.
+ */
+ offset = offset * (1000000 / HZ) / COUNT;
+
+ return offset;
+}
+
+static irqreturn_t
+ebsa110_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ u32 count;
+
+ /* latch and read timer 1 */
+ __raw_writeb(0x40, PIT_CTRL);
+ count = __raw_readb(PIT_T1);
+ count |= __raw_readb(PIT_T1) << 8;
+
+ count += COUNT;
+
+ __raw_writeb(count & 0xff, PIT_T1);
+ __raw_writeb(count >> 8, PIT_T1);
+
+ timer_tick(regs);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ebsa110_timer_irq = {
+ .name = "EBSA110 Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = ebsa110_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt.
+ */
+void __init ebsa110_time_init(void)
+{
+ /*
+ * Timer 1, mode 2, LSB/MSB
+ */
+ __raw_writeb(0x70, PIT_CTRL);
+ __raw_writeb(COUNT & 0xff, PIT_T1);
+ __raw_writeb(COUNT >> 8, PIT_T1);
+
+ gettimeoffset = ebsa110_gettimeoffset;
+
+ setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq);
+}
+
MACHINE_START(EBSA110, "EBSA110")
MAINTAINER("Russell King")
BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
@@ -98,4 +197,5 @@ MACHINE_START(EBSA110, "EBSA110")
SOFT_REBOOT
MAPIO(ebsa110_map_io)
INITIRQ(ebsa110_init_irq)
+ INITTIME(ebsa110_init_time)
MACHINE_END
diff --git a/include/asm-arm/arch-ebsa110/time.h b/arch/arm/mach-ebsa110/time.c
index c482e372b012..c482e372b012 100644
--- a/include/asm-arm/arch-ebsa110/time.h
+++ b/arch/arm/mach-ebsa110/time.c
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
index 71c2257dfd50..ae9f7c864b45 100644
--- a/arch/arm/mach-epxa10db/arch.c
+++ b/arch/arm/mach-epxa10db/arch.c
@@ -29,10 +29,13 @@
extern void epxa10db_map_io(void);
extern void epxa10db_init_irq(void);
+extern void epxa10db_init_time(void);
MACHINE_START(CAMELOT, "Altera Epxa10db")
MAINTAINER("Altera Corporation")
BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
MAPIO(epxa10db_map_io)
INITIRQ(epxa10db_init_irq)
+ INITTIME(epxa10db_init_time)
MACHINE_END
+
diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c
index 0c8b9cf7c7b7..7d72a433dad7 100644
--- a/arch/arm/mach-epxa10db/time.c
+++ b/arch/arm/mach-epxa10db/time.c
@@ -10,11 +10,17 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <asm/hardware.h>
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/mach/time.h>
-extern int (*set_rtc)(void);
+#define TIMER00_TYPE (volatile unsigned int*)
+#include <asm/arch/timer00.h>
static int epxa10db_set_rtc(void)
{
@@ -29,3 +35,39 @@ static int epxa10db_rtc_init(void)
}
__initcall(epxa10db_rtc_init);
+
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+ // ...clear the interrupt
+ *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK;
+
+ timer_tick(regs);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction epxa10db_timer_irq = {
+ .name = "Excalibur Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = epxa10db_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init epxa10db_init_time(void)
+{
+ /* Start the timer */
+ *TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
+ *TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
+ *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
+
+ setup_irq(IRQ_TIMER0, &epxa10db_timer_irq);
+}
+
diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile
index d011b2df2dbe..e0a2890522cd 100644
--- a/arch/arm/mach-footbridge/Makefile
+++ b/arch/arm/mach-footbridge/Makefile
@@ -4,7 +4,7 @@
# Object file lists.
-obj-y := arch.o dc21285.o dma.o irq.o isa-irq.o mm.o
+obj-y := arch.o dc21285.o dma.o irq.o isa-irq.o mm.o time.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/mach-footbridge/arch.c b/arch/arm/mach-footbridge/arch.c
index 91e34a8440ef..76119883661e 100644
--- a/arch/arm/mach-footbridge/arch.c
+++ b/arch/arm/mach-footbridge/arch.c
@@ -22,6 +22,7 @@
extern void footbridge_map_io(void);
extern void footbridge_init_irq(void);
+extern void footbridge_init_time(void);
unsigned int mem_fclk_21285 = 50000000;
@@ -43,6 +44,7 @@ MACHINE_START(EBSA285, "EBSA285")
VIDEO(0x000a0000, 0x000bffff)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
+ INITTIME(footbridge_init_time)
MACHINE_END
#endif
@@ -78,6 +80,7 @@ MACHINE_START(NETWINDER, "Rebel-NetWinder")
FIXUP(fixup_netwinder)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
+ INITTIME(footbridge_init_time)
MACHINE_END
#endif
@@ -103,6 +106,7 @@ MACHINE_START(CATS, "Chalice-CATS")
FIXUP(fixup_cats)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
+ INITTIME(footbridge_init_time)
MACHINE_END
#endif
@@ -129,6 +133,7 @@ MACHINE_START(CO285, "co-EBSA285")
FIXUP(fixup_coebsa285)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
+ INITTIME(footbridge_init_time)
MACHINE_END
#endif
@@ -139,5 +144,6 @@ MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
BOOT_PARAMS(0x00000100)
MAPIO(footbridge_map_io)
INITIRQ(footbridge_init_irq)
+ INITTIME(footbridge_init_time)
MACHINE_END
#endif
diff --git a/include/asm-arm/arch-ebsa285/time.h b/arch/arm/mach-footbridge/time.c
index f651eeb655be..d4b9c9f87fff 100644
--- a/include/asm-arm/arch-ebsa285/time.h
+++ b/arch/arm/mach-footbridge/time.c
@@ -17,12 +17,23 @@
#define RTC_PORT(x) (rtc_base+(x))
#define RTC_ALWAYS_BCD 0
+#include <linux/timex.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <linux/mc146818rtc.h>
#include <linux/bcd.h>
#include <asm/hardware/dec21285.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
+#include <asm/io.h>
+#include <asm/hardware/clps7111.h>
+
+#include <asm/mach/time.h>
static int rtc_base;
@@ -72,12 +83,7 @@ static unsigned long isa_gettimeoffset(void)
static irqreturn_t
isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- if (machine_is_netwinder())
- do_leds();
-
- do_timer(regs);
- do_set_rtc();
- do_profile(regs);
+ timer_tick(regs);
return IRQ_HANDLED;
}
@@ -195,22 +201,20 @@ timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
*CSR_TIMER1_CLR = 0;
- /* Do the LEDs things */
- do_leds();
- do_timer(regs);
- do_set_rtc();
- do_profile(regs);
+ timer_tick(regs);
return IRQ_HANDLED;
}
+static struct irqaction footbridge_timer_irq = {
+ .flags = SA_INTERRUPT
+};
+
/*
* Set up timer interrupt.
*/
-void __init time_init(void)
+void __init footbridge_init_time(void)
{
- int irq;
-
if (machine_is_co285() ||
machine_is_personal_server())
/*
@@ -270,8 +274,11 @@ void __init time_init(void)
*CSR_TIMER1_LOAD = timer1_latch;
*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
- timer_irq.handler = timer1_interrupt;
- irq = IRQ_TIMER1;
+ footbridge_timer_irq.name = "Timer1 Timer Tick";
+ footbrdige_timer_irq.handler = timer1_interrupt;
+
+ setup_irq(IRQ_TIMER1, &footbridge_timer_irq);
+
} else {
/* enable PIT timer */
/* set for periodic (4) and LSB/MSB write (0x30) */
@@ -280,8 +287,10 @@ void __init time_init(void)
outb((mSEC_10_from_14/6) >> 8, 0x40);
gettimeoffset = isa_gettimeoffset;
- timer_irq.handler = isa_timer_interrupt;
- irq = IRQ_ISA_TIMER;
+
+ footbridge_timer_irq.name = "ISA Timer Tick";
+ footbrdige_timer_irq.handler = isa_timer_interrupt;
+
+ setup_irq(IRQ_ISA, &footbridge_timer_irq);
}
- setup_irq(irq, &timer_irq);
}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 1d59766652d3..4fee881855f1 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -281,11 +281,17 @@ static void __init ap_init(void)
}
}
+static void ap_time_init(void)
+{
+ integrator_time_init(1000000 * TICKS_PER_uSEC / HZ, 0);
+}
+
MACHINE_START(INTEGRATOR, "ARM-Integrator")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
BOOT_PARAMS(0x00000100)
MAPIO(ap_map_io)
INITIRQ(ap_init_irq)
+ INITTIME(ap_time_init)
INIT_MACHINE(ap_init)
MACHINE_END
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index f63e45cbe8fa..aa29c76aacc0 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -249,7 +249,7 @@ static struct clk cp_clcd_clk = {
static struct clk cp_mmci_clk = {
.name = "MCLK",
- .rate = 33000000,
+ .rate = 14745600,
};
/*
@@ -351,7 +351,7 @@ static unsigned int mmc_status(struct device *dev)
}
static struct mmc_platform_data mmc_data = {
- .mclk = 33000000,
+ .mclk = 14745600,
.ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
.status = mmc_status,
};
@@ -419,11 +419,17 @@ static void __init intcp_init(void)
}
}
+static void __init intcp_init_time(void)
+{
+ integrator_time_init(1000000 / HZ, TIMER_CTRL_IE);
+}
+
MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
BOOT_PARAMS(0x00000100)
MAPIO(intcp_map_io)
INITIRQ(intcp_init_irq)
+ INITTIME(intcp_init_time)
INIT_MACHINE(intcp_init)
MACHINE_END
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 39606096fbd6..e12bcf814d95 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -10,9 +10,16 @@
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <asm/hardware.h>
#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/time.h>
#define RTC_DR (IO_ADDRESS(INTEGRATOR_RTC_BASE) + 0)
#define RTC_MR (IO_ADDRESS(INTEGRATOR_RTC_BASE) + 4)
@@ -44,3 +51,140 @@ static int integrator_rtc_init(void)
}
__initcall(integrator_rtc_init);
+
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000000)
+#define TIMER1_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000100)
+#define TIMER2_VA_BASE (IO_ADDRESS(INTEGRATOR_CT_BASE)+0x00000200)
+#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE)
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
+#if TIMER_INTERVAL >= 0x100000
+#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
+#elif TIMER_INTERVAL >= 0x10000
+#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
+#else
+#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
+#endif
+
+#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
+
+/*
+ * What does it look like?
+ */
+typedef struct TimerStruct {
+ unsigned long TimerLoad;
+ unsigned long TimerValue;
+ unsigned long TimerControl;
+ unsigned long TimerClear;
+} TimerStruct_t;
+
+extern unsigned long (*gettimeoffset)(void);
+
+static unsigned long timer_reload;
+
+/*
+ * Returns number of ms since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long integrator_gettimeoffset(void)
+{
+ volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
+ unsigned long ticks1, ticks2, status;
+
+ /*
+ * Get the current number of ticks. Note that there is a race
+ * condition between us reading the timer and checking for
+ * an interrupt. We get around this by ensuring that the
+ * counter has not reloaded between our two reads.
+ */
+ ticks2 = timer1->TimerValue & 0xffff;
+ do {
+ ticks1 = ticks2;
+ status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
+ ticks2 = timer1->TimerValue & 0xffff;
+ } while (ticks2 > ticks1);
+
+ /*
+ * Number of ticks since last interrupt.
+ */
+ ticks1 = timer_reload - ticks2;
+
+ /*
+ * Interrupt pending? If so, we've reloaded once already.
+ */
+ if (status & (1 << IRQ_TIMERINT1))
+ ticks1 += timer_reload;
+
+ /*
+ * Convert the ticks to usecs
+ */
+ return TICKS2USECS(ticks1);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
+
+ // ...clear the interrupt
+ timer1->TimerClear = 1;
+
+ timer_tick(regs);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction integrator_timer_irq = {
+ .name = "Integrator Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = integrator_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
+{
+ volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
+ volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
+ volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
+ unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */
+
+ timer_reload = reload;
+ timer_ctrl |= ctrl;
+
+ if (timer_reload > 0x100000) {
+ timer_reload >>= 8;
+ timer_ctrl |= 0x08; /* /256 */
+ } else if (timer_reload > 0x010000) {
+ timer_reload >>= 4;
+ timer_ctrl |= 0x04; /* /16 */
+ }
+
+ /*
+ * Initialise to a known state (all timers off)
+ */
+ timer0->TimerControl = 0;
+ timer1->TimerControl = 0;
+ timer2->TimerControl = 0;
+
+ timer1->TimerLoad = timer_reload;
+ timer1->TimerValue = timer_reload;
+ timer1->TimerControl = timer_ctrl;
+
+ /*
+ * Make irqs happen for the system timer
+ */
+ setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
+ gettimeoffset = integrator_gettimeoffset;
+}
diff --git a/arch/arm/mach-iop3xx/arch.c b/arch/arm/mach-iop3xx/arch.c
index eb3bab2db9c4..3df5e454c772 100644
--- a/arch/arm/mach-iop3xx/arch.c
+++ b/arch/arm/mach-iop3xx/arch.c
@@ -29,6 +29,7 @@ extern void iq80310_init_irq(void);
#ifdef CONFIG_ARCH_IQ80321
extern void iq80321_map_io(void);
extern void iop321_init_irq(void);
+extern void iop321_init_time(void);
#endif
#ifdef CONFIG_ARCH_IQ80310
@@ -67,6 +68,7 @@ MACHINE_START(IQ80321, "Intel IQ80321")
FIXUP(fixup_iop321)
MAPIO(iq80321_map_io)
INITIRQ(iop321_init_irq)
+ INITTIME(iop321_init_time)
MACHINE_END
#else
diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c
index a10a9b9533d1..be36c70690b1 100644
--- a/arch/arm/mach-iop3xx/iop321-time.c
+++ b/arch/arm/mach-iop3xx/iop321-time.c
@@ -23,7 +23,9 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+
#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
static unsigned long iop321_gettimeoffset(void)
{
@@ -61,27 +63,26 @@ iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr));
- do_timer(regs);
+ timer_tick(regs);
return IRQ_HANDLED;
}
-extern unsigned long (*gettimeoffset)(void);
-
-static struct irqaction timer_irq = {
- .name = "timer",
+static struct irqaction iop321_timer_irq = {
+ .name = "IOP321 Timer Tick",
.handler = iop321_timer_interrupt,
+ .flags = SA_INTERRUPT
};
extern int setup_arm_irq(int, struct irqaction*);
-void __init time_init(void)
+void __init iop321_init_time(void)
{
u32 timer_ctl;
u32 latch = LATCH;
gettimeoffset = iop321_gettimeoffset;
- setup_irq(IRQ_IOP321_TIMER0, &timer_irq);
+ setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq);
timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD |
IOP321_TMR_RATIO_1_1;
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index f0166508d5bb..a4edbe0eb909 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -36,6 +36,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
/*************************************************************************
@@ -227,24 +228,22 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs
* Catch up with the real idea of time
*/
do {
- do_timer(regs);
+ timer_tick(regs);
last_jiffy_time += LATCH;
} while((*IXP4XX_OSTS - last_jiffy_time) > LATCH);
return IRQ_HANDLED;
}
-extern unsigned long (*gettimeoffset)(void);
-
-static struct irqaction timer_irq = {
- .name = "IXP4xx Timer Tick",
- .flags = SA_INTERRUPT
+static struct irqaction ixp4xx_timer_irq = {
+ .name = "IXP4xx Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = ixp4xx_timer_interrupt
};
-void __init time_init(void)
+void __init ixp4xx_init_time(void)
{
gettimeoffset = ixp4xx_gettimeoffset;
- timer_irq.handler = ixp4xx_timer_interrupt;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
@@ -257,7 +256,7 @@ void __init time_init(void)
last_jiffy_time = 0;
/* Connect the interrupt handler and enable the interrupt */
- setup_irq(IRQ_IXP4XX_TIMER1, &timer_irq);
+ setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
}
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index bc6e0d0427a2..3d616bc6aff4 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -84,6 +84,7 @@ MACHINE_START(ADI_COYOTE, "ADI Engineering IXP4XX Coyote Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(coyote_map_io)
INITIRQ(ixp4xx_init_irq)
+ INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(coyote_init)
MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 160117c67764..ec289c866ae7 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -113,6 +113,7 @@ MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
+ INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
@@ -123,6 +124,7 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
+ INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
@@ -140,6 +142,7 @@ MACHINE_START(AVILA, "Gateworks Avila Network Platform")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(ixdp425_map_io)
INITIRQ(ixp4xx_init_irq)
+ INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(ixdp425_init)
MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/prpmc1100-setup.c b/arch/arm/mach-ixp4xx/prpmc1100-setup.c
index b0603205d070..ee092b1771cc 100644
--- a/arch/arm/mach-ixp4xx/prpmc1100-setup.c
+++ b/arch/arm/mach-ixp4xx/prpmc1100-setup.c
@@ -84,6 +84,7 @@ MACHINE_START(PRPMC1100, "Motorola PrPMC1100")
IXP4XX_PERIPHERAL_BASE_VIRT)
MAPIO(prpmc1100_map_io)
INITIRQ(ixp4xx_init_irq)
+ INITTIME(ixp4xx_init_time)
BOOT_PARAMS(0x0100)
INIT_MACHINE(prpmc1100_init)
MACHINE_END
diff --git a/arch/arm/mach-lh7a40x/Makefile b/arch/arm/mach-lh7a40x/Makefile
index db3be5a23a8a..6b361f788a22 100644
--- a/arch/arm/mach-lh7a40x/Makefile
+++ b/arch/arm/mach-lh7a40x/Makefile
@@ -4,7 +4,7 @@
# Object file lists.
-obj-y := fiq.o
+obj-y := fiq.o time.o
# generic.o
obj-$(CONFIG_MACH_KEV7A400) += arch-kev7a400.o irq-lh7a400.o
obj-$(CONFIG_MACH_LPD7A400) += arch-lpd7a40x.o ide-lpd7a40x.o irq-lh7a400.o
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
index 73d8b6b56e4c..6fa2a981ee80 100644
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -25,6 +25,7 @@
/* This function calls the board specific IRQ initialization function. */
extern void lh7a400_init_irq (void);
+extern void lh7a40x_init_time (void);
static struct map_desc kev7a400_io_desc[] __initdata = {
{ IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE },
@@ -108,4 +109,5 @@ MACHINE_START (KEV7A400, "Sharp KEV7a400")
BOOT_PARAMS (0xc0000100)
MAPIO (kev7a400_map_io)
INITIRQ (lh7a400_init_irq)
+ INITTIME (lh7a40x_init_time)
MACHINE_END
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index 75dba98360c0..33eb4b8dd358 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -280,6 +280,7 @@ MACHINE_END
#ifdef CONFIG_MACH_LPD7A404
extern void lh7a404_init_irq (void);
+extern void lh7a40x_init_time (void);
MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
MAINTAINER ("Marc Singer")
@@ -287,6 +288,7 @@ MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
BOOT_PARAMS (0xc0000100)
MAPIO (lpd7a400_map_io)
INITIRQ (lh7a404_init_irq)
+ INITTIME (lh7a40x_init_time)
INIT_MACHINE (lpd7a40x_init)
MACHINE_END
diff --git a/include/asm-arm/arch-lh7a40x/time.h b/arch/arm/mach-lh7a40x/time.c
index 5f1cf4f9b2c7..61ada24c78a7 100644
--- a/include/asm-arm/arch-lh7a40x/time.h
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -1,4 +1,5 @@
-/* include/asm-arm/arch-lh7a40x/time.h
+/*
+ * arch/arm/mach-lh7a40x/time.c
*
* Copyright (C) 2004 Logic Product Development
*
@@ -7,6 +8,18 @@
* version 2 as published by the Free Software Foundation.
*
*/
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+
+#include <asm/mach/time.h>
#if HZ < 100
# define TIMER_CONTROL TIMER_CONTROL1
@@ -28,24 +41,25 @@ static irqreturn_t
lh7a40x_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
TIMER_EOI = 0;
- do_profile (regs);
- do_leds();
- do_set_rtc();
- do_timer (regs);
+ timer_tick(regs);
return IRQ_HANDLED;
}
-void __init time_init(void)
+static struct irqaction lh7a40x_timer_irq = {
+ .name = "LHA740x Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = lh7a40x_timer_interrupt
+};
+
+void __init lh7a40x_init_time(void)
{
/* Stop/disable all timers */
TIMER_CONTROL1 = 0;
TIMER_CONTROL2 = 0;
TIMER_CONTROL3 = 0;
- timer_irq.handler = lh7a40x_timer_interrupt;
- timer_irq.flags |= SA_INTERRUPT;
- setup_irq (TIMER_IRQ, &timer_irq);
+ setup_irq (TIMER_IRQ, &lh7a40x_timer_irq);
TIMER_LOAD = TIMER_CONSTANT;
TIMER_CONTROL = TIMER_MODE;
diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile
index 272535091bc4..5fcb1e5c7627 100644
--- a/arch/arm/mach-omap/Makefile
+++ b/arch/arm/mach-omap/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o
+obj-y := common.o irq.o dma.o clocks.o mux.o bus.o gpio.o time.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c
index e0b09f86ae92..447046b24a08 100644
--- a/arch/arm/mach-omap/board-generic.c
+++ b/arch/arm/mach-omap/board-generic.c
@@ -65,6 +65,11 @@ static void __init omap_generic_map_io(void)
omap_map_io();
}
+static void __init omap_generic_init_time(void)
+{
+ omap_init_time();
+}
+
MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710")
MAINTAINER("Tony Lindgren <tony@atomide.com>")
BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
@@ -72,4 +77,6 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP-1510/1610/1710")
MAPIO(omap_generic_map_io)
INITIRQ(omap_generic_init_irq)
INIT_MACHINE(omap_generic_init)
+ INITTIME(omap_generic_init_time)
MACHINE_END
+
diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c
index c65f38f58bb8..6ef4d8dcf903 100644
--- a/arch/arm/mach-omap/board-innovator.c
+++ b/arch/arm/mach-omap/board-innovator.c
@@ -156,5 +156,6 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
BOOT_PARAMS(0x10000100)
MAPIO(innovator_map_io)
INITIRQ(innovator_init_irq)
+ INITTIME(omap_init_time)
INIT_MACHINE(innovator_init)
MACHINE_END
diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c
index 8044dd190efd..16ecd6be5a60 100644
--- a/arch/arm/mach-omap/board-osk.c
+++ b/arch/arm/mach-omap/board-osk.c
@@ -94,5 +94,6 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
BOOT_PARAMS(0x10000100)
MAPIO(osk_map_io)
INITIRQ(osk_init_irq)
+ INITTIME(omap_init_time)
INIT_MACHINE(osk_init)
MACHINE_END
diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c
index e938ea4b647e..8015d10fc75e 100644
--- a/arch/arm/mach-omap/board-perseus2.c
+++ b/arch/arm/mach-omap/board-perseus2.c
@@ -111,5 +111,6 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
BOOT_PARAMS(0x10000100)
MAPIO(omap_perseus2_map_io)
INITIRQ(omap_perseus2_init_irq)
+ INITTIME(omap_init_time)
INIT_MACHINE(omap_perseus2_init)
MACHINE_END
diff --git a/arch/arm/mach-omap/common.h b/arch/arm/mach-omap/common.h
index 1cc559dd2f81..96dcb3c53973 100644
--- a/arch/arm/mach-omap/common.h
+++ b/arch/arm/mach-omap/common.h
@@ -28,6 +28,7 @@
#define __ARCH_ARM_MACH_OMAP_COMMON_H
extern void omap_map_io(void);
+extern void omap_init_time(void);
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/time.h b/arch/arm/mach-omap/time.c
index 85d481219824..d62e22614394 100644
--- a/include/asm-arm/arch-omap/time.h
+++ b/arch/arm/mach-omap/time.c
@@ -1,7 +1,7 @@
/*
- * linux/include/asm-arm/arch-omap/time.h
+ * arch/arm/mach-omap/time.c
*
- * 32kHz timer definition
+ * OMAP Timer Tick
*
* Copyright (C) 2000 RidgeRun, Inc.
* Author: Greg Lonnon <glonnon@ridgerun.com>
@@ -26,8 +26,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#if !defined(__ASM_ARCH_OMAP_TIME_H)
-#define __ASM_ARCH_OMAP_TIME_H
#include <linux/config.h>
#include <linux/delay.h>
@@ -37,6 +35,7 @@
#include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
#include <asm/arch/clocks.h>
#ifndef __instrument
@@ -162,14 +161,14 @@ unsigned long __noinstrument machinecycles_to_usecs(unsigned long mputicks)
*/
static unsigned long systimer_mark;
-static unsigned long omap1510_gettimeoffset(void)
+static unsigned long omap_gettimeoffset(void)
{
/* Return elapsed usecs since last system timer ISR */
return machinecycles_to_usecs(do_getmachinecycles() - systimer_mark);
}
static irqreturn_t
-omap1510_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+omap_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long now, ilatency;
@@ -184,29 +183,30 @@ omap1510_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ilatency = MPUTICKS_PER_SEC / 100 - read_mputimer2();
systimer_mark = now - ilatency;
- do_leds();
- do_timer(regs);
- do_profile(regs);
+ timer_tick(regs);
return IRQ_HANDLED;
}
-void __init time_init(void)
+static struct irqaction omap_timer_irq = {
+ .name = "OMAP Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = omap_timer_interrupt
+};
+
+void __init omap_init_time(void)
{
/* Since we don't call request_irq, we must init the structure */
- gettimeoffset = omap1510_gettimeoffset;
+ gettimeoffset = omap_gettimeoffset;
- timer_irq.handler = omap1510_timer_interrupt;
- timer_irq.flags = SA_INTERRUPT;
#ifdef OMAP1510_USE_32KHZ_TIMER
timer32k_write(TIMER32k_CR, 0x0);
timer32k_write(TIMER32k_TVR,TIMER32k_PERIOD);
- setup_irq(INT_OS_32kHz_TIMER, &timer_irq);
+ setup_irq(INT_OS_32kHz_TIMER, &omap_timer_irq);
start_timer32k();
#else
- setup_irq(INT_TIMER2, &timer_irq);
+ setup_irq(INT_TIMER2, &omap_timer_irq);
start_mputimer2(MPUTICKS_PER_SEC / 100 - 1);
#endif
}
-#endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index cc33a476796b..23c51e388a91 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -3,7 +3,7 @@
#
# Common support (must be linked before board specific support)
-obj-y += generic.o irq.o dma.o
+obj-y += generic.o irq.o dma.o time.o
obj-$(CONFIG_PXA25x) += pxa25x.o
obj-$(CONFIG_PXA27x) += pxa27x.o
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 20b776ff92d2..981f7b9750f1 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -198,10 +198,26 @@ static struct platform_device pxafb_device = {
.resource = pxafb_resources,
};
+static struct platform_device ffuart_device = {
+ .name = "pxa2xx-uart",
+ .id = 0,
+};
+static struct platform_device btuart_device = {
+ .name = "pxa2xx-uart",
+ .id = 1,
+};
+static struct platform_device stuart_device = {
+ .name = "pxa2xx-uart",
+ .id = 2,
+};
+
static struct platform_device *devices[] __initdata = {
&pxamci_device,
&udc_device,
&pxafb_device,
+ &ffuart_device,
+ &btuart_device,
+ &stuart_device,
};
static int __init pxa_init(void)
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 6b33fb03ce42..0534d175617a 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -11,6 +11,7 @@
extern void __init pxa_map_io(void);
extern void __init pxa_init_irq(void);
+extern void __init pxa_init_time(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 706858ea2490..db53cd571cd0 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -118,5 +118,6 @@ MACHINE_START(PXA_IDP, "Accelent Xscale IDP")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(idp_map_io)
INITIRQ(idp_init_irq)
+ INITTIME(pxa_init_time)
INIT_MACHINE(idp_init)
MACHINE_END
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 023c5e9f316f..ce8666a7a79e 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -220,5 +220,6 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(lubbock_map_io)
INITIRQ(lubbock_init_irq)
+ INITTIME(pxa_init_time)
INIT_MACHINE(lubbock_init)
MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 663c1eef8a0a..ac998c44d577 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -137,5 +137,6 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
MAPIO(mainstone_map_io)
INITIRQ(mainstone_init_irq)
+ INITTIME(pxa_init_time)
INIT_MACHINE(mainstone_init)
MACHINE_END
diff --git a/include/asm-arm/arch-pxa/time.h b/arch/arm/mach-pxa/time.c
index bc9437a8c38d..7e89235632f8 100644
--- a/include/asm-arm/arch-pxa/time.h
+++ b/arch/arm/mach-pxa/time.c
@@ -1,5 +1,5 @@
/*
- * linux/include/asm-arm/arch-pxa/time.h
+ * arch/arm/mach-pxa/time.c
*
* Author: Nicolas Pitre
* Created: Jun 15, 2001
@@ -10,6 +10,24 @@
* published by the Free Software Foundation.
*/
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
static inline unsigned long pxa_get_rtc_time(void)
{
@@ -56,8 +74,6 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int next_match;
- do_profile(regs);
-
/* Loop until we get ahead of the free running timer.
* This ensures an exact clock tick count and time accuracy.
* IRQs are disabled inside the loop to ensure coherence between
@@ -74,9 +90,7 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* exactly one tick period which should be a pretty rare event.
*/
do {
- do_leds();
- do_set_rtc();
- do_timer(regs);
+ timer_tick(regs);
OSSR = OSSR_M0; /* Clear match on timer 0 */
next_match = (OSMR0 += LATCH);
} while( (signed long)(next_match - OSCR) <= 8 );
@@ -84,7 +98,13 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void __init time_init(void)
+static struct irqaction pxa_timer_irq = {
+ .name = "PXA Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = pxa_timer_interrupt
+};
+
+void __init pxa_init_time(void)
{
struct timespec tv;
@@ -95,10 +115,9 @@ void __init time_init(void)
tv.tv_sec = pxa_get_rtc_time();
do_settimeofday(&tv);
- timer_irq.handler = pxa_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */
- setup_irq(IRQ_OST0, &timer_irq);
+ setup_irq(IRQ_OST0, &pxa_timer_irq);
OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
OSCR = 0; /* initialize free-running timer, force first match */
}
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
index f45e28116609..d5a1a3af216c 100644
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -14,6 +14,8 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
#include <asm/elf.h>
#include <asm/io.h>
@@ -25,6 +27,7 @@
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
extern void rpc_init_irq(void);
@@ -82,6 +85,31 @@ void __init rpc_map_io(void)
elf_hwcap &= ~HWCAP_HALF;
}
+static irqreturn_t
+rpc_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ timer_tick(regs);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction rpc_timer_irq = {
+ .name = "RiscPC Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = rpc_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt.
+ */
+void __init rpc_init_time(void)
+{
+ extern void ioctime_init(void);
+ ioctime_init();
+
+ setup_irq(IRQ_TIMER, &rpc_timer_irq);
+}
+
MACHINE_START(RISCPC, "Acorn-RiscPC")
MAINTAINER("Russell King")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
@@ -90,4 +118,5 @@ MACHINE_START(RISCPC, "Acorn-RiscPC")
DISABLE_PARPORT(1)
MAPIO(rpc_map_io)
INITIRQ(rpc_init_irq)
+ INITTIME(rpc_init_time)
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index d36316999639..d183de782168 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -4,7 +4,7 @@
# Object file lists.
-obj-y := s3c2410.o irq.o
+obj-y := s3c2410.o irq.o time.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index c1f566f319f5..2268ab3c7c69 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -185,10 +185,16 @@ void __init bast_init_irq(void)
}
+void __init bast_init_time(void)
+{
+ s3c2410_init_time();
+}
+
MACHINE_START(BAST, "Simtec-BAST")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(bast_map_io)
INITIRQ(bast_init_irq)
+ INITTIME(bast_init_time)
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index a66b451ec7d0..f3515bcec1b7 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -91,10 +91,16 @@ void __init ipaq_init_irq(void)
}
+void __init ipaq_init_time(void)
+{
+ s3c2410_init_time();
+}
+
MACHINE_START(H1940, "IPAQ-H1940")
MAINTAINER("Ben Dooks <ben@fluff.org>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(ipaq_map_io)
INITIRQ(ipaq_init_irq)
+ INITTIME(ipaq_init_time)
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 4e0282b12fbb..fb180732b860 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -99,6 +99,11 @@ void __init smdk2410_init_irq(void)
s3c2410_init_irq();
}
+void __init smdk2410_init_time(void)
+{
+ s3c2401_init_time();
+}
+
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
* to SMDK2410 */
MAINTAINER("Jonas Dietsche")
@@ -106,4 +111,5 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(smdk2410_map_io)
INITIRQ(smdk2410_init_irq)
+ INITTIME(smdk2410_init_time)
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 1758422da7bf..856739ba1921 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -155,10 +155,16 @@ void __init vr1000_init_irq(void)
}
+void __init vr1000_init_time(void)
+{
+ s3c2401_init_time();
+}
+
MACHINE_START(VR1000, "Simtec-VR1000")
MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, S3C2410_VA_UART)
BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
MAPIO(vr1000_map_io)
INITIRQ(vr1000_init_irq)
+ INITTIME(vr1000_init_time)
MACHINE_END
diff --git a/arch/arm/mach-s3c2410/s3c2410.h b/arch/arm/mach-s3c2410/s3c2410.h
index 80c336caa86d..5ff132081a6f 100644
--- a/arch/arm/mach-s3c2410/s3c2410.h
+++ b/arch/arm/mach-s3c2410/s3c2410.h
@@ -4,3 +4,5 @@ extern void s3c2410_map_io(struct map_desc *, int count);
extern void s3c2410_init_irq(void);
+extern s3c2410_init_time(void);
+
diff --git a/include/asm-arm/arch-s3c2410/time.h b/arch/arm/mach-s3c2410/time.c
index 8aab3438a992..62d89d98c423 100644
--- a/include/asm-arm/arch-s3c2410/time.h
+++ b/arch/arm/mach-s3c2410/time.c
@@ -18,15 +18,20 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/arch/map.h>
#include <asm/arch/regs-timer.h>
-
-extern unsigned long (*gettimeoffset)(void);
+#include <asm/mach/time.h>
static unsigned long timer_startval;
static unsigned long timer_ticks_usec;
@@ -69,25 +74,24 @@ static unsigned long s3c2410_gettimeoffset (void)
static irqreturn_t
s3c2410_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- do_leds();
- do_timer(regs);
-
- do_set_rtc();
- //s3c2410_rtc_check();
- do_profile(regs);
+ timer_tick(regs);
return IRQ_HANDLED;
}
+static struct irqaction s3c2410_timer_irq = {
+ .name = "S32410 Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = s3c2410_timer_interrupt
+};
+
/*
* Set up timer interrupt, and return the current time in seconds.
- */
-
-/* currently we only use timer4, as it is the only timer which has no
+ *
+ * Currently we only use timer4, as it is the only timer which has no
* other function that can be exploited externally
-*/
-
-void __init time_init (void)
+ */
+void __init s3c2410_init_time (void)
{
unsigned long tcon;
unsigned long tcnt;
@@ -95,7 +99,6 @@ void __init time_init (void)
unsigned long tcfg0;
gettimeoffset = s3c2410_gettimeoffset;
- timer_irq.handler = s3c2410_timer_interrupt;
tcnt = 0xffff; /* default value for tcnt */
@@ -161,7 +164,7 @@ void __init time_init (void)
__raw_writel(tcnt, S3C2410_TCNTB(4));
__raw_writel(tcnt, S3C2410_TCMPB(4));
- setup_irq(IRQ_TIMER4, &timer_irq);
+ setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
/* start the timer running */
tcon |= S3C2410_TCON_T4START;
diff --git a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c
index d028a87ce2eb..53f990e7d615 100644
--- a/arch/arm/mach-sa1100/adsbitsy.c
+++ b/arch/arm/mach-sa1100/adsbitsy.c
@@ -147,4 +147,5 @@ MACHINE_START(ADSBITSY, "ADS Bitsy")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(adsbitsy_map_io)
INITIRQ(adsbitsy_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index dcd32454e606..e5098cf9c2e9 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -324,5 +324,6 @@ MACHINE_START(ASSABET, "Intel-Assabet")
FIXUP(fixup_assabet)
MAPIO(assabet_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
INIT_MACHINE(assabet_init)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index 71d9e165a3b6..cef71047ccb7 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -245,4 +245,5 @@ MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
BOOT_PARAMS(0xc0000100)
MAPIO(badge4_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/brutus.c b/arch/arm/mach-sa1100/brutus.c
index fdfe024b10fa..925bf0e59fe8 100644
--- a/arch/arm/mach-sa1100/brutus.c
+++ b/arch/arm/mach-sa1100/brutus.c
@@ -37,4 +37,5 @@ MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(brutus_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 00af122c4819..2c4c05013cc9 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -92,4 +92,5 @@ MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(cerf_map_io)
INITIRQ(cerf_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/empeg.c b/arch/arm/mach-sa1100/empeg.c
index b1faaa92f930..6ab57cdb0182 100644
--- a/arch/arm/mach-sa1100/empeg.c
+++ b/arch/arm/mach-sa1100/empeg.c
@@ -35,4 +35,5 @@ MACHINE_START(EMPEG, "empeg MP3 Car Audio Player")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(empeg_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/flexanet.c b/arch/arm/mach-sa1100/flexanet.c
index 0a40c7831515..370df9f773cf 100644
--- a/arch/arm/mach-sa1100/flexanet.c
+++ b/arch/arm/mach-sa1100/flexanet.c
@@ -183,5 +183,6 @@ MACHINE_START(FLEXANET, "FlexaNet")
BOOT_PARAMS(0xc0000100)
MAPIO(flexanet_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/freebird.c b/arch/arm/mach-sa1100/freebird.c
index 5363d02ee7e6..abd27aef72f9 100644
--- a/arch/arm/mach-sa1100/freebird.c
+++ b/arch/arm/mach-sa1100/freebird.c
@@ -77,4 +77,5 @@ MACHINE_START(FREEBIRD, "Freebird-HPC-1.1")
#endif
MAPIO(freebird_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index 4649fc5c5c4e..04bcfeb3b8a1 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -6,6 +6,7 @@
extern void __init sa1100_map_io(void);
extern void __init sa1100_init_irq(void);
+extern void __init sa1100_init_time(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
diff --git a/arch/arm/mach-sa1100/graphicsclient.c b/arch/arm/mach-sa1100/graphicsclient.c
index eb420d53a93d..2f628adbda2c 100644
--- a/arch/arm/mach-sa1100/graphicsclient.c
+++ b/arch/arm/mach-sa1100/graphicsclient.c
@@ -198,4 +198,5 @@ MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(graphicsclient_map_io)
INITIRQ(graphicsclient_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c
index 77d84368d7ac..7f1cfd18eaca 100644
--- a/arch/arm/mach-sa1100/graphicsmaster.c
+++ b/arch/arm/mach-sa1100/graphicsmaster.c
@@ -287,4 +287,5 @@ MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(graphicsmaster_map_io)
INITIRQ(graphicsmaster_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 9868d4129650..54ab44452401 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -286,6 +286,7 @@ MACHINE_START(H3100, "Compaq iPAQ H3100")
BOOT_PARAMS(0xc0000100)
MAPIO(h3100_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
#endif /* CONFIG_SA1100_H3100 */
@@ -400,6 +401,7 @@ MACHINE_START(H3600, "Compaq iPAQ H3600")
BOOT_PARAMS(0xc0000100)
MAPIO(h3600_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
#endif /* CONFIG_SA1100_H3600 */
@@ -783,6 +785,7 @@ MACHINE_START(H3800, "Compaq iPAQ H3800")
BOOT_PARAMS(0xc0000100)
MAPIO(h3800_map_io)
INITIRQ(h3800_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
#endif /* CONFIG_SA1100_H3800 */
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
index e79bb441c8fe..e24be9716ba4 100644
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -174,4 +174,5 @@ MACHINE_START(HACKKIT, "HackKit Cpu Board")
BOOT_PARAMS(0xc0000100)
MAPIO(hackkit_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/huw_webpanel.c b/arch/arm/mach-sa1100/huw_webpanel.c
index 1ed5f365c950..771b10620249 100644
--- a/arch/arm/mach-sa1100/huw_webpanel.c
+++ b/arch/arm/mach-sa1100/huw_webpanel.c
@@ -81,4 +81,5 @@ MACHINE_START(HUW_WEBPANEL, "HuW-Webpanel")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(huw_webpanel_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/itsy.c b/arch/arm/mach-sa1100/itsy.c
index 2d23c99c6115..a4af8d58867d 100644
--- a/arch/arm/mach-sa1100/itsy.c
+++ b/arch/arm/mach-sa1100/itsy.c
@@ -37,4 +37,5 @@ MACHINE_START(ITSY, "Compaq Itsy")
BOOT_PARAMS(0xc0000100)
MAPIO(itsy_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index c71e512830bd..8943e816a180 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -101,4 +101,5 @@ MACHINE_START(JORNADA720, "HP Jornada 720")
BOOT_PARAMS(0xc0000100)
MAPIO(jornada720_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index 728612961bd5..34ab20118c70 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -43,4 +43,5 @@ MACHINE_START(LART, "LART")
BOOT_PARAMS(0xc0000100)
MAPIO(lart_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
index 20b6d9a43d1d..84c870c3de49 100644
--- a/arch/arm/mach-sa1100/nanoengine.c
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -49,4 +49,5 @@ MACHINE_START(NANOENGINE, "BSE nanoEngine")
FIXUP(fixup_nanoengine)
MAPIO(nanoengine_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/omnimeter.c b/arch/arm/mach-sa1100/omnimeter.c
index baa3a0313a57..1533fc0ff51c 100644
--- a/arch/arm/mach-sa1100/omnimeter.c
+++ b/arch/arm/mach-sa1100/omnimeter.c
@@ -59,4 +59,5 @@ MACHINE_START(OMNIMETER, "OmniMeter")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(omnimeter_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/pangolin.c b/arch/arm/mach-sa1100/pangolin.c
index f7102f4388ed..29922dd70e41 100644
--- a/arch/arm/mach-sa1100/pangolin.c
+++ b/arch/arm/mach-sa1100/pangolin.c
@@ -40,4 +40,5 @@ MACHINE_START(PANGOLIN, "Dialogue-Pangolin")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(pangolin_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/pfs168.c b/arch/arm/mach-sa1100/pfs168.c
index 43b89fcc8919..04088629f4c7 100644
--- a/arch/arm/mach-sa1100/pfs168.c
+++ b/arch/arm/mach-sa1100/pfs168.c
@@ -112,4 +112,5 @@ MACHINE_START(PFS168, "Tulsa")
BOOT_PARAMS(0xc0000100)
MAPIO(pfs168_map_io)
INITIRQ(pfs168_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index b0284ff1c74a..2cdfef622c25 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -31,4 +31,5 @@ MACHINE_START(PLEB, "PLEB")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(pleb_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index 0dbe474c7611..8bec82676a3b 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -41,4 +41,5 @@ MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
BOOT_PARAMS(0xc0000100)
MAPIO(shannon_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/sherman.c b/arch/arm/mach-sa1100/sherman.c
index c36f46017f53..2e66fbadf16f 100644
--- a/arch/arm/mach-sa1100/sherman.c
+++ b/arch/arm/mach-sa1100/sherman.c
@@ -27,4 +27,5 @@ MACHINE_START(SHERMAN, "Blazie Engineering Sherman")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(sherman_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 472174365903..b73ec2e18eb0 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -231,4 +231,5 @@ MACHINE_START(SIMPAD, "Simpad")
BOOT_PARAMS(0xc0000100)
MAPIO(simpad_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/stork.c b/arch/arm/mach-sa1100/stork.c
index 5aeb087c45d0..f3b3a6eb8c09 100644
--- a/arch/arm/mach-sa1100/stork.c
+++ b/arch/arm/mach-sa1100/stork.c
@@ -331,6 +331,7 @@ MACHINE_START(STORK, "Stork Technologies prototype")
BOOT_PARAMS(0xc0000100)
MAPIO(stork_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/system3.c b/arch/arm/mach-sa1100/system3.c
index 09f679e4e67b..76e7d36e71bc 100644
--- a/arch/arm/mach-sa1100/system3.c
+++ b/arch/arm/mach-sa1100/system3.c
@@ -470,4 +470,5 @@ MACHINE_START(PT_SYSTEM3, "PT System 3")
BOOT_PARAMS(0xc0000100)
MAPIO(system3_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/include/asm-arm/arch-sa1100/time.h b/arch/arm/mach-sa1100/time.c
index d962626154dd..e58463b02e67 100644
--- a/include/asm-arm/arch-sa1100/time.h
+++ b/arch/arm/mach-sa1100/time.c
@@ -78,19 +78,21 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
unsigned int next_match;
do {
- do_leds();
- do_timer(regs);
+ timer_tick(regs);
OSSR = OSSR_M0; /* Clear match on timer 0 */
next_match = (OSMR0 += LATCH);
- do_set_rtc();
} while ((signed long)(next_match - OSCR) <= 0);
- do_profile(regs);
-
return IRQ_HANDLED;
}
-void __init time_init(void)
+static struct irqaction sa1100_timer_irq = {
+ .name = "SA11xx Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = sa1100_timer_interrupt
+};
+
+void __init sa1100_init_time(void)
{
struct timespec tv;
@@ -101,10 +103,9 @@ void __init time_init(void)
tv.tv_sec = sa1100_get_rtc_time();
do_settimeofday(&tv);
- timer_irq.handler = sa1100_timer_interrupt;
OSMR0 = 0; /* set initial match at 0 */
OSSR = 0xf; /* clear status on all timers */
- setup_irq(IRQ_OST0, &timer_irq);
+ setup_irq(IRQ_OST0, &sa1100_timer_irq);
OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
OSCR = 0; /* initialize free-running timer, force first match */
}
diff --git a/arch/arm/mach-sa1100/trizeps.c b/arch/arm/mach-sa1100/trizeps.c
index 199d9cfc5024..f3f1682ecd34 100644
--- a/arch/arm/mach-sa1100/trizeps.c
+++ b/arch/arm/mach-sa1100/trizeps.c
@@ -228,4 +228,5 @@ MACHINE_START(TRIZEPS, "TRIZEPS")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(trizeps_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/xp860.c b/arch/arm/mach-sa1100/xp860.c
index 501b1bfe8b2b..ab2a523c3b14 100644
--- a/arch/arm/mach-sa1100/xp860.c
+++ b/arch/arm/mach-sa1100/xp860.c
@@ -89,4 +89,5 @@ MACHINE_START(XP860, "XP860")
BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
MAPIO(xp860_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-sa1100/yopy.c b/arch/arm/mach-sa1100/yopy.c
index fd9df1bc9162..46e447fc87d9 100644
--- a/arch/arm/mach-sa1100/yopy.c
+++ b/arch/arm/mach-sa1100/yopy.c
@@ -91,4 +91,5 @@ MACHINE_START(YOPY, "Yopy")
BOOT_PARAMS(0xc0000100)
MAPIO(yopy_map_io)
INITIRQ(sa1100_init_irq)
+ INITTIME(sa1100_init_time)
MACHINE_END
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index fed8a03ddcf9..e4ae688899c1 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -5,13 +5,18 @@
*/
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/param.h>
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
extern void shark_init_irq(void);
@@ -24,10 +29,43 @@ static void __init shark_map_io(void)
iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc));
}
+#define IRQ_TIMER 0
+#define HZ_TIME ((1193180 + HZ/2) / HZ)
+
+static irqreturn_t
+shark_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ timer_tick(regs);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction shark_timer_irq = {
+ .name = "Shark Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = shark_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init shark_init_time(void)
+{
+ unsigned long flags;
+
+ outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */
+ outb(HZ_TIME & 0xff, 0x40); /* LSB of count */
+ outb(HZ_TIME >> 8, 0x40);
+
+ setup_irq(IRQ_TIMER, &shark_timer_irq);
+}
+
+
MACHINE_START(SHARK, "Shark")
MAINTAINER("Alexander Schulz")
BOOT_MEM(0x08000000, 0x40000000, 0xe0000000)
BOOT_PARAMS(0x08003000)
MAPIO(shark_map_io)
INITIRQ(shark_init_irq)
+ INITTIME(shark_init_time)
MACHINE_END
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 4c8646c62efa..a2f88df44ab9 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -22,7 +22,9 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <asm/system.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -33,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
#include <asm/mach/map.h>
#ifdef CONFIG_MMC
#include <asm/mach/mmc.h>
@@ -511,11 +514,153 @@ static void __init versatile_init(void)
leds_event = versatile_leds_event;
}
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE IO_ADDRESS(VERSATILE_TIMER0_1_BASE)
+#define TIMER1_VA_BASE (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_VA_BASE IO_ADDRESS(VERSATILE_TIMER2_3_BASE)
+#define TIMER3_VA_BASE (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)
+#define VA_IC_BASE IO_ADDRESS(VERSATILE_VIC_BASE)
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
+#if TIMER_INTERVAL >= 0x100000
+#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */
+#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */
+#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
+#elif TIMER_INTERVAL >= 0x10000
+#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
+#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */
+#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
+#else
+#define TIMER_RELOAD (TIMER_INTERVAL)
+#define TIMER_CTRL 0x80 /* Enable */
+#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
+#endif
+
+#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
+
+/*
+ * What does it look like?
+ */
+typedef struct TimerStruct {
+ unsigned long TimerLoad;
+ unsigned long TimerValue;
+ unsigned long TimerControl;
+ unsigned long TimerClear;
+} TimerStruct_t;
+
+extern unsigned long (*gettimeoffset)(void);
+
+/*
+ * Returns number of ms since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long versatile_gettimeoffset(void)
+{
+ volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
+ unsigned long ticks1, ticks2, status;
+
+ /*
+ * Get the current number of ticks. Note that there is a race
+ * condition between us reading the timer and checking for
+ * an interrupt. We get around this by ensuring that the
+ * counter has not reloaded between our two reads.
+ */
+ ticks2 = timer0->TimerValue & 0xffff;
+ do {
+ ticks1 = ticks2;
+ status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
+ ticks2 = timer0->TimerValue & 0xffff;
+ } while (ticks2 > ticks1);
+
+ /*
+ * Number of ticks since last interrupt.
+ */
+ ticks1 = TIMER_RELOAD - ticks2;
+
+ /*
+ * Interrupt pending? If so, we've reloaded once already.
+ *
+ * FIXME: Need to check this is effectively timer 0 that expires
+ */
+ if (status & IRQMASK_TIMERINT0_1)
+ ticks1 += TIMER_RELOAD;
+
+ /*
+ * Convert the ticks to usecs
+ */
+ return TICKS2USECS(ticks1);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
+
+ // ...clear the interrupt
+ timer0->TimerClear = 1;
+
+ timer_tick(regs);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction versatile_timer_irq = {
+ .name = "Versatile Timer Tick",
+ .flags = SA_INTERRUPT,
+ .handler = versatile_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init versatile_init_time(void)
+{
+ volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
+ volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
+ volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
+ volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
+
+ /*
+ * set clock frequency:
+ * VERSATILE_REFCLK is 32KHz
+ * VERSATILE_TIMCLK is 1MHz
+ */
+ *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |=
+ ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
+
+ /*
+ * Initialise to a known state (all timers off)
+ */
+ timer0->TimerControl = 0;
+ timer1->TimerControl = 0;
+ timer2->TimerControl = 0;
+ timer3->TimerControl = 0;
+
+ timer0->TimerLoad = TIMER_RELOAD;
+ timer0->TimerValue = TIMER_RELOAD;
+ timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */
+
+ /*
+ * Make irqs happen for the system timer
+ */
+ setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
+ gettimeoffset = versatile_gettimeoffset;
+}
+
MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
BOOT_PARAMS(0x00000100)
MAPIO(versatile_map_io)
INITIRQ(versatile_init_irq)
+ INITTIME(versatile_init_time)
INIT_MACHINE(versatile_init)
MACHINE_END
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index ba32817ad59f..545a548b1f69 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -220,7 +220,7 @@ config CPU_SA1100
# XScale
config CPU_XSCALE
bool
- depends on ARCH_IOP3XX || ARCH_ADIFCC || ARCH_PXA || ARCH_IXP4XX
+ depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX
default y
select CPU_32v5
select CPU_ABRT_EV5T
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 5a997a3716fc..32a0984318f6 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -36,12 +36,17 @@
#include <linux/fs.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
+static struct class_simple *cpuid_class;
+
#ifdef CONFIG_SMP
struct cpuid_command {
@@ -153,20 +158,84 @@ static struct file_operations cpuid_fops = {
.open = cpuid_open,
};
+static int cpuid_class_simple_device_add(int i)
+{
+ int err = 0;
+ struct class_device *class_err;
+
+ class_err = class_simple_device_add(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+ if (IS_ERR(class_err))
+ err = PTR_ERR(class_err);
+ return err;
+}
+
+static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ cpuid_class_simple_device_add(cpu);
+ break;
+ case CPU_DEAD:
+ class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpuid_class_cpu_notifier =
+{
+ .notifier_call = cpuid_class_cpu_callback,
+};
+
int __init cpuid_init(void)
{
+ int i, err = 0;
+ i = 0;
+
if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
CPUID_MAJOR);
- return -EBUSY;
+ err = -EBUSY;
+ goto out;
+ }
+ cpuid_class = class_simple_create(THIS_MODULE, "cpuid");
+ if (IS_ERR(cpuid_class)) {
+ err = PTR_ERR(cpuid_class);
+ goto out_chrdev;
}
+ for_each_online_cpu(i) {
+ err = cpuid_class_simple_device_add(i);
+ if (err != 0)
+ goto out_class;
+ }
+ register_cpu_notifier(&cpuid_class_cpu_notifier);
- return 0;
+ err = 0;
+ goto out;
+
+out_class:
+ i = 0;
+ for_each_online_cpu(i) {
+ class_simple_device_remove(MKDEV(CPUID_MAJOR, i));
+ }
+ class_simple_destroy(cpuid_class);
+out_chrdev:
+ unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+out:
+ return err;
}
void __exit cpuid_exit(void)
{
+ int cpu = 0;
+
+ for_each_online_cpu(cpu)
+ class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
+ class_simple_destroy(cpuid_class);
unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+ unregister_cpu_notifier(&cpuid_class_cpu_notifier);
}
module_init(cpuid_init);
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 0f88098de075..41cb82604f7f 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -1015,15 +1015,23 @@ void __init mp_config_acpi_legacy_irqs (void)
for (i = 0; i < 16; i++) {
int idx;
- for (idx = 0; idx < mp_irq_entries; idx++)
- if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
- (mp_irqs[idx].mpc_dstapic == ioapic) &&
- (mp_irqs[idx].mpc_srcbusirq == i ||
- mp_irqs[idx].mpc_dstirq == i))
- break;
-
- if (idx != mp_irq_entries)
- continue; /* IRQ already used */
+ for (idx = 0; idx < mp_irq_entries; idx++) {
+ struct mpc_config_intsrc *irq = mp_irqs + idx;
+
+ /* Do we already have a mapping for this ISA IRQ? */
+ if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i)
+ break;
+
+ /* Do we already have a mapping for this IOAPIC pin */
+ if ((irq->mpc_dstapic == intsrc.mpc_dstapic) &&
+ (irq->mpc_dstirq == i))
+ break;
+ }
+
+ if (idx != mp_irq_entries) {
+ printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i);
+ continue; /* IRQ already used */
+ }
intsrc.mpc_irqtype = mp_INT;
intsrc.mpc_srcbusirq = i; /* Identity mapped */
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 1a1093e4a4c2..670a71efafb3 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -35,12 +35,17 @@
#include <linux/smp_lock.h>
#include <linux/major.h>
#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/uaccess.h>
#include <asm/system.h>
+static struct class_simple *msr_class;
+
/* Note: "err" is handled in a funny way below. Otherwise one version
of gcc or another breaks. */
@@ -255,20 +260,82 @@ static struct file_operations msr_fops = {
.open = msr_open,
};
+static int msr_class_simple_device_add(int i)
+{
+ int err = 0;
+ struct class_device *class_err;
+
+ class_err = class_simple_device_add(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+ if (IS_ERR(class_err))
+ err = PTR_ERR(class_err);
+ return err;
+}
+
+static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ msr_class_simple_device_add(cpu);
+ break;
+ case CPU_DEAD:
+ class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block msr_class_cpu_notifier =
+{
+ .notifier_call = msr_class_cpu_callback,
+};
+
int __init msr_init(void)
{
+ int i, err = 0;
+ i = 0;
+
if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
printk(KERN_ERR "msr: unable to get major %d for msr\n",
MSR_MAJOR);
- return -EBUSY;
+ err = -EBUSY;
+ goto out;
+ }
+ msr_class = class_simple_create(THIS_MODULE, "msr");
+ if (IS_ERR(msr_class)) {
+ err = PTR_ERR(msr_class);
+ goto out_chrdev;
}
+ for_each_online_cpu(i) {
+ err = msr_class_simple_device_add(i);
+ if (err != 0)
+ goto out_class;
+ }
+ register_cpu_notifier(&msr_class_cpu_notifier);
- return 0;
+ err = 0;
+ goto out;
+
+out_class:
+ i = 0;
+ for_each_online_cpu(i)
+ class_simple_device_remove(MKDEV(MSR_MAJOR, i));
+ class_simple_destroy(msr_class);
+out_chrdev:
+ unregister_chrdev(MSR_MAJOR, "cpu/msr");
+out:
+ return err;
}
void __exit msr_exit(void)
{
+ int cpu = 0;
+ for_each_online_cpu(cpu)
+ class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
+ class_simple_destroy(msr_class);
unregister_chrdev(MSR_MAJOR, "cpu/msr");
+ unregister_cpu_notifier(&msr_class_cpu_notifier);
}
module_init(msr_init);
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 2b49740fbe10..ac5784c618b2 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1183,6 +1183,7 @@ endmenu
source "lib/Kconfig"
+source "arch/ppc/oprofile/Kconfig"
menu "Kernel hacking"
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index b050a1b03e34..52782b7ae2f1 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -50,6 +50,8 @@ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
drivers-$(CONFIG_8260) += arch/ppc/8260_io/
+drivers-$(CONFIG_OPROFILE) += arch/ppc/oprofile/
+
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
.PHONY: $(BOOT_TARGETS)
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 38cd36d6cbe9..873199e435f6 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -253,6 +253,24 @@ _GLOBAL(low_choose_750fx_pll)
mtmsr r7
blr
+_GLOBAL(low_choose_7447a_dfs)
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* Calc new HID1 value */
+ mfspr r4,SPRN_HID1
+ insrwi r4,r3,1,9 /* insert parameter into bit 9 */
+ sync
+ mtspr SPRN_HID1,r4
+ sync
+ isync
+
+ /* Return */
+ mtmsr r7
+ blr
+
#endif /* CONFIG_CPU_FREQ_PMAC && CONFIG_6xx */
/* void local_save_flags_ptr(unsigned long *flags) */
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index 96a6138e4109..cfeff0479c2e 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -56,6 +56,7 @@
#include <linux/mc146818rtc.h>
#include <linux/time.h>
#include <linux/init.h>
+#include <linux/profile.h>
#include <asm/segment.h>
#include <asm/io.h>
@@ -107,17 +108,23 @@ static inline int tb_delta(unsigned *jiffy_stamp) {
return delta;
}
-extern unsigned long prof_cpu_mask;
-extern unsigned int * prof_buffer;
-extern unsigned long prof_len;
-extern unsigned long prof_shift;
extern char _stext;
-static inline void ppc_do_profile (unsigned long nip)
+static inline void ppc_do_profile (struct pt_regs *regs)
{
+ unsigned long nip;
+ extern unsigned long prof_cpu_mask;
+
+ profile_hook(regs);
+
+ if (user_mode(regs))
+ return;
+
if (!prof_buffer)
return;
+ nip = instruction_pointer(regs);
+
/*
* Only measure the CPUs specified by /proc/irq/prof_cpu_mask.
* (default is all CPUs.)
@@ -156,8 +163,9 @@ void timer_interrupt(struct pt_regs * regs)
while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) {
jiffy_stamp += tb_ticks_per_jiffy;
- if (!user_mode(regs))
- ppc_do_profile(instruction_pointer(regs));
+
+ ppc_do_profile(regs);
+
if (smp_processor_id())
continue;
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index ebe93fe949b8..d72c35081da2 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -103,8 +103,7 @@ void die(const char * str, struct pt_regs * fp, long err)
do_exit(err);
}
-void
-_exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
+void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
{
siginfo_t info;
@@ -200,8 +199,7 @@ static inline int check_io_access(struct pt_regs *regs)
#define clear_single_step(regs) ((regs)->msr &= ~MSR_SE)
#endif
-void
-MachineCheckException(struct pt_regs *regs)
+void MachineCheckException(struct pt_regs *regs)
{
unsigned long reason = get_mc_reason(regs);
@@ -329,8 +327,7 @@ MachineCheckException(struct pt_regs *regs)
die("machine check", regs, SIGBUS);
}
-void
-SMIException(struct pt_regs *regs)
+void SMIException(struct pt_regs *regs)
{
debugger(regs);
#if !(defined(CONFIG_XMON) || defined(CONFIG_KGDB))
@@ -339,24 +336,21 @@ SMIException(struct pt_regs *regs)
#endif
}
-void
-UnknownException(struct pt_regs *regs)
+void UnknownException(struct pt_regs *regs)
{
printk("Bad trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
regs->nip, regs->msr, regs->trap, print_tainted());
_exception(SIGTRAP, regs, 0, 0);
}
-void
-InstructionBreakpoint(struct pt_regs *regs)
+void InstructionBreakpoint(struct pt_regs *regs)
{
if (debugger_iabr_match(regs))
return;
_exception(SIGTRAP, regs, TRAP_BRKPT, 0);
}
-void
-RunModeException(struct pt_regs *regs)
+void RunModeException(struct pt_regs *regs)
{
_exception(SIGTRAP, regs, 0, 0);
}
@@ -374,8 +368,7 @@ RunModeException(struct pt_regs *regs)
#define INST_MFSPR_PVR 0x7c1f42a6
#define INST_MFSPR_PVR_MASK 0xfc1fffff
-static int
-emulate_instruction(struct pt_regs *regs)
+static int emulate_instruction(struct pt_regs *regs)
{
u32 instword;
u32 rd;
@@ -438,8 +431,7 @@ static struct bug_entry *find_bug(unsigned long bugaddr)
return module_find_bug(bugaddr);
}
-int
-check_bug_trap(struct pt_regs *regs)
+int check_bug_trap(struct pt_regs *regs)
{
struct bug_entry *bug;
unsigned long addr;
@@ -476,8 +468,7 @@ check_bug_trap(struct pt_regs *regs)
return 0;
}
-void
-ProgramCheckException(struct pt_regs *regs)
+void ProgramCheckException(struct pt_regs *regs)
{
unsigned int reason = get_reason(regs);
extern int do_mathemu(struct pt_regs *regs);
@@ -550,8 +541,7 @@ ProgramCheckException(struct pt_regs *regs)
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
}
-void
-SingleStepException(struct pt_regs *regs)
+void SingleStepException(struct pt_regs *regs)
{
regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
if (debugger_sstep(regs))
@@ -559,8 +549,7 @@ SingleStepException(struct pt_regs *regs)
_exception(SIGTRAP, regs, TRAP_TRACE, 0);
}
-void
-AlignmentException(struct pt_regs *regs)
+void AlignmentException(struct pt_regs *regs)
{
int fixed;
@@ -580,8 +569,7 @@ AlignmentException(struct pt_regs *regs)
_exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
}
-void
-StackOverflow(struct pt_regs *regs)
+void StackOverflow(struct pt_regs *regs)
{
printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
current, regs->gpr[1]);
@@ -598,8 +586,7 @@ void nonrecoverable_exception(struct pt_regs *regs)
die("nonrecoverable exception", regs, SIGKILL);
}
-void
-trace_syscall(struct pt_regs *regs)
+void trace_syscall(struct pt_regs *regs)
{
printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
current, current->pid, regs->nip, regs->link, regs->gpr[0],
@@ -607,8 +594,7 @@ trace_syscall(struct pt_regs *regs)
}
#ifdef CONFIG_8xx
-void
-SoftwareEmulation(struct pt_regs *regs)
+void SoftwareEmulation(struct pt_regs *regs)
{
extern int do_mathemu(struct pt_regs *);
extern int Soft_emulate_8xx(struct pt_regs *);
@@ -660,8 +646,7 @@ void DebugException(struct pt_regs *regs, unsigned long debug_status)
#endif /* CONFIG_4xx || CONFIG_BOOKE */
#if !defined(CONFIG_TAU_INT)
-void
-TAUException(struct pt_regs *regs)
+void TAUException(struct pt_regs *regs)
{
printk("TAU trap at PC: %lx, MSR: %lx, vector=%lx %s\n",
regs->nip, regs->msr, regs->trap, print_tainted());
@@ -683,14 +668,13 @@ void AltivecUnavailException(struct pt_regs *regs)
/* The kernel has executed an altivec instruction without
first enabling altivec. Whinge but let it do it. */
if (++kernel_altivec_count < 10)
- printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%x)\n",
+ printk(KERN_ERR "AltiVec used in kernel (task=%p, pc=%lx)\n",
current, regs->nip);
regs->msr |= MSR_VEC;
}
#ifdef CONFIG_ALTIVEC
-void
-AltivecAssistException(struct pt_regs *regs)
+void AltivecAssistException(struct pt_regs *regs)
{
int err;
@@ -734,8 +718,7 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address,
#endif /* CONFIG_FSL_BOOKE */
#ifdef CONFIG_SPE
-void
-SPEFloatingPointException(struct pt_regs *regs)
+void SPEFloatingPointException(struct pt_regs *regs)
{
unsigned long spefscr;
int fpexc_mode;
diff --git a/arch/ppc/kernel/vecemu.c b/arch/ppc/kernel/vecemu.c
index 1430ef59279c..2411a1cbc638 100644
--- a/arch/ppc/kernel/vecemu.c
+++ b/arch/ppc/kernel/vecemu.c
@@ -256,8 +256,7 @@ static unsigned int rfin(unsigned int x)
return (x + half) & ~(0x7fffff >> exp);
}
-int
-emulate_altivec(struct pt_regs *regs)
+int emulate_altivec(struct pt_regs *regs)
{
unsigned int instr, i;
unsigned int va, vb, vc, vd;
diff --git a/arch/ppc/oprofile/Kconfig b/arch/ppc/oprofile/Kconfig
new file mode 100644
index 000000000000..19d37730b664
--- /dev/null
+++ b/arch/ppc/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+ depends on EXPERIMENTAL
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+endmenu
+
diff --git a/arch/ppc/oprofile/Makefile b/arch/ppc/oprofile/Makefile
new file mode 100644
index 000000000000..06e7c81ead2e
--- /dev/null
+++ b/arch/ppc/oprofile/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+oprofile-y := $(DRIVER_OBJS) init.o
diff --git a/arch/ppc/oprofile/init.c b/arch/ppc/oprofile/init.c
new file mode 100644
index 000000000000..e4217d66164e
--- /dev/null
+++ b/arch/ppc/oprofile/init.c
@@ -0,0 +1,23 @@
+/**
+ * @file init.c
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author John Levon <levon@movementarian.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+
+int __init oprofile_arch_init(struct oprofile_operations ** ops)
+{
+ return -ENODEV;
+}
+
+
+void oprofile_arch_exit(void)
+{
+}
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
index 2c8cec2723ad..b26c7e158792 100644
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -1,7 +1,8 @@
/*
* arch/ppc/platforms/pmac_cpufreq.c
*
- * Copyright (C) 2002 - 2003 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (C) 2002 - 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (C) 2004 John Steele Scott <toojays@toojays.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -47,6 +48,7 @@
#warning "WARNING, CPUFREQ not recommended on SMP kernels"
#endif
+extern void low_choose_7447a_dfs(int dfs);
extern void low_choose_750fx_pll(int pll);
extern void low_sleep_handler(void);
extern void openpic_suspend(struct sys_device *sysdev, u32 state);
@@ -54,18 +56,27 @@ extern void openpic_resume(struct sys_device *sysdev);
extern void enable_kernel_altivec(void);
extern void enable_kernel_fp(void);
+/*
+ * Currently, PowerMac cpufreq supports only high & low frequencies
+ * that are set by the firmware
+ */
static unsigned int low_freq;
static unsigned int hi_freq;
static unsigned int cur_freq;
-/* Clean that up some day ... use a func ptr or at least an enum... */
-static int cpufreq_uses_pmu;
-static int cpufreq_uses_gpios;
+/*
+ * Different models uses different mecanisms to switch the frequency
+ */
+static int (*set_speed_proc)(int low_speed);
+/*
+ * Some definitions used by the various speedprocs
+ */
static u32 voltage_gpio;
static u32 frequency_gpio;
static u32 slew_done_gpio;
+
#define PMAC_CPU_LOW_SPEED 1
#define PMAC_CPU_HIGH_SPEED 0
@@ -123,9 +134,39 @@ static int __pmac cpu_750fx_cpu_speed(int low_speed)
return 0;
}
+/* Switch CPU speed using DFS */
+static int __pmac dfs_set_cpu_speed(int low_speed)
+{
+ if (low_speed == 0) {
+ /* ramping up, set voltage first */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ/1000);
+ } else {
+ /* ramping down, enable aack delay first */
+ pmac_call_feature(PMAC_FTR_AACK_DELAY_ENABLE, NULL, 1, 0);
+ }
+
+ /* set frequency */
+ low_choose_7447a_dfs(low_speed);
+
+ if (low_speed == 1) {
+ /* ramping down, set voltage last */
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ/1000);
+ } else {
+ /* ramping up, disable aack delay last */
+ pmac_call_feature(PMAC_FTR_AACK_DELAY_ENABLE, NULL, 0, 0);
+ }
+
+ return 0;
+}
+
+
/* Switch CPU speed using slewing GPIOs
*/
-static int __pmac gpios_set_cpu_speed(unsigned int low_speed)
+static int __pmac gpios_set_cpu_speed(int low_speed)
{
int gpio;
@@ -138,7 +179,8 @@ static int __pmac gpios_set_cpu_speed(unsigned int low_speed)
}
/* Set frequency */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio, low_speed ? 0x04 : 0x05);
+ pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
+ low_speed ? 0x04 : 0x05);
udelay(200);
do {
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -163,7 +205,7 @@ static int __pmac gpios_set_cpu_speed(unsigned int low_speed)
/* Switch CPU speed under PMU control
*/
-static int __pmac pmu_set_cpu_speed(unsigned int low_speed)
+static int __pmac pmu_set_cpu_speed(int low_speed)
{
struct adb_request req;
unsigned long save_l2cr;
@@ -269,12 +311,7 @@ static int __pmac do_set_cpu_speed(int speed_mode)
return 0;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- if (cpufreq_uses_pmu)
- rc = pmu_set_cpu_speed(speed_mode);
- else if (cpufreq_uses_gpios)
- rc = gpios_set_cpu_speed(speed_mode);
- else
- rc = cpu_750fx_cpu_speed(speed_mode);
+ set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
@@ -338,20 +375,137 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
};
+static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
+ "voltage-gpio");
+ struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
+ "frequency-gpio");
+ struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
+ "slewing-done");
+ u32 *value;
+
+ /*
+ * Check to see if it's GPIO driven or PMU only
+ *
+ * The way we extract the GPIO address is slightly hackish, but it
+ * works well enough for now. We need to abstract the whole GPIO
+ * stuff sooner or later anyway
+ */
+
+ if (volt_gpio_np)
+ voltage_gpio = read_gpio(volt_gpio_np);
+ if (freq_gpio_np)
+ frequency_gpio = read_gpio(freq_gpio_np);
+ if (slew_done_gpio_np)
+ slew_done_gpio = read_gpio(slew_done_gpio_np);
+
+ /* If we use the frequency GPIOs, calculate the min/max speeds based
+ * on the bus frequencies
+ */
+ if (frequency_gpio && slew_done_gpio) {
+ int lenp, rc;
+ u32 *freqs, *ratio;
+
+ freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
+ lenp /= sizeof(u32);
+ if (freqs == NULL || lenp != 2) {
+ printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
+ return 1;
+ }
+ ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
+ if (ratio == NULL) {
+ printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
+ return 1;
+ }
+
+ /* Get the min/max bus frequencies */
+ low_freq = min(freqs[0], freqs[1]);
+ hi_freq = max(freqs[0], freqs[1]);
+
+ /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
+ * frequency, it claims it to be around 84Mhz on some models while
+ * it appears to be approx. 101Mhz on all. Let's hack around here...
+ * fortunately, we don't need to be too precise
+ */
+ if (low_freq < 98000000)
+ low_freq = 101000000;
+
+ /* Convert those to CPU core clocks */
+ low_freq = (low_freq * (*ratio)) / 2000;
+ hi_freq = (hi_freq * (*ratio)) / 2000;
+
+ /* Now we get the frequencies, we read the GPIO to see what is out current
+ * speed
+ */
+ rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
+ cur_freq = (rc & 0x01) ? hi_freq : low_freq;
+
+ set_speed_proc = gpios_set_cpu_speed;
+ return 1;
+ }
+
+ /* If we use the PMU, look for the min & max frequencies in the
+ * device-tree
+ */
+ value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ low_freq = (*value) / 1000;
+ /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
+ * here */
+ if (low_freq < 100000)
+ low_freq *= 10;
+
+ value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
+ if (!value)
+ return 1;
+ hi_freq = (*value) / 1000;
+ set_speed_proc = pmu_set_cpu_speed;
+
+ return 0;
+}
+
+static int __pmac pmac_cpufreq_init_7447A(struct device_node *cpunode)
+{
+ struct device_node *volt_gpio_np;
+
+ /* OF only reports the high frequency */
+ hi_freq = cur_freq;
+ low_freq = cur_freq/2;
+ if (mfspr(HID1) & HID1_DFS)
+ cur_freq = low_freq;
+ else
+ cur_freq = hi_freq;
+
+ volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
+ if (!volt_gpio_np){
+ printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
+ return 1;
+ }
+
+ u32 *reg = (u32 *)get_property(volt_gpio_np, "reg", NULL);
+ voltage_gpio = *reg;
+ set_speed_proc = dfs_set_cpu_speed;
+
+ return 0;
+}
+
/* Currently, we support the following machines:
*
* - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
* - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
+ * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
* - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
* - iBook2 500 (PMU based, 400Mhz & 500Mhz)
* - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
- * - Recent MacRISC3 machines
+ * - Recent MacRISC3 laptops
+ * - iBook G4s and PowerBook G4s with 7447A CPUs
*/
static int __init pmac_cpufreq_setup(void)
{
struct device_node *cpunode;
u32 *value;
- int has_freq_ctl = 0;
if (strstr(cmd_line, "nocpufreq"))
return 0;
@@ -367,113 +521,36 @@ static int __init pmac_cpufreq_setup(void)
goto out;
cur_freq = (*value) / 1000;
- /* Check for newer machines */
- if (machine_is_compatible("PowerBook3,4") ||
- machine_is_compatible("PowerBook3,5") ||
- machine_is_compatible("MacRISC3")) {
- struct device_node *volt_gpio_np = of_find_node_by_name(NULL, "voltage-gpio");
- struct device_node *freq_gpio_np = of_find_node_by_name(NULL, "frequency-gpio");
- struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL, "slewing-done");
-
- /*
- * Check to see if it's GPIO driven or PMU only
- *
- * The way we extract the GPIO address is slightly hackish, but it
- * works well enough for now. We need to abstract the whole GPIO
- * stuff sooner or later anyway
- */
-
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
- if (freq_gpio_np)
- frequency_gpio = read_gpio(freq_gpio_np);
- if (slew_done_gpio_np)
- slew_done_gpio = read_gpio(slew_done_gpio_np);
-
- /* If we use the frequency GPIOs, calculate the min/max speeds based
- * on the bus frequencies
- */
- if (frequency_gpio && slew_done_gpio) {
- int lenp, rc;
- u32 *freqs, *ratio;
-
- freqs = (u32 *)get_property(cpunode, "bus-frequencies", &lenp);
- lenp /= sizeof(u32);
- if (freqs == NULL || lenp != 2) {
- printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
- goto out;
- }
- ratio = (u32 *)get_property(cpunode, "processor-to-bus-ratio*2", NULL);
- if (ratio == NULL) {
- printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
- goto out;
- }
-
- /* Get the min/max bus frequencies */
- low_freq = min(freqs[0], freqs[1]);
- hi_freq = max(freqs[0], freqs[1]);
-
- /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
- * frequency, it claims it to be around 84Mhz on some models while
- * it appears to be approx. 101Mhz on all. Let's hack around here...
- * fortunately, we don't need to be too precise
- */
- if (low_freq < 98000000)
- low_freq = 101000000;
-
- /* Convert those to CPU core clocks */
- low_freq = (low_freq * (*ratio)) / 2000;
- hi_freq = (hi_freq * (*ratio)) / 2000;
-
- /* Now we get the frequencies, we read the GPIO to see what is out current
- * speed
- */
- rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
- cur_freq = (rc & 0x01) ? hi_freq : low_freq;
-
- has_freq_ctl = 1;
- cpufreq_uses_gpios = 1;
- goto out;
- }
-
- /* If we use the PMU, look for the min & max frequencies in the
- * device-tree
- */
- value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
- if (!value)
- goto out;
- low_freq = (*value) / 1000;
- /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
- * here */
- if (low_freq < 100000)
- low_freq *= 10;
-
- value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
- if (!value)
- goto out;
- hi_freq = (*value) / 1000;
- has_freq_ctl = 1;
- cpufreq_uses_pmu = 1;
- }
+ /* Check for 7447A based iBook G4 or PowerBook */
+ if (machine_is_compatible("PowerBook6,5") ||
+ machine_is_compatible("PowerBook6,4") ||
+ machine_is_compatible("PowerBook5,5") ||
+ machine_is_compatible("PowerBook5,4")) {
+ pmac_cpufreq_init_7447A(cpunode);
+ /* Check for other MacRISC3 machines */
+ } else if (machine_is_compatible("PowerBook3,4") ||
+ machine_is_compatible("PowerBook3,5") ||
+ machine_is_compatible("MacRISC3")) {
+ pmac_cpufreq_init_MacRISC3(cpunode);
/* Else check for iBook2 500 */
- else if (machine_is_compatible("PowerBook4,1")) {
+ } else if (machine_is_compatible("PowerBook4,1")) {
/* We only know about 500Mhz model */
if (cur_freq < 450000 || cur_freq > 550000)
goto out;
hi_freq = cur_freq;
low_freq = 400000;
- has_freq_ctl = 1;
- cpufreq_uses_pmu = 1;
+ set_speed_proc = pmu_set_cpu_speed;
}
- /* Else check for TiPb 500 */
+ /* Else check for TiPb 400 & 500 */
else if (machine_is_compatible("PowerBook3,2")) {
- /* We only know about 500Mhz model */
- if (cur_freq < 450000 || cur_freq > 550000)
+ /* We only know about the 400 MHz and the 500Mhz model
+ * they both have 300 MHz as low frequency
+ */
+ if (cur_freq < 350000 || cur_freq > 550000)
goto out;
hi_freq = cur_freq;
low_freq = 300000;
- has_freq_ctl = 1;
- cpufreq_uses_pmu = 1;
+ set_speed_proc = pmu_set_cpu_speed;
}
/* Else check for 750FX */
else if (PVR_VER(mfspr(PVR)) == 0x7000) {
@@ -483,21 +560,19 @@ static int __init pmac_cpufreq_setup(void)
value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
if (!value)
goto out;
- low_freq = (*value) / 1000;
- cpufreq_uses_pmu = 0;
- has_freq_ctl = 1;
+ low_freq = (*value) / 1000;
+ set_speed_proc = cpu_750fx_cpu_speed;
}
out:
- if (!has_freq_ctl)
+ if (set_speed_proc == NULL)
return -ENODEV;
pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
- printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz, switch method: %s\n",
- low_freq/1000, hi_freq/1000, cur_freq/1000,
- cpufreq_uses_pmu ? "PMU" : (cpufreq_uses_gpios ? "GPIOs" : "CPU"));
+ printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
+ low_freq/1000, hi_freq/1000, cur_freq/1000);
return cpufreq_register_driver(&pmac_cpufreq_driver);
}
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index abd06fc82a34..35714de243b8 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -1282,6 +1282,25 @@ core99_firewire_cable_power(struct device_node* node, long param, long value)
return 0;
}
+static long __pmac
+intrepid_aack_delay_enable(struct device_node* node, long param, long value)
+{
+ unsigned long flags;
+
+ if (uninorth_rev < 0xd2)
+ return -ENODEV;
+
+ LOCK(flags);
+ if (param)
+ UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
+ else
+ UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
+ UNLOCK(flags);
+
+ return 0;
+}
+
+
#endif /* CONFIG_POWER4 */
static long __pmac
@@ -1914,6 +1933,7 @@ static struct feature_table_entry intrepid_features[] __pmacdata = {
{ PMAC_FTR_SLEEP_STATE, core99_sleep_state },
{ PMAC_FTR_READ_GPIO, core99_read_gpio },
{ PMAC_FTR_WRITE_GPIO, core99_write_gpio },
+ { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable },
{ 0, NULL }
};
@@ -2116,6 +2136,14 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
},
+ { "PowerBook5,4", "PowerBook G4 15\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
+ { "PowerBook5,5", "PowerBook G4 17\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
{ "PowerBook6,1", "PowerBook G4 12\"",
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
@@ -2128,6 +2156,10 @@ static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
},
+ { "PowerBook6,4", "PowerBook G4 12\"",
+ PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
+ PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+ },
{ "PowerBook6,5", "iBook G4",
PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index c36dd89a4e3b..fda27888edd3 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -56,4 +56,6 @@ ifdef CONFIG_SMP
obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o
endif
+obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
+
CFLAGS_ioctl32.o += -Ifs/
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
index 593319735e5e..4de4982f58f3 100644
--- a/arch/ppc64/kernel/traps.c
+++ b/arch/ppc64/kernel/traps.c
@@ -544,9 +544,39 @@ AlignmentException(struct pt_regs *regs)
void
AltivecAssistException(struct pt_regs *regs)
{
+ int err;
+ siginfo_t info;
+
+ if (!user_mode(regs)) {
+ printk(KERN_EMERG "VMX/Altivec assist exception in kernel mode"
+ " at %lx\n", regs->nip);
+ die("Kernel VMX/Altivec assist exception", regs, SIGILL);
+ }
+
flush_altivec_to_thread(current);
- /* XXX quick hack for now: set the non-Java bit in the VSCR */
- current->thread.vscr.u[3] |= 0x10000;
+
+ err = emulate_altivec(regs);
+ if (err == 0) {
+ regs->nip += 4; /* skip emulated instruction */
+ emulate_single_step(regs);
+ return;
+ }
+
+ if (err == -EFAULT) {
+ /* got an error reading the instruction */
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = SEGV_MAPERR;
+ info.si_addr = (void *) regs->nip;
+ force_sig_info(SIGSEGV, &info, current);
+ } else {
+ /* didn't recognize the instruction */
+ /* XXX quick hack for now: set the non-Java bit in the VSCR */
+ if (printk_ratelimit())
+ printk(KERN_ERR "Unrecognized altivec instruction "
+ "in %s at %lx\n", current->comm, regs->nip);
+ current->thread.vscr.u[3] |= 0x10000;
+ }
}
#endif /* CONFIG_ALTIVEC */
diff --git a/arch/ppc64/kernel/vecemu.c b/arch/ppc64/kernel/vecemu.c
new file mode 100644
index 000000000000..1430ef59279c
--- /dev/null
+++ b/arch/ppc64/kernel/vecemu.c
@@ -0,0 +1,346 @@
+/*
+ * Routines to emulate some Altivec/VMX instructions, specifically
+ * those that can trap when given denormalized operands in Java mode.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+/* Functions in vector.S */
+extern void vaddfp(vector128 *dst, vector128 *a, vector128 *b);
+extern void vsubfp(vector128 *dst, vector128 *a, vector128 *b);
+extern void vmaddfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
+extern void vnmsubfp(vector128 *dst, vector128 *a, vector128 *b, vector128 *c);
+extern void vrefp(vector128 *dst, vector128 *src);
+extern void vrsqrtefp(vector128 *dst, vector128 *src);
+extern void vexptep(vector128 *dst, vector128 *src);
+
+static unsigned int exp2s[8] = {
+ 0x800000,
+ 0x8b95c2,
+ 0x9837f0,
+ 0xa5fed7,
+ 0xb504f3,
+ 0xc5672a,
+ 0xd744fd,
+ 0xeac0c7
+};
+
+/*
+ * Computes an estimate of 2^x. The `s' argument is the 32-bit
+ * single-precision floating-point representation of x.
+ */
+static unsigned int eexp2(unsigned int s)
+{
+ int exp, pwr;
+ unsigned int mant, frac;
+
+ /* extract exponent field from input */
+ exp = ((s >> 23) & 0xff) - 127;
+ if (exp > 7) {
+ /* check for NaN input */
+ if (exp == 128 && (s & 0x7fffff) != 0)
+ return s | 0x400000; /* return QNaN */
+ /* 2^-big = 0, 2^+big = +Inf */
+ return (s & 0x80000000)? 0: 0x7f800000; /* 0 or +Inf */
+ }
+ if (exp < -23)
+ return 0x3f800000; /* 1.0 */
+
+ /* convert to fixed point integer in 9.23 representation */
+ pwr = (s & 0x7fffff) | 0x800000;
+ if (exp > 0)
+ pwr <<= exp;
+ else
+ pwr >>= -exp;
+ if (s & 0x80000000)
+ pwr = -pwr;
+
+ /* extract integer part, which becomes exponent part of result */
+ exp = (pwr >> 23) + 126;
+ if (exp >= 254)
+ return 0x7f800000;
+ if (exp < -23)
+ return 0;
+
+ /* table lookup on top 3 bits of fraction to get mantissa */
+ mant = exp2s[(pwr >> 20) & 7];
+
+ /* linear interpolation using remaining 20 bits of fraction */
+ asm("mulhwu %0,%1,%2" : "=r" (frac)
+ : "r" (pwr << 12), "r" (0x172b83ff));
+ asm("mulhwu %0,%1,%2" : "=r" (frac) : "r" (frac), "r" (mant));
+ mant += frac;
+
+ if (exp >= 0)
+ return mant + (exp << 23);
+
+ /* denormalized result */
+ exp = -exp;
+ mant += 1 << (exp - 1);
+ return mant >> exp;
+}
+
+/*
+ * Computes an estimate of log_2(x). The `s' argument is the 32-bit
+ * single-precision floating-point representation of x.
+ */
+static unsigned int elog2(unsigned int s)
+{
+ int exp, mant, lz, frac;
+
+ exp = s & 0x7f800000;
+ mant = s & 0x7fffff;
+ if (exp == 0x7f800000) { /* Inf or NaN */
+ if (mant != 0)
+ s |= 0x400000; /* turn NaN into QNaN */
+ return s;
+ }
+ if ((exp | mant) == 0) /* +0 or -0 */
+ return 0xff800000; /* return -Inf */
+
+ if (exp == 0) {
+ /* denormalized */
+ asm("cntlzw %0,%1" : "=r" (lz) : "r" (mant));
+ mant <<= lz - 8;
+ exp = (-118 - lz) << 23;
+ } else {
+ mant |= 0x800000;
+ exp -= 127 << 23;
+ }
+
+ if (mant >= 0xb504f3) { /* 2^0.5 * 2^23 */
+ exp |= 0x400000; /* 0.5 * 2^23 */
+ asm("mulhwu %0,%1,%2" : "=r" (mant)
+ : "r" (mant), "r" (0xb504f334)); /* 2^-0.5 * 2^32 */
+ }
+ if (mant >= 0x9837f0) { /* 2^0.25 * 2^23 */
+ exp |= 0x200000; /* 0.25 * 2^23 */
+ asm("mulhwu %0,%1,%2" : "=r" (mant)
+ : "r" (mant), "r" (0xd744fccb)); /* 2^-0.25 * 2^32 */
+ }
+ if (mant >= 0x8b95c2) { /* 2^0.125 * 2^23 */
+ exp |= 0x100000; /* 0.125 * 2^23 */
+ asm("mulhwu %0,%1,%2" : "=r" (mant)
+ : "r" (mant), "r" (0xeac0c6e8)); /* 2^-0.125 * 2^32 */
+ }
+ if (mant > 0x800000) { /* 1.0 * 2^23 */
+ /* calculate (mant - 1) * 1.381097463 */
+ /* 1.381097463 == 0.125 / (2^0.125 - 1) */
+ asm("mulhwu %0,%1,%2" : "=r" (frac)
+ : "r" ((mant - 0x800000) << 1), "r" (0xb0c7cd3a));
+ exp += frac;
+ }
+ s = exp & 0x80000000;
+ if (exp != 0) {
+ if (s)
+ exp = -exp;
+ asm("cntlzw %0,%1" : "=r" (lz) : "r" (exp));
+ lz = 8 - lz;
+ if (lz > 0)
+ exp >>= lz;
+ else if (lz < 0)
+ exp <<= -lz;
+ s += ((lz + 126) << 23) + exp;
+ }
+ return s;
+}
+
+#define VSCR_SAT 1
+
+static int ctsxs(unsigned int x, int scale, unsigned int *vscrp)
+{
+ int exp, mant;
+
+ exp = (x >> 23) & 0xff;
+ mant = x & 0x7fffff;
+ if (exp == 255 && mant != 0)
+ return 0; /* NaN -> 0 */
+ exp = exp - 127 + scale;
+ if (exp < 0)
+ return 0; /* round towards zero */
+ if (exp >= 31) {
+ /* saturate, unless the result would be -2^31 */
+ if (x + (scale << 23) != 0xcf000000)
+ *vscrp |= VSCR_SAT;
+ return (x & 0x80000000)? 0x80000000: 0x7fffffff;
+ }
+ mant |= 0x800000;
+ mant = (mant << 7) >> (30 - exp);
+ return (x & 0x80000000)? -mant: mant;
+}
+
+static unsigned int ctuxs(unsigned int x, int scale, unsigned int *vscrp)
+{
+ int exp;
+ unsigned int mant;
+
+ exp = (x >> 23) & 0xff;
+ mant = x & 0x7fffff;
+ if (exp == 255 && mant != 0)
+ return 0; /* NaN -> 0 */
+ exp = exp - 127 + scale;
+ if (exp < 0)
+ return 0; /* round towards zero */
+ if (x & 0x80000000) {
+ /* negative => saturate to 0 */
+ *vscrp |= VSCR_SAT;
+ return 0;
+ }
+ if (exp >= 32) {
+ /* saturate */
+ *vscrp |= VSCR_SAT;
+ return 0xffffffff;
+ }
+ mant |= 0x800000;
+ mant = (mant << 8) >> (31 - exp);
+ return mant;
+}
+
+/* Round to floating integer, towards 0 */
+static unsigned int rfiz(unsigned int x)
+{
+ int exp;
+
+ exp = ((x >> 23) & 0xff) - 127;
+ if (exp == 128 && (x & 0x7fffff) != 0)
+ return x | 0x400000; /* NaN -> make it a QNaN */
+ if (exp >= 23)
+ return x; /* it's an integer already (or Inf) */
+ if (exp < 0)
+ return x & 0x80000000; /* |x| < 1.0 rounds to 0 */
+ return x & ~(0x7fffff >> exp);
+}
+
+/* Round to floating integer, towards +/- Inf */
+static unsigned int rfii(unsigned int x)
+{
+ int exp, mask;
+
+ exp = ((x >> 23) & 0xff) - 127;
+ if (exp == 128 && (x & 0x7fffff) != 0)
+ return x | 0x400000; /* NaN -> make it a QNaN */
+ if (exp >= 23)
+ return x; /* it's an integer already (or Inf) */
+ if ((x & 0x7fffffff) == 0)
+ return x; /* +/-0 -> +/-0 */
+ if (exp < 0)
+ /* 0 < |x| < 1.0 rounds to +/- 1.0 */
+ return (x & 0x80000000) | 0x3f800000;
+ mask = 0x7fffff >> exp;
+ /* mantissa overflows into exponent - that's OK,
+ it can't overflow into the sign bit */
+ return (x + mask) & ~mask;
+}
+
+/* Round to floating integer, to nearest */
+static unsigned int rfin(unsigned int x)
+{
+ int exp, half;
+
+ exp = ((x >> 23) & 0xff) - 127;
+ if (exp == 128 && (x & 0x7fffff) != 0)
+ return x | 0x400000; /* NaN -> make it a QNaN */
+ if (exp >= 23)
+ return x; /* it's an integer already (or Inf) */
+ if (exp < -1)
+ return x & 0x80000000; /* |x| < 0.5 -> +/-0 */
+ if (exp == -1)
+ /* 0.5 <= |x| < 1.0 rounds to +/- 1.0 */
+ return (x & 0x80000000) | 0x3f800000;
+ half = 0x400000 >> exp;
+ /* add 0.5 to the magnitude and chop off the fraction bits */
+ return (x + half) & ~(0x7fffff >> exp);
+}
+
+int
+emulate_altivec(struct pt_regs *regs)
+{
+ unsigned int instr, i;
+ unsigned int va, vb, vc, vd;
+ vector128 *vrs;
+
+ if (get_user(instr, (unsigned int *) regs->nip))
+ return -EFAULT;
+ if ((instr >> 26) != 4)
+ return -EINVAL; /* not an altivec instruction */
+ vd = (instr >> 21) & 0x1f;
+ va = (instr >> 16) & 0x1f;
+ vb = (instr >> 11) & 0x1f;
+ vc = (instr >> 6) & 0x1f;
+
+ vrs = current->thread.vr;
+ switch (instr & 0x3f) {
+ case 10:
+ switch (vc) {
+ case 0: /* vaddfp */
+ vaddfp(&vrs[vd], &vrs[va], &vrs[vb]);
+ break;
+ case 1: /* vsubfp */
+ vsubfp(&vrs[vd], &vrs[va], &vrs[vb]);
+ break;
+ case 4: /* vrefp */
+ vrefp(&vrs[vd], &vrs[vb]);
+ break;
+ case 5: /* vrsqrtefp */
+ vrsqrtefp(&vrs[vd], &vrs[vb]);
+ break;
+ case 6: /* vexptefp */
+ for (i = 0; i < 4; ++i)
+ vrs[vd].u[i] = eexp2(vrs[vb].u[i]);
+ break;
+ case 7: /* vlogefp */
+ for (i = 0; i < 4; ++i)
+ vrs[vd].u[i] = elog2(vrs[vb].u[i]);
+ break;
+ case 8: /* vrfin */
+ for (i = 0; i < 4; ++i)
+ vrs[vd].u[i] = rfin(vrs[vb].u[i]);
+ break;
+ case 9: /* vrfiz */
+ for (i = 0; i < 4; ++i)
+ vrs[vd].u[i] = rfiz(vrs[vb].u[i]);
+ break;
+ case 10: /* vrfip */
+ for (i = 0; i < 4; ++i) {
+ u32 x = vrs[vb].u[i];
+ x = (x & 0x80000000)? rfiz(x): rfii(x);
+ vrs[vd].u[i] = x;
+ }
+ break;
+ case 11: /* vrfim */
+ for (i = 0; i < 4; ++i) {
+ u32 x = vrs[vb].u[i];
+ x = (x & 0x80000000)? rfii(x): rfiz(x);
+ vrs[vd].u[i] = x;
+ }
+ break;
+ case 14: /* vctuxs */
+ for (i = 0; i < 4; ++i)
+ vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
+ &current->thread.vscr.u[3]);
+ break;
+ case 15: /* vctsxs */
+ for (i = 0; i < 4; ++i)
+ vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
+ &current->thread.vscr.u[3]);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case 46: /* vmaddfp */
+ vmaddfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
+ break;
+ case 47: /* vnmsubfp */
+ vnmsubfp(&vrs[vd], &vrs[va], &vrs[vb], &vrs[vc]);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/arch/ppc64/kernel/vector.S b/arch/ppc64/kernel/vector.S
new file mode 100644
index 000000000000..940cd7287346
--- /dev/null
+++ b/arch/ppc64/kernel/vector.S
@@ -0,0 +1,172 @@
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+/*
+ * The routines below are in assembler so we can closely control the
+ * usage of floating-point registers. These routines must be called
+ * with preempt disabled.
+ */
+ .section ".toc","aw"
+fpzero:
+ .tc FD_0_0[TC],0
+fpone:
+ .tc FD_3ff00000_0[TC],0x3ff0000000000000 /* 1.0 */
+fphalf:
+ .tc FD_3fe00000_0[TC],0x3fe0000000000000 /* 0.5 */
+
+ .text
+/*
+ * Internal routine to enable floating point and set FPSCR to 0.
+ * Don't call it from C; it doesn't use the normal calling convention.
+ */
+fpenable:
+ mfmsr r10
+ ori r11,r10,MSR_FP
+ mtmsr r11
+ isync
+ stfd fr31,-8(r1)
+ stfd fr0,-16(r1)
+ stfd fr1,-24(r1)
+ mffs fr31
+ lfd fr1,fpzero@toc(r2)
+ mtfsf 0xff,fr1
+ blr
+
+fpdisable:
+ mtlr r12
+ mtfsf 0xff,fr31
+ lfd fr1,-24(r1)
+ lfd fr0,-16(r1)
+ lfd fr31,-8(r1)
+ mtmsr r10
+ isync
+ blr
+
+/*
+ * Vector add, floating point.
+ */
+_GLOBAL(vaddfp)
+ mflr r12
+ bl fpenable
+ li r0,4
+ mtctr r0
+ li r6,0
+1: lfsx fr0,r4,r6
+ lfsx fr1,r5,r6
+ fadds fr0,fr0,fr1
+ stfsx fr0,r3,r6
+ addi r6,r6,4
+ bdnz 1b
+ b fpdisable
+
+/*
+ * Vector subtract, floating point.
+ */
+_GLOBAL(vsubfp)
+ mflr r12
+ bl fpenable
+ li r0,4
+ mtctr r0
+ li r6,0
+1: lfsx fr0,r4,r6
+ lfsx fr1,r5,r6
+ fsubs fr0,fr0,fr1
+ stfsx fr0,r3,r6
+ addi r6,r6,4
+ bdnz 1b
+ b fpdisable
+
+/*
+ * Vector multiply and add, floating point.
+ */
+_GLOBAL(vmaddfp)
+ mflr r12
+ bl fpenable
+ stfd fr2,-32(r1)
+ li r0,4
+ mtctr r0
+ li r7,0
+1: lfsx fr0,r4,r7
+ lfsx fr1,r5,r7
+ lfsx fr2,r6,r7
+ fmadds fr0,fr0,fr1,fr2
+ stfsx fr0,r3,r7
+ addi r7,r7,4
+ bdnz 1b
+ lfd fr2,-32(r1)
+ b fpdisable
+
+/*
+ * Vector negative multiply and subtract, floating point.
+ */
+_GLOBAL(vnmsubfp)
+ mflr r12
+ bl fpenable
+ stfd fr2,-32(r1)
+ li r0,4
+ mtctr r0
+ li r7,0
+1: lfsx fr0,r4,r7
+ lfsx fr1,r5,r7
+ lfsx fr2,r6,r7
+ fnmsubs fr0,fr0,fr1,fr2
+ stfsx fr0,r3,r7
+ addi r7,r7,4
+ bdnz 1b
+ lfd fr2,-32(r1)
+ b fpdisable
+
+/*
+ * Vector reciprocal estimate. We just compute 1.0/x.
+ * r3 -> destination, r4 -> source.
+ */
+_GLOBAL(vrefp)
+ mflr r12
+ bl fpenable
+ li r0,4
+ lfd fr1,fpone@toc(r2)
+ mtctr r0
+ li r6,0
+1: lfsx fr0,r4,r6
+ fdivs fr0,fr1,fr0
+ stfsx fr0,r3,r6
+ addi r6,r6,4
+ bdnz 1b
+ b fpdisable
+
+/*
+ * Vector reciprocal square-root estimate, floating point.
+ * We use the frsqrte instruction for the initial estimate followed
+ * by 2 iterations of Newton-Raphson to get sufficient accuracy.
+ * r3 -> destination, r4 -> source.
+ */
+_GLOBAL(vrsqrtefp)
+ mflr r12
+ bl fpenable
+ stfd fr2,-32(r1)
+ stfd fr3,-40(r1)
+ stfd fr4,-48(r1)
+ stfd fr5,-56(r1)
+ li r0,4
+ lfd fr4,fpone@toc(r2)
+ lfd fr5,fphalf@toc(r2)
+ mtctr r0
+ li r6,0
+1: lfsx fr0,r4,r6
+ frsqrte fr1,fr0 /* r = frsqrte(s) */
+ fmuls fr3,fr1,fr0 /* r * s */
+ fmuls fr2,fr1,fr5 /* r * 0.5 */
+ fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */
+ fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */
+ fmuls fr3,fr1,fr0 /* r * s */
+ fmuls fr2,fr1,fr5 /* r * 0.5 */
+ fnmsubs fr3,fr1,fr3,fr4 /* 1 - s * r * r */
+ fmadds fr1,fr2,fr3,fr1 /* r = r + 0.5 * r * (1 - s * r * r) */
+ stfsx fr1,r3,r6
+ addi r6,r6,4
+ bdnz 1b
+ lfd fr5,-56(r1)
+ lfd fr4,-48(r1)
+ lfd fr3,-40(r1)
+ lfd fr2,-32(r1)
+ b fpdisable
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index c43bb7bb23a3..c5b647febac4 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -859,16 +859,22 @@ void __init mp_config_acpi_legacy_irqs (void)
for (i = 0; i < 16; i++) {
int idx;
- for (idx = 0; idx < mp_irq_entries; idx++)
- if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
- (mp_irqs[idx].mpc_dstapic == ioapic) &&
- (mp_irqs[idx].mpc_srcbusirq == i ||
- mp_irqs[idx].mpc_dstirq == i))
- break;
+ for (idx = 0; idx < mp_irq_entries; idx++) {
+ struct mpc_config_intsrc *irq = mp_irqs + idx;
+
+ /* Do we already have a mapping for this ISA IRQ? */
+ if (irq->mpc_srcbus == MP_ISA_BUS && irq->mpc_srcbusirq == i)
+ break;
+
+ /* Do we already have a mapping for this IOAPIC pin */
+ if ((irq->mpc_dstapic == intsrc.mpc_dstapic) &&
+ (irq->mpc_dstirq == i))
+ break;
+ }
if (idx != mp_irq_entries) {
printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i);
- continue; /* IRQ already used */
+ continue; /* IRQ already used */
}
intsrc.mpc_irqtype = mp_INT;
diff --git a/drivers/base/base.h b/drivers/base/base.h
index da16cc5c9e30..8d1e8bd48632 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -6,12 +6,13 @@ extern void bus_remove_driver(struct device_driver *);
static inline struct class_device *to_class_dev(struct kobject *obj)
{
- return container_of(obj,struct class_device,kobj);
+ return container_of(obj, struct class_device, kobj);
}
+
static inline
struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
{
- return container_of(_attr,struct class_device_attribute,attr);
+ return container_of(_attr, struct class_device_attribute, attr);
}
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index b40af6a72afe..02ff97df6dee 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -17,17 +17,17 @@
#include "base.h"
#include "power/power.h"
-#define to_dev(node) container_of(node,struct device,bus_list)
-#define to_drv(node) container_of(node,struct device_driver,kobj.entry)
+#define to_dev(node) container_of(node, struct device, bus_list)
+#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
-#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
-#define to_bus(obj) container_of(obj,struct bus_type,subsys.kset.kobj)
+#define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
+#define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
/*
* sysfs bindings for drivers
*/
-#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
+#define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr)
#define to_driver(obj) container_of(obj, struct device_driver, kobj)
@@ -39,12 +39,12 @@ drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (drv_attr->show)
- ret = drv_attr->show(drv,buf);
+ ret = drv_attr->show(drv, buf);
return ret;
}
static ssize_t
-drv_attr_store(struct kobject * kobj, struct attribute * attr,
+drv_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct driver_attribute * drv_attr = to_drv_attr(attr);
@@ -52,7 +52,7 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (drv_attr->store)
- ret = drv_attr->store(drv,buf,count);
+ ret = drv_attr->store(drv, buf, count);
return ret;
}
@@ -87,12 +87,12 @@ bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (bus_attr->show)
- ret = bus_attr->show(bus,buf);
+ ret = bus_attr->show(bus, buf);
return ret;
}
static ssize_t
-bus_attr_store(struct kobject * kobj, struct attribute * attr,
+bus_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct bus_attribute * bus_attr = to_bus_attr(attr);
@@ -100,7 +100,7 @@ bus_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (bus_attr->store)
- ret = bus_attr->store(bus,buf,count);
+ ret = bus_attr->store(bus, buf, count);
return ret;
}
@@ -113,7 +113,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{
int error;
if (get_bus(bus)) {
- error = sysfs_create_file(&bus->subsys.kset.kobj,&attr->attr);
+ error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr);
put_bus(bus);
} else
error = -EINVAL;
@@ -123,7 +123,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{
if (get_bus(bus)) {
- sysfs_remove_file(&bus->subsys.kset.kobj,&attr->attr);
+ sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr);
put_bus(bus);
}
}
@@ -133,7 +133,7 @@ static struct kobj_type ktype_bus = {
};
-decl_subsys(bus,&ktype_bus,NULL);
+decl_subsys(bus, &ktype_bus, NULL);
/**
* bus_for_each_dev - device iterator.
@@ -151,10 +151,10 @@ decl_subsys(bus,&ktype_bus,NULL);
*
* NOTE: The device that returns a non-zero value is not retained
* in any way, nor is its refcount incremented. If the caller needs
- * to retain this data, it should do, and increment the reference
+ * to retain this data, it should do, and increment the reference
* count in the supplied callback.
*/
-int bus_for_each_dev(struct bus_type * bus, struct device * start,
+int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *))
{
struct device *dev;
@@ -170,7 +170,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
down_read(&bus->subsys.rwsem);
list_for_each_entry_continue(dev, head, bus_list) {
get_device(dev);
- error = fn(dev,data);
+ error = fn(dev, data);
put_device(dev);
if (error)
break;
@@ -193,7 +193,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
* and return it. If @start is not NULL, we use it as the head
* of the list.
*
- * NOTE: we don't return the driver that returns a non-zero
+ * NOTE: we don't return the driver that returns a non-zero
* value, nor do we leave the reference count incremented for that
* driver. If the caller needs to know that info, it must set it
* in the callback. It must also be sure to increment the refcount
@@ -216,7 +216,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
down_read(&bus->subsys.rwsem);
list_for_each_entry_continue(drv, head, kobj.entry) {
get_driver(drv);
- error = fn(drv,data);
+ error = fn(drv, data);
put_driver(drv);
if(error)
break;
@@ -233,8 +233,8 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
* Allow manual attachment of a driver to a deivce.
* Caller must have already set @dev->driver.
*
- * Note that this does not modify the bus reference count
- * nor take the bus's rwsem. Please verify those are accounted
+ * Note that this does not modify the bus reference count
+ * nor take the bus's rwsem. Please verify those are accounted
* for before calling this. (It is ok to call with no other effort
* from a driver's probe() method.)
*/
@@ -242,9 +242,9 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void device_bind_driver(struct device * dev)
{
pr_debug("bound device '%s' to driver '%s'\n",
- dev->bus_id,dev->driver->name);
- list_add_tail(&dev->driver_list,&dev->driver->devices);
- sysfs_create_link(&dev->driver->kobj,&dev->kobj,
+ dev->bus_id, dev->driver->name);
+ list_add_tail(&dev->driver_list, &dev->driver->devices);
+ sysfs_create_link(&dev->driver->kobj, &dev->kobj,
kobject_name(&dev->kobj));
}
@@ -255,18 +255,18 @@ void device_bind_driver(struct device * dev)
* @drv: driver.
*
* First, we call the bus's match function, which should compare
- * the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know
+ * the device IDs the driver supports with the device IDs of the
+ * device. Note we don't do this ourselves because we don't know
* the format of the ID structures, nor what is to be considered
* a match and what is not.
- *
- * If we find a match, we call @drv->probe(@dev) if it exists, and
+ *
+ * If we find a match, we call @drv->probe(@dev) if it exists, and
* call attach() above.
*/
static int bus_match(struct device * dev, struct device_driver * drv)
{
int error = -ENODEV;
- if (dev->bus->match(dev,drv)) {
+ if (dev->bus->match(dev, drv)) {
dev->driver = drv;
if (drv->probe) {
if ((error = drv->probe(dev))) {
@@ -285,7 +285,7 @@ static int bus_match(struct device * dev, struct device_driver * drv)
* device_attach - try to attach device to a driver.
* @dev: device.
*
- * Walk the list of drivers that the bus has and call bus_match()
+ * Walk the list of drivers that the bus has and call bus_match()
* for each pair. If a compatible pair is found, break out and return.
*/
static int device_attach(struct device * dev)
@@ -300,15 +300,15 @@ static int device_attach(struct device * dev)
}
if (bus->match) {
- list_for_each(entry,&bus->drivers.list) {
+ list_for_each(entry, &bus->drivers.list) {
struct device_driver * drv = to_drv(entry);
- error = bus_match(dev,drv);
- if (!error )
+ error = bus_match(dev, drv);
+ if (!error)
/* success, driver matched */
- return 1;
- if (error != -ENODEV)
+ return 1;
+ if (error != -ENODEV)
/* driver matched but the probe failed */
- printk(KERN_WARNING
+ printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, error);
}
@@ -327,7 +327,7 @@ static int device_attach(struct device * dev)
* If bus_match() returns 0 and the @dev->driver is set, we've found
* a compatible pair.
*
- * Note that we ignore the -ENODEV error from bus_match(), since it's
+ * Note that we ignore the -ENODEV error from bus_match(), since it's
* perfectly valid for a driver not to bind to any devices.
*/
void driver_attach(struct device_driver * drv)
@@ -339,13 +339,13 @@ void driver_attach(struct device_driver * drv)
if (!bus->match)
return;
- list_for_each(entry,&bus->devices.list) {
- struct device * dev = container_of(entry,struct device,bus_list);
+ list_for_each(entry, &bus->devices.list) {
+ struct device * dev = container_of(entry, struct device, bus_list);
if (!dev->driver) {
- error = bus_match(dev,drv);
+ error = bus_match(dev, drv);
if (error && (error != -ENODEV))
/* driver matched but the probe failed */
- printk(KERN_WARNING
+ printk(KERN_WARNING
"%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, error);
}
@@ -367,7 +367,7 @@ void device_release_driver(struct device * dev)
{
struct device_driver * drv = dev->driver;
if (drv) {
- sysfs_remove_link(&drv->kobj,kobject_name(&dev->kobj));
+ sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
list_del_init(&dev->driver_list);
device_detach_shutdown(dev);
if (drv->remove)
@@ -385,13 +385,44 @@ void device_release_driver(struct device * dev)
static void driver_detach(struct device_driver * drv)
{
struct list_head * entry, * next;
- list_for_each_safe(entry,next,&drv->devices) {
- struct device * dev = container_of(entry,struct device,driver_list);
+ list_for_each_safe(entry, next, &drv->devices) {
+ struct device * dev = container_of(entry, struct device, driver_list);
device_release_driver(dev);
}
+}
+
+static int device_add_attrs(struct bus_type * bus, struct device * dev)
+{
+ int error = 0;
+ int i;
+
+ if (bus->dev_attrs) {
+ for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
+ error = device_create_file(dev,&bus->dev_attrs[i]);
+ if (error)
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ device_remove_file(dev,&bus->dev_attrs[i]);
+ goto Done;
+}
+
+
+static void device_remove_attrs(struct bus_type * bus, struct device * dev)
+{
+ int i;
+ if (bus->dev_attrs) {
+ for (i = 0; attr_name(bus->dev_attrs[i]); i++)
+ device_remove_file(dev,&bus->dev_attrs[i]);
+ }
}
+
/**
* bus_add_device - add device to bus
* @dev: device being added
@@ -407,11 +438,12 @@ int bus_add_device(struct device * dev)
if (bus) {
down_write(&dev->bus->subsys.rwsem);
- pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id);
- list_add_tail(&dev->bus_list,&dev->bus->devices.list);
+ pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
+ list_add_tail(&dev->bus_list, &dev->bus->devices.list);
device_attach(dev);
up_write(&dev->bus->subsys.rwsem);
- sysfs_create_link(&bus->devices.kobj,&dev->kobj,dev->bus_id);
+ device_add_attrs(bus, dev);
+ sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
}
return error;
}
@@ -428,9 +460,10 @@ int bus_add_device(struct device * dev)
void bus_remove_device(struct device * dev)
{
if (dev->bus) {
- sysfs_remove_link(&dev->bus->devices.kobj,dev->bus_id);
+ sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
+ device_remove_attrs(dev->bus, dev);
down_write(&dev->bus->subsys.rwsem);
- pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id);
+ pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
device_release_driver(dev);
list_del_init(&dev->bus_list);
up_write(&dev->bus->subsys.rwsem);
@@ -450,8 +483,8 @@ int bus_add_driver(struct device_driver * drv)
int error = 0;
if (bus) {
- pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
- error = kobject_set_name(&drv->kobj,drv->name);
+ pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
+ error = kobject_set_name(&drv->kobj, drv->name);
if (error) {
put_bus(bus);
return error;
@@ -484,7 +517,7 @@ void bus_remove_driver(struct device_driver * drv)
{
if (drv->bus) {
down_write(&drv->bus->subsys.rwsem);
- pr_debug("bus %s: remove driver %s\n",drv->bus->name,drv->name);
+ pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
driver_detach(drv);
up_write(&drv->bus->subsys.rwsem);
kobject_unregister(&drv->kobj);
@@ -526,7 +559,7 @@ int bus_rescan_devices(struct bus_type * bus)
struct bus_type * get_bus(struct bus_type * bus)
{
- return bus ? container_of(subsys_get(&bus->subsys),struct bus_type,subsys) : NULL;
+ return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL;
}
void put_bus(struct bus_type * bus)
@@ -545,29 +578,64 @@ void put_bus(struct bus_type * bus)
struct bus_type * find_bus(char * name)
{
- struct kobject * k = kset_find_obj(&bus_subsys.kset,name);
+ struct kobject * k = kset_find_obj(&bus_subsys.kset, name);
return k ? to_bus(k) : NULL;
}
+
+/**
+ * bus_add_attrs - Add default attributes for this bus.
+ * @bus: Bus that has just been registered.
+ */
+
+static int bus_add_attrs(struct bus_type * bus)
+{
+ int error = 0;
+ int i;
+
+ if (bus->bus_attrs) {
+ for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
+ if ((error = bus_create_file(bus,&bus->bus_attrs[i])))
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ bus_remove_file(bus,&bus->bus_attrs[i]);
+ goto Done;
+}
+
+static void bus_remove_attrs(struct bus_type * bus)
+{
+ int i;
+
+ if (bus->bus_attrs) {
+ for (i = 0; attr_name(bus->bus_attrs[i]); i++)
+ bus_remove_file(bus,&bus->bus_attrs[i]);
+ }
+}
+
/**
* bus_register - register a bus with the system.
* @bus: bus.
*
* Once we have that, we registered the bus with the kobject
* infrastructure, then register the children subsystems it has:
- * the devices and drivers that belong to the bus.
+ * the devices and drivers that belong to the bus.
*/
int bus_register(struct bus_type * bus)
{
int retval;
- retval = kobject_set_name(&bus->subsys.kset.kobj,bus->name);
+ retval = kobject_set_name(&bus->subsys.kset.kobj, bus->name);
if (retval)
goto out;
- subsys_set_kset(bus,bus_subsys);
+ subsys_set_kset(bus, bus_subsys);
retval = subsystem_register(&bus->subsys);
- if (retval)
+ if (retval)
goto out;
kobject_set_name(&bus->devices.kobj, "devices");
@@ -582,8 +650,9 @@ int bus_register(struct bus_type * bus)
retval = kset_register(&bus->drivers);
if (retval)
goto bus_drivers_fail;
+ bus_add_attrs(bus);
- pr_debug("bus type '%s' registered\n",bus->name);
+ pr_debug("bus type '%s' registered\n", bus->name);
return 0;
bus_drivers_fail:
@@ -596,7 +665,7 @@ out:
/**
- * bus_unregister - remove a bus from the system
+ * bus_unregister - remove a bus from the system
* @bus: bus.
*
* Unregister the child subsystems and the bus itself.
@@ -604,7 +673,8 @@ out:
*/
void bus_unregister(struct bus_type * bus)
{
- pr_debug("bus %s: unregistering\n",bus->name);
+ pr_debug("bus %s: unregistering\n", bus->name);
+ bus_remove_attrs(bus);
kset_unregister(&bus->drivers);
kset_unregister(&bus->devices);
subsystem_unregister(&bus->subsys);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index ed13d9de0d1d..2693bb5455f4 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -5,7 +5,7 @@
* Copyright (c) 2002-3 Open Source Development Labs
* Copyright (c) 2003-2004 Greg Kroah-Hartman
* Copyright (c) 2003-2004 IBM Corp.
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -17,8 +17,8 @@
#include <linux/string.h>
#include "base.h"
-#define to_class_attr(_attr) container_of(_attr,struct class_attribute,attr)
-#define to_class(obj) container_of(obj,struct class,subsys.kset.kobj)
+#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
+#define to_class(obj) container_of(obj, struct class, subsys.kset.kobj)
static ssize_t
class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
@@ -28,12 +28,12 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (class_attr->show)
- ret = class_attr->show(dc,buf);
+ ret = class_attr->show(dc, buf);
return ret;
}
static ssize_t
-class_attr_store(struct kobject * kobj, struct attribute * attr,
+class_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct class_attribute * class_attr = to_class_attr(attr);
@@ -41,7 +41,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (class_attr->store)
- ret = class_attr->store(dc,buf,count);
+ ret = class_attr->store(dc, buf, count);
return ret;
}
@@ -69,14 +69,14 @@ static struct kobj_type ktype_class = {
};
/* Hotplug events for classes go to the class_obj subsys */
-static decl_subsys(class,&ktype_class,NULL);
+static decl_subsys(class, &ktype_class, NULL);
int class_create_file(struct class * cls, const struct class_attribute * attr)
{
int error;
if (cls) {
- error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
+ error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr);
} else
error = -EINVAL;
return error;
@@ -85,13 +85,13 @@ int class_create_file(struct class * cls, const struct class_attribute * attr)
void class_remove_file(struct class * cls, const struct class_attribute * attr)
{
if (cls)
- sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
+ sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr);
}
struct class * class_get(struct class * cls)
{
if (cls)
- return container_of(subsys_get(&cls->subsys),struct class,subsys);
+ return container_of(subsys_get(&cls->subsys), struct class, subsys);
return NULL;
}
@@ -100,33 +100,67 @@ void class_put(struct class * cls)
subsys_put(&cls->subsys);
}
+
+static int add_class_attrs(struct class * cls)
+{
+ int i;
+ int error = 0;
+
+ if (cls->class_attrs) {
+ for (i = 0; attr_name(cls->class_attrs[i]); i++) {
+ error = class_create_file(cls,&cls->class_attrs[i]);
+ if (error)
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ class_remove_file(cls,&cls->class_attrs[i]);
+ goto Done;
+}
+
+static void remove_class_attrs(struct class * cls)
+{
+ int i;
+
+ if (cls->class_attrs) {
+ for (i = 0; attr_name(cls->class_attrs[i]); i++)
+ class_remove_file(cls,&cls->class_attrs[i]);
+ }
+}
+
int class_register(struct class * cls)
{
int error;
- pr_debug("device class '%s': registering\n",cls->name);
+ pr_debug("device class '%s': registering\n", cls->name);
INIT_LIST_HEAD(&cls->children);
INIT_LIST_HEAD(&cls->interfaces);
- error = kobject_set_name(&cls->subsys.kset.kobj,cls->name);
+ error = kobject_set_name(&cls->subsys.kset.kobj, cls->name);
if (error)
return error;
- subsys_set_kset(cls,class_subsys);
+ subsys_set_kset(cls, class_subsys);
error = subsystem_register(&cls->subsys);
- if (error)
- return error;
-
- return 0;
+ if (!error) {
+ error = add_class_attrs(class_get(cls));
+ class_put(cls);
+ }
+ return error;
}
void class_unregister(struct class * cls)
{
- pr_debug("device class '%s': unregistering\n",cls->name);
+ pr_debug("device class '%s': unregistering\n", cls->name);
+ remove_class_attrs(cls);
subsystem_unregister(&cls->subsys);
}
+
/* Class Device Stuff */
int class_device_create_file(struct class_device * class_dev,
@@ -181,12 +215,12 @@ class_device_attr_show(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (class_dev_attr->show)
- ret = class_dev_attr->show(cd,buf);
+ ret = class_dev_attr->show(cd, buf);
return ret;
}
static ssize_t
-class_device_attr_store(struct kobject * kobj, struct attribute * attr,
+class_device_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
@@ -194,7 +228,7 @@ class_device_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (class_dev_attr->store)
- ret = class_dev_attr->store(cd,buf,count);
+ ret = class_dev_attr->store(cd, buf, count);
return ret;
}
@@ -208,7 +242,7 @@ static void class_dev_release(struct kobject * kobj)
struct class_device *cd = to_class_dev(kobj);
struct class * cls = cd->class;
- pr_debug("device class '%s': release.\n",cd->class_id);
+ pr_debug("device class '%s': release.\n", cd->class_id);
if (cls->release)
cls->release(cd);
@@ -272,6 +306,40 @@ static struct kset_hotplug_ops class_hotplug_ops = {
static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
+
+static int class_device_add_attrs(struct class_device * cd)
+{
+ int i;
+ int error = 0;
+ struct class * cls = cd->class;
+
+ if (cls->class_dev_attrs) {
+ for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
+ error = class_device_create_file(cd,
+ &cls->class_dev_attrs[i]);
+ if (error)
+ goto Err;
+ }
+ }
+ Done:
+ return error;
+ Err:
+ while (--i >= 0)
+ class_device_remove_file(cd,&cls->class_dev_attrs[i]);
+ goto Done;
+}
+
+static void class_device_remove_attrs(struct class_device * cd)
+{
+ int i;
+ struct class * cls = cd->class;
+
+ if (cls->class_dev_attrs) {
+ for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
+ class_device_remove_file(cd,&cls->class_dev_attrs[i]);
+ }
+}
+
void class_device_initialize(struct class_device *class_dev)
{
kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -311,7 +379,7 @@ int class_device_add(struct class_device *class_dev)
class_intf->add(class_dev);
up_write(&parent->subsys.rwsem);
}
-
+ class_device_add_attrs(class_dev);
class_device_dev_link(class_dev);
class_device_driver_link(class_dev);
@@ -344,7 +412,8 @@ void class_device_del(struct class_device *class_dev)
class_device_dev_unlink(class_dev);
class_device_driver_unlink(class_dev);
-
+ class_device_remove_attrs(class_dev);
+
kobject_del(&class_dev->kobj);
if (parent)
diff --git a/drivers/base/class_simple.c b/drivers/base/class_simple.c
index 20707be0dcd7..3410636de0a5 100644
--- a/drivers/base/class_simple.c
+++ b/drivers/base/class_simple.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2003-2004 IBM Corp.
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(class_simple_destroy);
/**
* class_simple_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct class_simple that this device should be registered to.
+ * @cs: pointer to the struct class_simple that this device should be registered to.
* @dev: the dev_t for the device to be added.
* @device: a pointer to a struct device that is assiociated with this class device.
* @fmt: string for the class device's name
@@ -146,8 +146,8 @@ struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev,
s_dev->dev = dev;
s_dev->class_dev.dev = device;
s_dev->class_dev.class = &cs->class;
-
- va_start(args,fmt);
+
+ va_start(args, fmt);
vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
va_end(args);
retval = class_device_register(&s_dev->class_dev);
@@ -173,10 +173,10 @@ EXPORT_SYMBOL(class_simple_device_add);
* @cs: pointer to the struct class_simple to hold the pointer
* @hotplug: function pointer to the hotplug function
*
- * Implement and set a hotplug function to add environment variables specific to this
+ * Implement and set a hotplug function to add environment variables specific to this
* class on the hotplug event.
*/
-int class_simple_set_hotplug(struct class_simple *cs,
+int class_simple_set_hotplug(struct class_simple *cs,
int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size))
{
if ((cs == NULL) || (IS_ERR(cs)))
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0eaa2c003e69..3325810c42ab 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -28,8 +28,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
* sysfs bindings for devices.
*/
-#define to_dev(obj) container_of(obj,struct device,kobj)
-#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
+#define to_dev(obj) container_of(obj, struct device, kobj)
+#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
extern struct attribute * dev_default_attrs[];
@@ -41,12 +41,12 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;
if (dev_attr->show)
- ret = dev_attr->show(dev,buf);
+ ret = dev_attr->show(dev, buf);
return ret;
}
static ssize_t
-dev_attr_store(struct kobject * kobj, struct attribute * attr,
+dev_attr_store(struct kobject * kobj, struct attribute * attr,
const char * buf, size_t count)
{
struct device_attribute * dev_attr = to_dev_attr(attr);
@@ -54,7 +54,7 @@ dev_attr_store(struct kobject * kobj, struct attribute * attr,
ssize_t ret = 0;
if (dev_attr->store)
- ret = dev_attr->store(dev,buf,count);
+ ret = dev_attr->store(dev, buf, count);
return ret;
}
@@ -153,7 +153,7 @@ int device_create_file(struct device * dev, struct device_attribute * attr)
{
int error = 0;
if (get_device(dev)) {
- error = sysfs_create_file(&dev->kobj,&attr->attr);
+ error = sysfs_create_file(&dev->kobj, &attr->attr);
put_device(dev);
}
return error;
@@ -168,7 +168,7 @@ int device_create_file(struct device * dev, struct device_attribute * attr)
void device_remove_file(struct device * dev, struct device_attribute * attr)
{
if (get_device(dev)) {
- sysfs_remove_file(&dev->kobj,&attr->attr);
+ sysfs_remove_file(&dev->kobj, &attr->attr);
put_device(dev);
}
}
@@ -179,7 +179,7 @@ void device_remove_file(struct device * dev, struct device_attribute * attr)
* @dev: device.
*
* This prepares the device for use by other layers,
- * including adding it to the device hierarchy.
+ * including adding it to the device hierarchy.
* It is the first half of device_register(), if called by
* that, though it can also be called separately, so one
* may use @dev's fields (e.g. the refcount).
@@ -187,7 +187,7 @@ void device_remove_file(struct device * dev, struct device_attribute * attr)
void device_initialize(struct device *dev)
{
- kobj_set_kset_s(dev,devices_subsys);
+ kobj_set_kset_s(dev, devices_subsys);
kobject_init(&dev->kobj);
INIT_LIST_HEAD(&dev->node);
INIT_LIST_HEAD(&dev->children);
@@ -200,7 +200,7 @@ void device_initialize(struct device *dev)
* device_add - add device to device hierarchy.
* @dev: device.
*
- * This is part 2 of device_register(), though may be called
+ * This is part 2 of device_register(), though may be called
* separately _iff_ device_initialize() has been called separately.
*
* This adds it to the kobject hierarchy via kobject_add(), adds it
@@ -221,7 +221,7 @@ int device_add(struct device *dev)
pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id);
/* first, register with generic layer. */
- kobject_set_name(&dev->kobj,dev->bus_id);
+ kobject_set_name(&dev->kobj, dev->bus_id);
if (parent)
dev->kobj.parent = &parent->kobj;
@@ -233,7 +233,7 @@ int device_add(struct device *dev)
goto BusError;
down_write(&devices_subsys.rwsem);
if (parent)
- list_add_tail(&dev->node,&parent->children);
+ list_add_tail(&dev->node, &parent->children);
up_write(&devices_subsys.rwsem);
/* notify platform of device entry */
@@ -245,7 +245,7 @@ int device_add(struct device *dev)
BusError:
device_pm_remove(dev);
PMError:
- kobject_unregister(&dev->kobj);
+ kobject_del(&dev->kobj);
Error:
if (parent)
put_device(parent);
@@ -258,9 +258,9 @@ int device_add(struct device *dev)
* @dev: pointer to the device structure
*
* This happens in two clean steps - initialize the device
- * and add it to the system. The two steps can be called
- * separately, but this is the easiest and most common.
- * I.e. you should only call the two helpers separately if
+ * and add it to the system. The two steps can be called
+ * separately, but this is the easiest and most common.
+ * I.e. you should only call the two helpers separately if
* have a clearly defined need to use and refcount the device
* before it is added to the hierarchy.
*/
@@ -301,13 +301,13 @@ void put_device(struct device * dev)
* device_del - delete device from system.
* @dev: device.
*
- * This is the first part of the device unregistration
+ * This is the first part of the device unregistration
* sequence. This removes the device from the lists we control
- * from here, has it removed from the other driver model
+ * from here, has it removed from the other driver model
* subsystems it was added to in device_add(), and removes it
* from the kobject hierarchy.
*
- * NOTE: this should be called manually _iff_ device_add() was
+ * NOTE: this should be called manually _iff_ device_add() was
* also called manually.
*/
@@ -340,7 +340,7 @@ void device_del(struct device * dev)
* we remove it from all the subsystems with device_del(), then
* we decrement the reference count via put_device(). If that
* is the final reference count, the device will be cleaned up
- * via device_release() above. Otherwise, the structure will
+ * via device_release() above. Otherwise, the structure will
* stick around until the final reference to the device is dropped.
*/
void device_unregister(struct device * dev)
@@ -358,7 +358,7 @@ void device_unregister(struct device * dev)
* @fn: function to be called for each device.
*
* Iterate over @dev's child devices, and call @fn for each,
- * passing it @data.
+ * passing it @data.
*
* We check the return of @fn each time. If it returns anything
* other than 0, we break out and return that value.
@@ -370,8 +370,8 @@ int device_for_each_child(struct device * dev, void * data,
int error = 0;
down_read(&devices_subsys.rwsem);
- list_for_each_entry(child,&dev->children,node) {
- if((error = fn(child,data)))
+ list_for_each_entry(child, &dev->children, node) {
+ if((error = fn(child, data)))
break;
}
up_read(&devices_subsys.rwsem);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 0236ba33542b..0604b2b20e6f 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -15,8 +15,8 @@
#include <linux/string.h>
#include "base.h"
-#define to_dev(node) container_of(node,struct device,driver_list)
-#define to_drv(obj) container_of(obj,struct device_driver,kobj)
+#define to_dev(node) container_of(node, struct device, driver_list)
+#define to_drv(obj) container_of(obj, struct device_driver, kobj)
/**
* driver_create_file - create sysfs file for driver.
@@ -28,7 +28,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att
{
int error;
if (get_driver(drv)) {
- error = sysfs_create_file(&drv->kobj,&attr->attr);
+ error = sysfs_create_file(&drv->kobj, &attr->attr);
put_driver(drv);
} else
error = -EINVAL;
@@ -45,7 +45,7 @@ int driver_create_file(struct device_driver * drv, struct driver_attribute * att
void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
{
if (get_driver(drv)) {
- sysfs_remove_file(&drv->kobj,&attr->attr);
+ sysfs_remove_file(&drv->kobj, &attr->attr);
put_driver(drv);
}
}
@@ -76,7 +76,7 @@ void put_driver(struct device_driver * drv)
* @drv: driver to register
*
* We pass off most of the work to the bus_add_driver() call,
- * since most of the things we have to do deal with the bus
+ * since most of the things we have to do deal with the bus
* structures.
*
* The one interesting aspect is that we initialize @drv->unload_sem
@@ -99,8 +99,8 @@ int driver_register(struct device_driver * drv)
*
* Though, once that is done, we attempt to take @drv->unload_sem.
* This will block until the driver refcount reaches 0, and it is
- * released. Only modular drivers will call this function, and we
- * have to guarantee that it won't complete, letting the driver
+ * released. Only modular drivers will call this function, and we
+ * have to guarantee that it won't complete, letting the driver
* unload until all references are gone.
*/
diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c
index 886d4961498b..0cff0498ea8b 100644
--- a/drivers/base/firmware.c
+++ b/drivers/base/firmware.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -12,11 +12,11 @@
#include <linux/module.h>
#include <linux/init.h>
-static decl_subsys(firmware,NULL,NULL);
+static decl_subsys(firmware, NULL, NULL);
int firmware_register(struct subsystem * s)
{
- kset_set_kset_s(s,firmware_subsys);
+ kset_set_kset_s(s, firmware_subsys);
return subsystem_register(s);
}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 8ff239f146cf..a57ba84eb2c6 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -68,7 +68,7 @@ firmware_timeout_show(struct class *class, char *buf)
* firmware will be provided.
*
* Note: zero means 'wait for ever'
- *
+ *
**/
static ssize_t
firmware_timeout_store(struct class *class, const char *buf, size_t count)
@@ -121,7 +121,7 @@ firmware_loading_show(struct class_device *class_dev, char *buf)
/**
* firmware_loading_store: - loading control file
* Description:
- * The relevant values are:
+ * The relevant values are:
*
* 1: Start a load, discarding any previous partial load.
* 0: Conclude the load and handle the data to the driver code.
@@ -376,7 +376,7 @@ out:
return retval;
}
-/**
+/**
* request_firmware: - request firmware to hotplug and wait for it
* Description:
* @firmware will be used to return a firmware image by the name
@@ -457,7 +457,7 @@ release_firmware(const struct firmware *fw)
/**
* register_firmware: - provide a firmware image for later usage
- *
+ *
* Description:
* Make sure that @data will be available by requesting firmware @name.
*
@@ -541,7 +541,7 @@ request_firmware_nowait(
ret = kernel_thread(request_firmware_work_func, fw_work,
CLONE_FS | CLONE_FILES);
-
+
if (ret < 0) {
fw_work->cont(NULL, fw_work->context);
return ret;
diff --git a/drivers/base/init.c b/drivers/base/init.c
index fd53f364b1ed..7b86c409c648 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -2,7 +2,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -33,7 +33,7 @@ void __init driver_init(void)
classes_init();
firmware_init();
- /* These are also core pieces, but must come after the
+ /* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init();
diff --git a/drivers/base/interface.c b/drivers/base/interface.c
index 1e2d4c328ed5..bd515843a0cb 100644
--- a/drivers/base/interface.c
+++ b/drivers/base/interface.c
@@ -1,10 +1,10 @@
/*
- * drivers/base/interface.c - common driverfs interface that's exported to
+ * drivers/base/interface.c - common driverfs interface that's exported to
* the world for all devices.
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -16,33 +16,33 @@
/**
* detach_state - control the default power state for the device.
- *
- * This is the state the device enters when it's driver module is
+ *
+ * This is the state the device enters when it's driver module is
* unloaded. The value is an unsigned integer, in the range of 0-4.
* '0' indicates 'On', so no action will be taken when the driver is
* unloaded. This is the default behavior.
* '4' indicates 'Off', meaning the driver core will call the driver's
* shutdown method to quiesce the device.
- * 1-3 indicate a low-power state for the device to enter via the
- * driver's suspend method.
+ * 1-3 indicate a low-power state for the device to enter via the
+ * driver's suspend method.
*/
static ssize_t detach_show(struct device * dev, char * buf)
{
- return sprintf(buf,"%u\n",dev->detach_state);
+ return sprintf(buf, "%u\n", dev->detach_state);
}
static ssize_t detach_store(struct device * dev, const char * buf, size_t n)
{
u32 state;
- state = simple_strtoul(buf,NULL,10);
+ state = simple_strtoul(buf, NULL, 10);
if (state > 4)
return -EINVAL;
dev->detach_state = state;
return n;
}
-static DEVICE_ATTR(detach_state,0644,detach_show,detach_store);
+static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store);
struct attribute * dev_default_attrs[] = {
diff --git a/drivers/base/node.c b/drivers/base/node.c
index b5aa9dc6cdb7..fa06de092972 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -29,7 +29,7 @@ static ssize_t node_read_cpumap(struct sys_device * dev, char * buf)
return len;
}
-static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
+static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumap, NULL);
/* Can be overwritten by architecture specific code. */
int __attribute__((weak)) hugetlb_report_node_meminfo(int node, char *buf)
@@ -54,17 +54,17 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
"Node %d LowFree: %8lu kB\n",
nid, K(i.totalram),
nid, K(i.freeram),
- nid, K(i.totalram-i.freeram),
+ nid, K(i.totalram - i.freeram),
nid, K(i.totalhigh),
nid, K(i.freehigh),
- nid, K(i.totalram-i.totalhigh),
- nid, K(i.freeram-i.freehigh));
+ nid, K(i.totalram - i.totalhigh),
+ nid, K(i.freeram - i.freehigh));
n += hugetlb_report_node_meminfo(nid, buf + n);
return n;
}
-#undef K
-static SYSDEV_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
+#undef K
+static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
{
@@ -104,7 +104,7 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
local_node,
other_node);
}
-static SYSDEV_ATTR(numastat,S_IRUGO,node_read_numastat,NULL);
+static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
/*
* register_node - Setup a driverfs device for a node.
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 0d75909a4538..dcb875e487d2 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- *
+ *
* This file is released under the GPLv2
*
* Please see Documentation/driver-model/platform.txt for more
@@ -19,12 +19,71 @@ struct device platform_bus = {
};
/**
+ * platform_get_resource - get a resource for a device
+ * @dev: platform device
+ * @type: resource type
+ * @num: resource index
+ */
+struct resource *
+platform_get_resource(struct platform_device *dev, unsigned int type,
+ unsigned int num)
+{
+ int i;
+
+ for (i = 0; i < dev->num_resources; i++) {
+ struct resource *r = &dev->resource[i];
+
+ if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
+ IORESOURCE_IRQ|IORESOURCE_DMA))
+ == type)
+ if (num-- == 0)
+ return r;
+ }
+ return NULL;
+}
+
+/**
+ * platform_get_irq - get an IRQ for a device
+ * @dev: platform device
+ * @num: IRQ number index
+ */
+int platform_get_irq(struct platform_device *dev, unsigned int num)
+{
+ struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
+
+ return r ? r->start : 0;
+}
+
+/**
+ * platform_add_devices - add a numbers of platform devices
+ * @devs: array of platform devices to add
+ * @num: number of platform devices in array
+ */
+int platform_add_devices(struct platform_device **devs, int num)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < num; i++) {
+ ret = platform_device_register(devs[i]);
+ if (ret) {
+ while (--i >= 0)
+ platform_device_unregister(devs[i]);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
* platform_device_register - add a platform-level device
* @dev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
{
+ int i, ret = 0;
+
if (!pdev)
return -EINVAL;
@@ -32,18 +91,59 @@ int platform_device_register(struct platform_device * pdev)
pdev->dev.parent = &platform_bus;
pdev->dev.bus = &platform_bus_type;
-
- snprintf(pdev->dev.bus_id,BUS_ID_SIZE,"%s%u",pdev->name,pdev->id);
+
+ if (pdev->id != -1)
+ snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s%u", pdev->name, pdev->id);
+ else
+ strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
+
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *p, *r = &pdev->resource[i];
+
+ r->name = pdev->dev.bus_id;
+
+ p = NULL;
+ if (r->flags & IORESOURCE_MEM)
+ p = &iomem_resource;
+ else if (r->flags & IORESOURCE_IO)
+ p = &ioport_resource;
+
+ if (p && request_resource(p, r)) {
+ printk(KERN_ERR
+ "%s: failed to claim resource %d\n",
+ pdev->dev.bus_id, i);
+ ret = -EBUSY;
+ goto failed;
+ }
+ }
pr_debug("Registering platform device '%s'. Parent at %s\n",
- pdev->dev.bus_id,pdev->dev.parent->bus_id);
- return device_register(&pdev->dev);
+ pdev->dev.bus_id, pdev->dev.parent->bus_id);
+
+ ret = device_register(&pdev->dev);
+ if (ret == 0)
+ return ret;
+
+ failed:
+ while (--i >= 0)
+ if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))
+ release_resource(&pdev->resource[i]);
+ return ret;
}
void platform_device_unregister(struct platform_device * pdev)
{
- if (pdev)
+ int i;
+
+ if (pdev) {
device_unregister(&pdev->dev);
+
+ for (i = 0; i < pdev->num_resources; i++) {
+ struct resource *r = &pdev->resource[i];
+ if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO))
+ release_resource(r);
+ }
+ }
}
@@ -52,13 +152,13 @@ void platform_device_unregister(struct platform_device * pdev)
* @dev: device.
* @drv: driver.
*
- * Platform device IDs are assumed to be encoded like this:
- * "<name><instance>", where <name> is a short description of the
- * type of device, like "pci" or "floppy", and <instance> is the
+ * Platform device IDs are assumed to be encoded like this:
+ * "<name><instance>", where <name> is a short description of the
+ * type of device, like "pci" or "floppy", and <instance> is the
* enumerated instance of the device, like '0' or '42'.
- * Driver IDs are simply "<name>".
- * So, extract the <name> from the platform_device structure,
- * and compare it against the name of the driver. Return whether
+ * Driver IDs are simply "<name>".
+ * So, extract the <name> from the platform_device structure,
+ * and compare it against the name of the driver. Return whether
* they match or not.
*/
@@ -114,3 +214,5 @@ EXPORT_SYMBOL(platform_bus);
EXPORT_SYMBOL(platform_bus_type);
EXPORT_SYMBOL(platform_device_register);
EXPORT_SYMBOL(platform_device_unregister);
+EXPORT_SYMBOL(platform_get_irq);
+EXPORT_SYMBOL(platform_get_resource);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 634c98f5c437..635ea200132e 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -12,10 +12,10 @@
* and add it to the list of power-controlled devices. sysfs entries for
* controlling device power management will also be added.
*
- * A different set of lists than the global subsystem list are used to
- * keep track of power info because we use different lists to hold
- * devices based on what stage of the power management process they
- * are in. The power domain dependencies may also differ from the
+ * A different set of lists than the global subsystem list are used to
+ * keep track of power info because we use different lists to hold
+ * devices based on what stage of the power management process they
+ * are in. The power domain dependencies may also differ from the
* ancestral dependencies that the subsystem list maintains.
*/
@@ -74,10 +74,10 @@ int device_pm_add(struct device * dev)
pr_debug("PM: Adding info for %s:%s\n",
dev->bus ? dev->bus->name : "No Bus", dev->kobj.name);
- atomic_set(&dev->power.pm_users,0);
+ atomic_set(&dev->power.pm_users, 0);
down(&dpm_sem);
- list_add_tail(&dev->power.entry,&dpm_active);
- device_pm_set_parent(dev,dev->parent);
+ list_add_tail(&dev->power.entry, &dpm_active);
+ device_pm_set_parent(dev, dev->parent);
if ((error = dpm_sysfs_add(dev)))
list_del(&dev->power.entry);
up(&dpm_sem);
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index b930ccef5785..6971cc667b17 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -27,7 +27,7 @@ extern void device_shutdown(void);
*/
extern struct semaphore dpm_sem;
-/*
+/*
* The PM lists.
*/
extern struct list_head dpm_active;
@@ -37,12 +37,12 @@ extern struct list_head dpm_off_irq;
static inline struct dev_pm_info * to_pm_info(struct list_head * entry)
{
- return container_of(entry,struct dev_pm_info,entry);
+ return container_of(entry, struct dev_pm_info, entry);
}
static inline struct device * to_device(struct list_head * entry)
{
- return container_of(to_pm_info(entry),struct device,power);
+ return container_of(to_pm_info(entry), struct device, power);
}
extern int device_pm_add(struct device *);
@@ -56,7 +56,7 @@ extern int dpm_sysfs_add(struct device *);
extern void dpm_sysfs_remove(struct device *);
/*
- * resume.c
+ * resume.c
*/
extern void dpm_resume(void);
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 21d4b56debe0..1d830be4c9bc 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -39,7 +39,7 @@ void dpm_resume(void)
if (!dev->power.prev_state)
resume_device(dev);
- list_add_tail(entry,&dpm_active);
+ list_add_tail(entry, &dpm_active);
}
}
@@ -48,7 +48,7 @@ void dpm_resume(void)
* device_resume - Restore state of each device in system.
*
* Walk the dpm_off list, remove each entry, resume the device,
- * then add it to the dpm_active list.
+ * then add it to the dpm_active list.
*/
void device_resume(void)
@@ -62,14 +62,14 @@ EXPORT_SYMBOL(device_resume);
/**
- * device_power_up_irq - Power on some devices.
+ * device_power_up_irq - Power on some devices.
*
- * Walk the dpm_off_irq list and power each device up. This
+ * Walk the dpm_off_irq list and power each device up. This
* is used for devices that required they be powered down with
* interrupts disabled. As devices are powered on, they are moved to
* the dpm_suspended list.
*
- * Interrupts must be disabled when calling this.
+ * Interrupts must be disabled when calling this.
*/
void dpm_power_up(void)
@@ -78,7 +78,7 @@ void dpm_power_up(void)
struct list_head * entry = dpm_off_irq.next;
list_del_init(entry);
resume_device(to_device(entry));
- list_add_tail(entry,&dpm_active);
+ list_add_tail(entry, &dpm_active);
}
}
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 4ff5340e90fb..5e58f68363af 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -24,9 +24,9 @@ static void runtime_resume(struct device * dev)
* dpm_runtime_resume - Power one device back on.
* @dev: Device.
*
- * Bring one device back to the on state by first powering it
+ * Bring one device back to the on state by first powering it
* on, then restoring state. We only operate on devices that aren't
- * already on.
+ * already on.
* FIXME: We need to handle devices that are in an unknown state.
*/
@@ -55,7 +55,7 @@ int dpm_runtime_suspend(struct device * dev, u32 state)
if (dev->power.power_state)
runtime_resume(dev);
- if (!(error = suspend_device(dev,state)))
+ if (!(error = suspend_device(dev, state)))
dev->power.power_state = state;
Done:
up(&dpm_sem);
@@ -70,7 +70,7 @@ int dpm_runtime_suspend(struct device * dev, u32 state)
*
* This is an update mechanism for drivers to notify the core
* what power state a device is in. Device probing code may not
- * always be able to tell, but we need accurate information to
+ * always be able to tell, but we need accurate information to
* work reliably.
*/
void dpm_set_power_state(struct device * dev, u32 state)
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c
index 6725ffacb518..d1e023fbe169 100644
--- a/drivers/base/power/shutdown.c
+++ b/drivers/base/power/shutdown.c
@@ -1,9 +1,9 @@
/*
* shutdown.c - power management functions for the device tree.
- *
+ *
* Copyright (c) 2002-3 Patrick Mochel
* 2002-3 Open Source Development Lab
- *
+ *
* This file is released under the GPLv2
*
*/
@@ -14,7 +14,7 @@
#include "power.h"
-#define to_dev(node) container_of(node,struct device,kobj.entry)
+#define to_dev(node) container_of(node, struct device, kobj.entry)
extern struct subsystem devices_subsys;
@@ -29,7 +29,7 @@ int device_detach_shutdown(struct device * dev)
dev->driver->shutdown(dev);
return 0;
}
- return dpm_runtime_suspend(dev,dev->detach_state);
+ return dpm_runtime_suspend(dev, dev->detach_state);
}
@@ -38,8 +38,8 @@ int device_detach_shutdown(struct device * dev)
* down last and resume them first. That way, we don't do anything stupid like
* shutting down the interrupt controller before any devices..
*
- * Note that there are not different stages for power management calls -
- * they only get one called once when interrupts are disabled.
+ * Note that there are not different stages for power management calls -
+ * they only get one called once when interrupts are disabled.
*/
extern int sysdev_shutdown(void);
@@ -50,10 +50,10 @@ extern int sysdev_shutdown(void);
void device_shutdown(void)
{
struct device * dev;
-
+
down_write(&devices_subsys.rwsem);
- list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) {
- pr_debug("shutting down %s: ",dev->bus_id);
+ list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) {
+ pr_debug("shutting down %s: ", dev->bus_id);
if (dev->driver && dev->driver->shutdown) {
pr_debug("Ok\n");
dev->driver->shutdown(dev);
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index a2bc41cc9a38..86f9e6ec05a8 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -1,5 +1,5 @@
/*
- * suspend.c - Functions for putting devices to sleep.
+ * suspend.c - Functions for putting devices to sleep.
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Labs
@@ -10,18 +10,18 @@
#include <linux/device.h>
#include "power.h"
-
+
extern int sysdev_suspend(u32 state);
/*
* The entries in the dpm_active list are in a depth first order, simply
- * because children are guaranteed to be discovered after parents, and
- * are inserted at the back of the list on discovery.
- *
+ * because children are guaranteed to be discovered after parents, and
+ * are inserted at the back of the list on discovery.
+ *
* All list on the suspend path are done in reverse order, so we operate
* on the leaves of the device tree (or forests, depending on how you want
- * to look at it ;) first. As nodes are removed from the back of the list,
- * they are inserted into the front of their destintation lists.
+ * to look at it ;) first. As nodes are removed from the back of the list,
+ * they are inserted into the front of their destintation lists.
*
* Things are the reverse on the resume path - iterations are done in
* forward order, and nodes are inserted at the back of their destination
@@ -44,7 +44,7 @@ int suspend_device(struct device * dev, u32 state)
dev->power.prev_state = dev->power.power_state;
if (dev->bus && dev->bus->suspend && !dev->power.power_state)
- error = dev->bus->suspend(dev,state);
+ error = dev->bus->suspend(dev, state);
return error;
}
@@ -52,16 +52,16 @@ int suspend_device(struct device * dev, u32 state)
/**
* device_suspend - Save state and stop all devices in system.
- * @state: Power state to put each device in.
+ * @state: Power state to put each device in.
*
* Walk the dpm_active list, call ->suspend() for each device, and move
- * it to dpm_off.
+ * it to dpm_off.
* Check the return value for each. If it returns 0, then we move the
- * the device to the dpm_off list. If it returns -EAGAIN, we move it to
- * the dpm_off_irq list. If we get a different error, try and back out.
+ * the device to the dpm_off list. If it returns -EAGAIN, we move it to
+ * the dpm_off_irq list. If we get a different error, try and back out.
*
* If we hit a failure with any of the devices, call device_resume()
- * above to bring the suspended devices back to life.
+ * above to bring the suspended devices back to life.
*
* Note this function leaves dpm_sem held to
* a) block other devices from registering.
@@ -78,14 +78,14 @@ int device_suspend(u32 state)
while(!list_empty(&dpm_active)) {
struct list_head * entry = dpm_active.prev;
struct device * dev = to_device(entry);
- error = suspend_device(dev,state);
+ error = suspend_device(dev, state);
if (!error) {
list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_off);
+ list_add(&dev->power.entry, &dpm_off);
} else if (error == -EAGAIN) {
list_del(&dev->power.entry);
- list_add(&dev->power.entry,&dpm_off_irq);
+ list_add(&dev->power.entry, &dpm_off_irq);
} else {
printk(KERN_ERR "Could not suspend device %s: "
"error %d\n", kobject_name(&dev->kobj), error);
@@ -108,8 +108,8 @@ EXPORT_SYMBOL(device_suspend);
* @state: Power state to enter.
*
* Walk the dpm_off_irq list, calling ->power_down() for each device that
- * couldn't power down the device with interrupts enabled. When we're
- * done, power down system devices.
+ * couldn't power down the device with interrupts enabled. When we're
+ * done, power down system devices.
*/
int device_power_down(u32 state)
@@ -117,10 +117,10 @@ int device_power_down(u32 state)
int error = 0;
struct device * dev;
- list_for_each_entry_reverse(dev,&dpm_off_irq,power.entry) {
- if ((error = suspend_device(dev,state)))
+ list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) {
+ if ((error = suspend_device(dev, state)))
break;
- }
+ }
if (error)
goto Error;
if ((error = sysdev_suspend(state)))
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 683dd59b0bff..6ac96349a8e8 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -11,10 +11,10 @@
*
* show() returns the current power state of the device. '0' indicates
* the device is on. Other values (1-3) indicate the device is in a low
- * power state.
+ * power state.
*
- * store() sets the current power state, which is an integer value
- * between 0-3. If the device is on ('0'), and the value written is
+ * store() sets the current power state, which is an integer value
+ * between 0-3. If the device is on ('0'), and the value written is
* greater than 0, then the device is placed directly into the low-power
* state (via its driver's ->suspend() method).
* If the device is currently in a low-power state, and the value is 0,
@@ -26,7 +26,7 @@
static ssize_t state_show(struct device * dev, char * buf)
{
- return sprintf(buf,"%u\n",dev->power.power_state);
+ return sprintf(buf, "%u\n", dev->power.power_state);
}
static ssize_t state_store(struct device * dev, const char * buf, size_t n)
@@ -35,17 +35,17 @@ static ssize_t state_store(struct device * dev, const char * buf, size_t n)
char * rest;
int error = 0;
- state = simple_strtoul(buf,&rest,10);
+ state = simple_strtoul(buf, &rest, 10);
if (*rest)
return -EINVAL;
if (state)
- error = dpm_runtime_suspend(dev,state);
+ error = dpm_runtime_suspend(dev, state);
else
dpm_runtime_resume(dev);
return error ? error : n;
}
-static DEVICE_ATTR(state,0644,state_show,state_store);
+static DEVICE_ATTR(state, 0644, state_show, state_store);
static struct attribute * power_attrs[] = {
@@ -59,10 +59,10 @@ static struct attribute_group pm_attr_group = {
int dpm_sysfs_add(struct device * dev)
{
- return sysfs_create_group(&dev->kobj,&pm_attr_group);
+ return sysfs_create_group(&dev->kobj, &pm_attr_group);
}
void dpm_sysfs_remove(struct device * dev)
{
- sysfs_remove_group(&dev->kobj,&pm_attr_group);
+ sysfs_remove_group(&dev->kobj, &pm_attr_group);
}
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index b0d55a930855..9d10500cd961 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -5,8 +5,8 @@
* 2002-3 Open Source Development Lab
*
* This file is released under the GPLv2
- *
- * This exports a 'system' bus type.
+ *
+ * This exports a 'system' bus type.
* By default, a 'sys' bus gets added to the root of the system. There will
* always be core system devices. Devices can use sysdev_register() to
* add themselves as children of the system bus.
@@ -24,31 +24,31 @@
extern struct subsystem devices_subsys;
-#define to_sysdev(k) container_of(k,struct sys_device,kobj)
-#define to_sysdev_attr(a) container_of(a,struct sysdev_attribute,attr)
+#define to_sysdev(k) container_of(k, struct sys_device, kobj)
+#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr)
-static ssize_t
+static ssize_t
sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
{
struct sys_device * sysdev = to_sysdev(kobj);
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->show)
- return sysdev_attr->show(sysdev,buffer);
+ return sysdev_attr->show(sysdev, buffer);
return 0;
}
static ssize_t
-sysdev_store(struct kobject * kobj, struct attribute * attr,
+sysdev_store(struct kobject * kobj, struct attribute * attr,
const char * buffer, size_t count)
{
struct sys_device * sysdev = to_sysdev(kobj);
struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->store)
- return sysdev_attr->store(sysdev,buffer,count);
+ return sysdev_attr->store(sysdev, buffer, count);
return 0;
}
@@ -64,22 +64,22 @@ static struct kobj_type ktype_sysdev = {
int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
{
- return sysfs_create_file(&s->kobj,&a->attr);
+ return sysfs_create_file(&s->kobj, &a->attr);
}
void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
{
- sysfs_remove_file(&s->kobj,&a->attr);
+ sysfs_remove_file(&s->kobj, &a->attr);
}
EXPORT_SYMBOL(sysdev_create_file);
EXPORT_SYMBOL(sysdev_remove_file);
-/*
- * declare system_subsys
+/*
+ * declare system_subsys
*/
-decl_subsys(system,&ktype_sysdev,NULL);
+decl_subsys(system, &ktype_sysdev, NULL);
int sysdev_class_register(struct sysdev_class * cls)
{
@@ -87,7 +87,7 @@ int sysdev_class_register(struct sysdev_class * cls)
kobject_name(&cls->kset.kobj));
INIT_LIST_HEAD(&cls->drivers);
cls->kset.subsys = &system_subsys;
- kset_set_kset_s(cls,system_subsys);
+ kset_set_kset_s(cls, system_subsys);
return kset_register(&cls->kset);
}
@@ -109,19 +109,19 @@ static LIST_HEAD(global_drivers);
* @cls: Device class driver belongs to.
* @drv: Driver.
*
- * If @cls is valid, then @drv is inserted into @cls->drivers to be
+ * If @cls is valid, then @drv is inserted into @cls->drivers to be
* called on each operation on devices of that class. The refcount
- * of @cls is incremented.
- * Otherwise, @drv is inserted into global_drivers, and called for
+ * of @cls is incremented.
+ * Otherwise, @drv is inserted into global_drivers, and called for
* each device.
*/
-int sysdev_driver_register(struct sysdev_class * cls,
+int sysdev_driver_register(struct sysdev_class * cls,
struct sysdev_driver * drv)
{
down_write(&system_subsys.rwsem);
if (cls && kset_get(&cls->kset)) {
- list_add_tail(&drv->entry,&cls->drivers);
+ list_add_tail(&drv->entry, &cls->drivers);
/* If devices of this class already exist, tell the driver */
if (drv->add) {
@@ -130,7 +130,7 @@ int sysdev_driver_register(struct sysdev_class * cls,
drv->add(dev);
}
} else
- list_add_tail(&drv->entry,&global_drivers);
+ list_add_tail(&drv->entry, &global_drivers);
up_write(&system_subsys.rwsem);
return 0;
}
@@ -180,12 +180,12 @@ int sysdev_register(struct sys_device * sysdev)
/* But make sure we point to the right type for sysfs translation */
sysdev->kobj.ktype = &ktype_sysdev;
- error = kobject_set_name(&sysdev->kobj,"%s%d",
- kobject_name(&cls->kset.kobj),sysdev->id);
+ error = kobject_set_name(&sysdev->kobj, "%s%d",
+ kobject_name(&cls->kset.kobj), sysdev->id);
if (error)
return error;
- pr_debug("Registering sys device '%s'\n",kobject_name(&sysdev->kobj));
+ pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj));
/* Register the object */
error = kobject_register(&sysdev->kobj);
@@ -194,18 +194,18 @@ int sysdev_register(struct sys_device * sysdev)
struct sysdev_driver * drv;
down_write(&system_subsys.rwsem);
- /* Generic notification is implicit, because it's that
- * code that should have called us.
+ /* Generic notification is implicit, because it's that
+ * code that should have called us.
*/
/* Notify global drivers */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->add)
drv->add(sysdev);
}
/* Notify class auxillary drivers */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->add)
drv->add(sysdev);
}
@@ -219,12 +219,12 @@ void sysdev_unregister(struct sys_device * sysdev)
struct sysdev_driver * drv;
down_write(&system_subsys.rwsem);
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->remove)
drv->remove(sysdev);
}
- list_for_each_entry(drv,&sysdev->cls->drivers,entry) {
+ list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
if (drv->remove)
drv->remove(sysdev);
}
@@ -241,12 +241,12 @@ void sysdev_unregister(struct sys_device * sysdev)
* Loop over each class of system devices, and the devices in each
* of those classes. For each device, we call the shutdown method for
* each driver registered for the device - the globals, the auxillaries,
- * and the class driver.
+ * and the class driver.
*
* Note: The list is iterated in reverse order, so that we shut down
* child devices before we shut down thier parents. The list ordering
* is guaranteed by virtue of the fact that child devices are registered
- * after their parents.
+ * after their parents.
*/
void sysdev_shutdown(void)
@@ -256,25 +256,25 @@ void sysdev_shutdown(void)
pr_debug("Shutting Down System Devices\n");
down_write(&system_subsys.rwsem);
- list_for_each_entry_reverse(cls,&system_subsys.kset.list,
+ list_for_each_entry_reverse(cls, &system_subsys.kset.list,
kset.kobj.entry) {
struct sys_device * sysdev;
pr_debug("Shutting down type '%s':\n",
kobject_name(&cls->kset.kobj));
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+ list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
- pr_debug(" %s\n",kobject_name(&sysdev->kobj));
+ pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call global drivers first. */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->shutdown)
drv->shutdown(sysdev);
}
/* Call auxillary drivers next. */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->shutdown)
drv->shutdown(sysdev);
}
@@ -295,7 +295,7 @@ void sysdev_shutdown(void)
* We perform an almost identical operation as sys_device_shutdown()
* above, though calling ->suspend() instead. Interrupts are disabled
* when this called. Devices are responsible for both saving state and
- * quiescing or powering down the device.
+ * quiescing or powering down the device.
*
* This is only called by the device PM core, so we let them handle
* all synchronization.
@@ -307,32 +307,32 @@ int sysdev_suspend(u32 state)
pr_debug("Suspending System Devices\n");
- list_for_each_entry_reverse(cls,&system_subsys.kset.list,
+ list_for_each_entry_reverse(cls, &system_subsys.kset.list,
kset.kobj.entry) {
struct sys_device * sysdev;
pr_debug("Suspending type '%s':\n",
kobject_name(&cls->kset.kobj));
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+ list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
- pr_debug(" %s\n",kobject_name(&sysdev->kobj));
+ pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call global drivers first. */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->suspend)
- drv->suspend(sysdev,state);
+ drv->suspend(sysdev, state);
}
/* Call auxillary drivers next. */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->suspend)
- drv->suspend(sysdev,state);
+ drv->suspend(sysdev, state);
}
/* Now call the generic one */
if (cls->suspend)
- cls->suspend(sysdev,state);
+ cls->suspend(sysdev, state);
}
}
return 0;
@@ -345,7 +345,7 @@ int sysdev_suspend(u32 state)
* Similar to sys_device_suspend(), but we iterate the list forwards
* to guarantee that parent devices are resumed before their children.
*
- * Note: Interrupts are disabled when called.
+ * Note: Interrupts are disabled when called.
*/
int sysdev_resume(void)
@@ -354,28 +354,28 @@ int sysdev_resume(void)
pr_debug("Resuming System Devices\n");
- list_for_each_entry(cls,&system_subsys.kset.list,kset.kobj.entry) {
+ list_for_each_entry(cls, &system_subsys.kset.list, kset.kobj.entry) {
struct sys_device * sysdev;
pr_debug("Resuming type '%s':\n",
kobject_name(&cls->kset.kobj));
- list_for_each_entry(sysdev,&cls->kset.list,kobj.entry) {
+ list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
- pr_debug(" %s\n",kobject_name(&sysdev->kobj));
+ pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* First, call the class-specific one */
if (cls->resume)
cls->resume(sysdev);
/* Call auxillary drivers next. */
- list_for_each_entry(drv,&cls->drivers,entry) {
+ list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->resume)
drv->resume(sysdev);
}
/* Call global drivers. */
- list_for_each_entry(drv,&global_drivers,entry) {
+ list_for_each_entry(drv, &global_drivers, entry) {
if (drv->resume)
drv->resume(sysdev);
}
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 0e18df6b76e5..afb9d4391a7a 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -285,14 +285,14 @@ config BLK_DEV_NBD
If unsure, say N.
-config BLK_DEV_CARMEL
- tristate "Promise SATA SX8 (carmel) support"
+config BLK_DEV_SX8
+ tristate "Promise SATA SX8 support"
depends on PCI
---help---
Saying Y or M here will enable support for the
- Promise SATA SX8 ("carmel") controllers.
+ Promise SATA SX8 controllers.
- Use devices /dev/carmel/$N and /dev/carmel/$Np$M.
+ Use devices /dev/sx8/$N and /dev/sx8/$Np$M.
config BLK_DEV_RAM
tristate "RAM disk support"
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 33b14e84cd8c..2654b5b7615e 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -41,5 +41,5 @@ obj-$(CONFIG_BLK_DEV_NBD) += nbd.o
obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o
obj-$(CONFIG_VIODASD) += viodasd.o
-obj-$(CONFIG_BLK_DEV_CARMEL) += carmel.o
+obj-$(CONFIG_BLK_DEV_SX8) += sx8.o
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 6203e02ad5c2..1ee5ab64f11f 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -2667,7 +2667,7 @@ static int __end_that_request_first(struct request *req, int uptodate,
}
total_bytes = bio_nbytes = 0;
- while ((bio = req->bio)) {
+ while ((bio = req->bio) != NULL) {
int nbytes;
if (nr_bytes >= bio->bi_size) {
diff --git a/drivers/block/carmel.c b/drivers/block/sx8.c
index 38fd6fe42d07..0a0234129030 100644
--- a/drivers/block/carmel.c
+++ b/drivers/block/sx8.c
@@ -1,5 +1,5 @@
/*
- * carmel.c: Driver for Promise SATA SX8 looks-like-I2O hardware
+ * sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
*
* Copyright 2004 Red Hat, Inc.
*
@@ -32,7 +32,7 @@
MODULE_AUTHOR("Jeff Garzik");
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Promise SATA SX8 (carmel) block driver");
+MODULE_DESCRIPTION("Promise SATA SX8 block driver");
#if 0
#define CARM_DEBUG
@@ -43,7 +43,7 @@ MODULE_DESCRIPTION("Promise SATA SX8 (carmel) block driver");
#endif
#undef CARM_NDEBUG
-#define DRV_NAME "carmel"
+#define DRV_NAME "sx8"
#define DRV_VERSION "0.8"
#define PFX DRV_NAME ": "
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 9c19dbc8eb19..b416bdf57080 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -18,6 +18,7 @@
#include <linux/capability.h>
#include <linux/uio.h>
#include <linux/cdev.h>
+#include <linux/device.h>
#include <asm/uaccess.h>
@@ -26,6 +27,7 @@ struct raw_device_data {
int inuse;
};
+static struct class_simple *raw_class;
static struct raw_device_data raw_devices[MAX_RAW_MINORS];
static DECLARE_MUTEX(raw_mutex);
static struct file_operations raw_ctl_fops; /* forward declaration */
@@ -123,6 +125,13 @@ raw_ioctl(struct inode *inode, struct file *filp,
return ioctl_by_bdev(bdev, command, arg);
}
+static void bind_device(struct raw_config_request rq)
+{
+ class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor));
+ class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq.raw_minor),
+ NULL, "raw%d", rq.raw_minor);
+}
+
/*
* Deal with ioctls against the raw-device control interface, to bind
* and unbind other raw devices.
@@ -191,12 +200,15 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
if (rq.block_major == 0 && rq.block_minor == 0) {
/* unbind */
rawdev->binding = NULL;
+ class_simple_device_remove(MKDEV(RAW_MAJOR, rq.raw_minor));
} else {
rawdev->binding = bdget(dev);
if (rawdev->binding == NULL)
err = -ENOMEM;
- else
+ else {
__module_get(THIS_MODULE);
+ bind_device(rq);
+ }
}
up(&raw_mutex);
} else {
@@ -287,6 +299,15 @@ static int __init raw_init(void)
goto error;
}
+ raw_class = class_simple_create(THIS_MODULE, "raw");
+ if (IS_ERR(raw_class)) {
+ printk(KERN_ERR "Error creating raw class.\n");
+ cdev_del(&raw_cdev);
+ unregister_chrdev_region(dev, MAX_RAW_MINORS);
+ goto error;
+ }
+ class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
+
devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
S_IFCHR | S_IRUGO | S_IWUGO,
"raw/rawctl");
@@ -309,6 +330,8 @@ static void __exit raw_exit(void)
devfs_remove("raw/raw%d", i);
devfs_remove("raw/rawctl");
devfs_remove("raw");
+ class_simple_device_remove(MKDEV(RAW_MAJOR, 0));
+ class_simple_destroy(raw_class);
cdev_del(&raw_cdev);
unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
}
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index c2b2dec8009c..703adb11115e 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -96,12 +96,13 @@ config IXP4XX_WATCHDOG
Say N if you are unsure.
config SA1100_WATCHDOG
- tristate "SA1100 watchdog"
- depends on WATCHDOG && ARCH_SA1100
+ tristate "SA1100/PXA2xx watchdog"
+ depends on WATCHDOG && ( ARCH_SA1100 || ARCH_PXA )
help
- Watchdog timer embedded into SA11x0 chips. This will reboot your
- system when timeout is reached.
- NOTE, that once enabled, this timer cannot be disabled.
+ Watchdog timer embedded into SA11x0 and PXA2xx chips. This will
+ reboot your system when timeout is reached.
+
+ NOTE: once enabled, this timer cannot be disabled.
To compile this driver as a module, choose M here: the
module will be called sa1100_wdt.
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index 862fb9ab344a..aa3901fbab26 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -1,5 +1,5 @@
/*
- * Watchdog driver for the SA11x0
+ * Watchdog driver for the SA11x0/PXA2xx
*
* (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
* Based on SoftDog driver by Alan Cox <alan@redhat.com>
@@ -174,7 +174,7 @@ static struct file_operations sa1100dog_fops =
static struct miscdevice sa1100dog_miscdev =
{
.minor = WATCHDOG_MINOR,
- .name = "SA1100 watchdog",
+ .name = "SA1100/PXA2xx watchdog",
.fops = &sa1100dog_fops,
};
@@ -194,7 +194,7 @@ static int __init sa1100dog_init(void)
ret = misc_register(&sa1100dog_miscdev);
if (ret == 0)
- printk("SA1100 Watchdog Timer: timer margin %d sec\n",
+ printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
margin);
return ret;
@@ -209,7 +209,7 @@ module_init(sa1100dog_init);
module_exit(sa1100dog_exit);
MODULE_AUTHOR("Oleg Drokin <green@crimea.edu>");
-MODULE_DESCRIPTION("SA1100 Watchdog");
+MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");
module_param(margin, int, 0);
MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 429070cd8f13..4f92849567aa 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -134,7 +134,7 @@ struct efivar_attribute {
#define EFI_ATTR(_name, _mode, _show, _store) \
struct subsys_attribute efi_attr_##_name = { \
- .attr {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
.show = _show, \
.store = _store, \
};
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 31ee54341952..6e22814a7f40 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -138,7 +138,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
- if(ibm_dmi_probe()) {
+ if(ibm_dmi_probe() && PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
dev_err(&PIIX4_dev->dev, "IBM Laptop detected; this module "
"may corrupt your serial eeprom! Refusing to load "
"module!\n");
diff --git a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
index f93b6f67696e..a416e4ee560e 100644
--- a/drivers/i2c/chips/asb100.c
+++ b/drivers/i2c/chips/asb100.c
@@ -272,7 +272,7 @@ static ssize_t \
return show_in(dev, buf, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
- show_in##offset, NULL) \
+ show_in##offset, NULL); \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
@@ -294,17 +294,17 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
-sysfs_in(0)
-sysfs_in(1)
-sysfs_in(2)
-sysfs_in(3)
-sysfs_in(4)
-sysfs_in(5)
-sysfs_in(6)
+sysfs_in(0);
+sysfs_in(1);
+sysfs_in(2);
+sysfs_in(3);
+sysfs_in(4);
+sysfs_in(5);
+sysfs_in(6);
#define device_create_file_in(client, offset) do { \
device_create_file(&client->dev, &dev_attr_in##offset##_input); \
@@ -410,15 +410,15 @@ static ssize_t set_fan##offset##_div(struct device *dev, const char *buf, \
return set_fan_div(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
- show_fan##offset, NULL) \
+ show_fan##offset, NULL); \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan##offset##_min, set_fan##offset##_min) \
+ show_fan##offset##_min, set_fan##offset##_min); \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_fan##offset##_div, set_fan##offset##_div)
+ show_fan##offset##_div, set_fan##offset##_div);
-sysfs_fan(1)
-sysfs_fan(2)
-sysfs_fan(3)
+sysfs_fan(1);
+sysfs_fan(2);
+sysfs_fan(3);
#define device_create_file_fan(client, offset) do { \
device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
@@ -449,9 +449,9 @@ static ssize_t show_##reg(struct device *dev, char *buf, int nr) \
return sprintf_temp_from_reg(data->reg[nr], buf, nr); \
}
-show_temp_reg(temp)
-show_temp_reg(temp_max)
-show_temp_reg(temp_hyst)
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_hyst);
#define set_temp_reg(REG, reg) \
static ssize_t set_##reg(struct device *dev, const char *buf, \
@@ -473,15 +473,15 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
return count; \
}
-set_temp_reg(MAX, temp_max)
-set_temp_reg(HYST, temp_hyst)
+set_temp_reg(MAX, temp_max);
+set_temp_reg(HYST, temp_hyst);
#define sysfs_temp(num) \
static ssize_t show_temp##num(struct device *dev, char *buf) \
{ \
return show_temp(dev, buf, num-1); \
} \
-static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL) \
+static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL); \
static ssize_t show_temp_max##num(struct device *dev, char *buf) \
{ \
return show_temp_max(dev, buf, num-1); \
@@ -492,7 +492,7 @@ static ssize_t set_temp_max##num(struct device *dev, const char *buf, \
return set_temp_max(dev, buf, count, num-1); \
} \
static DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \
- show_temp_max##num, set_temp_max##num) \
+ show_temp_max##num, set_temp_max##num); \
static ssize_t show_temp_hyst##num(struct device *dev, char *buf) \
{ \
return show_temp_hyst(dev, buf, num-1); \
@@ -503,12 +503,12 @@ static ssize_t set_temp_hyst##num(struct device *dev, const char *buf, \
return set_temp_hyst(dev, buf, count, num-1); \
} \
static DEVICE_ATTR(temp##num##_max_hyst, S_IRUGO | S_IWUSR, \
- show_temp_hyst##num, set_temp_hyst##num)
+ show_temp_hyst##num, set_temp_hyst##num);
-sysfs_temp(1)
-sysfs_temp(2)
-sysfs_temp(3)
-sysfs_temp(4)
+sysfs_temp(1);
+sysfs_temp(2);
+sysfs_temp(3);
+sysfs_temp(4);
/* VID */
#define device_create_file_temp(client, num) do { \
@@ -523,7 +523,7 @@ static ssize_t show_vid(struct device *dev, char *buf)
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
}
-static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid, NULL)
+static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid, NULL);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref)
@@ -544,7 +544,7 @@ static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
}
/* Alarms */
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm)
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm);
@@ -554,7 +554,7 @@ static ssize_t show_alarms(struct device *dev, char *buf)
return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms));
}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL)
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms)
@@ -594,9 +594,9 @@ static ssize_t set_pwm_enable1(struct device *dev, const char *buf,
return count;
}
-static DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1)
+static DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1);
static DEVICE_ATTR(fan1_pwm_enable, S_IRUGO | S_IWUSR,
- show_pwm_enable1, set_pwm_enable1)
+ show_pwm_enable1, set_pwm_enable1);
#define device_create_file_pwm1(client) do { \
device_create_file(&new_client->dev, &dev_attr_fan1_pwm); \
device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable); \
diff --git a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
index 061a0b8009b5..ef656298779a 100644
--- a/drivers/i2c/chips/it87.c
+++ b/drivers/i2c/chips/it87.c
@@ -128,15 +128,15 @@ static int reset;
#define IT87_REG_FAN(nr) (0x0d + (nr))
#define IT87_REG_FAN_MIN(nr) (0x10 + (nr))
-#define IT87_REG_FAN_CTRL 0x13
+#define IT87_REG_FAN_MAIN_CTRL 0x13
#define IT87_REG_VIN(nr) (0x20 + (nr))
#define IT87_REG_TEMP(nr) (0x29 + (nr))
#define IT87_REG_VIN_MAX(nr) (0x30 + (nr) * 2)
#define IT87_REG_VIN_MIN(nr) (0x31 + (nr) * 2)
-#define IT87_REG_TEMP_HIGH(nr) (0x40 + ((nr) * 2))
-#define IT87_REG_TEMP_LOW(nr) (0x41 + ((nr) * 2))
+#define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
+#define IT87_REG_TEMP_LOW(nr) (0x41 + (nr) * 2)
#define IT87_REG_I2C_ADDR 0x48
@@ -145,8 +145,8 @@ static int reset;
#define IT87_REG_CHIPID 0x58
-#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
-#define IN_FROM_REG(val) (((val) * 16) / 10)
+#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255))
+#define IN_FROM_REG(val) ((val) * 16)
static inline u8 FAN_TO_REG(long rpm, int div)
{
@@ -159,9 +159,9 @@ static inline u8 FAN_TO_REG(long rpm, int div)
#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-5)/10):\
- ((val)+5)/10),0,255))
-#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10)
+#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
+ ((val)+500)/1000),-128,127))
+#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000)
#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\
205-(val)*5)
@@ -170,7 +170,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
static int DIV_TO_REG(int val)
{
int answer = 0;
- while ((val >>= 1))
+ while ((val >>= 1) != 0)
answer++;
return answer;
}
@@ -231,19 +231,19 @@ static int it87_id = 0;
static ssize_t show_in(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])*10 );
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
}
static ssize_t show_in_min(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])*10 );
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
}
static ssize_t show_in_max(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])*10 );
+ return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
}
static ssize_t set_in_min(struct device *dev, const char *buf,
@@ -251,7 +251,7 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10)/10;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
data->in_min[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MIN(nr),
data->in_min[nr]);
@@ -262,7 +262,7 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10)/10;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
data->in_max[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MAX(nr),
data->in_max[nr]);
@@ -275,7 +275,7 @@ static ssize_t \
{ \
return show_in(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL)
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);
#define limit_in_offset(offset) \
static ssize_t \
@@ -299,9 +299,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
show_in_offset(0);
limit_in_offset(0);
@@ -325,24 +325,24 @@ show_in_offset(8);
static ssize_t show_temp(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])*100 );
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
}
static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])*100);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr]));
}
static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
{
struct it87_data *data = it87_update_device(dev);
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr])*100);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr]));
}
static ssize_t set_temp_max(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- int val = simple_strtol(buf, NULL, 10)/100;
+ int val = simple_strtol(buf, NULL, 10);
data->temp_high[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
return count;
@@ -352,7 +352,7 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
{
struct i2c_client *client = to_i2c_client(dev);
struct it87_data *data = i2c_get_clientdata(client);
- int val = simple_strtol(buf, NULL, 10)/100;
+ int val = simple_strtol(buf, NULL, 10);
data->temp_low[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
return count;
@@ -382,11 +382,11 @@ static ssize_t set_temp_##offset##_min (struct device *dev, \
{ \
return set_temp_min(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_max, set_temp_##offset##_max) \
+ show_temp_##offset##_max, set_temp_##offset##_max); \
static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_min, set_temp_##offset##_min)
+ show_temp_##offset##_min, set_temp_##offset##_min);
show_temp_offset(1);
show_temp_offset(2);
@@ -430,8 +430,8 @@ static ssize_t set_sensor_##offset (struct device *dev, \
{ \
return set_sensor(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
- show_sensor_##offset, set_sensor_##offset)
+static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
+ show_sensor_##offset, set_sensor_##offset);
show_sensor_offset(1);
show_sensor_offset(2);
@@ -525,11 +525,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \
{ \
return set_fan_div(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL); \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min) \
+ show_fan_##offset##_min, set_fan_##offset##_min); \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_div, set_fan_##offset##_div)
+ show_fan_##offset##_div, set_fan_##offset##_div);
show_fan_offset(1);
show_fan_offset(2);
@@ -773,9 +773,7 @@ static int it87_detach_client(struct i2c_client *client)
We don't want to lock the whole ISA bus, so we lock each client
separately.
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
- would slow down the IT87 access and should not be necessary.
- There are some ugly typecasts here, but the good new is - they should
- nowhere else be necessary! */
+ would slow down the IT87 access and should not be necessary. */
static int it87_read_value(struct i2c_client *client, u8 reg)
{
struct it87_data *data = i2c_get_clientdata(client);
@@ -795,9 +793,7 @@ static int it87_read_value(struct i2c_client *client, u8 reg)
We don't want to lock the whole ISA bus, so we lock each client
separately.
We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
- would slow down the IT87 access and should not be necessary.
- There are some ugly typecasts here, but the good new is - they should
- nowhere else be necessary! */
+ would slow down the IT87 access and should not be necessary. */
static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
{
struct it87_data *data = i2c_get_clientdata(client);
@@ -840,11 +836,11 @@ static void it87_init_client(struct i2c_client *client, struct it87_data *data)
}
/* Check if tachometers are reset manually or by some reason */
- tmp = it87_read_value(client, IT87_REG_FAN_CTRL);
+ tmp = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
if ((tmp & 0x70) == 0) {
/* Enable all fan tachometers */
tmp = (tmp & 0x8f) | 0x70;
- it87_write_value(client, IT87_REG_FAN_CTRL, tmp);
+ it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, tmp);
}
/* Start monitoring */
diff --git a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
index 74a1ca76cc04..b9ffad6c36e4 100644
--- a/drivers/i2c/chips/lm78.c
+++ b/drivers/i2c/chips/lm78.c
@@ -281,7 +281,7 @@ static ssize_t \
return show_in(dev, buf, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
- show_in##offset, NULL) \
+ show_in##offset, NULL); \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
@@ -303,9 +303,9 @@ static ssize_t set_in##offset##_max (struct device *dev, \
return set_in_max(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
show_in_offset(0);
show_in_offset(1);
@@ -354,11 +354,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
return count;
}
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL)
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
- show_temp_over, set_temp_over)
+ show_temp_over, set_temp_over);
static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- show_temp_hyst, set_temp_hyst)
+ show_temp_hyst, set_temp_hyst);
/* 3 Fans */
static ssize_t show_fan(struct device *dev, char *buf, int nr)
@@ -439,9 +439,9 @@ static ssize_t set_fan_##offset##_min (struct device *dev, \
{ \
return set_fan_min(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min)
+ show_fan_##offset##_min, set_fan_##offset##_min);
static ssize_t set_fan_1_div(struct device *dev, const char *buf,
size_t count)
@@ -461,10 +461,10 @@ show_fan_offset(3);
/* Fan 3 divisor is locked in H/W */
static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
- show_fan_1_div, set_fan_1_div)
+ show_fan_1_div, set_fan_1_div);
static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
- show_fan_2_div, set_fan_2_div)
-static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL)
+ show_fan_2_div, set_fan_2_div);
+static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
/* VID */
static ssize_t show_vid(struct device *dev, char *buf)
diff --git a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
index 795852aa6719..11f85043153b 100644
--- a/drivers/i2c/chips/lm85.c
+++ b/drivers/i2c/chips/lm85.c
@@ -451,9 +451,9 @@ static ssize_t set_fan_##offset##_min (struct device *dev, \
{ \
return set_fan_min(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min)
+ show_fan_##offset##_min, set_fan_##offset##_min);
show_fan_offset(1);
show_fan_offset(2);
@@ -468,7 +468,7 @@ static ssize_t show_vid_reg(struct device *dev, char *buf)
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
}
-static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL)
+static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);
static ssize_t show_vrm_reg(struct device *dev, char *buf)
{
@@ -487,7 +487,7 @@ static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count)
return count;
}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg)
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
static ssize_t show_alarms_reg(struct device *dev, char *buf)
{
@@ -495,7 +495,7 @@ static ssize_t show_alarms_reg(struct device *dev, char *buf)
return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));
}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL)
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
/* pwm */
@@ -542,8 +542,8 @@ static ssize_t show_pwm_enable##offset (struct device *dev, char *buf) \
return show_pwm_enable(dev, buf, 0x##offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
- show_pwm_##offset, set_pwm_##offset) \
-static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL)
+ show_pwm_##offset, set_pwm_##offset); \
+static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL);
show_pwm_reg(1);
show_pwm_reg(2);
@@ -617,11 +617,11 @@ static ssize_t set_in_##offset##_max (struct device *dev, \
{ \
return set_in_max(dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL) \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL); \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in_##offset##_min, set_in_##offset##_min) \
+ show_in_##offset##_min, set_in_##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in_##offset##_max, set_in_##offset##_max)
+ show_in_##offset##_max, set_in_##offset##_max);
show_in_reg(0);
show_in_reg(1);
@@ -697,11 +697,11 @@ static ssize_t set_temp_##offset##_max (struct device *dev, \
{ \
return set_temp_max(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_min, set_temp_##offset##_min) \
+ show_temp_##offset##_min, set_temp_##offset##_min); \
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_max, set_temp_##offset##_max)
+ show_temp_##offset##_max, set_temp_##offset##_max);
show_temp_reg(1);
show_temp_reg(2);
diff --git a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
index a5ec359b0f6f..3aa334583b89 100644
--- a/drivers/i2c/chips/via686a.c
+++ b/drivers/i2c/chips/via686a.c
@@ -405,11 +405,11 @@ static ssize_t set_in##offset##_max (struct device *dev, \
{ \
return set_in_max(dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL) \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
- show_in##offset##_min, set_in##offset##_min) \
+ show_in##offset##_min, set_in##offset##_min); \
static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
- show_in##offset##_max, set_in##offset##_max)
+ show_in##offset##_max, set_in##offset##_max);
show_in_offset(0);
show_in_offset(1);
@@ -473,11 +473,11 @@ static ssize_t set_temp_##offset##_hyst (struct device *dev, \
{ \
return set_temp_hyst(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL) \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_over, set_temp_##offset##_over) \
+ show_temp_##offset##_over, set_temp_##offset##_over); \
static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \
- show_temp_##offset##_hyst, set_temp_##offset##_hyst)
+ show_temp_##offset##_hyst, set_temp_##offset##_hyst);
show_temp_offset(1);
show_temp_offset(2);
@@ -542,11 +542,11 @@ static ssize_t set_fan_##offset##_div (struct device *dev, \
{ \
return set_fan_div(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_min, set_fan_##offset##_min) \
+ show_fan_##offset##_min, set_fan_##offset##_min); \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_fan_##offset##_div, set_fan_##offset##_div)
+ show_fan_##offset##_div, set_fan_##offset##_div);
show_fan_offset(1);
show_fan_offset(2);
diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
index c38a7f9712b6..5d1a31bcb222 100644
--- a/drivers/i2c/chips/w83627hf.c
+++ b/drivers/i2c/chips/w83627hf.c
@@ -199,7 +199,7 @@ superio_exit(void)
#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */
#define W83627THF_REG_PWM3 0x11 /* 637HF too */
-#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too, unused yet */
+#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */
static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
@@ -222,7 +222,7 @@ static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
these macros are called: arguments may be evaluated more than once.
Fixing this is just not worth it. */
#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255))
-#define IN_FROM_REG(val) ((val) * 16 + 5)
+#define IN_FROM_REG(val) ((val) * 16)
static inline u8 FAN_TO_REG(long rpm, int div)
{
@@ -312,6 +312,7 @@ struct w83627hf_data {
Default = 3435.
Other Betas unimplemented */
u8 vrm;
+ u8 vrm_ovt; /* Register value, 627thf & 637hf only */
};
@@ -370,7 +371,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \
{ \
return show_in(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL)
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
#define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
@@ -384,22 +385,104 @@ store_regs_in_##reg##offset (struct device *dev, \
return store_in_##reg (dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \
- show_regs_in_##reg##offset, store_regs_in_##reg##offset)
+ show_regs_in_##reg##offset, store_regs_in_##reg##offset);
#define sysfs_in_offsets(offset) \
sysfs_in_offset(offset) \
sysfs_in_reg_offset(min, offset) \
sysfs_in_reg_offset(max, offset)
-sysfs_in_offsets(0)
-sysfs_in_offsets(1)
-sysfs_in_offsets(2)
-sysfs_in_offsets(3)
-sysfs_in_offsets(4)
-sysfs_in_offsets(5)
-sysfs_in_offsets(6)
-sysfs_in_offsets(7)
-sysfs_in_offsets(8)
+sysfs_in_offsets(1);
+sysfs_in_offsets(2);
+sysfs_in_offsets(3);
+sysfs_in_offsets(4);
+sysfs_in_offsets(5);
+sysfs_in_offsets(6);
+sysfs_in_offsets(7);
+sysfs_in_offsets(8);
+
+/* use a different set of functions for in0 */
+static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
+{
+ long in0;
+
+ if ((data->vrm_ovt & 0x01) &&
+ (w83627thf == data->type || w83637hf == data->type))
+
+ /* use VRM9 calculation */
+ in0 = (long)((reg * 488 + 70000 + 50) / 100);
+ else
+ /* use VRM8 (standard) calculation */
+ in0 = (long)IN_FROM_REG(reg);
+
+ return sprintf(buf,"%ld\n", in0);
+}
+
+static ssize_t show_regs_in_0(struct device *dev, char *buf)
+{
+ struct w83627hf_data *data = w83627hf_update_device(dev);
+ return show_in_0(data, buf, data->in[0]);
+}
+
+static ssize_t show_regs_in_min0(struct device *dev, char *buf)
+{
+ struct w83627hf_data *data = w83627hf_update_device(dev);
+ return show_in_0(data, buf, data->in_min[0]);
+}
+
+static ssize_t show_regs_in_max0(struct device *dev, char *buf)
+{
+ struct w83627hf_data *data = w83627hf_update_device(dev);
+ return show_in_0(data, buf, data->in_max[0]);
+}
+
+static ssize_t store_regs_in_min0(struct device *dev,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627hf_data *data = i2c_get_clientdata(client);
+ u32 val;
+
+ val = simple_strtoul(buf, NULL, 10);
+ if ((data->vrm_ovt & 0x01) &&
+ (w83627thf == data->type || w83637hf == data->type))
+
+ /* use VRM9 calculation */
+ data->in_min[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+ else
+ /* use VRM8 (standard) calculation */
+ data->in_min[0] = IN_TO_REG(val);
+
+ w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]);
+ return count;
+}
+
+static ssize_t store_regs_in_max0(struct device *dev,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83627hf_data *data = i2c_get_clientdata(client);
+ u32 val;
+
+ val = simple_strtoul(buf, NULL, 10);
+ if ((data->vrm_ovt & 0x01) &&
+ (w83627thf == data->type || w83637hf == data->type))
+
+ /* use VRM9 calculation */
+ data->in_max[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+ else
+ /* use VRM8 (standard) calculation */
+ data->in_max[0] = IN_TO_REG(val);
+
+ w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]);
+ return count;
+}
+
+static DEVICE_ATTR(in0_input, S_IRUGO, show_regs_in_0, NULL);
+static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
+ show_regs_in_min0, store_regs_in_min0);
+static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
+ show_regs_in_max0, store_regs_in_max0);
#define device_create_file_in(client, offset) \
do { \
@@ -416,8 +499,8 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
FAN_FROM_REG(data->reg[nr-1], \
(long)DIV_FROM_REG(data->fan_div[nr-1]))); \
}
-show_fan_reg(fan)
-show_fan_reg(fan_min)
+show_fan_reg(fan);
+show_fan_reg(fan_min);
static ssize_t
store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
@@ -440,7 +523,7 @@ static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \
return show_fan(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL)
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
#define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
@@ -453,14 +536,14 @@ store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
return store_fan_min(dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
- show_regs_fan_min##offset, store_regs_fan_min##offset)
+ show_regs_fan_min##offset, store_regs_fan_min##offset);
-sysfs_fan_offset(1)
-sysfs_fan_min_offset(1)
-sysfs_fan_offset(2)
-sysfs_fan_min_offset(2)
-sysfs_fan_offset(3)
-sysfs_fan_min_offset(3)
+sysfs_fan_offset(1);
+sysfs_fan_min_offset(1);
+sysfs_fan_offset(2);
+sysfs_fan_min_offset(2);
+sysfs_fan_offset(3);
+sysfs_fan_min_offset(3);
#define device_create_file_fan(client, offset) \
do { \
@@ -479,9 +562,9 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
} \
}
-show_temp_reg(temp)
-show_temp_reg(temp_max)
-show_temp_reg(temp_max_hyst)
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_max_hyst);
#define store_temp_reg(REG, reg) \
static ssize_t \
@@ -505,8 +588,8 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
\
return count; \
}
-store_temp_reg(OVER, max)
-store_temp_reg(HYST, max_hyst)
+store_temp_reg(OVER, max);
+store_temp_reg(HYST, max_hyst);
#define sysfs_temp_offset(offset) \
static ssize_t \
@@ -514,7 +597,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \
{ \
return show_temp(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL)
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
#define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
@@ -528,16 +611,16 @@ store_regs_temp_##reg##offset (struct device *dev, \
return store_temp_##reg (dev, buf, count, 0x##offset); \
} \
static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
- show_regs_temp_##reg##offset, store_regs_temp_##reg##offset)
+ show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
#define sysfs_temp_offsets(offset) \
sysfs_temp_offset(offset) \
sysfs_temp_reg_offset(max, offset) \
sysfs_temp_reg_offset(max_hyst, offset)
-sysfs_temp_offsets(1)
-sysfs_temp_offsets(2)
-sysfs_temp_offsets(3)
+sysfs_temp_offsets(1);
+sysfs_temp_offsets(2);
+sysfs_temp_offsets(3);
#define device_create_file_temp(client, offset) \
do { \
@@ -552,7 +635,7 @@ show_vid_reg(struct device *dev, char *buf)
struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
}
-static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL)
+static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref)
@@ -574,7 +657,7 @@ store_vrm_reg(struct device *dev, const char *buf, size_t count)
return count;
}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg)
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm)
@@ -584,7 +667,7 @@ show_alarms_reg(struct device *dev, char *buf)
struct w83627hf_data *data = w83627hf_update_device(dev);
return sprintf(buf, "%ld\n", (long) data->alarms);
}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL)
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms)
@@ -641,10 +724,10 @@ store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \
return store_beep_reg(dev, buf, count, BEEP_##REG); \
} \
static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \
- show_regs_beep_##reg, store_regs_beep_##reg)
+ show_regs_beep_##reg, store_regs_beep_##reg);
-sysfs_beep(ENABLE, enable)
-sysfs_beep(MASK, mask)
+sysfs_beep(ENABLE, enable);
+sysfs_beep(MASK, mask);
#define device_create_file_beep(client) \
do { \
@@ -707,11 +790,11 @@ store_regs_fan_div_##offset (struct device *dev, \
return store_fan_div_reg(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
- show_regs_fan_div_##offset, store_regs_fan_div_##offset)
+ show_regs_fan_div_##offset, store_regs_fan_div_##offset);
-sysfs_fan_div(1)
-sysfs_fan_div(2)
-sysfs_fan_div(3)
+sysfs_fan_div(1);
+sysfs_fan_div(2);
+sysfs_fan_div(3);
#define device_create_file_fan_div(client, offset) \
do { \
@@ -763,11 +846,11 @@ store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \
return store_pwm_reg(dev, buf, count, offset); \
} \
static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
- show_regs_pwm_##offset, store_regs_pwm_##offset)
+ show_regs_pwm_##offset, store_regs_pwm_##offset);
-sysfs_pwm(1)
-sysfs_pwm(2)
-sysfs_pwm(3)
+sysfs_pwm(1);
+sysfs_pwm(2);
+sysfs_pwm(3);
#define device_create_file_pwm(client, offset) \
do { \
@@ -836,11 +919,11 @@ store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \
return store_sensor_reg(dev, buf, count, offset); \
} \
static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
- show_regs_sensor_##offset, store_regs_sensor_##offset)
+ show_regs_sensor_##offset, store_regs_sensor_##offset);
-sysfs_sensor(1)
-sysfs_sensor(2)
-sysfs_sensor(3)
+sysfs_sensor(1);
+sysfs_sensor(2);
+sysfs_sensor(3);
#define device_create_file_sensor(client, offset) \
do { \
@@ -1157,7 +1240,7 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
static void w83627hf_init_client(struct i2c_client *client)
{
struct w83627hf_data *data = i2c_get_clientdata(client);
- int vid = 0, i;
+ int i;
int type = data->type;
u8 tmp;
@@ -1191,10 +1274,15 @@ static void w83627hf_init_client(struct i2c_client *client)
data->vid = w83627thf_read_gpio5(client) & 0x1f;
}
- /* Convert VID to voltage based on default VRM */
- data->vrm = DEFAULT_VRM;
- if (type != w83697hf)
- vid = vid_from_reg(vid, data->vrm);
+ /* Read VRM & OVT Config only once */
+ if (w83627thf == data->type || w83637hf == data->type) {
+ data->vrm_ovt =
+ w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
+ data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82;
+ } else {
+ /* Convert VID to voltage based on default VRM */
+ data->vrm = DEFAULT_VRM;
+ }
tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
for (i = 1; i <= 3; i++) {
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
index ac378b54b1cd..785203d39d68 100644
--- a/drivers/i2c/chips/w83781d.c
+++ b/drivers/i2c/chips/w83781d.c
@@ -320,7 +320,7 @@ show_regs_in_##offset (struct device *dev, char *buf) \
{ \
return show_in(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL)
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
#define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
@@ -331,7 +331,7 @@ static ssize_t store_regs_in_##reg##offset (struct device *dev, const char *buf,
{ \
return store_in_##reg (dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset)
+static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset);
#define sysfs_in_offsets(offset) \
sysfs_in_offset(offset); \
@@ -386,7 +386,7 @@ static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \
return show_fan(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL)
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
#define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
@@ -397,7 +397,7 @@ static ssize_t store_regs_fan_min##offset (struct device *dev, const char *buf,
{ \
return store_fan_min(dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset)
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset);
sysfs_fan_offset(1);
sysfs_fan_min_offset(1);
@@ -466,7 +466,7 @@ show_regs_temp_##offset (struct device *dev, char *buf) \
{ \
return show_temp(dev, buf, 0x##offset); \
} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL)
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
#define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
@@ -477,7 +477,7 @@ static ssize_t store_regs_temp_##reg##offset (struct device *dev, const char *bu
{ \
return store_temp_##reg (dev, buf, count, 0x##offset); \
} \
-static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset)
+static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
#define sysfs_temp_offsets(offset) \
sysfs_temp_offset(offset); \
@@ -503,7 +503,7 @@ show_vid_reg(struct device *dev, char *buf)
}
static
-DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL)
+DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);
#define device_create_file_vid(client) \
device_create_file(&client->dev, &dev_attr_in0_ref);
static ssize_t
@@ -527,7 +527,7 @@ store_vrm_reg(struct device *dev, const char *buf, size_t count)
}
static
-DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg)
+DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
#define device_create_file_vrm(client) \
device_create_file(&client->dev, &dev_attr_vrm);
static ssize_t
@@ -538,7 +538,7 @@ show_alarms_reg(struct device *dev, char *buf)
}
static
-DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL)
+DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms);
static ssize_t show_beep_mask (struct device *dev, char *buf)
@@ -598,7 +598,7 @@ static ssize_t store_regs_beep_##reg (struct device *dev, const char *buf, size_
{ \
return store_beep_reg(dev, buf, count, BEEP_##REG); \
} \
-static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg)
+static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg);
sysfs_beep(ENABLE, enable);
sysfs_beep(MASK, mask);
@@ -665,7 +665,7 @@ static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf,
{ \
return store_fan_div_reg(dev, buf, count, offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset)
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset);
sysfs_fan_div(1);
sysfs_fan_div(2);
@@ -744,7 +744,7 @@ static ssize_t store_regs_pwm_##offset (struct device *dev, const char *buf, siz
{ \
return store_pwm_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset)
+static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset);
#define sysfs_pwmenable(offset) \
static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \
@@ -755,7 +755,7 @@ static ssize_t store_regs_pwmenable_##offset (struct device *dev, const char *bu
{ \
return store_pwmenable_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset)
+static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);
sysfs_pwm(1);
sysfs_pwm(2);
@@ -833,7 +833,7 @@ static ssize_t store_regs_sensor_##offset (struct device *dev, const char *buf,
{ \
return store_sensor_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset)
+static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset);
sysfs_sensor(1);
sysfs_sensor(2);
@@ -891,7 +891,7 @@ static ssize_t store_regs_rt_##offset (struct device *dev, const char *buf, size
{ \
return store_rt_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(rt##offset, S_IRUGO | S_IWUSR, show_regs_rt_##offset, store_regs_rt_##offset)
+static DEVICE_ATTR(rt##offset, S_IRUGO | S_IWUSR, show_regs_rt_##offset, store_regs_rt_##offset);
sysfs_rt(1);
sysfs_rt(2);
@@ -1491,7 +1491,7 @@ static void
w83781d_init_client(struct i2c_client *client)
{
struct w83781d_data *data = i2c_get_clientdata(client);
- int vid = 0, i, p;
+ int i, p;
int type = data->type;
u8 tmp;
@@ -1513,14 +1513,7 @@ w83781d_init_client(struct i2c_client *client)
w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0);
}
- if (type != w83697hf) {
- vid = w83781d_read_value(client, W83781D_REG_VID_FANDIV) & 0x0f;
- vid |=
- (w83781d_read_value(client, W83781D_REG_CHIPID) & 0x01) <<
- 4;
- data->vrm = DEFAULT_VRM;
- vid = vid_from_reg(vid, data->vrm);
- }
+ data->vrm = 82;
if ((type != w83781d) && (type != as99127f)) {
tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
diff --git a/drivers/i2c/chips/w83l785ts.c b/drivers/i2c/chips/w83l785ts.c
index 52118f9bf11f..58575861fc78 100644
--- a/drivers/i2c/chips/w83l785ts.c
+++ b/drivers/i2c/chips/w83l785ts.c
@@ -137,8 +137,8 @@ static ssize_t show_temp_over(struct device *dev, char *buf)
return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
}
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL)
-static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL)
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL);
/*
* Real code
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index a0a4aa15aa97..4e5a3671d6e3 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -181,7 +181,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
struct i2c_smbus_ioctl_data data_arg;
union i2c_smbus_data temp;
struct i2c_msg *rdwr_pa;
- u8 **data_ptrs;
+ u8 __user **data_ptrs;
int i,datasize,res;
unsigned long funcs;
@@ -238,8 +238,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
return -EFAULT;
}
- data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *),
- GFP_KERNEL);
+ data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
if (data_ptrs == NULL) {
kfree(rdwr_pa);
return -ENOMEM;
@@ -252,7 +251,7 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
res = -EINVAL;
break;
}
- data_ptrs[i] = rdwr_pa[i].buf;
+ data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
if(rdwr_pa[i].buf == NULL) {
res = -ENOMEM;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index ec58f197f54f..8b1d16b9c1ad 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -95,6 +95,26 @@ if BLK_DEV_IDE
comment "Please see Documentation/ide.txt for help/info on IDE drives"
+config BLK_DEV_IDE_SATA
+ bool "Support for SATA (deprecated; conflicts with libata SATA driver)"
+ default n
+ ---help---
+ There are two drivers for Serial ATA controllers.
+
+ The main driver, "libata", exists inside the SCSI subsystem
+ and supports most modern SATA controllers.
+
+ The IDE driver (which you are currently configuring) supports
+ a few first-generation SATA controllers.
+
+ In order to eliminate conflicts between the two subsystems,
+ this config option enables the IDE driver's SATA support.
+ Normally this is disabled, as it is preferred that libata
+ supports SATA controllers, and this (IDE) driver supports
+ PATA controllers.
+
+ If unsure, say N.
+
config BLK_DEV_HD_IDE
bool "Use old disk-only driver on primary interface"
depends on (X86 || SH_MPC1211)
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 05ea9a7057eb..5d35808ac781 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -660,7 +660,7 @@ static int hd_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
- struct hd_geometry *loc = (struct hd_geometry *) arg;
+ struct hd_geometry __user *loc = (struct hd_geometry __user *) arg;
struct hd_geometry g;
if (cmd != HDIO_GETGEO)
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index d6b052300dfa..30bdcb3ec22f 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -71,11 +71,7 @@ static struct amd_ide_chip {
{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 },
- { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, 0x50, AMD_UDMA_133 },
- { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, 0x50, AMD_UDMA_133 },
{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
- { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, 0x50, AMD_UDMA_133 },
- { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, 0x50, AMD_UDMA_133 },
{ 0 }
};
@@ -487,11 +483,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
/* 11 */ DECLARE_NV_DEV("NFORCE3-250-SATA"),
/* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"),
/* 13 */ DECLARE_NV_DEV("NFORCE-CK804"),
- /* 14 */ DECLARE_NV_DEV("NFORCE-CK804-SATA"),
- /* 15 */ DECLARE_NV_DEV("NFORCE-CK804-SATA2"),
- /* 16 */ DECLARE_NV_DEV("NFORCE-MCP04"),
- /* 17 */ DECLARE_NV_DEV("NFORCE-MCP04-SATA"),
- /* 18 */ DECLARE_NV_DEV("NFORCE-MCP04-SATA2")
+ /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
};
static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -512,17 +504,17 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
+#ifdef CONFIG_BLK_DEV_IDE_SATA
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
+#endif
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
+#ifdef CONFIG_BLK_DEV_IDE_SATA
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
+#endif
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
- { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index e73279563a58..2150a18a8252 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -127,7 +127,9 @@ static struct pci_device_id generic_pci_tbl[] = {
{ PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
{ PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
+#ifdef CONFIG_BLK_DEV_IDE_SATA
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
+#endif
{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10},
{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11},
{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12},
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index fec700bbacbc..26719f2c7932 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -793,9 +793,9 @@ static struct pci_device_id piix_pci_tbl[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17},
-#ifndef CONFIG_SCSI_SATA
+#ifdef CONFIG_BLK_DEV_IDE_SATA
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18},
-#endif /* !CONFIG_SCSI_SATA */
+#endif
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19},
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20},
{ 0, },
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 5a7483ef6003..b1c9e8cd5d7c 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -21,6 +21,7 @@
* if neccessary
*/
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -1127,8 +1128,10 @@ static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_devi
static struct pci_device_id siimage_pci_tbl[] = {
{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#ifdef CONFIG_BLK_DEV_IDE_SATA
{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+#endif
{ 0, },
};
MODULE_DEVICE_TABLE(pci, siimage_pci_tbl);
diff --git a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c
index 10606f8f110e..4ee5d42e8a20 100644
--- a/drivers/ieee1394/amdtp.c
+++ b/drivers/ieee1394/amdtp.c
@@ -1095,7 +1095,7 @@ void stream_free(struct stream *s)
/* File operations */
-static ssize_t amdtp_write(struct file *file, const char *buffer, size_t count,
+static ssize_t amdtp_write(struct file *file, const char __user *buffer, size_t count,
loff_t *offset_is_ignored)
{
struct stream *s = file->private_data;
@@ -1150,7 +1150,7 @@ static int amdtp_ioctl(struct inode *inode, struct file *file,
{
case AMDTP_IOC_PLUG:
case AMDTP_IOC_CHANNEL:
- if (copy_from_user(&cfg, (struct amdtp_ioctl *) arg, sizeof cfg))
+ if (copy_from_user(&cfg, (struct amdtp_ioctl __user *) arg, sizeof cfg))
return -EFAULT;
else
return stream_configure(s, cmd, &cfg);
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 9964d6fbc5a1..626298dd3e99 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1333,7 +1333,7 @@ static int dv1394_fasync(int fd, struct file *file, int on)
return 0;
}
-static ssize_t dv1394_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
struct video_card *video = file_to_video_card(file);
DECLARE_WAITQUEUE(wait, current);
@@ -1430,7 +1430,7 @@ static ssize_t dv1394_write(struct file *file, const char *buffer, size_t count,
}
-static ssize_t dv1394_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t dv1394_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
struct video_card *video = file_to_video_card(file);
DECLARE_WAITQUEUE(wait, current);
@@ -1549,6 +1549,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
struct video_card *video = file_to_video_card(file);
unsigned long flags;
int ret = -EINVAL;
+ void __user *argp = (void __user *)arg;
DECLARE_WAITQUEUE(wait, current);
@@ -1718,10 +1719,10 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
case DV1394_IOC_INIT: {
struct dv1394_init init;
- if (arg == (unsigned long) NULL) {
+ if (!argp) {
ret = do_dv1394_init_default(video);
} else {
- if (copy_from_user(&init, (void*)arg, sizeof(init))) {
+ if (copy_from_user(&init, argp, sizeof(init))) {
ret = -EFAULT;
goto out;
}
@@ -1767,7 +1768,7 @@ static int dv1394_ioctl(struct inode *inode, struct file *file,
spin_unlock_irqrestore(&video->spinlock, flags);
- if (copy_to_user((void*)arg, &status, sizeof(status))) {
+ if (copy_to_user(argp, &status, sizeof(status))) {
ret = -EFAULT;
goto out;
}
diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h
index 674d55c7f8eb..c93587be9cab 100644
--- a/drivers/ieee1394/raw1394-private.h
+++ b/drivers/ieee1394/raw1394-private.h
@@ -35,11 +35,11 @@ struct file_info {
struct list_head addr_list;
- u8 *fcp_buffer;
+ u8 __user *fcp_buffer;
/* old ISO API */
u64 listen_channels;
- quadlet_t *iso_buffer;
+ quadlet_t __user *iso_buffer;
size_t iso_buffer_length;
u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index dd43837d1d5f..35a9056aa30d 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -56,11 +56,11 @@
#include "raw1394-private.h"
#if BITS_PER_LONG == 64
-#define int2ptr(x) ((void *)x)
-#define ptr2int(x) ((u64)x)
+#define int2ptr(x) ((void __user *)x)
+#define ptr2int(x) ((u64)(unsigned long)(void __user *)x)
#else
-#define int2ptr(x) ((void *)(u32)x)
-#define ptr2int(x) ((u64)(u32)x)
+#define int2ptr(x) ((void __user *)(u32)x)
+#define ptr2int(x) ((u64)(unsigned long)(void __user *)x)
#endif
#ifdef CONFIG_IEEE1394_VERBOSEDEBUG
@@ -410,7 +410,7 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
}
-static ssize_t raw1394_read(struct file *file, char *buffer, size_t count,
+static ssize_t raw1394_read(struct file *file, char __user *buffer, size_t count,
loff_t *offset_is_ignored)
{
struct file_info *fi = (struct file_info *)file->private_data;
@@ -602,7 +602,7 @@ static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
if (fi->fcp_buffer) {
req->req.error = RAW1394_ERROR_ALREADY;
} else {
- fi->fcp_buffer = (u8 *)int2ptr(req->req.recvb);
+ fi->fcp_buffer = int2ptr(req->req.recvb);
}
} else {
if (!fi->fcp_buffer) {
@@ -826,7 +826,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
return sizeof(struct raw1394_request);
}
- if (copy_from_user(packet->data, ((u8*) int2ptr(req->req.sendb)) + header_length,
+ if (copy_from_user(packet->data, int2ptr(req->req.sendb) + header_length,
packet->data_size)) {
req->req.error = RAW1394_ERROR_MEMFAULT;
req->req.length = 0;
@@ -964,9 +964,8 @@ static int arm_read (struct hpsb_host *host, int nodeid, quadlet_t *buffer,
arm_req->buffer = NULL;
arm_resp->buffer = NULL;
if (rcode == RCODE_COMPLETE) {
- arm_resp->buffer = ((byte_t *)(arm_resp) +
- (sizeof(struct arm_response)));
- memcpy (arm_resp->buffer,
+ byte_t *buf = (byte_t *)arm_resp + sizeof(struct arm_response);
+ memcpy (buf,
(arm_addr->addr_space_buffer)+(addr-(arm_addr->start)),
length);
arm_resp->buffer = int2ptr((arm_addr->recvb) +
@@ -1091,10 +1090,9 @@ static int arm_write (struct hpsb_host *host, int nodeid, int destid,
(sizeof (struct arm_request_response)));
arm_resp = (struct arm_response *) ((byte_t *)(arm_req) +
(sizeof(struct arm_request)));
- arm_req->buffer = ((byte_t *)(arm_resp) +
- (sizeof(struct arm_response)));
arm_resp->buffer = NULL;
- memcpy (arm_req->buffer, data, length);
+ memcpy ((byte_t *)arm_resp + sizeof(struct arm_response),
+ data, length);
arm_req->buffer = int2ptr((arm_addr->recvb) +
sizeof (struct arm_request_response) +
sizeof (struct arm_request) +
@@ -1233,6 +1231,7 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
}
}
if (arm_addr->notification_options & ARM_LOCK) {
+ byte_t *buf1, *buf2;
DBGMSG("arm_lock -> entering notification-section");
req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) {
@@ -1258,26 +1257,22 @@ static int arm_lock (struct hpsb_host *host, int nodeid, quadlet_t *store,
(sizeof (struct arm_request_response)));
arm_resp = (struct arm_response *) ((byte_t *)(arm_req) +
(sizeof(struct arm_request)));
- arm_req->buffer = ((byte_t *)(arm_resp) +
- (sizeof(struct arm_response)));
- arm_resp->buffer = ((byte_t *)(arm_req->buffer) +
- (2* sizeof(*store)));
+ buf1 = (byte_t *)arm_resp + sizeof(struct arm_response);
+ buf2 = buf1 + 2 * sizeof(*store);
if ((ext_tcode == EXTCODE_FETCH_ADD) ||
(ext_tcode == EXTCODE_LITTLE_ADD)) {
arm_req->buffer_length = sizeof(*store);
- memcpy (arm_req->buffer, &data, sizeof(*store));
+ memcpy (buf1, &data, sizeof(*store));
} else {
arm_req->buffer_length = 2 * sizeof(*store);
- memcpy (arm_req->buffer, &arg, sizeof(*store));
- memcpy (((arm_req->buffer) + sizeof(*store)),
- &data, sizeof(*store));
+ memcpy (buf1, &arg, sizeof(*store));
+ memcpy (buf1 + sizeof(*store), &data, sizeof(*store));
}
if (rcode == RCODE_COMPLETE) {
arm_resp->buffer_length = sizeof(*store);
- memcpy (arm_resp->buffer, &old, sizeof(*store));
+ memcpy (buf2, &old, sizeof(*store));
} else {
- arm_resp->buffer = NULL;
arm_resp->buffer_length = 0;
}
req->file_info = fi;
@@ -1438,6 +1433,7 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
}
}
if (arm_addr->notification_options & ARM_LOCK) {
+ byte_t *buf1, *buf2;
DBGMSG("arm_lock64 -> entering notification-section");
req = __alloc_pending_request(SLAB_ATOMIC);
if (!req) {
@@ -1463,26 +1459,22 @@ static int arm_lock64 (struct hpsb_host *host, int nodeid, octlet_t *store,
(sizeof (struct arm_request_response)));
arm_resp = (struct arm_response *) ((byte_t *)(arm_req) +
(sizeof(struct arm_request)));
- arm_req->buffer = ((byte_t *)(arm_resp) +
- (sizeof(struct arm_response)));
- arm_resp->buffer = ((byte_t *)(arm_req->buffer) +
- (2* sizeof(*store)));
+ buf1 = (byte_t *)arm_resp + sizeof(struct arm_response);
+ buf2 = buf1 + 2 * sizeof(*store);
if ((ext_tcode == EXTCODE_FETCH_ADD) ||
(ext_tcode == EXTCODE_LITTLE_ADD)) {
arm_req->buffer_length = sizeof(*store);
- memcpy (arm_req->buffer, &data, sizeof(*store));
+ memcpy (buf1, &data, sizeof(*store));
} else {
arm_req->buffer_length = 2 * sizeof(*store);
- memcpy (arm_req->buffer, &arg, sizeof(*store));
- memcpy (((arm_req->buffer) + sizeof(*store)),
- &data, sizeof(*store));
+ memcpy (buf1, &arg, sizeof(*store));
+ memcpy (buf1 + sizeof(*store), &data, sizeof(*store));
}
if (rcode == RCODE_COMPLETE) {
arm_resp->buffer_length = sizeof(*store);
- memcpy (arm_resp->buffer, &old, sizeof(*store));
+ memcpy (buf2, &old, sizeof(*store));
} else {
- arm_resp->buffer = NULL;
arm_resp->buffer_length = 0;
}
req->file_info = fi;
@@ -2146,7 +2138,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
}
-static ssize_t raw1394_write(struct file *file, const char *buffer, size_t count,
+static ssize_t raw1394_write(struct file *file, const char __user *buffer, size_t count,
loff_t *offset_is_ignored)
{
struct file_info *fi = (struct file_info *)file->private_data;
@@ -2262,7 +2254,7 @@ static void raw1394_iso_fill_status(struct hpsb_iso *iso, struct raw1394_iso_sta
stat->xmit_cycle = iso->xmit_cycle;
}
-static int raw1394_iso_xmit_init(struct file_info *fi, void *uaddr)
+static int raw1394_iso_xmit_init(struct file_info *fi, void __user *uaddr)
{
struct raw1394_iso_status stat;
@@ -2294,7 +2286,7 @@ static int raw1394_iso_xmit_init(struct file_info *fi, void *uaddr)
return 0;
}
-static int raw1394_iso_recv_init(struct file_info *fi, void *uaddr)
+static int raw1394_iso_recv_init(struct file_info *fi, void __user *uaddr)
{
struct raw1394_iso_status stat;
@@ -2322,7 +2314,7 @@ static int raw1394_iso_recv_init(struct file_info *fi, void *uaddr)
return 0;
}
-static int raw1394_iso_get_status(struct file_info *fi, void *uaddr)
+static int raw1394_iso_get_status(struct file_info *fi, void __user *uaddr)
{
struct raw1394_iso_status stat;
struct hpsb_iso *iso = fi->iso_handle;
@@ -2338,7 +2330,7 @@ static int raw1394_iso_get_status(struct file_info *fi, void *uaddr)
}
/* copy N packet_infos out of the ringbuffer into user-supplied array */
-static int raw1394_iso_recv_packets(struct file_info *fi, void *uaddr)
+static int raw1394_iso_recv_packets(struct file_info *fi, void __user *uaddr)
{
struct raw1394_iso_packets upackets;
unsigned int packet = fi->iso_handle->first_packet;
@@ -2369,7 +2361,7 @@ static int raw1394_iso_recv_packets(struct file_info *fi, void *uaddr)
}
/* copy N packet_infos from user to ringbuffer, and queue them for transmission */
-static int raw1394_iso_send_packets(struct file_info *fi, void *uaddr)
+static int raw1394_iso_send_packets(struct file_info *fi, void __user *uaddr)
{
struct raw1394_iso_packets upackets;
int i, rv;
@@ -2426,14 +2418,15 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct file_info *fi = file->private_data;
+ void __user *argp = (void __user *)arg;
switch(fi->iso_state) {
case RAW1394_ISO_INACTIVE:
switch(cmd) {
case RAW1394_IOC_ISO_XMIT_INIT:
- return raw1394_iso_xmit_init(fi, (void*) arg);
+ return raw1394_iso_xmit_init(fi, argp);
case RAW1394_IOC_ISO_RECV_INIT:
- return raw1394_iso_recv_init(fi, (void*) arg);
+ return raw1394_iso_recv_init(fi, argp);
default:
break;
}
@@ -2443,7 +2436,7 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
case RAW1394_IOC_ISO_RECV_START: {
/* copy args from user-space */
int args[3];
- if (copy_from_user(&args[0], (void*) arg, sizeof(args)))
+ if (copy_from_user(&args[0], argp, sizeof(args)))
return -EFAULT;
return hpsb_iso_recv_start(fi->iso_handle, args[0], args[1], args[2]);
}
@@ -2457,14 +2450,14 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: {
/* copy the u64 from user-space */
u64 mask;
- if (copy_from_user(&mask, (void*) arg, sizeof(mask)))
+ if (copy_from_user(&mask, argp, sizeof(mask)))
return -EFAULT;
return hpsb_iso_recv_set_channel_mask(fi->iso_handle, mask);
}
case RAW1394_IOC_ISO_GET_STATUS:
- return raw1394_iso_get_status(fi, (void*) arg);
+ return raw1394_iso_get_status(fi, argp);
case RAW1394_IOC_ISO_RECV_PACKETS:
- return raw1394_iso_recv_packets(fi, (void*) arg);
+ return raw1394_iso_recv_packets(fi, argp);
case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
case RAW1394_IOC_ISO_RECV_FLUSH:
@@ -2482,7 +2475,7 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
case RAW1394_IOC_ISO_XMIT_START: {
/* copy two ints from user-space */
int args[2];
- if (copy_from_user(&args[0], (void*) arg, sizeof(args)))
+ if (copy_from_user(&args[0], argp, sizeof(args)))
return -EFAULT;
return hpsb_iso_xmit_start(fi->iso_handle, args[0], args[1]);
}
@@ -2492,9 +2485,9 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, unsigned int cm
hpsb_iso_stop(fi->iso_handle);
return 0;
case RAW1394_IOC_ISO_GET_STATUS:
- return raw1394_iso_get_status(fi, (void*) arg);
+ return raw1394_iso_get_status(fi, argp);
case RAW1394_IOC_ISO_XMIT_PACKETS:
- return raw1394_iso_send_packets(fi, (void*) arg);
+ return raw1394_iso_send_packets(fi, argp);
case RAW1394_IOC_ISO_SHUTDOWN:
raw1394_iso_shutdown(fi);
return 0;
diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h
index 258ed558e496..35bfc38f013c 100644
--- a/drivers/ieee1394/raw1394.h
+++ b/drivers/ieee1394/raw1394.h
@@ -105,18 +105,18 @@ typedef struct arm_request {
__u8 extended_transaction_code;
__u32 generation;
__u16 buffer_length;
- __u8 *buffer;
+ __u8 __user *buffer;
} *arm_request_t;
typedef struct arm_response {
__s32 response_code;
__u16 buffer_length;
- __u8 *buffer;
+ __u8 __user *buffer;
} *arm_response_t;
typedef struct arm_request_response {
- struct arm_request *request;
- struct arm_response *response;
+ struct arm_request __user *request;
+ struct arm_response __user *response;
} *arm_request_response_t;
/* rawiso API */
@@ -136,7 +136,7 @@ struct raw1394_iso_packet_info {
/* argument for RAW1394_ISO_RECV/XMIT_PACKETS ioctls */
struct raw1394_iso_packets {
__u32 n_packets;
- struct raw1394_iso_packet_info *infos;
+ struct raw1394_iso_packet_info __user *infos;
};
struct raw1394_iso_config {
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 7a757fc43f1d..e954d0834ff3 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -705,6 +705,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
struct file_ctx *ctx = (struct file_ctx *)file->private_data;
struct ti_ohci *ohci = ctx->ohci;
unsigned long flags;
+ void __user *argp = (void __user *)arg;
switch(cmd)
{
@@ -716,7 +717,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
struct dma_iso_ctx *d;
int i;
- if (copy_from_user(&v, (void *)arg, sizeof(v)))
+ if (copy_from_user(&v, argp, sizeof(v)))
return -EFAULT;
/* if channel < 0, find lowest available one */
@@ -813,7 +814,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
v.channel);
}
- if (copy_to_user((void *)arg, &v, sizeof(v)))
+ if (copy_to_user(argp, &v, sizeof(v)))
return -EFAULT;
return 0;
@@ -825,7 +826,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
u64 mask;
struct dma_iso_ctx *d;
- if (copy_from_user(&channel, (void *)arg, sizeof(int)))
+ if (copy_from_user(&channel, argp, sizeof(int)))
return -EFAULT;
if (channel<0 || channel>(ISO_CHANNELS-1)) {
@@ -860,7 +861,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
struct video1394_wait v;
struct dma_iso_ctx *d;
- if (copy_from_user(&v, (void *)arg, sizeof(v)))
+ if (copy_from_user(&v, argp, sizeof(v)))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
@@ -923,7 +924,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
struct dma_iso_ctx *d;
int i;
- if (copy_from_user(&v, (void *)arg, sizeof(v)))
+ if (copy_from_user(&v, argp, sizeof(v)))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
@@ -994,7 +995,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
spin_unlock_irqrestore(&d->lock, flags);
v.buffer=i;
- if (copy_to_user((void *)arg, &v, sizeof(v)))
+ if (copy_to_user(argp, &v, sizeof(v)))
return -EFAULT;
return 0;
@@ -1007,7 +1008,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
qv.packet_sizes = NULL;
- if (copy_from_user(&v, (void *)arg, sizeof(v)))
+ if (copy_from_user(&v, argp, sizeof(v)))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
@@ -1023,7 +1024,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
unsigned int *psizes;
int buf_size = d->nb_cmd * sizeof(unsigned int);
- if (copy_from_user(&qv, (void *)arg, sizeof(qv)))
+ if (copy_from_user(&qv, argp, sizeof(qv)))
return -EFAULT;
psizes = kmalloc(buf_size, GFP_KERNEL);
@@ -1111,7 +1112,7 @@ static int video1394_ioctl(struct inode *inode, struct file *file,
struct video1394_wait v;
struct dma_iso_ctx *d;
- if (copy_from_user(&v, (void *)arg, sizeof(v)))
+ if (copy_from_user(&v, argp, sizeof(v)))
return -EFAULT;
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 62ffcc67b050..a11be53573d0 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -320,8 +320,8 @@ isdn_ppp_open(int min, struct file *file)
is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
#endif
#ifdef CONFIG_IPPP_FILTER
- is->pass_filter.filter = NULL;
- is->active_filter.filter = NULL;
+ is->pass_filter = NULL;
+ is->active_filter = NULL;
#endif
is->state = IPPP_OPEN;
@@ -378,13 +378,13 @@ isdn_ppp_release(int min, struct file *file)
is->slcomp = NULL;
#endif
#ifdef CONFIG_IPPP_FILTER
- if (is->pass_filter.filter) {
- kfree(is->pass_filter.filter);
- is->pass_filter.filter = NULL;
+ if (is->pass_filter) {
+ kfree(is->pass_filter);
+ is->pass_filter = NULL;
}
- if (is->active_filter.filter) {
- kfree(is->active_filter.filter);
- is->active_filter.filter = NULL;
+ if (is->active_filter) {
+ kfree(is->active_filter);
+ is->active_filter = NULL;
}
#endif
@@ -414,11 +414,11 @@ isdn_ppp_release(int min, struct file *file)
* get_arg .. ioctl helper
*/
static int
-get_arg(void *b, void *val, int len)
+get_arg(void __user *b, void *val, int len)
{
if (len <= 0)
len = sizeof(void *);
- if (copy_from_user((void *) val, b, len))
+ if (copy_from_user(val, b, len))
return -EFAULT;
return 0;
}
@@ -427,15 +427,50 @@ get_arg(void *b, void *val, int len)
* set arg .. ioctl helper
*/
static int
-set_arg(void *b, void *val,int len)
+set_arg(void __user *b, void *val,int len)
{
if(len <= 0)
len = sizeof(void *);
- if (copy_to_user(b, (void *) val, len))
+ if (copy_to_user(b, val, len))
return -EFAULT;
return 0;
}
+static int get_filter(void __user *arg, struct sock_filter **p)
+{
+ struct sock_fprog uprog;
+ struct sock_filter *code = NULL;
+ int len, err;
+
+ if (copy_from_user(&uprog, arg, sizeof(uprog)))
+ return -EFAULT;
+
+ if (!uprog.len) {
+ *p = NULL;
+ return 0;
+ }
+
+ /* uprog.len is unsigned short, so no overflow here */
+ len = uprog.len * sizeof(struct sock_filter);
+ code = kmalloc(len, GFP_KERNEL);
+ if (code == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(code, uprog.filter, len)) {
+ kfree(code);
+ return -EFAULT;
+ }
+
+ err = sk_chk_filter(code, uprog.len);
+ if (err) {
+ kfree(code);
+ return err;
+ }
+
+ *p = code;
+ return uprog.len;
+}
+
/*
* ippp device ioctl
*/
@@ -447,6 +482,7 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
struct ippp_struct *is;
isdn_net_local *lp;
struct isdn_ppp_comp_data data;
+ void __user *argp = (void __user *)arg;
is = (struct ippp_struct *) file->private_data;
lp = is->lp;
@@ -462,7 +498,7 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
#ifdef CONFIG_ISDN_MPP
if (!(is->state & IPPP_CONNECT))
return -EINVAL;
- if ((r = get_arg((void *) arg, &val, sizeof(val) )))
+ if ((r = get_arg(argp, &val, sizeof(val) )))
return r;
printk(KERN_DEBUG "iPPP-bundle: minor: %d, slave unit: %d, master unit: %d\n",
(int) min, (int) is->unit, (int) val);
@@ -472,30 +508,30 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
#endif
break;
case PPPIOCGUNIT: /* get ppp/isdn unit number */
- if ((r = set_arg((void *) arg, &is->unit, sizeof(is->unit) )))
+ if ((r = set_arg(argp, &is->unit, sizeof(is->unit) )))
return r;
break;
case PPPIOCGIFNAME:
if(!lp)
return -EINVAL;
- if ((r = set_arg((void *) arg, lp->name, strlen(lp->name))))
+ if ((r = set_arg(argp, lp->name, strlen(lp->name))))
return r;
break;
case PPPIOCGMPFLAGS: /* get configuration flags */
- if ((r = set_arg((void *) arg, &is->mpppcfg, sizeof(is->mpppcfg) )))
+ if ((r = set_arg(argp, &is->mpppcfg, sizeof(is->mpppcfg) )))
return r;
break;
case PPPIOCSMPFLAGS: /* set configuration flags */
- if ((r = get_arg((void *) arg, &val, sizeof(val) )))
+ if ((r = get_arg(argp, &val, sizeof(val) )))
return r;
is->mpppcfg = val;
break;
case PPPIOCGFLAGS: /* get configuration flags */
- if ((r = set_arg((void *) arg, &is->pppcfg,sizeof(is->pppcfg) )))
+ if ((r = set_arg(argp, &is->pppcfg,sizeof(is->pppcfg) )))
return r;
break;
case PPPIOCSFLAGS: /* set configuration flags */
- if ((r = get_arg((void *) arg, &val, sizeof(val) ))) {
+ if ((r = get_arg(argp, &val, sizeof(val) ))) {
return r;
}
if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
@@ -512,12 +548,12 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
if (lp) {
struct ppp_idle pidle;
pidle.xmit_idle = pidle.recv_idle = lp->huptimer;
- if ((r = set_arg((void *) arg, &pidle,sizeof(struct ppp_idle))))
+ if ((r = set_arg(argp, &pidle,sizeof(struct ppp_idle))))
return r;
}
break;
case PPPIOCSMRU: /* set receive unit size for PPP */
- if ((r = get_arg((void *) arg, &val, sizeof(val) )))
+ if ((r = get_arg(argp, &val, sizeof(val) )))
return r;
is->mru = val;
break;
@@ -526,7 +562,7 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
case PPPIOCSMPMTU:
break;
case PPPIOCSMAXCID: /* set the maximum compression slot id */
- if ((r = get_arg((void *) arg, &val, sizeof(val) )))
+ if ((r = get_arg(argp, &val, sizeof(val) )))
return r;
val++;
if (is->maxcid != val) {
@@ -549,11 +585,11 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
}
break;
case PPPIOCGDEBUG:
- if ((r = set_arg((void *) arg, &is->debug, sizeof(is->debug) )))
+ if ((r = set_arg(argp, &is->debug, sizeof(is->debug) )))
return r;
break;
case PPPIOCSDEBUG:
- if ((r = get_arg((void *) arg, &val, sizeof(val) )))
+ if ((r = get_arg(argp, &val, sizeof(val) )))
return r;
is->debug = val;
break;
@@ -568,12 +604,12 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
protos[j] |= (0x1<<i);
ipc = ipc->next;
}
- if ((r = set_arg((void *) arg,protos,8*sizeof(long) )))
+ if ((r = set_arg(argp,protos,8*sizeof(long) )))
return r;
}
break;
case PPPIOCSCOMPRESSOR:
- if ((r = get_arg((void *) arg, &data, sizeof(struct isdn_ppp_comp_data))))
+ if ((r = get_arg(argp, &data, sizeof(struct isdn_ppp_comp_data))))
return r;
return isdn_ppp_set_compressor(is, &data);
case PPPIOCGCALLINFO:
@@ -594,38 +630,29 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
if(lp->flags & ISDN_NET_CALLBACK)
pci.calltype |= CALLTYPE_CALLBACK;
}
- return set_arg((void *)arg,&pci,sizeof(struct pppcallinfo));
+ return set_arg(argp,&pci,sizeof(struct pppcallinfo));
}
#ifdef CONFIG_IPPP_FILTER
case PPPIOCSPASS:
+ {
+ struct sock_filter *code;
+ int len = get_filter(argp, &code);
+ if (len < 0)
+ return len;
+ kfree(is->pass_filter);
+ is->pass_filter = code;
+ is->pass_len = len;
+ break;
+ }
case PPPIOCSACTIVE:
{
- struct sock_fprog uprog, *filtp;
- struct sock_filter *code = NULL;
- int len, err;
-
- if (copy_from_user(&uprog, (void *) arg, sizeof(uprog)))
- return -EFAULT;
- if (uprog.len > 0) {
- len = uprog.len * sizeof(struct sock_filter);
- code = kmalloc(len, GFP_KERNEL);
- if (code == NULL)
- return -ENOMEM;
- if (copy_from_user(code, uprog.filter, len)) {
- kfree(code);
- return -EFAULT;
- }
- err = sk_chk_filter(code, uprog.len);
- if (err) {
- kfree(code);
- return err;
- }
- }
- filtp = (cmd == PPPIOCSPASS) ? &is->pass_filter : &is->active_filter;
- if (filtp->filter)
- kfree(filtp->filter);
- filtp->filter = code;
- filtp->len = uprog.len;
+ struct sock_filter *code;
+ int len = get_filter(argp, &code);
+ if (len < 0)
+ return len;
+ kfree(is->active_filter);
+ is->active_filter = code;
+ is->active_len = len;
break;
}
#endif /* CONFIG_IPPP_FILTER */
@@ -733,7 +760,7 @@ isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
*/
int
-isdn_ppp_read(int min, struct file *file, char *buf, int count)
+isdn_ppp_read(int min, struct file *file, char __user *buf, int count)
{
struct ippp_struct *is;
struct ippp_buf_queue *b;
@@ -746,7 +773,7 @@ isdn_ppp_read(int min, struct file *file, char *buf, int count)
if (!(is->state & IPPP_OPEN))
return 0;
- if ((r = verify_area(VERIFY_WRITE, (void *) buf, count)))
+ if ((r = verify_area(VERIFY_WRITE, buf, count)))
return r;
spin_lock_irqsave(&is->buflock, flags);
@@ -773,7 +800,7 @@ isdn_ppp_read(int min, struct file *file, char *buf, int count)
*/
int
-isdn_ppp_write(int min, struct file *file, const char *buf, int count)
+isdn_ppp_write(int min, struct file *file, const char __user *buf, int count)
{
isdn_net_local *lp;
struct ippp_struct *is;
@@ -1128,17 +1155,16 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
*p = 0; /* indicate inbound in DLT_LINUX_SLL */
}
- if (is->pass_filter.filter
- && sk_run_filter(skb, is->pass_filter.filter,
- is->pass_filter.len) == 0) {
+ if (is->pass_filter
+ && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0) {
if (is->debug & 0x2)
printk(KERN_DEBUG "IPPP: inbound frame filtered.\n");
kfree_skb(skb);
return;
}
- if (!(is->active_filter.filter
- && sk_run_filter(skb, is->active_filter.filter,
- is->active_filter.len) == 0)) {
+ if (!(is->active_filter
+ && sk_run_filter(skb, is->active_filter,
+ is->active_len) == 0)) {
if (is->debug & 0x2)
printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
lp->huptimer = 0;
@@ -1276,17 +1302,16 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
*p = htons(proto);
}
- if (ipt->pass_filter.filter
- && sk_run_filter(skb, ipt->pass_filter.filter,
- ipt->pass_filter.len) == 0) {
+ if (ipt->pass_filter
+ && sk_run_filter(skb, ipt->pass_filter, ipt->pass_len) == 0) {
if (ipt->debug & 0x4)
printk(KERN_DEBUG "IPPP: outbound frame filtered.\n");
kfree_skb(skb);
goto unlock;
}
- if (!(ipt->active_filter.filter
- && sk_run_filter(skb, ipt->active_filter.filter,
- ipt->active_filter.len) == 0)) {
+ if (!(ipt->active_filter
+ && sk_run_filter(skb, ipt->active_filter,
+ ipt->active_len) == 0)) {
if (ipt->debug & 0x4)
printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
lp->huptimer = 0;
@@ -1475,12 +1500,10 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
*p = htons(proto);
}
- drop |= is->pass_filter.filter
- && sk_run_filter(skb, is->pass_filter.filter,
- is->pass_filter.len) == 0;
- drop |= is->active_filter.filter
- && sk_run_filter(skb, is->active_filter.filter,
- is->active_filter.len) == 0;
+ drop |= is->pass_filter
+ && sk_run_filter(skb, is->pass_filter, is->pass_len) == 0;
+ drop |= is->active_filter
+ && sk_run_filter(skb, is->active_filter, is->active_len) == 0;
skb_push(skb, IPPP_MAX_HEADER - 4);
return drop;
@@ -1969,12 +1992,11 @@ out:
static int
isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
{
- struct ppp_stats *res,
- t;
+ struct ppp_stats __user *res = ifr->ifr_data;
+ struct ppp_stats t;
isdn_net_local *lp = (isdn_net_local *) dev->priv;
int err;
- res = (struct ppp_stats *) ifr->ifr_ifru.ifru_data;
err = verify_area(VERIFY_WRITE, res, sizeof(struct ppp_stats));
if (err)
@@ -2004,7 +2026,8 @@ isdn_ppp_dev_ioctl_stats(int slot, struct ifreq *ifr, struct net_device *dev)
}
#endif
}
- if( copy_to_user(res, &t, sizeof(struct ppp_stats))) return -EFAULT;
+ if (copy_to_user(res, &t, sizeof(struct ppp_stats)))
+ return -EFAULT;
return 0;
}
@@ -2012,7 +2035,6 @@ int
isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
int error=0;
- char *r;
int len;
isdn_net_local *lp = (isdn_net_local *) dev->priv;
@@ -2023,9 +2045,8 @@ isdn_ppp_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
switch (cmd) {
#define PPP_VERSION "2.3.7"
case SIOCGPPPVER:
- r = (char *) ifr->ifr_ifru.ifru_data;
len = strlen(PPP_VERSION) + 1;
- if (copy_to_user(r, PPP_VERSION, len))
+ if (copy_to_user(ifr->ifr_data, PPP_VERSION, len))
error = -EFAULT;
break;
diff --git a/drivers/isdn/i4l/isdn_ppp.h b/drivers/isdn/i4l/isdn_ppp.h
index f14b8a849a9d..8cc05c7ccf78 100644
--- a/drivers/isdn/i4l/isdn_ppp.h
+++ b/drivers/isdn/i4l/isdn_ppp.h
@@ -12,8 +12,8 @@
#include <linux/ppp_defs.h> /* for PPP_PROTOCOL */
#include <linux/isdn_ppp.h> /* for isdn_ppp info */
-extern int isdn_ppp_read(int, struct file *, char *, int);
-extern int isdn_ppp_write(int, struct file *, const char *, int);
+extern int isdn_ppp_read(int, struct file *, char __user *, int);
+extern int isdn_ppp_write(int, struct file *, const char __user *, int);
extern int isdn_ppp_open(int, struct file *);
extern int isdn_ppp_init(void);
extern void isdn_ppp_cleanup(void);
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 53dc879651e4..8ffa894c3017 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -55,8 +55,9 @@
#include <linux/if_arp.h> /* For ARPHRD_ETHER */
#include <linux/ip.h>
#include <linux/tcp.h>
+#include <linux/percpu.h>
-static struct net_device_stats *loopback_stats;
+static DEFINE_PER_CPU(struct net_device_stats, loopback_stats);
#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
@@ -124,6 +125,7 @@ static void emulate_large_send_offload(struct sk_buff *skb)
*/
static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
{
+ struct net_device_stats *lb_stats;
skb_orphan(skb);
@@ -142,13 +144,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
}
dev->last_rx = jiffies;
- if (likely(loopback_stats)) {
- get_cpu_ptr(loopback_stats)->rx_bytes += skb->len;
- get_cpu_ptr(loopback_stats)->tx_bytes += skb->len;
- get_cpu_ptr(loopback_stats)->rx_packets++;
- get_cpu_ptr(loopback_stats)->tx_packets++;
- put_cpu_ptr(loopback_stats);
- }
+
+ lb_stats = &per_cpu(loopback_stats, get_cpu());
+ lb_stats->rx_bytes += skb->len;
+ lb_stats->tx_bytes += skb->len;
+ lb_stats->rx_packets++;
+ lb_stats->tx_packets++;
+ put_cpu();
netif_rx(skb);
@@ -165,17 +167,17 @@ static struct net_device_stats *get_stats(struct net_device *dev)
}
memset(stats, 0, sizeof(struct net_device_stats));
- if (!loopback_stats) {
- return stats;
- }
for (i=0; i < NR_CPUS; i++) {
+ struct net_device_stats *lb_stats;
+
if (!cpu_possible(i))
continue;
- stats->rx_bytes += per_cpu_ptr(loopback_stats, i)->rx_bytes;
- stats->tx_bytes += per_cpu_ptr(loopback_stats, i)->tx_bytes;
- stats->rx_packets += per_cpu_ptr(loopback_stats, i)->rx_packets;
- stats->tx_packets += per_cpu_ptr(loopback_stats, i)->tx_packets;
+ lb_stats = &per_cpu(loopback_stats, i);
+ stats->rx_bytes += lb_stats->rx_bytes;
+ stats->tx_bytes += lb_stats->tx_bytes;
+ stats->rx_packets += lb_stats->rx_packets;
+ stats->tx_packets += lb_stats->tx_packets;
}
return stats;
@@ -211,8 +213,6 @@ int __init loopback_init(void)
loopback_dev.priv = stats;
loopback_dev.get_stats = &get_stats;
}
-
- loopback_stats = alloc_percpu(struct net_device_stats);
return register_netdev(&loopback_dev);
};
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index ffd5ac3a848e..8523970c73ed 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -129,8 +129,9 @@ struct ppp {
#endif /* CONFIG_PPP_MULTILINK */
struct net_device_stats stats; /* statistics */
#ifdef CONFIG_PPP_FILTER
- struct sock_fprog pass_filter; /* filter for packets to pass */
- struct sock_fprog active_filter;/* filter for pkts to reset idle */
+ struct sock_filter *pass_filter; /* filter for packets to pass */
+ struct sock_filter *active_filter;/* filter for pkts to reset idle */
+ unsigned pass_len, active_len;
#endif /* CONFIG_PPP_FILTER */
};
@@ -493,6 +494,43 @@ static unsigned int ppp_poll(struct file *file, poll_table *wait)
return mask;
}
+static int get_filter(void __user *arg, struct sock_filter **p)
+{
+ struct sock_fprog uprog;
+ struct sock_filter *code = NULL;
+ int len, err;
+
+ if (copy_from_user(&uprog, arg, sizeof(uprog)))
+ return -EFAULT;
+
+ if (uprog.len > BPF_MAXINSNS)
+ return -EINVAL;
+
+ if (!uprog.len) {
+ *p = NULL;
+ return 0;
+ }
+
+ len = uprog.len * sizeof(struct sock_filter);
+ code = kmalloc(len, GFP_KERNEL);
+ if (code == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(code, uprog.filter, len)) {
+ kfree(code);
+ return -EFAULT;
+ }
+
+ err = sk_chk_filter(code, uprog.len);
+ if (err) {
+ kfree(code);
+ return err;
+ }
+
+ *p = code;
+ return uprog.len;
+}
+
static int ppp_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -503,6 +541,8 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
struct npioctl npi;
int unit, cflags;
struct slcompress *vj;
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
if (pf == 0)
return ppp_unattached_ioctl(pf, file, cmd, arg);
@@ -540,7 +580,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case PPPIOCCONNECT:
- if (get_user(unit, (int *) arg))
+ if (get_user(unit, p))
break;
err = ppp_connect_channel(pch, unit);
break;
@@ -569,14 +609,14 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
ppp = PF_TO_PPP(pf);
switch (cmd) {
case PPPIOCSMRU:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
break;
ppp->mru = val;
err = 0;
break;
case PPPIOCSFLAGS:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
break;
ppp_lock(ppp);
cflags = ppp->flags & ~val;
@@ -589,7 +629,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
case PPPIOCGFLAGS:
val = ppp->flags | ppp->xstate | ppp->rstate;
- if (put_user(val, (int *) arg))
+ if (put_user(val, p))
break;
err = 0;
break;
@@ -599,20 +639,20 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
break;
case PPPIOCGUNIT:
- if (put_user(ppp->file.index, (int *) arg))
+ if (put_user(ppp->file.index, p))
break;
err = 0;
break;
case PPPIOCSDEBUG:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
break;
ppp->debug = val;
err = 0;
break;
case PPPIOCGDEBUG:
- if (put_user(ppp->debug, (int *) arg))
+ if (put_user(ppp->debug, p))
break;
err = 0;
break;
@@ -620,13 +660,13 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
case PPPIOCGIDLE:
idle.xmit_idle = (jiffies - ppp->last_xmit) / HZ;
idle.recv_idle = (jiffies - ppp->last_recv) / HZ;
- if (copy_to_user((void __user *) arg, &idle, sizeof(idle)))
+ if (copy_to_user(argp, &idle, sizeof(idle)))
break;
err = 0;
break;
case PPPIOCSMAXCID:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
break;
val2 = 15;
if ((val >> 16) != 0) {
@@ -649,7 +689,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
case PPPIOCGNPMODE:
case PPPIOCSNPMODE:
- if (copy_from_user(&npi, (void __user *) arg, sizeof(npi)))
+ if (copy_from_user(&npi, argp, sizeof(npi)))
break;
err = proto_to_npindex(npi.protocol);
if (err < 0)
@@ -658,7 +698,7 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
if (cmd == PPPIOCGNPMODE) {
err = -EFAULT;
npi.mode = ppp->npmode[i];
- if (copy_to_user((void __user *) arg, &npi, sizeof(npi)))
+ if (copy_to_user(argp, &npi, sizeof(npi)))
break;
} else {
ppp->npmode[i] = npi.mode;
@@ -670,49 +710,38 @@ static int ppp_ioctl(struct inode *inode, struct file *file,
#ifdef CONFIG_PPP_FILTER
case PPPIOCSPASS:
+ {
+ struct sock_filter *code;
+ err = get_filter(argp, &code);
+ if (err >= 0) {
+ ppp_lock(ppp);
+ kfree(ppp->pass_filter);
+ ppp->pass_filter = code;
+ ppp->pass_len = err;
+ ppp_unlock(ppp);
+ err = 0;
+ }
+ break;
+ }
case PPPIOCSACTIVE:
{
- struct sock_fprog uprog, *filtp;
- struct sock_filter *code = NULL;
- int len;
-
- if (copy_from_user(&uprog, (void __user *) arg, sizeof(uprog)))
- break;
- err = -EINVAL;
- if (uprog.len > BPF_MAXINSNS)
- break;
- err = -ENOMEM;
- if (uprog.len > 0) {
- len = uprog.len * sizeof(struct sock_filter);
- code = kmalloc(len, GFP_KERNEL);
- if (code == NULL)
- break;
- err = -EFAULT;
- if (copy_from_user(code, (void __user *) uprog.filter, len)) {
- kfree(code);
- break;
- }
- err = sk_chk_filter(code, uprog.len);
- if (err) {
- kfree(code);
- break;
- }
+ struct sock_filter *code;
+ err = get_filter(argp, &code);
+ if (err >= 0) {
+ ppp_lock(ppp);
+ kfree(ppp->active_filter);
+ ppp->active_filter = code;
+ ppp->active_len = err;
+ ppp_unlock(ppp);
+ err = 0;
}
- filtp = (cmd == PPPIOCSPASS)? &ppp->pass_filter: &ppp->active_filter;
- ppp_lock(ppp);
- if (filtp->filter)
- kfree(filtp->filter);
- filtp->filter = code;
- filtp->len = uprog.len;
- ppp_unlock(ppp);
- err = 0;
break;
}
#endif /* CONFIG_PPP_FILTER */
#ifdef CONFIG_PPP_MULTILINK
case PPPIOCSMRRU:
- if (get_user(val, (int *) arg))
+ if (get_user(val, p))
break;
ppp_recv_lock(ppp);
ppp->mrru = val;
@@ -734,11 +763,12 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
int unit, err = -EFAULT;
struct ppp *ppp;
struct channel *chan;
+ int __user *p = (int __user *)arg;
switch (cmd) {
case PPPIOCNEWUNIT:
/* Create a new ppp unit */
- if (get_user(unit, (int *) arg))
+ if (get_user(unit, p))
break;
ppp = ppp_create_interface(unit, &err);
if (ppp == 0)
@@ -746,14 +776,14 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
file->private_data = &ppp->file;
ppp->owner = file;
err = -EFAULT;
- if (put_user(ppp->file.index, (int *) arg))
+ if (put_user(ppp->file.index, p))
break;
err = 0;
break;
case PPPIOCATTACH:
/* Attach to an existing ppp unit */
- if (get_user(unit, (int *) arg))
+ if (get_user(unit, p))
break;
down(&all_ppp_sem);
err = -ENXIO;
@@ -767,7 +797,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
break;
case PPPIOCATTCHAN:
- if (get_user(unit, (int *) arg))
+ if (get_user(unit, p))
break;
spin_lock_bh(&all_channels_lock);
err = -ENXIO;
@@ -999,18 +1029,18 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
*p = htons(4); /* indicate outbound in DLT_LINUX_SLL */;
}
- if (ppp->pass_filter.filter
- && sk_run_filter(skb, ppp->pass_filter.filter,
- ppp->pass_filter.len) == 0) {
+ if (ppp->pass_filter
+ && sk_run_filter(skb, ppp->pass_filter,
+ ppp->pass_len) == 0) {
if (ppp->debug & 1)
printk(KERN_DEBUG "PPP: outbound frame not passed\n");
kfree_skb(skb);
return;
}
/* if this packet passes the active filter, record the time */
- if (!(ppp->active_filter.filter
- && sk_run_filter(skb, ppp->active_filter.filter,
- ppp->active_filter.len) == 0))
+ if (!(ppp->active_filter
+ && sk_run_filter(skb, ppp->active_filter,
+ ppp->active_len) == 0))
ppp->last_xmit = jiffies;
skb_pull(skb, 2);
#else
@@ -1546,17 +1576,17 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
*p = 0; /* indicate inbound in DLT_LINUX_SLL */
}
- if (ppp->pass_filter.filter
- && sk_run_filter(skb, ppp->pass_filter.filter,
- ppp->pass_filter.len) == 0) {
+ if (ppp->pass_filter
+ && sk_run_filter(skb, ppp->pass_filter,
+ ppp->pass_len) == 0) {
if (ppp->debug & 1)
printk(KERN_DEBUG "PPP: inbound frame not passed\n");
kfree_skb(skb);
return;
}
- if (!(ppp->active_filter.filter
- && sk_run_filter(skb, ppp->active_filter.filter,
- ppp->active_filter.len) == 0))
+ if (!(ppp->active_filter
+ && sk_run_filter(skb, ppp->active_filter,
+ ppp->active_len) == 0))
ppp->last_recv = jiffies;
skb_pull(skb, 2);
#else
@@ -2423,13 +2453,13 @@ static void ppp_destroy_interface(struct ppp *ppp)
skb_queue_purge(&ppp->mrq);
#endif /* CONFIG_PPP_MULTILINK */
#ifdef CONFIG_PPP_FILTER
- if (ppp->pass_filter.filter) {
- kfree(ppp->pass_filter.filter);
- ppp->pass_filter.filter = NULL;
+ if (ppp->pass_filter) {
+ kfree(ppp->pass_filter);
+ ppp->pass_filter = NULL;
}
- if (ppp->active_filter.filter) {
- kfree(ppp->active_filter.filter);
- ppp->active_filter.filter = 0;
+ if (ppp->active_filter) {
+ kfree(ppp->active_filter);
+ ppp->active_filter = 0;
}
#endif /* CONFIG_PPP_FILTER */
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index b831eef1bca2..6fe6f3601a98 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -33,6 +33,7 @@
#include <linux/crc32.h>
#include <linux/random.h>
#include <linux/workqueue.h>
+#include <linux/if_vlan.h>
#include <asm/system.h>
#include <asm/bitops.h>
@@ -742,7 +743,7 @@ static void gem_rx(struct gem *gp)
PCI_DMA_FROMDEVICE);
gp->rx_skbs[entry] = new_skb;
new_skb->dev = gp->dev;
- skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET));
+ skb_put(new_skb, (gp->rx_buf_sz + RX_OFFSET));
rxd->buffer = cpu_to_le64(pci_map_page(gp->pdev,
virt_to_page(new_skb->data),
offset_in_page(new_skb->data),
@@ -1482,6 +1483,9 @@ static void gem_init_rings(struct gem *gp)
gem_clean_rings(gp);
+ gp->rx_buf_sz = max(dev->mtu + ETH_HLEN + VLAN_HLEN,
+ (unsigned)VLAN_ETH_FRAME_LEN);
+
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
struct gem_rxd *rxd = &gb->rxd[i];
@@ -1495,7 +1499,7 @@ static void gem_init_rings(struct gem *gp)
gp->rx_skbs[i] = skb;
skb->dev = dev;
- skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET));
+ skb_put(skb, (gp->rx_buf_sz + RX_OFFSET));
dma_addr = pci_map_page(gp->pdev,
virt_to_page(skb->data),
offset_in_page(skb->data),
@@ -1750,7 +1754,7 @@ static void gem_init_mac(struct gem *gp)
writel(0x40, gp->regs + MAC_MINFSZ);
/* Ethernet payload + header + FCS + optional VLAN tag. */
- writel(0x20000000 | (gp->dev->mtu + ETH_HLEN + 4 + 4), gp->regs + MAC_MAXFSZ);
+ writel(0x20000000 | (gp->rx_buf_sz + 4), gp->regs + MAC_MAXFSZ);
writel(0x07, gp->regs + MAC_PASIZE);
writel(0x04, gp->regs + MAC_JAMSIZE);
@@ -1827,7 +1831,7 @@ static void gem_init_pause_thresholds(struct gem *gp)
if (gp->rx_fifo_sz <= (2 * 1024)) {
gp->rx_pause_off = gp->rx_pause_on = gp->rx_fifo_sz;
} else {
- int max_frame = (gp->dev->mtu + ETH_HLEN + 4 + 4 + 64) & ~63;
+ int max_frame = (gp->rx_buf_sz + 4 + 64) & ~63;
int off = (gp->rx_fifo_sz - (max_frame * 2));
int on = off - max_frame;
diff --git a/drivers/net/sungem.h b/drivers/net/sungem.h
index ab83530f20ae..eed77bfe1b60 100644
--- a/drivers/net/sungem.h
+++ b/drivers/net/sungem.h
@@ -911,7 +911,7 @@ struct gem_rxd {
(GP)->tx_old - (GP)->tx_new - 1)
#define RX_OFFSET 2
-#define RX_BUF_ALLOC_SIZE(gp) ((gp)->dev->mtu + 46 + RX_OFFSET + 64)
+#define RX_BUF_ALLOC_SIZE(gp) ((gp)->rx_buf_sz + 28 + RX_OFFSET + 64)
#define RX_COPY_THRESHOLD 256
@@ -979,6 +979,7 @@ struct gem {
int rx_fifo_sz;
int rx_pause_off;
int rx_pause_on;
+ int rx_buf_sz;
int mii_phy_addr;
u32 mac_rx_cfg;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 10fa8e79d98e..dd1c6155fdd3 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -127,6 +127,7 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */
#include <linux/ioport.h>
#include <linux/netdevice.h>
+#include <linux/ip.h>
#include <linux/trdevice.h>
#include <linux/ibmtr.h>
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 7f471804045e..e8cfa4fc993a 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -220,7 +220,8 @@ static int c101_close(struct net_device *dev)
static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
const size_t size = sizeof(sync_serial_settings);
- sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync;
+ sync_serial_settings new_line;
+ sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
port_t *port = dev_to_port(dev);
#ifdef DEBUG_RINGS
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index a4d0452c3c97..da86c5132a4d 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -301,9 +301,9 @@ static char *chrdev_setup_rx(struct channel_data *channel, int size);
static int chrdev_rx_done(struct channel_data *channel);
static int chrdev_tx_done(struct channel_data *channel, int size);
static ssize_t cosa_read(struct file *file,
- char *buf, size_t count, loff_t *ppos);
+ char __user *buf, size_t count, loff_t *ppos);
static ssize_t cosa_write(struct file *file,
- const char *buf, size_t count, loff_t *ppos);
+ const char __user *buf, size_t count, loff_t *ppos);
static unsigned int cosa_poll(struct file *file, poll_table *poll);
static int cosa_open(struct inode *inode, struct file *file);
static int cosa_release(struct inode *inode, struct file *file);
@@ -330,13 +330,13 @@ static struct file_operations cosa_fops = {
/* Ioctls */
static int cosa_start(struct cosa_data *cosa, int address);
static int cosa_reset(struct cosa_data *cosa);
-static int cosa_download(struct cosa_data *cosa, unsigned long a);
-static int cosa_readmem(struct cosa_data *cosa, unsigned long a);
+static int cosa_download(struct cosa_data *cosa, void __user *a);
+static int cosa_readmem(struct cosa_data *cosa, void __user *a);
/* COSA/SRP ROM monitor */
-static int download(struct cosa_data *cosa, const char *data, int addr, int len);
+static int download(struct cosa_data *cosa, const char __user *data, int addr, int len);
static int startmicrocode(struct cosa_data *cosa, int address);
-static int readmem(struct cosa_data *cosa, char *data, int addr, int len);
+static int readmem(struct cosa_data *cosa, char __user *data, int addr, int len);
static int cosa_reset_and_read_id(struct cosa_data *cosa, char *id);
/* Auxilliary functions */
@@ -830,7 +830,7 @@ static void chardev_channel_init(struct channel_data *chan)
}
static ssize_t cosa_read(struct file *file,
- char *buf, size_t count, loff_t *ppos)
+ char __user *buf, size_t count, loff_t *ppos)
{
DECLARE_WAITQUEUE(wait, current);
unsigned long flags;
@@ -905,7 +905,7 @@ static int chrdev_rx_done(struct channel_data *chan)
static ssize_t cosa_write(struct file *file,
- const char *buf, size_t count, loff_t *ppos)
+ const char __user *buf, size_t count, loff_t *ppos)
{
DECLARE_WAITQUEUE(wait, current);
struct channel_data *chan = file->private_data;
@@ -1066,7 +1066,7 @@ static inline int cosa_reset(struct cosa_data *cosa)
}
/* High-level function to download data into COSA memory. Calls download() */
-static inline int cosa_download(struct cosa_data *cosa, unsigned long arg)
+static inline int cosa_download(struct cosa_data *cosa, void __user *arg)
{
struct cosa_download d;
int i;
@@ -1080,7 +1080,7 @@ static inline int cosa_download(struct cosa_data *cosa, unsigned long arg)
return -EPERM;
}
- if (copy_from_user(&d, (void __user *) arg, sizeof(d)))
+ if (copy_from_user(&d, arg, sizeof(d)))
return -EFAULT;
if (d.addr < 0 || d.addr > COSA_MAX_FIRMWARE_SIZE)
@@ -1105,7 +1105,7 @@ static inline int cosa_download(struct cosa_data *cosa, unsigned long arg)
}
/* High-level function to read COSA memory. Calls readmem() */
-static inline int cosa_readmem(struct cosa_data *cosa, unsigned long arg)
+static inline int cosa_readmem(struct cosa_data *cosa, void __user *arg)
{
struct cosa_download d;
int i;
@@ -1120,7 +1120,7 @@ static inline int cosa_readmem(struct cosa_data *cosa, unsigned long arg)
return -EPERM;
}
- if (copy_from_user(&d, (void __user *) arg, sizeof(d)))
+ if (copy_from_user(&d, arg, sizeof(d)))
return -EFAULT;
/* If something fails, force the user to reset the card */
@@ -1167,7 +1167,7 @@ static inline int cosa_start(struct cosa_data *cosa, int address)
}
/* Buffer of size at least COSA_MAX_ID_STRING is expected */
-static inline int cosa_getidstr(struct cosa_data *cosa, char *string)
+static inline int cosa_getidstr(struct cosa_data *cosa, char __user *string)
{
int l = strlen(cosa->id_string)+1;
if (copy_to_user(string, cosa->id_string, l))
@@ -1176,7 +1176,7 @@ static inline int cosa_getidstr(struct cosa_data *cosa, char *string)
}
/* Buffer of size at least COSA_MAX_ID_STRING is expected */
-static inline int cosa_gettype(struct cosa_data *cosa, char *string)
+static inline int cosa_gettype(struct cosa_data *cosa, char __user *string)
{
int l = strlen(cosa->type)+1;
if (copy_to_user(string, cosa->type, l))
@@ -1187,6 +1187,7 @@ static inline int cosa_gettype(struct cosa_data *cosa, char *string)
static int cosa_ioctl_common(struct cosa_data *cosa,
struct channel_data *channel, unsigned int cmd, unsigned long arg)
{
+ void __user *argp = (void __user *)arg;
switch(cmd) {
case COSAIORSET: /* Reset the device */
if (!capable(CAP_NET_ADMIN))
@@ -1200,15 +1201,15 @@ static int cosa_ioctl_common(struct cosa_data *cosa,
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return cosa_download(cosa, arg);
+ return cosa_download(cosa, argp);
case COSAIORMEM:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return cosa_readmem(cosa, arg);
+ return cosa_readmem(cosa, argp);
case COSAIORTYPE:
- return cosa_gettype(cosa, (char *)arg);
+ return cosa_gettype(cosa, argp);
case COSAIORIDSTR:
- return cosa_getidstr(cosa, (char *)arg);
+ return cosa_getidstr(cosa, argp);
case COSAIONRCARDS:
return nr_cards;
case COSAIONRCHANS:
@@ -1434,7 +1435,7 @@ static int cosa_dma_able(struct channel_data *chan, char *buf, int len)
* by a single space. Monitor has to reply with a space. Now the download
* begins. After the download monitor replies with "\r\n." (CR LF dot).
*/
-static int download(struct cosa_data *cosa, const char *microcode, int length, int address)
+static int download(struct cosa_data *cosa, const char __user *microcode, int length, int address)
{
int i;
@@ -1508,7 +1509,7 @@ static int startmicrocode(struct cosa_data *cosa, int address)
* This routine is not needed during the normal operation and serves
* for debugging purposes only.
*/
-static int readmem(struct cosa_data *cosa, char *microcode, int length, int address)
+static int readmem(struct cosa_data *cosa, char __user *microcode, int length, int address)
{
if (put_wait_data(cosa, 'r') == -1) return -1;
if ((get_wait_data(cosa)) != 'r') return -2;
diff --git a/drivers/net/wan/cosa.h b/drivers/net/wan/cosa.h
index b59e3efffa73..63a8a5c42f0a 100644
--- a/drivers/net/wan/cosa.h
+++ b/drivers/net/wan/cosa.h
@@ -66,7 +66,7 @@
/* ioctls */
struct cosa_download {
int addr, len;
- char *code;
+ char __user *code;
};
/* Reset the device */
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index b98f27e99a9a..4cbda752b07e 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -1296,7 +1296,7 @@ done:
static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
- sync_serial_settings *line = ifr->ifr_settings.ifs_ifsu.sync;
+ sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
const size_t size = sizeof(dpriv->settings);
int ret = 0;
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 31b379da2ed9..c1b6896d7007 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -272,7 +272,7 @@ static void cisco_stop(struct net_device *dev)
int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
{
- cisco_proto *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco;
+ cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco;
const size_t size = sizeof(cisco_proto);
cisco_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 8feed459c284..7f450b51a6cb 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1137,7 +1137,7 @@ static void fr_destroy(hdlc_device *hdlc)
int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
{
- fr_proto *fr_s = ifr->ifr_settings.ifs_ifsu.fr;
+ fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr;
const size_t size = sizeof(fr_proto);
fr_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index 42690658b146..c41fb70b6929 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -34,7 +34,7 @@ static unsigned short raw_type_trans(struct sk_buff *skb,
int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
{
- raw_hdlc_proto *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
+ raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
const size_t size = sizeof(raw_hdlc_proto);
raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 4ddc2e08c4ec..b1285cc8fee6 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -46,7 +46,7 @@ static int eth_tx(struct sk_buff *skb, struct net_device *dev)
int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
{
- raw_hdlc_proto *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
+ raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
const size_t size = sizeof(raw_hdlc_proto);
raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
diff --git a/drivers/net/wan/lmc/lmc_ioctl.h b/drivers/net/wan/lmc/lmc_ioctl.h
index 38f3c1bca827..57dd861cd3db 100644
--- a/drivers/net/wan/lmc/lmc_ioctl.h
+++ b/drivers/net/wan/lmc/lmc_ioctl.h
@@ -234,7 +234,7 @@ typedef struct lmc_st1f_control {
int command;
int address;
int value;
- char *data;
+ char __user *data;
} lmc_t1f_control;
enum lmc_xilinx_c {
@@ -246,7 +246,7 @@ enum lmc_xilinx_c {
struct lmc_xilinx_control {
enum lmc_xilinx_c command;
int len;
- char *data;
+ char __user *data;
};
/* ------------------ end T1 defs ------------------- */
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 179b750cc8a8..9dc4a8db2a9f 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -254,7 +254,8 @@ static int n2_close(struct net_device *dev)
static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
const size_t size = sizeof(sync_serial_settings);
- sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync;
+ sync_serial_settings new_line;
+ sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
port_t *port = dev_to_port(dev);
#ifdef DEBUG_RINGS
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index 899034164003..0ea4b239e27b 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -204,7 +204,8 @@ static int pci200_close(struct net_device *dev)
static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
const size_t size = sizeof(sync_serial_settings);
- sync_serial_settings new_line, *line = ifr->ifr_settings.ifs_ifsu.sync;
+ sync_serial_settings new_line;
+ sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
port_t *port = dev_to_port(dev);
#ifdef DEBUG_RINGS
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 4243fea5354d..9fb04ca14cb5 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -733,7 +733,7 @@ static int x25_asy_ioctl(struct tty_struct *tty, struct file *file,
switch(cmd) {
case SIOCGIFNAME:
- if (copy_to_user((void *)arg, sl->dev->name,
+ if (copy_to_user((void __user *)arg, sl->dev->name,
strlen(sl->dev->name) + 1))
return -EFAULT;
return 0;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 0dea6b1ddd52..9936879eb719 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -539,6 +539,7 @@ struct bus_type pci_bus_type = {
.hotplug = pci_hotplug,
.suspend = pci_device_suspend,
.resume = pci_device_resume,
+ .dev_attrs = pci_dev_attrs,
};
static int __init pci_driver_init(void)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 34161c9f88ff..120a441a88d6 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -23,14 +23,13 @@
/* show configuration fields */
#define pci_config_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+field##_show(struct device *dev, char *buf) \
{ \
struct pci_dev *pdev; \
\
pdev = to_pci_dev (dev); \
return sprintf (buf, format_string, pdev->field); \
-} \
-static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);
+}
pci_config_attr(vendor, "0x%04x\n");
pci_config_attr(device, "0x%04x\n");
@@ -41,7 +40,7 @@ pci_config_attr(irq, "%u\n");
/* show resources */
static ssize_t
-pci_show_resources(struct device * dev, char * buf)
+resource_show(struct device * dev, char * buf)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
char * str = buf;
@@ -60,7 +59,16 @@ pci_show_resources(struct device * dev, char * buf)
return (str - buf);
}
-static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);
+struct device_attribute pci_dev_attrs[] = {
+ __ATTR_RO(resource),
+ __ATTR_RO(vendor),
+ __ATTR_RO(device),
+ __ATTR_RO(subsystem_vendor),
+ __ATTR_RO(subsystem_device),
+ __ATTR_RO(class),
+ __ATTR_RO(irq),
+ __ATTR_NULL,
+};
static ssize_t
pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
@@ -180,21 +188,10 @@ static struct bin_attribute pcie_config_attr = {
void pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
- struct device *dev = &pdev->dev;
-
- /* current configuration's attributes */
- device_create_file (dev, &dev_attr_vendor);
- device_create_file (dev, &dev_attr_device);
- device_create_file (dev, &dev_attr_subsystem_vendor);
- device_create_file (dev, &dev_attr_subsystem_device);
- device_create_file (dev, &dev_attr_class);
- device_create_file (dev, &dev_attr_irq);
- device_create_file (dev, &dev_attr_resource);
-
if (pdev->cfg_size < 4096)
- sysfs_create_bin_file(&dev->kobj, &pci_config_attr);
+ sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
- sysfs_create_bin_file(&dev->kobj, &pcie_config_attr);
+ sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
/* add platform-specific attributes */
pcibios_add_platform_entries(pdev);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index e1985b618fc9..a9b243770580 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -62,3 +62,4 @@ extern int pci_visit_dev(struct pci_visit *fn,
extern spinlock_t pci_bus_lock;
extern int pciehp_msi_quirk;
+extern struct device_attribute pci_dev_attrs[];
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 6104ca04656c..e54ebde20fa2 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -433,6 +433,14 @@ config SCSI_ATA_PIIX
If unsure, say N.
+config SCSI_SATA_NV
+ tristate "NVIDIA SATA support"
+ depends on SCSI_SATA && PCI && EXPERIMENTAL
+ help
+ This option enables support for NVIDIA Serial ATA.
+
+ If unsure, say N.
+
config SCSI_SATA_PROMISE
tristate "Promise SATA TX2/TX4 support"
depends on SCSI_SATA && PCI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index fe95ba7809f0..e117d9a616fe 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -127,6 +127,7 @@ obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o
obj-$(CONFIG_SCSI_SATA_SIS) += libata.o sata_sis.o
obj-$(CONFIG_SCSI_SATA_SX4) += libata.o sata_sx4.o
+obj-$(CONFIG_SCSI_SATA_NV) += libata.o sata_nv.o
obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index a6588b0f8c98..ff2e7385f59a 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -57,6 +57,7 @@ enum {
ich5_pata = 0,
ich5_sata = 1,
piix4_pata = 2,
+ ich6_sata = 3,
};
static int piix_init_one (struct pci_dev *pdev,
@@ -91,10 +92,8 @@ static struct pci_device_id piix_pci_tbl[] = {
* and enhanced mode, with queueing and other fancy stuff.
* This is distinguished by PCI class code.
*/
- { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_STORAGE_IDE << 8, 0xffff00, ich5_sata },
- { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID,
- PCI_CLASS_STORAGE_IDE << 8, 0xffff00, ich5_sata },
+ { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
+ { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
{ } /* terminate list */
};
@@ -138,7 +137,7 @@ static struct ata_port_operations piix_pata_ops = {
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
- .fill_sg = ata_fill_sg,
+ .qc_prep = ata_qc_prep,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
@@ -161,7 +160,7 @@ static struct ata_port_operations piix_sata_ops = {
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
- .fill_sg = ata_fill_sg,
+ .qc_prep = ata_qc_prep,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
@@ -199,6 +198,17 @@ static struct ata_port_info piix_port_info[] = {
.udma_mask = ATA_UDMA_MASK_40C, /* FIXME: cbl det */
.port_ops = &piix_pata_ops,
},
+
+ /* ich6_sata */
+ {
+ .sht = &piix_sht,
+ .host_flags = ATA_FLAG_SATA | ATA_FLAG_SRST |
+ PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
+ ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x03, /* pio3-4 */
+ .udma_mask = 0x7f, /* udma0-6 ; FIXME */
+ .port_ops = &piix_sata_ops,
+ },
};
static struct pci_bits piix_enable_bits[] = {
@@ -327,13 +337,6 @@ static int piix_sata_probe (struct ata_port *ap)
static void piix_sata_phy_reset(struct ata_port *ap)
{
- if (!pci_test_config_bits(ap->host_set->pdev,
- &piix_enable_bits[ap->port_no])) {
- ata_port_disable(ap);
- printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
- return;
- }
-
if (!piix_sata_probe(ap)) {
ata_port_disable(ap);
printk(KERN_INFO "ata%u: SATA port has no device.\n", ap->id);
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 29dee2c25ba0..d1fadbc4ba78 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -50,7 +50,6 @@ static unsigned int ata_busy_sleep (struct ata_port *ap,
unsigned long tmout_pat,
unsigned long tmout);
static void __ata_dev_select (struct ata_port *ap, unsigned int device);
-static void ata_dma_complete(struct ata_queued_cmd *qc, u8 host_stat);
static void ata_host_set_pio(struct ata_port *ap);
static void ata_host_set_udma(struct ata_port *ap);
static void ata_dev_set_pio(struct ata_port *ap, unsigned int device);
@@ -65,37 +64,6 @@ MODULE_AUTHOR("Jeff Garzik");
MODULE_DESCRIPTION("Library module for ATA devices");
MODULE_LICENSE("GPL");
-static const char * thr_state_name[] = {
- "THR_UNKNOWN",
- "THR_PORT_RESET",
- "THR_AWAIT_DEATH",
- "THR_PROBE_FAILED",
- "THR_IDLE",
- "THR_PROBE_SUCCESS",
- "THR_PROBE_START",
-};
-
-/**
- * ata_thr_state_name - convert thread state enum to string
- * @thr_state: thread state to be converted to string
- *
- * Converts the specified thread state id to a constant C string.
- *
- * LOCKING:
- * None.
- *
- * RETURNS:
- * The THR_xxx-prefixed string naming the specified thread
- * state id, or the string "<invalid THR_xxx state>".
- */
-
-static const char *ata_thr_state_name(unsigned int thr_state)
-{
- if (thr_state < ARRAY_SIZE(thr_state_name))
- return thr_state_name[thr_state];
- return "<invalid THR_xxx state>";
-}
-
/**
* ata_tf_load_pio - send taskfile registers to host controller
* @ap: Port to which output is sent
@@ -1150,13 +1118,16 @@ err_out:
}
/**
- * ata_port_reset -
- * @ap:
+ * ata_bus_probe - Reset and probe ATA bus
+ * @ap: Bus to probe
*
* LOCKING:
+ *
+ * RETURNS:
+ * Zero on success, non-zero on error.
*/
-static void ata_port_reset(struct ata_port *ap)
+static int ata_bus_probe(struct ata_port *ap)
{
unsigned int i, found = 0;
@@ -1180,14 +1151,12 @@ static void ata_port_reset(struct ata_port *ap)
if (ap->flags & ATA_FLAG_PORT_DISABLED)
goto err_out_disable;
- ap->thr_state = THR_PROBE_SUCCESS;
-
- return;
+ return 0;
err_out_disable:
ap->ops->port_disable(ap);
err_out:
- ap->thr_state = THR_PROBE_FAILED;
+ return -1;
}
/**
@@ -1806,13 +1775,13 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
}
/**
- * ata_fill_sg -
- * @qc:
+ * ata_fill_sg - Fill PCI IDE PRD table
+ * @qc: Metadata associated with taskfile to be transferred
*
* LOCKING:
*
*/
-void ata_fill_sg(struct ata_queued_cmd *qc)
+static void ata_fill_sg(struct ata_queued_cmd *qc)
{
struct scatterlist *sg = qc->sg;
struct ata_port *ap = qc->ap;
@@ -1854,6 +1823,21 @@ void ata_fill_sg(struct ata_queued_cmd *qc)
}
/**
+ * ata_qc_prep - Prepare taskfile for submission
+ * @qc: Metadata associated with taskfile to be prepared
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host_set lock)
+ */
+void ata_qc_prep(struct ata_queued_cmd *qc)
+{
+ if (!(qc->flags & ATA_QCFLAG_SG))
+ return;
+
+ ata_fill_sg(qc);
+}
+
+/**
* ata_sg_setup_one -
* @qc:
*
@@ -1870,7 +1854,6 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
struct scsi_cmnd *cmd = qc->scsicmd;
int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
struct scatterlist *sg = qc->sg;
- unsigned int have_sg = (qc->flags & ATA_QCFLAG_SG);
dma_addr_t dma_address;
assert(sg == &qc->sgent);
@@ -1880,9 +1863,6 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
sg->offset = (unsigned long) cmd->request_buffer & ~PAGE_MASK;
sg_dma_len(sg) = cmd->request_bufflen;
- if (!have_sg)
- return 0;
-
dma_address = pci_map_single(ap->host_set->pdev, cmd->request_buffer,
cmd->request_bufflen, dir);
if (pci_dma_mapping_error(dma_address))
@@ -1912,22 +1892,19 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct scsi_cmnd *cmd = qc->scsicmd;
struct scatterlist *sg;
- int n_elem;
- unsigned int have_sg = (qc->flags & ATA_QCFLAG_SG);
+ int n_elem, dir;
VPRINTK("ENTER, ata%u, use_sg %d\n", ap->id, cmd->use_sg);
assert(cmd->use_sg > 0);
sg = (struct scatterlist *)cmd->request_buffer;
- if (have_sg) {
- int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
- n_elem = pci_map_sg(ap->host_set->pdev, sg, cmd->use_sg, dir);
- if (n_elem < 1)
- return -1;
- DPRINTK("%d sg elements mapped\n", n_elem);
- } else {
- n_elem = cmd->use_sg;
- }
+ dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+ n_elem = pci_map_sg(ap->host_set->pdev, sg, cmd->use_sg, dir);
+ if (n_elem < 1)
+ return -1;
+
+ DPRINTK("%d sg elements mapped\n", n_elem);
+
qc->n_elem = n_elem;
return 0;
@@ -2146,8 +2123,8 @@ static void ata_pio_task(void *_data)
}
/**
- * ata_eng_timeout - Handle timeout of queued command
- * @ap: Port on which timed-out command is active
+ * ata_qc_timeout - Handle timeout of queued command
+ * @qc: Command that timed out
*
* Some part of the kernel (currently, only the SCSI layer)
* has noticed that the active command on port @ap has not
@@ -2161,23 +2138,15 @@ static void ata_pio_task(void *_data)
* transaction completed successfully.
*
* LOCKING:
- * Inherited from SCSI layer (none, can sleep)
*/
-void ata_eng_timeout(struct ata_port *ap)
+static void ata_qc_timeout(struct ata_queued_cmd *qc)
{
- u8 host_stat, drv_stat;
- struct ata_queued_cmd *qc;
+ struct ata_port *ap = qc->ap;
+ u8 host_stat = 0, drv_stat;
DPRINTK("ENTER\n");
- qc = ata_qc_from_tag(ap, ap->active_tag);
- if (!qc) {
- printk(KERN_ERR "ata%u: BUG: timeout without command\n",
- ap->id);
- goto out;
- }
-
/* hack alert! We cannot use the supplied completion
* function from inside the ->eh_strategy_handler() thread.
* libata is the only user of ->eh_strategy_handler() in
@@ -2187,38 +2156,69 @@ void ata_eng_timeout(struct ata_port *ap)
qc->scsidone = scsi_finish_command;
switch (qc->tf.protocol) {
+
case ATA_PROT_DMA:
- if (ap->flags & ATA_FLAG_MMIO) {
- void *mmio = (void *) ap->ioaddr.bmdma_addr;
- host_stat = readb(mmio + ATA_DMA_STATUS);
- } else
- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ case ATA_PROT_ATAPI_DMA:
+ host_stat = ata_bmdma_status(ap);
- printk(KERN_ERR "ata%u: DMA timeout, stat 0x%x\n",
- ap->id, host_stat);
+ /* before we do anything else, clear DMA-Start bit */
+ ata_bmdma_stop(ap);
- ata_dma_complete(qc, host_stat);
- break;
+ /* fall through */
case ATA_PROT_NODATA:
- drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+ default:
+ ata_altstatus(ap);
+ drv_stat = ata_chk_status(ap);
+
+ /* ack bmdma irq events */
+ ata_bmdma_ack_irq(ap);
- printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x\n",
- ap->id, qc->tf.command, drv_stat);
+ printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
+ ap->id, qc->tf.command, drv_stat, host_stat);
+ /* complete taskfile transaction */
ata_qc_complete(qc, drv_stat);
break;
+ }
- default:
- drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+ DPRINTK("EXIT\n");
+}
+
+/**
+ * ata_eng_timeout - Handle timeout of queued command
+ * @ap: Port on which timed-out command is active
+ *
+ * Some part of the kernel (currently, only the SCSI layer)
+ * has noticed that the active command on port @ap has not
+ * completed after a specified length of time. Handle this
+ * condition by disabling DMA (if necessary) and completing
+ * transactions, with error if necessary.
+ *
+ * This also handles the case of the "lost interrupt", where
+ * for some reason (possibly hardware bug, possibly driver bug)
+ * an interrupt was not delivered to the driver, even though the
+ * transaction completed successfully.
+ *
+ * LOCKING:
+ * Inherited from SCSI layer (none, can sleep)
+ */
+
+void ata_eng_timeout(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
- printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
- ap->id, qc->tf.command, drv_stat);
+ DPRINTK("ENTER\n");
- ata_qc_complete(qc, drv_stat);
- break;
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (!qc) {
+ printk(KERN_ERR "ata%u: BUG: timeout without command\n",
+ ap->id);
+ goto out;
}
+ ata_qc_timeout(qc);
+
out:
DPRINTK("EXIT\n");
}
@@ -2316,7 +2316,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
qc->scsidone(cmd);
}
- qc->flags &= ~ATA_QCFLAG_ACTIVE;
+ qc->flags = 0;
tag = qc->tag;
if (likely(ata_tag_valid(tag))) {
if (tag == ap->active_tag)
@@ -2362,10 +2362,10 @@ int ata_qc_issue(struct ata_queued_cmd *qc)
if (ata_sg_setup_one(qc))
goto err_out;
}
-
- ap->ops->fill_sg(qc);
}
+ ap->ops->qc_prep(qc);
+
qc->ap->active_tag = qc->tag;
qc->flags |= ATA_QCFLAG_ACTIVE;
@@ -2446,7 +2446,7 @@ void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 host_stat, dmactl;
+ u8 dmactl;
void *mmio = (void *) ap->ioaddr.bmdma_addr;
/* load PRD table addr. */
@@ -2460,10 +2460,6 @@ void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
dmactl |= ATA_DMA_WR;
writeb(dmactl, mmio + ATA_DMA_CMD);
- /* clear interrupt, error bits */
- host_stat = readb(mmio + ATA_DMA_STATUS);
- writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR, mmio + ATA_DMA_STATUS);
-
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
}
@@ -2511,7 +2507,7 @@ void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 host_stat, dmactl;
+ u8 dmactl;
/* load PRD table addr. */
outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
@@ -2523,11 +2519,6 @@ void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
dmactl |= ATA_DMA_WR;
outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- /* clear interrupt, error bits */
- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
- ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
}
@@ -2552,50 +2543,6 @@ void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
}
/**
- * ata_dma_complete - Complete an active ATA BMDMA command
- * @qc: Command to complete
- * @host_stat: BMDMA status register contents
- *
- * LOCKING:
- */
-
-static void ata_dma_complete(struct ata_queued_cmd *qc, u8 host_stat)
-{
- struct ata_port *ap = qc->ap;
- VPRINTK("ENTER\n");
-
- if (ap->flags & ATA_FLAG_MMIO) {
- void *mmio = (void *) ap->ioaddr.bmdma_addr;
-
- /* clear start/stop bit */
- writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
- mmio + ATA_DMA_CMD);
-
- /* ack intr, err bits */
- writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
- mmio + ATA_DMA_STATUS);
- } else {
- /* clear start/stop bit */
- outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
- /* ack intr, err bits */
- outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
- ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- }
-
-
- /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
- ata_altstatus(ap); /* dummy read */
-
- DPRINTK("host %u, host_stat==0x%X, drv_stat==0x%X\n",
- ap->id, (u32) host_stat, (u32) ata_chk_status(ap));
-
- /* get drive status; clear intr; complete txn */
- ata_qc_complete(qc, ata_wait_idle(ap));
-}
-
-/**
* ata_host_intr - Handle host interrupt for given (port, task)
* @ap: Port on which interrupt arrived (possibly...)
* @qc: Taskfile currently active in engine
@@ -2615,59 +2562,60 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
struct ata_queued_cmd *qc)
{
u8 status, host_stat;
- unsigned int handled = 0;
switch (qc->tf.protocol) {
- /* BMDMA completion */
case ATA_PROT_DMA:
case ATA_PROT_ATAPI_DMA:
- if (ap->flags & ATA_FLAG_MMIO) {
- void *mmio = (void *) ap->ioaddr.bmdma_addr;
- host_stat = readb(mmio + ATA_DMA_STATUS);
- } else
- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ /* check status of DMA engine */
+ host_stat = ata_bmdma_status(ap);
VPRINTK("BUS_DMA (host_stat 0x%X)\n", host_stat);
- if (!(host_stat & ATA_DMA_INTR)) {
- ap->stats.idle_irq++;
- break;
- }
+ /* if it's not our irq... */
+ if (!(host_stat & ATA_DMA_INTR))
+ goto idle_irq;
- ata_dma_complete(qc, host_stat);
- handled = 1;
- break;
+ /* before we do anything else, clear DMA-Start bit */
+ ata_bmdma_stop(ap);
+
+ /* fall through */
- /* command completion, but no data xfer */
- /* FIXME: a shared interrupt _will_ cause a non-data command
- * to be completed prematurely, with an error.
- *
- * This doesn't matter right now, since we aren't sending
- * non-data commands down this pipe except in development
- * situations.
- */
- case ATA_PROT_ATAPI:
case ATA_PROT_NODATA:
- status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
- DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
+ /* check altstatus */
+ status = ata_altstatus(ap);
+ if (status & ATA_BUSY)
+ goto idle_irq;
+
+ /* check main status, clearing INTRQ */
+ status = ata_chk_status(ap);
+ if (unlikely(status & ATA_BUSY))
+ goto idle_irq;
+ DPRINTK("BUS_NODATA (dev_stat 0x%X)\n", status);
+
+ /* ack bmdma irq events */
+ ata_bmdma_ack_irq(ap);
+
+ /* complete taskfile transaction */
ata_qc_complete(qc, status);
- handled = 1;
break;
default:
- ap->stats.idle_irq++;
+ goto idle_irq;
+ }
+
+ return 1; /* irq handled */
+
+idle_irq:
+ ap->stats.idle_irq++;
#ifdef ATA_IRQ_TRAP
- if ((ap->stats.idle_irq % 1000) == 0) {
- handled = 1;
- ata_irq_ack(ap, 0); /* debug trap */
- printk(KERN_WARNING "ata%d: irq trap\n", ap->id);
- }
-#endif
- break;
+ if ((ap->stats.idle_irq % 1000) == 0) {
+ handled = 1;
+ ata_irq_ack(ap, 0); /* debug trap */
+ printk(KERN_WARNING "ata%d: irq trap\n", ap->id);
}
-
- return handled;
+#endif
+ return 0; /* irq not handled */
}
/**
@@ -2701,7 +2649,7 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && (!(qc->tf.ctl & ATA_NIEN)))
- handled += ata_host_intr(ap, qc);
+ handled |= ata_host_intr(ap, qc);
}
}
@@ -2711,62 +2659,6 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
}
/**
- * ata_thread_iter -
- * @ap:
- *
- * LOCKING:
- *
- * RETURNS:
- *
- */
-
-static unsigned long ata_thread_iter(struct ata_port *ap)
-{
- long timeout = 0;
-
- DPRINTK("ata%u: thr_state %s\n",
- ap->id, ata_thr_state_name(ap->thr_state));
-
- switch (ap->thr_state) {
- case THR_UNKNOWN:
- ap->thr_state = THR_PORT_RESET;
- break;
-
- case THR_PROBE_START:
- ap->thr_state = THR_PORT_RESET;
- break;
-
- case THR_PORT_RESET:
- ata_port_reset(ap);
- break;
-
- case THR_PROBE_SUCCESS:
- up(&ap->probe_sem);
- ap->thr_state = THR_IDLE;
- break;
-
- case THR_PROBE_FAILED:
- up(&ap->probe_sem);
- ap->thr_state = THR_AWAIT_DEATH;
- break;
-
- case THR_AWAIT_DEATH:
- case THR_IDLE:
- timeout = -1;
- break;
-
- default:
- printk(KERN_DEBUG "ata%u: unknown thr state %s\n",
- ap->id, ata_thr_state_name(ap->thr_state));
- break;
- }
-
- DPRINTK("ata%u: new thr_state %s, returning %ld\n",
- ap->id, ata_thr_state_name(ap->thr_state), timeout);
- return timeout;
-}
-
-/**
* atapi_packet_task - Write CDB bytes to hardware
* @_data: Port to which ATAPI device is attached.
*
@@ -2847,21 +2739,6 @@ void ata_port_stop (struct ata_port *ap)
pci_free_consistent(pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
}
-static void ata_probe_task(void *_data)
-{
- struct ata_port *ap = _data;
- long timeout;
-
- timeout = ata_thread_iter(ap);
- if (timeout < 0)
- return;
-
- if (timeout > 0)
- queue_delayed_work(ata_wq, &ap->probe_task, timeout);
- else
- queue_work(ata_wq, &ap->probe_task);
-}
-
/**
* ata_host_remove - Unregister SCSI host structure with upper layers
* @ap: Port to unregister
@@ -2918,7 +2795,6 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
ap->udma_mask = ent->udma_mask;
ap->flags |= ent->host_flags;
ap->ops = ent->port_ops;
- ap->thr_state = THR_PROBE_START;
ap->cbl = ATA_CBL_NONE;
ap->device[0].flags = ATA_DFLAG_MASTER;
ap->active_tag = ATA_TAG_POISON;
@@ -2926,13 +2802,10 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
INIT_WORK(&ap->packet_task, atapi_packet_task, ap);
INIT_WORK(&ap->pio_task, ata_pio_task, ap);
- INIT_WORK(&ap->probe_task, ata_probe_task, ap);
for (i = 0; i < ATA_MAX_DEVICES; i++)
ap->device[i].devno = i;
- init_MUTEX_LOCKED(&ap->probe_sem);
-
#ifdef ATA_IRQ_TRAP
ap->stats.unhandled_irq = 1;
ap->stats.idle_irq = 1;
@@ -3041,6 +2914,10 @@ int ata_device_add(struct ata_probe_ent *ent)
return 0;
}
+ /* TODO: ack irq here, to ensure it won't scream
+ * when we enable it?
+ */
+
/* obtain irq, that is shared between channels */
if (request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
DRV_NAME, host_set))
@@ -3055,12 +2932,17 @@ int ata_device_add(struct ata_probe_ent *ent)
ap = host_set->ports[i];
DPRINTK("ata%u: probe begin\n", ap->id);
- queue_work(ata_wq, &ap->probe_task); /* start probe */
-
- DPRINTK("ata%u: probe-wait begin\n", ap->id);
- down(&ap->probe_sem); /* wait for end */
+ rc = ata_bus_probe(ap);
+ DPRINTK("ata%u: probe end\n", ap->id);
- DPRINTK("ata%u: probe-wait end\n", ap->id);
+ if (rc) {
+ /* FIXME: do something useful here?
+ * Current libata behavior will
+ * tear down everything when
+ * the module is removed
+ * or the h/w is unplugged.
+ */
+ }
rc = scsi_add_host(ap->host, &pdev->dev);
if (rc) {
@@ -3480,7 +3362,7 @@ EXPORT_SYMBOL_GPL(ata_exec_command_mmio);
EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_port_stop);
EXPORT_SYMBOL_GPL(ata_interrupt);
-EXPORT_SYMBOL_GPL(ata_fill_sg);
+EXPORT_SYMBOL_GPL(ata_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_setup_pio);
EXPORT_SYMBOL_GPL(ata_bmdma_start_pio);
EXPORT_SYMBOL_GPL(ata_bmdma_setup_mmio);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index fed311e81c50..1c24c0eefe0e 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -182,7 +182,8 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
* 65534 when Jens Axboe's patch for dynamically
* determining max_sectors is merged.
*/
- if (dev->flags & ATA_DFLAG_LBA48) {
+ if ((dev->flags & ATA_DFLAG_LBA48) &&
+ ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) {
sdev->host->max_sectors = 2048;
blk_queue_max_sectors(sdev->request_queue, 2048);
}
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
new file mode 100644
index 000000000000..f90821e67cac
--- /dev/null
+++ b/drivers/scsi/sata_nv.c
@@ -0,0 +1,353 @@
+/*
+ * sata_nv.c - NVIDIA nForce SATA
+ *
+ * Copyright 2004 NVIDIA Corp. All rights reserved.
+ * Copyright 2004 Andrew Chew
+ *
+ * The contents of this file are subject to the Open
+ * Software License version 1.1 that can be found at
+ * http://www.opensource.org/licenses/osl-1.1.txt and is included herein
+ * by reference.
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of the GNU General Public License version 2 (the "GPL") as distributed
+ * in the kernel source COPYING file, in which case the provisions of
+ * the GPL are applicable instead of the above. If you wish to allow
+ * the use of your version of this file only under the terms of the
+ * GPL and not to allow others to use your version of this file under
+ * the OSL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the GPL.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under either the OSL or the GPL.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include "scsi.h"
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "sata_nv"
+#define DRV_VERSION "0.01"
+
+#define NV_PORTS 2
+#define NV_PIO_MASK 0x1f
+#define NV_UDMA_MASK 0x7f
+#define NV_PORT0_BMDMA_REG_OFFSET 0x00
+#define NV_PORT1_BMDMA_REG_OFFSET 0x08
+#define NV_PORT0_SCR_REG_OFFSET 0x00
+#define NV_PORT1_SCR_REG_OFFSET 0x40
+
+#define NV_INT_STATUS 0x10
+#define NV_INT_STATUS_PDEV_INT 0x01
+#define NV_INT_STATUS_PDEV_PM 0x02
+#define NV_INT_STATUS_PDEV_ADDED 0x04
+#define NV_INT_STATUS_PDEV_REMOVED 0x08
+#define NV_INT_STATUS_SDEV_INT 0x10
+#define NV_INT_STATUS_SDEV_PM 0x20
+#define NV_INT_STATUS_SDEV_ADDED 0x40
+#define NV_INT_STATUS_SDEV_REMOVED 0x80
+#define NV_INT_STATUS_PDEV_HOTPLUG (NV_INT_STATUS_PDEV_ADDED | \
+ NV_INT_STATUS_PDEV_REMOVED)
+#define NV_INT_STATUS_SDEV_HOTPLUG (NV_INT_STATUS_SDEV_ADDED | \
+ NV_INT_STATUS_SDEV_REMOVED)
+#define NV_INT_STATUS_HOTPLUG (NV_INT_STATUS_PDEV_HOTPLUG | \
+ NV_INT_STATUS_SDEV_HOTPLUG)
+
+#define NV_INT_ENABLE 0x11
+#define NV_INT_ENABLE_PDEV_MASK 0x01
+#define NV_INT_ENABLE_PDEV_PM 0x02
+#define NV_INT_ENABLE_PDEV_ADDED 0x04
+#define NV_INT_ENABLE_PDEV_REMOVED 0x08
+#define NV_INT_ENABLE_SDEV_MASK 0x10
+#define NV_INT_ENABLE_SDEV_PM 0x20
+#define NV_INT_ENABLE_SDEV_ADDED 0x40
+#define NV_INT_ENABLE_SDEV_REMOVED 0x80
+#define NV_INT_ENABLE_PDEV_HOTPLUG (NV_INT_ENABLE_PDEV_ADDED | \
+ NV_INT_ENABLE_PDEV_REMOVED)
+#define NV_INT_ENABLE_SDEV_HOTPLUG (NV_INT_ENABLE_SDEV_ADDED | \
+ NV_INT_ENABLE_SDEV_REMOVED)
+#define NV_INT_ENABLE_HOTPLUG (NV_INT_ENABLE_PDEV_HOTPLUG | \
+ NV_INT_ENABLE_SDEV_HOTPLUG)
+
+#define NV_INT_CONFIG 0x12
+#define NV_INT_CONFIG_METHD 0x01 // 0 = INT, 1 = SMI
+
+static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
+static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+static void nv_host_stop (struct ata_host_set *host_set);
+
+static struct pci_device_id nv_pci_tbl[] = {
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ { 0, } /* terminate list */
+};
+
+static struct pci_driver nv_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = nv_pci_tbl,
+ .probe = nv_init_one,
+ .remove = ata_pci_remove_one,
+};
+
+static Scsi_Host_Template nv_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .queuecommand = ata_scsi_queuecmd,
+ .eh_strategy_handler = ata_scsi_error,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = ATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+};
+
+static struct ata_port_operations nv_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load_pio,
+ .tf_read = ata_tf_read_pio,
+ .exec_command = ata_exec_command_pio,
+ .check_status = ata_check_status_pio,
+ .phy_reset = sata_phy_reset,
+ .bmdma_setup = ata_bmdma_setup_pio,
+ .bmdma_start = ata_bmdma_start_pio,
+ .qc_prep = ata_qc_prep,
+ .eng_timeout = ata_eng_timeout,
+ .irq_handler = nv_interrupt,
+ .scr_read = nv_scr_read,
+ .scr_write = nv_scr_write,
+ .port_start = ata_port_start,
+ .port_stop = ata_port_stop,
+ .host_stop = nv_host_stop,
+};
+
+MODULE_AUTHOR("NVIDIA");
+MODULE_DESCRIPTION("low-level driver for NVIDIA nForce SATA controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
+
+irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+{
+ struct ata_host_set *host_set = dev_instance;
+ unsigned int i;
+ unsigned int handled = 0;
+ unsigned long flags;
+ u8 intr_status;
+ u8 intr_enable;
+
+ spin_lock_irqsave(&host_set->lock, flags);
+
+ for (i = 0; i < host_set->n_ports; i++) {
+ struct ata_port *ap;
+
+ ap = host_set->ports[i];
+ if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) {
+ struct ata_queued_cmd *qc;
+
+ qc = ata_qc_from_tag(ap, ap->active_tag);
+ if (qc && (!(qc->tf.ctl & ATA_NIEN)))
+ handled += ata_host_intr(ap, qc);
+ }
+
+ intr_status = inb(ap->ioaddr.scr_addr + NV_INT_STATUS);
+ intr_enable = inb(ap->ioaddr.scr_addr + NV_INT_ENABLE);
+
+ // Clear interrupt status.
+ outb(0xff, ap->ioaddr.scr_addr + NV_INT_STATUS);
+
+ if (intr_status & NV_INT_STATUS_HOTPLUG) {
+ if (intr_status & NV_INT_STATUS_PDEV_ADDED) {
+ printk(KERN_WARNING "ata%u: "
+ "Primary device added\n", ap->id);
+ }
+
+ if (intr_status & NV_INT_STATUS_PDEV_REMOVED) {
+ printk(KERN_WARNING "ata%u: "
+ "Primary device removed\n", ap->id);
+ }
+
+ if (intr_status & NV_INT_STATUS_SDEV_ADDED) {
+ printk(KERN_WARNING "ata%u: "
+ "Secondary device added\n", ap->id);
+ }
+
+ if (intr_status & NV_INT_STATUS_SDEV_REMOVED) {
+ printk(KERN_WARNING "ata%u: "
+ "Secondary device removed\n", ap->id);
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&host_set->lock, flags);
+
+ return IRQ_RETVAL(handled);
+}
+
+static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg)
+{
+ if (sc_reg > SCR_CONTROL)
+ return 0xffffffffU;
+
+ return inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+}
+
+static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
+{
+ if (sc_reg > SCR_CONTROL)
+ return;
+
+ outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+}
+
+static void nv_host_stop (struct ata_host_set *host_set)
+{
+ int i;
+
+ for (i=0; i<host_set->n_ports; i++) {
+ u8 intr_mask;
+
+ // Disable hotplug event interrupts.
+ intr_mask = inb(host_set->ports[i]->ioaddr.scr_addr +
+ NV_INT_ENABLE);
+ intr_mask &= ~(NV_INT_ENABLE_HOTPLUG);
+ outb(intr_mask, host_set->ports[i]->ioaddr.scr_addr +
+ NV_INT_ENABLE);
+ }
+}
+
+static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version = 0;
+ struct ata_probe_ent *probe_ent = NULL;
+ int i;
+ int rc;
+
+ if (!printed_version++)
+ printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto err_out;
+
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ goto err_out_regions;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ goto err_out_regions;
+
+ probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ if (!probe_ent) {
+ rc = -ENOMEM;
+ goto err_out_regions;
+ }
+
+ memset(probe_ent, 0, sizeof(*probe_ent));
+ INIT_LIST_HEAD(&probe_ent->node);
+
+ probe_ent->pdev = pdev;
+ probe_ent->sht = &nv_sht;
+ probe_ent->host_flags = ATA_FLAG_SATA |
+ ATA_FLAG_SATA_RESET |
+ ATA_FLAG_SRST |
+ ATA_FLAG_NO_LEGACY;
+ probe_ent->port_ops = &nv_ops;
+ probe_ent->n_ports = NV_PORTS;
+ probe_ent->irq = pdev->irq;
+ probe_ent->irq_flags = SA_SHIRQ;
+ probe_ent->pio_mask = NV_PIO_MASK;
+ probe_ent->udma_mask = NV_UDMA_MASK;
+
+ probe_ent->port[0].cmd_addr = pci_resource_start(pdev, 0);
+ ata_std_ports(&probe_ent->port[0]);
+ probe_ent->port[0].altstatus_addr =
+ probe_ent->port[0].ctl_addr =
+ pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
+ probe_ent->port[0].bmdma_addr =
+ pci_resource_start(pdev, 4) | NV_PORT0_BMDMA_REG_OFFSET;
+ probe_ent->port[0].scr_addr =
+ pci_resource_start(pdev, 5) | NV_PORT0_SCR_REG_OFFSET;
+
+ probe_ent->port[1].cmd_addr = pci_resource_start(pdev, 2);
+ ata_std_ports(&probe_ent->port[1]);
+ probe_ent->port[1].altstatus_addr =
+ probe_ent->port[1].ctl_addr =
+ pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
+ probe_ent->port[1].bmdma_addr =
+ pci_resource_start(pdev, 4) | NV_PORT1_BMDMA_REG_OFFSET;
+ probe_ent->port[1].scr_addr =
+ pci_resource_start(pdev, 5) | NV_PORT1_SCR_REG_OFFSET;
+
+ pci_set_master(pdev);
+
+ rc = ata_device_add(probe_ent);
+ if (rc != NV_PORTS)
+ goto err_out_regions;
+
+ // Enable hotplug event interrupts.
+ for (i=0; i<probe_ent->n_ports; i++) {
+ u8 intr_mask;
+
+ outb(NV_INT_STATUS_HOTPLUG, probe_ent->port[i].scr_addr +
+ NV_INT_STATUS);
+
+ intr_mask = inb(probe_ent->port[i].scr_addr + NV_INT_ENABLE);
+ intr_mask |= NV_INT_ENABLE_HOTPLUG;
+ outb(intr_mask, probe_ent->port[i].scr_addr + NV_INT_ENABLE);
+ }
+
+ kfree(probe_ent);
+
+ return 0;
+
+err_out_regions:
+ pci_release_regions(pdev);
+
+err_out:
+ pci_disable_device(pdev);
+ return rc;
+}
+
+static int __init nv_init(void)
+{
+ return pci_module_init(&nv_pci_driver);
+}
+
+static void __exit nv_exit(void)
+{
+ pci_unregister_driver(&nv_pci_driver);
+}
+
+module_init(nv_init);
+module_exit(nv_exit);
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 268b2c345728..ae6d77c96786 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -81,7 +81,7 @@ static void pdc_eng_timeout(struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
static void pdc_port_stop(struct ata_port *ap);
static void pdc_phy_reset(struct ata_port *ap);
-static void pdc_fill_sg(struct ata_queued_cmd *qc);
+static void pdc_qc_prep(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static inline void pdc_dma_complete (struct ata_port *ap,
@@ -114,7 +114,7 @@ static struct ata_port_operations pdc_sata_ops = {
.phy_reset = pdc_phy_reset,
.bmdma_setup = pdc_dma_setup,
.bmdma_start = pdc_dma_start,
- .fill_sg = pdc_fill_sg,
+ .qc_prep = pdc_qc_prep,
.eng_timeout = pdc_eng_timeout,
.irq_handler = pdc_interrupt,
.scr_read = pdc_sata_scr_read,
@@ -261,14 +261,14 @@ static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
}
-static void pdc_fill_sg(struct ata_queued_cmd *qc)
+static void pdc_qc_prep(struct ata_queued_cmd *qc)
{
struct pdc_port_priv *pp = qc->ap->private_data;
unsigned int i;
VPRINTK("ENTER\n");
- ata_fill_sg(qc);
+ ata_qc_prep(qc);
i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, qc->dev->devno, pp->pkt);
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 33ae676e2d78..12043e8f84cb 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -131,7 +131,7 @@ static struct ata_port_operations sil_ops = {
.post_set_mode = sil_post_set_mode,
.bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
- .fill_sg = ata_fill_sg,
+ .qc_prep = ata_qc_prep,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
.scr_read = sil_scr_read,
@@ -302,6 +302,7 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
ap->id, dev->devno);
ap->host->max_sectors = 15;
ap->host->hostt->max_sectors = 15;
+ dev->flags |= ATA_DFLAG_LOCK_SECTORS;
return;
}
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 8965ee281839..a2106d2ebb18 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -100,7 +100,7 @@ static struct ata_port_operations sis_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
- .fill_sg = ata_fill_sg,
+ .qc_prep = ata_qc_prep,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
.scr_read = sis_scr_read,
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 60841abc4398..af28b1f7a95f 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -233,7 +233,7 @@ static struct ata_port_operations k2_sata_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
- .fill_sg = ata_fill_sg,
+ .qc_prep = ata_qc_prep,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
.scr_read = k2_sata_scr_read,
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 3268fdf7e583..ea8ddcc78a6d 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -153,7 +153,7 @@ static void pdc_eng_timeout(struct ata_port *ap);
static void pdc_20621_phy_reset (struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
static void pdc_port_stop(struct ata_port *ap);
-static void pdc20621_fill_sg(struct ata_queued_cmd *qc);
+static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static void pdc20621_host_stop(struct ata_host_set *host_set);
@@ -200,7 +200,7 @@ static struct ata_port_operations pdc_20621_ops = {
.phy_reset = pdc_20621_phy_reset,
.bmdma_setup = pdc20621_dma_setup,
.bmdma_start = pdc20621_dma_start,
- .fill_sg = pdc20621_fill_sg,
+ .qc_prep = pdc20621_qc_prep,
.eng_timeout = pdc_eng_timeout,
.irq_handler = pdc20621_interrupt,
.port_start = pdc_port_start,
@@ -434,7 +434,7 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf,
buf32[dw + 3]);
}
-static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
+static void pdc20621_qc_prep(struct ata_queued_cmd *qc)
{
struct scatterlist *sg = qc->sg;
struct ata_port *ap = qc->ap;
@@ -446,6 +446,9 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
unsigned int i, last, idx, total_len = 0, sgt_len;
u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
+ if (!(qc->flags & ATA_QCFLAG_SG))
+ return;
+
VPRINTK("ata%u: ENTER\n", ap->id);
/* hard-code chip #0 */
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 46d385128842..84ee429471ce 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -108,7 +108,7 @@ static struct ata_port_operations svia_sata_ops = {
.bmdma_setup = ata_bmdma_setup_pio,
.bmdma_start = ata_bmdma_start_pio,
- .fill_sg = ata_fill_sg,
+ .qc_prep = ata_qc_prep,
.eng_timeout = ata_eng_timeout,
.irq_handler = ata_interrupt,
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index e0ad17121850..a09f03ee0ef0 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -215,7 +215,7 @@ static struct ata_port_operations vsc_sata_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup_mmio,
.bmdma_start = ata_bmdma_start_mmio,
- .fill_sg = ata_fill_sg,
+ .qc_prep = ata_qc_prep,
.eng_timeout = ata_eng_timeout,
.irq_handler = vsc_sata_interrupt,
.scr_read = vsc_sata_scr_read,
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index d291d68cd1b0..4067ba593d9c 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1404,7 +1404,7 @@ static ssize_t sdebug_delay_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(delay, S_IRUGO | S_IWUSR, sdebug_delay_show,
- sdebug_delay_store)
+ sdebug_delay_store);
static ssize_t sdebug_opts_show(struct device_driver * ddp, char * buf)
{
@@ -1433,7 +1433,7 @@ opts_done:
return count;
}
DRIVER_ATTR(opts, S_IRUGO | S_IWUSR, sdebug_opts_show,
- sdebug_opts_store)
+ sdebug_opts_store);
static ssize_t sdebug_ptype_show(struct device_driver * ddp, char * buf)
{
@@ -1450,7 +1450,7 @@ static ssize_t sdebug_ptype_store(struct device_driver * ddp,
}
return -EINVAL;
}
-DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store)
+DRIVER_ATTR(ptype, S_IRUGO | S_IWUSR, sdebug_ptype_show, sdebug_ptype_store);
static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf)
{
@@ -1469,19 +1469,19 @@ static ssize_t sdebug_num_tgts_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(num_tgts, S_IRUGO | S_IWUSR, sdebug_num_tgts_show,
- sdebug_num_tgts_store)
+ sdebug_num_tgts_store);
static ssize_t sdebug_dev_size_mb_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_dev_size_mb);
}
-DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL)
+DRIVER_ATTR(dev_size_mb, S_IRUGO, sdebug_dev_size_mb_show, NULL);
static ssize_t sdebug_num_parts_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_parts);
}
-DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL)
+DRIVER_ATTR(num_parts, S_IRUGO, sdebug_num_parts_show, NULL);
static ssize_t sdebug_every_nth_show(struct device_driver * ddp, char * buf)
{
@@ -1500,7 +1500,7 @@ static ssize_t sdebug_every_nth_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(every_nth, S_IRUGO | S_IWUSR, sdebug_every_nth_show,
- sdebug_every_nth_store)
+ sdebug_every_nth_store);
static ssize_t sdebug_max_luns_show(struct device_driver * ddp, char * buf)
{
@@ -1519,13 +1519,13 @@ static ssize_t sdebug_max_luns_store(struct device_driver * ddp,
return -EINVAL;
}
DRIVER_ATTR(max_luns, S_IRUGO | S_IWUSR, sdebug_max_luns_show,
- sdebug_max_luns_store)
+ sdebug_max_luns_store);
static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf)
{
return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_scsi_level);
}
-DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL)
+DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL);
static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf)
{
@@ -1562,7 +1562,7 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp,
return count;
}
DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show,
- sdebug_add_host_store)
+ sdebug_add_host_store);
static void do_create_driverfs_files(void)
{
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index fceb6f9a1be1..a9ff002bb0a5 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -99,7 +99,7 @@ show_##name (struct class_device *class_dev, char *buf) \
*/
#define shost_rd_attr2(name, field, format_string) \
shost_show_function(name, field, format_string) \
-static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
#define shost_rd_attr(field, format_string) \
shost_rd_attr2(field, field, format_string)
@@ -228,8 +228,8 @@ sdev_show_##field (struct device *dev, char *buf) \
* read only field.
*/
#define sdev_rd_attr(field, format_string) \
- sdev_show_function(field, format_string) \
-static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL)
+ sdev_show_function(field, format_string) \
+static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL);
/*
@@ -247,7 +247,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
snscanf (buf, 20, format_string, &sdev->field); \
return count; \
} \
-static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field);
/* Currently we don't export bit fields, but we might in future,
* so leave this code in */
@@ -272,7 +272,7 @@ sdev_store_##field (struct device *dev, const char *buf, size_t count) \
} \
return ret; \
} \
-static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
+static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field);
/*
* scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
@@ -320,7 +320,7 @@ sdev_store_timeout (struct device *dev, const char *buf, size_t count)
sdev->timeout = timeout * HZ;
return count;
}
-static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout)
+static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);
static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count)
@@ -328,7 +328,7 @@ store_rescan_field (struct device *dev, const char *buf, size_t count)
scsi_rescan_device(dev);
return count;
}
-static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field)
+static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);
static ssize_t sdev_store_delete(struct device *dev, const char *buf,
size_t count)
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 3b30baff2000..9c41eefb9640 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -152,7 +152,7 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \
spi_transport_store_function(field, format_string) \
static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \
show_spi_transport_##field, \
- store_spi_transport_##field)
+ store_spi_transport_##field);
/* The Parallel SCSI Tranport Attributes: */
spi_transport_rd_attr(offset, "%d\n");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e5ce98eb0378..cb005e5a5bca 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -603,5 +603,28 @@ config SERIAL_PMACZILOG_CONSOLE
on your PowerMac as the console, you can do so by answering
Y to this option.
+config SERIAL_LH7A40X
+ tristate "Sharp LH7A40X embedded UART support"
+ depends on ARM && ARCH_LH7A40X
+ select SERIAL_CORE
+ help
+ This enables support for the three on-board UARTs of the
+ Sharp LH7A40X series CPUs. Choose Y or M.
+
+config SERIAL_LH7A40X_CONSOLE
+ bool "Support for connsole on Sharp LH7A40X serial port"
+ depends on SERIAL_LH7A40X=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Say Y here if you wish to use one of the serial ports as the
+ system console--the system console is the device which
+ receives all kernel messages and warnings and which allows
+ logins in single user mode.
+
+ Even if you say Y here, the currently visible framebuffer console
+ (/dev/tty0) will still be used as the default system console, but
+ you can alter that using a kernel command line, for example
+ "console=ttyAM1".
+
endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index c2eb159d8b43..ceacc99d8cd1 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SERIAL_68360) += 68360serial.o
obj-$(CONFIG_SERIAL_COLDFIRE) += mcfserial.o
obj-$(CONFIG_V850E_UART) += v850e_uart.o
obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
+obj-$(CONFIG_SERIAL_LH7A40X) += serial_lh7a40x.o
obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o
obj-$(CONFIG_SERIAL_DZ) += dz.o
obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index e83bb0728a37..cb6b4f3ec5c9 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -35,6 +35,7 @@
#include <linux/circ_buf.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/device.h>
#include <asm/io.h>
#include <asm/hardware.h>
@@ -804,26 +805,76 @@ static struct uart_driver serial_pxa_reg = {
.cons = PXA_CONSOLE,
};
-static int __init serial_pxa_init(void)
+static int serial_pxa_suspend(struct device *_dev, u32 state, u32 level)
{
- int i, ret;
+ struct uart_pxa_port *sport = dev_get_drvdata(_dev);
- ret = uart_register_driver(&serial_pxa_reg);
- if (ret)
- return ret;
+ if (sport && level == SUSPEND_DISABLE)
+ uart_suspend_port(&serial_pxa_reg, &sport->port);
+
+ return 0;
+}
- for (i = 0; i < ARRAY_SIZE(serial_pxa_ports); i++)
- uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[i].port);
+static int serial_pxa_resume(struct device *_dev, u32 level)
+{
+ struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+
+ if (sport && level == RESUME_ENABLE)
+ uart_resume_port(&serial_pxa_reg, &sport->port);
+
+ return 0;
+}
+static int serial_pxa_probe(struct device *_dev)
+{
+ struct platform_device *dev = to_platform_device(_dev);
+
+ serial_pxa_ports[dev->id].port.dev = _dev;
+ uart_add_one_port(&serial_pxa_reg, &serial_pxa_ports[dev->id].port);
+ dev_set_drvdata(_dev, &serial_pxa_ports[dev->id]);
return 0;
}
-static void __exit serial_pxa_exit(void)
+static int serial_pxa_remove(struct device *_dev)
{
- int i;
+ struct uart_pxa_port *sport = dev_get_drvdata(_dev);
+
+ dev_set_drvdata(_dev, NULL);
- for (i = 0; i < ARRAY_SIZE(serial_pxa_ports); i++)
- uart_remove_one_port(&serial_pxa_reg, &serial_pxa_ports[i].port);
+ if (sport)
+ uart_remove_one_port(&serial_pxa_reg, &sport->port);
+
+ return 0;
+}
+
+static struct device_driver serial_pxa_driver = {
+ .name = "pxa2xx-uart",
+ .bus = &platform_bus_type,
+ .probe = serial_pxa_probe,
+ .remove = serial_pxa_remove,
+
+ .suspend = serial_pxa_suspend,
+ .resume = serial_pxa_resume,
+};
+
+int __init serial_pxa_init(void)
+{
+ int ret;
+
+ ret = uart_register_driver(&serial_pxa_reg);
+ if (ret != 0)
+ return ret;
+
+ ret = driver_register(&serial_pxa_driver);
+ if (ret != 0)
+ uart_unregister_driver(&serial_pxa_reg);
+
+ return ret;
+}
+
+void __exit serial_pxa_exit(void)
+{
+ driver_unregister(&serial_pxa_driver);
uart_unregister_driver(&serial_pxa_reg);
}
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
new file mode 100644
index 000000000000..d863368e45e2
--- /dev/null
+++ b/drivers/serial/serial_lh7a40x.c
@@ -0,0 +1,708 @@
+/* drivers/serial/serial_lh7a40x.c
+ *
+ * Copyright (C) 2004 Coastal Environmental Systems
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+
+/* Driver for Sharp LH7A40X embedded serial ports
+ *
+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ * Based on drivers/serial/amba.c, by Deep Blue Solutions Ltd.
+ *
+ * ---
+ *
+ * This driver supports the embedded UARTs of the Sharp LH7A40X series
+ * CPUs. While similar to the 16550 and other UART chips, there is
+ * nothing close to register compatibility. Moreover, some of the
+ * modem control lines are not available, either in the chip or they
+ * are lacking in the board-level implementation.
+ *
+ * - Use of SIRDIS
+ * For simplicity, we disable the IR functions of any UART whenever
+ * we enable it.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#if defined(CONFIG_SERIAL_LH7A40X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/serial_core.h>
+
+#include <asm/arch/serial.h>
+
+#define DEV_MAJOR 204
+#define DEV_MINOR 16
+#define DEV_NR 3
+
+#define ISR_LOOP_LIMIT 256
+
+#define UR(p,o) _UR ((p)->membase, o)
+#define _UR(b,o) (*((volatile unsigned int*)(((unsigned char*) b) + (o))))
+#define BIT_CLR(p,o,m) UR(p,o) = UR(p,o) & (~(unsigned int)m)
+#define BIT_SET(p,o,m) UR(p,o) = UR(p,o) | ( (unsigned int)m)
+
+#define UART_REG_SIZE 32
+
+#define UARTEN (0x01) /* UART enable */
+#define SIRDIS (0x02) /* Serial IR disable (UART1 only) */
+
+#define RxEmpty (0x10)
+#define TxEmpty (0x80)
+#define TxFull (0x20)
+#define nRxRdy RxEmpty
+#define nTxRdy TxFull
+#define TxBusy (0x08)
+
+#define RxBreak (0x0800)
+#define RxOverrunError (0x0400)
+#define RxParityError (0x0200)
+#define RxFramingError (0x0100)
+#define RxError (RxBreak | RxOverrunError | RxParityError | RxFramingError)
+
+#define DCD (0x04)
+#define DSR (0x02)
+#define CTS (0x01)
+
+#define RxInt (0x01)
+#define TxInt (0x02)
+#define ModemInt (0x04)
+#define RxTimeoutInt (0x08)
+
+#define MSEOI (0x10)
+
+#define WLEN_8 (0x60)
+#define WLEN_7 (0x40)
+#define WLEN_6 (0x20)
+#define WLEN_5 (0x00)
+#define WLEN (0x60) /* Mask for all word-length bits */
+#define STP2 (0x08)
+#define PEN (0x02) /* Parity Enable */
+#define EPS (0x04) /* Even Parity Set */
+#define FEN (0x10) /* FIFO Enable */
+#define BRK (0x01) /* Send Break */
+
+
+struct uart_port_lh7a40x {
+ struct uart_port port;
+ unsigned int statusPrev; /* Most recently read modem status */
+};
+
+static void lh7a40xuart_stop_tx (struct uart_port* port, unsigned int tty_stop)
+{
+ BIT_CLR (port, UART_R_INTEN, TxInt);
+}
+
+static void lh7a40xuart_start_tx (struct uart_port* port,
+ unsigned int tty_start)
+{
+ BIT_SET (port, UART_R_INTEN, TxInt);
+
+ /* *** FIXME: do I need to check for startup of the
+ transmitter? The old driver did, but AMBA
+ doesn't . */
+}
+
+static void lh7a40xuart_stop_rx (struct uart_port* port)
+{
+ BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt);
+}
+
+static void lh7a40xuart_enable_ms (struct uart_port* port)
+{
+ BIT_SET (port, UART_R_INTEN, ModemInt);
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+lh7a40xuart_rx_chars (struct uart_port* port, struct pt_regs* regs)
+#else
+lh7a40xuart_rx_chars (struct uart_port* port)
+#endif
+{
+ struct tty_struct* tty = port->info->tty;
+ int cbRxMax = 256; /* (Gross) limit on receive */
+ unsigned int data; /* Received data and status */
+
+ while (!(UR (port, UART_R_STATUS) & nRxRdy) && --cbRxMax) {
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ tty->flip.work.func((void*)tty);
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+ printk(KERN_WARNING "TTY_DONT_FLIP set\n");
+ return;
+ }
+ }
+
+ data = UR (port, UART_R_DATA);
+
+ *tty->flip.char_buf_ptr = (unsigned char) data;
+ *tty->flip.flag_buf_ptr = TTY_NORMAL;
+ ++port->icount.rx;
+
+ if (data & RxError) { /* Quick check, short-circuit */
+ if (data & RxBreak) {
+ data &= ~(RxFramingError | RxParityError);
+ ++port->icount.brk;
+ if (uart_handle_break (port))
+ continue;
+ }
+ else if (data & RxParityError)
+ ++port->icount.parity;
+ else if (data & RxFramingError)
+ ++port->icount.frame;
+ if (data & RxOverrunError)
+ ++port->icount.overrun;
+
+ /* Mask by termios, leave Rx'd byte */
+ data &= port->read_status_mask | 0xff;
+
+ if (data & RxBreak)
+ *tty->flip.flag_buf_ptr = TTY_BREAK;
+ else if (data & RxParityError)
+ *tty->flip.flag_buf_ptr = TTY_PARITY;
+ else if (data & RxFramingError)
+ *tty->flip.flag_buf_ptr = TTY_FRAME;
+ }
+
+ if (uart_handle_sysrq_char (port, (unsigned char) data, regs))
+ continue;
+
+ if ((data & port->ignore_status_mask) == 0) {
+ ++tty->flip.flag_buf_ptr;
+ ++tty->flip.char_buf_ptr;
+ ++tty->flip.count;
+ }
+ if ((data & RxOverrunError)
+ && tty->flip.count < TTY_FLIPBUF_SIZE) {
+ /*
+ * Overrun is special, since it's reported
+ * immediately, and doesn't affect the current
+ * character
+ */
+ *tty->flip.char_buf_ptr++ = 0;
+ *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+ ++tty->flip.count;
+ }
+ }
+ tty_flip_buffer_push (tty);
+ return;
+}
+
+static void lh7a40xuart_tx_chars (struct uart_port* port)
+{
+ struct circ_buf* xmit = &port->info->xmit;
+ int cbTxMax = port->fifosize;
+
+ if (port->x_char) {
+ UR (port, UART_R_DATA) = port->x_char;
+ ++port->icount.tx;
+ port->x_char = 0;
+ return;
+ }
+ if (uart_circ_empty (xmit) || uart_tx_stopped (port)) {
+ lh7a40xuart_stop_tx (port, 0);
+ return;
+ }
+
+ /* Unlike the AMBA UART, the lh7a40x UART does not guarantee
+ that at least half of the FIFO is empty. Instead, we check
+ status for every character. Using the AMBA method causes
+ the transmitter to drop characters. */
+
+ do {
+ UR (port, UART_R_DATA) = xmit->buf[xmit->tail];
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ ++port->icount.tx;
+ if (uart_circ_empty(xmit))
+ break;
+ } while (!(UR (port, UART_R_STATUS) & nTxRdy)
+ && cbTxMax--);
+
+ if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
+ uart_write_wakeup (port);
+
+ if (uart_circ_empty (xmit))
+ lh7a40xuart_stop_tx (port, 0);
+}
+
+static void lh7a40xuart_modem_status (struct uart_port* port)
+{
+ unsigned int status = UR (port, UART_R_STATUS);
+ unsigned int delta
+ = status ^ ((struct uart_port_lh7a40x*) port)->statusPrev;
+
+ BIT_SET (port, UART_R_RAWISR, MSEOI); /* Clear modem status intr */
+
+ if (!delta) /* Only happens if we missed 2 transitions */
+ return;
+
+ ((struct uart_port_lh7a40x*) port)->statusPrev = status;
+
+ if (delta & DCD)
+ uart_handle_dcd_change (port, status & DCD);
+
+ if (delta & DSR)
+ ++port->icount.dsr;
+
+ if (delta & CTS)
+ uart_handle_cts_change (port, status & CTS);
+
+ wake_up_interruptible (&port->info->delta_msr_wait);
+}
+
+static irqreturn_t lh7a40xuart_int (int irq, void* dev_id,
+ struct pt_regs* regs)
+{
+ struct uart_port* port = dev_id;
+ unsigned int cLoopLimit = ISR_LOOP_LIMIT;
+ unsigned int isr = UR (port, UART_R_ISR);
+
+
+ do {
+ if (isr & (RxInt | RxTimeoutInt))
+#ifdef SUPPORT_SYSRQ
+ lh7a40xuart_rx_chars(port, regs);
+#else
+ lh7a40xuart_rx_chars(port);
+#endif
+ if (isr & ModemInt)
+ lh7a40xuart_modem_status (port);
+ if (isr & TxInt)
+ lh7a40xuart_tx_chars (port);
+
+ if (--cLoopLimit == 0)
+ break;
+
+ isr = UR (port, UART_R_ISR);
+ } while (isr & (RxInt | TxInt | RxTimeoutInt));
+
+ return IRQ_HANDLED;
+}
+
+static unsigned int lh7a40xuart_tx_empty (struct uart_port* port)
+{
+ return (UR (port, UART_R_STATUS) & TxEmpty) ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int lh7a40xuart_get_mctrl (struct uart_port* port)
+{
+ unsigned int result = 0;
+ unsigned int status = UR (port, UART_R_STATUS);
+
+ if (status & DCD)
+ result |= TIOCM_CAR;
+ if (status & DSR)
+ result |= TIOCM_DSR;
+ if (status & CTS)
+ result |= TIOCM_CTS;
+
+ return result;
+}
+
+static void lh7a40xuart_set_mctrl (struct uart_port* port, unsigned int mctrl)
+{
+ /* None of the ports supports DTR. UART1 supports RTS through GPIO. */
+ /* Note, kernel appears to be setting DTR and RTS on console. */
+
+ /* *** FIXME: this deserves more work. There's some work in
+ tracing all of the IO pins. */
+#if 0
+ if( port->mapbase == UART1_PHYS) {
+ gpioRegs_t *gpio = (gpioRegs_t *)IO_ADDRESS(GPIO_PHYS);
+
+ if (mctrl & TIOCM_RTS)
+ gpio->pbdr &= ~GPIOB_UART1_RTS;
+ else
+ gpio->pbdr |= GPIOB_UART1_RTS;
+ }
+#endif
+}
+
+static void lh7a40xuart_break_ctl (struct uart_port* port, int break_state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ if (break_state == -1)
+ BIT_SET (port, UART_R_FCON, BRK); /* Assert break */
+ else
+ BIT_CLR (port, UART_R_FCON, BRK); /* Deassert break */
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int lh7a40xuart_startup (struct uart_port* port)
+{
+ int retval;
+
+ retval = request_irq (port->irq, lh7a40xuart_int, 0,
+ "serial_lh7a40x", port);
+ if (retval)
+ return retval;
+
+ /* Initial modem control-line settings */
+ ((struct uart_port_lh7a40x*) port)->statusPrev
+ = UR (port, UART_R_STATUS);
+
+ /* There is presently no configuration option to enable IR.
+ Thus, we always disable it. */
+
+ BIT_SET (port, UART_R_CON, UARTEN | SIRDIS);
+ BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt);
+
+ return 0;
+}
+
+static void lh7a40xuart_shutdown (struct uart_port* port)
+{
+ free_irq (port->irq, port);
+ BIT_CLR (port, UART_R_FCON, BRK | FEN);
+ BIT_CLR (port, UART_R_CON, UARTEN);
+}
+
+static void lh7a40xuart_set_termios (struct uart_port* port,
+ struct termios* termios,
+ struct termios* old)
+{
+ unsigned int con;
+ unsigned int inten;
+ unsigned int fcon;
+ unsigned long flags;
+ unsigned int baud;
+ unsigned int quot;
+
+ baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16);
+ quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */
+
+ switch (termios->c_cflag & CSIZE) {
+ case CS5:
+ fcon = WLEN_5;
+ break;
+ case CS6:
+ fcon = WLEN_6;
+ break;
+ case CS7:
+ fcon = WLEN_7;
+ break;
+ case CS8:
+ default:
+ fcon = WLEN_8;
+ break;
+ }
+ if (termios->c_cflag & CSTOPB)
+ fcon |= STP2;
+ if (termios->c_cflag & PARENB) {
+ fcon |= PEN;
+ if (!(termios->c_cflag & PARODD))
+ fcon |= EPS;
+ }
+ if (port->fifosize > 1)
+ fcon |= FEN;
+
+ spin_lock_irqsave (&port->lock, flags);
+
+ uart_update_timeout (port, termios->c_cflag, baud);
+
+ port->read_status_mask = RxOverrunError;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= RxFramingError | RxParityError;
+ if (termios->c_iflag & (BRKINT | PARMRK))
+ port->read_status_mask |= RxBreak;
+
+ /* Figure mask for status we ignore */
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= RxFramingError | RxParityError;
+ if (termios->c_iflag & IGNBRK) {
+ port->ignore_status_mask |= RxBreak;
+ /* Ignore overrun when ignorning parity */
+ /* *** FIXME: is this in the right place? */
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= RxOverrunError;
+ }
+
+ /* Ignore all receive errors when receive disabled */
+ if ((termios->c_cflag & CREAD) == 0)
+ port->ignore_status_mask |= RxError;
+
+ con = UR (port, UART_R_CON);
+ inten = (UR (port, UART_R_INTEN) & ~ModemInt);
+
+ if (UART_ENABLE_MS (port, termios->c_cflag))
+ inten |= ModemInt;
+
+ BIT_CLR (port, UART_R_CON, UARTEN); /* Disable UART */
+ UR (port, UART_R_INTEN) = 0; /* Disable interrupts */
+ UR (port, UART_R_BRCON) = quot - 1; /* Set baud rate divisor */
+ UR (port, UART_R_FCON) = fcon; /* Set FIFO and frame ctrl */
+ UR (port, UART_R_INTEN) = inten; /* Enable interrupts */
+ UR (port, UART_R_CON) = con; /* Restore UART mode */
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char* lh7a40xuart_type (struct uart_port* port)
+{
+ return port->type == PORT_LH7A40X ? "LH7A40X" : NULL;
+}
+
+static void lh7a40xuart_release_port (struct uart_port* port)
+{
+ release_mem_region (port->mapbase, UART_REG_SIZE);
+}
+
+static int lh7a40xuart_request_port (struct uart_port* port)
+{
+ return request_mem_region (port->mapbase, UART_REG_SIZE,
+ "serial_lh7a40x") != NULL
+ ? 0 : -EBUSY;
+}
+
+static void lh7a40xuart_config_port (struct uart_port* port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE) {
+ port->type = PORT_LH7A40X;
+ lh7a40xuart_request_port (port);
+ }
+}
+
+static int lh7a40xuart_verify_port (struct uart_port* port,
+ struct serial_struct* ser)
+{
+ int ret = 0;
+
+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X)
+ ret = -EINVAL;
+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ ret = -EINVAL;
+ if (ser->baud_base < 9600) /* *** FIXME: is this true? */
+ ret = -EINVAL;
+ return ret;
+}
+
+static struct uart_ops lh7a40x_uart_ops = {
+ .tx_empty = lh7a40xuart_tx_empty,
+ .set_mctrl = lh7a40xuart_set_mctrl,
+ .get_mctrl = lh7a40xuart_get_mctrl,
+ .stop_tx = lh7a40xuart_stop_tx,
+ .start_tx = lh7a40xuart_start_tx,
+ .stop_rx = lh7a40xuart_stop_rx,
+ .enable_ms = lh7a40xuart_enable_ms,
+ .break_ctl = lh7a40xuart_break_ctl,
+ .startup = lh7a40xuart_startup,
+ .shutdown = lh7a40xuart_shutdown,
+ .set_termios = lh7a40xuart_set_termios,
+ .type = lh7a40xuart_type,
+ .release_port = lh7a40xuart_release_port,
+ .request_port = lh7a40xuart_request_port,
+ .config_port = lh7a40xuart_config_port,
+ .verify_port = lh7a40xuart_verify_port,
+};
+
+static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
+ {
+ .port = {
+ .membase = (void*) io_p2v (UART1_PHYS),
+ .mapbase = UART1_PHYS,
+ .iotype = SERIAL_IO_MEM,
+ .irq = IRQ_UART1INTR,
+ .uartclk = 14745600/2,
+ .fifosize = 16,
+ .ops = &lh7a40x_uart_ops,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ },
+ {
+ .port = {
+ .membase = (void*) io_p2v (UART2_PHYS),
+ .mapbase = UART2_PHYS,
+ .iotype = SERIAL_IO_MEM,
+ .irq = IRQ_UART2INTR,
+ .uartclk = 14745600/2,
+ .fifosize = 16,
+ .ops = &lh7a40x_uart_ops,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ },
+ {
+ .port = {
+ .membase = (void*) io_p2v (UART3_PHYS),
+ .mapbase = UART3_PHYS,
+ .iotype = SERIAL_IO_MEM,
+ .irq = IRQ_UART3INTR,
+ .uartclk = 14745600/2,
+ .fifosize = 16,
+ .ops = &lh7a40x_uart_ops,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 2,
+ },
+ },
+};
+
+#ifndef CONFIG_SERIAL_LH7A40X_CONSOLE
+# define LH7A40X_CONSOLE NULL
+#else
+# define LH7A40X_CONSOLE &lh7a40x_console
+
+
+static void lh7a40xuart_console_write (struct console* co,
+ const char* s,
+ unsigned int count)
+{
+ struct uart_port* port = &lh7a40x_ports[co->index].port;
+ unsigned int con = UR (port, UART_R_CON);
+ unsigned int inten = UR (port, UART_R_INTEN);
+
+
+ UR (port, UART_R_INTEN) = 0; /* Disable all interrupts */
+ BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */
+
+ for (; count-- > 0; ++s) {
+ while (UR (port, UART_R_STATUS) & nTxRdy)
+ ;
+ UR (port, UART_R_DATA) = *s;
+ if (*s == '\n') {
+ while ((UR (port, UART_R_STATUS) & TxBusy))
+ ;
+ UR (port, UART_R_DATA) = '\r';
+ }
+ }
+
+ /* Wait until all characters are sent */
+ while (UR (port, UART_R_STATUS) & TxBusy)
+ ;
+
+ /* Restore control and interrupt mask */
+ UR (port, UART_R_CON) = con;
+ UR (port, UART_R_INTEN) = inten;
+}
+
+static void __init lh7a40xuart_console_get_options (struct uart_port* port,
+ int* baud,
+ int* parity,
+ int* bits)
+{
+ if (UR (port, UART_R_CON) & UARTEN) {
+ unsigned int fcon = UR (port, UART_R_FCON);
+ unsigned int quot = UR (port, UART_R_BRCON) + 1;
+
+ switch (fcon & (PEN | EPS)) {
+ default: *parity = 'n'; break;
+ case PEN: *parity = 'o'; break;
+ case PEN | EPS: *parity = 'e'; break;
+ }
+
+ switch (fcon & WLEN) {
+ default:
+ case WLEN_8: *bits = 8; break;
+ case WLEN_7: *bits = 7; break;
+ case WLEN_6: *bits = 6; break;
+ case WLEN_5: *bits = 5; break;
+ }
+
+ *baud = port->uartclk/(16*quot);
+ }
+}
+
+static int __init lh7a40xuart_console_setup (struct console* co, char* options)
+{
+ struct uart_port* port;
+ int baud = 38400;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index >= DEV_NR) /* Bounds check on device number */
+ co->index = 0;
+ port = &lh7a40x_ports[co->index].port;
+
+ if (options)
+ uart_parse_options (options, &baud, &parity, &bits, &flow);
+ else
+ lh7a40xuart_console_get_options (port, &baud, &parity, &bits);
+
+ return uart_set_options (port, co, baud, parity, bits, flow);
+}
+
+extern struct uart_driver lh7a40x_reg;
+static struct console lh7a40x_console = {
+ .name = "ttyAM",
+ .write = lh7a40xuart_console_write,
+ .device = uart_console_device,
+ .setup = lh7a40xuart_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &lh7a40x_reg,
+};
+
+static int __init lh7a40xuart_console_init(void)
+{
+ register_console (&lh7a40x_console);
+ return 0;
+}
+
+console_initcall (lh7a40xuart_console_init);
+
+#endif
+
+static struct uart_driver lh7a40x_reg = {
+ .owner = THIS_MODULE,
+ .driver_name = "ttyAM",
+ .dev_name = "ttyAM",
+ .major = DEV_MAJOR,
+ .minor = DEV_MINOR,
+ .nr = DEV_NR,
+ .cons = LH7A40X_CONSOLE,
+};
+
+static int __init lh7a40xuart_init(void)
+{
+ int ret;
+
+ printk (KERN_INFO "serial: LH7A40X serial driver\n");
+
+ ret = uart_register_driver (&lh7a40x_reg);
+
+ if (ret == 0) {
+ int i;
+
+ for (i = 0; i < DEV_NR; i++)
+ uart_add_one_port (&lh7a40x_reg,
+ &lh7a40x_ports[i].port);
+ }
+ return ret;
+}
+
+static void __exit lh7a40xuart_exit(void)
+{
+ int i;
+
+ for (i = 0; i < DEV_NR; i++)
+ uart_remove_one_port (&lh7a40x_reg, &lh7a40x_ports[i].port);
+
+ uart_unregister_driver (&lh7a40x_reg);
+}
+
+module_init (lh7a40xuart_init);
+module_exit (lh7a40xuart_exit);
+
+MODULE_AUTHOR ("Marc Singer");
+MODULE_DESCRIPTION ("Sharp LH7A40X serial port driver");
+MODULE_LICENSE ("GPL");
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 3b7f089002e9..6f61c8fb58a2 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -290,8 +290,11 @@ static void destroy_async (struct dev_state *ps, struct list_head *list)
spin_lock_irqsave(&ps->lock, flags);
}
spin_unlock_irqrestore(&ps->lock, flags);
- while ((as = async_getcompleted(ps)))
+ as = async_getcompleted(ps);
+ while (as) {
free_async(as);
+ as = async_getcompleted(ps);
+ }
}
static void destroy_async_on_interface (struct dev_state *ps, unsigned int ifnum)
@@ -968,29 +971,27 @@ static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
static int processcompl(struct async *as)
{
struct urb *urb = as->urb;
+ struct usbdevfs_urb __user *userurb = as->userurb;
unsigned int i;
if (as->userbuffer)
if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length))
return -EFAULT;
- if (put_user(urb->status,
- &((struct usbdevfs_urb *)as->userurb)->status))
+ if (put_user(urb->status, &userurb->status))
return -EFAULT;
- if (put_user(urb->actual_length,
- &((struct usbdevfs_urb *)as->userurb)->actual_length))
+ if (put_user(urb->actual_length, &userurb->actual_length))
return -EFAULT;
- if (put_user(urb->error_count,
- &((struct usbdevfs_urb *)as->userurb)->error_count))
+ if (put_user(urb->error_count, &userurb->error_count))
return -EFAULT;
if (!(usb_pipeisoc(urb->pipe)))
return 0;
for (i = 0; i < urb->number_of_packets; i++) {
if (put_user(urb->iso_frame_desc[i].actual_length,
- &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length))
+ &userurb->iso_frame_desc[i].actual_length))
return -EFAULT;
if (put_user(urb->iso_frame_desc[i].status,
- &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status))
+ &userurb->iso_frame_desc[i].status))
return -EFAULT;
}
return 0;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index aa01713469ff..69b19c22f68f 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2268,9 +2268,17 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
/*
* Map the BIOS ROM if any and retreive PLL parameters from
- * either BIOS or Open Firmware
+ * the BIOS. We skip that on mobility chips as the real panel
+ * values we need aren't in the ROM but in the BIOS image in
+ * memory. This is definitely not the best meacnism though,
+ * we really need the arch code to tell us which is the "primary"
+ * video adapter to use the memory image (or better, the arch
+ * should provide us a copy of the BIOS image to shield us from
+ * archs who would store that elsewhere and/or could initialize
+ * more than one adapter during boot).
*/
- radeon_map_ROM(rinfo, pdev);
+ if (!rinfo->is_mobility)
+ radeon_map_ROM(rinfo, pdev);
/*
* On x86, the primary display on laptop may have it's BIOS
@@ -2283,6 +2291,12 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
radeon_find_mem_vbios(rinfo);
#endif /* __i386__ */
+ /* If both above failed, try the BIOS ROM again for mobility
+ * chips
+ */
+ if (rinfo->bios_seg == NULL && rinfo->is_mobility)
+ radeon_map_ROM(rinfo, pdev);
+
/* Get informations about the board's PLL */
radeon_get_pllinfo(rinfo);
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index b14a667dbd81..1bca4cd1f71b 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -328,17 +328,17 @@ static struct sa1100fb_mach_info brutus_info __initdata = {
#ifdef CONFIG_SA1100_COLLIE
static struct sa1100fb_mach_info collie_info __initdata = {
- pixclock: 171521, bpp: 16,
- xres: 320, yres: 240,
+ .pixclock = 171521, .bpp = 16,
+ .xres = 320, .yres = 240,
- hsync_len: 5, vsync_len: 1,
- left_margin: 11, upper_margin: 2,
- right_margin: 30, lower_margin: 0,
+ .hsync_len = 5, .vsync_len = 1,
+ .left_margin = 11, .upper_margin = 2,
+ .right_margin = 30, .lower_margin = 0,
- sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
- lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
};
#endif
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 5e66bc917c28..deab8f23ffa1 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2490,7 +2490,8 @@ static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
return 0;
} /* End Function devfs_mknod */
-static int devfs_readlink(struct dentry *dentry, char *buffer, int buflen)
+static int devfs_readlink(struct dentry *dentry, char __user *buffer,
+ int buflen)
{
int err;
struct devfs_entry *de;
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index 6a3531580946..a7eb88163095 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -30,7 +30,7 @@
#define NCP_PACKET_SIZE_INTERNAL 65536
static int
-ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info* arg)
+ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_info __user *arg)
{
struct ncp_fs_info info;
@@ -58,7 +58,7 @@ ncp_get_fs_info(struct ncp_server* server, struct inode* inode, struct ncp_fs_in
}
static int
-ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2* arg)
+ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs_info_v2 __user * arg)
{
struct ncp_fs_info_v2 info2;
@@ -90,7 +90,7 @@ ncp_get_fs_info_v2(struct ncp_server* server, struct inode* inode, struct ncp_fs
* Thanks Petr Vandrovec for idea and many hints.
*/
static int
-ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl* arg)
+ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
{
struct ncp_nls_ioctl user;
struct nls_table *codepage;
@@ -148,7 +148,7 @@ ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl* arg)
}
static int
-ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl* arg)
+ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
{
struct ncp_nls_ioctl user;
int len;
@@ -185,6 +185,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
int result;
struct ncp_ioctl_request request;
char* bouncebuffer;
+ void __user *argp = (void __user *)arg;
switch (cmd) {
case NCP_IOC_NCPREQUEST:
@@ -193,8 +194,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
&& (current->uid != server->m.mounted_uid)) {
return -EACCES;
}
- if (copy_from_user(&request, (struct ncp_ioctl_request *) arg,
- sizeof(request)))
+ if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
if ((request.function > 255)
@@ -245,10 +245,10 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return ncp_conn_logged_in(inode->i_sb);
case NCP_IOC_GET_FS_INFO:
- return ncp_get_fs_info(server, inode, (struct ncp_fs_info *)arg);
+ return ncp_get_fs_info(server, inode, argp);
case NCP_IOC_GET_FS_INFO_V2:
- return ncp_get_fs_info_v2(server, inode, (struct ncp_fs_info_v2 *)arg);
+ return ncp_get_fs_info_v2(server, inode, argp);
case NCP_IOC_GETMOUNTUID2:
{
@@ -259,7 +259,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{
return -EACCES;
}
- if (put_user(tmp, (unsigned long*) arg))
+ if (put_user(tmp, (unsigned long __user *)argp))
return -EFAULT;
return 0;
}
@@ -292,9 +292,8 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
sr.namespace = 0;
sr.dirEntNum = 0;
}
- if (copy_to_user((struct ncp_setroot_ioctl*)arg,
- &sr,
- sizeof(sr))) return -EFAULT;
+ if (copy_to_user(argp, &sr, sizeof(sr)))
+ return -EFAULT;
return 0;
}
case NCP_IOC_SETROOT:
@@ -308,9 +307,8 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return -EACCES;
}
if (server->root_setuped) return -EBUSY;
- if (copy_from_user(&sr,
- (struct ncp_setroot_ioctl*)arg,
- sizeof(sr))) return -EFAULT;
+ if (copy_from_user(&sr, argp, sizeof(sr)))
+ return -EFAULT;
if (sr.volNumber < 0) {
server->m.mounted_vol[0] = 0;
vnum = NCP_NUMBER_OF_VOLUMES;
@@ -348,13 +346,13 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
{
return -EACCES;
}
- if (arg) {
+ if (argp) {
if (server->sign_wanted)
{
struct ncp_sign_init sign;
- if (copy_from_user(&sign, (struct ncp_sign_init *) arg,
- sizeof(sign))) return -EFAULT;
+ if (copy_from_user(&sign, argp, sizeof(sign)))
+ return -EFAULT;
memcpy(server->sign_root,sign.sign_root,8);
memcpy(server->sign_last,sign.sign_last,16);
server->sign_active = 1;
@@ -372,7 +370,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return -EACCES;
}
- if (put_user(server->sign_wanted, (int*) arg))
+ if (put_user(server->sign_wanted, (int __user *)argp))
return -EFAULT;
return 0;
case NCP_IOC_SET_SIGN_WANTED:
@@ -385,7 +383,7 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
return -EACCES;
}
/* get only low 8 bits... */
- if (get_user(newstate, (unsigned char *) arg))
+ if (get_user(newstate, (unsigned char __user *)argp))
return -EFAULT;
if (server->sign_active) {
/* cannot turn signatures OFF when active */
@@ -409,8 +407,8 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
struct ncp_lock_ioctl rqdata;
int result;
- if (copy_from_user(&rqdata, (struct ncp_lock_ioctl*)arg,
- sizeof(rqdata))) return -EFAULT;
+ if (copy_from_user(&rqdata, argp, sizeof(rqdata)))
+ return -EFAULT;
if (rqdata.origin != 0)
return -EINVAL;
/* check for cmd */
@@ -480,9 +478,8 @@ outrel:
struct ncp_objectname_ioctl user;
size_t outl;
- if (copy_from_user(&user,
- (struct ncp_objectname_ioctl*)arg,
- sizeof(user))) return -EFAULT;
+ if (copy_from_user(&user, argp, sizeof(user)))
+ return -EFAULT;
user.auth_type = server->auth.auth_type;
outl = user.object_name_len;
user.object_name_len = server->auth.object_name_len;
@@ -493,9 +490,8 @@ outrel:
server->auth.object_name,
outl)) return -EFAULT;
}
- if (copy_to_user((struct ncp_objectname_ioctl*)arg,
- &user,
- sizeof(user))) return -EFAULT;
+ if (copy_to_user(argp, &user, sizeof(user)))
+ return -EFAULT;
return 0;
}
case NCP_IOC_SETOBJECTNAME:
@@ -510,9 +506,8 @@ outrel:
void* oldprivate;
size_t oldprivatelen;
- if (copy_from_user(&user,
- (struct ncp_objectname_ioctl*)arg,
- sizeof(user))) return -EFAULT;
+ if (copy_from_user(&user, argp, sizeof(user)))
+ return -EFAULT;
if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)
return -ENOMEM;
if (user.object_name_len) {
@@ -550,9 +545,8 @@ outrel:
struct ncp_privatedata_ioctl user;
size_t outl;
- if (copy_from_user(&user,
- (struct ncp_privatedata_ioctl*)arg,
- sizeof(user))) return -EFAULT;
+ if (copy_from_user(&user, argp, sizeof(user)))
+ return -EFAULT;
outl = user.len;
user.len = server->priv.len;
if (outl > user.len) outl = user.len;
@@ -561,9 +555,8 @@ outrel:
server->priv.data,
outl)) return -EFAULT;
}
- if (copy_to_user((struct ncp_privatedata_ioctl*)arg,
- &user,
- sizeof(user))) return -EFAULT;
+ if (copy_to_user(argp, &user, sizeof(user)))
+ return -EFAULT;
return 0;
}
case NCP_IOC_SETPRIVATEDATA:
@@ -576,9 +569,8 @@ outrel:
void* old;
size_t oldlen;
- if (copy_from_user(&user,
- (struct ncp_privatedata_ioctl*)arg,
- sizeof(user))) return -EFAULT;
+ if (copy_from_user(&user, argp, sizeof(user)))
+ return -EFAULT;
if (user.len > NCP_PRIVATE_DATA_MAX_LEN)
return -ENOMEM;
if (user.len) {
@@ -603,10 +595,10 @@ outrel:
#ifdef CONFIG_NCPFS_NLS
case NCP_IOC_SETCHARSETS:
- return ncp_set_charsets(server, (struct ncp_nls_ioctl *)arg);
+ return ncp_set_charsets(server, argp);
case NCP_IOC_GETCHARSETS:
- return ncp_get_charsets(server, (struct ncp_nls_ioctl *)arg);
+ return ncp_get_charsets(server, argp);
#endif /* CONFIG_NCPFS_NLS */
@@ -617,7 +609,7 @@ outrel:
{
u_int32_t user;
- if (copy_from_user(&user, (u_int32_t*)arg, sizeof(user)))
+ if (copy_from_user(&user, argp, sizeof(user)))
return -EFAULT;
/* 20 secs at most... */
if (user > 20000)
@@ -630,7 +622,7 @@ outrel:
case NCP_IOC_GETDENTRYTTL:
{
u_int32_t user = (server->dentry_ttl * 1000) / HZ;
- if (copy_to_user((u_int32_t*)arg, &user, sizeof(user)))
+ if (copy_to_user(argp, &user, sizeof(user)))
return -EFAULT;
return 0;
}
@@ -646,7 +638,7 @@ outrel:
return -EACCES;
}
SET_UID(uid, server->m.mounted_uid);
- if (put_user(uid, (__kernel_uid_t *) arg))
+ if (put_user(uid, (__kernel_uid_t __user *)argp))
return -EFAULT;
return 0;
}
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 5d62232721e6..9e3a70ea23f9 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1463,7 +1463,8 @@ static struct inode_operations proc_tid_attr_inode_operations = {
/*
* /proc/self:
*/
-static int proc_self_readlink(struct dentry *dentry, char *buffer, int buflen)
+static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
+ int buflen)
{
char tmp[30];
sprintf(tmp, "%d", current->tgid);
@@ -1747,7 +1748,9 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
ino_t ino = fake_ino(tgid,PROC_TGID_INO);
unsigned long j = PROC_NUMBUF;
- do buf[--j] = '0' + (tgid % 10); while (tgid/=10);
+ do
+ buf[--j] = '0' + (tgid % 10);
+ while ((tgid /= 10) != 0);
if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino, DT_DIR) < 0) {
filp->f_version = tgid;
@@ -1799,7 +1802,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
do
buf[--j] = '0' + (tid % 10);
- while (tid /= 10);
+ while ((tid /= 10) != 0);
if (filldir(dirent, buf+j, PROC_NUMBUF-j, pos, ino, DT_DIR) < 0)
break;
diff --git a/fs/quota.c b/fs/quota.c
index 680dd072a8c6..cf2c31ea8df0 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -150,7 +150,7 @@ void sync_dquots(struct super_block *sb, int type)
}
/* Copy parameters and call proper function */
-static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr)
+static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr)
{
int ret;
@@ -264,7 +264,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, cadd
* calls. Maybe we need to add the process quotas etc. in the future,
* but we probably should use rlimits for that.
*/
-asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t id, caddr_t addr)
+asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t id, void __user *addr)
{
uint cmds, type;
struct super_block *sb = NULL;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index ac5c0b962ba9..d0030a4b151a 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -46,8 +46,13 @@ int sysfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
struct inode * inode = NULL;
if (dentry) {
if (!dentry->d_inode) {
- if ((inode = sysfs_new_inode(mode)))
+ if ((inode = sysfs_new_inode(mode))) {
+ if (dentry->d_parent && dentry->d_parent->d_inode) {
+ struct inode *p_inode = dentry->d_parent->d_inode;
+ p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
+ }
goto Proceed;
+ }
else
error = -ENOMEM;
} else
diff --git a/include/asm-arm/arch-adifcc/adi_evb.h b/include/asm-arm/arch-adifcc/adi_evb.h
deleted file mode 100644
index f4b74c6fcf9a..000000000000
--- a/include/asm-arm/arch-adifcc/adi_evb.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * linux/include/asm/arch-80200fcc/adi_evb.h
- *
- * ADI 80200FCC evaluation board definitions
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- *
- * Copyright (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#define ADI_EVB__RAMBASE 0xa0000000
-#define ADI_EVB__UART 0x00400000 /* UART */
-#define ADI_EVB_7SEG_1 0x00500000 /* 7-Segment */
-
diff --git a/include/asm-arm/arch-adifcc/dma.h b/include/asm-arm/arch-adifcc/dma.h
deleted file mode 100644
index 19aa1dbc3be7..000000000000
--- a/include/asm-arm/arch-adifcc/dma.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * linux/include/asm-arm/arch-80200fcc/dma.h
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS 0xffffffff
-
-/* No DMA */
-#define MAX_DMA_CHANNELS 0
-
-#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-adifcc/hardware.h b/include/asm-arm/arch-adifcc/hardware.h
deleted file mode 100644
index 9eeb3cb507da..000000000000
--- a/include/asm-arm/arch-adifcc/hardware.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/hardware.h
- *
- * Hardware definitions for ADI based systems
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- *
- * Copyright (C) 2000-2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <linux/config.h>
-
-#define PCIO_BASE 0
-
-#if defined(CONFIG_ARCH_ADI_EVB)
-#include "adi_evb.h"
-#endif
-
-#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-adifcc/io.h b/include/asm-arm/arch-adifcc/io.h
deleted file mode 100644
index bdcaec08bddf..000000000000
--- a/include/asm-arm/arch-adifcc/io.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/io.h
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-#define __io(a) (PCIO_BASE + (a))
-#define __mem_pci(a) ((unsigned long)(a))
-#define __mem_isa(a) ((unsigned long)(a))
-
-#endif
diff --git a/include/asm-arm/arch-adifcc/irqs.h b/include/asm-arm/arch-adifcc/irqs.h
deleted file mode 100644
index b559ca79ef80..000000000000
--- a/include/asm-arm/arch-adifcc/irqs.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * linux/include/asm-arm/arch-80200fcc/irqs.h
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- * Copyright: (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#define IRQ_XS80200_BCU 0 /* Bus Control Unit */
-#define IRQ_XS80200_PMU 1 /* Performance Monitoring Unit */
-#define IRQ_XS80200_EXTIRQ 2 /* external IRQ signal */
-#define IRQ_XS80200_EXTFIQ 3 /* external IRQ signal */
-
-#define NR_XS80200_IRQS 4
-#define NR_IRQS NR_XS80200_IRQS
-
-#define IRQ_XSCALE_PMU IRQ_XS80200_PMU
diff --git a/include/asm-arm/arch-adifcc/memory.h b/include/asm-arm/arch-adifcc/memory.h
deleted file mode 100644
index b76187d8d42b..000000000000
--- a/include/asm-arm/arch-adifcc/memory.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/memory.h
- *
- * Copyright (c) 2001 MontaVista Software, Inc.
- */
-
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-/*
- * Physical DRAM offset.
- */
-#define PHYS_OFFSET (0xC0000000UL)
-
-/*
- * Virtual view <-> DMA view memory address translations
- * virt_to_bus: Used to translate the virtual address to an
- * address suitable to be passed to set_dma_addr
- * bus_to_virt: Used to convert an address for DMA operations
- * to an address that the kernel can use.
- *
- * These are dummies for now.
- */
-#define __virt_to_bus(x) __virt_to_phys(x)
-#define __bus_to_virt(x) __phys_to_virt(x)
-
-#endif
diff --git a/include/asm-arm/arch-adifcc/param.h b/include/asm-arm/arch-adifcc/param.h
deleted file mode 100644
index b1a410eff447..000000000000
--- a/include/asm-arm/arch-adifcc/param.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/param.h
- */
diff --git a/include/asm-arm/arch-adifcc/serial.h b/include/asm-arm/arch-adifcc/serial.h
deleted file mode 100644
index ce4e87699c91..000000000000
--- a/include/asm-arm/arch-adifcc/serial.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * include/asm-arm/arch-adifcc/serial.h
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- *
- * Copyright (c) 2001 MontaVista Software, Inc.
- */
-#include <linux/config.h>
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD ( 1852000 / 16 )
-
-/* Standard COM flags */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-#ifdef CONFIG_ARCH_ADI_EVB
-
-/*
- * One serial port, int goes to FIQ, so we run in polled mode
- */
-#define STD_SERIAL_PORT_DEFNS \
- /* UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, 0xff400000, 0, STD_COM_FLAGS } /* ttyS0 */
-
-#define EXTRA_SERIAL_PORT_DEFNS
-
-#endif
-
diff --git a/include/asm-arm/arch-adifcc/system.h b/include/asm-arm/arch-adifcc/system.h
deleted file mode 100644
index 4bffbdc294a0..000000000000
--- a/include/asm-arm/arch-adifcc/system.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/system.h
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-static inline void arch_idle(void)
-{
-#if 0
- cpu_do_idle();
-#endif
-}
-
-
-static inline void arch_reset(char mode)
-{
- if ( 1 && mode == 's') {
- /* Jump into ROM at address 0 */
- cpu_reset(0);
- } else {
- /* Use on-chip reset capability */
- }
-}
-
diff --git a/include/asm-arm/arch-adifcc/time.h b/include/asm-arm/arch-adifcc/time.h
deleted file mode 100644
index 2237ef006e71..000000000000
--- a/include/asm-arm/arch-adifcc/time.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/time.h
- *
- */
-
-/*
- * No on board timer, implementation @ arch/arm/kernel/xscale-time.c
- */
-
diff --git a/include/asm-arm/arch-adifcc/timex.h b/include/asm-arm/arch-adifcc/timex.h
deleted file mode 100644
index d994c8abecd5..000000000000
--- a/include/asm-arm/arch-adifcc/timex.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/timex.h
- *
- * XScale architecture timex specifications
- */
-
-/* This is for a timer based on the XS80200's PMU counter */
-
-#define CLOCK_TICK_RATE 600000000 /* Underlying HZ */
-
diff --git a/include/asm-arm/arch-adifcc/uncompress.h b/include/asm-arm/arch-adifcc/uncompress.h
deleted file mode 100644
index 792b4e17aa86..000000000000
--- a/include/asm-arm/arch-adifcc/uncompress.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/uncompress.h
- *
- * Author: Deepak Saxena <dsaxena@mvista.com>
- *
- * Copyright (c) 2001 MontaVista Software, Inc.
- *
- */
-
-#define UART_BASE ((volatile unsigned char *)0x00400000)
-
-static __inline__ void putc(char c)
-{
- while ((UART_BASE[5] & 0x60) != 0x60);
- UART_BASE[0] = c;
-}
-
-/*
- * This does not append a newline
- */
-static void puts(const char *s)
-{
- while (*s) {
- putc(*s);
- if (*s == '\n')
- putc('\r');
- s++;
- }
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
-#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-adifcc/vmalloc.h b/include/asm-arm/arch-adifcc/vmalloc.h
deleted file mode 100644
index d45b27e1ad0e..000000000000
--- a/include/asm-arm/arch-adifcc/vmalloc.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * linux/include/asm-arm/arch-adifcc/vmalloc.h
- */
-
-/*
- * Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 8MB value just means that there will be a 8MB "hole" after the
- * physical memory until the kernel virtual memory starts. That means that
- * any out-of-bounds memory accesses will hopefully be caught.
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-#define VMALLOC_OFFSET (8*1024*1024)
-#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
-#define VMALLOC_END (0xe8000000)
diff --git a/include/asm-arm/arch-cl7500/time.h b/include/asm-arm/arch-cl7500/time.h
deleted file mode 100644
index e5e5be510265..000000000000
--- a/include/asm-arm/arch-cl7500/time.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/include/asm-arm/arch-cl7500/time.h
- *
- * Copyright (c) 1996-2000 Russell King.
- *
- * Changelog:
- * 24-Sep-1996 RMK Created
- * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
- * 04-Dec-1997 RMK Updated for new arch/arm/time.c
- */
-
-extern void ioctime_init(void);
-
-static irqreturn_t
-timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- do_timer(regs);
- do_set_rtc();
- do_profile(regs);
-
- {
- /* Twinkle the lights. */
- static int count, state = 0xff00;
- if (count-- == 0) {
- state ^= 0x100;
- count = 25;
- *((volatile unsigned int *)LED_ADDRESS) = state;
- }
- }
- return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt.
- */
-void __init time_init(void)
-{
- ioctime_init();
-
- timer_irq.handler = timer_interrupt;
-
- setup_irq(IRQ_TIMER, &timer_irq);
-}
diff --git a/include/asm-arm/arch-epxa10db/time.h b/include/asm-arm/arch-epxa10db/time.h
deleted file mode 100644
index 749770b83e9a..000000000000
--- a/include/asm-arm/arch-epxa10db/time.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * linux/include/asm-arm/arch-epxa10db/time.h
- *
- * Copyright (C) 2001 Altera Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <asm/system.h>
-#include <asm/leds.h>
-#include <asm/arch/hardware.h>
-#define TIMER00_TYPE (volatile unsigned int*)
-#include <asm/arch/timer00.h>
-
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-excalibur_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-
- // ...clear the interrupt
- *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK;
-
- do_leds();
- do_timer(regs);
- do_profile(regs);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-void __init time_init(void)
-{
- timer_irq.handler = excalibur_timer_interrupt;
-
- /*
- * Make irqs happen for the system timer
- */
- setup_irq(IRQ_TIMER0, &timer_irq);
-
- /* Start the timer */
- *TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200);
- *TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1;
- *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK;
-}
diff --git a/include/asm-arm/arch-integrator/platform.h b/include/asm-arm/arch-integrator/platform.h
index 6b67e41669f4..09ec7902f4bf 100644
--- a/include/asm-arm/arch-integrator/platform.h
+++ b/include/asm-arm/arch-integrator/platform.h
@@ -457,6 +457,10 @@
#define mSEC_25 (mSEC_1 * 25)
#define SEC_1 (mSEC_1 * 1000)
+#ifndef __ASSEMBLY__
+extern void integrator_time_init(unsigned long, unsigned int);
+#endif
+
#define INTEGRATOR_CSR_BASE 0x10000000
#define INTEGRATOR_CSR_SIZE 0x10000000
diff --git a/include/asm-arm/arch-iop3xx/time.h b/include/asm-arm/arch-iop3xx/time.h
deleted file mode 100644
index b58ac84f954e..000000000000
--- a/include/asm-arm/arch-iop3xx/time.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * linux/include/asm-arm/arch-iop80310/time.h
- *
- * Author: Nicolas Pitre
- * Copyright: (C) 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h
index 52c1c445c536..b8ea57968d4a 100644
--- a/include/asm-arm/arch-ixp4xx/platform.h
+++ b/include/asm-arm/arch-ixp4xx/platform.h
@@ -58,6 +58,7 @@ struct ixp4xx_i2c_pins {
*/
extern void ixp4xx_map_io(void);
extern void ixp4xx_init_irq(void);
+extern void ixp4xx_init_time(void);
extern void ixp4xx_pci_preinit(void);
struct pci_sys_data;
extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
diff --git a/include/asm-arm/arch-ixp4xx/time.h b/include/asm-arm/arch-ixp4xx/time.h
deleted file mode 100644
index e79f4acbe7b3..000000000000
--- a/include/asm-arm/arch-ixp4xx/time.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ixp4xx/time.h
- *
- * We implement timer code in arch/arm/mach-ixp4xx/time.c
- *
- */
-
diff --git a/include/asm-arm/arch-rpc/time.h b/include/asm-arm/arch-rpc/time.h
deleted file mode 100644
index 1df6a12cd0e3..000000000000
--- a/include/asm-arm/arch-rpc/time.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * linux/include/asm-arm/arch-rpc/time.h
- *
- * Copyright (C) 1996-2000 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Changelog:
- * 24-Sep-1996 RMK Created
- * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
- * 04-Dec-1997 RMK Updated for new arch/arm/time.c
- */
-extern void ioctime_init(void);
-
-static irqreturn_t
-timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- do_timer(regs);
- do_set_rtc();
- do_profile(regs);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt.
- */
-void __init time_init(void)
-{
- ioctime_init();
-
- timer_irq.handler = timer_interrupt;
-
- setup_irq(IRQ_TIMER, &timer_irq);
-}
diff --git a/include/asm-arm/arch-shark/time.h b/include/asm-arm/arch-shark/time.h
deleted file mode 100644
index 66e45254a628..000000000000
--- a/include/asm-arm/arch-shark/time.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * linux/include/asm-arm/arch-shark/time.h
- *
- * by Alexander Schulz
- *
- * derived from include/asm-arm/arch-ebsa110/time.h
- * Copyright (c) 1996,1997,1998 Russell King.
- */
-
-#include <asm/leds.h>
-#include <asm/param.h>
-
-#define IRQ_TIMER 0
-#define HZ_TIME ((1193180 + HZ/2) / HZ)
-
-static irqreturn_t
-timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- do_leds();
- do_timer(regs);
- do_profile(regs);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-void __init time_init(void)
-{
- unsigned long flags;
-
- outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */
- outb(HZ_TIME & 0xff, 0x40); /* LSB of count */
- outb(HZ_TIME >> 8, 0x40);
-
- timer_irq.handler = timer_interrupt;
- setup_irq(IRQ_TIMER, &timer_irq);
-}
diff --git a/include/asm-arm/arch-versatile/time.h b/include/asm-arm/arch-versatile/time.h
deleted file mode 100644
index 7d97d9565a4b..000000000000
--- a/include/asm-arm/arch-versatile/time.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * linux/include/asm-arm/arch-versatile/time.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <asm/system.h>
-#include <asm/leds.h>
-
-/*
- * Where is the timer (VA)?
- */
-#define TIMER0_VA_BASE IO_ADDRESS(VERSATILE_TIMER0_1_BASE)
-#define TIMER1_VA_BASE (IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)
-#define TIMER2_VA_BASE IO_ADDRESS(VERSATILE_TIMER2_3_BASE)
-#define TIMER3_VA_BASE (IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)
-#define VA_IC_BASE IO_ADDRESS(VERSATILE_VIC_BASE)
-
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */
-#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */
-#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
-#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */
-#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD (TIMER_INTERVAL)
-#define TIMER_CTRL 0x80 /* Enable */
-#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
-#endif
-
-#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */
-
-/*
- * What does it look like?
- */
-typedef struct TimerStruct {
- unsigned long TimerLoad;
- unsigned long TimerValue;
- unsigned long TimerControl;
- unsigned long TimerClear;
-} TimerStruct_t;
-
-extern unsigned long (*gettimeoffset)(void);
-
-/*
- * Returns number of ms since last clock interrupt. Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-static unsigned long versatile_gettimeoffset(void)
-{
- volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
- unsigned long ticks1, ticks2, status;
-
- /*
- * Get the current number of ticks. Note that there is a race
- * condition between us reading the timer and checking for
- * an interrupt. We get around this by ensuring that the
- * counter has not reloaded between our two reads.
- */
- ticks2 = timer0->TimerValue & 0xffff;
- do {
- ticks1 = ticks2;
- status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
- ticks2 = timer0->TimerValue & 0xffff;
- } while (ticks2 > ticks1);
-
- /*
- * Number of ticks since last interrupt.
- */
- ticks1 = TIMER_RELOAD - ticks2;
-
- /*
- * Interrupt pending? If so, we've reloaded once already.
- *
- * FIXME: Need to check this is effectively timer 0 that expires
- */
- if (status & IRQMASK_TIMERINT0_1)
- ticks1 += TIMER_RELOAD;
-
- /*
- * Convert the ticks to usecs
- */
- return TICKS2USECS(ticks1);
-}
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-
- // ...clear the interrupt
- timer0->TimerClear = 1;
-
- do_leds();
- do_timer(regs);
- do_profile(regs);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-void __init time_init(void)
-{
- volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
- volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
- volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
- volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
-
- /*
- * set clock frequency:
- * VERSATILE_REFCLK is 32KHz
- * VERSATILE_TIMCLK is 1MHz
- */
- *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |=
- ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
- (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
-
- timer_irq.handler = versatile_timer_interrupt;
-
- /*
- * Initialise to a known state (all timers off)
- */
- timer0->TimerControl = 0;
- timer1->TimerControl = 0;
- timer2->TimerControl = 0;
- timer3->TimerControl = 0;
-
- timer0->TimerLoad = TIMER_RELOAD;
- timer0->TimerValue = TIMER_RELOAD;
- timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */
-
- /*
- * Make irqs happen for the system timer
- */
- setup_irq(IRQ_TIMERINT0_1, &timer_irq);
- gettimeoffset = versatile_gettimeoffset;
-}
diff --git a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h
index daa0f4e0abbf..f82f595c75af 100644
--- a/include/asm-arm/checksum.h
+++ b/include/asm-arm/checksum.h
@@ -9,6 +9,8 @@
#ifndef __ASM_ARM_CHECKSUM_H
#define __ASM_ARM_CHECKSUM_H
+#include <linux/in6.h>
+
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
diff --git a/include/asm-arm/cpu-multi32.h b/include/asm-arm/cpu-multi32.h
index 00f936197ad9..ff48022e4720 100644
--- a/include/asm-arm/cpu-multi32.h
+++ b/include/asm-arm/cpu-multi32.h
@@ -7,9 +7,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#ifndef __ASSEMBLY__
-
-#include <asm/memory.h>
#include <asm/page.h>
struct mm_struct;
@@ -64,16 +61,4 @@ extern struct processor {
#define cpu_do_idle() processor._do_idle()
#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
#define cpu_set_pte(ptep, pte) processor.set_pte(ptep, pte)
-
-#define cpu_switch_mm(pgd,mm) processor.switch_mm(__virt_to_phys((unsigned long)(pgd)),mm)
-
-#define cpu_get_pgd() \
- ({ \
- unsigned long pg; \
- __asm__("mrc p15, 0, %0, c2, c0, 0" \
- : "=r" (pg) : : "cc"); \
- pg &= ~0x3fff; \
- (pgd_t *)phys_to_virt(pg); \
- })
-
-#endif
+#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
diff --git a/include/asm-arm/cpu-single.h b/include/asm-arm/cpu-single.h
index cc213ad7167f..b5ec5d54665d 100644
--- a/include/asm-arm/cpu-single.h
+++ b/include/asm-arm/cpu-single.h
@@ -27,12 +27,9 @@
#define cpu_reset __cpu_fn(CPU_NAME,_reset)
#define cpu_do_idle __cpu_fn(CPU_NAME,_do_idle)
#define cpu_dcache_clean_area __cpu_fn(CPU_NAME,_dcache_clean_area)
-#define cpu__switch_mm __cpu_fn(CPU_NAME,_switch_mm)
+#define cpu_do_switch_mm __cpu_fn(CPU_NAME,_switch_mm)
#define cpu_set_pte __cpu_fn(CPU_NAME,_set_pte)
-#ifndef __ASSEMBLY__
-
-#include <asm/memory.h>
#include <asm/page.h>
struct mm_struct;
@@ -42,20 +39,6 @@ extern void cpu_proc_init(void);
extern void cpu_proc_fin(void);
extern int cpu_do_idle(void);
extern void cpu_dcache_clean_area(void *, int);
-extern void cpu__switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_set_pte(pte_t *ptep, pte_t pte);
-
extern volatile void cpu_reset(unsigned long addr);
-
-#define cpu_switch_mm(pgd,mm) cpu__switch_mm(__virt_to_phys((unsigned long)(pgd)),mm)
-
-#define cpu_get_pgd() \
- ({ \
- unsigned long pg; \
- __asm__("mrc p15, 0, %0, c2, c0, 0" \
- : "=r" (pg) : : "cc"); \
- pg &= ~0x3fff; \
- (pgd_t *)phys_to_virt(pg); \
- })
-
-#endif
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
index d751faf725de..37ae74796331 100644
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -45,6 +45,7 @@ struct machine_desc {
struct meminfo *);
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
+ void (*init_time)(void);
void (*init_machine)(void);
};
@@ -87,6 +88,9 @@ const struct machine_desc __mach_desc_##_type \
#define INITIRQ(_func) \
.init_irq = _func,
+#define INITTIME(_func) \
+ .init_time = _func,
+
#define INIT_MACHINE(_func) \
.init_machine = _func,
diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h
new file mode 100644
index 000000000000..edb6fcc6a200
--- /dev/null
+++ b/include/asm-arm/mach/time.h
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-arm/mach/time.h
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_MACH_TIME_H
+#define __ASM_ARM_MACH_TIME_H
+
+extern void (*init_arch_time)(void);
+
+extern int (*set_rtc)(void);
+extern unsigned long(*gettimeoffset)(void);
+
+void timer_tick(struct pt_regs *);
+
+#endif
diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h
index 9599c6e2f55a..7bef2bf6be51 100644
--- a/include/asm-arm/proc-fns.h
+++ b/include/asm-arm/proc-fns.h
@@ -148,11 +148,27 @@
# endif
#endif
+#ifndef __ASSEMBLY__
+
#ifndef MULTI_CPU
#include "asm/cpu-single.h"
#else
#include "asm/cpu-multi32.h"
#endif
+#include <asm/memory.h>
+
+#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
+
+#define cpu_get_pgd() \
+ ({ \
+ unsigned long pg; \
+ __asm__("mrc p15, 0, %0, c2, c0, 0" \
+ : "=r" (pg) : : "cc"); \
+ pg &= ~0x3fff; \
+ (pgd_t *)phys_to_virt(pg); \
+ })
+
+#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* __ASM_PROCFNS_H */
diff --git a/include/asm-ppc/pmac_feature.h b/include/asm-ppc/pmac_feature.h
index 11065e368382..ee15e9c59aa2 100644
--- a/include/asm-ppc/pmac_feature.h
+++ b/include/asm-ppc/pmac_feature.h
@@ -273,6 +273,12 @@ static inline long pmac_call_feature(int selector, struct device_node* node,
*/
#define PMAC_FTR_ENABLE_MPIC PMAC_FTR_DEF(19)
+/* PMAC_FTR_AACK_DELAY_ENABLE (NULL, int enable, 0)
+ *
+ * Enable/disable the AACK delay on the northbridge for systems using DFS
+ */
+#define PMAC_FTR_AACK_DELAY_ENABLE PMAC_FTR_DEF(20)
+
/* Don't use those directly, they are for the sake of pmac_setup.c */
extern long pmac_do_feature_call(unsigned int selector, ...);
diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
index fe7a94383a1d..63fc68e784c5 100644
--- a/include/asm-ppc/processor.h
+++ b/include/asm-ppc/processor.h
@@ -197,6 +197,8 @@ extern inline void prefetchw(const void *x)
#define spin_lock_prefetch(x) prefetchw(x)
+extern int emulate_altivec(struct pt_regs *regs);
+
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_PPC_PROCESSOR_H */
diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
index f02ec3cf65ec..15c93af4079a 100644
--- a/include/asm-ppc/reg.h
+++ b/include/asm-ppc/reg.h
@@ -174,6 +174,7 @@
#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */
#define HID1_EMCP (1<<31) /* 7450 Machine Check Pin Enable */
+#define HID1_DFS (1<<22) /* 7447A Dynamic Frequency Scaling */
#define HID1_PC0 (1<<16) /* 7450 PLL_CFG[0] */
#define HID1_PC1 (1<<15) /* 7450 PLL_CFG[1] */
#define HID1_PC2 (1<<14) /* 7450 PLL_CFG[2] */
diff --git a/include/asm-ppc/uninorth.h b/include/asm-ppc/uninorth.h
index eeff122f365b..2cf025936edf 100644
--- a/include/asm-ppc/uninorth.h
+++ b/include/asm-ppc/uninorth.h
@@ -142,6 +142,12 @@
*/
#define UNI_N_HWINIT_STATE_CPU1_FLAG 0x10000000
+/* This register controls AACK delay, which is set when 2004 iBook/PowerBook
+ * is in low speed mode.
+ */
+#define UNI_N_AACK_DELAY 0x0100
+#define UNI_N_AACK_DELAY_ENABLE 0x00000001
+
/* Uninorth 1.5 rev. has additional perf. monitor registers at 0xf00-0xf50 */
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
index 67ac484a14cd..06ecd1bb285d 100644
--- a/include/asm-ppc64/system.h
+++ b/include/asm-ppc64/system.h
@@ -116,6 +116,7 @@ extern void enable_kernel_fp(void);
extern void giveup_altivec(struct task_struct *);
extern void disable_kernel_altivec(void);
extern void enable_kernel_altivec(void);
+extern int emulate_altivec(struct pt_regs *);
extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
extern void cvt_df(double *from, float *to, unsigned long *fpscr);
diff --git a/include/asm-sparc64/bug.h b/include/asm-sparc64/bug.h
index bdaba5ccc11e..bfac1afa9983 100644
--- a/include/asm-sparc64/bug.h
+++ b/include/asm-sparc64/bug.h
@@ -3,6 +3,8 @@
#ifndef _SPARC64_BUG_H
#define _SPARC64_BUG_H
+#include <linux/compiler.h>
+
#ifdef CONFIG_DEBUG_BUGVERBOSE
extern void do_BUG(const char *file, int line);
#define BUG() do { \
diff --git a/include/linux/device.h b/include/linux/device.h
index 2b8b3d636889..3f6e14c099e2 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -54,6 +54,9 @@ struct bus_type {
struct kset drivers;
struct kset devices;
+ struct bus_attribute * bus_attrs;
+ struct device_attribute * dev_attrs;
+
int (*match)(struct device * dev, struct device_driver * drv);
struct device * (*add) (struct device * parent, char * bus_id);
int (*hotplug) (struct device *dev, char **envp,
@@ -90,11 +93,7 @@ struct bus_attribute {
};
#define BUS_ATTR(_name,_mode,_show,_store) \
-struct bus_attribute bus_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int bus_create_file(struct bus_type *, struct bus_attribute *);
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
@@ -131,11 +130,7 @@ struct driver_attribute {
};
#define DRIVER_ATTR(_name,_mode,_show,_store) \
-struct driver_attribute driver_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int driver_create_file(struct device_driver *, struct driver_attribute *);
extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
@@ -151,6 +146,9 @@ struct class {
struct list_head children;
struct list_head interfaces;
+ struct class_attribute * class_attrs;
+ struct class_device_attribute * class_dev_attrs;
+
int (*hotplug)(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
@@ -172,11 +170,7 @@ struct class_attribute {
};
#define CLASS_ATTR(_name,_mode,_show,_store) \
-struct class_attribute class_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int class_create_file(struct class *, const struct class_attribute *);
extern void class_remove_file(struct class *, const struct class_attribute *);
@@ -224,11 +218,8 @@ struct class_device_attribute {
};
#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \
-struct class_device_attribute class_device_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct class_device_attribute class_device_attr_##_name = \
+ __ATTR(_name,_mode,_show,_store)
extern int class_device_create_file(struct class_device *,
const struct class_device_attribute *);
@@ -342,11 +333,7 @@ struct device_attribute {
};
#define DEVICE_ATTR(_name,_mode,_show,_store) \
-struct device_attribute dev_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
- .show = _show, \
- .store = _store, \
-};
+struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
extern int device_create_file(struct device *device, struct device_attribute * entry);
@@ -390,6 +377,10 @@ extern void platform_device_unregister(struct platform_device *);
extern struct bus_type platform_bus_type;
extern struct device platform_bus;
+extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
+extern int platform_get_irq(struct platform_device *, unsigned int);
+extern int platform_add_devices(struct platform_device **, int);
+
/* drivers/base/power.c */
extern void device_shutdown(void);
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 591e7ad68d30..520fe7220cd3 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -101,6 +101,14 @@
#define I2C_DRIVERID_UDA1342 53 /* UDA1342 audio codec */
#define I2C_DRIVERID_ADV7170 54 /* video encoder */
#define I2C_DRIVERID_RADEON 55 /* I2C bus on Radeon boards */
+#define I2C_DRIVERID_MAX1617 56 /* temp sensor */
+#define I2C_DRIVERID_SAA7191 57 /* video encoder */
+#define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */
+#define I2C_DRIVERID_BT832 59 /* CMOS camera video processor */
+#define I2C_DRIVERID_TDA9887 60 /* TDA988x IF-PLL demodulator */
+#define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */
+#define I2C_DRIVERID_TDA7313 62 /* TDA7313 audio processor */
+#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
@@ -264,6 +272,10 @@
#define I2C_HW_SMBUS_SCX200 0x0b
#define I2C_HW_SMBUS_NFORCE2 0x0c
#define I2C_HW_SMBUS_W9968CF 0x0d
+#define I2C_HW_SMBUS_OV511 0x0e /* OV511(+) USB 1.1 webcam ICs */
+#define I2C_HW_SMBUS_OV518 0x0f /* OV518(+) USB 1.1 webcam ICs */
+#define I2C_HW_SMBUS_OV519 0x10 /* OV519 USB 1.1 webcam IC */
+#define I2C_HW_SMBUS_OVFX2 0x11 /* Cypress/OmniVision FX2 webcam */
/* --- ISA pseudo-adapter */
#define I2C_HW_ISA 0x00
diff --git a/include/linux/if.h b/include/linux/if.h
index 296a6c21ec71..110282dbd3e0 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -108,15 +108,15 @@ struct if_settings
unsigned int size; /* Size of the data allocated by the caller */
union {
/* {atm/eth/dsl}_settings anyone ? */
- raw_hdlc_proto *raw_hdlc;
- cisco_proto *cisco;
- fr_proto *fr;
- fr_proto_pvc *fr_pvc;
- fr_proto_pvc_info *fr_pvc_info;
+ raw_hdlc_proto __user *raw_hdlc;
+ cisco_proto __user *cisco;
+ fr_proto __user *fr;
+ fr_proto_pvc __user *fr_pvc;
+ fr_proto_pvc_info __user *fr_pvc_info;
/* interface settings */
- sync_serial_settings *sync;
- te1_settings *te1;
+ sync_serial_settings __user *sync;
+ te1_settings __user *te1;
} ifs_ifsu;
};
diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h
index 0cc5f030dace..26b00a76e135 100644
--- a/include/linux/isdn_ppp.h
+++ b/include/linux/isdn_ppp.h
@@ -233,8 +233,9 @@ struct ippp_struct {
struct slcompress *slcomp;
#endif
#ifdef CONFIG_IPPP_FILTER
- struct sock_fprog pass_filter; /* filter for packets to pass */
- struct sock_fprog active_filter; /* filter for pkts to reset idle */
+ struct sock_filter *pass_filter; /* filter for packets to pass */
+ struct sock_filter *active_filter; /* filter for pkts to reset idle */
+ unsigned pass_len, active_len;
#endif
unsigned long debug;
struct isdn_ppp_compressor *compressor,*decompressor;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 18c90a0c1cfd..a40286d08e23 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -91,6 +91,7 @@ enum {
ATA_DFLAG_MASTER = (1 << 2), /* is device 0? */
ATA_DFLAG_WCACHE = (1 << 3), /* has write cache we can
* (hopefully) flush? */
+ ATA_DFLAG_LOCK_SECTORS = (1 << 4), /* don't adjust max_sectors */
ATA_DEV_UNKNOWN = 0, /* unknown device */
ATA_DEV_ATA = 1, /* ATA device */
@@ -133,24 +134,10 @@ enum {
BUS_IDENTIFY = 8,
BUS_PACKET = 9,
- /* thread states */
- THR_UNKNOWN = 0,
- THR_PORT_RESET = (THR_UNKNOWN + 1),
- THR_AWAIT_DEATH = (THR_PORT_RESET + 1),
- THR_PROBE_FAILED = (THR_AWAIT_DEATH + 1),
- THR_IDLE = (THR_PROBE_FAILED + 1),
- THR_PROBE_SUCCESS = (THR_IDLE + 1),
- THR_PROBE_START = (THR_PROBE_SUCCESS + 1),
-
/* SATA port states */
PORT_UNKNOWN = 0,
PORT_ENABLED = 1,
PORT_DISABLED = 2,
-
- /* ata_qc_cb_t flags - note uses above ATA_QCFLAG_xxx namespace,
- * but not numberspace
- */
- ATA_QCFLAG_TIMEOUT = (1 << 0),
};
enum pio_task_states {
@@ -294,18 +281,12 @@ struct ata_port {
struct ata_host_stats stats;
struct ata_host_set *host_set;
- struct semaphore probe_sem;
-
- unsigned int thr_state;
-
struct work_struct packet_task;
struct work_struct pio_task;
unsigned int pio_task_state;
unsigned long pio_task_timeout;
- struct work_struct probe_task;
-
void *private_data;
};
@@ -330,7 +311,7 @@ struct ata_port_operations {
void (*bmdma_setup) (struct ata_queued_cmd *qc);
void (*bmdma_start) (struct ata_queued_cmd *qc);
- void (*fill_sg) (struct ata_queued_cmd *qc);
+ void (*qc_prep) (struct ata_queued_cmd *qc);
void (*eng_timeout) (struct ata_port *ap);
irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
@@ -390,7 +371,7 @@ extern void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-extern void ata_fill_sg(struct ata_queued_cmd *qc);
+extern void ata_qc_prep(struct ata_queued_cmd *qc);
extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
unsigned int ofs, unsigned int len);
extern void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc);
@@ -556,4 +537,44 @@ static inline unsigned int sata_dev_present(struct ata_port *ap)
return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
}
+static inline void ata_bmdma_stop(struct ata_port *ap)
+{
+ if (ap->flags & ATA_FLAG_MMIO) {
+ void *mmio = (void *) ap->ioaddr.bmdma_addr;
+
+ /* clear start/stop bit */
+ writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
+ mmio + ATA_DMA_CMD);
+ } else {
+ /* clear start/stop bit */
+ outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
+ ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ }
+
+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+ ata_altstatus(ap); /* dummy read */
+}
+
+static inline void ata_bmdma_ack_irq(struct ata_port *ap)
+{
+ if (ap->flags & ATA_FLAG_MMIO) {
+ void *mmio = ((void *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
+ writeb(readb(mmio), mmio);
+ } else {
+ unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
+ outb(inb(addr), addr);
+ }
+}
+
+static inline u8 ata_bmdma_status(struct ata_port *ap)
+{
+ u8 host_stat;
+ if (ap->flags & ATA_FLAG_MMIO) {
+ void *mmio = (void *) ap->ioaddr.bmdma_addr;
+ host_stat = readb(mmio + ATA_DMA_STATUS);
+ } else
+ host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ return host_stat;
+}
+
#endif /* __LINUX_LIBATA_H__ */
diff --git a/include/linux/module.h b/include/linux/module.h
index 2709330e8684..2ad187c3bda1 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -225,6 +225,22 @@ struct module_kobject
struct module_attribute attr[0];
};
+/* Similar stuff for section attributes. */
+#define MODULE_SECT_NAME_LEN 32
+struct module_sect_attr
+{
+ struct attribute attr;
+ char name[MODULE_SECT_NAME_LEN];
+ unsigned long address;
+};
+
+struct module_sections
+{
+ struct kobject kobj;
+ struct module_sect_attr attrs[0];
+};
+
+
struct module
{
enum module_state state;
@@ -298,6 +314,9 @@ struct module
Elf_Sym *symtab;
unsigned long num_symtab;
char *strtab;
+
+ /* Section attributes */
+ struct module_sections *sect_attrs;
#endif
/* Per-cpu data. */
diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
index 9e2f1923ce5c..d9ab889ed7d0 100644
--- a/include/linux/ncp_fs.h
+++ b/include/linux/ncp_fs.h
@@ -24,7 +24,7 @@
struct ncp_ioctl_request {
unsigned int function;
unsigned int size;
- char *data;
+ char __user *data;
};
struct ncp_fs_info {
@@ -88,13 +88,13 @@ struct ncp_objectname_ioctl
#define NCP_AUTH_NDS 0x32
int auth_type;
size_t object_name_len;
- void* object_name; /* an userspace data, in most cases user name */
+ void __user * object_name; /* an userspace data, in most cases user name */
};
struct ncp_privatedata_ioctl
{
size_t len;
- void* data; /* ~1000 for NDS */
+ void __user * data; /* ~1000 for NDS */
};
/* NLS charsets by ioctl */
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index 26d7f3a11fd7..1974f162f5a0 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -103,7 +103,7 @@ union ip_conntrack_nat_help {
#include <linux/types.h>
#include <linux/skbuff.h>
-#ifdef CONFIG_NF_DEBUG
+#ifdef CONFIG_NETFILTER_DEBUG
#define IP_NF_ASSERT(x) \
do { \
if (!(x)) \
diff --git a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h
new file mode 100644
index 000000000000..166ed01a8122
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_addrtype.h
@@ -0,0 +1,11 @@
+#ifndef _IPT_ADDRTYPE_H
+#define _IPT_ADDRTYPE_H
+
+struct ipt_addrtype_info {
+ u_int16_t source; /* source-type mask */
+ u_int16_t dest; /* dest-type mask */
+ u_int32_t invert_source;
+ u_int32_t invert_dest;
+};
+
+#endif
diff --git a/include/linux/netfilter_ipv4/ipt_realm.h b/include/linux/netfilter_ipv4/ipt_realm.h
new file mode 100644
index 000000000000..a4d6698723ac
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_realm.h
@@ -0,0 +1,10 @@
+#ifndef _IPT_REALM_H
+#define _IPT_REALM_H
+
+struct ipt_realm_info {
+ u_int32_t id;
+ u_int32_t mask;
+ u_int8_t invert;
+};
+
+#endif /* _IPT_REALM_H */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index f79c67d6f281..c653647073f1 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -80,6 +80,9 @@
/* SGI IP22 aka Indy / Challenge S / Indigo 2 */
#define PORT_IP22ZILOG 56
+/* Sharp LH7a40x -- an ARM9 SoC series */
+#define PORT_LH7A40X 57
+
#ifdef __KERNEL__
#include <linux/config.h>
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1b33d607f276..f47163e84760 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1109,6 +1109,14 @@ static inline void nf_conntrack_get(struct nf_ct_info *nfct)
if (nfct)
atomic_inc(&nfct->master->use);
}
+static inline void nf_reset(struct sk_buff *skb)
+{
+ nf_conntrack_put(skb->nfct);
+ skb->nfct = NULL;
+#ifdef CONFIG_NETFILTER_DEBUG
+ skb->nf_debug = 0;
+#endif
+}
#ifdef CONFIG_BRIDGE_NETFILTER
static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
@@ -1121,9 +1129,10 @@ static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge)
if (nf_bridge)
atomic_inc(&nf_bridge->use);
}
-#endif
-
-#endif
+#endif /* CONFIG_BRIDGE_NETFILTER */
+#else /* CONFIG_NETFILTER */
+static inline void nf_reset(struct sk_buff *skb) {}
+#endif /* CONFIG_NETFILTER */
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index ef193874f81a..fadfc6d7a87e 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -382,7 +382,7 @@ asmlinkage long sys_fchdir(unsigned int fd);
asmlinkage long sys_rmdir(const char __user *pathname);
asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user *buf, size_t len);
asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special,
- qid_t id, caddr_t addr);
+ qid_t id, void __user *addr);
asmlinkage long sys_getdents(unsigned int fd,
struct linux_dirent __user *dirent,
unsigned int count);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 4cb54379e85a..f94c7ac77c48 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -24,6 +24,27 @@ struct attribute_group {
};
+
+/**
+ * Use these macros to make defining attributes easier. See include/linux/device.h
+ * for examples..
+ */
+
+#define __ATTR(_name,_mode,_show,_store) { \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
+ .show = _show, \
+ .store = _store, \
+}
+
+#define __ATTR_RO(_name) { \
+ .attr = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE }, \
+ .show = _name##_show, \
+}
+
+#define __ATTR_NULL { .attr = { .name = NULL } }
+
+#define attr_name(_attr) (_attr).attr.name
+
struct bin_attribute {
struct attribute attr;
size_t size;
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 39e2d22619dc..d95f58a553b0 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -262,8 +262,8 @@ struct tcp_opt {
__u32 frto_highmark; /* snd_nxt when RTO occurred */
__u8 unused_pad;
- __u8 queue_shrunk; /* Write queue has been shrunk recently.*/
__u8 defer_accept; /* User waits for some data after accept() */
+ /* one byte hole, try to pack */
/* RTT measurement */
__u8 backoff; /* backoff */
@@ -297,7 +297,6 @@ struct tcp_opt {
struct sk_buff_head out_of_order_queue; /* Out of order segments go here */
struct tcp_func *af_specific; /* Operations which are AF_INET{4,6} specific */
- struct sk_buff *send_head; /* Front of stuff to transmit */
__u32 rcv_wnd; /* Current receiver window */
__u32 rcv_wup; /* rcv_nxt on last window update sent */
@@ -371,8 +370,6 @@ struct tcp_opt {
struct open_request *accept_queue;
struct open_request *accept_queue_tail;
- int write_pending; /* A write to socket waits to start. */
-
unsigned int keepalive_time; /* time before keep alive takes place */
unsigned int keepalive_intvl; /* time interval between keep alive probes */
int linger2;
diff --git a/include/net/esp.h b/include/net/esp.h
index a513d14522ee..90cd94fad7d9 100644
--- a/include/net/esp.h
+++ b/include/net/esp.h
@@ -2,9 +2,14 @@
#define _NET_ESP_H
#include <net/xfrm.h>
+#include <asm/scatterlist.h>
+
+#define ESP_NUM_FAST_SG 4
struct esp_data
{
+ struct scatterlist sgbuf[ESP_NUM_FAST_SG];
+
/* Confidentiality */
struct {
u8 *key; /* Key */
diff --git a/include/net/sock.h b/include/net/sock.h
index 0ee6ccddca40..0398823e18ed 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -167,6 +167,9 @@ struct sock_common {
* @sk_socket - Identd and reporting IO signals
* @sk_user_data - RPC layer private data
* @sk_owner - module that owns this socket
+ * @sk_send_head - front of stuff to transmit
+ * @sk_write_pending - a write to stream socket waits to start
+ * @sk_queue_shrunk - write queue has been shrunk recently
* @sk_state_change - callback to indicate change in the state of the sock
* @sk_data_ready - callback to indicate there is data to be processed
* @sk_write_space - callback to indicate there is bf sending space available
@@ -246,8 +249,12 @@ struct sock {
struct timeval sk_stamp;
struct socket *sk_socket;
void *sk_user_data;
+ struct sk_buff *sk_send_head;
struct module *sk_owner;
+ int sk_write_pending;
void *sk_security;
+ __u8 sk_queue_shrunk;
+ /* three bytes hole, try to pack */
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(struct sock *sk);
@@ -434,6 +441,24 @@ static inline int sk_stream_memory_free(struct sock *sk)
return sk->sk_wmem_queued < sk->sk_sndbuf;
}
+extern void sk_stream_rfree(struct sk_buff *skb);
+
+static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk)
+{
+ skb->sk = sk;
+ skb->destructor = sk_stream_rfree;
+ atomic_add(skb->truesize, &sk->sk_rmem_alloc);
+ sk->sk_forward_alloc -= skb->truesize;
+}
+
+static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
+{
+ sk->sk_queue_shrunk = 1;
+ sk->sk_wmem_queued -= skb->truesize;
+ sk->sk_forward_alloc += skb->truesize;
+ __kfree_skb(skb);
+}
+
/* The per-socket spinlock must be held here. */
#define sk_add_backlog(__sk, __skb) \
do { if (!(__sk)->sk_backlog.tail) { \
@@ -458,6 +483,11 @@ do { if (!(__sk)->sk_backlog.tail) { \
rc; \
})
+extern int sk_stream_wait_connect(struct sock *sk, long *timeo_p);
+extern int sk_stream_wait_memory(struct sock *sk, long *timeo_p);
+extern void sk_stream_wait_close(struct sock *sk, long timeo_p);
+extern int sk_stream_error(struct sock *sk, int flags, int err);
+
extern int sk_wait_data(struct sock *sk, long *timeo);
/* IP protocol blocks we attach to sockets.
@@ -1067,6 +1097,20 @@ static inline void sk_wake_async(struct sock *sk, int how, int band)
#define SOCK_MIN_SNDBUF 2048
#define SOCK_MIN_RCVBUF 256
+static inline void sk_stream_moderate_sndbuf(struct sock *sk)
+{
+ if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) {
+ sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2);
+ sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF);
+ }
+}
+
+#define sk_stream_for_retrans_queue(skb, sk) \
+ for (skb = (sk)->sk_write_queue.next; \
+ (skb != (sk)->sk_send_head) && \
+ (skb != (struct sk_buff *)&(sk)->sk_write_queue); \
+ skb = skb->next)
+
/*
* Default write policy as shown to user space via poll/select/SIGIO
*/
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 3a323cd1e79f..22a62d58c24d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1186,13 +1186,6 @@ struct tcp_skb_cb {
#define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0]))
-#define for_retrans_queue(skb, sk, tp) \
- for (skb = (sk)->sk_write_queue.next; \
- (skb != (tp)->send_head) && \
- (skb != (struct sk_buff *)&(sk)->sk_write_queue); \
- skb=skb->next)
-
-
#include <net/tcp_ecn.h>
/* This determines how many packets are "in the network" to the best
@@ -1400,7 +1393,7 @@ tcp_nagle_check(struct tcp_opt *tp, struct sk_buff *skb, unsigned mss_now, int n
tcp_minshall_check(tp))));
}
-/* This checks if the data bearing packet SKB (usually tp->send_head)
+/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
* should be put on the wire right now.
*/
static __inline__ int tcp_snd_test(struct tcp_opt *tp, struct sk_buff *skb,
@@ -1457,7 +1450,7 @@ static __inline__ void __tcp_push_pending_frames(struct sock *sk,
unsigned cur_mss,
int nonagle)
{
- struct sk_buff *skb = tp->send_head;
+ struct sk_buff *skb = sk->sk_send_head;
if (skb) {
if (!tcp_skb_is_last(sk, skb))
@@ -1477,7 +1470,7 @@ static __inline__ void tcp_push_pending_frames(struct sock *sk,
static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_opt *tp)
{
- struct sk_buff *skb = tp->send_head;
+ struct sk_buff *skb = sk->sk_send_head;
return (skb &&
tcp_snd_test(tp, skb, tcp_current_mss(sk, 1),
@@ -1876,14 +1869,6 @@ static __inline__ void tcp_openreq_init(struct open_request *req,
#define TCP_MEM_QUANTUM ((int)PAGE_SIZE)
-static inline void tcp_free_skb(struct sock *sk, struct sk_buff *skb)
-{
- tcp_sk(sk)->queue_shrunk = 1;
- sk->sk_wmem_queued -= skb->truesize;
- sk->sk_forward_alloc += skb->truesize;
- __kfree_skb(skb);
-}
-
extern void __tcp_mem_reclaim(struct sock *sk);
extern int tcp_mem_schedule(struct sock *sk, int size, int kind);
@@ -1901,14 +1886,6 @@ static inline void tcp_enter_memory_pressure(void)
}
}
-static inline void tcp_moderate_sndbuf(struct sock *sk)
-{
- if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) {
- sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2);
- sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF);
- }
-}
-
static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem, int gfp)
{
struct sk_buff *skb = alloc_skb(size+MAX_TCP_HEADER, gfp);
@@ -1923,7 +1900,7 @@ static inline struct sk_buff *tcp_alloc_pskb(struct sock *sk, int size, int mem,
__kfree_skb(skb);
} else {
tcp_enter_memory_pressure();
- tcp_moderate_sndbuf(sk);
+ sk_stream_moderate_sndbuf(sk);
}
return NULL;
}
@@ -1942,7 +1919,7 @@ static inline struct page * tcp_alloc_page(struct sock *sk)
return page;
}
tcp_enter_memory_pressure();
- tcp_moderate_sndbuf(sk);
+ sk_stream_moderate_sndbuf(sk);
return NULL;
}
@@ -1951,20 +1928,10 @@ static inline void tcp_writequeue_purge(struct sock *sk)
struct sk_buff *skb;
while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
- tcp_free_skb(sk, skb);
+ sk_stream_free_skb(sk, skb);
tcp_mem_reclaim(sk);
}
-extern void tcp_rfree(struct sk_buff *skb);
-
-static inline void tcp_set_owner_r(struct sk_buff *skb, struct sock *sk)
-{
- skb->sk = sk;
- skb->destructor = tcp_rfree;
- atomic_add(skb->truesize, &sk->sk_rmem_alloc);
- sk->sk_forward_alloc -= skb->truesize;
-}
-
extern void tcp_listen_wlock(void);
/* - We may sleep inside this lock.
@@ -2049,8 +2016,8 @@ static inline int tcp_use_frto(const struct sock *sk)
* unsent new data, and the advertised window should allow
* sending it.
*/
- return (sysctl_tcp_frto && tp->send_head &&
- !after(TCP_SKB_CB(tp->send_head)->end_seq,
+ return (sysctl_tcp_frto && sk->sk_send_head &&
+ !after(TCP_SKB_CB(sk->sk_send_head)->end_seq,
tp->snd_una + tp->snd_wnd));
}
diff --git a/kernel/module.c b/kernel/module.c
index b96b1397422b..71a0944bddb1 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -980,6 +980,104 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
return ret;
}
+
+/*
+ * /sys/module/foo/sections stuff
+ * J. Corbet <corbet@lwn.net>
+ */
+#ifdef CONFIG_KALLSYMS
+static void module_sect_attrs_release(struct kobject *kobj)
+{
+ kfree(container_of(kobj, struct module_sections, kobj));
+}
+
+static ssize_t module_sect_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct module_sect_attr *sattr =
+ container_of(attr, struct module_sect_attr, attr);
+ return sprintf(buf, "0x%lx\n", sattr->address);
+}
+
+static struct sysfs_ops module_sect_ops = {
+ .show = module_sect_show,
+};
+
+static struct kobj_type module_sect_ktype = {
+ .sysfs_ops = &module_sect_ops,
+ .release = module_sect_attrs_release,
+};
+
+static void add_sect_attrs(struct module *mod, unsigned int nsect,
+ char *secstrings, Elf_Shdr *sechdrs)
+{
+ unsigned int nloaded = 0, i;
+ struct module_sect_attr *sattr;
+
+ if (!mod->mkobj)
+ return;
+
+ /* Count loaded sections and allocate structures */
+ for (i = 0; i < nsect; i++)
+ if (sechdrs[i].sh_flags & SHF_ALLOC)
+ nloaded++;
+ mod->sect_attrs = kmalloc(sizeof(struct module_sections) +
+ nloaded*sizeof(mod->sect_attrs->attrs[0]), GFP_KERNEL);
+ if (! mod->sect_attrs)
+ return;
+
+ /* sections entry setup */
+ memset(mod->sect_attrs, 0, sizeof(struct module_sections));
+ if (kobject_set_name(&mod->sect_attrs->kobj, "sections"))
+ goto out;
+ mod->sect_attrs->kobj.parent = &mod->mkobj->kobj;
+ mod->sect_attrs->kobj.ktype = &module_sect_ktype;
+ if (kobject_register(&mod->sect_attrs->kobj))
+ goto out;
+
+ /* And the section attributes. */
+ sattr = &mod->sect_attrs->attrs[0];
+ for (i = 0; i < nsect; i++) {
+ if (! (sechdrs[i].sh_flags & SHF_ALLOC))
+ continue;
+ sattr->address = sechdrs[i].sh_addr;
+ strlcpy(sattr->name, secstrings + sechdrs[i].sh_name,
+ MODULE_SECT_NAME_LEN);
+ sattr->attr.name = sattr->name;
+ sattr->attr.owner = mod;
+ sattr->attr.mode = S_IRUGO;
+ (void) sysfs_create_file(&mod->sect_attrs->kobj, &sattr->attr);
+ sattr++;
+ }
+ return;
+ out:
+ kfree(mod->sect_attrs);
+ mod->sect_attrs = NULL;
+}
+
+static void remove_sect_attrs(struct module *mod)
+{
+ if (mod->sect_attrs) {
+ kobject_unregister(&mod->sect_attrs->kobj);
+ mod->sect_attrs = NULL;
+ }
+}
+
+
+#else
+static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
+ char *sectstrings, Elf_Shdr *sechdrs)
+{
+}
+
+static inline void remove_sect_attrs(struct module *mod)
+{
+}
+#endif /* CONFIG_KALLSYMS */
+
+
+
+
#define to_module_attr(n) container_of(n, struct module_attribute, attr);
static ssize_t module_attr_show(struct kobject *kobj,
@@ -1098,6 +1196,7 @@ static void free_module(struct module *mod)
list_del(&mod->list);
spin_unlock_irq(&modlist_lock);
+ remove_sect_attrs(mod);
mod_kobject_remove(mod);
/* Arch-specific cleanup. */
@@ -1711,6 +1810,7 @@ static struct module *load_module(void __user *umod,
/ sizeof(struct kernel_param));
if (err < 0)
goto arch_cleanup;
+ add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
/* Get rid of temporary copy */
vfree(hdr);
diff --git a/lib/zlib_deflate/deflate.c b/lib/zlib_deflate/deflate.c
index d5b3e0a3f829..ad9a1bf4fc63 100644
--- a/lib/zlib_deflate/deflate.c
+++ b/lib/zlib_deflate/deflate.c
@@ -1262,7 +1262,7 @@ static block_state deflate_slow(
return flush == Z_FINISH ? finish_done : block_done;
}
-extern int zlib_deflate_workspacesize(void)
+int zlib_deflate_workspacesize(void)
{
return sizeof(deflate_workspace);
}
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 154d05795678..6422f1b8d810 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -652,7 +652,7 @@ static int try_to_unuse(unsigned int type)
* open() method called) - so swap entries may be invisible
* to swapoff for a while, then reappear - but that is rare.
*/
- while ((i = find_next_to_unuse(si, i))) {
+ while ((i = find_next_to_unuse(si, i)) != 0) {
if (signal_pending(current)) {
retval = -EINTR;
break;
diff --git a/net/core/dev.c b/net/core/dev.c
index 9729210ca4cb..95a2b344e949 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1406,13 +1406,12 @@ int dev_queue_xmit(struct sk_buff *skb)
Either shot noqueue qdisc, it is even simpler 8)
*/
if (dev->flags & IFF_UP) {
- preempt_disable();
- int cpu = smp_processor_id();
+ int cpu = get_cpu();
if (dev->xmit_lock_owner != cpu) {
HARD_TX_LOCK_BH(dev, cpu);
- preempt_enable();
+ put_cpu();
if (!netif_queue_stopped(dev)) {
if (netdev_nit)
@@ -1430,7 +1429,7 @@ int dev_queue_xmit(struct sk_buff *skb)
"queue packet!\n", dev->name);
goto out_enetdown;
} else {
- preempt_enable();
+ put_cpu();
/* Recursion is detected! It is possible,
* unfortunately */
if (net_ratelimit())
diff --git a/net/core/sock.c b/net/core/sock.c
index 289f5824e97c..992c2ab34c7a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1147,6 +1147,8 @@ void sock_init_data(struct socket *sock, struct sock *sk)
skb_queue_head_init(&sk->sk_write_queue);
skb_queue_head_init(&sk->sk_error_queue);
+ sk->sk_send_head = NULL;
+
init_timer(&sk->sk_timer);
sk->sk_allocation = GFP_KERNEL;
@@ -1176,6 +1178,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_peercred.pid = 0;
sk->sk_peercred.uid = -1;
sk->sk_peercred.gid = -1;
+ sk->sk_write_pending = 0;
sk->sk_rcvlowat = 1;
sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
diff --git a/net/core/stream.c b/net/core/stream.c
index 24a6f72a0594..d00c8d90565f 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/net.h>
#include <linux/signal.h>
+#include <linux/tcp.h>
#include <linux/wait.h>
#include <net/sock.h>
@@ -39,3 +40,151 @@ void sk_stream_write_space(struct sock *sk)
}
EXPORT_SYMBOL(sk_stream_write_space);
+
+/**
+ * sk_stream_wait_connect - Wait for a socket to get into the connected state
+ * @sk - sock to wait on
+ * @timeo_p - for how long to wait
+ *
+ * Must be called with the socket locked.
+ */
+int sk_stream_wait_connect(struct sock *sk, long *timeo_p)
+{
+ struct task_struct *tsk = current;
+ DEFINE_WAIT(wait);
+
+ while (1) {
+ if (sk->sk_err)
+ return sock_error(sk);
+ if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
+ return -EPIPE;
+ if (!*timeo_p)
+ return -EAGAIN;
+ if (signal_pending(tsk))
+ return sock_intr_errno(*timeo_p);
+
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+ sk->sk_write_pending++;
+ if (sk_wait_event(sk, timeo_p,
+ !((1 << sk->sk_state) &
+ ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))))
+ break;
+ finish_wait(sk->sk_sleep, &wait);
+ sk->sk_write_pending--;
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL(sk_stream_wait_connect);
+
+/**
+ * sk_stream_closing - Return 1 if we still have things to send in our buffers.
+ * @sk - socket to verify
+ */
+static inline int sk_stream_closing(struct sock *sk)
+{
+ return (1 << sk->sk_state) &
+ (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK);
+}
+
+void sk_stream_wait_close(struct sock *sk, long timeout)
+{
+ if (timeout) {
+ DEFINE_WAIT(wait);
+
+ do {
+ prepare_to_wait(sk->sk_sleep, &wait,
+ TASK_INTERRUPTIBLE);
+ if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk)))
+ break;
+ } while (!signal_pending(current) && timeout);
+
+ finish_wait(sk->sk_sleep, &wait);
+ }
+}
+
+EXPORT_SYMBOL(sk_stream_wait_close);
+
+/**
+ * sk_stream_wait_memory - Wait for more memory for a socket
+ * @sk - socket to wait for memory
+ * @timeo_p - for how long
+ */
+int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
+{
+ int err = 0;
+ long vm_wait = 0;
+ long current_timeo = *timeo_p;
+ DEFINE_WAIT(wait);
+
+ if (sk_stream_memory_free(sk))
+ current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2;
+
+ while (1) {
+ set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+
+ if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+ goto do_error;
+ if (!*timeo_p)
+ goto do_nonblock;
+ if (signal_pending(current))
+ goto do_interrupted;
+ clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+ if (sk_stream_memory_free(sk) && !vm_wait)
+ break;
+
+ set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+ sk->sk_write_pending++;
+ sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) &&
+ vm_wait);
+ sk->sk_write_pending--;
+
+ if (vm_wait) {
+ vm_wait -= current_timeo;
+ current_timeo = *timeo_p;
+ if (current_timeo != MAX_SCHEDULE_TIMEOUT &&
+ (current_timeo -= vm_wait) < 0)
+ current_timeo = 0;
+ vm_wait = 0;
+ }
+ *timeo_p = current_timeo;
+ }
+out:
+ finish_wait(sk->sk_sleep, &wait);
+ return err;
+
+do_error:
+ err = -EPIPE;
+ goto out;
+do_nonblock:
+ err = -EAGAIN;
+ goto out;
+do_interrupted:
+ err = sock_intr_errno(*timeo_p);
+ goto out;
+}
+
+EXPORT_SYMBOL(sk_stream_wait_memory);
+
+void sk_stream_rfree(struct sk_buff *skb)
+{
+ struct sock *sk = skb->sk;
+
+ atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
+ sk->sk_forward_alloc += skb->truesize;
+}
+
+EXPORT_SYMBOL(sk_stream_rfree);
+
+int sk_stream_error(struct sock *sk, int flags, int err)
+{
+ if (err == -EPIPE)
+ err = sock_error(sk) ? : -EPIPE;
+ if (err == -EPIPE && !(flags & MSG_NOSIGNAL))
+ send_sig(SIGPIPE, current, 0);
+ return err;
+}
+
+EXPORT_SYMBOL(sk_stream_error);
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index acecd602a2c8..2cd91612ed63 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -11,8 +11,6 @@
#include <net/icmp.h>
#include <net/udp.h>
-#define MAX_SG_ONSTACK 4
-
/* decapsulation data for use when post-processing */
struct esp_decap_data {
xfrm_address_t saddr;
@@ -185,17 +183,16 @@ int esp_output(struct sk_buff **pskb)
crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
do {
- struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
- struct scatterlist *sg = sgbuf;
+ struct scatterlist *sg = &esp->sgbuf[0];
- if (unlikely(nfrags > MAX_SG_ONSTACK)) {
+ if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg)
goto error;
}
skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
crypto_cipher_encrypt(tfm, sg, sg, clen);
- if (unlikely(sg != sgbuf))
+ if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
} while (0);
@@ -283,19 +280,18 @@ int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
{
u8 nexthdr[2];
- struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
- struct scatterlist *sg = sgbuf;
+ struct scatterlist *sg = &esp->sgbuf[0];
u8 workbuf[60];
int padlen;
- if (unlikely(nfrags > MAX_SG_ONSTACK)) {
+ if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg)
goto out;
}
skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
- if (unlikely(sg != sgbuf))
+ if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 4a227f51b2c1..0c2f8ca5ae83 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -643,13 +643,7 @@ int ipgre_rcv(struct sk_buff *skb)
skb->dev = tunnel->dev;
dst_release(skb->dst);
skb->dst = NULL;
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-#endif
+ nf_reset(skb);
ipgre_ecn_decapsulate(iph, skb);
netif_rx(skb);
read_unlock(&ipgre_lock);
@@ -877,13 +871,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-#endif
+ nf_reset(skb);
IPTUNNEL_XMIT();
tunnel->recursion--;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 2f71ed5cfcc9..5b473004fab9 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -202,17 +202,13 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
#ifdef CONFIG_NETFILTER_DEBUG
nf_debug_ip_local_deliver(skb);
- skb->nf_debug = 0;
#endif /*CONFIG_NETFILTER_DEBUG*/
__skb_pull(skb, ihl);
-#ifdef CONFIG_NETFILTER
/* Free reference early: we don't need it any more, and it may
hold ip_conntrack module loaded indefinitely. */
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#endif /*CONFIG_NETFILTER*/
+ nf_reset(skb);
/* Point into the IP datagram, just past the header. */
skb->h.raw = skb->data;
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 757b1d3f6aa2..98ba22404ac3 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -497,13 +497,7 @@ static int ipip_rcv(struct sk_buff *skb)
skb->dev = tunnel->dev;
dst_release(skb->dst);
skb->dst = NULL;
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-#endif
+ nf_reset(skb);
ipip_ecn_decapsulate(iph, skb);
netif_rx(skb);
read_unlock(&ipip_lock);
@@ -648,13 +642,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = old_iph->ttl;
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-#endif
+ nf_reset(skb);
IPTUNNEL_XMIT();
tunnel->recursion--;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index a25e56077072..3aecdcf5e085 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1105,10 +1105,7 @@ static void ip_encap(struct sk_buff *skb, u32 saddr, u32 daddr)
skb->h.ipiph = skb->nh.iph;
skb->nh.iph = iph;
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#endif
+ nf_reset(skb);
}
static inline int ipmr_forward_finish(struct sk_buff *skb)
@@ -1461,10 +1458,7 @@ int pim_rcv_v1(struct sk_buff * skb)
skb->dst = NULL;
((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len;
((struct net_device_stats*)reg_dev->priv)->rx_packets++;
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#endif
+ nf_reset(skb);
netif_rx(skb);
dev_put(reg_dev);
return 0;
@@ -1520,10 +1514,7 @@ static int pim_rcv(struct sk_buff * skb)
((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len;
((struct net_device_stats*)reg_dev->priv)->rx_packets++;
skb->dst = NULL;
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#endif
+ nf_reset(skb);
netif_rx(skb);
dev_put(reg_dev);
return 0;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index f5a5110f97da..eaf79408bc03 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -603,5 +603,29 @@ config IP_NF_RAW
<file:Documentation/modules.txt>. If unsure, say `N'.
help
+config IP_NF_MATCH_ADDRTYPE
+ tristate 'address type match support'
+ depends on IP_NF_IPTABLES
+ help
+ This option allows you to match what routing thinks of an address,
+ eg. UNICAST, LOCAL, BROADCAST, ...
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
+
+config IP_NF_MATCH_REALM
+ tristate 'realm match support'
+ depends on IP_NF_IPTABLES
+ select NET_CLS_ROUTE
+ help
+ This option adds a `realm' match, which allows you to use the realm
+ key from the routing subsytem inside iptables.
+
+ This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option
+ in tc world.
+
+ If you want to compile it as a module, say M here and read
+ Documentation/modules.txt. If unsure, say `N'.
+
endmenu
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 52bedf2d7c62..bdb23fde133f 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -64,6 +64,8 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
+obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
+obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index ae1bc2509dd2..4e8f4d83baf2 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -107,7 +107,7 @@ static int help(struct sk_buff *skb,
exp->mask.dst.u.tcp.port = 0xFFFF;
exp_amanda_info = &exp->help.exp_amanda_info;
- exp_amanda_info->offset = data - amanda_buffer;
+ exp_amanda_info->offset = tmp - amanda_buffer;
exp_amanda_info->port = port;
exp_amanda_info->len = len;
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 1f47e9bbc4eb..00a89f4f8d8b 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -174,13 +174,12 @@ static void
destroy_expect(struct ip_conntrack_expect *exp)
{
DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use));
- IP_NF_ASSERT(atomic_read(&exp->use));
+ IP_NF_ASSERT(atomic_read(&exp->use) == 0);
IP_NF_ASSERT(!timer_pending(&exp->timeout));
kfree(exp);
}
-
inline void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
{
IP_NF_ASSERT(exp);
@@ -716,7 +715,6 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
conntrack, expected);
/* Welcome, Mr. Bond. We've been expecting you... */
- IP_NF_ASSERT(master_ct(conntrack));
__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
conntrack->master = expected;
expected->sibling = conntrack;
@@ -949,9 +947,8 @@ ip_conntrack_expect_insert(struct ip_conntrack_expect *new,
atomic_set(&new->use, 1);
/* add to expected list for this connection */
- list_add(&new->expected_list, &related_to->sibling_list);
+ list_add_tail(&new->expected_list, &related_to->sibling_list);
/* add to global list of expectations */
-
list_prepend(&ip_conntrack_expect_list, &new->list);
/* add and start timer if required */
if (related_to->helper->timeout) {
@@ -1005,7 +1002,6 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
} else if (related_to->helper->max_expected &&
related_to->expecting >= related_to->helper->max_expected) {
- struct list_head *cur_item;
/* old == NULL */
if (!(related_to->helper->flags &
IP_CT_HELPER_F_REUSE_EXPECT)) {
@@ -1031,21 +1027,14 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect,
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
/* choose the the oldest expectation to evict */
- list_for_each(cur_item, &related_to->sibling_list) {
- struct ip_conntrack_expect *cur;
-
- cur = list_entry(cur_item,
- struct ip_conntrack_expect,
- expected_list);
- if (cur->sibling == NULL) {
- old = cur;
+ list_for_each_entry(old, &related_to->sibling_list,
+ expected_list)
+ if (old->sibling == NULL)
break;
- }
- }
- /* (!old) cannot happen, since related_to->expecting is the
- * number of unconfirmed expects */
- IP_NF_ASSERT(old);
+ /* We cannot fail since related_to->expecting is the number
+ * of unconfirmed expectations */
+ IP_NF_ASSERT(old && old->sibling == NULL);
/* newnat14 does not reuse the real allocated memory
* structures but rather unexpects the old and
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index fbe26d1ca0ad..80edac904188 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -503,7 +503,7 @@ static int init_or_cleanup(int init)
if (ret < 0)
goto cleanup_nothing;
- proc = proc_net_create("ip_conntrack",0,list_conntracks);
+ proc = proc_net_create("ip_conntrack", 0440, list_conntracks);
if (!proc) goto cleanup_init;
proc->owner = THIS_MODULE;
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 3e5ca975459d..1c6b7810655a 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -528,6 +528,7 @@ ip_nat_setup_info(struct ip_conntrack *conntrack,
MUST_BE_WRITE_LOCKED(&ip_nat_lock);
IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
|| hooknum == NF_IP_POST_ROUTING
+ || hooknum == NF_IP_LOCAL_IN
|| hooknum == NF_IP_LOCAL_OUT);
IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS);
IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
@@ -816,7 +817,7 @@ do_bindings(struct ip_conntrack *ct,
/* Have to grab read lock before sibling_list traversal */
READ_LOCK(&ip_conntrack_lock);
- list_for_each(cur_item, &ct->sibling_list) {
+ list_for_each_prev(cur_item, &ct->sibling_list) {
exp = list_entry(cur_item, struct ip_conntrack_expect,
expected_list);
@@ -899,10 +900,10 @@ icmp_reply_translation(struct sk_buff **pskb,
/* Must be RELATED */
IP_NF_ASSERT((*pskb)->nfct
- - (struct ip_conntrack *)(*pskb)->nfct->master
+ - ((struct ip_conntrack *)(*pskb)->nfct->master)->infos
== IP_CT_RELATED
|| (*pskb)->nfct
- - (struct ip_conntrack *)(*pskb)->nfct->master
+ - ((struct ip_conntrack *)(*pskb)->nfct->master)->infos
== IP_CT_RELATED+IP_CT_IS_REPLY);
/* Redirects on non-null nats must be dropped, else they'll
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 2d433b69d099..a612865a5635 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1731,6 +1731,15 @@ static inline int print_name(const char *i,
return 0;
}
+static inline int print_target(const struct ipt_target *t,
+ off_t start_offset, char *buffer, int length,
+ off_t *pos, unsigned int *count)
+{
+ if (t == &ipt_standard_target || t == &ipt_error_target)
+ return 0;
+ return print_name((char *)t, start_offset, buffer, length, pos, count);
+}
+
static int ipt_get_tables(char *buffer, char **start, off_t offset, int length)
{
off_t pos = 0;
@@ -1757,7 +1766,7 @@ static int ipt_get_targets(char *buffer, char **start, off_t offset, int length)
if (down_interruptible(&ipt_mutex) != 0)
return 0;
- LIST_FIND(&ipt_target, print_name, void *,
+ LIST_FIND(&ipt_target, print_target, struct ipt_target *,
offset, buffer, length, &pos, &count);
up(&ipt_mutex);
diff --git a/net/ipv4/netfilter/ipt_CLASSIFY.c b/net/ipv4/netfilter/ipt_CLASSIFY.c
index e7b300465532..9842e6e23184 100644
--- a/net/ipv4/netfilter/ipt_CLASSIFY.c
+++ b/net/ipv4/netfilter/ipt_CLASSIFY.c
@@ -54,15 +54,17 @@ checkentry(const char *tablename,
return 0;
}
- if (hook_mask & ~(1 << NF_IP_POST_ROUTING)) {
- printk(KERN_ERR "CLASSIFY: only valid in POST_ROUTING.\n");
+ if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
+ (1 << NF_IP_POST_ROUTING))) {
+ printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD "
+ "and POST_ROUTING.\n");
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
- printk(KERN_WARNING "CLASSIFY: can only be called from "
- "\"mangle\" table, not \"%s\".\n",
- tablename);
+ printk(KERN_ERR "CLASSIFY: can only be called from "
+ "\"mangle\" table, not \"%s\".\n",
+ tablename);
return 0;
}
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f6183f968b2b..b8018cb023ff 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -142,12 +142,8 @@ static void send_reset(struct sk_buff *oldskb, int hook)
nskb->dst = &rt->u.dst;
/* This packet will not be the same as the other: clear nf fields */
- nf_conntrack_put(nskb->nfct);
- nskb->nfct = NULL;
+ nf_reset(nskb);
nskb->nfcache = 0;
-#ifdef CONFIG_NETFILTER_DEBUG
- nskb->nf_debug = 0;
-#endif
nskb->nfmark = 0;
#ifdef CONFIG_BRIDGE_NETFILTER
nf_bridge_put(nskb->nf_bridge);
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
new file mode 100644
index 000000000000..7392ba6bd23f
--- /dev/null
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -0,0 +1,77 @@
+/*
+ * iptables module to match inet_addr_type() of an ip.
+ *
+ * Copyright (c) 2004 Patrick McHardy <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ip.h>
+#include <net/route.h>
+
+#include <linux/netfilter_ipv4/ipt_addrtype.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("iptables addrtype match");
+
+static inline int match_type(u_int32_t addr, u_int16_t mask)
+{
+ return !!(mask & (1 << inet_addr_type(addr)));
+}
+
+static int match(const struct sk_buff *skb, const struct net_device *in,
+ const struct net_device *out, const void *matchinfo,
+ int offset, int *hotdrop)
+{
+ const struct ipt_addrtype_info *info = matchinfo;
+ const struct iphdr *iph = skb->nh.iph;
+ int ret = 1;
+
+ if (info->source)
+ ret &= match_type(iph->saddr, info->source)^info->invert_source;
+ if (info->dest)
+ ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
+
+ return ret;
+}
+
+static int checkentry(const char *tablename, const struct ipt_ip *ip,
+ void *matchinfo, unsigned int matchsize,
+ unsigned int hook_mask)
+{
+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
+ printk(KERN_ERR "ipt_addrtype: invalid size (%u != %u)\n.",
+ matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct ipt_match addrtype_match = {
+ .name = "addrtype",
+ .match = match,
+ .checkentry = checkentry,
+ .me = THIS_MODULE
+};
+
+static int __init init(void)
+{
+ return ipt_register_match(&addrtype_match);
+}
+
+static void __exit fini(void)
+{
+ ipt_unregister_match(&addrtype_match);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
index bed83c79e3cc..ee9881ece49f 100644
--- a/net/ipv4/netfilter/ipt_helper.c
+++ b/net/ipv4/netfilter/ipt_helper.c
@@ -41,17 +41,17 @@ match(const struct sk_buff *skb,
struct ip_conntrack_expect *exp;
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
- int ret = 0;
+ int ret = info->invert;
ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo);
if (!ct) {
DEBUGP("ipt_helper: Eek! invalid conntrack?\n");
- return 0;
+ return ret;
}
if (!ct->master) {
DEBUGP("ipt_helper: conntrack %p has no master\n", ct);
- return 0;
+ return ret;
}
exp = ct->master;
@@ -71,8 +71,11 @@ match(const struct sk_buff *skb,
DEBUGP("master's name = %s , info->name = %s\n",
exp->expectant->helper->name, info->name);
- ret = !strncmp(exp->expectant->helper->name, info->name,
- strlen(exp->expectant->helper->name)) ^ info->invert;
+ if (info->name[0] == '\0')
+ ret ^= 1;
+ else
+ ret ^= !strncmp(exp->expectant->helper->name, info->name,
+ strlen(exp->expectant->helper->name));
out_unlock:
READ_UNLOCK(&ip_conntrack_lock);
return ret;
@@ -92,10 +95,6 @@ static int check(const char *tablename,
if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info)))
return 0;
- /* verify that we actually should match anything */
- if ( strlen(info->name) == 0 )
- return 0;
-
return 1;
}
@@ -108,7 +107,6 @@ static struct ipt_match helper_match = {
static int __init init(void)
{
- need_ip_conntrack();
return ipt_register_match(&helper_match);
}
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index 91c3fd3f1f8f..3b9065e06381 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -184,7 +184,15 @@ checkentry(const char *tablename,
IPT_ALIGN(sizeof(struct ipt_owner_info)));
return 0;
}
-
+#ifdef CONFIG_SMP
+ /* files->file_lock can not be used in a BH */
+ if (((struct ipt_owner_info *)matchinfo)->match
+ & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
+ printk("ipt_owner: pid, sid and command matching is broken "
+ "on SMP.\n");
+ return 0;
+ }
+#endif
return 1;
}
diff --git a/net/ipv4/netfilter/ipt_realm.c b/net/ipv4/netfilter/ipt_realm.c
new file mode 100644
index 000000000000..54a6897ebaa6
--- /dev/null
+++ b/net/ipv4/netfilter/ipt_realm.c
@@ -0,0 +1,76 @@
+/* IP tables module for matching the routing realm
+ *
+ * $Id: ipt_realm.c,v 1.3 2004/03/05 13:25:40 laforge Exp $
+ *
+ * (C) 2003 by Sampsa Ranta <sampsa@netsonic.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <net/route.h>
+
+#include <linux/netfilter_ipv4/ipt_realm.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("iptables realm match");
+
+static int
+match(const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const void *matchinfo,
+ int offset,
+ int *hotdrop)
+{
+ const struct ipt_realm_info *info = matchinfo;
+ struct dst_entry *dst = skb->dst;
+
+ return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
+}
+
+static int check(const char *tablename,
+ const struct ipt_ip *ip,
+ void *matchinfo,
+ unsigned int matchsize,
+ unsigned int hook_mask)
+{
+ if (hook_mask
+ & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
+ (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) {
+ printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, "
+ "LOCAL_IN or FORWARD.\n");
+ return 0;
+ }
+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) {
+ printk("ipt_realm: invalid matchsize.\n");
+ return 0;
+ }
+ return 1;
+}
+
+static struct ipt_match realm_match = {
+ .name = "realm",
+ .match = match,
+ .checkentry = check,
+ .me = THIS_MODULE
+};
+
+static int __init init(void)
+{
+ return ipt_register_match(&realm_match);
+}
+
+static void __exit fini(void)
+{
+ ipt_unregister_match(&realm_match);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 1c3d96b5f7f7..b5b43b277fe2 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -173,7 +173,9 @@ ipt_local_hook(unsigned int hook,
if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE
&& ((*pskb)->nh.iph->saddr != saddr
|| (*pskb)->nh.iph->daddr != daddr
+#ifdef CONFIG_IP_ROUTE_FWMARK
|| (*pskb)->nfmark != nfmark
+#endif
|| (*pskb)->nh.iph->tos != tos))
return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 4c2266d2013b..0fd648ac0df3 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -32,43 +32,64 @@ static struct
struct ipt_replace repl;
struct ipt_standard entries[2];
struct ipt_error term;
-} initial_table __initdata
-= { { "raw", RAW_VALID_HOOKS, 3,
- sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
- { [NF_IP_PRE_ROUTING] 0,
- [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
- { [NF_IP_PRE_ROUTING] 0,
- [NF_IP_LOCAL_OUT] sizeof(struct ipt_standard) },
- 0, NULL, { } },
- {
- /* PRE_ROUTING */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } },
- /* LOCAL_OUT */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_standard),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
- -NF_ACCEPT - 1 } }
- },
- /* ERROR */
- { { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
- 0,
- sizeof(struct ipt_entry),
- sizeof(struct ipt_error),
- 0, { 0, 0 }, { } },
- { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
- { } },
- "ERROR"
- }
- }
+} initial_table __initdata = {
+ .repl = {
+ .name = "raw",
+ .valid_hooks = RAW_VALID_HOOKS,
+ .num_entries = 3,
+ .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
+ .hook_entry = {
+ [NF_IP_PRE_ROUTING] = 0,
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
+ .underflow = {
+ [NF_IP_PRE_ROUTING] = 0,
+ [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) },
+ },
+ .entries = {
+ /* PRE_ROUTING */
+ {
+ .entry = {
+ .target_offset = sizeof(struct ipt_entry),
+ .next_offset = sizeof(struct ipt_standard),
+ },
+ .target = {
+ .target = {
+ .u.target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
+ },
+ .verdict = -NF_ACCEPT - 1,
+ },
+ },
+
+ /* LOCAL_OUT */
+ {
+ .entry = {
+ .target_offset = sizeof(struct ipt_entry),
+ .next_offset = sizeof(struct ipt_standard),
+ },
+ .target = {
+ .target = {
+ .u.target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
+ },
+ .verdict = -NF_ACCEPT - 1,
+ },
+ },
+ },
+ /* ERROR */
+ .term = {
+ .entry = {
+ .target_offset = sizeof(struct ipt_entry),
+ .next_offset = sizeof(struct ipt_error),
+ },
+ .target = {
+ .target = {
+ .u.user = {
+ .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)),
+ .name = IPT_ERROR_TARGET,
+ },
+ },
+ .errorname = "ERROR",
+ },
+ }
};
static struct ipt_table packet_raw = {
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index cf0adc2f1a89..bf17df099f66 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -333,7 +333,7 @@ int tcp_mem_schedule(struct sock *sk, int size, int kind)
suppress_allocation:
if (!kind) {
- tcp_moderate_sndbuf(sk);
+ sk_stream_moderate_sndbuf(sk);
/* Fail only if socket is _under_ its sndbuf.
* In this case we cannot block, so that we have to fail.
@@ -360,14 +360,6 @@ void __tcp_mem_reclaim(struct sock *sk)
}
}
-void tcp_rfree(struct sk_buff *skb)
-{
- struct sock *sk = skb->sk;
-
- atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
- sk->sk_forward_alloc += skb->truesize;
-}
-
/*
* LISTEN is a special case for poll..
*/
@@ -636,102 +628,6 @@ static void tcp_listen_stop (struct sock *sk)
BUG_TRAP(!sk->sk_ack_backlog);
}
-/*
- * Wait for a socket to get into the connected state
- *
- * Note: Must be called with the socket locked.
- */
-static int wait_for_tcp_connect(struct sock *sk, int flags, long *timeo_p)
-{
- struct tcp_opt *tp = tcp_sk(sk);
- struct task_struct *tsk = current;
- DEFINE_WAIT(wait);
-
- while ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
- if (sk->sk_err)
- return sock_error(sk);
- if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
- return -EPIPE;
- if (!*timeo_p)
- return -EAGAIN;
- if (signal_pending(tsk))
- return sock_intr_errno(*timeo_p);
-
- prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- tp->write_pending++;
-
- release_sock(sk);
- *timeo_p = schedule_timeout(*timeo_p);
- lock_sock(sk);
-
- finish_wait(sk->sk_sleep, &wait);
- tp->write_pending--;
- }
- return 0;
-}
-
-/*
- * Wait for more memory for a socket
- */
-static int wait_for_tcp_memory(struct sock *sk, long *timeo)
-{
- struct tcp_opt *tp = tcp_sk(sk);
- int err = 0;
- long vm_wait = 0;
- long current_timeo = *timeo;
- DEFINE_WAIT(wait);
-
- if (sk_stream_memory_free(sk))
- current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2;
-
- for (;;) {
- set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
-
- prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
-
- if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
- goto do_error;
- if (!*timeo)
- goto do_nonblock;
- if (signal_pending(current))
- goto do_interrupted;
- clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
- if (sk_stream_memory_free(sk) && !vm_wait)
- break;
-
- set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
- tp->write_pending++;
- release_sock(sk);
- if (!sk_stream_memory_free(sk) || vm_wait)
- current_timeo = schedule_timeout(current_timeo);
- lock_sock(sk);
- tp->write_pending--;
-
- if (vm_wait) {
- vm_wait -= current_timeo;
- current_timeo = *timeo;
- if (current_timeo != MAX_SCHEDULE_TIMEOUT &&
- (current_timeo -= vm_wait) < 0)
- current_timeo = 0;
- vm_wait = 0;
- }
- *timeo = current_timeo;
- }
-out:
- finish_wait(sk->sk_sleep, &wait);
- return err;
-
-do_error:
- err = -EPIPE;
- goto out;
-do_nonblock:
- err = -EAGAIN;
- goto out;
-do_interrupted:
- err = sock_intr_errno(*timeo);
- goto out;
-}
-
static inline void fill_page_desc(struct sk_buff *skb, int i,
struct page *page, int off, int size)
{
@@ -763,8 +659,8 @@ static inline void skb_entail(struct sock *sk, struct tcp_opt *tp,
TCP_SKB_CB(skb)->sacked = 0;
__skb_queue_tail(&sk->sk_write_queue, skb);
sk_charge_skb(sk, skb);
- if (!tp->send_head)
- tp->send_head = skb;
+ if (!sk->sk_send_head)
+ sk->sk_send_head = skb;
else if (tp->nonagle&TCP_NAGLE_PUSH)
tp->nonagle &= ~TCP_NAGLE_PUSH;
}
@@ -782,7 +678,7 @@ static inline void tcp_mark_urg(struct tcp_opt *tp, int flags,
static inline void tcp_push(struct sock *sk, struct tcp_opt *tp, int flags,
int mss_now, int nonagle)
{
- if (tp->send_head) {
+ if (sk->sk_send_head) {
struct sk_buff *skb = sk->sk_write_queue.prev;
if (!(flags & MSG_MORE) || forced_push(tp))
tcp_mark_push(tp, skb);
@@ -792,15 +688,6 @@ static inline void tcp_push(struct sock *sk, struct tcp_opt *tp, int flags,
}
}
-static int tcp_error(struct sock *sk, int flags, int err)
-{
- if (err == -EPIPE)
- err = sock_error(sk) ? : -EPIPE;
- if (err == -EPIPE && !(flags & MSG_NOSIGNAL))
- send_sig(SIGPIPE, current, 0);
- return err;
-}
-
static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
size_t psize, int flags)
{
@@ -812,7 +699,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
/* Wait for a connection to finish. */
if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))
- if ((err = wait_for_tcp_connect(sk, 0, &timeo)) != 0)
+ if ((err = sk_stream_wait_connect(sk, &timeo)) != 0)
goto out_err;
clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
@@ -831,7 +718,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse
int offset = poffset % PAGE_SIZE;
int size = min_t(size_t, psize, PAGE_SIZE - offset);
- if (!tp->send_head || (copy = mss_now - skb->len) <= 0) {
+ if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) {
new_segment:
if (!sk_stream_memory_free(sk))
goto wait_for_sndbuf;
@@ -879,7 +766,7 @@ new_segment:
if (forced_push(tp)) {
tcp_mark_push(tp, skb);
__tcp_push_pending_frames(sk, tp, mss_now, TCP_NAGLE_PUSH);
- } else if (skb == tp->send_head)
+ } else if (skb == sk->sk_send_head)
tcp_push_one(sk, mss_now);
continue;
@@ -889,7 +776,7 @@ wait_for_memory:
if (copied)
tcp_push(sk, tp, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
- if ((err = wait_for_tcp_memory(sk, &timeo)) != 0)
+ if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
goto do_error;
mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
@@ -904,7 +791,7 @@ do_error:
if (copied)
goto out;
out_err:
- return tcp_error(sk, flags, err);
+ return sk_stream_error(sk, flags, err);
}
ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset,
@@ -965,7 +852,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* Wait for a connection to finish. */
if ((1 << sk->sk_state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))
- if ((err = wait_for_tcp_connect(sk, flags, &timeo)) != 0)
+ if ((err = sk_stream_wait_connect(sk, &timeo)) != 0)
goto out_err;
/* This should be in poll */
@@ -993,7 +880,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
skb = sk->sk_write_queue.prev;
- if (!tp->send_head ||
+ if (!sk->sk_send_head ||
(copy = mss_now - skb->len) <= 0) {
new_segment:
@@ -1122,7 +1009,7 @@ new_segment:
if (forced_push(tp)) {
tcp_mark_push(tp, skb);
__tcp_push_pending_frames(sk, tp, mss_now, TCP_NAGLE_PUSH);
- } else if (skb == tp->send_head)
+ } else if (skb == sk->sk_send_head)
tcp_push_one(sk, mss_now);
continue;
@@ -1132,7 +1019,7 @@ wait_for_memory:
if (copied)
tcp_push(sk, tp, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
- if ((err = wait_for_tcp_memory(sk, &timeo)) != 0)
+ if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
goto do_error;
mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
@@ -1148,17 +1035,17 @@ out:
do_fault:
if (!skb->len) {
- if (tp->send_head == skb)
- tp->send_head = NULL;
+ if (sk->sk_send_head == skb)
+ sk->sk_send_head = NULL;
__skb_unlink(skb, skb->list);
- tcp_free_skb(sk, skb);
+ sk_stream_free_skb(sk, skb);
}
do_error:
if (copied)
goto out;
out_err:
- err = tcp_error(sk, flags, err);
+ err = sk_stream_error(sk, flags, err);
TCP_CHECK_TIMER(sk);
release_sock(sk);
return err;
@@ -1747,17 +1634,6 @@ void tcp_shutdown(struct sock *sk, int how)
}
}
-
-/*
- * Return 1 if we still have things to send in our buffers.
- */
-
-static inline int closing(struct sock *sk)
-{
- return (1 << sk->sk_state) &
- (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK);
-}
-
static __inline__ void tcp_kill_sk_queues(struct sock *sk)
{
/* First the read buffer. */
@@ -1900,22 +1776,7 @@ void tcp_close(struct sock *sk, long timeout)
tcp_send_fin(sk);
}
- if (timeout) {
- struct task_struct *tsk = current;
- DEFINE_WAIT(wait);
-
- do {
- prepare_to_wait(sk->sk_sleep, &wait,
- TASK_INTERRUPTIBLE);
- if (!closing(sk))
- break;
- release_sock(sk);
- timeout = schedule_timeout(timeout);
- lock_sock(sk);
- } while (!signal_pending(tsk) && timeout);
-
- finish_wait(sk->sk_sleep, &wait);
- }
+ sk_stream_wait_close(sk, timeout);
adjudge_to_death:
/* It is the last release_sock in its life. It will remove backlog. */
@@ -2046,7 +1907,7 @@ int tcp_disconnect(struct sock *sk, int flags)
tcp_set_ca_state(tp, TCP_CA_Open);
tcp_clear_retrans(tp);
tcp_delack_init(tp);
- tp->send_head = NULL;
+ sk->sk_send_head = NULL;
tp->saw_tstamp = 0;
tcp_sack_reset(tp);
__sk_dst_reset(sk);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index cd72986ebc50..65afca6006b2 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1009,7 +1009,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
if (after(end_seq, tp->high_seq))
flag |= FLAG_DATA_LOST;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
u8 sacked = TCP_SKB_CB(skb)->sacked;
int in_sack;
@@ -1113,7 +1113,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
if (lost_retrans && tp->ca_state == TCP_CA_Recovery) {
struct sk_buff *skb;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
if (after(TCP_SKB_CB(skb)->seq, lost_retrans))
break;
if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
@@ -1179,7 +1179,7 @@ void tcp_enter_frto(struct sock *sk)
tp->undo_marker = tp->snd_una;
tp->undo_retrans = 0;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
TCP_SKB_CB(skb)->sacked &= ~TCPCB_RETRANS;
}
tcp_sync_left_out(tp);
@@ -1202,7 +1202,7 @@ static void tcp_enter_frto_loss(struct sock *sk)
tp->lost_out = 0;
tp->fackets_out = 0;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
cnt++;
TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) {
@@ -1275,7 +1275,7 @@ void tcp_enter_loss(struct sock *sk, int how)
if (!how)
tp->undo_marker = tp->snd_una;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
cnt++;
if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS)
tp->undo_marker = 0;
@@ -1518,7 +1518,7 @@ tcp_mark_head_lost(struct sock *sk, struct tcp_opt *tp, int packets, u32 high_se
BUG_TRAP(cnt <= tp->packets_out);
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
if (--cnt < 0 || after(TCP_SKB_CB(skb)->end_seq, high_seq))
break;
if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
@@ -1550,7 +1550,7 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_opt *tp)
if (tcp_head_timedout(sk, tp)) {
struct sk_buff *skb;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
if (tcp_skb_timedout(tp, skb) &&
!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) {
TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
@@ -1719,7 +1719,7 @@ static int tcp_try_undo_loss(struct sock *sk, struct tcp_opt *tp)
{
if (tcp_may_undo(tp)) {
struct sk_buff *skb;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
}
DBGUNDO(sk, tp, "partial loss");
@@ -2328,7 +2328,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
int acked = 0;
__s32 seq_rtt = -1;
- while ((skb = skb_peek(&sk->sk_write_queue)) && skb != tp->send_head) {
+ while ((skb = skb_peek(&sk->sk_write_queue)) && skb != sk->sk_send_head) {
struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
__u8 sacked = scb->sacked;
@@ -2376,7 +2376,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
tp->fackets_out--;
tp->packets_out--;
__skb_unlink(skb, skb->list);
- tcp_free_skb(sk, skb);
+ sk_stream_free_skb(sk, skb);
}
if (acked&FLAG_ACKED) {
@@ -2416,7 +2416,7 @@ static void tcp_ack_probe(struct sock *sk)
/* Was it a usable window open? */
- if (!after(TCP_SKB_CB(tp->send_head)->end_seq,
+ if (!after(TCP_SKB_CB(sk->sk_send_head)->end_seq,
tp->snd_una + tp->snd_wnd)) {
tp->backoff = 0;
tcp_clear_xmit_timer(sk, TCP_TIME_PROBE0);
@@ -2857,7 +2857,7 @@ no_queue:
* being used to time the probes, and is probably far higher than
* it needs to be for normal retransmission.
*/
- if (tp->send_head)
+ if (sk->sk_send_head)
tcp_ack_probe(sk);
return 1;
@@ -3461,7 +3461,7 @@ queue_and_out:
if (tcp_prune_queue(sk) < 0 || !tcp_rmem_schedule(sk, skb))
goto drop;
}
- tcp_set_owner_r(skb, sk);
+ sk_stream_set_owner_r(skb, sk);
__skb_queue_tail(&sk->sk_receive_queue, skb);
}
tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
@@ -3542,7 +3542,7 @@ drop:
SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
- tcp_set_owner_r(skb, sk);
+ sk_stream_set_owner_r(skb, sk);
if (!skb_peek(&tp->out_of_order_queue)) {
/* Initial out of order segment, build 1 SACK. */
@@ -3681,7 +3681,7 @@ tcp_collapse(struct sock *sk, struct sk_buff *head,
memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
__skb_insert(nskb, skb->prev, skb, skb->list);
- tcp_set_owner_r(nskb, sk);
+ sk_stream_set_owner_r(nskb, sk);
/* Copy data, releasing collapsed skbs. */
while (copy > 0) {
@@ -3837,7 +3837,7 @@ void tcp_cwnd_application_limited(struct sock *sk)
/* When incoming ACK allowed to free some skb from write_queue,
- * we remember this event in flag tp->queue_shrunk and wake up socket
+ * we remember this event in flag sk->sk_queue_shrunk and wake up socket
* on the exit from tcp input handler.
*
* PROBLEM: sndbuf expansion does not work well with largesend.
@@ -3865,10 +3865,8 @@ static void tcp_new_space(struct sock *sk)
static inline void tcp_check_space(struct sock *sk)
{
- struct tcp_opt *tp = tcp_sk(sk);
-
- if (tp->queue_shrunk) {
- tp->queue_shrunk = 0;
+ if (sk->sk_queue_shrunk) {
+ sk->sk_queue_shrunk = 0;
if (sk->sk_socket &&
test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
tcp_new_space(sk);
@@ -3887,8 +3885,7 @@ static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb)
static __inline__ void tcp_data_snd_check(struct sock *sk)
{
- struct tcp_opt *tp = tcp_sk(sk);
- struct sk_buff *skb = tp->send_head;
+ struct sk_buff *skb = sk->sk_send_head;
if (skb != NULL)
__tcp_data_snd_check(sk, skb);
@@ -4242,7 +4239,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
/* Bulk data transfer: receiver */
__skb_pull(skb,tcp_header_len);
__skb_queue_tail(&sk->sk_receive_queue, skb);
- tcp_set_owner_r(skb, sk);
+ sk_stream_set_owner_r(skb, sk);
tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
}
@@ -4482,7 +4479,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
sk_wake_async(sk, 0, POLL_OUT);
}
- if (tp->write_pending || tp->defer_accept || tp->ack.pingpong) {
+ if (sk->sk_write_pending || tp->defer_accept || tp->ack.pingpong) {
/* Save one ACK. Data will be ready after
* several ticks, if write_pending is set.
*
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 3af98bd3ff3e..dacd76e33133 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -718,6 +718,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
sock_reset_flag(newsk, SOCK_DONE);
newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK;
newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
+ newsk->sk_send_head = NULL;
newsk->sk_callback_lock = RW_LOCK_UNLOCKED;
skb_queue_head_init(&newsk->sk_error_queue);
newsk->sk_write_space = sk_stream_write_space;
@@ -775,7 +776,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
tcp_set_ca_state(newtp, TCP_CA_Open);
tcp_init_xmit_timers(newsk);
skb_queue_head_init(&newtp->out_of_order_queue);
- newtp->send_head = NULL;
newtp->rcv_wup = req->rcv_isn + 1;
newtp->write_seq = req->snt_isn + 1;
newtp->pushed_seq = newtp->write_seq;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index ad0c2ac89a1a..7d6eca0cd01e 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -48,9 +48,9 @@ int sysctl_tcp_retrans_collapse = 1;
static __inline__
void update_send_head(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
{
- tp->send_head = skb->next;
- if (tp->send_head == (struct sk_buff *)&sk->sk_write_queue)
- tp->send_head = NULL;
+ sk->sk_send_head = skb->next;
+ if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
+ sk->sk_send_head = NULL;
tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
if (tp->packets_out++ == 0)
tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
@@ -329,8 +329,8 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
sk_charge_skb(sk, skb);
/* Queue it, remembering where we must start sending. */
- if (tp->send_head == NULL)
- tp->send_head = skb;
+ if (sk->sk_send_head == NULL)
+ sk->sk_send_head = skb;
}
/* Send _single_ skb sitting at the send head. This function requires
@@ -339,13 +339,13 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
void tcp_push_one(struct sock *sk, unsigned cur_mss)
{
struct tcp_opt *tp = tcp_sk(sk);
- struct sk_buff *skb = tp->send_head;
+ struct sk_buff *skb = sk->sk_send_head;
if (tcp_snd_test(tp, skb, cur_mss, TCP_NAGLE_PUSH)) {
/* Send it out now. */
TCP_SKB_CB(skb)->when = tcp_time_stamp;
if (!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation))) {
- tp->send_head = NULL;
+ sk->sk_send_head = NULL;
tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
if (tp->packets_out++ == 0)
tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
@@ -572,8 +572,10 @@ int tcp_write_xmit(struct sock *sk, int nonagle)
*/
mss_now = tcp_current_mss(sk, 1);
- while((skb = tp->send_head) &&
- tcp_snd_test(tp, skb, mss_now, tcp_skb_is_last(sk, skb) ? nonagle : TCP_NAGLE_PUSH)) {
+ while ((skb = sk->sk_send_head) &&
+ tcp_snd_test(tp, skb, mss_now,
+ tcp_skb_is_last(sk, skb) ? nonagle :
+ TCP_NAGLE_PUSH)) {
if (skb->len > mss_now) {
if (tcp_fragment(sk, skb, mss_now))
break;
@@ -593,7 +595,7 @@ int tcp_write_xmit(struct sock *sk, int nonagle)
return 0;
}
- return !tp->packets_out && tp->send_head;
+ return !tp->packets_out && sk->sk_send_head;
}
return 0;
}
@@ -763,7 +765,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int m
*/
if (tp->fackets_out)
tp->fackets_out--;
- tcp_free_skb(sk, next_skb);
+ sk_stream_free_skb(sk, next_skb);
tp->packets_out--;
}
}
@@ -779,7 +781,7 @@ void tcp_simple_retransmit(struct sock *sk)
unsigned int mss = tcp_current_mss(sk, 0);
int lost = 0;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
if (skb->len > mss &&
!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) {
if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) {
@@ -865,7 +867,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
/* Collapse two adjacent packets if worthwhile and we can. */
if(!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) &&
(skb->len < (cur_mss >> 1)) &&
- (skb->next != tp->send_head) &&
+ (skb->next != sk->sk_send_head) &&
(skb->next != (struct sk_buff *)&sk->sk_write_queue) &&
(skb_shinfo(skb)->nr_frags == 0 && skb_shinfo(skb->next)->nr_frags == 0) &&
(sysctl_tcp_retrans_collapse != 0))
@@ -940,7 +942,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
/* First pass: retransmit lost packets. */
if (packet_cnt) {
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
__u8 sacked = TCP_SKB_CB(skb)->sacked;
if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
@@ -988,7 +990,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
packet_cnt = 0;
- for_retrans_queue(skb, sk, tp) {
+ sk_stream_for_retrans_queue(skb, sk) {
if(++packet_cnt > tp->fackets_out)
break;
@@ -1025,7 +1027,7 @@ void tcp_send_fin(struct sock *sk)
*/
mss_now = tcp_current_mss(sk, 1);
- if(tp->send_head != NULL) {
+ if (sk->sk_send_head != NULL) {
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_FIN;
TCP_SKB_CB(skb)->end_seq++;
tp->write_seq++;
@@ -1104,7 +1106,7 @@ int tcp_send_synack(struct sock *sk)
return -ENOMEM;
__skb_unlink(skb, &sk->sk_write_queue);
__skb_queue_head(&sk->sk_write_queue, nskb);
- tcp_free_skb(sk, skb);
+ sk_stream_free_skb(sk, skb);
sk_charge_skb(sk, nskb);
skb = nskb;
}
@@ -1404,7 +1406,7 @@ int tcp_write_wakeup(struct sock *sk)
struct tcp_opt *tp = tcp_sk(sk);
struct sk_buff *skb;
- if ((skb = tp->send_head) != NULL &&
+ if ((skb = sk->sk_send_head) != NULL &&
before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)) {
int err;
int mss = tcp_current_mss(sk, 0);
@@ -1458,7 +1460,7 @@ void tcp_send_probe0(struct sock *sk)
err = tcp_write_wakeup(sk);
- if (tp->packets_out || !tp->send_head) {
+ if (tp->packets_out || !sk->sk_send_head) {
/* Cancel probe timer, if it is not required. */
tp->probes_out = 0;
tp->backoff = 0;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index cab2678b1958..44615198e6a1 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -269,7 +269,7 @@ static void tcp_probe_timer(struct sock *sk)
struct tcp_opt *tp = tcp_sk(sk);
int max_probes;
- if (tp->packets_out || !tp->send_head) {
+ if (tp->packets_out || !sk->sk_send_head) {
tp->probes_out = 0;
return;
}
@@ -606,7 +606,7 @@ static void tcp_keepalive_timer (unsigned long data)
elapsed = keepalive_time_when(tp);
/* It is alive without keepalive 8) */
- if (tp->packets_out || tp->send_head)
+ if (tp->packets_out || sk->sk_send_head)
goto resched;
elapsed = tcp_time_stamp - tp->rcv_tstamp;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index fb2720697d96..8682cf13402a 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -38,8 +38,6 @@
#include <net/ipv6.h>
#include <linux/icmpv6.h>
-#define MAX_SG_ONSTACK 4
-
int esp6_output(struct sk_buff **pskb)
{
int err;
@@ -151,17 +149,16 @@ int esp6_output(struct sk_buff **pskb)
crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
do {
- struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
- struct scatterlist *sg = sgbuf;
+ struct scatterlist *sg = &esp->sgbuf[0];
- if (unlikely(nfrags > MAX_SG_ONSTACK)) {
+ if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg)
goto error;
}
skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
crypto_cipher_encrypt(tfm, sg, sg, clen);
- if (unlikely(sg != sgbuf))
+ if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
} while (0);
@@ -259,12 +256,11 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
{
u8 nexthdr[2];
- struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
- struct scatterlist *sg = sgbuf;
+ struct scatterlist *sg = &esp->sgbuf[0];
u8 padlen;
u8 *prevhdr;
- if (unlikely(nfrags > MAX_SG_ONSTACK)) {
+ if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg) {
ret = -ENOMEM;
@@ -273,7 +269,7 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
}
skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen);
crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
- if (unlikely(sg != sgbuf))
+ if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 9e5677dd45a2..0c8db0391a78 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -722,13 +722,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
ipv6h->nexthdr = proto;
ipv6_addr_copy(&ipv6h->saddr, &fl.fl6_src);
ipv6_addr_copy(&ipv6h->daddr, &fl.fl6_dst);
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-#endif
+ nf_reset(skb);
pkt_len = skb->len;
err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
skb->dst->dev, dst_output);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 223212888321..d2ce00d81d4c 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1845,6 +1845,15 @@ static inline int print_name(const char *i,
return 0;
}
+static inline int print_target(const struct ip6t_target *t,
+ off_t start_offset, char *buffer, int length,
+ off_t *pos, unsigned int *count)
+{
+ if (t == &ip6t_standard_target || t == &ip6t_error_target)
+ return 0;
+ return print_name((char *)t, start_offset, buffer, length, pos, count);
+}
+
static int ip6t_get_tables(char *buffer, char **start, off_t offset, int length)
{
off_t pos = 0;
@@ -1871,7 +1880,7 @@ static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length
if (down_interruptible(&ip6t_mutex) != 0)
return 0;
- LIST_FIND(&ip6t_target, print_name, char *,
+ LIST_FIND(&ip6t_target, print_target, struct ip6t_target *,
offset, buffer, length, &pos, &count);
up(&ip6t_mutex);
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index 0bb9c661b73c..272257b3b637 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -143,7 +143,14 @@ checkentry(const char *tablename,
if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_owner_info)))
return 0;
-
+#ifdef CONFIG_SMP
+ /* files->file_lock can not be used in a BH */
+ if (((struct ip6t_owner_info *)matchinfo)->match
+ & (IP6T_OWNER_PID|IP6T_OWNER_SID)) {
+ printk("ip6t_owner: pid and sid matching is broken on SMP.\n");
+ return 0;
+ }
+#endif
return 1;
}
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 2fac873fdd3d..2958bb9c76fe 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -388,13 +388,7 @@ static int ipip6_rcv(struct sk_buff *skb)
skb->dev = tunnel->dev;
dst_release(skb->dst);
skb->dst = NULL;
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-#endif
+ nf_reset(skb);
ipip6_ecn_decapsulate(iph, skb);
netif_rx(skb);
read_unlock(&ipip6_lock);
@@ -580,13 +574,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if ((iph->ttl = tiph->ttl) == 0)
iph->ttl = iph6->hop_limit;
-#ifdef CONFIG_NETFILTER
- nf_conntrack_put(skb->nfct);
- skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
- skb->nf_debug = 0;
-#endif
-#endif
+ nf_reset(skb);
IPTUNNEL_XMIT();
tunnel->recursion--;
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 8931426e0243..293655830d98 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -242,6 +242,7 @@ config NET_CLS_TCINDEX
config NET_CLS_ROUTE4
tristate "Routing table based classifier"
depends on NET_CLS
+ select NET_CLS_ROUTE
help
If you say Y here, you will be able to classify outgoing packets
according to the route table entry they matched. If unsure, say Y.
@@ -251,8 +252,7 @@ config NET_CLS_ROUTE4
config NET_CLS_ROUTE
bool
- depends on NET_CLS_ROUTE4
- default y
+ default n
config NET_CLS_FW
tristate "Firewall based classifier"
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 491b510b0782..d1b683952499 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -990,7 +990,7 @@ static int sctp_error(struct sock *sk, int flags, int err)
* Note: This function could use a rewrite especially when explicit
* connect support comes in.
*/
-/* BUG: We do not implement the equivalent of wait_for_tcp_memory(). */
+/* BUG: We do not implement the equivalent of sk_stream_wait_memory(). */
SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *);
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index 95dfeef913f1..4f80fec4f5c7 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -931,6 +931,13 @@ static int __init snd_pmac_detect(pmac_t *chip)
chip->freq_table = tumbler_freqs;
chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
}
+ if (device_is_compatible(sound, "AOAKeylargo")) {
+ /* Seems to support the stock AWACS frequencies, but has
+ a snapper mixer */
+ chip->model = PMAC_SNAPPER;
+ // chip->can_byte_swap = 0; /* FIXME: check this */
+ chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */
+ }
prop = (unsigned int *)get_property(sound, "device-id", 0);
if (prop)
chip->device_id = *prop;