Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 9 Feb 2006 01:06:51 +0000 (17:06 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 9 Feb 2006 01:06:51 +0000 (17:06 -0800)
372 files changed:
Documentation/feature-removal-schedule.txt
Documentation/hwmon/f71805f [new file with mode: 0644]
Documentation/hwmon/it87
Documentation/hwmon/sysfs-interface
Documentation/i2c/busses/i2c-sis96x [moved from Documentation/i2c/busses/i2c-sis69x with 98% similarity]
Documentation/powerpc/booting-without-of.txt
Documentation/spi/butterfly
Documentation/unshare.txt [new file with mode: 0644]
Documentation/video4linux/CARDLIST.cx88
Documentation/video4linux/CARDLIST.saa7134
MAINTAINERS
arch/alpha/kernel/smp.c
arch/arm/Kconfig
arch/arm/configs/enp2611_defconfig
arch/arm/configs/ixdp2400_defconfig
arch/arm/configs/ixdp2401_defconfig
arch/arm/configs/ixdp2801_defconfig
arch/arm/configs/s3c2410_defconfig
arch/arm/kernel/calls.S
arch/arm/kernel/entry-armv.S
arch/arm/kernel/sys_oabi-compat.c
arch/arm/mach-clps711x/Kconfig
arch/arm/mach-imx/mx1ads.c
arch/arm/mach-ixp2000/enp2611.c
arch/arm/mach-ixp2000/ixdp2400.c
arch/arm/mach-ixp2000/ixdp2x01.c
arch/arm/mach-omap1/board-generic.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-netstar.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/io.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-realview/core.c
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/clock.h
arch/arm/mach-s3c2410/devs.c
arch/arm/plat-omap/sram.c
arch/cris/arch-v10/kernel/ptrace.c
arch/cris/kernel/setup.c
arch/i386/kernel/syscall_table.S
arch/ia64/dig/setup.c
arch/ia64/sn/kernel/setup.c
arch/m32r/kernel/m32r_ksyms.c
arch/m32r/kernel/setup.c
arch/m68knommu/kernel/process.c
arch/mips/cobalt/setup.c
arch/mips/kernel/process.c
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/syscall.c
arch/mips/lasat/setup.c
arch/mips/mips-boards/atlas/atlas_setup.c
arch/mips/mips-boards/sead/sead_setup.c
arch/mips/mips-boards/sim/sim_setup.c
arch/mips/momentum/jaguar_atx/ja-console.c
arch/mips/philips/pnx8550/common/platform.c
arch/mips/pmc-sierra/yosemite/setup.c
arch/mips/sgi-ip32/ip32-setup.c
arch/parisc/hpux/sys_hpux.c
arch/powerpc/kernel/fpu.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/udbg_16550.c
arch/powerpc/mm/lmb.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/cell/Makefile
arch/powerpc/platforms/chrp/chrp.h
arch/powerpc/platforms/chrp/pci.c
arch/powerpc/platforms/chrp/setup.c
arch/powerpc/platforms/chrp/time.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/pci.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/pseries/eeh_driver.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/dart_iommu.c
arch/ppc/kernel/head_8xx.S
arch/ppc/kernel/ppc_ksyms.c
arch/ppc/platforms/4xx/bamboo.c
arch/ppc/platforms/4xx/bubinga.c
arch/ppc/platforms/4xx/ebony.c
arch/ppc/platforms/4xx/luan.c
arch/ppc/platforms/4xx/ocotea.c
arch/ppc/platforms/4xx/xilinx_ml300.c
arch/ppc/platforms/4xx/yucca.c
arch/ppc/platforms/83xx/mpc834x_sys.c
arch/ppc/platforms/85xx/mpc8540_ads.c
arch/ppc/platforms/85xx/mpc85xx_cds_common.c
arch/ppc/platforms/85xx/sbc8560.c
arch/ppc/platforms/85xx/tqm85xx.c
arch/ppc/platforms/chestnut.c
arch/ppc/platforms/ev64260.c
arch/ppc/platforms/radstone_ppc7d.c
arch/ppc/platforms/spruce.c
arch/ppc/syslib/ocp.c
arch/ppc/syslib/ppc83xx_setup.c
arch/ppc/syslib/ppc85xx_setup.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/sys_s390.c
arch/s390/kernel/traps.c
arch/s390/mm/cmm.c
arch/sh/boards/renesas/rts7751r2d/io.c
arch/sh64/kernel/sh_ksyms.c
arch/sparc/kernel/entry.S
arch/sparc/kernel/process.c
arch/sparc/kernel/systbls.S
arch/sparc64/defconfig
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/systbls.S
arch/sparc64/solaris/systbl.S
arch/um/drivers/chan_user.c
arch/um/drivers/net_kern.c
arch/um/include/registers.h
arch/um/kernel/skas/process.c [deleted file]
arch/um/kernel/um_arch.c
arch/um/os-Linux/drivers/tuntap_user.c
arch/um/os-Linux/skas/mem.c
arch/um/os-Linux/skas/process.c
arch/um/os-Linux/start_up.c
arch/um/os-Linux/sys-i386/registers.c
arch/um/os-Linux/sys-x86_64/registers.c
arch/um/sys-x86_64/ptrace_user.c
arch/um/sys-x86_64/user-offsets.c
arch/x86_64/ia32/ia32entry.S
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/time.c
arch/x86_64/kernel/x8664_ksyms.c
arch/x86_64/pci/mmconfig.c
block/elevator.c
block/ll_rw_blk.c
block/scsi_ioctl.c
crypto/scatterwalk.c
drivers/base/base.h
drivers/base/bus.c
drivers/base/memory.c
drivers/base/power/resume.c
drivers/base/power/shutdown.c
drivers/base/power/suspend.c
drivers/base/power/sysfs.c
drivers/base/sys.c
drivers/cdrom/viocd.c
drivers/char/Kconfig
drivers/char/drm/drmP.h
drivers/char/drm/drm_stub.c
drivers/char/drm/drm_sysfs.c
drivers/char/ser_a2232.c
drivers/char/watchdog/sbc_epx_c3.c
drivers/edac/i82875p_edac.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/f71805f.c [new file with mode: 0644]
drivers/hwmon/it87.c
drivers/hwmon/lm77.c
drivers/hwmon/w83792d.c
drivers/i2c/algos/i2c-algo-sibyte.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-parport-light.c
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/i2c-core.c
drivers/ide/ide-disk.c
drivers/infiniband/core/ucm.c
drivers/isdn/hisax/Kconfig
drivers/macintosh/Kconfig
drivers/macintosh/Makefile
drivers/macintosh/windfarm.h
drivers/macintosh/windfarm_core.c
drivers/macintosh/windfarm_max6690_sensor.c [new file with mode: 0644]
drivers/macintosh/windfarm_pid.c
drivers/macintosh/windfarm_pid.h
drivers/macintosh/windfarm_pm112.c [new file with mode: 0644]
drivers/macintosh/windfarm_pm81.c
drivers/macintosh/windfarm_pm91.c
drivers/macintosh/windfarm_smu_controls.c
drivers/macintosh/windfarm_smu_sat.c [new file with mode: 0644]
drivers/macintosh/windfarm_smu_sensors.c
drivers/media/dvb/b2c2/Kconfig
drivers/media/dvb/b2c2/flexcop-common.h
drivers/media/dvb/b2c2/flexcop-dma.c
drivers/media/dvb/b2c2/flexcop-fe-tuner.c
drivers/media/dvb/b2c2/flexcop-misc.c
drivers/media/dvb/b2c2/flexcop-pci.c
drivers/media/dvb/b2c2/flexcop-reg.h
drivers/media/dvb/bt8xx/bt878.c
drivers/media/dvb/bt8xx/bt878.h
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/dvb-usb/digitv.c
drivers/media/dvb/dvb-usb/dtt200u.c
drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/dvb-usb/vp702x.c
drivers/media/dvb/dvb-usb/vp702x.h
drivers/media/dvb/dvb-usb/vp7045-fe.c
drivers/media/dvb/dvb-usb/vp7045.c
drivers/media/dvb/frontends/Kconfig
drivers/media/dvb/frontends/Makefile
drivers/media/dvb/frontends/at76c651.c [deleted file]
drivers/media/dvb/frontends/at76c651.h [deleted file]
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/frontends/dvb-pll.h
drivers/media/dvb/frontends/nxt2002.c [deleted file]
drivers/media/dvb/frontends/nxt2002.h [deleted file]
drivers/media/dvb/frontends/nxt200x.c
drivers/media/dvb/frontends/tda80xx.c [deleted file]
drivers/media/dvb/frontends/tda80xx.h [deleted file]
drivers/media/dvb/ttpci/av7110.c
drivers/media/dvb/ttpci/av7110.h
drivers/media/dvb/ttpci/av7110_ir.c
drivers/media/video/bttv-driver.c
drivers/media/video/compat_ioctl32.c
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx88/Kconfig
drivers/media/video/cx88/Makefile
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-input.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-i2c.c
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/stradis.c
drivers/media/video/tda9887.c
drivers/media/video/tuner-core.c
drivers/media/video/tvaudio.c
drivers/media/video/tvp5150.c
drivers/mmc/Kconfig
drivers/mtd/chips/Kconfig
drivers/net/hamradio/baycom_par.c
drivers/net/mv643xx_eth.c
drivers/net/wan/pci200syn.c
drivers/net/wan/wanxl.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/scsi/aacraid/commsup.c
drivers/scsi/mac53c94.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/sg.c
drivers/serial/21285.c
drivers/serial/68328serial.c
drivers/serial/68360serial.c
drivers/serial/8250.c
drivers/serial/8250_au1x00.c
drivers/serial/8250_pci.c
drivers/serial/amba-pl010.c
drivers/serial/au1x00_uart.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/dz.c
drivers/serial/imx.c
drivers/serial/ip22zilog.c
drivers/serial/m32r_sio.c
drivers/serial/m32r_sio.h
drivers/serial/mcfserial.c
drivers/serial/mux.c
drivers/serial/pmac_zilog.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/serial_lh7a40x.c
drivers/serial/sh-sci.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/serial/v850e_uart.c
drivers/sn/ioc3.c
drivers/spi/Kconfig
drivers/spi/spi_butterfly.c
drivers/tc/tc.c
drivers/video/backlight/backlight.c
drivers/video/backlight/lcd.c
drivers/video/pmag-ba-fb.c
drivers/video/pmagb-b-fb.c
fs/compat_ioctl.c
fs/debugfs/file.c
fs/inotify.c
fs/namei.c
fs/namespace.c
fs/nfs/nfsroot.c
fs/nfsd/nfs4proc.c
fs/reiserfs/hashes.c
fs/select.c
fs/super.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_iops.c
include/asm-alpha/system.h
include/asm-arm/arch-omap/io.h
include/asm-arm/mutex.h
include/asm-i386/unistd.h
include/asm-m68knommu/hardirq.h
include/asm-mips/abi.h
include/asm-mips/io.h
include/asm-mips/thread_info.h
include/asm-mips/unistd.h
include/asm-powerpc/compat.h
include/asm-powerpc/dma-mapping.h
include/asm-powerpc/prom.h
include/asm-powerpc/smu.h
include/asm-powerpc/thread_info.h
include/asm-s390/uaccess.h
include/asm-sparc/unistd.h
include/asm-sparc64/unistd.h
include/asm-x86_64/ia32_unistd.h
include/asm-x86_64/numa.h
include/asm-x86_64/unistd.h
include/linux/cpumask.h
include/linux/dcache.h
include/linux/dvb/video.h
include/linux/elevator.h
include/linux/i2c.h
include/linux/ioc3.h
include/linux/jbd.h
include/linux/mm.h
include/linux/mtd/map.h
include/linux/namespace.h
include/linux/nodemask.h
include/linux/pci_ids.h
include/linux/smp.h
include/linux/suspend.h
include/linux/videodev2.h
init/Kconfig
kernel/compat.c
kernel/fork.c
kernel/module.c
kernel/power/console.c
kernel/power/power.h
kernel/power/swsusp.c
kernel/sys.c
kernel/timer.c
lib/kobject.c
lib/kobject_uevent.c
lib/spinlock_debug.c
mm/hugetlb.c
mm/slob.c
mm/swap.c
net/dccp/ccids/lib/tfrc_equation.c
net/ipv4/igmp.c
net/ipv4/xfrm4_policy.c
net/ipv6/addrconf.c
net/ipv6/mcast.c
net/ipv6/raw.c
net/ipv6/xfrm6_policy.c
net/xfrm/xfrm_policy.c
security/selinux/Kconfig
security/selinux/avc.c
sound/oss/dmasound/tas_common.h
sound/oss/emu10k1/recmgr.c
sound/ppc/pmac.c
sound/ppc/tumbler.c

index 4d4897c..b730d76 100644 (file)
@@ -162,3 +162,12 @@ What:      pci_module_init(driver)
 When:  January 2007
 Why:   Is replaced by pci_register_driver(pci_driver).
 Who:   Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de>
+
+---------------------------
+
+What:  I2C interface of the it87 driver
+When:  January 2007
+Why:   The ISA interface is faster and should be always available. The I2C
+       probing is also known to cause trouble in at least one case (see
+       bug #5889.)
+Who:   Jean Delvare <khali@linux-fr.org>
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f
new file mode 100644 (file)
index 0000000..28c5b7d
--- /dev/null
@@ -0,0 +1,105 @@
+Kernel driver f71805f
+=====================
+
+Supported chips:
+  * Fintek F71805F/FG
+    Prefix: 'f71805f'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Provided by Fintek on request
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+Thanks to Denis Kieft from Barracuda Networks for the donation of a
+test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and
+for providing initial documentation.
+
+Thanks to Kris Chen from Fintek for answering technical questions and
+providing additional documentation.
+
+Thanks to Chris Lin from Jetway for providing wiring schematics and
+anwsering technical questions.
+
+
+Description
+-----------
+
+The Fintek F71805F/FG Super I/O chip includes complete hardware monitoring
+capabilities. It can monitor up to 9 voltages (counting its own power
+source), 3 fans and 3 temperature sensors.
+
+This chip also has fan controlling features, using either DC or PWM, in
+three different modes (one manual, two automatic). The driver doesn't
+support these features yet.
+
+The driver assumes that no more than one chip is present, which seems
+reasonable.
+
+
+Voltage Monitoring
+------------------
+
+Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported
+range is thus from 0 to 2.040 V. Voltage values outside of this range
+need external resistors. An exception is in0, which is used to monitor
+the chip's own power source (+3.3V), and is divided internally by a
+factor 2.
+
+The two LSB of the voltage limit registers are not used (always 0), so
+you can only set the limits in steps of 32 mV (before scaling).
+
+The wirings and resistor values suggested by Fintek are as follow:
+
+        pin                                           expected
+        name    use           R1      R2     divider  raw val.
+
+in0     VCC     VCC3.3V     int.    int.        2.00    1.65 V
+in1     VIN1    VTT1.2V      10K       -        1.00    1.20 V
+in2     VIN2    VRAM        100K    100K        2.00   ~1.25 V (1)
+in3     VIN3    VCHIPSET     47K    100K        1.47    2.24 V (2)
+in4     VIN4    VCC5V       200K     47K        5.25    0.95 V
+in5     VIN5    +12V        200K     20K       11.00    1.05 V
+in6     VIN6    VCC1.5V      10K       -        1.00    1.50 V
+in7     VIN7    VCORE        10K       -        1.00   ~1.40 V (1)
+in8     VIN8    VSB5V       200K     47K        1.00    0.95 V
+
+(1) Depends on your hardware setup.
+(2) Obviously not correct, swapping R1 and R2 would make more sense.
+
+These values can be used as hints at best, as motherboard manufacturers
+are free to use a completely different setup. As a matter of fact, the
+Jetway K8M8MS uses a significantly different setup. You will have to
+find out documentation about your own motherboard, and edit sensors.conf
+accordingly.
+
+Each voltage measured has associated low and high limits, each of which
+triggers an alarm when crossed.
+
+
+Fan Monitoring
+--------------
+
+Fan rotation speeds are reported as 12-bit values from a gated clock
+signal. Speeds down to 366 RPM can be measured. There is no theoretical
+high limit, but values over 6000 RPM seem to cause problem. The effective
+resolution is much lower than you would expect, the step between different
+register values being 10 rather than 1.
+
+The chip assumes 2 pulse-per-revolution fans.
+
+An alarm is triggered if the rotation speed drops below a programmable
+limit or is too low to be measured.
+
+
+Temperature Monitoring
+----------------------
+
+Temperatures are reported in degrees Celsius. Each temperature measured
+has a high limit, those crossing triggers an alarm. There is an associated
+hysteresis value, below which the temperature has to drop before the
+alarm is cleared.
+
+All temperature channels are external, there is no embedded temperature
+sensor. Each channel can be used for connecting either a thermal diode
+or a thermistor. The driver reports the currently selected mode, but
+doesn't allow changing it. In theory, the BIOS should have configured
+everything properly.
index 7f42e44..9555be1 100644 (file)
@@ -9,7 +9,7 @@ Supported chips:
                http://www.ite.com.tw/
   * IT8712F
     Prefix: 'it8712'
-    Addresses scanned: I2C 0x28 - 0x2f
+    Addresses scanned: I2C 0x2d
                        from Super I/O config space (8 I/O ports)
     Datasheet: Publicly available at the ITE website
                http://www.ite.com.tw/
index 764cdc5..a0d0ab2 100644 (file)
@@ -179,11 +179,12 @@ temp[1-*]_auto_point[1-*]_temp_hyst
 ****************
 
 temp[1-3]_type Sensor type selection.
-               Integers 1, 2, 3 or thermistor Beta value (3435)
+               Integers 1 to 4 or thermistor Beta value (typically 3435)
                Read/Write.
                1: PII/Celeron Diode
                2: 3904 transistor
                3: thermal diode
+               4: thermistor (default/unknown Beta)
                Not all types are supported by all chips
 
 temp[1-4]_max  Temperature max value.
@@ -261,6 +262,21 @@ alarms             Alarm bitmask.
                of individual bits.
                Bits are defined in kernel/include/sensors.h.
 
+alarms_in      Alarm bitmask relative to in (voltage) channels
+               Read only
+               A '1' bit means an alarm, LSB corresponds to in0 and so on
+               Prefered to 'alarms' for newer chips
+
+alarms_fan     Alarm bitmask relative to fan channels
+               Read only
+               A '1' bit means an alarm, LSB corresponds to fan1 and so on
+               Prefered to 'alarms' for newer chips
+
+alarms_temp    Alarm bitmask relative to temp (temperature) channels
+               Read only
+               A '1' bit means an alarm, LSB corresponds to temp1 and so on
+               Prefered to 'alarms' for newer chips
+
 beep_enable    Beep/interrupt enable
                0 to disable.
                1 to enable.
similarity index 98%
rename from Documentation/i2c/busses/i2c-sis69x
rename to Documentation/i2c/busses/i2c-sis96x
index b88953d..00a009b 100644 (file)
@@ -7,7 +7,7 @@ Supported adapters:
     Any combination of these host bridges:
        645, 645DX (aka 646), 648, 650, 651, 655, 735, 745, 746
     and these south bridges:
-       961, 962, 963(L) 
+       961, 962, 963(L)
 
 Author: Mark M. Hoffman <mhoffman@lightlink.com>
 
@@ -29,7 +29,7 @@ The command "lspci" as root should produce something like these lines:
 
 or perhaps this...
 
-00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645 
+00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645
 00:02.0 ISA bridge: Silicon Integrated Systems [SiS]: Unknown device 0961
 00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016
 
index 1284498..54e5f9b 100644 (file)
@@ -880,6 +880,10 @@ address which can extend beyond that limit.
     - device_type : Should be "soc"
     - ranges : Should be defined as specified in 1) to describe the
       translation of SOC addresses for memory mapped SOC registers.
+    - bus-frequency: Contains the bus frequency for the SOC node.
+      Typically, the value of this field is filled in by the boot
+      loader. 
+
 
   Recommended properties:
 
@@ -919,6 +923,7 @@ SOC.
                device_type = "soc";
                ranges = <00000000 e0000000 00100000>
                reg = <e0000000 00003000>;
+               bus-frequency = <0>;
        }
 
 
@@ -1170,6 +1175,8 @@ platforms are moved over to use the flattened-device-tree model.
 
        mdio@24520 {
                reg = <24520 20>;
+               device_type = "mdio"; 
+               compatible = "gianfar";
 
                ethernet-phy@0 {
                        ......
@@ -1317,6 +1324,7 @@ not necessary as they are usually the same as the root node.
                device_type = "soc";
                ranges = <00000000 e0000000 00100000>
                reg = <e0000000 00003000>;
+               bus-frequency = <0>;
 
                mdio@24520 {
                        reg = <24520 20>;
index a2e8c8d..9927af7 100644 (file)
@@ -12,13 +12,20 @@ You can make this adapter from an old printer cable and solder things
 directly to the Butterfly.  Or (if you have the parts and skills) you
 can come up with something fancier, providing ciruit protection to the
 Butterfly and the printer port, or with a better power supply than two
-signal pins from the printer port.
+signal pins from the printer port.  Or for that matter, you can use
+similar cables to talk to many AVR boards, even a breadboard.
+
+This is more powerful than "ISP programming" cables since it lets kernel
+SPI protocol drivers interact with the AVR, and could even let the AVR
+issue interrupts to them.  Later, your protocol driver should work
+easily with a "real SPI controller", instead of this bitbanger.
 
 
 The first cable connections will hook Linux up to one SPI bus, with the
 AVR and a DataFlash chip; and to the AVR reset line.  This is all you
 need to reflash the firmware, and the pins are the standard Atmel "ISP"
-connector pins (used also on non-Butterfly AVR boards).
+connector pins (used also on non-Butterfly AVR boards).  On the parport
+side this is like "sp12" programming cables.
 
        Signal    Butterfly       Parport (DB-25)
        ------    ---------       ---------------
@@ -40,10 +47,14 @@ by clearing PORTB.[0-3]); (b) configure the mtd_dataflash driver; and
        SELECT  = J400.PB0/nSS  = pin 17/C3,nSELECT
        GND     = J400.GND      = pin 24/GND
 
-The "USI" controller, using J405, can be used for a second SPI bus.  That
-would let you talk to the AVR over SPI, running firmware that makes it act
-as an SPI slave, while letting either Linux or the AVR use the DataFlash.
-There are plenty of spare parport pins to wire this one up, such as:
+Or you could flash firmware making the AVR into an SPI slave (keeping the
+DataFlash in reset) and tweak the spi_butterfly driver to make it bind to
+the driver for your custom SPI-based protocol.
+
+The "USI" controller, using J405, can also be used for a second SPI bus.
+That would let you talk to the AVR using custom SPI-with-USI firmware,
+while letting either Linux or the AVR use the DataFlash.  There are plenty
+of spare parport pins to wire this one up, such as:
 
        Signal    Butterfly       Parport (DB-25)
        ------    ---------       ---------------
diff --git a/Documentation/unshare.txt b/Documentation/unshare.txt
new file mode 100644 (file)
index 0000000..90a5e9e
--- /dev/null
@@ -0,0 +1,295 @@
+
+unshare system call:
+--------------------
+This document describes the new system call, unshare. The document
+provides an overview of the feature, why it is needed, how it can
+be used, its interface specification, design, implementation and
+how it can be tested.
+
+Change Log:
+-----------
+version 0.1  Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006
+
+Contents:
+---------
+       1) Overview
+       2) Benefits
+       3) Cost
+       4) Requirements
+       5) Functional Specification
+       6) High Level Design
+       7) Low Level Design
+       8) Test Specification
+       9) Future Work
+
+1) Overview
+-----------
+Most legacy operating system kernels support an abstraction of threads
+as multiple execution contexts within a process. These kernels provide
+special resources and mechanisms to maintain these "threads". The Linux
+kernel, in a clever and simple manner, does not make distinction
+between processes and "threads". The kernel allows processes to share
+resources and thus they can achieve legacy "threads" behavior without
+requiring additional data structures and mechanisms in the kernel. The
+power of implementing threads in this manner comes not only from
+its simplicity but also from allowing application programmers to work
+outside the confinement of all-or-nothing shared resources of legacy
+threads. On Linux, at the time of thread creation using the clone system
+call, applications can selectively choose which resources to share
+between threads.
+
+unshare system call adds a primitive to the Linux thread model that
+allows threads to selectively 'unshare' any resources that were being
+shared at the time of their creation. unshare was conceptualized by
+Al Viro in the August of 2000, on the Linux-Kernel mailing list, as part
+of the discussion on POSIX threads on Linux.  unshare augments the
+usefulness of Linux threads for applications that would like to control
+shared resources without creating a new process. unshare is a natural
+addition to the set of available primitives on Linux that implement
+the concept of process/thread as a virtual machine.
+
+2) Benefits
+-----------
+unshare would be useful to large application frameworks such as PAM
+where creating a new process to control sharing/unsharing of process
+resources is not possible. Since namespaces are shared by default
+when creating a new process using fork or clone, unshare can benefit
+even non-threaded applications if they have a need to disassociate
+from default shared namespace. The following lists two use-cases
+where unshare can be used.
+
+2.1 Per-security context namespaces
+-----------------------------------
+unshare can be used to implement polyinstantiated directories using
+the kernel's per-process namespace mechanism. Polyinstantiated directories,
+such as per-user and/or per-security context instance of /tmp, /var/tmp or
+per-security context instance of a user's home directory, isolate user
+processes when working with these directories. Using unshare, a PAM
+module can easily setup a private namespace for a user at login.
+Polyinstantiated directories are required for Common Criteria certification
+with Labeled System Protection Profile, however, with the availability
+of shared-tree feature in the Linux kernel, even regular Linux systems
+can benefit from setting up private namespaces at login and
+polyinstantiating /tmp, /var/tmp and other directories deemed
+appropriate by system administrators.
+
+2.2 unsharing of virtual memory and/or open files
+-------------------------------------------------
+Consider a client/server application where the server is processing
+client requests by creating processes that share resources such as
+virtual memory and open files. Without unshare, the server has to
+decide what needs to be shared at the time of creating the process
+which services the request. unshare allows the server an ability to
+disassociate parts of the context during the servicing of the
+request. For large and complex middleware application frameworks, this
+ability to unshare after the process was created can be very
+useful.
+
+3) Cost
+-------
+In order to not duplicate code and to handle the fact that unshare
+works on an active task (as opposed to clone/fork working on a newly
+allocated inactive task) unshare had to make minor reorganizational
+changes to copy_* functions utilized by clone/fork system call.
+There is a cost associated with altering existing, well tested and
+stable code to implement a new feature that may not get exercised
+extensively in the beginning. However, with proper design and code
+review of the changes and creation of an unshare test for the LTP
+the benefits of this new feature can exceed its cost.
+
+4) Requirements
+---------------
+unshare reverses sharing that was done using clone(2) system call,
+so unshare should have a similar interface as clone(2). That is,
+since flags in clone(int flags, void *stack) specifies what should
+be shared, similar flags in unshare(int flags) should specify
+what should be unshared. Unfortunately, this may appear to invert
+the meaning of the flags from the way they are used in clone(2).
+However, there was no easy solution that was less confusing and that
+allowed incremental context unsharing in future without an ABI change.
+
+unshare interface should accommodate possible future addition of
+new context flags without requiring a rebuild of old applications.
+If and when new context flags are added, unshare design should allow
+incremental unsharing of those resources on an as needed basis.
+
+5) Functional Specification
+---------------------------
+NAME
+       unshare - disassociate parts of the process execution context
+
+SYNOPSIS
+       #include <sched.h>
+
+       int unshare(int flags);
+
+DESCRIPTION
+       unshare allows a process to disassociate parts of its execution
+       context that are currently being shared with other processes. Part
+       of execution context, such as the namespace, is shared by default
+       when a new process is created using fork(2), while other parts,
+       such as the virtual memory, open file descriptors, etc, may be
+       shared by explicit request to share them when creating a process
+       using clone(2).
+
+       The main use of unshare is to allow a process to control its
+       shared execution context without creating a new process.
+
+       The flags argument specifies one or bitwise-or'ed of several of
+       the following constants.
+
+       CLONE_FS
+               If CLONE_FS is set, file system information of the caller
+               is disassociated from the shared file system information.
+
+       CLONE_FILES
+               If CLONE_FILES is set, the file descriptor table of the
+               caller is disassociated from the shared file descriptor
+               table.
+
+       CLONE_NEWNS
+               If CLONE_NEWNS is set, the namespace of the caller is
+               disassociated from the shared namespace.
+
+       CLONE_VM
+               If CLONE_VM is set, the virtual memory of the caller is
+               disassociated from the shared virtual memory.
+
+RETURN VALUE
+       On success, zero returned. On failure, -1 is returned and errno is
+
+ERRORS
+       EPERM   CLONE_NEWNS was specified by a non-root process (process
+               without CAP_SYS_ADMIN).
+
+       ENOMEM  Cannot allocate sufficient memory to copy parts of caller's
+               context that need to be unshared.
+
+       EINVAL  Invalid flag was specified as an argument.
+
+CONFORMING TO
+       The unshare() call is Linux-specific and  should  not be used
+       in programs intended to be portable.
+
+SEE ALSO
+       clone(2), fork(2)
+
+6) High Level Design
+--------------------
+Depending on the flags argument, the unshare system call allocates
+appropriate process context structures, populates it with values from
+the current shared version, associates newly duplicated structures
+with the current task structure and releases corresponding shared
+versions. Helper functions of clone (copy_*) could not be used
+directly by unshare because of the following two reasons.
+  1) clone operates on a newly allocated not-yet-active task
+     structure, where as unshare operates on the current active
+     task. Therefore unshare has to take appropriate task_lock()
+     before associating newly duplicated context structures
+  2) unshare has to allocate and duplicate all context structures
+     that are being unshared, before associating them with the
+     current task and releasing older shared structures. Failure
+     do so will create race conditions and/or oops when trying
+     to backout due to an error. Consider the case of unsharing
+     both virtual memory and namespace. After successfully unsharing
+     vm, if the system call encounters an error while allocating
+     new namespace structure, the error return code will have to
+     reverse the unsharing of vm. As part of the reversal the
+     system call will have to go back to older, shared, vm
+     structure, which may not exist anymore.
+
+Therefore code from copy_* functions that allocated and duplicated
+current context structure was moved into new dup_* functions. Now,
+copy_* functions call dup_* functions to allocate and duplicate
+appropriate context structures and then associate them with the
+task structure that is being constructed. unshare system call on
+the other hand performs the following:
+  1) Check flags to force missing, but implied, flags
+  2) For each context structure, call the corresponding unshare
+     helper function to allocate and duplicate a new context
+     structure, if the appropriate bit is set in the flags argument.
+  3) If there is no error in allocation and duplication and there
+     are new context structures then lock the current task structure,
+     associate new context structures with the current task structure,
+     and release the lock on the current task structure.
+  4) Appropriately release older, shared, context structures.
+
+7) Low Level Design
+-------------------
+Implementation of unshare can be grouped in the following 4 different
+items:
+  a) Reorganization of existing copy_* functions
+  b) unshare system call service function
+  c) unshare helper functions for each different process context
+  d) Registration of system call number for different architectures
+
+  7.1) Reorganization of copy_* functions
+       Each copy function such as copy_mm, copy_namespace, copy_files,
+       etc, had roughly two components. The first component allocated
+       and duplicated the appropriate structure and the second component
+       linked it to the task structure passed in as an argument to the copy
+       function. The first component was split into its own function.
+       These dup_* functions allocated and duplicated the appropriate
+       context structure. The reorganized copy_* functions invoked
+       their corresponding dup_* functions and then linked the newly
+       duplicated structures to the task structure with which the
+       copy function was called.
+
+  7.2) unshare system call service function
+       * Check flags
+        Force implied flags. If CLONE_THREAD is set force CLONE_VM.
+        If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is
+        set and signals are also being shared, force CLONE_THREAD. If
+        CLONE_NEWNS is set, force CLONE_FS.
+       * For each context flag, invoke the corresponding unshare_*
+        helper routine with flags passed into the system call and a
+        reference to pointer pointing the new unshared structure
+       * If any new structures are created by unshare_* helper
+        functions, take the task_lock() on the current task,
+        modify appropriate context pointers, and release the
+         task lock.
+       * For all newly unshared structures, release the corresponding
+         older, shared, structures.
+
+  7.3) unshare_* helper functions
+       For unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND,
+       and CLONE_THREAD, return -EINVAL since they are not implemented yet.
+       For others, check the flag value to see if the unsharing is
+       required for that structure. If it is, invoke the corresponding
+       dup_* function to allocate and duplicate the structure and return
+       a pointer to it.
+
+  7.4) Appropriately modify architecture specific code to register the
+       the new system call.
+
+8) Test Specification
+---------------------
+The test for unshare should test the following:
+  1) Valid flags: Test to check that clone flags for signal and
+       signal handlers, for which unsharing is not implemented
+       yet, return -EINVAL.
+  2) Missing/implied flags: Test to make sure that if unsharing
+       namespace without specifying unsharing of filesystem, correctly
+       unshares both namespace and filesystem information.
+  3) For each of the four (namespace, filesystem, files and vm)
+       supported unsharing, verify that the system call correctly
+       unshares the appropriate structure. Verify that unsharing
+       them individually as well as in combination with each
+       other works as expected.
+  4) Concurrent execution: Use shared memory segments and futex on
+       an address in the shm segment to synchronize execution of
+       about 10 threads. Have a couple of threads execute execve,
+       a couple _exit and the rest unshare with different combination
+       of flags. Verify that unsharing is performed as expected and
+       that there are no oops or hangs.
+
+9) Future Work
+--------------
+The current implementation of unshare does not allow unsharing of
+signals and signal handlers. Signals are complex to begin with and
+to unshare signals and/or signal handlers of a currently running
+process is even more complex. If in the future there is a specific
+need to allow unsharing of signals and/or signal handlers, it can
+be incrementally added to unshare without affecting legacy
+applications using unshare.
+
index 56e194f..8bea3fb 100644 (file)
@@ -42,4 +42,4 @@
  41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)  [0070:9800,0070:9802]
  42 -> digitalnow DNTV Live! DVB-T Pro                     [1822:0025]
  43 -> KWorld/VStream XPert DVB-T with cx22702             [17de:08a1]
- 44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50]
+ 44 -> DViCO FusionHDTV DVB-T Dual Digital                 [18ac:db50,18ac:db54]
index cb3a59b..8a35259 100644 (file)
@@ -1,7 +1,7 @@
   0 -> UNKNOWN/GENERIC
   1 -> Proteus Pro [philips reference design]   [1131:2001,1131:2001]
   2 -> LifeView FlyVIDEO3000                    [5168:0138,4e42:0138]
-  3 -> LifeView FlyVIDEO2000                    [5168:0138]
+  3 -> LifeView/Typhoon FlyVIDEO2000            [5168:0138,4e42:0138]
   4 -> EMPRESS                                  [1131:6752]
   5 -> SKNet Monster TV                         [1131:4e85]
   6 -> Tevion MD 9717
  52 -> AverMedia AverTV/305                     [1461:2108]
  53 -> ASUS TV-FM 7135                          [1043:4845]
  54 -> LifeView FlyTV Platinum FM               [5168:0214,1489:0214]
- 55 -> LifeView FlyDVB-T DUO                    [5168:0502,5168:0306]
+ 55 -> LifeView FlyDVB-T DUO                    [5168:0306]
  56 -> Avermedia AVerTV 307                     [1461:a70a]
  57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
  58 -> ADS Tech Instant TV (saa7135)            [1421:0350,1421:0351,1421:0370,1421:1370]
  59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
- 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
+ 60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus    [5168:0502,4e42:0502]
  61 -> Philips TOUGH DVB-T reference design     [1131:2004]
  62 -> Compro VideoMate TV Gold+II
  63 -> Kworld Xpert TV PVR7134
index 11d44da..b22db52 100644 (file)
@@ -540,7 +540,8 @@ S:  Supported
 
 BTTV VIDEO4LINUX DRIVER
 P:     Mauro Carvalho Chehab
-M:     mchehab@brturbo.com.br
+M:     mchehab@infradead.org
+M:     v4l-dvb-maintainer@linuxtv.org
 L:     video4linux-list@redhat.com
 W:     http://linuxtv.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
@@ -837,11 +838,12 @@ S:        Maintained
 
 DVB SUBSYSTEM AND DRIVERS
 P:     LinuxTV.org Project
-M:     linux-dvb-maintainer@linuxtv.org
+M:     mchehab@infradead.org
+M:     v4l-dvb-maintainer@linuxtv.org
 L:     linux-dvb@linuxtv.org (subscription required)
 W:     http://linuxtv.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
-S:     Supported
+S:     Maintained
 
 EATA-DMA SCSI DRIVER
 P:     Michael Neuffer
@@ -929,6 +931,12 @@ M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com
 L:     ext3-users@redhat.com
 S:     Maintained
 
+F71805F HARDWARE MONITORING DRIVER
+P:     Jean Delvare
+M:     khali@linux-fr.org
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+
 FARSYNC SYNCHRONOUS DRIVER
 P:     Kevin Curtis
 M:     kevin.curtis@farsite.co.uk
@@ -2956,7 +2964,8 @@ S:      Maintained
 
 VIDEO FOR LINUX
 P:     Mauro Carvalho Chehab
-M:     mchehab@brturbo.com.br
+M:     mchehab@infradead.org
+M:     v4l-dvb-maintainer@linuxtv.org
 L:     video4linux-list@redhat.com
 W:     http://linuxtv.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
index 4b87352..02c2db0 100644 (file)
@@ -73,9 +73,6 @@ cpumask_t cpu_online_map;
 
 EXPORT_SYMBOL(cpu_online_map);
 
-/* cpus reported in the hwrpb */
-static unsigned long hwrpb_cpu_present_mask __initdata = 0;
-
 int smp_num_probed;            /* Internal processor count */
 int smp_num_cpus = 1;          /* Number that came online.  */
 
@@ -442,7 +439,7 @@ setup_smp(void)
                        if ((cpu->flags & 0x1cc) == 0x1cc) {
                                smp_num_probed++;
                                /* Assume here that "whami" == index */
-                               hwrpb_cpu_present_mask |= (1UL << i);
+                               cpu_set(i, cpu_possible_map);
                                cpu->pal_revision = boot_cpu_palrev;
                        }
 
@@ -453,12 +450,12 @@ setup_smp(void)
                }
        } else {
                smp_num_probed = 1;
-               hwrpb_cpu_present_mask = (1UL << boot_cpuid);
+               cpu_set(boot_cpuid, cpu_possible_map);
        }
        cpu_present_mask = cpumask_of_cpu(boot_cpuid);
 
        printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
-              smp_num_probed, hwrpb_cpu_present_mask);
+              smp_num_probed, cpu_possible_map.bits[0]);
 }
 
 /*
@@ -467,8 +464,6 @@ setup_smp(void)
 void __init
 smp_prepare_cpus(unsigned int max_cpus)
 {
-       int cpu_count, i;
-
        /* Take care of some initial bookkeeping.  */
        memset(ipi_data, 0, sizeof(ipi_data));
 
@@ -486,19 +481,7 @@ smp_prepare_cpus(unsigned int max_cpus)
 
        printk(KERN_INFO "SMP starting up secondaries.\n");
 
-       cpu_count = 1;
-       for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) {
-               if (i == boot_cpuid)
-                       continue;
-
-               if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
-                       continue;
-
-               cpu_set(i, cpu_possible_map);
-               cpu_count++;
-       }
-
-       smp_num_cpus = cpu_count;
+       smp_num_cpus = smp_num_probed;
 }
 
 void __devinit
index 5959e36..15dc1a0 100644 (file)
@@ -10,9 +10,9 @@ config ARM
        default y
        help
          The ARM series is a line of low-power-consumption RISC chip designs
-         licensed by ARM ltd and targeted at embedded applications and
+         licensed by ARM Ltd and targeted at embedded applications and
          handhelds such as the Compaq IPAQ.  ARM-based PCs are no longer
-         manufactured, but  legacy ARM-based PC hardware remains popular in
+         manufactured, but legacy ARM-based PC hardware remains popular in
          Europe.  There is an ARM Linux project with a web page at
          <http://www.arm.linux.org.uk/>.
 
@@ -69,6 +69,9 @@ config GENERIC_ISA_DMA
 config FIQ
        bool
 
+config ARCH_MTD_XIP
+       bool
+
 source "init/Kconfig"
 
 menu "System Type"
@@ -81,45 +84,62 @@ config ARCH_CLPS7500
        bool "Cirrus-CL-PS7500FE"
        select TIMER_ACORN
        select ISA
+       help
+         Support for the Cirrus Logic PS7500FE system-on-a-chip.
 
 config ARCH_CLPS711X
        bool "CLPS711x/EP721x-based"
+       help
+         Support for Cirrus Logic 711x/721x based boards.
 
 config ARCH_CO285
        bool "Co-EBSA285"
        select FOOTBRIDGE
        select FOOTBRIDGE_ADDIN
+       help
+         Support for Intel's EBSA285 companion chip.
 
 config ARCH_EBSA110
        bool "EBSA-110"
        select ISA
        help
          This is an evaluation board for the StrongARM processor available
-         from Digital. It has limited hardware on-board, including an onboard
+         from Digital. It has limited hardware on-board, including an
          Ethernet interface, two PCMCIA sockets, two serial ports and a
          parallel port.
 
 config ARCH_FOOTBRIDGE
        bool "FootBridge"
        select FOOTBRIDGE
+       help
+         Support for systems based on the DC21285 companion chip
+         ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
 config ARCH_INTEGRATOR
        bool "Integrator"
        select ARM_AMBA
        select ICST525
+       help
+         Support for ARM's Integrator platform.
 
 config ARCH_IOP3XX
        bool "IOP3xx-based"
        select PCI
+       help
+         Support for Intel's IOP3XX (XScale) family of processors.
 
 config ARCH_IXP4XX
        bool "IXP4xx-based"
        select DMABOUNCE
        select PCI
+       help
+         Support for Intel's IXP4XX (XScale) family of processors.
 
 config ARCH_IXP2000
        bool "IXP2400/2800-based"
        select PCI
+       help
+         Support for Intel's IXP2400/2800 (XScale) family of processors.
 
 config ARCH_L7200
        bool "LinkUp-L7200"
@@ -136,6 +156,9 @@ config ARCH_L7200
 
 config ARCH_PXA
        bool "PXA2xx-based"
+       select ARCH_MTD_XIP
+       help
+         Support for Intel's PXA2XX processor line.
 
 config ARCH_RPC
        bool "RiscPC"
@@ -152,19 +175,25 @@ config ARCH_SA1100
        bool "SA1100-based"
        select ISA
        select ARCH_DISCONTIGMEM_ENABLE
+       select ARCH_MTD_XIP
+       help
+         Support for StrongARM 11x0 based boards.
 
 config ARCH_S3C2410
        bool "Samsung S3C2410"
        help
          Samsung S3C2410X CPU based systems, such as the Simtec Electronics
          BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
-         the Samsung SMDK2410 development board (and derviatives).
+         the Samsung SMDK2410 development board (and derivatives).
 
 config ARCH_SHARK
        bool "Shark"
        select ISA
        select ISA_DMA
        select PCI
+       help
+         Support for the StrongARM based Digital DNARD machine, also known
+         as "Shark" (<http://www.shark-linux.de/shark.html>).
 
 config ARCH_LH7A40X
        bool "Sharp LH7A40X"
@@ -176,6 +205,8 @@ config ARCH_LH7A40X
 
 config ARCH_OMAP
        bool "TI OMAP"
+       help
+         Support for TI's OMAP platform (OMAP1 and OMAP2).
 
 config ARCH_VERSATILE
        bool "Versatile"
@@ -194,6 +225,8 @@ config ARCH_REALVIEW
 
 config ARCH_IMX
        bool "IMX"
+       help
+         Support for Motorola's i.MX family of processors (MX1, MXL).
 
 config ARCH_H720X
        bool "Hynix-HMS720x-based"
@@ -210,8 +243,8 @@ config ARCH_AAEC2000
 config ARCH_AT91RM9200
        bool "AT91RM9200"
        help
-         Say Y here if you intend to run this kernel on an AT91RM9200-based
-         board.
+         Say Y here if you intend to run this kernel on an Atmel
+         AT91RM9200-based board.
 
 endchoice
 
@@ -417,8 +450,8 @@ config AEABI
          To use this you need GCC version 4.0.0 or later.
 
 config OABI_COMPAT
-       bool "Allow old ABI binaries to run with this kernel"
-       depends on AEABI
+       bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
+       depends on AEABI && EXPERIMENTAL
        default y
        help
          This option preserves the old syscall interface along with the
index 9592e39..5fdaf3c 100644 (file)
@@ -171,7 +171,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index d9d6bb8..c67fc44 100644 (file)
@@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index 2dc9d49..60d66e8 100644 (file)
@@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index ea8f4b4..f54f3dc 100644 (file)
@@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware ixdp2x01_clock=50000000"
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0"
 # CONFIG_XIP_KERNEL is not set
 
 #
index 1964ccd..6695b07 100644 (file)
@@ -1,11 +1,10 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Sun Nov 13 17:41:24 2005
+# Linux kernel version: 2.6.16-rc2
+# Mon Feb  6 11:17:23 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
-CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 
@@ -28,27 +27,31 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_UID16=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
+CONFIG_ELF_CORE=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+CONFIG_OBSOLETE_INTERMODULE=y
 
 #
 # Loadable module support
@@ -102,6 +105,7 @@ CONFIG_ARCH_S3C2410=y
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_AT91RM9200 is not set
 
 #
 # S3C24XX Implementations
@@ -160,7 +164,6 @@ CONFIG_CPU_TLB_V4WBI=y
 # Bus support
 #
 CONFIG_ISA=y
-CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -172,6 +175,7 @@ CONFIG_ISA_DMA_API=y
 #
 # CONFIG_PREEMPT is not set
 # CONFIG_NO_IDLE_HZ is not set
+# CONFIG_AEABI is not set
 # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_FLATMEM_MANUAL=y
@@ -214,6 +218,8 @@ CONFIG_BINFMT_AOUT=y
 # Power management options
 #
 CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
 CONFIG_APM=y
 
 #
@@ -259,6 +265,11 @@ CONFIG_TCP_CONG_BIC=y
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_VLAN_8021Q is not set
@@ -276,7 +287,6 @@ CONFIG_TCP_CONG_BIC=y
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -299,6 +309,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_DEBUG_DRIVER is not set
 
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
 #
 # Memory Technology Devices (MTD)
 #
@@ -412,8 +427,6 @@ CONFIG_PARPORT_1284=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -502,7 +515,6 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_SMC91X is not set
 CONFIG_DM9000=y
@@ -607,11 +619,11 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
 # CONFIG_DIGIEPCA is not set
-# CONFIG_ESPSERIAL is not set
 # CONFIG_MOXA_INTELLIO is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
+# CONFIG_SYNCLINK_GT is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
@@ -625,6 +637,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -687,6 +700,7 @@ CONFIG_S3C2410_RTC=y
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
@@ -730,6 +744,12 @@ CONFIG_SENSORS_EEPROM=m
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
 #
 # Hardware Monitoring support
 #
@@ -863,6 +883,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
 CONFIG_ROMFS_FS=y
 CONFIG_INOTIFY=y
@@ -897,6 +918,7 @@ CONFIG_SYSFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 # CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -965,6 +987,7 @@ CONFIG_SOLARIS_X86_PARTITION=y
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
 
 #
@@ -1020,12 +1043,13 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1034,6 +1058,7 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_WAITQ is not set
index d058e7c..8c3035d 100644 (file)
                CALL(sys_mq_getsetattr)
 /* 280 */      CALL(sys_waitid)
                CALL(sys_socket)
-               CALL(sys_bind)
-               CALL(sys_connect)
+               CALL(ABI(sys_bind, sys_oabi_bind))
+               CALL(ABI(sys_connect, sys_oabi_connect))
                CALL(sys_listen)
 /* 285 */      CALL(sys_accept)
                CALL(sys_getsockname)
                CALL(sys_getpeername)
                CALL(sys_socketpair)
                CALL(sys_send)
-/* 290 */      CALL(sys_sendto)
+/* 290 */      CALL(ABI(sys_sendto, sys_oabi_sendto))
                CALL(sys_recv)
                CALL(sys_recvfrom)
                CALL(sys_shutdown)
                CALL(sys_setsockopt)
 /* 295 */      CALL(sys_getsockopt)
-               CALL(sys_sendmsg)
+               CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
                CALL(sys_recvmsg)
                CALL(ABI(sys_semop, sys_oabi_semop))
                CALL(sys_semget)
index d401d90..964cd71 100644 (file)
@@ -333,9 +333,13 @@ __pabt_svc:
                                        @ from the exception stack
 
 #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#ifndef CONFIG_MMU
+#warning "NPTL on non MMU needs fixing"
+#else
        @ make sure our user space atomic helper is aborted
        cmp     r2, #TASK_SIZE
        bichs   r3, r3, #PSR_Z_BIT
+#endif
 #endif
 
        @
@@ -705,7 +709,12 @@ __kuser_memory_barrier:                            @ 0xffff0fa0
  * The C flag is also set if *ptr was changed to allow for assembly
  * optimization in the calling code.
  *
- * Note: this routine already includes memory barriers as needed.
+ * Notes:
+ *
+ *    - This routine already includes memory barriers as needed.
+ *
+ *    - A failure might be transient, i.e. it is possible, although unlikely,
+ *      that "failure" be returned even if *ptr == oldval.
  *
  * For example, a user space atomic_add implementation could look like this:
  *
@@ -756,12 +765,18 @@ __kuser_cmpxchg:                          @ 0xffff0fc0
         * exception happening just after the str instruction which would
         * clear the Z flag although the exchange was done.
         */
+#ifdef CONFIG_MMU
        teq     ip, ip                  @ set Z flag
        ldr     ip, [r2]                @ load current val
        add     r3, r2, #1              @ prepare store ptr
        teqeq   ip, r0                  @ compare with oldval if still allowed
        streq   r1, [r3, #-1]!          @ store newval if still allowed
        subs    r0, r2, r3              @ if r2 == r3 the str occured
+#else
+#warning "NPTL on non MMU needs fixing"
+       mov     r0, #-1
+       adds    r0, r0, #0
+#endif
        mov     pc, lr
 
 #else
index eafa8e5..9d4b764 100644 (file)
  *   struct sembuf loses its padding with EABI.  Since arrays of them are
  *   used they have to be copyed to remove the padding. Compatibility wrappers
  *   provided below.
+ *
+ * sys_bind:
+ * sys_connect:
+ * sys_sendmsg:
+ * sys_sendto:
+ *
+ *   struct sockaddr_un loses its padding with EABI.  Since the size of the
+ *   structure is used as a validation test in unix_mkname(), we need to
+ *   change the length argument to 110 whenever it is 112.  Compatibility
+ *   wrappers provided below.
  */
 
 #include <linux/syscalls.h>
@@ -67,6 +77,7 @@
 #include <linux/fcntl.h>
 #include <linux/eventpoll.h>
 #include <linux/sem.h>
+#include <linux/socket.h>
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
 
@@ -337,3 +348,63 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
                return sys_ipc(call, first, second, third, ptr, fifth);
        }
 }
+
+asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen)
+{
+       sa_family_t sa_family;
+       if (addrlen == 112 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+                       addrlen = 110;
+       return sys_bind(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen)
+{
+       sa_family_t sa_family;
+       if (addrlen == 112 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+                       addrlen = 110;
+       return sys_connect(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
+                               size_t len, unsigned flags,
+                               struct sockaddr __user *addr,
+                               int addrlen)
+{
+       sa_family_t sa_family;
+       if (addrlen == 112 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+                       addrlen = 110;
+       return sys_sendto(fd, buff, len, flags, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+{
+       struct sockaddr __user *addr;
+       int msg_namelen;
+       sa_family_t sa_family;
+       if (msg &&
+           get_user(msg_namelen, &msg->msg_namelen) == 0 &&
+           msg_namelen == 112 &&
+           get_user(addr, &msg->msg_name) == 0 &&
+           get_user(sa_family, &addr->sa_family) == 0 &&
+           sa_family == AF_UNIX)
+       {
+               /*
+                * HACK ALERT: there is a limit to how much backward bending
+                * we should do for what is actually a transitional
+                * compatibility layer.  This already has known flaws with
+                * a few ioctls that we don't intend to fix.  Therefore
+                * consider this blatent hack as another one... and take care
+                * to run for cover.  In most cases it will "just work fine".
+                * If it doesn't, well, tough.
+                */
+               put_user(110, &msg->msg_namelen);
+       }
+       return sys_sendmsg(fd, msg, flags);
+}
+
index 0793dcf..0e2b641 100644 (file)
@@ -24,6 +24,8 @@ config ARCH_CEIVA
 
 config ARCH_CLEP7312
        bool "CLEP7312"
+       help
+         Boards based on the Cirrus Logic 7212/7312 chips.
 
 config ARCH_EDB7211
        bool "EDB7211"
index dc31e3f..8ab1b04 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/mach/arch.h>
 #include <linux/interrupt.h>
 #include "generic.h"
-#include <asm/serial.h>
 
 static struct resource cs89x0_resources[] = {
        [0] = {
index 9e5a13b..52fac89 100644 (file)
@@ -106,6 +106,7 @@ static void __init enp2611_pci_preinit(void)
 {
        ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
        ixp2000_pci_preinit();
+       pcibios_setup("firmware");
 }
 
 static inline int enp2611_pci_valid_device(struct pci_bus *bus,
index 7c78240..0910127 100644 (file)
@@ -68,6 +68,7 @@ void __init ixdp2400_pci_preinit(void)
 {
        ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
        ixp2000_pci_preinit();
+       pcibios_setup("firmware");
 }
 
 int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys)
index 10f0660..150519f 100644 (file)
@@ -212,6 +212,7 @@ void __init ixdp2x01_pci_preinit(void)
 {
        ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000);
        ixp2000_pci_preinit();
+       pcibios_setup("firmware");
 }
 
 #define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
@@ -299,7 +300,9 @@ struct hw_pci ixdp2x01_pci __initdata = {
 
 int __init ixdp2x01_pci_init(void)
 {
-       pci_common_init(&ixdp2x01_pci);
+       if (machine_is_ixdp2401() || machine_is_ixdp2801())
+               pci_common_init(&ixdp2x01_pci);
+
        return 0;
 }
 
index bdc20b5..a177e78 100644 (file)
@@ -30,6 +30,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
 }
 
@@ -104,7 +105,7 @@ static void __init omap_generic_init(void)
 
 static void __init omap_generic_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
index 9533c36..89f0cc7 100644 (file)
@@ -128,6 +128,7 @@ static void __init h2_init_smc91x(void)
 
 static void __init h2_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        h2_init_smc91x();
@@ -194,7 +195,7 @@ static void __init h2_init(void)
 
 static void __init h2_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_H2, "TI-H2")
index d665efc..d9f3862 100644 (file)
@@ -203,6 +203,7 @@ static void __init h3_init_smc91x(void)
 
 void h3_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        h3_init_smc91x();
@@ -210,7 +211,7 @@ void h3_init_irq(void)
 
 static void __init h3_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
index 652f37c..a04e433 100644 (file)
@@ -181,6 +181,7 @@ static void __init innovator_init_smc91x(void)
 
 void innovator_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
 #ifdef CONFIG_ARCH_OMAP15XX
@@ -285,7 +286,7 @@ static void __init innovator_init(void)
 
 static void __init innovator_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 
 #ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap1510()) {
index 58f7839..60d5f8a 100644 (file)
@@ -65,6 +65,7 @@ static struct omap_board_config_kernel netstar_config[] = {
 
 static void __init netstar_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
 }
@@ -108,7 +109,7 @@ static void __init netstar_init(void)
 
 static void __init netstar_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 #define MACHINE_PANICED                1
index e5d126e..543fa13 100644 (file)
@@ -169,6 +169,7 @@ static void __init osk_init_cf(void)
 
 static void __init osk_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        osk_init_smc91x();
@@ -269,7 +270,7 @@ static void __init osk_init(void)
 
 static void __init osk_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_OSK, "TI-OSK")
index 67fada2..e488f72 100644 (file)
@@ -34,6 +34,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
 }
 
@@ -72,7 +73,7 @@ static void __init omap_generic_init(void)
 
 static void __init omap_generic_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
index 88708a0..3913a3c 100644 (file)
@@ -144,6 +144,7 @@ static void __init perseus2_init_smc91x(void)
 
 void omap_perseus2_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        perseus2_init_smc91x();
@@ -160,7 +161,7 @@ static struct map_desc omap_perseus2_io_desc[] __initdata = {
 
 static void __init omap_perseus2_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
        iotable_init(omap_perseus2_io_desc,
                     ARRAY_SIZE(omap_perseus2_io_desc));
 
index 959b4b8..bfd5fdd 100644 (file)
@@ -162,6 +162,7 @@ static struct omap_board_config_kernel voiceblue_config[] = {
 
 static void __init voiceblue_init_irq(void)
 {
+       omap1_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
 }
@@ -206,7 +207,7 @@ static void __init voiceblue_init(void)
 
 static void __init voiceblue_map_io(void)
 {
-       omap_map_common_io();
+       omap1_map_common_io();
 }
 
 #define MACHINE_PANICED                1
index a7a19f7..82d556b 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
+#include <asm/tlb.h>
 #include <asm/mach/map.h>
 #include <asm/io.h>
 #include <asm/arch/mux.h>
@@ -83,15 +84,24 @@ static struct map_desc omap16xx_io_desc[] __initdata = {
 };
 #endif
 
-static int initialized = 0;
-
-static void __init _omap_map_io(void)
+/*
+ * Maps common IO regions for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_map_common_io(void)
 {
-       initialized = 1;
-
-       /* We have to initialize the IO space mapping before we can run
-        * cpu_is_omapxxx() macros. */
        iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+
+       /* Normally devicemaps_init() would flush caches and tlb after
+        * mdesc->map_io(), but we must also do it here because of the CPU
+        * revision check below.
+        */
+       local_flush_tlb_all();
+       flush_cache_all();
+
+       /* We want to check CPU revision early for cpu_is_omapxxxx() macros.
+        * IO space mapping must be initialized before we can do that.
+        */
        omap_check_revision();
 
 #ifdef CONFIG_ARCH_OMAP730
@@ -111,7 +121,14 @@ static void __init _omap_map_io(void)
 #endif
 
        omap_sram_init();
+}
 
+/*
+ * Common low-level hardware init for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_init_common_hw()
+{
        /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
         * on a Posted Write in the TIPB Bridge".
         */
@@ -121,16 +138,7 @@ static void __init _omap_map_io(void)
        /* Must init clocks early to assure that timer interrupt works
         */
        omap1_clk_init();
-}
 
-/*
- * This should only get called from board specific init
- */
-void __init omap_map_common_io(void)
-{
-       if (!initialized) {
-               _omap_map_io();
-               omap1_mux_init();
-       }
+       omap1_mux_init();
 }
 
index b937123..eaecbf4 100644 (file)
@@ -33,6 +33,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
+       omap2_init_common_hw();
        omap_init_irq();
 }
 
@@ -64,7 +65,7 @@ static void __init omap_generic_init(void)
 
 static void __init omap_generic_map_io(void)
 {
-       omap_map_common_io();
+       omap2_map_common_io();
 }
 
 MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
index c3c35d4..a300d63 100644 (file)
@@ -136,6 +136,7 @@ static inline void __init h4_init_smc91x(void)
 
 static void __init omap_h4_init_irq(void)
 {
+       omap2_init_common_hw();
        omap_init_irq();
        omap_gpio_init();
        h4_init_smc91x();
@@ -181,7 +182,7 @@ static void __init omap_h4_init(void)
 
 static void __init omap_h4_map_io(void)
 {
-       omap_map_common_io();
+       omap2_map_common_io();
 }
 
 MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
index 4a222f5..4303d98 100644 (file)
@@ -182,7 +182,7 @@ static const struct icst307_params realview_oscvco_params = {
 static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
 {
        void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
-       void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET;
+       void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET;
        u32 val;
 
        val = readl(sys_osc) & ~0x7ffff;
index af2f3d5..08489ef 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/mutex.h>
 
 #include <asm/hardware.h>
-#include <asm/atomic.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
@@ -59,22 +58,18 @@ static DEFINE_MUTEX(clocks_mutex);
 void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
 {
        unsigned long clkcon;
-       unsigned long flags;
-
-       local_irq_save(flags);
 
        clkcon = __raw_readl(S3C2410_CLKCON);
-       clkcon &= ~clocks;
 
        if (enable)
                clkcon |= clocks;
+       else
+               clkcon &= ~clocks;
 
        /* ensure none of the special function bits set */
        clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
 
        __raw_writel(clkcon, S3C2410_CLKCON);
-
-       local_irq_restore(flags);
 }
 
 /* enable and disable calls for use with the clk struct */
@@ -138,16 +133,32 @@ void clk_put(struct clk *clk)
 
 int clk_enable(struct clk *clk)
 {
-       if (IS_ERR(clk))
+       if (IS_ERR(clk) || clk == NULL)
                return -EINVAL;
 
-       return (clk->enable)(clk, 1);
+       clk_enable(clk->parent);
+
+       mutex_lock(&clocks_mutex);
+
+       if ((clk->usage++) == 0)
+               (clk->enable)(clk, 1);
+
+       mutex_unlock(&clocks_mutex);
+       return 0;
 }
 
 void clk_disable(struct clk *clk)
 {
-       if (!IS_ERR(clk))
+       if (IS_ERR(clk) || clk == NULL)
+               return;
+
+       mutex_lock(&clocks_mutex);
+
+       if ((--clk->usage) == 0)
                (clk->enable)(clk, 0);
+
+       mutex_unlock(&clocks_mutex);
+       clk_disable(clk->parent);
 }
 
 
@@ -361,6 +372,14 @@ int s3c24xx_register_clock(struct clk *clk)
        if (clk->enable == NULL)
                clk->enable = clk_null_enable;
 
+       /* if this is a standard clock, set the usage state */
+
+       if (clk->ctrlbit) {
+               unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
+
+               clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0;
+       }
+
        /* add to the list of available clocks */
 
        mutex_lock(&clocks_mutex);
@@ -402,6 +421,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
         * the LCD clock if it is not needed.
        */
 
+       mutex_lock(&clocks_mutex);
+
        s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
        s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
        s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
@@ -409,6 +430,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
        s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
        s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
 
+       mutex_unlock(&clocks_mutex);
+
        /* assume uart clocks are correctly setup */
 
        /* register our clocks */
index 177d5c8..eb5c95d 100644 (file)
@@ -16,6 +16,7 @@ struct clk {
        struct clk           *parent;
        const char           *name;
        int                   id;
+       int                   usage;
        unsigned long         rate;
        unsigned long         ctrlbit;
        int                 (*enable)(struct clk *, int enable);
index b8d994a..0a47d38 100644 (file)
@@ -275,6 +275,11 @@ static struct resource s3c_adc_resource[] = {
        },
        [1] = {
                .start = IRQ_TC,
+               .end   = IRQ_TC,
+               .flags = IORESOURCE_IRQ,
+       },
+       [2] = {
+               .start = IRQ_ADC,
                .end   = IRQ_ADC,
                .flags = IORESOURCE_IRQ,
        }
index 792f663..ee82763 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 
 #include <asm/mach/map.h>
+#include <asm/tlb.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
@@ -95,6 +96,14 @@ void __init omap_map_sram(void)
               omap_sram_io_desc[0].pfn, omap_sram_io_desc[0].virtual,
               omap_sram_io_desc[0].length);
 
+       /*
+        * Normally devicemaps_init() would flush caches and tlb after
+        * mdesc->map_io(), but since we're called from map_io(), we
+        * must do it here.
+        */
+       local_flush_tlb_all();
+       flush_cache_all();
+
        /*
         * Looks like we need to preserve some bootloader code at the
         * beginning of SRAM for jumping to flash for reboot to work...
index f214f74..961c0d5 100644 (file)
@@ -202,18 +202,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        int i;
                        unsigned long tmp;
                        
+                       ret = 0;
                        for (i = 0; i <= PT_MAX; i++) {
                                tmp = get_reg(child, i);
                                
                                if (put_user(tmp, datap)) {
                                        ret = -EFAULT;
-                                       goto out_tsk;
+                                       break;
                                }
                                
                                data += sizeof(long);
                        }
 
-                       ret = 0;
                        break;
                }
 
@@ -222,10 +222,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        int i;
                        unsigned long tmp;
                        
+                       ret = 0;
                        for (i = 0; i <= PT_MAX; i++) {
                                if (get_user(tmp, datap)) {
                                        ret = -EFAULT;
-                                       goto out_tsk;
+                                       break;
                                }
                                
                                if (i == PT_DCCR) {
@@ -237,7 +238,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                                data += sizeof(long);
                        }
                        
-                       ret = 0;
                        break;
                }
 
index d11206e..1ba57ef 100644 (file)
@@ -24,7 +24,6 @@
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
 struct screen_info screen_info;
 
 extern int root_mountflags;
index 1b66592..5a8b3fb 100644 (file)
@@ -309,3 +309,4 @@ ENTRY(sys_call_table)
        .long sys_faccessat
        .long sys_pselect6
        .long sys_ppoll
+       .long sys_unshare               /* 310 */
index d58003f..c9104bf 100644 (file)
 #include <asm/machvec.h>
 #include <asm/system.h>
 
-/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present.  In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator.  Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-char drive_info[4*16];
-
 void __init
 dig_setup (char **cmdline_p)
 {
index 6ea5b8a..48645ac 100644 (file)
@@ -125,20 +125,6 @@ struct screen_info sn_screen_info = {
        .orig_video_points = 16
 };
 
-/*
- * This is here so we can use the CMOS detection in ide-probe.c to
- * determine what drives are present.  In theory, we don't need this
- * as the auto-detection could be done via ide-probe.c:do_probe() but
- * in practice that would be much slower, which is painful when
- * running in the simulator.  Note that passing zeroes in DRIVE_INFO
- * is sufficient (the IDE driver will autodetect the drive geometry).
- */
-#ifdef CONFIG_IA64_GENERIC
-extern char drive_info[4 * 16];
-#else
-char drive_info[4 * 16];
-#endif
-
 /*
  * This routine can only be used during init, since
  * smp_boot_data is an init data structure.
index dbc8a39..be8b711 100644 (file)
 #include <asm/irq.h>
 #include <asm/tlbflush.h>
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
 EXPORT_SYMBOL(dump_fpu);
index c2e4dcc..d742037 100644 (file)
 extern void init_mmu(void);
 #endif
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)  \
-       || defined(CONFIG_BLK_DEV_IDE_MODULE)                   \
-       || defined(CONFIG_BLK_DEV_HD_MODULE)
-struct drive_info_struct { char dummy[32]; } drive_info;
-#endif
-
 extern char _end[];
 
 /*
index 99bf438..63c117d 100644 (file)
 
 asmlinkage void ret_from_fork(void);
 
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+EXPORT_SYMBOL(pm_idle);
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
 /*
  * The idle loop on an m68knommu..
index 050685b..b9713a7 100644 (file)
@@ -140,7 +140,7 @@ void __init plat_setup(void)
                uart.type       = PORT_UNKNOWN;
                uart.uartclk    = 18432000;
                uart.irq        = COBALT_SERIAL_IRQ;
-               uart.flags      = STD_COM_FLAGS;
+               uart.flags      = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
                uart.iobase     = 0xc800000;
                uart.iotype     = UPIO_PORT;
 
index fa98f10..5232fc7 100644 (file)
@@ -4,6 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others.
+ * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  * Copyright (C) 2004 Thiemo Seufer
  */
@@ -58,8 +59,8 @@ ATTRIB_NORET void cpu_idle(void)
        }
 }
 
-extern int do_signal(sigset_t *oldset, struct pt_regs *regs);
-extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+extern void do_signal(struct pt_regs *regs);
+extern void do_signal32(struct pt_regs *regs);
 
 /*
  * Native o32 and N64 ABI without DSP ASE
index a42e0e8..d7c4a38 100644 (file)
@@ -617,6 +617,23 @@ einval:    li      v0, -EINVAL
        sys     sys_inotify_init        0
        sys     sys_inotify_add_watch   3       /* 4285 */
        sys     sys_inotify_rm_watch    2
+       sys     sys_migrate_pages       4
+       sys     sys_openat              4
+       sys     sys_mkdirat             3
+       sys     sys_mknodat             4       /* 4290 */
+       sys     sys_fchownat            5
+       sys     sys_futimesat           3
+       sys     sys_newfstatat          4
+       sys     sys_unlinkat            3
+       sys     sys_renameat            4       /* 4295 */
+       sys     sys_linkat              4
+       sys     sys_symlinkat           3
+       sys     sys_readlinkat          4
+       sys     sys_fchmodat            3
+       sys     sys_faccessat           3       /* 4300 */
+       sys     sys_pselect6            6
+       sys     sys_ppoll               5
+       sys     sys_unshare             1
        .endm
 
        /* We pre-compute the number of _instruction_ bytes needed to
index 47bfbd4..98bf25d 100644 (file)
@@ -443,3 +443,20 @@ sys_call_table:
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch
        PTR     sys_inotify_rm_watch            /* 5245 */
+       PTR     sys_migrate_pages
+       PTR     sys_openat
+       PTR     sys_mkdirat
+       PTR     sys_mknodat
+       PTR     sys_fchownat                    /* 5250 */
+       PTR     sys_futimesat
+       PTR     sys_newfstatat
+       PTR     sys_unlinkat
+       PTR     sys_renameat
+       PTR     sys_linkat                      /* 5255 */
+       PTR     sys_symlinkat
+       PTR     sys_readlinkat
+       PTR     sys_fchmodat
+       PTR     sys_faccessat
+       PTR     sys_pselect6                    /* 5260 */
+       PTR     sys_ppoll
+       PTR     sys_unshare
index b465ced..bc4980c 100644 (file)
@@ -369,3 +369,20 @@ EXPORT(sysn32_call_table)
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch
        PTR     sys_inotify_rm_watch
+       PTR     sys_migrate_pages               /* 6250 */
+       PTR     sys_openat
+       PTR     sys_mkdirat
+       PTR     sys_mknodat
+       PTR     sys_fchownat
+       PTR     sys_futimesat                   /* 6255 */
+       PTR     sys_newfstatat
+       PTR     sys_unlinkat
+       PTR     sys_renameat
+       PTR     sys_linkat
+       PTR     sys_symlinkat                   /* 6260 */
+       PTR     sys_readlinkat
+       PTR     sys_fchmodat
+       PTR     sys_faccessat
+       PTR     sys_pselect6
+       PTR     sys_ppoll                       /* 6265 */
+       PTR     sys_unshare
index 3d338ca..5b04140 100644 (file)
@@ -491,4 +491,21 @@ sys_call_table:
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch           /* 4285 */
        PTR     sys_inotify_rm_watch
+       PTR     sys_migrate_pages
+       PTR     compat_sys_openat
+       PTR     sys_mkdirat
+       PTR     sys_mknodat                     /* 4290 */
+       PTR     sys_fchownat
+       PTR     compat_sys_futimesat
+       PTR     compat_sys_newfstatat
+       PTR     sys_unlinkat
+       PTR     sys_renameat                    /* 4295 */
+       PTR     sys_linkat
+       PTR     sys_symlinkat
+       PTR     sys_readlinkat
+       PTR     sys_fchmodat
+       PTR     sys_faccessat                   /* 4300 */
+       PTR     sys_pselect6
+       PTR     sys_ppoll
+       PTR     sys_unshare
        .size   sys_call_table,.-sys_call_table
index aaec478..c974cc9 100644 (file)
@@ -39,8 +39,6 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs);
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -50,7 +48,7 @@ save_static_function(sys_sigsuspend);
 __attribute_used__ noinline static int
 _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-       sigset_t saveset, newset;
+       sigset_t newset;
        sigset_t __user *uset;
 
        uset = (sigset_t __user *) regs.regs[4];
@@ -59,19 +57,15 @@ _sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
        spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
+       current->saved_sigmask = current->blocked;
        current->blocked = newset;
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       regs.regs[2] = EINTR;
-       regs.regs[7] = 1;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&saveset, &regs))
-                       return -EINTR;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
 }
 #endif
 
@@ -79,7 +73,7 @@ save_static_function(sys_rt_sigsuspend);
 __attribute_used__ noinline static int
 _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 {
-       sigset_t saveset, newset;
+       sigset_t newset;
        sigset_t __user *unewset;
        size_t sigsetsize;
 
@@ -94,19 +88,15 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
        sigdelsetmask(&newset, ~_BLOCKABLE);
 
        spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
+       current->saved_sigmask = current->blocked;
        current->blocked = newset;
         recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       regs.regs[2] = EINTR;
-       regs.regs[7] = 1;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&saveset, &regs))
-                       return -EINTR;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_thread_flag(TIF_RESTORE_SIGMASK);
+       return -ERESTARTNOHAND;
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
@@ -315,11 +305,11 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, frame->regs[31]);
 #endif
-        return 1;
+        return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 #endif
 
@@ -375,11 +365,11 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 
 static inline int handle_signal(unsigned long sig, siginfo_t *info,
@@ -393,7 +383,7 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
                regs->regs[2] = EINTR;
                break;
        case ERESTARTSYS:
-               if(!(ka->sa.sa_flags & SA_RESTART)) {
+               if (!(ka->sa.sa_flags & SA_RESTART)) {
                        regs->regs[2] = EINTR;
                        break;
                }
@@ -420,9 +410,10 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
        return ret;
 }
 
-int do_signal(sigset_t *oldset, struct pt_regs *regs)
+void do_signal(struct pt_regs *regs)
 {
        struct k_sigaction ka;
+       sigset_t *oldset;
        siginfo_t info;
        int signr;
 
@@ -432,17 +423,31 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
         * if so.
         */
        if (!user_mode(regs))
-               return 1;
+               return;
 
        if (try_to_freeze())
                goto no_signal;
 
-       if (!oldset)
+       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+               oldset = &current->saved_sigmask;
+       else
                oldset = &current->blocked;
 
+
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0)
-               return handle_signal(signr, &info, &ka, oldset, regs);
+       if (signr > 0) {
+               /* Whee!  Actually deliver the signal.  */
+               if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+                       /*
+                        * A signal was successfully delivered; the saved
+                        * sigmask will have been stored in the signal frame,
+                        * and will be restored by sigreturn, so we can simply
+                        * clear the TIF_RESTORE_SIGMASK flag.
+                        */
+                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               }
+       }
 
 no_signal:
        /*
@@ -463,18 +468,25 @@ no_signal:
                        regs->cp0_epc -= 4;
                }
        }
-       return 0;
+
+       /*
+        * If there's no signal to deliver, we just put the saved sigmask
+        * back
+        */
+       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+       }
 }
 
 /*
  * notification of userspace execution resumption
- * - triggered by current->work.notify_resume
+ * - triggered by the TIF_WORK_MASK flags
  */
-asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset,
+asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
        __u32 thread_info_flags)
 {
        /* deal with pending signal delivery */
-       if (thread_info_flags & _TIF_SIGPENDING) {
-               current->thread.abi->do_signal(oldset, regs);
-       }
+       if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+               current->thread.abi->do_signal(regs);
 }
index 136260c..da3271e 100644 (file)
@@ -694,11 +694,11 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, frame->sf_code);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 
 int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
@@ -765,11 +765,11 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
               current->comm, current->pid,
               frame, regs->cp0_epc, frame->rs_code);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
 
 static inline int handle_signal(unsigned long sig, siginfo_t *info,
index 9156863..384fc4a 100644 (file)
@@ -186,9 +186,9 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 #endif
-       return 1;
+       return 0;
 
 give_sigsegv:
        force_sigsegv(signr, current);
-       return 0;
+       return -EFAULT;
 }
index 3323584..1da2eeb 100644 (file)
@@ -212,12 +212,12 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
        int error;
        char * filename;
 
-       filename = getname((char *) (long)regs.regs[4]);
+       filename = getname((char __user *) (long)regs.regs[4]);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, (char **) (long)regs.regs[5],
-                         (char **) (long)regs.regs[6], &regs);
+       error = do_execve(filename, (char __user *__user *) (long)regs.regs[5],
+                         (char __user *__user *) (long)regs.regs[6], &regs);
        putname(filename);
 
 out:
@@ -227,7 +227,7 @@ out:
 /*
  * Compacrapability ...
  */
-asmlinkage int sys_uname(struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname __user * name)
 {
        if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
                return 0;
@@ -237,7 +237,7 @@ asmlinkage int sys_uname(struct old_utsname * name)
 /*
  * Compacrapability ...
  */
-asmlinkage int sys_olduname(struct oldold_utsname * name)
+asmlinkage int sys_olduname(struct oldold_utsname __user * name)
 {
        int error;
 
@@ -274,7 +274,7 @@ void sys_set_thread_area(unsigned long addr)
 asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
 {
        int     tmp, len;
-       char    *name;
+       char    __user *name;
 
        switch(cmd) {
        case SETNAME: {
@@ -283,7 +283,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
 
-               name = (char *) arg1;
+               name = (char __user *) arg1;
 
                len = strncpy_from_user(nodename, name, __NEW_UTS_LEN);
                if (len < 0)
@@ -324,7 +324,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
  * This is really horribly ugly.
  */
 asmlinkage int sys_ipc (uint call, int first, int second,
-                       unsigned long third, void *ptr, long fifth)
+                       unsigned long third, void __user *ptr, long fifth)
 {
        int version, ret;
 
@@ -333,24 +333,25 @@ asmlinkage int sys_ipc (uint call, int first, int second,
 
        switch (call) {
        case SEMOP:
-               return sys_semtimedop (first, (struct sembuf *)ptr, second,
-                                      NULL);
+               return sys_semtimedop (first, (struct sembuf __user *)ptr,
+                                      second, NULL);
        case SEMTIMEDOP:
-               return sys_semtimedop (first, (struct sembuf *)ptr, second,
-                                      (const struct timespec __user *)fifth);
+               return sys_semtimedop (first, (struct sembuf __user *)ptr,
+                                      second,
+                                      (const struct timespec __user *)fifth);
        case SEMGET:
                return sys_semget (first, second, third);
        case SEMCTL: {
                union semun fourth;
                if (!ptr)
                        return -EINVAL;
-               if (get_user(fourth.__pad, (void **) ptr))
+               if (get_user(fourth.__pad, (void *__user *) ptr))
                        return -EFAULT;
                return sys_semctl (first, second, third, fourth);
        }
 
        case MSGSND:
-               return sys_msgsnd (first, (struct msgbuf *) ptr,
+               return sys_msgsnd (first, (struct msgbuf __user *) ptr,
                                   second, third);
        case MSGRCV:
                switch (version) {
@@ -360,7 +361,7 @@ asmlinkage int sys_ipc (uint call, int first, int second,
                                return -EINVAL;
 
                        if (copy_from_user(&tmp,
-                                          (struct ipc_kludge *) ptr,
+                                          (struct ipc_kludge __user *) ptr,
                                           sizeof (tmp)))
                                return -EFAULT;
                        return sys_msgrcv (first, tmp.msgp, second,
@@ -368,35 +369,38 @@ asmlinkage int sys_ipc (uint call, int first, int second,
                }
                default:
                        return sys_msgrcv (first,
-                                          (struct msgbuf *) ptr,
+                                          (struct msgbuf __user *) ptr,
                                           second, fifth, third);
                }
        case MSGGET:
                return sys_msgget ((key_t) first, second);
        case MSGCTL:
-               return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+               return sys_msgctl (first, second,
+                                  (struct msqid_ds __user *) ptr);
 
        case SHMAT:
                switch (version) {
                default: {
                        ulong raddr;
-                       ret = do_shmat (first, (char *) ptr, second, &raddr);
+                       ret = do_shmat (first, (char __user *) ptr, second,
+                                       &raddr);
                        if (ret)
                                return ret;
-                       return put_user (raddr, (ulong *) third);
+                       return put_user (raddr, (ulong __user *) third);
                }
                case 1: /* iBCS2 emulator entry point */
                        if (!segment_eq(get_fs(), get_ds()))
                                return -EINVAL;
-                       return do_shmat (first, (char *) ptr, second, (ulong *) third);
+                       return do_shmat (first, (char __user *) ptr, second,
+                                        (ulong *) third);
                }
        case SHMDT:
-               return sys_shmdt ((char *)ptr);
+               return sys_shmdt ((char __user *)ptr);
        case SHMGET:
                return sys_shmget (first, second, third);
        case SHMCTL:
                return sys_shmctl (first, second,
-                                  (struct shmid_ds *) ptr);
+                                  (struct shmid_ds __user *) ptr);
        default:
                return -ENOSYS;
        }
index dcd819d..83eb08b 100644 (file)
@@ -134,8 +134,8 @@ void __init serial_init(void)
 
        memset(&s, 0, sizeof(s));
 
-       s.flags = STD_COM_FLAGS;
-       s.iotype = SERIAL_IO_MEM;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+       s.iotype = UPIO_MEM;
 
        if (mips_machtype == MACH_LASAT_100) {
                s.uartclk = LASAT_BASE_BAUD_100 * 16;
index 625843b..873cf31 100644 (file)
@@ -82,8 +82,8 @@ static void __init serial_init(void)
 #endif
        s.irq = ATLASINT_UART;
        s.uartclk = ATLAS_BASE_BAUD * 16;
-       s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-       s.iotype = SERIAL_IO_PORT;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ;
+       s.iotype = UPIO_PORT;
        s.regshift = 3;
 
        if (early_serial_setup(&s) != 0) {
index f966bc1..4266ce4 100644 (file)
@@ -71,8 +71,8 @@ static void __init serial_init(void)
 #endif
        s.irq = MIPSCPU_INT_BASE + MIPSCPU_INT_UART0;
        s.uartclk = SEAD_BASE_BAUD * 16;
-       s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
-       s.iotype = 0;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ;
+       s.iotype = UPIO_PORT;
        s.regshift = 3;
 
        if (early_serial_setup(&s) != 0) {
index 485d5a5..a2fd629 100644 (file)
@@ -88,8 +88,8 @@ static void __init serial_init(void)
         but poll for now */
        s.irq =  0;
        s.uartclk = BASE_BAUD * 16;
-       s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST;
-       s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST;
+       s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
+       s.iotype = UPIO_PORT;
        s.regshift = 0;
        s.timeout = 4;
 
index da6e1ed..2292d0e 100644 (file)
@@ -93,7 +93,7 @@ static void inline ja_console_probe(void)
        up.uartclk      = JAGUAR_ATX_UART_CLK;
        up.regshift     = 2;
        up.iotype       = UPIO_MEM;
-       up.flags        = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       up.flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        up.line         = 0;
 
        if (early_serial_setup(&up))
index 8aa9bd6..a592260 100644 (file)
@@ -66,28 +66,28 @@ struct ip3106_port ip3106_ports[] = {
        [0] = {
                .port   = {
                        .type           = PORT_IP3106,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .membase        = (void __iomem *)PNX8550_UART_PORT0,
                        .mapbase        = PNX8550_UART_PORT0,
                        .irq            = PNX8550_UART_INT(0),
                        .uartclk        = 3692300,
                        .fifosize       = 16,
                        .ops            = &ip3106_pops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 0,
                },
        },
        [1] = {
                .port   = {
                        .type           = PORT_IP3106,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .membase        = (void __iomem *)PNX8550_UART_PORT1,
                        .mapbase        = PNX8550_UART_PORT1,
                        .irq            = PNX8550_UART_INT(1),
                        .uartclk        = 3692300,
                        .fifosize       = 16,
                        .ops            = &ip3106_pops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 1,
                },
        },
index 059755b..8bce711 100644 (file)
@@ -185,7 +185,7 @@ static void __init py_uart_setup(void)
        up.uartclk      = TITAN_UART_CLK;
        up.regshift     = 0;
        up.iotype       = UPIO_MEM;
-       up.flags        = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       up.flags        = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        up.line         = 0;
 
        if (early_serial_setup(&up))
index d10a269..2c38770 100644 (file)
@@ -66,11 +66,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str)
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
-extern int early_serial_setup(struct uart_port *port);
-
-#define STD_COM_FLAGS (ASYNC_SKIP_TEST)
-#define BASE_BAUD (1843200 / 16)
-
 #endif /* CONFIG_SERIAL_8250 */
 
 /* An arbitrary time; this can be decreased if reliability looks good */
@@ -110,8 +105,8 @@ void __init plat_setup(void)
                o2_serial[0].type       = PORT_16550A;
                o2_serial[0].line       = 0;
                o2_serial[0].irq        = MACEISA_SERIAL1_IRQ;
-               o2_serial[0].flags      = STD_COM_FLAGS;
-               o2_serial[0].uartclk    = BASE_BAUD * 16;
+               o2_serial[0].flags      = UPF_SKIP_TEST;
+               o2_serial[0].uartclk    = 1843200;
                o2_serial[0].iotype     = UPIO_MEM;
                o2_serial[0].membase    = (char *)&mace->isa.serial1;
                o2_serial[0].fifosize   = 14;
@@ -121,8 +116,8 @@ void __init plat_setup(void)
                o2_serial[1].type       = PORT_16550A;
                o2_serial[1].line       = 1;
                o2_serial[1].irq        = MACEISA_SERIAL2_IRQ;
-               o2_serial[1].flags      = STD_COM_FLAGS;
-               o2_serial[1].uartclk    = BASE_BAUD * 16;
+               o2_serial[1].flags      = UPF_SKIP_TEST;
+               o2_serial[1].uartclk    = 1843200;
                o2_serial[1].iotype     = UPIO_MEM;
                o2_serial[1].membase    = (char *)&mace->isa.serial2;
                o2_serial[1].fifosize   = 14;
index 29b4d61..05273cc 100644 (file)
@@ -468,19 +468,23 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2)
        if ( opcode == 1 ) { /* GETFSIND */     
                len = strlen_user((char *)arg1);
                printk(KERN_DEBUG "len of arg1 = %d\n", len);
-
-               fsname = (char *) kmalloc(len+1, GFP_KERNEL);
+               if (len == 0)
+                       return 0;
+               fsname = (char *) kmalloc(len, GFP_KERNEL);
                if ( !fsname ) {
                        printk(KERN_DEBUG "failed to kmalloc fsname\n");
                        return 0;
                }
 
-               if ( copy_from_user(fsname, (char *)arg1, len+1) ) {
+               if ( copy_from_user(fsname, (char *)arg1, len) ) {
                        printk(KERN_DEBUG "failed to copy_from_user fsname\n");
                        kfree(fsname);
                        return 0;
                }
 
+               /* String could be altered by userspace after strlen_user() */
+               fsname[len] = '\0';
+
                printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname);
                if ( !strcmp(fsname, "hfs") ) {
                        fstype = 0;
index e4362df..340730f 100644 (file)
@@ -66,7 +66,7 @@ _GLOBAL(load_up_fpu)
 #else
        ld      r4,PACACURRENT(r13)
        addi    r5,r4,THREAD            /* Get THREAD */
-       l     r4,THREAD_FPEXC_MODE(r5)
+       lwz     r4,THREAD_FPEXC_MODE(r5)
        ori     r12,r12,MSR_FP
        or      r12,r12,r4
        std     r12,_MSR(r1)
index 3082684..4156596 100644 (file)
@@ -749,11 +749,12 @@ iSeries_secondary_smp_loop:
 
        .globl decrementer_iSeries_masked
 decrementer_iSeries_masked:
+       /* We may not have a valid TOC pointer in here. */
        li      r11,1
        ld      r12,PACALPPACAPTR(r13)
        stb     r11,LPPACADECRINT(r12)
-       LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy)
-       lwz     r12,ADDROFF(tb_ticks_per_jiffy)(r12)
+       LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy)
+       lwz     r12,0(r12)
        mtspr   SPRN_DEC,r12
        /* fall through */
 
index 4d9b438..946f321 100644 (file)
@@ -334,9 +334,6 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 
        spin_unlock_irqrestore(&(tbl->it_lock), flags);
 
-       /* Make sure updates are seen by hardware */
-       mb();
-
        DBG("mapped %d elements:\n", outcount);
 
        /* For the sake of iommu_unmap_sg, we clear out the length in the
@@ -347,6 +344,10 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                outs->dma_address = DMA_ERROR_CODE;
                outs->dma_length = 0;
        }
+
+       /* Make sure updates are seen by hardware */
+       mb();
+
        return outcount;
 
  failure:
@@ -358,6 +359,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                        npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr)
                                >> PAGE_SHIFT;
                        __iommu_free(tbl, vaddr, npages);
+                       s->dma_address = DMA_ERROR_CODE;
+                       s->dma_length = 0;
                }
        }
        spin_unlock_irqrestore(&(tbl->it_lock), flags);
index d50c8df..294832a 100644 (file)
@@ -491,7 +491,12 @@ void __init finish_device_tree(void)
        size = 16;
        finish_node(allnodes, &size, 1);
        size -= 16;
-       end = start = (unsigned long) __va(lmb_alloc(size, 128));
+
+       if (0 == size)
+               end = start = 0;
+       else
+               end = start = (unsigned long)__va(lmb_alloc(size, 128));
+
        finish_node(allnodes, &end, 0);
        BUG_ON(end != start + size);
 
@@ -1398,8 +1403,8 @@ struct device_node *of_find_node_by_name(struct device_node *from,
 
        read_lock(&devtree_lock);
        np = from ? from->allnext : allnodes;
-       for (; np != 0; np = np->allnext)
-               if (np->name != 0 && strcasecmp(np->name, name) == 0
+       for (; np != NULL; np = np->allnext)
+               if (np->name != NULL && strcasecmp(np->name, name) == 0
                    && of_node_get(np))
                        break;
        if (from)
@@ -1917,3 +1922,30 @@ int prom_update_property(struct device_node *np,
 
        return 0;
 }
+
+#ifdef CONFIG_KEXEC
+/* We may have allocated the flat device tree inside the crash kernel region
+ * in prom_init. If so we need to move it out into regular memory. */
+void kdump_move_device_tree(void)
+{
+       unsigned long start, end;
+       struct boot_param_header *new;
+
+       start = __pa((unsigned long)initial_boot_params);
+       end = start + initial_boot_params->totalsize;
+
+       if (end < crashk_res.start || start > crashk_res.end)
+               return;
+
+       new = (struct boot_param_header*)
+               __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE));
+
+       memcpy(new, initial_boot_params, initial_boot_params->totalsize);
+
+       initial_boot_params = new;
+
+       DBG("Flat device tree blob moved to %p\n", initial_boot_params);
+
+       /* XXX should we unreserve the old DT? */
+}
+#endif /* CONFIG_KEXEC */
index 7881ec9..ec7153f 100644 (file)
@@ -2098,6 +2098,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         */
        prom_init_stdout();
 
+       /* Bail if this is a kdump kernel. */
+       if (PHYSICAL_START > 0)
+               prom_panic("Error: You can't boot a kdump kernel from OF!\n");
+
        /*
         * Check for an initrd
         */
index a8099c8..3934c22 100644 (file)
@@ -465,8 +465,10 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
        if (parent == NULL)
                return NULL;
        bus = of_match_bus(parent);
-       if (strcmp(bus->name, "pci"))
+       if (strcmp(bus->name, "pci")) {
+               of_node_put(parent);
                return NULL;
+       }
        bus->count_cells(dev, &na, &ns);
        of_node_put(parent);
        if (!OF_CHECK_COUNTS(na, ns))
index 7fe4a5c..b5b2add 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <asm/prom.h>
 #include <asm/rtas.h>
+#include <asm/hvcall.h>
 #include <asm/semaphore.h>
 #include <asm/machdep.h>
 #include <asm/page.h>
@@ -565,6 +566,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
 #ifdef CONFIG_PPC_PSERIES
 static void rtas_percpu_suspend_me(void *info)
 {
+       int i;
        long rc;
        long flags;
        struct rtas_suspend_me_data *data =
@@ -587,18 +589,16 @@ static void rtas_percpu_suspend_me(void *info)
 
        if (rc == H_Continue) {
                data->waiting = 0;
-               rtas_call(ibm_suspend_me_token, 0, 1,
-                         data->args->args);
+               data->args->args[data->args->nargs] =
+                       rtas_call(ibm_suspend_me_token, 0, 1, NULL);
+               for_each_cpu(i)
+                       plpar_hcall_norets(H_PROD,i);
        } else {
                data->waiting = -EBUSY;
                printk(KERN_ERR "Error on H_Join hypervisor call\n");
        }
 
 out:
-       /* before we restore interrupts, make sure we don't
-        * generate a spurious soft lockup errors
-        */
-       touch_softlockup_watchdog();
        local_irq_restore(flags);
        return;
 }
index 5050009..aaf384c 100644 (file)
@@ -672,8 +672,7 @@ static void rtas_flash_firmware(int reboot_type)
 static void remove_flash_pde(struct proc_dir_entry *dp)
 {
        if (dp) {
-               if (dp->data != NULL)
-                       kfree(dp->data);
+               kfree(dp->data);
                dp->owner = NULL;
                remove_proc_entry(dp->name, dp->parent);
        }
index e29b275..a717dff 100644 (file)
@@ -398,6 +398,9 @@ void __init setup_system(void)
 {
        DBG(" -> setup_system()\n");
 
+#ifdef CONFIG_KEXEC
+       kdump_move_device_tree();
+#endif
        /*
         * Unflatten the device-tree passed by prom_init or kexec
         */
index c6d0595..bd837b5 100644 (file)
@@ -142,11 +142,7 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
        return 0;
 }
 
-static inline compat_uptr_t to_user_ptr(void *kp)
-{
-       return (compat_uptr_t)(u64)kp;
-}
-
+#define to_user_ptr(p)         ptr_to_compat(p)
 #define from_user_ptr(p)       compat_ptr(p)
 
 static inline int save_general_regs(struct pt_regs *regs,
@@ -213,8 +209,8 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka,
        return 0;
 }
 
-#define to_user_ptr(p)         (p)
-#define from_user_ptr(p)       (p)
+#define to_user_ptr(p)         ((unsigned long)(p))
+#define from_user_ptr(p)       ((void __user *)(p))
 
 static inline int save_general_regs(struct pt_regs *regs,
                struct mcontext __user *frame)
@@ -526,7 +522,7 @@ long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act,
 
        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
        if (!ret && oact) {
-               ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
+               ret = put_user(to_user_ptr(old_ka.sa.sa_handler), &oact->sa_handler);
                ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
                ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
        }
@@ -675,8 +671,8 @@ long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo
 int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
                      int r6, int r7, int r8, struct pt_regs *regs)
 {
-       stack_32_t __user * newstack = (stack_32_t __user *)(long) __new;
-       stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old;
+       stack_32_t __user * newstack = compat_ptr(__new);
+       stack_32_t __user * oldstack = compat_ptr(__old);
        stack_t uss, uoss;
        int ret;
        mm_segment_t old_fs;
@@ -708,7 +704,7 @@ int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
        set_fs(old_fs);
        /* Copy the stack information to the user output buffer */
        if (!ret && oldstack  &&
-               (put_user((long)uoss.ss_sp, &oldstack->ss_sp) ||
+               (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) ||
                 __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
                 __put_user(uoss.ss_size, &oldstack->ss_size)))
                return -EFAULT;
index b319311..497a5d3 100644 (file)
@@ -60,8 +60,8 @@ struct rt_sigframe {
        struct ucontext uc;
        unsigned long _unused[2];
        unsigned int tramp[TRAMP_SIZE];
-       struct siginfo *pinfo;
-       void *puc;
+       struct siginfo __user *pinfo;
+       void __user *puc;
        struct siginfo info;
        /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */
        char abigap[288];
index c8458c5..13595a6 100644 (file)
@@ -540,6 +540,9 @@ int __devinit start_secondary(void *unused)
        if (smp_ops->take_timebase)
                smp_ops->take_timebase();
 
+       if (system_state > SYSTEM_BOOTING)
+               per_cpu(last_jiffy, cpu) = get_tb();
+
        spin_lock(&call_lock);
        cpu_set(cpu, cpu_online_map);
        spin_unlock(&call_lock);
index c4a294d..1886045 100644 (file)
@@ -612,10 +612,10 @@ void __init generic_calibrate_decr(void)
 
        ppc_tb_freq = DEFAULT_TB_FREQ;          /* hardcoded default */
        node_found = 0;
-       if (cpu != 0) {
+       if (cpu) {
                fp = (unsigned int *)get_property(cpu, "timebase-frequency",
                                                  NULL);
-               if (fp != 0) {
+               if (fp) {
                        node_found = 1;
                        ppc_tb_freq = *fp;
                }
@@ -626,10 +626,10 @@ void __init generic_calibrate_decr(void)
 
        ppc_proc_freq = DEFAULT_PROC_FREQ;
        node_found = 0;
-       if (cpu != 0) {
+       if (cpu) {
                fp = (unsigned int *)get_property(cpu, "clock-frequency",
                                                  NULL);
-               if (fp != 0) {
+               if (fp) {
                        node_found = 1;
                        ppc_proc_freq = *fp;
                }
index 2da65a9..5d29dcc 100644 (file)
@@ -144,7 +144,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
 }
 
 #ifdef CONFIG_PPC_MAPLE
-void udbg_maple_real_putc(unsigned char c)
+void udbg_maple_real_putc(char c)
 {
        if (udbg_comport) {
                while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
index 9584608..bbe3eac 100644 (file)
@@ -197,6 +197,8 @@ long __init lmb_reserve(unsigned long base, unsigned long size)
 {
        struct lmb_region *_rgn = &(lmb.reserved);
 
+       BUG_ON(0 == size);
+
        return lmb_add_region(_rgn, base, size);
 }
 
@@ -227,6 +229,8 @@ unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
        long i, j;
        unsigned long base = 0;
 
+       BUG_ON(0 == size);
+
 #ifdef CONFIG_PPC32
        /* On 32-bit, make sure we allocate lowmem */
        if (max_addr == LMB_ALLOC_ANYWHERE)
index 15aac0d..550517c 100644 (file)
@@ -435,17 +435,12 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
 {
        clear_page(page);
 
-       if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
-               return;
        /*
         * We shouldnt have to do this, but some versions of glibc
         * require it (ld.so assumes zero filled pages are icache clean)
         * - Anton
         */
-
-       /* avoid an atomic op if possible */
-       if (test_bit(PG_arch_1, &pg->flags))
-               clear_bit(PG_arch_1, &pg->flags);
+       flush_dcache_page(pg);
 }
 EXPORT_SYMBOL(clear_user_page);
 
@@ -469,12 +464,7 @@ void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
                return;
 #endif
 
-       if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
-               return;
-
-       /* avoid an atomic op if possible */
-       if (test_bit(PG_arch_1, &pg->flags))
-               clear_bit(PG_arch_1, &pg->flags);
+       flush_dcache_page(pg);
 }
 
 void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
index 16031b5..3b998a3 100644 (file)
@@ -2,7 +2,7 @@ obj-y                   += interrupt.o iommu.o setup.o spider-pic.o
 obj-y                  += pervasive.o
 
 obj-$(CONFIG_SMP)      += smp.o
-obj-$(CONFIG_SPU_FS)   += spufs/ spu-base.o
+obj-$(CONFIG_SPU_FS)   += spu-base.o spufs/
 
 spu-base-y             += spu_base.o spu_priv1.o
 
index 3a2057f..814f547 100644 (file)
@@ -5,7 +5,6 @@
 extern void chrp_nvram_init(void);
 extern void chrp_get_rtc_time(struct rtc_time *);
 extern int chrp_set_rtc_time(struct rtc_time *);
-extern void chrp_calibrate_decr(void);
 extern long chrp_time_init(void);
 
 extern void chrp_find_bridges(void);
index 00c52f2..8ef279a 100644 (file)
@@ -204,9 +204,11 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
        struct device_node *root = find_path_device("/");
        struct device_node *rtas;
 
+       of_node_get(root);
        rtas = of_find_node_by_name (root, "rtas");
        if (rtas) {
                hose->ops = &rtas_pci_ops;
+               of_node_put(rtas);
        } else {
                printk ("RTAS supporting Pegasos OF not found, please upgrade"
                        " your firmware\n");
index 2dc87aa..e1fadbf 100644 (file)
@@ -506,7 +506,7 @@ void __init chrp_init(void)
        ppc_md.halt           = rtas_halt;
 
        ppc_md.time_init      = chrp_time_init;
-       ppc_md.calibrate_decr = chrp_calibrate_decr;
+       ppc_md.calibrate_decr = generic_calibrate_decr;
 
        /* this may get overridden with rtas routines later... */
        ppc_md.set_rtc_time   = chrp_set_rtc_time;
index 36a0f97..78df2e7 100644 (file)
@@ -167,24 +167,3 @@ void chrp_get_rtc_time(struct rtc_time *tm)
        tm->tm_mon = mon;
        tm->tm_year = year;
 }
-
-
-void __init chrp_calibrate_decr(void)
-{
-       struct device_node *cpu;
-       unsigned int freq, *fp;
-
-       /*
-        * The cpu node should have a timebase-frequency property
-        * to tell us the rate at which the decrementer counts.
-        */
-       freq = 16666000;                /* hardcoded default */
-       cpu = find_type_devices("cpu");
-       if (cpu != 0) {
-               fp = (unsigned int *)
-                       get_property(cpu, "timebase-frequency", NULL);
-               if (fp != 0)
-                       freq = *fp;
-       }
-       ppc_tb_freq = freq;
-}
index 535c802..87eb6bb 100644 (file)
@@ -1052,8 +1052,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter)
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus);
 
-extern int pmac_i2c_match_adapter(struct device_node *dev,
-                                 struct i2c_adapter *adapter)
+int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter)
 {
        struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev);
 
index f671ed2..de3f30e 100644 (file)
@@ -136,14 +136,14 @@ static void __init fixup_bus_range(struct device_node *bridge)
        |(((unsigned int)(off)) & 0xFCUL) \
        |1UL)
 
-static unsigned long macrisc_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose,
                                               u8 bus, u8 dev_fn, u8 offset)
 {
        unsigned int caddr;
 
        if (bus == hose->first_busno) {
                if (dev_fn < (11 << 3))
-                       return 0;
+                       return NULL;
                caddr = MACRISC_CFA0(dev_fn, offset);
        } else
                caddr = MACRISC_CFA1(bus, dev_fn, offset);
@@ -154,14 +154,14 @@ static unsigned long macrisc_cfg_access(struct pci_controller* hose,
        } while (in_le32(hose->cfg_addr) != caddr);
 
        offset &= has_uninorth ? 0x07 : 0x03;
-       return ((unsigned long)hose->cfg_data) + offset;
+       return hose->cfg_data + offset;
 }
 
 static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
                                      int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -177,13 +177,13 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -193,7 +193,7 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
                                       int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -209,16 +209,16 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32(addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -348,25 +348,23 @@ static int u3_ht_skip_device(struct pci_controller *hose,
                + (((unsigned int)bus) << 16) \
                + 0x01000000UL)
 
-static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
                                             u8 bus, u8 devfn, u8 offset)
 {
        if (bus == hose->first_busno) {
                /* For now, we don't self probe U3 HT bridge */
                if (PCI_SLOT(devfn) == 0)
-                       return 0;
-               return ((unsigned long)hose->cfg_data) +
-                       U3_HT_CFA0(devfn, offset);
+                       return NULL;
+               return hose->cfg_data + U3_HT_CFA0(devfn, offset);
        } else
-               return ((unsigned long)hose->cfg_data) +
-                       U3_HT_CFA1(bus, devfn, offset);
+               return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
 }
 
 static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                                    int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -400,13 +398,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -416,7 +414,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -442,16 +440,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32((u32 __iomem *)addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -476,7 +474,7 @@ static struct pci_ops u3_ht_pci_ops =
         |(((unsigned int)(off)) & 0xfcU)       \
         |1UL)
 
-static unsigned long u4_pcie_cfg_access(struct pci_controller* hose,
+static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose,
                                        u8 bus, u8 dev_fn, int offset)
 {
        unsigned int caddr;
@@ -492,14 +490,14 @@ static unsigned long u4_pcie_cfg_access(struct pci_controller* hose,
        } while (in_le32(hose->cfg_addr) != caddr);
 
        offset &= 0x03;
-       return ((unsigned long)hose->cfg_data) + offset;
+       return hose->cfg_data + offset;
 }
 
 static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
                               int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -515,13 +513,13 @@ static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               *val = in_8((u8 *)addr);
+               *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16((u16 *)addr);
+               *val = in_le16(addr);
                break;
        default:
-               *val = in_le32((u32 *)addr);
+               *val = in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -531,7 +529,7 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
                                int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       unsigned long addr;
+       volatile void __iomem *addr;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
@@ -547,16 +545,16 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
         */
        switch (len) {
        case 1:
-               out_8((u8 *)addr, val);
-               (void) in_8((u8 *)addr);
+               out_8(addr, val);
+               (void) in_8(addr);
                break;
        case 2:
-               out_le16((u16 *)addr, val);
-               (void) in_le16((u16 *)addr);
+               out_le16(addr, val);
+               (void) in_le16(addr);
                break;
        default:
-               out_le32((u32 *)addr, val);
-               (void) in_le32((u32 *)addr);
+               out_le32(addr, val);
+               (void) in_le32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -773,8 +771,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
         * the reg address cell, we shall fix that by killing struct
         * reg_property and using some accessor functions instead
         */
-       hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000,
-                                                          0x02000000);
+       hose->cfg_data = ioremap(0xf2000000, 0x02000000);
 
        /*
         * /ht node doesn't expose a "ranges" property, so we "remove"
index 89c4c36..1955462 100644 (file)
@@ -82,8 +82,6 @@
 
 #undef SHOW_GATWICK_IRQS
 
-unsigned char drive_info;
-
 int ppc_override_l2cr = 0;
 int ppc_override_l2cr_value;
 int has_l2cache = 0;
index 6373372..e3cbba4 100644 (file)
@@ -333,7 +333,7 @@ void handle_eeh_events (struct eeh_event *event)
                rc = eeh_reset_device(frozen_pdn, NULL);
                if (rc)
                        goto hard_fail;
-               pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+               pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
        }
 
        /* If all devices reported they can proceed, the re-enable PIO */
@@ -342,11 +342,11 @@ void handle_eeh_events (struct eeh_event *event)
                rc = eeh_reset_device(frozen_pdn, NULL);
                if (rc)
                        goto hard_fail;
-               pci_walk_bus(frozen_bus, eeh_report_reset, 0);
+               pci_walk_bus(frozen_bus, eeh_report_reset, NULL);
        }
 
        /* Tell all device drivers that they can resume operations */
-       pci_walk_bus(frozen_bus, eeh_report_resume, 0);
+       pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
 
        return;
        
@@ -367,7 +367,7 @@ hard_fail:
        eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
 
        /* Notify all devices that they're about to go down. */
-       pci_walk_bus(frozen_bus, eeh_report_failure, 0);
+       pci_walk_bus(frozen_bus, eeh_report_failure, NULL);
 
        /* Shut down the device drivers for good. */
        pcibios_remove_pci_devices(frozen_bus);
index da6ceba..9edeca8 100644 (file)
@@ -585,7 +585,7 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
 static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
 {
        /* Don't risk a hypervisor call if we're crashing */
-       if (!crash_shutdown) {
+       if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
                unsigned long vpa = __pa(get_lppaca());
 
                if (unregister_vpa(hard_smp_processor_id(), vpa)) {
index 977de9d..6298264 100644 (file)
@@ -59,7 +59,7 @@ static unsigned long dart_tablesize;
 static u32 *dart_vbase;
 
 /* Mapped base address for the dart */
-static unsigned int *__iomem dart;
+static unsigned int __iomem *dart;
 
 /* Dummy val that entries are set to when unused */
 static unsigned int dart_emptyval;
index 3e6ca7f..c1e89ad 100644 (file)
@@ -810,13 +810,16 @@ initial_mmu:
        mtspr   SPRN_MD_TWC, r9
        li      r11, MI_BOOTINIT        /* Create RPN for address 0 */
        addis   r11, r11, 0x0080        /* Add 8M */
-       mtspr   SPRN_MD_RPN, r8
+       mtspr   SPRN_MD_RPN, r11
+
+       addi    r10, r10, 0x0100
+       mtspr   SPRN_MD_CTR, r10
 
        addis   r8, r8, 0x0080          /* Add 8M */
        mtspr   SPRN_MD_EPN, r8
        mtspr   SPRN_MD_TWC, r9
        addis   r11, r11, 0x0080        /* Add 8M */
-       mtspr   SPRN_MD_RPN, r8
+       mtspr   SPRN_MD_RPN, r11
 #endif
 
        /* Since the cache is enabled according to the information we
index 3a6e4bc..15bd9b4 100644 (file)
@@ -186,11 +186,15 @@ EXPORT_SYMBOL(flush_tlb_kernel_range);
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(_tlbie);
 #ifdef CONFIG_ALTIVEC
+#ifndef CONFIG_SMP
 EXPORT_SYMBOL(last_task_used_altivec);
+#endif
 EXPORT_SYMBOL(giveup_altivec);
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_SPE
+#ifndef CONFIG_SMP
 EXPORT_SYMBOL(last_task_used_spe);
+#endif
 EXPORT_SYMBOL(giveup_spe);
 #endif /* CONFIG_SPE */
 #ifdef CONFIG_SMP
index 159b228..0ec53f0 100644 (file)
@@ -332,8 +332,8 @@ bamboo_early_serial_map(void)
        port.irq = 0;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 8110f55..ce48a4f 100644 (file)
@@ -97,8 +97,8 @@ bubinga_early_serial_map(void)
        port.irq = ACTING_UART0_INT;
        port.uartclk = uart_clock;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 64ebae1..9a828b6 100644 (file)
@@ -225,8 +225,8 @@ ebony_early_serial_map(void)
        port.irq = 0;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index d810b73..21d2913 100644 (file)
@@ -279,8 +279,8 @@ luan_early_serial_map(void)
        port.irq = UART0_INT;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 73b2c98..4f355b6 100644 (file)
@@ -248,8 +248,8 @@ ocotea_early_serial_map(void)
        port.irq = UART0_INT;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 0b1b77d..e90d97f 100644 (file)
@@ -95,8 +95,8 @@ ml300_early_serial_map(void)
                port.irq = old_ports[i].irq;
                port.uartclk = old_ports[i].baud_base * 16;
                port.regshift = old_ports[i].iomem_reg_shift;
-               port.iotype = SERIAL_IO_MEM;
-               port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+               port.iotype = UPIO_MEM;
+               port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
                port.line = i;
 
                if (early_serial_setup(&port) != 0) {
index e60f4bd..b065b8b 100644 (file)
@@ -305,8 +305,8 @@ yucca_early_serial_map(void)
        port.irq = UART0_INT;
        port.uartclk = clocks.uart0;
        port.regshift = 0;
-       port.iotype = SERIAL_IO_MEM;
-       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.iotype = UPIO_MEM;
+       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
        port.line = 0;
 
        if (early_serial_setup(&port) != 0) {
index 012e1e6..1a659bb 100644 (file)
@@ -301,14 +301,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                struct uart_port p;
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4500);
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4600);
                p.uartclk = binfo->bi_busfreq;
 
index 2eceb1e..408d64f 100644 (file)
@@ -162,14 +162,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                          binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
index b332eba..1801ab3 100644 (file)
@@ -534,14 +534,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                                binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
index e777ba8..8a72221 100644 (file)
@@ -64,7 +64,7 @@ sbc8560_early_serial_map(void)
        uart_req.irq = MPC85xx_IRQ_EXT9;
        uart_req.flags = STD_COM_FLAGS;
        uart_req.uartclk = BASE_BAUD * 16;
-        uart_req.iotype = SERIAL_IO_MEM;
+        uart_req.iotype = UPIO_MEM;
         uart_req.mapbase = UARTA_ADDR;
         uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE);
        uart_req.type = PORT_16650;
index b436f4d..a5e38ba 100644 (file)
@@ -346,14 +346,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                          binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
                gen550_init(0, &p);
 
                memset(&p, 0, sizeof (p));
-               p.iotype = SERIAL_IO_MEM;
+               p.iotype = UPIO_MEM;
                p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET;
                p.uartclk = binfo->bi_busfreq;
 
index 48a4a51..aefcc0e 100644 (file)
@@ -116,7 +116,7 @@ chestnut_early_serial_map(void)
        port.uartclk = BASE_BAUD * 16;
        port.irq = UART0_INT;
        port.flags = STD_COM_FLAGS | UPF_IOREMAP;
-       port.iotype = SERIAL_IO_MEM;
+       port.iotype = UPIO_MEM;
        port.mapbase = CHESTNUT_UART0_IO_BASE;
        port.regshift = 0;
 
index 32358b3..ffde8f6 100644 (file)
@@ -330,7 +330,7 @@ ev64260_early_serial_map(void)
                port.irq = EV64260_UART_0_IRQ;
                port.uartclk = BASE_BAUD * 16;
                port.regshift = 2;
-               port.iotype = SERIAL_IO_MEM;
+               port.iotype = UPIO_MEM;
                port.flags = STD_COM_FLAGS;
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
index 708b873..872c0a3 100644 (file)
@@ -100,7 +100,7 @@ static void __init ppc7d_early_serial_map(void)
        serial_req.uartclk = UART_CLK;
        serial_req.irq = 4;
        serial_req.flags = STD_COM_FLAGS;
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.iotype = UPIO_MEM;
        serial_req.membase = (u_char *) PPC7D_SERIAL_0;
 
        gen550_init(0, &serial_req);
index 5ad70d3..69e1de7 100644 (file)
@@ -176,8 +176,8 @@ spruce_early_serial_map(void)
        memset(&serial_req, 0, sizeof(serial_req));
        serial_req.uartclk = uart_clk;
        serial_req.irq = UART0_INT;
-       serial_req.flags = ASYNC_BOOT_AUTOCONF;
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.flags = UPF_BOOT_AUTOCONF;
+       serial_req.iotype = UPIO_MEM;
        serial_req.membase = (u_char *)UART0_IO_BASE;
        serial_req.regshift = 0;
 
index ab34b1d..2fe28de 100644 (file)
@@ -189,8 +189,8 @@ ocp_device_resume(struct device *dev)
 struct bus_type ocp_bus_type = {
        .name = "ocp",
        .match = ocp_device_match,
-       .probe = ocp_driver_probe,
-       .remove = ocp_driver_remove,
+       .probe = ocp_device_probe,
+       .remove = ocp_device_remove,
        .suspend = ocp_device_suspend,
        .resume = ocp_device_resume,
 };
index 1b5fe9e..7bada82 100644 (file)
@@ -108,7 +108,7 @@ mpc83xx_early_serial_map(void)
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
        memset(&serial_req, 0, sizeof (serial_req));
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.iotype = UPIO_MEM;
        serial_req.mapbase = pdata[0].mapbase;
        serial_req.membase = pdata[0].membase;
        serial_req.regshift = 0;
index 1a47ff4..e4dda43 100644 (file)
@@ -90,7 +90,7 @@ mpc85xx_early_serial_map(void)
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
        memset(&serial_req, 0, sizeof (serial_req));
-       serial_req.iotype = SERIAL_IO_MEM;
+       serial_req.iotype = UPIO_MEM;
        serial_req.mapbase = pdata[0].mapbase;
        serial_req.membase = pdata[0].membase;
        serial_req.regshift = 0;
index bf9a7a3..cc20f0e 100644 (file)
 #define SET_STAT_UID(stat, uid)                (stat).st_uid = high2lowuid(uid)
 #define SET_STAT_GID(stat, gid)                (stat).st_gid = high2lowgid(gid)
 
-asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
 {
        return sys_chown(filename, low2highuid(user), low2highgid(group));
 }
 
-asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
+asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group)
 {
        return sys_lchown(filename, low2highuid(user), low2highgid(group));
 }
@@ -141,7 +141,7 @@ asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
                low2highuid(suid));
 }
 
-asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
+asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid)
 {
        int retval;
 
@@ -158,7 +158,7 @@ asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
                low2highgid(sgid));
 }
 
-asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
+asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
 {
        int retval;
 
@@ -179,7 +179,7 @@ asmlinkage long sys32_setfsgid16(u16 gid)
        return sys_setfsgid((gid_t)gid);
 }
 
-static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
+static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
 {
        int i;
        u16 group;
@@ -193,7 +193,7 @@ static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
        return 0;
 }
 
-static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
+static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)
 {
        int i;
        u16 group;
@@ -207,7 +207,7 @@ static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
        return 0;
 }
 
-asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
 {
        int i;
 
@@ -231,7 +231,7 @@ out:
        return i;
 }
 
-asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
+asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
 {
        struct group_info *group_info;
        int retval;
@@ -278,14 +278,14 @@ asmlinkage long sys32_getegid16(void)
 
 /* 32-bit timeval and related flotsam.  */
 
-static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
+static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
 {
        return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
                (__get_user(o->tv_sec, &i->tv_sec) ||
                 __get_user(o->tv_usec, &i->tv_usec)));
 }
 
-static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
+static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
 {
        return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
                (__put_user(i->tv_sec, &o->tv_sec) ||
@@ -341,7 +341,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
        return -ENOSYS;
 }
 
-asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low)
+asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
 {
        if ((int)high < 0)
                return -EINVAL;
@@ -357,7 +357,7 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
                return sys_ftruncate(fd, (high << 32) | low);
 }
 
-int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
+int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
 {
        int err;
 
@@ -591,7 +591,7 @@ sys32_delete_module(const char __user *name_user, unsigned int flags)
 
 extern struct timezone sys_tz;
 
-asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        if (tv) {
                struct timeval ktv;
@@ -606,7 +606,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *t
        return 0;
 }
 
-static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
+static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
 {
        long usec;
 
@@ -620,7 +620,7 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
        return 0;
 }
 
-asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
+asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
 {
        struct timespec kts;
        struct timezone ktz;
@@ -645,7 +645,7 @@ asmlinkage long sys32_pause(void)
        return -ERESTARTNOHAND;
 }
 
-asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
+asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
 {
        if ((compat_ssize_t) count < 0)
@@ -653,7 +653,7 @@ asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
        return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf,
+asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
                                size_t count, u32 poshi, u32 poslo)
 {
        if ((compat_ssize_t) count < 0)
@@ -666,7 +666,7 @@ asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 coun
        return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
 }
 
-asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count)
+asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count)
 {
        mm_segment_t old_fs = get_fs();
        int ret;
@@ -686,7 +686,7 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size
 }
 
 asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
-                               compat_loff_t *offset, s32 count)
+                               compat_loff_t __user *offset, s32 count)
 {
        mm_segment_t old_fs = get_fs();
        int ret;
@@ -722,7 +722,7 @@ struct timex32 {
 
 extern int do_adjtimex(struct timex *);
 
-asmlinkage long sys32_adjtimex(struct timex32 *utp)
+asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
 {
        struct timex txc;
        int ret;
@@ -789,12 +789,13 @@ struct __sysctl_args32 {
        u32 __unused[4];
 };
 
-asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
+asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
 {
        struct __sysctl_args32 tmp;
        int error;
-       size_t oldlen, *oldlenp = NULL;
-       unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
+       size_t oldlen;
+       size_t __user *oldlenp = NULL;
+       unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
 
        if (copy_from_user(&tmp, args, sizeof(tmp)))
                return -EFAULT;
@@ -806,20 +807,20 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
                   basically copy the whole sysctl.c here, and
                   glibc's __sysctl uses rw memory for the structure
                   anyway.  */
-               if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
-                   put_user(oldlen, (size_t *)addr))
+               if (get_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)) ||
+                   put_user(oldlen, (size_t __user *)addr))
                        return -EFAULT;
-               oldlenp = (size_t *)addr;
+               oldlenp = (size_t __user *)addr;
        }
 
        lock_kernel();
-       error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
-                         oldlenp, (void *)A(tmp.newval), tmp.newlen);
+       error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, compat_ptr(tmp.oldval),
+                         oldlenp, compat_ptr(tmp.newval), tmp.newlen);
        unlock_kernel();
        if (oldlenp) {
                if (!error) {
-                       if (get_user(oldlen, (size_t *)addr) ||
-                           put_user(oldlen, (u32 *)A(tmp.oldlenp)))
+                       if (get_user(oldlen, (size_t __user *)addr) ||
+                           put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
                                error = -EFAULT;
                }
                copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
@@ -853,7 +854,7 @@ struct stat64_emu31 {
        unsigned long   st_ino;
 };     
 
-static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
+static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)
 {
        struct stat64_emu31 tmp;
 
@@ -877,7 +878,7 @@ static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
        return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
 }
 
-asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_stat64(char __user * filename, struct stat64_emu31 __user * statbuf)
 {
        struct kstat stat;
        int ret = vfs_stat(filename, &stat);
@@ -886,7 +887,7 @@ asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
        return ret;
 }
 
-asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_lstat64(char __user * filename, struct stat64_emu31 __user * statbuf)
 {
        struct kstat stat;
        int ret = vfs_lstat(filename, &stat);
@@ -895,7 +896,7 @@ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
        return ret;
 }
 
-asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf)
+asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf)
 {
        struct kstat stat;
        int ret = vfs_fstat(fd, &stat);
@@ -952,7 +953,7 @@ out:
 
 
 asmlinkage unsigned long
-old32_mmap(struct mmap_arg_struct_emu31 *arg)
+old32_mmap(struct mmap_arg_struct_emu31 __user *arg)
 {
        struct mmap_arg_struct_emu31 a;
        int error = -EFAULT;
@@ -970,7 +971,7 @@ out:
 }
 
 asmlinkage long 
-sys32_mmap2(struct mmap_arg_struct_emu31 *arg)
+sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg)
 {
        struct mmap_arg_struct_emu31 a;
        int error = -EFAULT;
@@ -982,7 +983,7 @@ out:
        return error;
 }
 
-asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count)
 {
        if ((compat_ssize_t) count < 0)
                return -EINVAL; 
@@ -990,7 +991,7 @@ asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
        return sys_read(fd, buf, count);
 }
 
-asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count)
+asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
 {
        if ((compat_ssize_t) count < 0)
                return -EINVAL; 
@@ -1002,12 +1003,12 @@ asmlinkage long sys32_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-       int *parent_tidptr, *child_tidptr;
+       int __user *parent_tidptr, *child_tidptr;
 
         clone_flags = regs.gprs[3] & 0xffffffffUL;
         newsp = regs.orig_gpr2 & 0x7fffffffUL;
-       parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL);
-       child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL);
+       parent_tidptr = compat_ptr(regs.gprs[4]);
+       child_tidptr = compat_ptr(regs.gprs[5]);
         if (!newsp)
                 newsp = regs.gprs[15];
         return do_fork(clone_flags, newsp, &regs, 0,
index 6a63553..e351780 100644 (file)
@@ -122,8 +122,8 @@ out:
 #ifndef CONFIG_64BIT
 struct sel_arg_struct {
        unsigned long n;
-       fd_set *inp, *outp, *exp;
-       struct timeval *tvp;
+       fd_set __user *inp, *outp, *exp;
+       struct timeval __user *tvp;
 };
 
 asmlinkage long old_select(struct sel_arg_struct __user *arg)
index 5d21e9e..a46793b 100644 (file)
@@ -486,7 +486,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
                info.si_signo = signal;
                info.si_errno = 0;
                info.si_code = ILL_ILLOPC;
-               info.si_addr = (void *) location;
+               info.si_addr = (void __user *) location;
                do_trap(interruption_code, signal,
                        "illegal operation", regs, &info);
        }
index 2d5cb13..b075ab4 100644 (file)
@@ -42,8 +42,8 @@ static volatile long cmm_timed_pages_target = 0;
 static long cmm_timeout_pages = 0;
 static long cmm_timeout_seconds = 0;
 
-static struct cmm_page_array *cmm_page_list = 0;
-static struct cmm_page_array *cmm_timed_page_list = 0;
+static struct cmm_page_array *cmm_page_list = NULL;
+static struct cmm_page_array *cmm_timed_page_list = NULL;
 
 static unsigned long cmm_thread_active = 0;
 static struct work_struct cmm_thread_starter;
@@ -259,7 +259,7 @@ static struct ctl_table cmm_table[];
 
 static int
 cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
-                 void *buffer, size_t *lenp, loff_t *ppos)
+                 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        char buf[16], *p;
        long pages;
@@ -300,7 +300,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
 
 static int
 cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
-                   void *buffer, size_t *lenp, loff_t *ppos)
+                   void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        char buf[64], *p;
        long pages, seconds;
@@ -419,7 +419,7 @@ cmm_init (void)
 #ifdef CONFIG_CMM_IUCV
        smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
 #endif
-       INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, 0);
+       INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, NULL);
        init_waitqueue_head(&cmm_thread_wait);
        init_timer(&cmm_timer);
        return 0;
index c46f915..123abbb 100644 (file)
@@ -216,24 +216,26 @@ void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count)
 {
        volatile __u8 *bp;
        volatile __u16 *p;
+       unsigned char *s = addr;
 
        if (CHECK_AX88796L_PORT(port)) {
                p = (volatile unsigned short *)port88796l(port, 0);
-               while (count--) *((unsigned char *) addr)++ = *p & 0xff;
+               while (count--) *s++ = *p & 0xff;
        } else if (PXSEG(port))
-               while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port;
+               while (count--) *s++ = *(volatile unsigned char *)port;
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                bp = (__u8 *)PCI_IOMAP(port);
-               while (count--) *((volatile unsigned char *) addr)++ = *bp;
+               while (count--) *s++ = *bp;
        } else {
                p = (volatile unsigned short *)port2adr(port);
-               while (count--) *((unsigned char *) addr)++ = *p & 0xff;
+               while (count--) *s++ = *p & 0xff;
        }
 }
 
 void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
 {
        volatile __u16 *p;
+       __u16 *s = addr;
 
        if (CHECK_AX88796L_PORT(port))
                p = (volatile unsigned short *)port88796l(port, 1);
@@ -243,7 +245,7 @@ void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
                p = (volatile unsigned short *)PCI_IOMAP(port);
        else
                p = (volatile unsigned short *)port2adr(port);
-       while (count--) *((__u16 *) addr)++ = *p;
+       while (count--) *s++ = *p;
 }
 
 void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
@@ -252,8 +254,9 @@ void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
                maybebadio(insl, port);
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
+               __u32 *s = addr;
 
-               while (count--) *((__u32 *) addr)++ = *p;
+               while (count--) *s++ = *p;
        } else
                maybebadio(insl, port);
 }
@@ -262,24 +265,26 @@ void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
 {
        volatile __u8 *bp;
        volatile __u16 *p;
+       const __u8 *s = addr;
 
        if (CHECK_AX88796L_PORT(port)) {
                p = (volatile unsigned short *)port88796l(port, 0);
-               while (count--) *p = *((unsigned char *) addr)++;
+               while (count--) *p = *s++;
        } else if (PXSEG(port))
-               while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++;
+               while (count--) *(volatile unsigned char *)port = *s++;
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                bp = (__u8 *)PCI_IOMAP(port);
-               while (count--) *bp = *((volatile unsigned char *) addr)++;
+               while (count--) *bp = *s++;
        } else {
                p = (volatile unsigned short *)port2adr(port);
-               while (count--) *p = *((unsigned char *) addr)++;
+               while (count--) *p = *s++;
        }
 }
 
 void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
 {
        volatile __u16 *p;
+       const __u16 *s = addr;
 
        if (CHECK_AX88796L_PORT(port))
                p = (volatile unsigned short *)port88796l(port, 1);
@@ -289,7 +294,7 @@ void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
                p = (volatile unsigned short *)PCI_IOMAP(port);
        else
                p = (volatile unsigned short *)port2adr(port);
-       while (count--) *p = *((__u16 *) addr)++;
+       while (count--) *p = *s++;
 }
 
 void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
@@ -298,8 +303,9 @@ void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
                maybebadio(outsl, port);
        else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
                volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
+               const __u32 *s = addr;
 
-               while (count--) *p = *((__u32 *) addr)++;
+               while (count--) *p = *s++;
        } else
                maybebadio(outsl, port);
 }
index 472b450..de29c45 100644 (file)
 
 extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 
-#if 0
-/* Not yet - there's no declaration of drive_info anywhere. */
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(iounmap);
index 267ec8f..887f6a1 100644 (file)
@@ -38,7 +38,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 299      /* Each OS is different... */
+#define NR_SYSCALLS 300      /* Each OS is different... */
 
 /* These are just handy. */
 #define _SV    save    %sp, -STACKFRAME_SZ, %sp
index fbb05a4..118cac8 100644 (file)
@@ -54,7 +54,7 @@ void (*pm_idle)(void);
  * This is done via auxio, but could be used as a fallback
  * handler when auxio is not present-- unused for now...
  */
-void (*pm_power_off)(void);
+void (*pm_power_off)(void) = machine_power_off;
 
 /*
  * sysctl - toggle power-off restriction for serial console 
index 6877ae4..c031470 100644 (file)
@@ -78,7 +78,7 @@ sys_call_table:
 /*280*/        .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
 /*285*/        .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat
 /*290*/        .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-/*295*/        .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
+/*295*/        .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
 
 #ifdef CONFIG_SUNOS_EMUL
        /* Now the SunOS syscall table. */
@@ -190,5 +190,6 @@ sunos_sys_table:
 /*290*/        .long sunos_nosys, sunos_nosys, sunos_nosys
        .long sunos_nosys, sunos_nosys, sunos_nosys
        .long sunos_nosys, sunos_nosys, sunos_nosys
+       .long sunos_nosys
 
 #endif
index bc56a7d..069d497 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.16-rc2
-# Sat Feb  4 02:31:38 2006
+# Tue Feb  7 17:47:18 2006
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -30,7 +30,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 # General setup
 #
 CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -766,6 +766,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
index 12911e7..a73553a 100644 (file)
@@ -25,7 +25,7 @@
 
 #define curptr      g6
 
-#define NR_SYSCALLS 299      /* Each OS is different... */
+#define NR_SYSCALLS 300      /* Each OS is different... */
 
        .text
        .align          32
index 2881faf..5928b3c 100644 (file)
@@ -79,7 +79,7 @@ sys_call_table32:
 /*280*/        .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
        .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat
 /*285*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-       .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll
+       .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
 
 #endif /* CONFIG_COMPAT */
 
@@ -148,7 +148,7 @@ sys_call_table:
 /*280*/        .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat
        .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat
 /*285*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
-       .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll
+       .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -261,4 +261,5 @@ sunos_sys_table:
 /*290*/        .word sunos_nosys, sunos_nosys, sunos_nosys
        .word sunos_nosys, sunos_nosys, sunos_nosys
        .word sunos_nosys, sunos_nosys, sunos_nosys
+       .word sunos_nosys
 #endif
index d25667e..7043ca1 100644 (file)
@@ -283,32 +283,3 @@ solaris_sys_table:
        .word solaris_unimplemented     /*                      253     */
        .word solaris_unimplemented     /*                      254     */
        .word solaris_unimplemented     /*                      255     */
-       .word solaris_unimplemented     /*                      256     */
-       .word solaris_unimplemented     /*                      257     */
-       .word solaris_unimplemented     /*                      258     */
-       .word solaris_unimplemented     /*                      259     */
-       .word solaris_unimplemented     /*                      260     */
-       .word solaris_unimplemented     /*                      261     */
-       .word solaris_unimplemented     /*                      262     */
-       .word solaris_unimplemented     /*                      263     */
-       .word solaris_unimplemented     /*                      264     */
-       .word solaris_unimplemented     /*                      265     */
-       .word solaris_unimplemented     /*                      266     */
-       .word solaris_unimplemented     /*                      267     */
-       .word solaris_unimplemented     /*                      268     */
-       .word solaris_unimplemented     /*                      269     */
-       .word solaris_unimplemented     /*                      270     */
-       .word solaris_unimplemented     /*                      271     */
-       .word solaris_unimplemented     /*                      272     */
-       .word solaris_unimplemented     /*                      273     */
-       .word solaris_unimplemented     /*                      274     */
-       .word solaris_unimplemented     /*                      275     */
-       .word solaris_unimplemented     /*                      276     */
-       .word solaris_unimplemented     /*                      277     */
-       .word solaris_unimplemented     /*                      278     */
-       .word solaris_unimplemented     /*                      279     */
-       .word solaris_unimplemented     /*                      280     */
-       .word solaris_unimplemented     /*                      281     */
-       .word solaris_unimplemented     /*                      282     */
-       .word solaris_unimplemented     /*                      283     */
-
index 5d50d4a..2f880cb 100644 (file)
@@ -9,6 +9,7 @@
 #include <termios.h>
 #include <string.h>
 #include <signal.h>
+#include <sched.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -73,7 +74,6 @@ static void winch_handler(int sig)
 struct winch_data {
        int pty_fd;
        int pipe_fd;
-       int close_me;
 };
 
 static int winch_thread(void *arg)
@@ -84,7 +84,6 @@ static int winch_thread(void *arg)
        int count, err;
        char c = 1;
 
-       os_close_file(data->close_me);
        pty_fd = data->pty_fd;
        pipe_fd = data->pipe_fd;
        count = os_write_file(pipe_fd, &c, sizeof(c));
@@ -153,15 +152,16 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
        }
 
        data = ((struct winch_data) { .pty_fd           = fd,
-                                     .pipe_fd          = fds[1],
-                                     .close_me         = fds[0] } );
-       err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
+                                     .pipe_fd          = fds[1] } );
+       /* CLONE_FILES so this thread doesn't hold open files which are open
+        * now, but later closed.  This is a problem with /dev/net/tun.
+        */
+       err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0);
        if(err < 0){
                printk("fork of winch_thread failed - errno = %d\n", errno);
                goto out_close;
        }
 
-       os_close_file(fds[1]);
        *fd_out = fds[0];
        n = os_read_file(fds[0], &c, sizeof(c));
        if(n != sizeof(c)){
@@ -169,13 +169,12 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
                printk("read failed, err = %d\n", -n);
                printk("fd %d will not support SIGWINCH\n", fd);
                 err = -EINVAL;
-               goto out_close1;
+               goto out_close;
        }
        return err ;
 
  out_close:
        os_close_file(fds[1]);
- out_close1:
        os_close_file(fds[0]);
  out:
        return err;
index 8ebb224..8c7279b 100644 (file)
@@ -131,9 +131,8 @@ static int uml_net_open(struct net_device *dev)
                             SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
        if(err != 0){
                printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
-               if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
-               lp->fd = -1;
                err = -ENETUNREACH;
+               goto out_close;
        }
 
        lp->tl.data = (unsigned long) &lp->user;
@@ -145,9 +144,19 @@ static int uml_net_open(struct net_device *dev)
         */
        while((err = uml_net_rx(dev)) > 0) ;
 
- out:
        spin_unlock(&lp->lock);
-       return(err);
+
+       spin_lock(&opened_lock);
+       list_add(&lp->list, &opened);
+       spin_unlock(&opened_lock);
+
+       return 0;
+out_close:
+       if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
+       lp->fd = -1;
+out:
+       spin_unlock(&lp->lock);
+       return err;
 }
 
 static int uml_net_close(struct net_device *dev)
@@ -161,9 +170,13 @@ static int uml_net_close(struct net_device *dev)
        if(lp->close != NULL)
                (*lp->close)(lp->fd, &lp->user);
        lp->fd = -1;
-       list_del(&lp->list);
 
        spin_unlock(&lp->lock);
+
+       spin_lock(&opened_lock);
+       list_del(&lp->list);
+       spin_unlock(&opened_lock);
+
        return 0;
 }
 
@@ -410,11 +423,7 @@ static int eth_configure(int n, void *init, char *mac,
        if (device->have_mac)
                set_ether_mac(dev, device->mac);
 
-       spin_lock(&opened_lock);
-       list_add(&lp->list, &opened);
-       spin_unlock(&opened_lock);
-
-       return(0);
+       return 0;
 }
 
 static struct uml_net *find_device(int n)
index 4892e5f..83b688c 100644 (file)
@@ -14,7 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs);
 extern void save_registers(int pid, union uml_pt_regs *regs);
 extern void restore_registers(int pid, union uml_pt_regs *regs);
 extern void init_registers(int pid);
-extern void get_safe_registers(unsigned long * regs);
+extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs);
 extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
 
 #endif
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
deleted file mode 100644 (file)
index eea1c9c..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-/* 
- * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <sched.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <sys/user.h>
-#include <sys/time.h>
-#include <asm/unistd.h>
-#include <asm/types.h>
-#include "user.h"
-#include "ptrace_user.h"
-#include "sysdep/ptrace.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "skas.h"
-#include "stub-data.h"
-#include "mm_id.h"
-#include "sysdep/sigcontext.h"
-#include "sysdep/stub.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "skas_ptrace.h"
-#include "chan_user.h"
-#include "registers.h"
-#include "mem.h"
-#include "uml-config.h"
-#include "process.h"
-
-int is_skas_winch(int pid, int fd, void *data)
-{
-        if(pid != os_getpgrp())
-               return(0);
-
-       register_winch_irq(-1, fd, -1, data);
-       return(1);
-}
-
-void wait_stub_done(int pid, int sig, char * fname)
-{
-        int n, status, err;
-
-        do {
-                if ( sig != -1 ) {
-                        err = ptrace(PTRACE_CONT, pid, 0, sig);
-                        if(err)
-                                panic("%s : continue failed, errno = %d\n",
-                                      fname, errno);
-                }
-                sig = 0;
-
-                CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-        } while((n >= 0) && WIFSTOPPED(status) &&
-                ((WSTOPSIG(status) == SIGVTALRM) ||
-                /* running UML inside a detached screen can cause
-                 * SIGWINCHes
-                 */
-                (WSTOPSIG(status) == SIGWINCH)));
-
-        if((n < 0) || !WIFSTOPPED(status) ||
-           (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
-               unsigned long regs[HOST_FRAME_SIZE];
-               if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
-                       printk("Failed to get registers from stub, "
-                              "errno = %d\n", errno);
-               else {
-                       int i;
-
-                       printk("Stub registers -\n");
-                       for(i = 0; i < HOST_FRAME_SIZE; i++)
-                               printk("\t%d - %lx\n", i, regs[i]);
-               }
-                panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
-                      "pid = %d, n = %d, errno = %d, status = 0x%x\n",
-                      fname, pid, n, errno, status);
-        }
-}
-
-void get_skas_faultinfo(int pid, struct faultinfo * fi)
-{
-        int err;
-
-        if(ptrace_faultinfo){
-                err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
-                if(err)
-                        panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
-                              "errno = %d\n", errno);
-
-                /* Special handling for i386, which has different structs */
-                if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
-                        memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
-                               sizeof(struct faultinfo) -
-                               sizeof(struct ptrace_faultinfo));
-        }
-        else {
-                wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
-
-                /* faultinfo is prepared by the stub-segv-handler at start of
-                 * the stub stack page. We just have to copy it.
-                 */
-                memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
-        }
-}
-
-static void handle_segv(int pid, union uml_pt_regs * regs)
-{
-        get_skas_faultinfo(pid, &regs->skas.faultinfo);
-        segv(regs->skas.faultinfo, 0, 1, NULL);
-}
-
-/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
-static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu)
-{
-       int err, status;
-
-       /* Mark this as a syscall */
-       UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs);
-
-       if (!local_using_sysemu)
-       {
-               err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
-               if(err < 0)
-                       panic("handle_trap - nullifying syscall failed errno = %d\n",
-                             errno);
-
-               err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
-               if(err < 0)
-                       panic("handle_trap - continuing to end of syscall failed, "
-                             "errno = %d\n", errno);
-
-               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
-               if((err < 0) || !WIFSTOPPED(status) ||
-                  (WSTOPSIG(status) != SIGTRAP + 0x80))
-                       panic("handle_trap - failed to wait at end of syscall, "
-                             "errno = %d, status = %d\n", errno, status);
-       }
-
-       handle_syscall(regs);
-}
-
-extern int __syscall_stub_start;
-int stub_code_fd = -1;
-__u64 stub_code_offset;
-
-static int userspace_tramp(void *stack)
-{
-       void *addr;
-
-       ptrace(PTRACE_TRACEME, 0, 0, 0);
-
-       init_new_thread_signals(1);
-       enable_timer();
-
-       if(!proc_mm){
-               /* This has a pte, but it can't be mapped in with the usual
-                * tlb_flush mechanism because this is part of that mechanism
-                */
-               addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
-                             PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
-                             stub_code_fd, stub_code_offset);
-               if(addr == MAP_FAILED){
-                       printk("mapping stub code failed, errno = %d\n",
-                              errno);
-                       exit(1);
-               }
-
-               if(stack != NULL){
-                       int fd;
-                       __u64 offset;
-
-                       fd = phys_mapping(to_phys(stack), &offset);
-                       addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
-                                   PROT_READ | PROT_WRITE,
-                                   MAP_FIXED | MAP_SHARED, fd, offset);
-                       if(addr == MAP_FAILED){
-                               printk("mapping stub stack failed, "
-                                      "errno = %d\n", errno);
-                               exit(1);
-                       }
-               }
-       }
-       if(!ptrace_faultinfo){
-               unsigned long v = UML_CONFIG_STUB_CODE +
-                                 (unsigned long) stub_segv_handler -
-                                 (unsigned long) &__syscall_stub_start;
-
-               set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
-               set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
-                           SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
-                           SIGUSR1, -1);
-       }
-
-       os_stop_process(os_getpid());
-       return(0);
-}
-
-/* Each element set once, and only accessed by a single processor anyway */
-#undef NR_CPUS
-#define NR_CPUS 1
-int userspace_pid[NR_CPUS];
-
-int start_userspace(unsigned long stub_stack)
-{
-       void *stack;
-       unsigned long sp;
-       int pid, status, n, flags;
-
-       if ( stub_code_fd == -1 )
-               stub_code_fd = phys_mapping(to_phys(&__syscall_stub_start),
-                                           &stub_code_offset);
-
-       stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
-                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if(stack == MAP_FAILED)
-               panic("start_userspace : mmap failed, errno = %d", errno);
-       sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
-
-       flags = CLONE_FILES | SIGCHLD;
-       if(proc_mm) flags |= CLONE_VM;
-       pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
-       if(pid < 0)
-               panic("start_userspace : clone failed, errno = %d", errno);
-
-       do {
-               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
-               if(n < 0)
-                       panic("start_userspace : wait failed, errno = %d", 
-                             errno);
-       } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
-
-       if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
-               panic("start_userspace : expected SIGSTOP, got status = %d",
-                     status);
-
-       if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
-               panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n",
-                     errno);
-
-       if(munmap(stack, PAGE_SIZE) < 0)
-               panic("start_userspace : munmap failed, errno = %d\n", errno);
-
-       return(pid);
-}
-
-void userspace(union uml_pt_regs *regs)
-{
-       int err, status, op, pid = userspace_pid[0];
-       int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
-
-       while(1){
-               restore_registers(pid, regs);
-
-               /* Now we set local_using_sysemu to be used for one loop */
-               local_using_sysemu = get_using_sysemu();
-
-               op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
-
-               err = ptrace(op, pid, 0, 0);
-               if(err)
-                       panic("userspace - could not resume userspace process, "
-                             "pid=%d, ptrace operation = %d, errno = %d\n",
-                             op, errno);
-
-               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
-               if(err < 0)
-                       panic("userspace - waitpid failed, errno = %d\n", 
-                             errno);
-
-               regs->skas.is_user = 1;
-               save_registers(pid, regs);
-               UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
-
-               if(WIFSTOPPED(status)){
-                       switch(WSTOPSIG(status)){
-                       case SIGSEGV:
-                                if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
-                                        user_signal(SIGSEGV, regs, pid);
-                                else handle_segv(pid, regs);
-                               break;
-                       case SIGTRAP + 0x80:
-                               handle_trap(pid, regs, local_using_sysemu);
-                               break;
-                       case SIGTRAP:
-                               relay_signal(SIGTRAP, regs);
-                               break;
-                       case SIGIO:
-                       case SIGVTALRM:
-                       case SIGILL:
-                       case SIGBUS:
-                       case SIGFPE:
-                       case SIGWINCH:
-                                user_signal(WSTOPSIG(status), regs, pid);
-                               break;
-                       default:
-                               printk("userspace - child stopped with signal "
-                                      "%d\n", WSTOPSIG(status));
-                       }
-                       pid = userspace_pid[0];
-                       interrupt_end();
-
-                       /* Avoid -ERESTARTSYS handling in host */
-                       PT_SYSCALL_NR(regs->skas.regs) = -1;
-               }
-       }
-}
-#define INIT_JMP_NEW_THREAD 0
-#define INIT_JMP_REMOVE_SIGSTACK 1
-#define INIT_JMP_CALLBACK 2
-#define INIT_JMP_HALT 3
-#define INIT_JMP_REBOOT 4
-
-
-int copy_context_skas0(unsigned long new_stack, int pid)
-{
-       int err;
-       unsigned long regs[MAX_REG_NR];
-       unsigned long current_stack = current_stub_stack();
-       struct stub_data *data = (struct stub_data *) current_stack;
-       struct stub_data *child_data = (struct stub_data *) new_stack;
-       __u64 new_offset;
-       int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
-
-       /* prepare offset and fd of child's stack as argument for parent's
-        * and child's mmap2 calls
-        */
-       *data = ((struct stub_data) { .offset   = MMAP_OFFSET(new_offset),
-                                     .fd       = new_fd,
-                                     .timer    = ((struct itimerval)
-                                                  { { 0, 1000000 / hz() },
-                                                    { 0, 1000000 / hz() }})});
-       get_safe_registers(regs);
-
-       /* Set parent's instruction pointer to start of clone-stub */
-       regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
-                               (unsigned long) stub_clone_handler -
-                               (unsigned long) &__syscall_stub_start;
-       regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
-               sizeof(void *);
-       err = ptrace_setregs(pid, regs);
-       if(err < 0)
-               panic("copy_context_skas0 : PTRACE_SETREGS failed, "
-                     "pid = %d, errno = %d\n", pid, errno);
-
-       /* set a well known return code for detection of child write failure */
-       child_data->err = 12345678;
-
-       /* Wait, until parent has finished its work: read child's pid from
-        * parent's stack, and check, if bad result.
-        */
-       wait_stub_done(pid, 0, "copy_context_skas0");
-
-       pid = data->err;
-       if(pid < 0)
-               panic("copy_context_skas0 - stub-parent reports error %d\n",
-                     pid);
-
-       /* Wait, until child has finished too: read child's result from
-        * child's stack and check it.
-        */
-       wait_stub_done(pid, -1, "copy_context_skas0");
-       if (child_data->err != UML_CONFIG_STUB_DATA)
-               panic("copy_context_skas0 - stub-child reports error %d\n",
-                     child_data->err);
-
-       if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
-                  (void *)PTRACE_O_TRACESYSGOOD) < 0)
-               panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, "
-                     "errno = %d\n", errno);
-
-       return pid;
-}
-
-/*
- * This is used only, if stub pages are needed, while proc_mm is
- * availabl. Opening /proc/mm creates a new mm_context, which lacks
- * the stub-pages. Thus, we map them using /proc/mm-fd
- */
-void map_stub_pages(int fd, unsigned long code,
-                   unsigned long data, unsigned long stack)
-{
-       struct proc_mm_op mmop;
-       int n;
-
-       mmop = ((struct proc_mm_op) { .op        = MM_MMAP,
-                                     .u         =
-                                     { .mmap    =
-                                       { .addr    = code,
-                                         .len     = PAGE_SIZE,
-                                         .prot    = PROT_EXEC,
-                                         .flags   = MAP_FIXED | MAP_PRIVATE,
-                                         .fd      = stub_code_fd,
-                                         .offset  = stub_code_offset
-       } } });
-       n = os_write_file(fd, &mmop, sizeof(mmop));
-       if(n != sizeof(mmop))
-               panic("map_stub_pages : /proc/mm map for code failed, "
-                     "err = %d\n", -n);
-
-       if ( stack ) {
-               __u64 map_offset;
-               int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
-               mmop = ((struct proc_mm_op)
-                               { .op        = MM_MMAP,
-                                 .u         =
-                                 { .mmap    =
-                                   { .addr    = data,
-                                     .len     = PAGE_SIZE,
-                                     .prot    = PROT_READ | PROT_WRITE,
-                                     .flags   = MAP_FIXED | MAP_SHARED,
-                                     .fd      = map_fd,
-                                     .offset  = map_offset
-               } } });
-               n = os_write_file(fd, &mmop, sizeof(mmop));
-               if(n != sizeof(mmop))
-                       panic("map_stub_pages : /proc/mm map for data failed, "
-                             "err = %d\n", -n);
-       }
-}
-
-void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
-               void (*handler)(int))
-{
-       unsigned long flags;
-       sigjmp_buf switch_buf, fork_buf;
-
-       *switch_buf_ptr = &switch_buf;
-       *fork_buf_ptr = &fork_buf;
-
-       /* Somewhat subtle - siglongjmp restores the signal mask before doing
-        * the longjmp.  This means that when jumping from one stack to another
-        * when the target stack has interrupts enabled, an interrupt may occur
-        * on the source stack.  This is bad when starting up a process because
-        * it's not supposed to get timer ticks until it has been scheduled.
-        * So, we disable interrupts around the sigsetjmp to ensure that
-        * they can't happen until we get back here where they are safe.
-        */
-       flags = get_signals();
-       block_signals();
-       if(sigsetjmp(fork_buf, 1) == 0)
-               new_thread_proc(stack, handler);
-
-       remove_sigstack();
-
-       set_signals(flags);
-}
-
-void thread_wait(void *sw, void *fb)
-{
-       sigjmp_buf buf, **switch_buf = sw, *fork_buf;
-
-       *switch_buf = &buf;
-       fork_buf = fb;
-       if(sigsetjmp(buf, 1) == 0)
-               siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
-}
-
-void switch_threads(void *me, void *next)
-{
-       sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
-       
-       *me_ptr = &my_buf;
-       if(sigsetjmp(my_buf, 1) == 0)
-               siglongjmp(*next_buf, 1);
-}
-
-static sigjmp_buf initial_jmpbuf;
-
-/* XXX Make these percpu */
-static void (*cb_proc)(void *arg);
-static void *cb_arg;
-static sigjmp_buf *cb_back;
-
-int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
-{
-       sigjmp_buf **switch_buf = switch_buf_ptr;
-       int n;
-
-       set_handler(SIGWINCH, (__sighandler_t) sig_handler,
-                   SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
-                   SIGVTALRM, -1);
-
-       *fork_buf_ptr = &initial_jmpbuf;
-       n = sigsetjmp(initial_jmpbuf, 1);
-        switch(n){
-        case INIT_JMP_NEW_THREAD:
-                new_thread_proc((void *) stack, new_thread_handler);
-                break;
-        case INIT_JMP_REMOVE_SIGSTACK:
-                remove_sigstack();
-                break;
-        case INIT_JMP_CALLBACK:
-               (*cb_proc)(cb_arg);
-               siglongjmp(*cb_back, 1);
-                break;
-        case INIT_JMP_HALT:
-               kmalloc_ok = 0;
-               return(0);
-        case INIT_JMP_REBOOT:
-               kmalloc_ok = 0;
-               return(1);
-        default:
-                panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
-       }
-       siglongjmp(**switch_buf, 1);
-}
-
-void initial_thread_cb_skas(void (*proc)(void *), void *arg)
-{
-       sigjmp_buf here;
-
-       cb_proc = proc;
-       cb_arg = arg;
-       cb_back = &here;
-
-       block_signals();
-       if(sigsetjmp(here, 1) == 0)
-               siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK);
-       unblock_signals();
-
-       cb_proc = NULL;
-       cb_arg = NULL;
-       cb_back = NULL;
-}
-
-void halt_skas(void)
-{
-       block_signals();
-       siglongjmp(initial_jmpbuf, INIT_JMP_HALT);
-}
-
-void reboot_skas(void)
-{
-       block_signals();
-       siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
-}
-
-void switch_mm_skas(struct mm_id *mm_idp)
-{
-       int err;
-
-#warning need cpu pid in switch_mm_skas
-       if(proc_mm){
-               err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
-                            mm_idp->u.mm_fd);
-               if(err)
-                       panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
-                             "errno = %d\n", errno);
-       }
-       else userspace_pid[0] = mm_idp->u.pid;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index e2d3ca4..27cdf91 100644 (file)
@@ -193,6 +193,24 @@ __uml_setup("root=", uml_root_setup,
 "        root=/dev/ubd5\n\n"
 );
 
+#ifndef CONFIG_MODE_TT
+
+static int __init no_skas_debug_setup(char *line, int *add)
+{
+       printf("'debug' is not necessary to gdb UML in skas mode - run \n");
+       printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n");
+       printf("doesn't work as expected\n");
+
+       return 0;
+}
+
+__uml_setup("debug", no_skas_debug_setup,
+"debug\n"
+"    this flag is not needed to run gdb on UML in skas mode\n\n"
+);
+
+#endif
+
 #ifdef CONFIG_SMP
 static int __init uml_ncpus_setup(char *line, int *add)
 {
index 5294533..87c3aa0 100644 (file)
@@ -122,6 +122,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
                return(-EINVAL);
        }
        *fd_out = ((int *) CMSG_DATA(cmsg))[0];
+       os_set_exec_close(*fd_out, 1);
        return(0);
 }
 
@@ -137,7 +138,8 @@ static int tuntap_open(void *data)
                return(err);
 
        if(pri->fixed_config){
-               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
+               pri->fd = os_open_file("/dev/net/tun",
+                                      of_cloexec(of_rdwr(OPENFLAGS())), 0);
                if(pri->fd < 0){
                        printk("Failed to open /dev/net/tun, err = %d\n",
                               -pri->fd);
index 9890e90..fbb080c 100644 (file)
@@ -60,7 +60,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
 
        multi_count++;
 
-       get_safe_registers(regs);
+       get_safe_registers(regs, NULL);
        regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
                ((unsigned long) &batch_syscall_stub -
                 (unsigned long) &__syscall_stub_start);
index 120a21c..bbf34cb 100644 (file)
@@ -310,16 +310,12 @@ void userspace(union uml_pt_regs *regs)
                }
        }
 }
-#define INIT_JMP_NEW_THREAD 0
-#define INIT_JMP_REMOVE_SIGSTACK 1
-#define INIT_JMP_CALLBACK 2
-#define INIT_JMP_HALT 3
-#define INIT_JMP_REBOOT 4
 
 int copy_context_skas0(unsigned long new_stack, int pid)
 {
        int err;
-       unsigned long regs[MAX_REG_NR];
+       unsigned long regs[HOST_FRAME_SIZE];
+       unsigned long fp_regs[HOST_FP_SIZE];
        unsigned long current_stack = current_stub_stack();
        struct stub_data *data = (struct stub_data *) current_stack;
        struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -334,7 +330,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
                                      .timer    = ((struct itimerval)
                                                    { { 0, 1000000 / hz() },
                                                      { 0, 1000000 / hz() }})});
-       get_safe_registers(regs);
+       get_safe_registers(regs, fp_regs);
 
        /* Set parent's instruction pointer to start of clone-stub */
        regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
@@ -350,6 +346,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
                panic("copy_context_skas0 : PTRACE_SETREGS failed, "
                      "pid = %d, errno = %d\n", pid, errno);
 
+       err = ptrace_setfpregs(pid, fp_regs);
+       if(err < 0)
+               panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
+                     "pid = %d, errno = %d\n", pid, errno);
+
        /* set a well known return code for detection of child write failure */
        child_data->err = 12345678;
 
@@ -457,6 +458,12 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
        set_signals(flags);
 }
 
+#define INIT_JMP_NEW_THREAD 0
+#define INIT_JMP_REMOVE_SIGSTACK 1
+#define INIT_JMP_CALLBACK 2
+#define INIT_JMP_HALT 3
+#define INIT_JMP_REBOOT 4
+
 void thread_wait(void *sw, void *fb)
 {
        sigjmp_buf buf, **switch_buf = sw, *fork_buf;
index 6c5b17e..829d6b0 100644 (file)
@@ -49,6 +49,7 @@ static int ptrace_child(void *arg)
        int pid = os_getpid(), ppid = getppid();
        int sc_result;
 
+       change_sig(SIGWINCH, 0);
        if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
                perror("ptrace");
                os_kill_process(pid, 0);
index aee4812..7a6f6b9 100644 (file)
@@ -122,9 +122,12 @@ void init_registers(int pid)
                      err);
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
        memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+       if(fp_regs != NULL)
+               memcpy(fp_regs, exec_fp_regs,
+                      HOST_FP_SIZE * sizeof(unsigned long));
 }
 
 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
index 4b638df..001941f 100644 (file)
@@ -70,9 +70,12 @@ void init_registers(int pid)
                      err);
 }
 
-void get_safe_registers(unsigned long *regs)
+void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
 {
        memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+       if(fp_regs != NULL)
+               memcpy(fp_regs, exec_fp_regs,
+                      HOST_FP_SIZE * sizeof(unsigned long));
 }
 
 void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
index 12e404c..b5f9c33 100644 (file)
@@ -24,6 +24,13 @@ int ptrace_setregs(long pid, unsigned long *regs)
        return(0);
 }
 
+int ptrace_setfpregs(long pid, unsigned long *regs)
+{
+       if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0)
+               return -errno;
+       return 0;
+}
+
 void ptrace_pokeuser(unsigned long addr, unsigned long data)
 {
        panic("ptrace_pokeuser");
index 5a585bf..7bd54a9 100644 (file)
@@ -57,7 +57,7 @@ void foo(void)
 #endif
 
        DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE);
-       DEFINE(HOST_FP_SIZE, 0);
+       DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
        DEFINE(HOST_XFP_SIZE, 0);
        DEFINE_LONGS(HOST_RBX, RBX);
        DEFINE_LONGS(HOST_RCX, RCX);
index 067c0f4..ada4535 100644 (file)
@@ -685,6 +685,9 @@ ia32_sys_call_table:
        .quad sys_readlinkat            /* 305 */
        .quad sys_fchmodat
        .quad sys_faccessat
+       .quad sys_ni_syscall            /* pselect6 for now */
+       .quad sys_ni_syscall            /* ppoll for now */
+       .quad sys_unshare               /* 310 */
 ia32_syscall_end:              
        .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
                .quad ni_syscall
index 363db5a..9435ab7 100644 (file)
@@ -94,7 +94,6 @@ unsigned long saved_video_mode;
 /*
  * Setup options
  */
-struct drive_info_struct { char dummy[32]; } drive_info;
 struct screen_info screen_info;
 struct sys_desc_table_struct {
        unsigned short length;
@@ -572,7 +571,6 @@ void __init setup_arch(char **cmdline_p)
        unsigned long kernel_end;
 
        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-       drive_info = DRIVE_INFO;
        screen_info = SCREEN_INFO;
        edid_info = EDID_INFO;
        saved_video_mode = SAVED_VIDEO_MODE;
index a28756e..67e4e28 100644 (file)
@@ -59,6 +59,7 @@
 #include <asm/nmi.h>
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
+#include <asm/numa.h>
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
@@ -890,6 +891,7 @@ do_rest:
        if (boot_error) {
                cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
                clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+               clear_node_cpumask(cpu); /* was set by numa_add_cpu */
                cpu_clear(cpu, cpu_present_map);
                cpu_clear(cpu, cpu_possible_map);
                x86_cpu_to_apicid[cpu] = BAD_APICID;
@@ -1187,6 +1189,7 @@ void remove_cpu_from_maps(void)
        cpu_clear(cpu, cpu_callout_map);
        cpu_clear(cpu, cpu_callin_map);
        clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+       clear_node_cpumask(cpu);
 }
 
 int __cpu_disable(void)
index c0844bf..dba7237 100644 (file)
@@ -748,7 +748,7 @@ static __init int late_hpet_init(void)
         * Timer0 and Timer1 is used by platform.
         */
        hd.hd_phys_address = vxtime.hpet_address;
-       hd.hd_address = (void *)fix_to_virt(FIX_HPET_BASE);
+       hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
        hd.hd_nirqs = ntimer;
        hd.hd_flags = HPET_DATA_PLATFORM;
        hpet_reserve_timer(&hd, 0);
index b614d54..3496abc 100644 (file)
@@ -39,11 +39,6 @@ extern void __write_lock_failed(rwlock_t *rw);
 extern void __read_lock_failed(rwlock_t *rw);
 #endif
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
 //EXPORT_SYMBOL(dump_fpu);
index b4a3fe4..18f371f 100644 (file)
@@ -49,7 +49,7 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus)
                return pci_mmcfg_virt[0].virt;
 
        /* Fall back to type 0 */
-       return 0;
+       return NULL;
 }
 
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
index 2fc269f..24b702d 100644 (file)
@@ -293,7 +293,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
 
        rq->flags &= ~REQ_STARTED;
 
-       __elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE, 0);
+       elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
 }
 
 static void elv_drain_elevator(request_queue_t *q)
@@ -310,41 +310,11 @@ static void elv_drain_elevator(request_queue_t *q)
        }
 }
 
-void __elv_add_request(request_queue_t *q, struct request *rq, int where,
-                      int plug)
+void elv_insert(request_queue_t *q, struct request *rq, int where)
 {
        struct list_head *pos;
        unsigned ordseq;
 
-       if (q->ordcolor)
-               rq->flags |= REQ_ORDERED_COLOR;
-
-       if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
-               /*
-                * toggle ordered color
-                */
-               if (blk_barrier_rq(rq))
-                       q->ordcolor ^= 1;
-
-               /*
-                * barriers implicitly indicate back insertion
-                */
-               if (where == ELEVATOR_INSERT_SORT)
-                       where = ELEVATOR_INSERT_BACK;
-
-               /*
-                * this request is scheduling boundary, update end_sector
-                */
-               if (blk_fs_request(rq)) {
-                       q->end_sector = rq_end_sector(rq);
-                       q->boundary_rq = rq;
-               }
-       } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
-               where = ELEVATOR_INSERT_BACK;
-
-       if (plug)
-               blk_plug_device(q);
-
        rq->q = q;
 
        switch (where) {
@@ -425,6 +395,42 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
        }
 }
 
+void __elv_add_request(request_queue_t *q, struct request *rq, int where,
+                      int plug)
+{
+       if (q->ordcolor)
+               rq->flags |= REQ_ORDERED_COLOR;
+
+       if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
+               /*
+                * toggle ordered color
+                */
+               if (blk_barrier_rq(rq))
+                       q->ordcolor ^= 1;
+
+               /*
+                * barriers implicitly indicate back insertion
+                */
+               if (where == ELEVATOR_INSERT_SORT)
+                       where = ELEVATOR_INSERT_BACK;
+
+               /*
+                * this request is scheduling boundary, update
+                * end_sector
+                */
+               if (blk_fs_request(rq)) {
+                       q->end_sector = rq_end_sector(rq);
+                       q->boundary_rq = rq;
+               }
+       } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
+               where = ELEVATOR_INSERT_BACK;
+
+       if (plug)
+               blk_plug_device(q);
+
+       elv_insert(q, rq, where);
+}
+
 void elv_add_request(request_queue_t *q, struct request *rq, int where,
                     int plug)
 {
index ee5ed98..03d9c82 100644 (file)
@@ -454,7 +454,7 @@ static void queue_flush(request_queue_t *q, unsigned which)
        rq->end_io = end_io;
        q->prepare_flush_fn(q, rq);
 
-       __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+       elv_insert(q, rq, ELEVATOR_INSERT_FRONT);
 }
 
 static inline struct request *start_ordered(request_queue_t *q,
@@ -490,7 +490,7 @@ static inline struct request *start_ordered(request_queue_t *q,
        else
                q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH;
 
-       __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+       elv_insert(q, rq, ELEVATOR_INSERT_FRONT);
 
        if (q->ordered & QUEUE_ORDERED_PREFLUSH) {
                queue_flush(q, QUEUE_ORDERED_PREFLUSH);
index cc72210..24f7af9 100644 (file)
@@ -310,6 +310,8 @@ static int sg_io(struct file *file, request_queue_t *q,
        if (!rq->timeout)
                rq->timeout = BLK_DEFAULT_TIMEOUT;
 
+       rq->retries = 0;
+
        start_time = jiffies;
 
        /* ignore return value. All information is passed back to caller
@@ -427,6 +429,7 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
        rq->data = buffer;
        rq->data_len = bytes;
        rq->flags |= REQ_BLOCK_PC;
+       rq->retries = 0;
 
        blk_execute_rq(q, bd_disk, rq, 0);
        err = rq->errors & 0xff;        /* only 8 bit SCSI status */
index 47ac90e..2953e2c 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
-#include <asm/bug.h>
 #include <asm/scatterlist.h>
 #include "internal.h"
 #include "scatterwalk.h"
index e3b548d..5735b38 100644 (file)
@@ -19,6 +19,10 @@ extern void bus_remove_driver(struct device_driver *);
 extern void driver_detach(struct device_driver * drv);
 extern int driver_probe_device(struct device_driver *, struct device *);
 
+extern void sysdev_shutdown(void);
+extern int sysdev_suspend(pm_message_t state);
+extern int sysdev_resume(void);
+
 static inline struct class_device *to_class_dev(struct kobject *obj)
 {
        return container_of(obj, struct class_device, kobj);
index 29f6af5..c314156 100644 (file)
@@ -133,6 +133,8 @@ static struct kobj_type ktype_bus = {
 decl_subsys(bus, &ktype_bus, NULL);
 
 
+#ifdef CONFIG_HOTPLUG
+
 /* Manually detach a device from its associated driver. */
 static int driver_helper(struct device *dev, void *data)
 {
@@ -193,6 +195,7 @@ static ssize_t driver_bind(struct device_driver *drv,
 }
 static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
 
+#endif
 
 static struct device * next_device(struct klist_iter * i)
 {
index d1a0522..105a0d6 100644 (file)
@@ -303,7 +303,7 @@ static int block_size_init(void)
  */
 #ifdef CONFIG_ARCH_MEMORY_PROBE
 static ssize_t
-memory_probe_store(struct class *class, const char __user *buf, size_t count)
+memory_probe_store(struct class *class, const char *buf, size_t count)
 {
        u64 phys_addr;
        int ret;
index 0a7aa07..317edbf 100644 (file)
@@ -9,10 +9,9 @@
  */
 
 #include <linux/device.h>
+#include "../base.h"
 #include "power.h"
 
-extern int sysdev_resume(void);
-
 
 /**
  *     resume_device - Restore state for one device.
index c2475f3..8826a5b 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/device.h>
 #include <asm/semaphore.h>
 
+#include "../base.h"
 #include "power.h"
 
 #define to_dev(node) container_of(node, struct device, kobj.entry)
@@ -28,7 +29,6 @@ extern struct subsystem devices_subsys;
  * they only get one called once when interrupts are disabled.
  */
 
-extern int sysdev_shutdown(void);
 
 /**
  * device_shutdown - call ->shutdown() on each device to shutdown.
index 5050176..8660779 100644 (file)
@@ -9,10 +9,9 @@
  */
 
 #include <linux/device.h>
+#include "../base.h"
 #include "power.h"
 
-extern int sysdev_suspend(pm_message_t 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
index f3a0c56..40d7242 100644 (file)
 
 static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
-       return sprintf(buf, "%u\n", dev->power.power_state.event);
+       if (dev->power.power_state.event)
+               return sprintf(buf, "2\n");
+       else
+               return sprintf(buf, "0\n");
 }
 
 static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
 {
        pm_message_t state;
-       char * rest;
-       int error = 0;
+       int error = -EINVAL;
 
-       state.event = simple_strtoul(buf, &rest, 10);
-       if (*rest)
-               return -EINVAL;
-       if (state.event)
+       state.event = PM_EVENT_SUSPEND;
+       /* Older apps expected to write "3" here - confused with PCI D3 */
+       if ((n == 1) && !strcmp(buf, "3"))
                error = dpm_runtime_suspend(dev, state);
-       else
+
+       if ((n == 1) && !strcmp(buf, "2"))
+               error = dpm_runtime_suspend(dev, state);
+
+       if ((n == 1) && !strcmp(buf, "0")) {
                dpm_runtime_resume(dev);
+               error = 0;
+       }
+
        return error ? error : n;
 }
 
index 66ed8f2..6fc23ab 100644 (file)
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/pm.h>
+#include <linux/device.h>
 #include <asm/semaphore.h>
 
+#include "base.h"
+
 extern struct subsystem devices_subsys;
 
 #define to_sysdev(k) container_of(k, struct sys_device, kobj)
index 193446e..e276172 100644 (file)
@@ -42,8 +42,6 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
-#include <asm/bug.h>
-
 #include <asm/vio.h>
 #include <asm/scatterlist.h>
 #include <asm/iseries/hv_types.h>
index 4c67727..05ba410 100644 (file)
@@ -222,7 +222,7 @@ config SYNCLINKMP
 
 config SYNCLINK_GT
        tristate "SyncLink GT/AC support"
-       depends on SERIAL_NONSTANDARD
+       depends on SERIAL_NONSTANDARD && PCI
        help
          Support for SyncLink GT and SyncLink AC families of
          synchronous and asynchronous serial adapters
index 71b8b32..107df9f 100644 (file)
@@ -980,7 +980,7 @@ extern int drm_put_head(drm_head_t * head);
 extern unsigned int drm_debug;
 extern unsigned int drm_cards_limit;
 extern drm_head_t **drm_heads;
-extern struct drm_sysfs_class *drm_class;
+extern struct class *drm_class;
 extern struct proc_dir_entry *drm_proc_root;
 
                                /* Proc support (drm_proc.h) */
@@ -1011,11 +1011,9 @@ extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
 extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah);
 
                               /* sysfs support (drm_sysfs.c) */
-struct drm_sysfs_class;
-extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner,
-                                               char *name);
-extern void drm_sysfs_destroy(struct drm_sysfs_class *cs);
-extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
+extern struct class *drm_sysfs_create(struct module *owner, char *name);
+extern void drm_sysfs_destroy(struct class *cs);
+extern struct class_device *drm_sysfs_device_add(struct class *cs,
                                                 drm_head_t *head);
 extern void drm_sysfs_device_remove(struct class_device *class_dev);
 
index 7a9263f..68073e1 100644 (file)
@@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444);
 module_param_named(debug, drm_debug, int, 0600);
 
 drm_head_t **drm_heads;
-struct drm_sysfs_class *drm_class;
+struct class *drm_class;
 struct proc_dir_entry *drm_proc_root;
 
 static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
index 68e43dd..0b9f98a 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * drm_sysfs.c - Modifications to drm_sysfs_class.c to support
  *               extra sysfs attribute from DRM. Normal drm_sysfs_class
 #include "drm_core.h"
 #include "drmP.h"
 
-struct drm_sysfs_class {
-       struct class_device_attribute attr;
-       struct class class;
-};
-#define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class)
-
-struct simple_dev {
-       dev_t dev;
-       struct class_device class_dev;
-};
-#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
-
-static void release_simple_dev(struct class_device *class_dev)
-{
-       struct simple_dev *s_dev = to_simple_dev(class_dev);
-       kfree(s_dev);
-}
-
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
-       struct simple_dev *s_dev = to_simple_dev(class_dev);
-       return print_dev_t(buf, s_dev->dev);
-}
-
-static void drm_sysfs_class_release(struct class *class)
-{
-       struct drm_sysfs_class *cs = to_drm_sysfs_class(class);
-       kfree(cs);
-}
-
 /* Display the version of drm_core. This doesn't work right in current design */
 static ssize_t version_show(struct class *dev, char *buf)
 {
@@ -69,38 +40,16 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
  * Note, the pointer created here is to be destroyed when finished by making a
  * call to drm_sysfs_destroy().
  */
-struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
+struct class *drm_sysfs_create(struct module *owner, char *name)
 {
-       struct drm_sysfs_class *cs;
-       int retval;
-
-       cs = kmalloc(sizeof(*cs), GFP_KERNEL);
-       if (!cs) {
-               retval = -ENOMEM;
-               goto error;
-       }
-       memset(cs, 0x00, sizeof(*cs));
-
-       cs->class.name = name;
-       cs->class.class_release = drm_sysfs_class_release;
-       cs->class.release = release_simple_dev;
-
-       cs->attr.attr.name = "dev";
-       cs->attr.attr.mode = S_IRUGO;
-       cs->attr.attr.owner = owner;
-       cs->attr.show = show_dev;
-       cs->attr.store = NULL;
-
-       retval = class_register(&cs->class);
-       if (retval)
-               goto error;
-       class_create_file(&cs->class, &class_attr_version);
-
-       return cs;
-
-      error:
-       kfree(cs);
-       return ERR_PTR(retval);
+       struct class *class;
+
+       class = class_create(owner, name);
+       if (!class)
+               return class;
+
+       class_create_file(class, &class_attr_version);
+       return class;
 }
 
 /**
@@ -110,12 +59,13 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name)
  * Note, the pointer to be destroyed must have been created with a call to
  * drm_sysfs_create().
  */
-void drm_sysfs_destroy(struct drm_sysfs_class *cs)
+void drm_sysfs_destroy(struct class *class)
 {
-       if ((cs == NULL) || (IS_ERR(cs)))
+       if ((class == NULL) || (IS_ERR(class)))
                return;
 
-       class_unregister(&cs->class);
+       class_remove_file(class, &class_attr_version);
+       class_destroy(class);
 }
 
 static ssize_t show_dri(struct class_device *class_device, char *buf)
@@ -132,7 +82,7 @@ static struct class_device_attribute class_device_attrs[] = {
 
 /**
  * drm_sysfs_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct drm_sysfs_class that this device should be registered to.
+ * @cs: pointer to the struct class 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
@@ -141,46 +91,26 @@ static struct class_device_attribute class_device_attrs[] = {
  * class.  A "dev" file will be created, showing the dev_t for the device.  The
  * pointer to the struct class_device will be returned from the call.  Any further
  * sysfs files that might be required can be created using this pointer.
- * Note: the struct drm_sysfs_class passed to this function must have previously been
+ * Note: the struct class passed to this function must have previously been
  * created with a call to drm_sysfs_create().
  */
-struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs,
-                                         drm_head_t *head)
+struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head)
 {
-       struct simple_dev *s_dev = NULL;
-       int i, retval;
-
-       if ((cs == NULL) || (IS_ERR(cs))) {
-               retval = -ENODEV;
-               goto error;
-       }
-
-       s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
-       if (!s_dev) {
-               retval = -ENOMEM;
-               goto error;
-       }
-       memset(s_dev, 0x00, sizeof(*s_dev));
-
-       s_dev->dev = MKDEV(DRM_MAJOR, head->minor);
-       s_dev->class_dev.dev = &(head->dev->pdev)->dev;
-       s_dev->class_dev.class = &cs->class;
+       struct class_device *class_dev;
+       int i;
 
-       snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor);
-       retval = class_device_register(&s_dev->class_dev);
-       if (retval)
-               goto error;
+       class_dev = class_device_create(cs, NULL,
+                                       MKDEV(DRM_MAJOR, head->minor),
+                                       &(head->dev->pdev)->dev,
+                                       "card%d", head->minor);
+       if (!class_dev)
+               return NULL;
 
-       class_device_create_file(&s_dev->class_dev, &cs->attr);
-       class_set_devdata(&s_dev->class_dev, head);
+       class_set_devdata(class_dev, head);
 
        for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]);
-       return &s_dev->class_dev;
-
-error:
-       kfree(s_dev);
-       return ERR_PTR(retval);
+               class_device_create_file(class_dev, &class_device_attrs[i]);
+       return class_dev;
 }
 
 /**
@@ -192,10 +122,9 @@ error:
  */
 void drm_sysfs_device_remove(struct class_device *class_dev)
 {
-       struct simple_dev *s_dev = to_simple_dev(class_dev);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++)
-               class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]);
-       class_device_unregister(&s_dev->class_dev);
+               class_device_remove_file(class_dev, &class_device_attrs[i]);
+       class_device_unregister(class_dev);
 }
index 80a5b84..fee68cc 100644 (file)
 
 #include <linux/serial.h>
 #include <linux/generic_serial.h>
+#include <linux/tty_flip.h>
 
 #include "ser_a2232.h"
 #include "ser_a2232fw.h"
index 7a4dfb9..837b1ec 100644 (file)
@@ -92,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t epx_c3_write(struct file *file, const char *data,
+static ssize_t epx_c3_write(struct file *file, const char __user *data,
                        size_t len, loff_t *ppos)
 {
        /* Refresh the timer. */
@@ -105,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
                        unsigned int cmd, unsigned long arg)
 {
        int options, retval = -EINVAL;
+       int __user *argp = (void __user *)arg;
        static struct watchdog_info ident = {
                .options                = WDIOF_KEEPALIVEPING |
                                          WDIOF_MAGICCLOSE,
@@ -114,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
-               if (copy_to_user((struct watchdog_info *)arg,
-                                &ident, sizeof(ident)))
+               if (copy_to_user(argp, &ident, sizeof(ident)))
                        return -EFAULT;
                return 0;
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-               return put_user(0,(int *)arg);
+               return put_user(0, argp);
        case WDIOC_KEEPALIVE:
                epx_c3_pet();
                return 0;
        case WDIOC_GETTIMEOUT:
-               return put_user(WATCHDOG_TIMEOUT,(int *)arg);
-       case WDIOC_SETOPTIONS: {
-               if (get_user(options, (int *)arg))
+               return put_user(WATCHDOG_TIMEOUT, argp);
+       case WDIOC_SETOPTIONS:
+               if (get_user(options, argp))
                        return -EFAULT;
 
                if (options & WDIOS_DISABLECARD) {
@@ -141,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file,
                }
 
                return retval;
-       }
        default:
                return -ENOIOCTLCMD;
        }
index 009c08f..1991f94 100644 (file)
@@ -159,7 +159,7 @@ enum i82875p_chips {
 
 struct i82875p_pvt {
        struct pci_dev *ovrfl_pdev;
-       void *ovrfl_window;
+       void __iomem *ovrfl_window;
 };
 
 
index c582959..7230d4e 100644 (file)
@@ -113,6 +113,16 @@ config SENSORS_DS1621
          This driver can also be built as a module.  If so, the module
          will be called ds1621.
 
+config SENSORS_F71805F
+       tristate "Fintek F71805F/FG"
+       depends on HWMON && EXPERIMENTAL
+       help
+         If you say yes here you get support for hardware monitoring
+         features of the Fintek F71805F/FG chips.
+
+         This driver can also be built as a module.  If so, the module
+         will be called f71805f.
+
 config SENSORS_FSCHER
        tristate "FSC Hermes"
        depends on HWMON && I2C && EXPERIMENTAL
index 06d4a1d..fbdb8d9 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
 obj-$(CONFIG_SENSORS_ADM9240)  += adm9240.o
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
 obj-$(CONFIG_SENSORS_DS1621)   += ds1621.o
+obj-$(CONFIG_SENSORS_F71805F)  += f71805f.o
 obj-$(CONFIG_SENSORS_FSCHER)   += fscher.o
 obj-$(CONFIG_SENSORS_FSCPOS)   += fscpos.o
 obj-$(CONFIG_SENSORS_GL518SM)  += gl518sm.o
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
new file mode 100644 (file)
index 0000000..e029e0a
--- /dev/null
@@ -0,0 +1,908 @@
+/*
+ * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated
+ *             hardware monitoring features
+ * Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+ *
+ * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates
+ * complete hardware monitoring features: voltage, fan and temperature
+ * sensors, and manual and automatic fan speed control.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <asm/io.h>
+
+static struct platform_device *pdev;
+
+#define DRVNAME "f71805f"
+
+/*
+ * Super-I/O constants and functions
+ */
+
+#define F71805F_LD_HWM         0x04
+
+#define SIO_REG_LDSEL          0x07    /* Logical device select */
+#define SIO_REG_DEVID          0x20    /* Device ID (2 bytes) */
+#define SIO_REG_DEVREV         0x22    /* Device revision */
+#define SIO_REG_MANID          0x23    /* Fintek ID (2 bytes) */
+#define SIO_REG_ENABLE         0x30    /* Logical device enable */
+#define SIO_REG_ADDR           0x60    /* Logical device address (2 bytes) */
+
+#define SIO_FINTEK_ID          0x1934
+#define SIO_F71805F_ID         0x0406
+
+static inline int
+superio_inb(int base, int reg)
+{
+       outb(reg, base);
+       return inb(base + 1);
+}
+
+static int
+superio_inw(int base, int reg)
+{
+       int val;
+       outb(reg++, base);
+       val = inb(base + 1) << 8;
+       outb(reg, base);
+       val |= inb(base + 1);
+       return val;
+}
+
+static inline void
+superio_select(int base, int ld)
+{
+       outb(SIO_REG_LDSEL, base);
+       outb(ld, base + 1);
+}
+
+static inline void
+superio_enter(int base)
+{
+       outb(0x87, base);
+       outb(0x87, base);
+}
+
+static inline void
+superio_exit(int base)
+{
+       outb(0xaa, base);
+}
+
+/*
+ * ISA constants
+ */
+
+#define REGION_LENGTH          2
+#define ADDR_REG_OFFSET                0
+#define DATA_REG_OFFSET                1
+
+static struct resource f71805f_resource __initdata = {
+       .flags  = IORESOURCE_IO,
+};
+
+/*
+ * Registers
+ */
+
+/* in nr from 0 to 8 (8-bit values) */
+#define F71805F_REG_IN(nr)             (0x10 + (nr))
+#define F71805F_REG_IN_HIGH(nr)                (0x40 + 2 * (nr))
+#define F71805F_REG_IN_LOW(nr)         (0x41 + 2 * (nr))
+/* fan nr from 0 to 2 (12-bit values, two registers) */
+#define F71805F_REG_FAN(nr)            (0x20 + 2 * (nr))
+#define F71805F_REG_FAN_LOW(nr)                (0x28 + 2 * (nr))
+#define F71805F_REG_FAN_CTRL(nr)       (0x60 + 16 * (nr))
+/* temp nr from 0 to 2 (8-bit values) */
+#define F71805F_REG_TEMP(nr)           (0x1B + (nr))
+#define F71805F_REG_TEMP_HIGH(nr)      (0x54 + 2 * (nr))
+#define F71805F_REG_TEMP_HYST(nr)      (0x55 + 2 * (nr))
+#define F71805F_REG_TEMP_MODE          0x01
+
+#define F71805F_REG_START              0x00
+/* status nr from 0 to 2 */
+#define F71805F_REG_STATUS(nr)         (0x36 + (nr))
+
+/*
+ * Data structures and manipulation thereof
+ */
+
+struct f71805f_data {
+       unsigned short addr;
+       const char *name;
+       struct semaphore lock;
+       struct class_device *class_dev;
+
+       struct semaphore update_lock;
+       char valid;             /* !=0 if following fields are valid */
+       unsigned long last_updated;     /* In jiffies */
+       unsigned long last_limits;      /* In jiffies */
+
+       /* Register values */
+       u8 in[9];
+       u8 in_high[9];
+       u8 in_low[9];
+       u16 fan[3];
+       u16 fan_low[3];
+       u8 fan_enabled;         /* Read once at init time */
+       u8 temp[3];
+       u8 temp_high[3];
+       u8 temp_hyst[3];
+       u8 temp_mode;
+       u8 alarms[3];
+};
+
+static inline long in_from_reg(u8 reg)
+{
+       return (reg * 8);
+}
+
+/* The 2 least significant bits are not used */
+static inline u8 in_to_reg(long val)
+{
+       if (val <= 0)
+               return 0;
+       if (val >= 2016)
+               return 0xfc;
+       return (((val + 16) / 32) << 2);
+}
+
+/* in0 is downscaled by a factor 2 internally */
+static inline long in0_from_reg(u8 reg)
+{
+       return (reg * 16);
+}
+
+static inline u8 in0_to_reg(long val)
+{
+       if (val <= 0)
+               return 0;
+       if (val >= 4032)
+               return 0xfc;
+       return (((val + 32) / 64) << 2);
+}
+
+/* The 4 most significant bits are not used */
+static inline long fan_from_reg(u16 reg)
+{
+       reg &= 0xfff;
+       if (!reg || reg == 0xfff)
+               return 0;
+       return (1500000 / reg);
+}
+
+static inline u16 fan_to_reg(long rpm)
+{
+       /* If the low limit is set below what the chip can measure,
+          store the largest possible 12-bit value in the registers,
+          so that no alarm will ever trigger. */
+       if (rpm < 367)
+               return 0xfff;
+       return (1500000 / rpm);
+}
+
+static inline long temp_from_reg(u8 reg)
+{
+       return (reg * 1000);
+}
+
+static inline u8 temp_to_reg(long val)
+{
+       if (val < 0)
+               val = 0;
+       else if (val > 1000 * 0xff)
+               val = 0xff;
+       return ((val + 500) / 1000);
+}
+
+/*
+ * Device I/O access
+ */
+
+static u8 f71805f_read8(struct f71805f_data *data, u8 reg)
+{
+       u8 val;
+
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       val = inb(data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+
+       return val;
+}
+
+static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
+{
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       outb(val, data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+}
+
+/* It is important to read the MSB first, because doing so latches the
+   value of the LSB, so we are sure both bytes belong to the same value. */
+static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
+{
+       u16 val;
+
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       val = inb(data->addr + DATA_REG_OFFSET) << 8;
+       outb(++reg, data->addr + ADDR_REG_OFFSET);
+       val |= inb(data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+
+       return val;
+}
+
+static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
+{
+       down(&data->lock);
+       outb(reg, data->addr + ADDR_REG_OFFSET);
+       outb(val >> 8, data->addr + DATA_REG_OFFSET);
+       outb(++reg, data->addr + ADDR_REG_OFFSET);
+       outb(val & 0xff, data->addr + DATA_REG_OFFSET);
+       up(&data->lock);
+}
+
+static struct f71805f_data *f71805f_update_device(struct device *dev)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       int nr;
+
+       down(&data->update_lock);
+
+       /* Limit registers cache is refreshed after 60 seconds */
+       if (time_after(jiffies, data->last_updated + 60 * HZ)
+        || !data->valid) {
+               for (nr = 0; nr < 9; nr++) {
+                       data->in_high[nr] = f71805f_read8(data,
+                                           F71805F_REG_IN_HIGH(nr));
+                       data->in_low[nr] = f71805f_read8(data,
+                                          F71805F_REG_IN_LOW(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       if (data->fan_enabled & (1 << nr))
+                               data->fan_low[nr] = f71805f_read16(data,
+                                                   F71805F_REG_FAN_LOW(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       data->temp_high[nr] = f71805f_read8(data,
+                                             F71805F_REG_TEMP_HIGH(nr));
+                       data->temp_hyst[nr] = f71805f_read8(data,
+                                             F71805F_REG_TEMP_HYST(nr));
+               }
+               data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE);
+
+               data->last_limits = jiffies;
+       }
+
+       /* Measurement registers cache is refreshed after 1 second */
+       if (time_after(jiffies, data->last_updated + HZ)
+        || !data->valid) {
+               for (nr = 0; nr < 9; nr++) {
+                       data->in[nr] = f71805f_read8(data,
+                                      F71805F_REG_IN(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       if (data->fan_enabled & (1 << nr))
+                               data->fan[nr] = f71805f_read16(data,
+                                               F71805F_REG_FAN(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       data->temp[nr] = f71805f_read8(data,
+                                        F71805F_REG_TEMP(nr));
+               }
+               for (nr = 0; nr < 3; nr++) {
+                       data->alarms[nr] = f71805f_read8(data,
+                                          F71805F_REG_STATUS(nr));
+               }
+
+               data->last_updated = jiffies;
+               data->valid = 1;
+       }
+
+       up(&data->update_lock);
+
+       return data;
+}
+
+/*
+ * Sysfs interface
+ */
+
+static ssize_t show_in0(struct device *dev, struct device_attribute *devattr,
+                       char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in[0]));
+}
+
+static ssize_t show_in0_max(struct device *dev, struct device_attribute
+                           *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0]));
+}
+
+static ssize_t show_in0_min(struct device *dev, struct device_attribute
+                           *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0]));
+}
+
+static ssize_t set_in0_max(struct device *dev, struct device_attribute
+                          *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_high[0] = in0_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t set_in0_min(struct device *dev, struct device_attribute
+                          *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_low[0] = in0_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL);
+static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max);
+static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min);
+
+static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
+                      char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", in_from_reg(data->in[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev, struct device_attribute
+                          *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev, struct device_attribute
+                          *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr]));
+}
+
+static ssize_t set_in_max(struct device *dev, struct device_attribute
+                         *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_high[nr] = in_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute
+                         *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->in_low[nr] = in_to_reg(val);
+       f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+#define sysfs_in(offset)                                       \
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,         \
+               show_in, NULL, offset);                         \
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+               show_in_max, set_in_max, offset);               \
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+               show_in_min, set_in_min, offset)
+
+sysfs_in(1);
+sysfs_in(2);
+sysfs_in(3);
+sysfs_in(4);
+sysfs_in(5);
+sysfs_in(6);
+sysfs_in(7);
+sysfs_in(8);
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
+                       char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr]));
+}
+
+static ssize_t show_fan_min(struct device *dev, struct device_attribute
+                           *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr]));
+}
+
+static ssize_t set_fan_min(struct device *dev, struct device_attribute
+                          *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->fan_low[nr] = fan_to_reg(val);
+       f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+#define sysfs_fan(offset)                                      \
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,                \
+               show_fan, NULL, offset - 1);                    \
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,        \
+               show_fan_min, set_fan_min, offset - 1)
+
+sysfs_fan(1);
+sysfs_fan(2);
+sysfs_fan(3);
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
+                        char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr]));
+}
+
+static ssize_t show_temp_max(struct device *dev, struct device_attribute
+                            *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr]));
+}
+
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute
+                             *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr]));
+}
+
+static ssize_t show_temp_type(struct device *dev, struct device_attribute
+                             *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+
+       /* 3 is diode, 4 is thermistor */
+       return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4);
+}
+
+static ssize_t set_temp_max(struct device *dev, struct device_attribute
+                           *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->temp_high[nr] = temp_to_reg(val);
+       f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute
+                            *devattr, const char *buf, size_t count)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int nr = attr->index;
+       long val = simple_strtol(buf, NULL, 10);
+
+       down(&data->update_lock);
+       data->temp_hyst[nr] = temp_to_reg(val);
+       f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
+       up(&data->update_lock);
+
+       return count;
+}
+
+#define sysfs_temp(offset)                                             \
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,               \
+               show_temp, NULL, offset - 1);                           \
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,       \
+               show_temp_max, set_temp_max, offset - 1);               \
+static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR,  \
+               show_temp_hyst, set_temp_hyst, offset - 1);             \
+static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO,                        \
+               show_temp_type, NULL, offset - 1)
+
+sysfs_temp(1);
+sysfs_temp(2);
+sysfs_temp(3);
+
+static ssize_t show_alarms_in(struct device *dev, struct device_attribute
+                             *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%d\n", data->alarms[0] |
+                                   ((data->alarms[1] & 0x01) << 8));
+}
+
+static ssize_t show_alarms_fan(struct device *dev, struct device_attribute
+                              *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%d\n", data->alarms[2] & 0x07);
+}
+
+static ssize_t show_alarms_temp(struct device *dev, struct device_attribute
+                               *devattr, char *buf)
+{
+       struct f71805f_data *data = f71805f_update_device(dev);
+
+       return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07);
+}
+
+static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL);
+static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL);
+static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL);
+
+static ssize_t show_name(struct device *dev, struct device_attribute
+                        *devattr, char *buf)
+{
+       struct f71805f_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", data->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+/*
+ * Device registration and initialization
+ */
+
+static void __devinit f71805f_init_device(struct f71805f_data *data)
+{
+       u8 reg;
+       int i;
+
+       reg = f71805f_read8(data, F71805F_REG_START);
+       if ((reg & 0x41) != 0x01) {
+               printk(KERN_DEBUG DRVNAME ": Starting monitoring "
+                      "operations\n");
+               f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40);
+       }
+
+       /* Fan monitoring can be disabled. If it is, we won't be polling
+          the register values, and won't create the related sysfs files. */
+       for (i = 0; i < 3; i++) {
+               reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i));
+               if (!(reg & 0x80))
+                       data->fan_enabled |= (1 << i);
+       }
+}
+
+static int __devinit f71805f_probe(struct platform_device *pdev)
+{
+       struct f71805f_data *data;
+       struct resource *res;
+       int err;
+
+       if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Out of memory\n");
+               goto exit;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       data->addr = res->start;
+       init_MUTEX(&data->lock);
+       data->name = "f71805f";
+       init_MUTEX(&data->update_lock);
+
+       platform_set_drvdata(pdev, data);
+
+       data->class_dev = hwmon_device_register(&pdev->dev);
+       if (IS_ERR(data->class_dev)) {
+               err = PTR_ERR(data->class_dev);
+               dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+               goto exit_free;
+       }
+
+       /* Initialize the F71805F chip */
+       f71805f_init_device(data);
+
+       /* Register sysfs interface files */
+       device_create_file(&pdev->dev, &dev_attr_in0_input);
+       device_create_file(&pdev->dev, &dev_attr_in0_max);
+       device_create_file(&pdev->dev, &dev_attr_in0_min);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr);
+       if (data->fan_enabled & (1 << 0)) {
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan1_input.dev_attr);
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan1_min.dev_attr);
+       }
+       if (data->fan_enabled & (1 << 1)) {
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan2_input.dev_attr);
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan2_min.dev_attr);
+       }
+       if (data->fan_enabled & (1 << 2)) {
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan3_input.dev_attr);
+               device_create_file(&pdev->dev,
+                                  &sensor_dev_attr_fan3_min.dev_attr);
+       }
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp1_input.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp2_input.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp3_input.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp1_max_hyst.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp2_max_hyst.dev_attr);
+       device_create_file(&pdev->dev,
+                          &sensor_dev_attr_temp3_max_hyst.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr);
+       device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr);
+       device_create_file(&pdev->dev, &dev_attr_alarms_in);
+       device_create_file(&pdev->dev, &dev_attr_alarms_fan);
+       device_create_file(&pdev->dev, &dev_attr_alarms_temp);
+       device_create_file(&pdev->dev, &dev_attr_name);
+
+       return 0;
+
+exit_free:
+       kfree(data);
+exit:
+       return err;
+}
+
+static int __devexit f71805f_remove(struct platform_device *pdev)
+{
+       struct f71805f_data *data = platform_get_drvdata(pdev);
+
+       platform_set_drvdata(pdev, NULL);
+       hwmon_device_unregister(data->class_dev);
+       kfree(data);
+
+       return 0;
+}
+
+static struct platform_driver f71805f_driver = {
+       .driver = {
+               .owner  = THIS_MODULE,
+               .name   = DRVNAME,
+       },
+       .probe          = f71805f_probe,
+       .remove         = __devexit_p(f71805f_remove),
+};
+
+static int __init f71805f_device_add(unsigned short address)
+{
+       int err;
+
+       pdev = platform_device_alloc(DRVNAME, address);
+       if (!pdev) {
+               err = -ENOMEM;
+               printk(KERN_ERR DRVNAME ": Device allocation failed\n");
+               goto exit;
+       }
+
+       f71805f_resource.start = address;
+       f71805f_resource.end = address + REGION_LENGTH - 1;
+       f71805f_resource.name = pdev->name;
+       err = platform_device_add_resources(pdev, &f71805f_resource, 1);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device resource addition failed "
+                      "(%d)\n", err);
+               goto exit_device_put;
+       }
+
+       err = platform_device_add(pdev);
+       if (err) {
+               printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
+                      err);
+               goto exit_device_put;
+       }
+
+       return 0;
+
+exit_device_put:
+       platform_device_put(pdev);
+exit:
+       return err;
+}
+
+static int __init f71805f_find(int sioaddr, unsigned short *address)
+{
+       int err = -ENODEV;
+       u16 devid;
+
+       superio_enter(sioaddr);
+
+       devid = superio_inw(sioaddr, SIO_REG_MANID);
+       if (devid != SIO_FINTEK_ID)
+               goto exit;
+
+       devid = superio_inw(sioaddr, SIO_REG_DEVID);
+       if (devid != SIO_F71805F_ID) {
+               printk(KERN_INFO DRVNAME ": Unsupported Fintek device, "
+                      "skipping\n");
+               goto exit;
+       }
+
+       superio_select(sioaddr, F71805F_LD_HWM);
+       if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
+               printk(KERN_WARNING DRVNAME ": Device not activated, "
+                      "skipping\n");
+               goto exit;
+       }
+
+       *address = superio_inw(sioaddr, SIO_REG_ADDR);
+       if (*address == 0) {
+               printk(KERN_WARNING DRVNAME ": Base address not set, "
+                      "skipping\n");
+               goto exit;
+       }
+
+       err = 0;
+       printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n",
+              *address, superio_inb(sioaddr, SIO_REG_DEVREV));
+
+exit:
+       superio_exit(sioaddr);
+       return err;
+}
+
+static int __init f71805f_init(void)
+{
+       int err;
+       unsigned short address;
+
+       if (f71805f_find(0x2e, &address)
+        && f71805f_find(0x4e, &address))
+               return -ENODEV;
+
+       err = platform_driver_register(&f71805f_driver);
+       if (err)
+               goto exit;
+
+       /* Sets global pdev as a side effect */
+       err = f71805f_device_add(address);
+       if (err)
+               goto exit_driver;
+
+       return 0;
+
+exit_driver:
+       platform_driver_unregister(&f71805f_driver);
+exit:
+       return err;
+}
+
+static void __exit f71805f_exit(void)
+{
+       platform_device_unregister(pdev);
+       platform_driver_unregister(&f71805f_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("F71805F hardware monitoring driver");
+
+module_init(f71805f_init);
+module_exit(f71805f_exit);
index 0da7c9c..e87d52c 100644 (file)
@@ -45,8 +45,7 @@
 
 
 /* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
-                                       0x2e, 0x2f, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
 static unsigned short isa_address;
 
 /* Insmod parameters */
@@ -830,6 +829,11 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
        if ((err = i2c_attach_client(new_client)))
                goto ERROR2;
 
+       if (!is_isa)
+               dev_info(&new_client->dev, "The I2C interface to IT87xxF "
+                        "hardware monitoring chips is deprecated. Please "
+                        "report if you still rely on it.\n");
+
        /* Check PWM configuration */
        enable_pwm_interface = it87_check_pwm(new_client);
 
index a2f420d..df9e02a 100644 (file)
@@ -87,15 +87,15 @@ static struct i2c_driver lm77_driver = {
 
 /* In the temperature registers, the low 3 bits are not part of the
    temperature values; they are the status bits. */
-static inline u16 LM77_TEMP_TO_REG(int temp)
+static inline s16 LM77_TEMP_TO_REG(int temp)
 {
        int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
-       return (u16)((ntemp / 500) * 8);
+       return (ntemp / 500) * 8;
 }
 
-static inline int LM77_TEMP_FROM_REG(u16 reg)
+static inline int LM77_TEMP_FROM_REG(s16 reg)
 {
-       return ((int)reg / 8) * 500;
+       return (reg / 8) * 500;
 }
 
 /* sysfs stuff */
index b176bf0..a2f6bb6 100644 (file)
@@ -303,10 +303,6 @@ struct w83792d_data {
 static int w83792d_attach_adapter(struct i2c_adapter *adapter);
 static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind);
 static int w83792d_detach_client(struct i2c_client *client);
-
-static int w83792d_read_value(struct i2c_client *client, u8 register);
-static int w83792d_write_value(struct i2c_client *client, u8 register,
-                               u8 value);
 static struct w83792d_data *w83792d_update_device(struct device *dev);
 
 #ifdef DEBUG
@@ -329,6 +325,20 @@ static inline long in_count_from_reg(int nr, struct w83792d_data *data)
        return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03));
 }
 
+/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
+   but the driver only accesses registers in bank 0, so we don't have
+   to switch banks and lock access between switches. */
+static inline int w83792d_read_value(struct i2c_client *client, u8 reg)
+{
+       return i2c_smbus_read_byte_data(client, reg);
+}
+
+static inline int
+w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+       return i2c_smbus_write_byte_data(client, reg, value);
+}
+
 /* following are the sysfs callback functions */
 static ssize_t show_in(struct device *dev, struct device_attribute *attr,
                        char *buf)
@@ -1386,19 +1396,6 @@ w83792d_detach_client(struct i2c_client *client)
        return 0;
 }
 
-/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
-   but the driver only accesses registers in bank 0, so we don't have
-   to switch banks and lock access between switches. */
-static int w83792d_read_value(struct i2c_client *client, u8 reg)
-{
-       return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-       return i2c_smbus_write_byte_data(client, reg, value);
-}
-
 static void
 w83792d_init_client(struct i2c_client *client)
 {
index 938848a..3df3f09 100644 (file)
@@ -202,7 +202,7 @@ EXPORT_SYMBOL(i2c_sibyte_del_bus);
 #ifdef MODULE
 MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
 MODULE_DESCRIPTION("SiByte I2C-Bus algorithm");
-MODULE_PARM(bit_scan, "i");
+module_param(bit_scan, int, 0);
 MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
 MODULE_LICENSE("GPL");
 
index 08d5b8f..ff92735 100644 (file)
@@ -124,6 +124,7 @@ config I2C_I801
            ICH6
            ICH7
            ESB2
+           ICH8
 
          This driver can also be built as a module.  If so, the module
          will be called i2c-i801.
index 1c752dd..8e0f315 100644 (file)
@@ -32,6 +32,7 @@
     ICH6               266A
     ICH7               27DA
     ESB2               269B
+    ICH8               283E
     This driver supports several versions of Intel's I/O Controller Hubs (ICH).
     For SMBus support, they are similar to the PIIX4 and are part
     of Intel's '810' and other chipsets.
@@ -527,6 +528,7 @@ static struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
        { 0, }
 };
 
index 3e5eba9..c63025a 100644 (file)
@@ -121,14 +121,11 @@ static struct i2c_adapter parport_adapter = {
 
 static int __init i2c_parport_init(void)
 {
-       int type_count;
-
-       type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm);
-       if (type < 0 || type >= type_count) {
+       if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
                printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
                type = 0;
        }
-       
+
        if (base == 0) {
                printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE);
                base = DEFAULT_BASE;
@@ -152,7 +149,7 @@ static int __init i2c_parport_init(void)
                release_region(base, 3);
                return -ENODEV;
        }
-       
+
        return 0;
 }
 
index 2854d85..7e2e8cd 100644 (file)
@@ -241,14 +241,11 @@ static struct parport_driver i2c_parport_driver = {
 
 static int __init i2c_parport_init(void)
 {
-       int type_count;
-
-       type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm);
-       if (type < 0 || type >= type_count) {
+       if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) {
                printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type);
                type = 0;
        }
-       
+
        return parport_register_driver(&i2c_parport_driver);
 }
 
index 86e2234..7579f4b 100644 (file)
@@ -861,7 +861,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *r
                decode_ISR(isr);
        }
 
-       if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32))
+       if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog))
                i2c->isrlog[i2c->irqlogidx++] = isr;
 
        show_state(i2c);
index 0ce58b5..1a2c9ab 100644 (file)
@@ -946,6 +946,20 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val
        }
 }
 
+s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
+                                  u8 length, u8 *values)
+{
+       union i2c_smbus_data data;
+
+       if (length > I2C_SMBUS_BLOCK_MAX)
+               length = I2C_SMBUS_BLOCK_MAX;
+       data.block[0] = length;
+       memcpy(data.block + 1, values, length);
+       return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+                             I2C_SMBUS_WRITE, command,
+                             I2C_SMBUS_I2C_BLOCK_DATA, &data);
+}
+
 /* Simulate a SMBus command using the i2c protocol 
    No checking of parameters is done!  */
 static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, 
@@ -1150,6 +1164,7 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data);
 EXPORT_SYMBOL(i2c_smbus_write_word_data);
 EXPORT_SYMBOL(i2c_smbus_write_block_data);
 EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data);
+EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data);
 
 MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
 MODULE_DESCRIPTION("I2C-Bus main module");
index 6c60a9d..09086b8 100644 (file)
@@ -190,7 +190,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
                if (lba48) {
                        task_ioreg_t tasklets[10];
 
-                       pr_debug("%s: LBA=0x%012llx\n", drive->name, block);
+                       pr_debug("%s: LBA=0x%012llx\n", drive->name,
+                                       (unsigned long long)block);
 
                        tasklets[0] = 0;
                        tasklets[1] = 0;
@@ -317,7 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s
 
        pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
                 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
-                block, rq->nr_sectors, (unsigned long)rq->buffer);
+                (unsigned long long)block, rq->nr_sectors,
+                (unsigned long)rq->buffer);
 
        if (hwif->rw_disk)
                hwif->rw_disk(drive, rq);
index e95c429..f6a0596 100644 (file)
@@ -1319,15 +1319,6 @@ static struct class ucm_class = {
        .release = ib_ucm_release_class_dev
 };
 
-static ssize_t show_dev(struct class_device *class_dev, char *buf)
-{
-       struct ib_ucm_device *dev;
-       
-       dev = container_of(class_dev, struct ib_ucm_device, class_dev);
-       return print_dev_t(buf, dev->dev.dev);
-}
-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
-
 static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
 {
        struct ib_ucm_device *dev;
@@ -1364,14 +1355,12 @@ static void ib_ucm_add_one(struct ib_device *device)
 
        ucm_dev->class_dev.class = &ucm_class;
        ucm_dev->class_dev.dev = device->dma_device;
+       ucm_dev->class_dev.devt = ucm_dev->dev.dev;
        snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d",
                 ucm_dev->devnum);
        if (class_device_register(&ucm_dev->class_dev))
                goto err_cdev;
 
-       if (class_device_create_file(&ucm_dev->class_dev,
-                                    &class_device_attr_dev))
-               goto err_class;
        if (class_device_create_file(&ucm_dev->class_dev,
                                     &class_device_attr_ibdev))
                goto err_class;
index 0ef5601..6dfc941 100644 (file)
@@ -351,7 +351,7 @@ config HISAX_ENTERNOW_PCI
 
 config HISAX_AMD7930
        bool "Am7930 (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && SPARC
+       depends on EXPERIMENTAL && SPARC && BROKEN
        help
          This enables HiSax support for the AMD7930 chips on some SPARCs.
          This code is not finished yet.
index 7d4a0ac..12ad462 100644 (file)
@@ -187,6 +187,14 @@ config WINDFARM_PM91
          This driver provides thermal control for the PowerMac9,1
           which is the recent (SMU based) single CPU desktop G5
 
+config WINDFARM_PM112
+       tristate "Support for thermal management on PowerMac11,2"
+       depends on WINDFARM && I2C && PMAC_SMU
+       select I2C_POWERMAC
+       help
+         This driver provides thermal control for the PowerMac11,2
+         which are the recent dual and quad G5 machines using the
+         970MP dual-core processor.
 
 config ANSLCD
        tristate "Support for ANS LCD display"
index f4657aa..6081acd 100644 (file)
@@ -35,3 +35,8 @@ obj-$(CONFIG_WINDFARM_PM91)     += windfarm_smu_controls.o \
                                   windfarm_smu_sensors.o \
                                   windfarm_lm75_sensor.o windfarm_pid.o \
                                   windfarm_cpufreq_clamp.o windfarm_pm91.o
+obj-$(CONFIG_WINDFARM_PM112)   += windfarm_pm112.o windfarm_smu_sat.o \
+                                  windfarm_smu_controls.o \
+                                  windfarm_smu_sensors.o \
+                                  windfarm_max6690_sensor.o \
+                                  windfarm_lm75_sensor.o windfarm_pid.o
index 3f0cb03..7a2482c 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
+#include <linux/device.h>
 
 /* Display a 16.16 fixed point value */
 #define FIX32TOPRINT(f)        ((f) >> 16),((((f) & 0xffff) * 1000) >> 16)
@@ -39,6 +40,7 @@ struct wf_control {
        char                    *name;
        int                     type;
        struct kref             ref;
+       struct device_attribute attr;
 };
 
 #define WF_CONTROL_TYPE_GENERIC                0
@@ -87,6 +89,7 @@ struct wf_sensor {
        struct wf_sensor_ops    *ops;
        char                    *name;
        struct kref             ref;
+       struct device_attribute attr;
 };
 
 /* Same lifetime rules as controls */
index 6c2a471..bb8d5ef 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/reboot.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/mutex.h>
 
 #include "windfarm.h"
 
 
 static LIST_HEAD(wf_controls);
 static LIST_HEAD(wf_sensors);
-static DECLARE_MUTEX(wf_lock);
+static DEFINE_MUTEX(wf_lock);
 static struct notifier_block *wf_client_list;
 static int wf_client_count;
 static unsigned int wf_overtemp;
 static unsigned int wf_overtemp_counter;
 struct task_struct *wf_thread;
 
+static struct platform_device wf_platform_device = {
+       .name   = "windfarm",
+};
+
 /*
  * Utilities & tick thread
  */
@@ -156,26 +161,67 @@ static void wf_control_release(struct kref *kref)
                kfree(ct);
 }
 
+static ssize_t wf_show_control(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
+       s32 val = 0;
+       int err;
+
+       err = ctrl->ops->get_value(ctrl, &val);
+       if (err < 0)
+               return err;
+       return sprintf(buf, "%d\n", val);
+}
+
+/* This is really only for debugging... */
+static ssize_t wf_store_control(struct device *dev,
+                               struct device_attribute *attr,
+                               const char *buf, size_t count)
+{
+       struct wf_control *ctrl = container_of(attr, struct wf_control, attr);
+       int val;
+       int err;
+       char *endp;
+
+       val = simple_strtoul(buf, &endp, 0);
+       while (endp < buf + count && (*endp == ' ' || *endp == '\n'))
+               ++endp;
+       if (endp - buf < count)
+               return -EINVAL;
+       err = ctrl->ops->set_value(ctrl, val);
+       if (err < 0)
+               return err;
+       return count;
+}
+
 int wf_register_control(struct wf_control *new_ct)
 {
        struct wf_control *ct;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(ct, &wf_controls, link) {
                if (!strcmp(ct->name, new_ct->name)) {
                        printk(KERN_WARNING "windfarm: trying to register"
                               " duplicate control %s\n", ct->name);
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return -EEXIST;
                }
        }
        kref_init(&new_ct->ref);
        list_add(&new_ct->link, &wf_controls);
 
+       new_ct->attr.attr.name = new_ct->name;
+       new_ct->attr.attr.owner = THIS_MODULE;
+       new_ct->attr.attr.mode = 0644;
+       new_ct->attr.show = wf_show_control;
+       new_ct->attr.store = wf_store_control;
+       device_create_file(&wf_platform_device.dev, &new_ct->attr);
+
        DBG("wf: Registered control %s\n", new_ct->name);
 
        wf_notify(WF_EVENT_NEW_CONTROL, new_ct);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        return 0;
 }
@@ -183,9 +229,9 @@ EXPORT_SYMBOL_GPL(wf_register_control);
 
 void wf_unregister_control(struct wf_control *ct)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_del(&ct->link);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        DBG("wf: Unregistered control %s\n", ct->name);
 
@@ -197,16 +243,16 @@ struct wf_control * wf_find_control(const char *name)
 {
        struct wf_control *ct;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(ct, &wf_controls, link) {
                if (!strcmp(ct->name, name)) {
                        if (wf_get_control(ct))
                                ct = NULL;
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return ct;
                }
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
        return NULL;
 }
 EXPORT_SYMBOL_GPL(wf_find_control);
@@ -246,26 +292,46 @@ static void wf_sensor_release(struct kref *kref)
                kfree(sr);
 }
 
+static ssize_t wf_show_sensor(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr);
+       s32 val = 0;
+       int err;
+
+       err = sens->ops->get_value(sens, &val);
+       if (err < 0)
+               return err;
+       return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val));
+}
+
 int wf_register_sensor(struct wf_sensor *new_sr)
 {
        struct wf_sensor *sr;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(sr, &wf_sensors, link) {
                if (!strcmp(sr->name, new_sr->name)) {
                        printk(KERN_WARNING "windfarm: trying to register"
                               " duplicate sensor %s\n", sr->name);
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return -EEXIST;
                }
        }
        kref_init(&new_sr->ref);
        list_add(&new_sr->link, &wf_sensors);
 
+       new_sr->attr.attr.name = new_sr->name;
+       new_sr->attr.attr.owner = THIS_MODULE;
+       new_sr->attr.attr.mode = 0444;
+       new_sr->attr.show = wf_show_sensor;
+       new_sr->attr.store = NULL;
+       device_create_file(&wf_platform_device.dev, &new_sr->attr);
+
        DBG("wf: Registered sensor %s\n", new_sr->name);
 
        wf_notify(WF_EVENT_NEW_SENSOR, new_sr);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        return 0;
 }
@@ -273,9 +339,9 @@ EXPORT_SYMBOL_GPL(wf_register_sensor);
 
 void wf_unregister_sensor(struct wf_sensor *sr)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_del(&sr->link);
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        DBG("wf: Unregistered sensor %s\n", sr->name);
 
@@ -287,16 +353,16 @@ struct wf_sensor * wf_find_sensor(const char *name)
 {
        struct wf_sensor *sr;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        list_for_each_entry(sr, &wf_sensors, link) {
                if (!strcmp(sr->name, name)) {
                        if (wf_get_sensor(sr))
                                sr = NULL;
-                       up(&wf_lock);
+                       mutex_unlock(&wf_lock);
                        return sr;
                }
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
        return NULL;
 }
 EXPORT_SYMBOL_GPL(wf_find_sensor);
@@ -329,7 +395,7 @@ int wf_register_client(struct notifier_block *nb)
        struct wf_control *ct;
        struct wf_sensor *sr;
 
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        rc = notifier_chain_register(&wf_client_list, nb);
        if (rc != 0)
                goto bail;
@@ -341,19 +407,19 @@ int wf_register_client(struct notifier_block *nb)
        if (wf_client_count == 1)
                wf_start_thread();
  bail:
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
        return rc;
 }
 EXPORT_SYMBOL_GPL(wf_register_client);
 
 int wf_unregister_client(struct notifier_block *nb)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        notifier_chain_unregister(&wf_client_list, nb);
        wf_client_count++;
        if (wf_client_count == 0)
                wf_stop_thread();
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 
        return 0;
 }
@@ -361,23 +427,23 @@ EXPORT_SYMBOL_GPL(wf_unregister_client);
 
 void wf_set_overtemp(void)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        wf_overtemp++;
        if (wf_overtemp == 1) {
                printk(KERN_WARNING "windfarm: Overtemp condition detected !\n");
                wf_overtemp_counter = 0;
                wf_notify(WF_EVENT_OVERTEMP, NULL);
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 }
 EXPORT_SYMBOL_GPL(wf_set_overtemp);
 
 void wf_clear_overtemp(void)
 {
-       down(&wf_lock);
+       mutex_lock(&wf_lock);
        WARN_ON(wf_overtemp == 0);
        if (wf_overtemp == 0) {
-               up(&wf_lock);
+               mutex_unlock(&wf_lock);
                return;
        }
        wf_overtemp--;
@@ -385,7 +451,7 @@ void wf_clear_overtemp(void)
                printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n");
                wf_notify(WF_EVENT_NORMALTEMP, NULL);
        }
-       up(&wf_lock);
+       mutex_unlock(&wf_lock);
 }
 EXPORT_SYMBOL_GPL(wf_clear_overtemp);
 
@@ -395,10 +461,6 @@ int wf_is_overtemp(void)
 }
 EXPORT_SYMBOL_GPL(wf_is_overtemp);
 
-static struct platform_device wf_platform_device = {
-       .name   = "windfarm",
-};
-
 static int __init windfarm_core_init(void)
 {
        DBG("wf: core loaded\n");
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
new file mode 100644 (file)
index 0000000..5b9ad6c
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Windfarm PowerMac thermal control.  MAX6690 sensor.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ *
+ * Use and redistribute under the terms of the GNU GPL v2.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/prom.h>
+#include <asm/pmac_low_i2c.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.1"
+
+/* This currently only exports the external temperature sensor,
+   since that's all the control loops need. */
+
+/* Some MAX6690 register numbers */
+#define MAX6690_INTERNAL_TEMP  0
+#define MAX6690_EXTERNAL_TEMP  1
+
+struct wf_6690_sensor {
+       struct i2c_client       i2c;
+       struct wf_sensor        sens;
+};
+
+#define wf_to_6690(x)  container_of((x), struct wf_6690_sensor, sens)
+#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c)
+
+static int wf_max6690_attach(struct i2c_adapter *adapter);
+static int wf_max6690_detach(struct i2c_client *client);
+
+static struct i2c_driver wf_max6690_driver = {
+       .driver = {
+               .name           = "wf_max6690",
+       },
+       .attach_adapter = wf_max6690_attach,
+       .detach_client  = wf_max6690_detach,
+};
+
+static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
+{
+       struct wf_6690_sensor *max = wf_to_6690(sr);
+       s32 data;
+
+       if (max->i2c.adapter == NULL)
+               return -ENODEV;
+
+       /* chip gets initialized by firmware */
+       data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP);
+       if (data < 0)
+               return data;
+       *value = data << 16;
+       return 0;
+}
+
+static void wf_max6690_release(struct wf_sensor *sr)
+{
+       struct wf_6690_sensor *max = wf_to_6690(sr);
+
+       if (max->i2c.adapter) {
+               i2c_detach_client(&max->i2c);
+               max->i2c.adapter = NULL;
+       }
+       kfree(max);
+}
+
+static struct wf_sensor_ops wf_max6690_ops = {
+       .get_value      = wf_max6690_get,
+       .release        = wf_max6690_release,
+       .owner          = THIS_MODULE,
+};
+
+static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr)
+{
+       struct wf_6690_sensor *max;
+       char *name = "u4-temp";
+
+       max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
+       if (max == NULL) {
+               printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
+                      "no memory\n", name);
+               return;
+       }
+
+       max->sens.ops = &wf_max6690_ops;
+       max->sens.name = name;
+       max->i2c.addr = addr >> 1;
+       max->i2c.adapter = adapter;
+       max->i2c.driver = &wf_max6690_driver;
+       strncpy(max->i2c.name, name, I2C_NAME_SIZE-1);
+
+       if (i2c_attach_client(&max->i2c)) {
+               printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
+               goto fail;
+       }
+
+       if (wf_register_sensor(&max->sens)) {
+               i2c_detach_client(&max->i2c);
+               goto fail;
+       }
+
+       return;
+
+ fail:
+       kfree(max);
+}
+
+static int wf_max6690_attach(struct i2c_adapter *adapter)
+{
+       struct device_node *busnode, *dev = NULL;
+       struct pmac_i2c_bus *bus;
+       const char *loc;
+       u32 *reg;
+
+       bus = pmac_i2c_adapter_to_bus(adapter);
+       if (bus == NULL)
+               return -ENODEV;
+       busnode = pmac_i2c_get_bus_node(bus);
+
+       while ((dev = of_get_next_child(busnode, dev)) != NULL) {
+               if (!device_is_compatible(dev, "max6690"))
+                       continue;
+               loc = get_property(dev, "hwsensor-location", NULL);
+               reg = (u32 *) get_property(dev, "reg", NULL);
+               if (!loc || !reg)
+                       continue;
+               printk("found max6690, loc=%s reg=%x\n", loc, *reg);
+               if (strcmp(loc, "BACKSIDE"))
+                       continue;
+               wf_max6690_create(adapter, *reg);
+       }
+
+       return 0;
+}
+
+static int wf_max6690_detach(struct i2c_client *client)
+{
+       struct wf_6690_sensor *max = i2c_to_6690(client);
+
+       max->i2c.adapter = NULL;
+       wf_unregister_sensor(&max->sens);
+
+       return 0;
+}
+
+static int __init wf_max6690_sensor_init(void)
+{
+       return i2c_add_driver(&wf_max6690_driver);
+}
+
+static void __exit wf_max6690_sensor_exit(void)
+{
+       i2c_del_driver(&wf_max6690_driver);
+}
+
+module_init(wf_max6690_sensor_init);
+module_exit(wf_max6690_sensor_exit);
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control");
+MODULE_LICENSE("GPL");
index 2e803b3..0842432 100644 (file)
@@ -88,8 +88,8 @@ EXPORT_SYMBOL_GPL(wf_cpu_pid_init);
 
 s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
 {
-       s64     error, integ, deriv, prop;
-       s32     target, sval, adj;
+       s64     integ, deriv, prop;
+       s32     error, target, sval, adj;
        int     i, hlen = st->param.history_len;
 
        /* Calculate error term */
@@ -117,7 +117,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
                integ += st->errors[(st->index + hlen - i) % hlen];
        integ *= st->param.interval;
        integ *= st->param.gr;
-       sval = st->param.tmax - ((integ >> 20) & 0xffffffff);
+       sval = st->param.tmax - (s32)(integ >> 20);
        adj = min(st->param.ttarget, sval);
 
        DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj);
@@ -129,7 +129,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
        deriv *= st->param.gd;
 
        /* Calculate proportional term */
-       prop = (new_temp - adj);
+       prop = st->last_delta = (new_temp - adj);
        prop *= st->param.gp;
 
        DBG("deriv: %lx, prop: %lx\n", deriv, prop);
index a364c2a..bbccc22 100644 (file)
@@ -72,6 +72,7 @@ struct wf_cpu_pid_state {
        int     index;                          /* index of current power */
        int     tindex;                         /* index of current temp */
        s32     target;                         /* current target value */
+       s32     last_delta;                     /* last Tactual - Ttarget */
        s32     powers[WF_PID_MAX_HISTORY];     /* power history buffer */
        s32     errors[WF_PID_MAX_HISTORY];     /* error history buffer */
        s32     temps[2];                       /* temp. history buffer */
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c
new file mode 100644 (file)
index 0000000..c2a4e68
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * Windfarm PowerMac thermal control.
+ * Control loops for machines with SMU and PPC970MP processors.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
+ *
+ * Use and redistribute under the terms of the GNU GPL v2.
+ */
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <asm/prom.h>
+#include <asm/smu.h>
+
+#include "windfarm.h"
+#include "windfarm_pid.h"
+
+#define VERSION "0.2"
+
+#define DEBUG
+#undef LOTSA_DEBUG
+
+#ifdef DEBUG
+#define DBG(args...)   printk(args)
+#else
+#define DBG(args...)   do { } while(0)
+#endif
+
+#ifdef LOTSA_DEBUG
+#define DBG_LOTS(args...)      printk(args)
+#else
+#define DBG_LOTS(args...)      do { } while(0)
+#endif
+
+/* define this to force CPU overtemp to 60 degree, useful for testing
+ * the overtemp code
+ */
+#undef HACKED_OVERTEMP
+
+/* We currently only handle 2 chips, 4 cores... */
+#define NR_CHIPS       2
+#define NR_CORES       4
+#define NR_CPU_FANS    3 * NR_CHIPS
+
+/* Controls and sensors */
+static struct wf_sensor *sens_cpu_temp[NR_CORES];
+static struct wf_sensor *sens_cpu_power[NR_CORES];
+static struct wf_sensor *hd_temp;
+static struct wf_sensor *slots_power;
+static struct wf_sensor *u4_temp;
+
+static struct wf_control *cpu_fans[NR_CPU_FANS];
+static char *cpu_fan_names[NR_CPU_FANS] = {
+       "cpu-rear-fan-0",
+       "cpu-rear-fan-1",
+       "cpu-front-fan-0",
+       "cpu-front-fan-1",
+       "cpu-pump-0",
+       "cpu-pump-1",
+};
+static struct wf_control *cpufreq_clamp;
+
+/* Second pump isn't required (and isn't actually present) */
+#define CPU_FANS_REQD          (NR_CPU_FANS - 2)
+#define FIRST_PUMP             4
+#define LAST_PUMP              5
+
+/* We keep a temperature history for average calculation of 180s */
+#define CPU_TEMP_HIST_SIZE     180
+
+/* Scale factor for fan speed, *100 */
+static int cpu_fan_scale[NR_CPU_FANS] = {
+       100,
+       100,
+       97,             /* inlet fans run at 97% of exhaust fan */
+       97,
+       100,            /* updated later */
+       100,            /* updated later */
+};
+
+static struct wf_control *backside_fan;
+static struct wf_control *slots_fan;
+static struct wf_control *drive_bay_fan;
+
+/* PID loop state */
+static struct wf_cpu_pid_state cpu_pid[NR_CORES];
+static u32 cpu_thist[CPU_TEMP_HIST_SIZE];
+static int cpu_thist_pt;
+static s64 cpu_thist_total;
+static s32 cpu_all_tmax = 100 << 16;
+static int cpu_last_target;
+static struct wf_pid_state backside_pid;
+static int backside_tick;
+static struct wf_pid_state slots_pid;
+static int slots_started;
+static struct wf_pid_state drive_bay_pid;
+static int drive_bay_tick;
+
+static int nr_cores;
+static int have_all_controls;
+static int have_all_sensors;
+static int started;
+
+static int failure_state;
+#define FAILURE_SENSOR         1
+#define FAILURE_FAN            2
+#define FAILURE_PERM           4
+#define FAILURE_LOW_OVERTEMP   8
+#define FAILURE_HIGH_OVERTEMP  16
+
+/* Overtemp values */
+#define LOW_OVER_AVERAGE       0
+#define LOW_OVER_IMMEDIATE     (10 << 16)
+#define LOW_OVER_CLEAR         ((-10) << 16)
+#define HIGH_OVER_IMMEDIATE    (14 << 16)
+#define HIGH_OVER_AVERAGE      (10 << 16)
+#define HIGH_OVER_IMMEDIATE    (14 << 16)
+
+
+/* Implementation... */
+static int create_cpu_loop(int cpu)
+{
+       int chip = cpu / 2;
+       int core = cpu & 1;
+       struct smu_sdbp_header *hdr;
+       struct smu_sdbp_cpupiddata *piddata;
+       struct wf_cpu_pid_param pid;
+       struct wf_control *main_fan = cpu_fans[0];
+       s32 tmax;
+       int fmin;
+
+       /* Get PID params from the appropriate SAT */
+       hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL);
+       if (hdr == NULL) {
+               printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n");
+               return -EINVAL;
+       }
+       piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
+
+       /* Get FVT params to get Tmax; if not found, assume default */
+       hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL);
+       if (hdr) {
+               struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1];
+               tmax = fvt->maxtemp << 16;
+       } else
+               tmax = 95 << 16;        /* default to 95 degrees C */
+
+       /* We keep a global tmax for overtemp calculations */
+       if (tmax < cpu_all_tmax)
+               cpu_all_tmax = tmax;
+
+       /*
+        * Darwin has a minimum fan speed of 1000 rpm for the 4-way and
+        * 515 for the 2-way.  That appears to be overkill, so for now,
+        * impose a minimum of 750 or 515.
+        */
+       fmin = (nr_cores > 2) ? 750 : 515;
+
+       /* Initialize PID loop */
+       pid.interval = 1;       /* seconds */
+       pid.history_len = piddata->history_len;
+       pid.gd = piddata->gd;
+       pid.gp = piddata->gp;
+       pid.gr = piddata->gr / piddata->history_len;
+       pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8);
+       pid.ttarget = tmax - (piddata->target_temp_delta << 16);
+       pid.tmax = tmax;
+       pid.min = main_fan->ops->get_min(main_fan);
+       pid.max = main_fan->ops->get_max(main_fan);
+       if (pid.min < fmin)
+               pid.min = fmin;
+
+       wf_cpu_pid_init(&cpu_pid[cpu], &pid);
+       return 0;
+}
+
+static void cpu_max_all_fans(void)
+{
+       int i;
+
+       /* We max all CPU fans in case of a sensor error. We also do the
+        * cpufreq clamping now, even if it's supposedly done later by the
+        * generic code anyway, we do it earlier here to react faster
+        */
+       if (cpufreq_clamp)
+               wf_control_set_max(cpufreq_clamp);
+       for (i = 0; i < NR_CPU_FANS; ++i)
+               if (cpu_fans[i])
+                       wf_control_set_max(cpu_fans[i]);
+}
+
+static int cpu_check_overtemp(s32 temp)
+{
+       int new_state = 0;
+       s32 t_avg, t_old;
+
+       /* First check for immediate overtemps */
+       if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) {
+               new_state |= FAILURE_LOW_OVERTEMP;
+               if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Overtemp due to immediate CPU"
+                              " temperature !\n");
+       }
+       if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) {
+               new_state |= FAILURE_HIGH_OVERTEMP;
+               if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Critical overtemp due to"
+                              " immediate CPU temperature !\n");
+       }
+
+       /* We calculate a history of max temperatures and use that for the
+        * overtemp management
+        */
+       t_old = cpu_thist[cpu_thist_pt];
+       cpu_thist[cpu_thist_pt] = temp;
+       cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE;
+       cpu_thist_total -= t_old;
+       cpu_thist_total += temp;
+       t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE;
+
+       DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n",
+                FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp));
+
+       /* Now check for average overtemps */
+       if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) {
+               new_state |= FAILURE_LOW_OVERTEMP;
+               if ((failure_state & FAILURE_LOW_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Overtemp due to average CPU"
+                              " temperature !\n");
+       }
+       if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) {
+               new_state |= FAILURE_HIGH_OVERTEMP;
+               if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0)
+                       printk(KERN_ERR "windfarm: Critical overtemp due to"
+                              " average CPU temperature !\n");
+       }
+
+       /* Now handle overtemp conditions. We don't currently use the windfarm
+        * overtemp handling core as it's not fully suited to the needs of those
+        * new machine. This will be fixed later.
+        */
+       if (new_state) {
+               /* High overtemp -> immediate shutdown */
+               if (new_state & FAILURE_HIGH_OVERTEMP)
+                       machine_power_off();
+               if ((failure_state & new_state) != new_state)
+                       cpu_max_all_fans();
+               failure_state |= new_state;
+       } else if ((failure_state & FAILURE_LOW_OVERTEMP) &&
+                  (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) {
+               printk(KERN_ERR "windfarm: Overtemp condition cleared !\n");
+               failure_state &= ~FAILURE_LOW_OVERTEMP;
+       }
+
+       return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP);
+}
+
+static void cpu_fans_tick(void)
+{
+       int err, cpu;
+       s32 greatest_delta = 0;
+       s32 temp, power, t_max = 0;
+       int i, t, target = 0;
+       struct wf_sensor *sr;
+       struct wf_control *ct;
+       struct wf_cpu_pid_state *sp;
+
+       DBG_LOTS(KERN_DEBUG);
+       for (cpu = 0; cpu < nr_cores; ++cpu) {
+               /* Get CPU core temperature */
+               sr = sens_cpu_temp[cpu];
+               err = sr->ops->get_value(sr, &temp);
+               if (err) {
+                       DBG("\n");
+                       printk(KERN_WARNING "windfarm: CPU %d temperature "
+                              "sensor error %d\n", cpu, err);
+                       failure_state |= FAILURE_SENSOR;
+                       cpu_max_all_fans();
+                       return;
+               }
+
+               /* Keep track of highest temp */
+               t_max = max(t_max, temp);
+
+               /* Get CPU power */
+               sr = sens_cpu_power[cpu];
+               err = sr->ops->get_value(sr, &power);
+               if (err) {
+                       DBG("\n");
+                       printk(KERN_WARNING "windfarm: CPU %d power "
+                              "sensor error %d\n", cpu, err);
+                       failure_state |= FAILURE_SENSOR;
+                       cpu_max_all_fans();
+                       return;
+               }
+
+               /* Run PID */
+               sp = &cpu_pid[cpu];
+               t = wf_cpu_pid_run(sp, power, temp);
+
+               if (cpu == 0 || sp->last_delta > greatest_delta) {
+                       greatest_delta = sp->last_delta;
+                       target = t;
+               }
+               DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ",
+                   cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp));
+       }
+       DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max));
+
+       /* Darwin limits decrease to 20 per iteration */
+       if (target < (cpu_last_target - 20))
+               target = cpu_last_target - 20;
+       cpu_last_target = target;
+       for (cpu = 0; cpu < nr_cores; ++cpu)
+               cpu_pid[cpu].target = target;
+
+       /* Handle possible overtemps */
+       if (cpu_check_overtemp(t_max))
+               return;
+
+       /* Set fans */
+       for (i = 0; i < NR_CPU_FANS; ++i) {
+               ct = cpu_fans[i];
+               if (ct == NULL)
+                       continue;
+               err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100);
+               if (err) {
+                       printk(KERN_WARNING "windfarm: fan %s reports "
+                              "error %d\n", ct->name, err);
+                       failure_state |= FAILURE_FAN;
+                       break;
+               }
+       }
+}
+
+/* Backside/U4 fan */
+static struct wf_pid_param backside_param = {
+       .interval       = 5,
+       .history_len    = 2,
+       .gd             = 48 << 20,
+       .gp             = 5 << 20,
+       .gr             = 0,
+       .itarget        = 64 << 16,
+       .additive       = 1,
+};
+
+static void backside_fan_tick(void)
+{
+       s32 temp;
+       int speed;
+       int err;
+
+       if (!backside_fan || !u4_temp)
+               return;
+       if (!backside_tick) {
+               /* first time; initialize things */
+               backside_param.min = backside_fan->ops->get_min(backside_fan);
+               backside_param.max = backside_fan->ops->get_max(backside_fan);
+               wf_pid_init(&backside_pid, &backside_param);
+               backside_tick = 1;
+       }
+       if (--backside_tick > 0)
+               return;
+       backside_tick = backside_pid.param.interval;
+
+       err = u4_temp->ops->get_value(u4_temp, &temp);
+       if (err) {
+               printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n",
+                      err);
+               failure_state |= FAILURE_SENSOR;
+               wf_control_set_max(backside_fan);
+               return;
+       }
+       speed = wf_pid_run(&backside_pid, temp);
+       DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n",
+                FIX32TOPRINT(temp), speed);
+
+       err = backside_fan->ops->set_value(backside_fan, speed);
+       if (err) {
+               printk(KERN_WARNING "windfarm: backside fan error %d\n", err);
+               failure_state |= FAILURE_FAN;
+       }
+}
+
+/* Drive bay fan */
+static struct wf_pid_param drive_bay_prm = {
+       .interval       = 5,
+       .history_len    = 2,
+       .gd             = 30 << 20,
+       .gp             = 5 << 20,
+       .gr             = 0,
+       .itarget        = 40 << 16,
+       .additive       = 1,
+};
+
+static void drive_bay_fan_tick(void)
+{
+       s32 temp;
+       int speed;
+       int err;
+
+       if (!drive_bay_fan || !hd_temp)
+               return;
+       if (!drive_bay_tick) {
+               /* first time; initialize things */
+               drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan);
+               drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan);
+               wf_pid_init(&drive_bay_pid, &drive_bay_prm);
+               drive_bay_tick = 1;
+       }
+       if (--drive_bay_tick > 0)
+               return;
+       drive_bay_tick = drive_bay_pid.param.interval;
+
+       err = hd_temp->ops->get_value(hd_temp, &temp);
+       if (err) {
+               printk(KERN_WARNING "windfarm: drive bay temp sensor "
+                      "error %d\n", err);
+               failure_state |= FAILURE_SENSOR;
+               wf_control_set_max(drive_bay_fan);
+               return;
+       }
+       speed = wf_pid_run(&drive_bay_pid, temp);
+       DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n",
+                FIX32TOPRINT(temp), speed);
+
+       err = drive_bay_fan->ops->set_value(drive_bay_fan, speed);
+       if (err) {
+               printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err);
+               failure_state |= FAILURE_FAN;
+       }
+}
+
+/* PCI slots area fan */
+/* This makes the fan speed proportional to the power consumed */
+static struct wf_pid_param slots_param = {
+       .interval       = 1,
+       .history_len    = 2,
+       .gd             = 0,
+       .gp             = 0,
+       .gr             = 0x1277952,
+       .itarget        = 0,
+       .min            = 1560,
+       .max            = 3510,
+};
+
+static void slots_fan_tick(void)
+{
+       s32 power;
+       int speed;
+       int err;
+
+       if (!slots_fan || !slots_power)
+               return;
+       if (!slots_started) {
+               /* first time; initialize things */
+               wf_pid_init(&slots_pid, &slots_param);
+               slots_started = 1;
+       }
+
+       err = slots_power->ops->get_value(slots_power, &power);
+       if (err) {
+               printk(KERN_WARNING "windfarm: slots power sensor error %d\n",
+                      err);
+               failure_state |= FAILURE_SENSOR;
+               wf_control_set_max(slots_fan);
+               return;
+       }
+       speed = wf_pid_run(&slots_pid, power);
+       DBG_LOTS("slots PID power=%d.%.3d speed=%d\n",
+                FIX32TOPRINT(power), speed);
+
+       err = slots_fan->ops->set_value(slots_fan, speed);
+       if (err) {
+               printk(KERN_WARNING "windfarm: slots fan error %d\n", err);
+               failure_state |= FAILURE_FAN;
+       }
+}
+
+static void set_fail_state(void)
+{
+       int i;
+
+       if (cpufreq_clamp)
+               wf_control_set_max(cpufreq_clamp);
+       for (i = 0; i < NR_CPU_FANS; ++i)
+               if (cpu_fans[i])
+                       wf_control_set_max(cpu_fans[i]);
+       if (backside_fan)
+               wf_control_set_max(backside_fan);
+       if (slots_fan)
+               wf_control_set_max(slots_fan);
+       if (drive_bay_fan)
+               wf_control_set_max(drive_bay_fan);
+}
+
+static void pm112_tick(void)
+{
+       int i, last_failure;
+
+       if (!started) {
+               started = 1;
+               for (i = 0; i < nr_cores; ++i) {
+                       if (create_cpu_loop(i) < 0) {
+                               failure_state = FAILURE_PERM;
+                               set_fail_state();
+                               break;
+                       }
+               }
+               DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax));
+
+#ifdef HACKED_OVERTEMP
+               cpu_all_tmax = 60 << 16;
+#endif
+       }
+
+       /* Permanent failure, bail out */
+       if (failure_state & FAILURE_PERM)
+               return;
+       /* Clear all failure bits except low overtemp which will be eventually
+        * cleared by the control loop itself
+        */
+       last_failure = failure_state;
+       failure_state &= FAILURE_LOW_OVERTEMP;
+       cpu_fans_tick();
+       backside_fan_tick();
+       slots_fan_tick();
+       drive_bay_fan_tick();
+
+       DBG_LOTS("last_failure: 0x%x, failure_state: %x\n",
+                last_failure, failure_state);
+
+       /* Check for failures. Any failure causes cpufreq clamping */
+       if (failure_state && last_failure == 0 && cpufreq_clamp)
+               wf_control_set_max(cpufreq_clamp);
+       if (failure_state == 0 && last_failure && cpufreq_clamp)
+               wf_control_set_min(cpufreq_clamp);
+
+       /* That's it for now, we might want to deal with other failures
+        * differently in the future though
+        */
+}
+
+static void pm112_new_control(struct wf_control *ct)
+{
+       int i, max_exhaust;
+
+       if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
+               if (wf_get_control(ct) == 0)
+                       cpufreq_clamp = ct;
+       }
+
+       for (i = 0; i < NR_CPU_FANS; ++i) {
+               if (!strcmp(ct->name, cpu_fan_names[i])) {
+                       if (cpu_fans[i] == NULL && wf_get_control(ct) == 0)
+                               cpu_fans[i] = ct;
+                       break;
+               }
+       }
+       if (i >= NR_CPU_FANS) {
+               /* not a CPU fan, try the others */
+               if (!strcmp(ct->name, "backside-fan")) {
+                       if (backside_fan == NULL && wf_get_control(ct) == 0)
+                               backside_fan = ct;
+               } else if (!strcmp(ct->name, "slots-fan")) {
+                       if (slots_fan == NULL && wf_get_control(ct) == 0)
+                               slots_fan = ct;
+               } else if (!strcmp(ct->name, "drive-bay-fan")) {
+                       if (drive_bay_fan == NULL && wf_get_control(ct) == 0)
+                               drive_bay_fan = ct;
+               }
+               return;
+       }
+
+       for (i = 0; i < CPU_FANS_REQD; ++i)
+               if (cpu_fans[i] == NULL)
+                       return;
+
+       /* work out pump scaling factors */
+       max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]);
+       for (i = FIRST_PUMP; i <= LAST_PUMP; ++i)
+               if ((ct = cpu_fans[i]) != NULL)
+                       cpu_fan_scale[i] =
+                               ct->ops->get_max(ct) * 100 / max_exhaust;
+
+       have_all_controls = 1;
+}
+
+static void pm112_new_sensor(struct wf_sensor *sr)
+{
+       unsigned int i;
+
+       if (have_all_sensors)
+               return;
+       if (!strncmp(sr->name, "cpu-temp-", 9)) {
+               i = sr->name[9] - '0';
+               if (sr->name[10] == 0 && i < NR_CORES &&
+                   sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0)
+                       sens_cpu_temp[i] = sr;
+
+       } else if (!strncmp(sr->name, "cpu-power-", 10)) {
+               i = sr->name[10] - '0';
+               if (sr->name[11] == 0 && i < NR_CORES &&
+                   sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0)
+                       sens_cpu_power[i] = sr;
+       } else if (!strcmp(sr->name, "hd-temp")) {
+               if (hd_temp == NULL && wf_get_sensor(sr) == 0)
+                       hd_temp = sr;
+       } else if (!strcmp(sr->name, "slots-power")) {
+               if (slots_power == NULL && wf_get_sensor(sr) == 0)
+                       slots_power = sr;
+       } else if (!strcmp(sr->name, "u4-temp")) {
+               if (u4_temp == NULL && wf_get_sensor(sr) == 0)
+                       u4_temp = sr;
+       } else
+               return;
+
+       /* check if we have all the sensors we need */
+       for (i = 0; i < nr_cores; ++i)
+               if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL)
+                       return;
+
+       have_all_sensors = 1;
+}
+
+static int pm112_wf_notify(struct notifier_block *self,
+                          unsigned long event, void *data)
+{
+       switch (event) {
+       case WF_EVENT_NEW_SENSOR:
+               pm112_new_sensor(data);
+               break;
+       case WF_EVENT_NEW_CONTROL:
+               pm112_new_control(data);
+               break;
+       case WF_EVENT_TICK:
+               if (have_all_controls && have_all_sensors)
+                       pm112_tick();
+       }
+       return 0;
+}
+
+static struct notifier_block pm112_events = {
+       .notifier_call = pm112_wf_notify,
+};
+
+static int wf_pm112_probe(struct device *dev)
+{
+       wf_register_client(&pm112_events);
+       return 0;
+}
+
+static int wf_pm112_remove(struct device *dev)
+{
+       wf_unregister_client(&pm112_events);
+       /* should release all sensors and controls */
+       return 0;
+}
+
+static struct device_driver wf_pm112_driver = {
+       .name = "windfarm",
+       .bus = &platform_bus_type,
+       .probe = wf_pm112_probe,
+       .remove = wf_pm112_remove,
+};
+
+static int __init wf_pm112_init(void)
+{
+       struct device_node *cpu;
+
+       if (!machine_is_compatible("PowerMac11,2"))
+               return -ENODEV;
+
+       /* Count the number of CPU cores */
+       nr_cores = 0;
+       for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; )
+               ++nr_cores;
+
+       printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n");
+       driver_register(&wf_pm112_driver);
+       return 0;
+}
+
+static void __exit wf_pm112_exit(void)
+{
+       driver_unregister(&wf_pm112_driver);
+}
+
+module_init(wf_pm112_init);
+module_exit(wf_pm112_exit);
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("Thermal control for PowerMac11,2");
+MODULE_LICENSE("GPL");
index eb69a60..f1df6ef 100644 (file)
@@ -538,45 +538,6 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
        }
 }
 
-
-/*
- * ****** Attributes ******
- *
- */
-
-#define BUILD_SHOW_FUNC_FIX(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       ssize_t r;                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val));         \
-       return r;                                               \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-
-#define BUILD_SHOW_FUNC_INT(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       return sprintf(buf, "%d", val);                         \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
-BUILD_SHOW_FUNC_INT(sys_fan, fan_system);
-BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
-
-BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
-BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
-BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
-
 /*
  * ****** Setup / Init / Misc ... ******
  *
@@ -654,17 +615,13 @@ static void wf_smu_new_control(struct wf_control *ct)
                return;
 
        if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_cpu_main = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
-               }
        }
 
        if (fan_system == NULL && !strcmp(ct->name, "system-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_system = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_sys_fan);
-               }
        }
 
        if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
@@ -683,10 +640,8 @@ static void wf_smu_new_control(struct wf_control *ct)
        }
 
        if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_hd = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_fan);
-               }
        }
 
        if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp)
@@ -699,24 +654,18 @@ static void wf_smu_new_sensor(struct wf_sensor *sr)
                return;
 
        if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_power = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_power);
-               }
        }
 
        if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
-               }
        }
 
        if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_hd_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_temp);
-               }
        }
 
        if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp)
@@ -794,32 +743,20 @@ static int wf_smu_remove(struct device *ddev)
         * with that except by adding locks all over... I'll do that
         * eventually but heh, who ever rmmod this module anyway ?
         */
-       if (sensor_cpu_power) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+       if (sensor_cpu_power)
                wf_put_sensor(sensor_cpu_power);
-       }
-       if (sensor_cpu_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+       if (sensor_cpu_temp)
                wf_put_sensor(sensor_cpu_temp);
-       }
-       if (sensor_hd_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+       if (sensor_hd_temp)
                wf_put_sensor(sensor_hd_temp);
-       }
 
        /* Release all controls */
-       if (fan_cpu_main) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+       if (fan_cpu_main)
                wf_put_control(fan_cpu_main);
-       }
-       if (fan_hd) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+       if (fan_hd)
                wf_put_control(fan_hd);
-       }
-       if (fan_system) {
-               device_remove_file(wf_smu_dev, &dev_attr_sys_fan);
+       if (fan_system)
                wf_put_control(fan_system);
-       }
        if (cpufreq_clamp)
                wf_put_control(cpufreq_clamp);
 
index 43243cf..0d6372e 100644 (file)
@@ -457,45 +457,6 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st)
 }
 
 
-/*
- * ****** Attributes ******
- *
- */
-
-#define BUILD_SHOW_FUNC_FIX(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       ssize_t r;                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val));         \
-       return r;                                               \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-
-#define BUILD_SHOW_FUNC_INT(name, data)                                \
-static ssize_t show_##name(struct device *dev,                  \
-                          struct device_attribute *attr,       \
-                          char *buf)                           \
-{                                                              \
-       s32 val = 0;                                            \
-       data->ops->get_value(data, &val);                       \
-       return sprintf(buf, "%d", val);                         \
-}                                                               \
-static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
-
-BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
-BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
-BUILD_SHOW_FUNC_INT(slots_fan, fan_slots);
-
-BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
-BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
-BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
-BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power);
-
 /*
  * ****** Setup / Init / Misc ... ******
  *
@@ -581,10 +542,8 @@ static void wf_smu_new_control(struct wf_control *ct)
                return;
 
        if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_cpu_main = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
-               }
        }
 
        if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) {
@@ -603,17 +562,13 @@ static void wf_smu_new_control(struct wf_control *ct)
        }
 
        if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_hd = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_fan);
-               }
        }
 
        if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) {
-               if (wf_get_control(ct) == 0) {
+               if (wf_get_control(ct) == 0)
                        fan_slots = ct;
-                       device_create_file(wf_smu_dev, &dev_attr_slots_fan);
-               }
        }
 
        if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd &&
@@ -627,31 +582,23 @@ static void wf_smu_new_sensor(struct wf_sensor *sr)
                return;
 
        if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_power = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_power);
-               }
        }
 
        if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_cpu_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
-               }
        }
 
        if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_hd_temp = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_hd_temp);
-               }
        }
 
        if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) {
-               if (wf_get_sensor(sr) == 0) {
+               if (wf_get_sensor(sr) == 0)
                        sensor_slots_power = sr;
-                       device_create_file(wf_smu_dev, &dev_attr_slots_power);
-               }
        }
 
        if (sensor_cpu_power && sensor_cpu_temp &&
@@ -720,40 +667,26 @@ static int wf_smu_remove(struct device *ddev)
         * with that except by adding locks all over... I'll do that
         * eventually but heh, who ever rmmod this module anyway ?
         */
-       if (sensor_cpu_power) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
+       if (sensor_cpu_power)
                wf_put_sensor(sensor_cpu_power);
-       }
-       if (sensor_cpu_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
+       if (sensor_cpu_temp)
                wf_put_sensor(sensor_cpu_temp);
-       }
-       if (sensor_hd_temp) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
+       if (sensor_hd_temp)
                wf_put_sensor(sensor_hd_temp);
-       }
-       if (sensor_slots_power) {
-               device_remove_file(wf_smu_dev, &dev_attr_slots_power);
+       if (sensor_slots_power)
                wf_put_sensor(sensor_slots_power);
-       }
 
        /* Release all controls */
-       if (fan_cpu_main) {
-               device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
+       if (fan_cpu_main)
                wf_put_control(fan_cpu_main);
-       }
        if (fan_cpu_second)
                wf_put_control(fan_cpu_second);
        if (fan_cpu_third)
                wf_put_control(fan_cpu_third);
-       if (fan_hd) {
-               device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
+       if (fan_hd)
                wf_put_control(fan_hd);
-       }
-       if (fan_slots) {
-               device_remove_file(wf_smu_dev, &dev_attr_slots_fan);
+       if (fan_slots)
                wf_put_control(fan_slots);
-       }
        if (cpufreq_clamp)
                wf_put_control(cpufreq_clamp);
 
index 4d81160..a9e88ed 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "windfarm.h"
 
-#define VERSION "0.3"
+#define VERSION "0.4"
 
 #undef DEBUG
 
@@ -34,6 +34,8 @@
 #define DBG(args...)   do { } while(0)
 #endif
 
+static int smu_supports_new_fans_ops = 1;
+
 /*
  * SMU fans control object
  */
@@ -59,23 +61,49 @@ static int smu_set_fan(int pwm, u8 id, u16 value)
 
        /* Fill SMU command structure */
        cmd.cmd = SMU_CMD_FAN_COMMAND;
-       cmd.data_len = 14;
+
+       /* The SMU has an "old" and a "new" way of setting the fan speed
+        * Unfortunately, I found no reliable way to know which one works
+        * on a given machine model. After some investigations it appears
+        * that MacOS X just tries the new one, and if it fails fallbacks
+        * to the old ones ... Ugh.
+        */
+ retry:
+       if (smu_supports_new_fans_ops) {
+               buffer[0] = 0x30;
+               buffer[1] = id;
+               *((u16 *)(&buffer[2])) = value;
+               cmd.data_len = 4;
+       } else {
+               if (id > 7)
+                       return -EINVAL;
+               /* Fill argument buffer */
+               memset(buffer, 0, 16);
+               buffer[0] = pwm ? 0x10 : 0x00;
+               buffer[1] = 0x01 << id;
+               *((u16 *)&buffer[2 + id * 2]) = value;
+               cmd.data_len = 14;
+       }
+
        cmd.reply_len = 16;
        cmd.data_buf = cmd.reply_buf = buffer;
        cmd.status = 0;
        cmd.done = smu_done_complete;
        cmd.misc = &comp;
 
-       /* Fill argument buffer */
-       memset(buffer, 0, 16);
-       buffer[0] = pwm ? 0x10 : 0x00;
-       buffer[1] = 0x01 << id;
-       *((u16 *)&buffer[2 + id * 2]) = value;
-
        rc = smu_queue_cmd(&cmd);
        if (rc)
                return rc;
        wait_for_completion(&comp);
+
+       /* Handle fallback (see coment above) */
+       if (cmd.status != 0 && smu_supports_new_fans_ops) {
+               printk(KERN_WARNING "windfarm: SMU failed new fan command "
+                      "falling back to old method\n");
+               smu_supports_new_fans_ops = 0;
+               goto retry;
+       }
+
        return cmd.status;
 }
 
@@ -158,19 +186,29 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node,
 
        /* Names used on desktop models */
        if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") ||
-           !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan"))
+           !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") ||
+           !strcmp(l, "CPU A EXHAUST"))
                fct->ctrl.name = "cpu-rear-fan-0";
-       else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1"))
+       else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") ||
+                !strcmp(l, "CPU B EXHAUST"))
                fct->ctrl.name = "cpu-rear-fan-1";
        else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") ||
-                !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan"))
+                !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") ||
+                !strcmp(l, "CPU A INTAKE"))
                fct->ctrl.name = "cpu-front-fan-0";
-       else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1"))
+       else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") ||
+                !strcmp(l, "CPU B INTAKE"))
                fct->ctrl.name = "cpu-front-fan-1";
-       else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan"))
+       else if (!strcmp(l, "CPU A PUMP"))
+               fct->ctrl.name = "cpu-pump-0";
+       else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") ||
+                !strcmp(l, "EXPANSION SLOTS INTAKE"))
                fct->ctrl.name = "slots-fan";
-       else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay"))
+       else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") ||
+                !strcmp(l, "DRIVE BAY A INTAKE"))
                fct->ctrl.name = "drive-bay-fan";
+       else if (!strcmp(l, "BACKSIDE"))
+               fct->ctrl.name = "backside-fan";
 
        /* Names used on iMac models */
        if (!strcmp(l, "System Fan") || !strcmp(l, "System fan"))
@@ -223,7 +261,8 @@ static int __init smu_controls_init(void)
 
        /* Look for RPM fans */
        for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
-               if (!strcmp(fans->name, "rpm-fans"))
+               if (!strcmp(fans->name, "rpm-fans") ||
+                   device_is_compatible(fans, "smu-rpm-fans"))
                        break;
        for (fan = NULL;
             fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
new file mode 100644 (file)
index 0000000..3a32c59
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * Windfarm PowerMac thermal control.  SMU "satellite" controller sensors.
+ *
+ * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
+ *
+ * Released under the terms of the GNU GPL v2.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+#include <asm/semaphore.h>
+#include <asm/prom.h>
+#include <asm/smu.h>
+#include <asm/pmac_low_i2c.h>
+
+#include "windfarm.h"
+
+#define VERSION "0.2"
+
+#define DEBUG
+
+#ifdef DEBUG
+#define DBG(args...)   printk(args)
+#else
+#define DBG(args...)   do { } while(0)
+#endif
+
+/* If the cache is older than 800ms we'll refetch it */
+#define MAX_AGE                msecs_to_jiffies(800)
+
+struct wf_sat {
+       int                     nr;
+       atomic_t                refcnt;
+       struct semaphore        mutex;
+       unsigned long           last_read; /* jiffies when cache last updated */
+       u8                      cache[16];
+       struct i2c_client       i2c;
+       struct device_node      *node;
+};
+
+static struct wf_sat *sats[2];
+
+struct wf_sat_sensor {
+       int             index;
+       int             index2;         /* used for power sensors */
+       int             shift;
+       struct wf_sat   *sat;
+       struct wf_sensor sens;
+};
+
+#define wf_to_sat(c)   container_of(c, struct wf_sat_sensor, sens)
+#define i2c_to_sat(c)  container_of(c, struct wf_sat, i2c)
+
+static int wf_sat_attach(struct i2c_adapter *adapter);
+static int wf_sat_detach(struct i2c_client *client);
+
+static struct i2c_driver wf_sat_driver = {
+       .driver = {
+               .name           = "wf_smu_sat",
+       },
+       .attach_adapter = wf_sat_attach,
+       .detach_client  = wf_sat_detach,
+};
+
+/*
+ * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested
+ * length down to the low-level driver, so we use this, which
+ * works well enough with the SMU i2c driver code...
+ */
+static int sat_read_block(struct i2c_client *client, u8 command,
+                         u8 *values, int len)
+{
+       union i2c_smbus_data data;
+       int err;
+
+       data.block[0] = len;
+       err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+                            I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA,
+                            &data);
+       if (!err)
+               memcpy(values, data.block, len);
+       return err;
+}
+
+struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
+                                                 unsigned int *size)
+{
+       struct wf_sat *sat;
+       int err;
+       unsigned int i, len;
+       u8 *buf;
+       u8 data[4];
+
+       /* TODO: Add the resulting partition to the device-tree */
+
+       if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
+               return NULL;
+
+       err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8);
+       if (err) {
+               printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
+               return NULL;
+       }
+
+       len = i2c_smbus_read_word_data(&sat->i2c, 9);
+       if (len < 0) {
+               printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
+               return NULL;
+       }
+       if (len == 0) {
+               printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id);
+               return NULL;
+       }
+
+       len = le16_to_cpu(len);
+       len = (len + 3) & ~3;
+       buf = kmalloc(len, GFP_KERNEL);
+       if (buf == NULL)
+               return NULL;
+
+       for (i = 0; i < len; i += 4) {
+               err = sat_read_block(&sat->i2c, 0xa, data, 4);
+               if (err) {
+                       printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
+                              err);
+                       goto fail;
+               }
+               buf[i] = data[1];
+               buf[i+1] = data[0];
+               buf[i+2] = data[3];
+               buf[i+3] = data[2];
+       }
+#ifdef DEBUG
+       DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id);
+       for (i = 0; i < len; ++i)
+               DBG(" %x", buf[i]);
+       DBG("\n");
+#endif
+
+       if (size)
+               *size = len;
+       return (struct smu_sdbp_header *) buf;
+
+ fail:
+       kfree(buf);
+       return NULL;
+}
+
+/* refresh the cache */
+static int wf_sat_read_cache(struct wf_sat *sat)
+{
+       int err;
+
+       err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16);
+       if (err)
+               return err;
+       sat->last_read = jiffies;
+#ifdef LOTSA_DEBUG
+       {
+               int i;
+               DBG(KERN_DEBUG "wf_sat_get: data is");
+               for (i = 0; i < 16; ++i)
+                       DBG(" %.2x", sat->cache[i]);
+               DBG("\n");
+       }
+#endif
+       return 0;
+}
+
+static int wf_sat_get(struct wf_sensor *sr, s32 *value)
+{
+       struct wf_sat_sensor *sens = wf_to_sat(sr);
+       struct wf_sat *sat = sens->sat;
+       int i, err;
+       s32 val;
+
+       if (sat->i2c.adapter == NULL)
+               return -ENODEV;
+
+       down(&sat->mutex);
+       if (time_after(jiffies, (sat->last_read + MAX_AGE))) {
+               err = wf_sat_read_cache(sat);
+               if (err)
+                       goto fail;
+       }
+
+       i = sens->index * 2;
+       val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift;
+       if (sens->index2 >= 0) {
+               i = sens->index2 * 2;
+               /* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */
+               val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4;
+       }
+
+       *value = val;
+       err = 0;
+
+ fail:
+       up(&sat->mutex);
+       return err;
+}
+
+static void wf_sat_release(struct wf_sensor *sr)
+{
+       struct wf_sat_sensor *sens = wf_to_sat(sr);
+       struct wf_sat *sat = sens->sat;
+
+       if (atomic_dec_and_test(&sat->refcnt)) {
+               if (sat->i2c.adapter) {
+                       i2c_detach_client(&sat->i2c);
+                       sat->i2c.adapter = NULL;
+               }
+               if (sat->nr >= 0)
+                       sats[sat->nr] = NULL;
+               kfree(sat);
+       }
+       kfree(sens);
+}
+
+static struct wf_sensor_ops wf_sat_ops = {
+       .get_value      = wf_sat_get,
+       .release        = wf_sat_release,
+       .owner          = THIS_MODULE,
+};
+
+static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
+{
+       struct wf_sat *sat;
+       struct wf_sat_sensor *sens;
+       u32 *reg;
+       char *loc, *type;
+       u8 addr, chip, core;
+       struct device_node *child;
+       int shift, cpu, index;
+       char *name;
+       int vsens[2], isens[2];
+
+       reg = (u32 *) get_property(dev, "reg", NULL);
+       if (reg == NULL)
+               return;
+       addr = *reg;
+       DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
+
+       sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
+       if (sat == NULL)
+               return;
+       sat->nr = -1;
+       sat->node = of_node_get(dev);
+       atomic_set(&sat->refcnt, 0);
+       init_MUTEX(&sat->mutex);
+       sat->i2c.addr = (addr >> 1) & 0x7f;
+       sat->i2c.adapter = adapter;
+       sat->i2c.driver = &wf_sat_driver;
+       strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1);
+
+       if (i2c_attach_client(&sat->i2c)) {
+               printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
+               goto fail;
+       }
+
+       vsens[0] = vsens[1] = -1;
+       isens[0] = isens[1] = -1;
+       child = NULL;
+       while ((child = of_get_next_child(dev, child)) != NULL) {
+               reg = (u32 *) get_property(child, "reg", NULL);
+               type = get_property(child, "device_type", NULL);
+               loc = get_property(child, "location", NULL);
+               if (reg == NULL || loc == NULL)
+                       continue;
+
+               /* the cooked sensors are between 0x30 and 0x37 */
+               if (*reg < 0x30 || *reg > 0x37)
+                       continue;
+               index = *reg - 0x30;
+
+               /* expect location to be CPU [AB][01] ... */
+               if (strncmp(loc, "CPU ", 4) != 0)
+                       continue;
+               chip = loc[4] - 'A';
+               core = loc[5] - '0';
+               if (chip > 1 || core > 1) {
+                       printk(KERN_ERR "wf_sat_create: don't understand "
+                              "location %s for %s\n", loc, child->full_name);
+                       continue;
+               }
+               cpu = 2 * chip + core;
+               if (sat->nr < 0)
+                       sat->nr = chip;
+               else if (sat->nr != chip) {
+                       printk(KERN_ERR "wf_sat_create: can't cope with "
+                              "multiple CPU chips on one SAT (%s)\n", loc);
+                       continue;
+               }
+
+               if (strcmp(type, "voltage-sensor") == 0) {
+                       name = "cpu-voltage";
+                       shift = 4;
+                       vsens[core] = index;
+               } else if (strcmp(type, "current-sensor") == 0) {
+                       name = "cpu-current";
+                       shift = 8;
+                       isens[core] = index;
+               } else if (strcmp(type, "temp-sensor") == 0) {
+                       name = "cpu-temp";
+                       shift = 10;
+               } else
+                       continue;       /* hmmm shouldn't happen */
+
+               /* the +16 is enough for "cpu-voltage-n" */
+               sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
+               if (sens == NULL) {
+                       printk(KERN_ERR "wf_sat_create: couldn't create "
+                              "%s sensor %d (no memory)\n", name, cpu);
+                       continue;
+               }
+               sens->index = index;
+               sens->index2 = -1;
+               sens->shift = shift;
+               sens->sat = sat;
+               atomic_inc(&sat->refcnt);
+               sens->sens.ops = &wf_sat_ops;
+               sens->sens.name = (char *) (sens + 1);
+               snprintf(sens->sens.name, 16, "%s-%d", name, cpu);
+
+               if (wf_register_sensor(&sens->sens)) {
+                       atomic_dec(&sat->refcnt);
+                       kfree(sens);
+               }
+       }
+
+       /* make the power sensors */
+       for (core = 0; core < 2; ++core) {
+               if (vsens[core] < 0 || isens[core] < 0)
+                       continue;
+               cpu = 2 * sat->nr + core;
+               sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL);
+               if (sens == NULL) {
+                       printk(KERN_ERR "wf_sat_create: couldn't create power "
+                              "sensor %d (no memory)\n", cpu);
+                       continue;
+               }
+               sens->index = vsens[core];
+               sens->index2 = isens[core];
+               sens->shift = 0;
+               sens->sat = sat;
+               atomic_inc(&sat->refcnt);
+               sens->sens.ops = &wf_sat_ops;
+               sens->sens.name = (char *) (sens + 1);
+               snprintf(sens->sens.name, 16, "cpu-power-%d", cpu);
+
+               if (wf_register_sensor(&sens->sens)) {
+                       atomic_dec(&sat->refcnt);
+                       kfree(sens);
+               }
+       }
+
+       if (sat->nr >= 0)
+               sats[sat->nr] = sat;
+
+       return;
+
+ fail:
+       kfree(sat);
+}
+
+static int wf_sat_attach(struct i2c_adapter *adapter)
+{
+       struct device_node *busnode, *dev = NULL;
+       struct pmac_i2c_bus *bus;
+
+       bus = pmac_i2c_adapter_to_bus(adapter);
+       if (bus == NULL)
+               return -ENODEV;
+       busnode = pmac_i2c_get_bus_node(bus);
+
+       while ((dev = of_get_next_child(busnode, dev)) != NULL)
+               if (device_is_compatible(dev, "smu-sat"))
+                       wf_sat_create(adapter, dev);
+       return 0;
+}
+
+static int wf_sat_detach(struct i2c_client *client)
+{
+       struct wf_sat *sat = i2c_to_sat(client);
+
+       /* XXX TODO */
+
+       sat->i2c.adapter = NULL;
+       return 0;
+}
+
+static int __init sat_sensors_init(void)
+{
+       int err;
+
+       err = i2c_add_driver(&wf_sat_driver);
+       if (err < 0)
+               return err;
+       return 0;
+}
+
+static void __exit sat_sensors_exit(void)
+{
+       i2c_del_driver(&wf_sat_driver);
+}
+
+module_init(sat_sensors_init);
+/*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */
+
+MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
+MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control");
+MODULE_LICENSE("GPL");
index 1a00d9c..bed25dc 100644 (file)
@@ -220,14 +220,29 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node)
            !strcmp(l, "CPU T-Diode")) {
                ads->sens.ops = &smu_cputemp_ops;
                ads->sens.name = "cpu-temp";
+               if (cpudiode == NULL) {
+                       DBG("wf: cpudiode partition (%02x) not found\n",
+                           SMU_SDB_CPUDIODE_ID);
+                       goto fail;
+               }
        } else if (!strcmp(c, "current-sensor") &&
                   !strcmp(l, "CPU Current")) {
                ads->sens.ops = &smu_cpuamp_ops;
                ads->sens.name = "cpu-current";
+               if (cpuvcp == NULL) {
+                       DBG("wf: cpuvcp partition (%02x) not found\n",
+                           SMU_SDB_CPUVCP_ID);
+                       goto fail;
+               }
        } else if (!strcmp(c, "voltage-sensor") &&
                   !strcmp(l, "CPU Voltage")) {
                ads->sens.ops = &smu_cpuvolt_ops;
                ads->sens.name = "cpu-voltage";
+               if (cpuvcp == NULL) {
+                       DBG("wf: cpuvcp partition (%02x) not found\n",
+                           SMU_SDB_CPUVCP_ID);
+                       goto fail;
+               }
        } else if (!strcmp(c, "power-sensor") &&
                   !strcmp(l, "Slots Power")) {
                ads->sens.ops = &smu_slotspow_ops;
@@ -365,29 +380,22 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps)
        return NULL;
 }
 
-static int smu_fetch_param_partitions(void)
+static void smu_fetch_param_partitions(void)
 {
        struct smu_sdbp_header *hdr;
 
        /* Get CPU voltage/current/power calibration data */
        hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL);
-       if (hdr == NULL) {
-               DBG("wf: cpuvcp partition (%02x) not found\n",
-                   SMU_SDB_CPUVCP_ID);
-               return -ENODEV;
+       if (hdr != NULL) {
+               cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
+               /* Keep version around */
+               cpuvcp_version = hdr->version;
        }
-       cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
-       /* Keep version around */
-       cpuvcp_version = hdr->version;
 
        /* Get CPU diode calibration data */
        hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL);
-       if (hdr == NULL) {
-               DBG("wf: cpudiode partition (%02x) not found\n",
-                   SMU_SDB_CPUDIODE_ID);
-               return -ENODEV;
-       }
-       cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
+       if (hdr != NULL)
+               cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
 
        /* Get slots power calibration data if any */
        hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL);
@@ -398,23 +406,18 @@ static int smu_fetch_param_partitions(void)
        hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL);
        if (hdr != NULL)
                debugswitches = (u8 *)&hdr[1];
-
-       return 0;
 }
 
 static int __init smu_sensors_init(void)
 {
        struct device_node *smu, *sensors, *s;
        struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL;
-       int rc;
 
        if (!smu_present())
                return -ENODEV;
 
        /* Get parameters partitions */
-       rc = smu_fetch_param_partitions();
-       if (rc)
-               return rc;
+       smu_fetch_param_partitions();
 
        smu = of_find_node_by_type(NULL, "smu");
        if (smu == NULL)
index 2583a86..2963605 100644 (file)
@@ -4,7 +4,7 @@ config DVB_B2C2_FLEXCOP
        select DVB_STV0299
        select DVB_MT352
        select DVB_MT312
-       select DVB_NXT2002
+       select DVB_NXT200X
        select DVB_STV0297
        select DVB_BCM3510
        select DVB_LGDT330X
index 344a3c8..7d7e161 100644 (file)
@@ -116,11 +116,9 @@ void flexcop_dma_free(struct flexcop_dma *dma);
 
 int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
 int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
 int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
-int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
 
 /* from flexcop-eeprom.c */
 /* the PCI part uses this call to get the MAC address, the USB part has its own */
index cf4ed1d..6f592bc 100644 (file)
@@ -169,38 +169,3 @@ int flexcop_dma_config_timer(struct flexcop_device *fc,
 }
 EXPORT_SYMBOL(flexcop_dma_config_timer);
 
-/* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc,
-               flexcop_dma_index_t no,
-               int onoff)
-{
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
-
-       deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
-       if (no & FC_DMA_1)
-               v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
-
-       if (no & FC_DMA_2)
-               v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
-
-       fc->write_ibi_reg(fc,ctrl_208,v);
-       deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
-
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
-
-int flexcop_dma_config_packet_count(struct flexcop_device *fc,
-               flexcop_dma_index_t dma_idx,
-               u8 packets)
-{
-       flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
-       flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
-
-       flexcop_dma_remap(fc,dma_idx,1);
-
-       v.dma_0x4_remap.DMA_maxpackets = packets;
-       fc->write_ibi_reg(fc,r,v);
-       return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config_packet_count);
index 0b940e1..390cc3a 100644 (file)
@@ -9,7 +9,7 @@
 
 #include "stv0299.h"
 #include "mt352.h"
-#include "nxt2002.h"
+#include "nxt200x.h"
 #include "bcm3510.h"
 #include "stv0297.h"
 #include "mt312.h"
@@ -343,9 +343,10 @@ static struct lgdt330x_config air2pc_atsc_hd5000_config = {
        .clock_polarity_flip = 1,
 };
 
-static struct nxt2002_config samsung_tbmv_config = {
+static struct nxt200x_config samsung_tbmv_config = {
        .demod_address    = 0x0a,
-       .request_firmware = flexcop_fe_request_firmware,
+       .pll_address      = 0xc2,
+       .pll_desc         = &dvb_pll_samsung_tbmv,
 };
 
 static struct bcm3510_config air2pc_atsc_first_gen_config = {
@@ -505,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
                info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
        } else
        /* try the air atsc 2nd generation (nxt2002) */
-       if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
+       if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
                fc->dev_type          = FC_AIR_ATSC2;
                info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
        } else
index 62282d8..167583b 100644 (file)
@@ -36,14 +36,14 @@ void flexcop_determine_revision(struct flexcop_device *fc)
        /* bus parts have to decide if hw pid filtering is used or not. */
 }
 
-const char *flexcop_revision_names[] = {
+static const char *flexcop_revision_names[] = {
        "Unkown chip",
        "FlexCopII",
        "FlexCopIIb",
        "FlexCopIII",
 };
 
-const char *flexcop_device_names[] = {
+static const char *flexcop_device_names[] = {
        "Unkown device",
        "Air2PC/AirStar 2 DVB-T",
        "Air2PC/AirStar 2 ATSC 1st generation",
@@ -54,7 +54,7 @@ const char *flexcop_device_names[] = {
        "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
 };
 
-const char *flexcop_bus_names[] = {
+static const char *flexcop_bus_names[] = {
        "USB",
        "PCI",
 };
index 2f76eb3..9bc40bd 100644 (file)
@@ -161,8 +161,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs)
                        fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
                u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
 
-               deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
-                               jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+               deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
+                               jiffies_to_usecs(jiffies - fc_pci->last_irq),
+                               v.raw, (unsigned long long)cur_addr, cur_pos,
+                               fc_pci->last_dma1_cur_pos);
                fc_pci->last_irq = jiffies;
 
                /* buffer end was reached, restarted from the beginning
index 3153f95..491f9bd 100644 (file)
@@ -16,8 +16,6 @@ typedef enum {
        FLEXCOP_III,
 } flexcop_revision_t;
 
-extern const char *flexcop_revision_names[];
-
 typedef enum {
        FC_UNK = 0,
        FC_AIR_DVB,
@@ -34,8 +32,6 @@ typedef enum {
        FC_PCI,
 } flexcop_bus_t;
 
-extern const char *flexcop_device_names[];
-
 /* FlexCop IBI Registers */
 #if defined(__LITTLE_ENDIAN)
        #include "flexcop_ibi_value_le.h"
index a04bb61..34c3189 100644 (file)
@@ -381,6 +381,23 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *
 
 EXPORT_SYMBOL(bt878_device_control);
 
+
+struct cards card_list[] __devinitdata = {
+
+       { 0x01010071, BTTV_BOARD_NEBULA_DIGITV,                 "Nebula Electronics DigiTV" },
+       { 0x07611461, BTTV_BOARD_AVDVBT_761,                    "AverMedia AverTV DVB-T 761" },
+       { 0x001c11bd, BTTV_BOARD_PINNACLESAT,                   "Pinnacle PCTV Sat" },
+       { 0x002611bd, BTTV_BOARD_TWINHAN_DST,                   "Pinnacle PCTV SAT CI" },
+       { 0x00011822, BTTV_BOARD_TWINHAN_DST,                   "Twinhan VisionPlus DVB" },
+       { 0xfc00270f, BTTV_BOARD_TWINHAN_DST,                   "ChainTech digitop DST-1000 DVB-S" },
+       { 0x07711461, BTTV_BOARD_AVDVBT_771,                    "AVermedia AverTV DVB-T 771" },
+       { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE,               "DViCO FusionHDTV DVB-T Lite" },
+       { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE,       "DViCO FusionHDTV 5 Lite" },
+       { 0x20007063, BTTV_BOARD_PC_HDTV,                       "pcHDTV HD-2000 TV"},
+       { 0, -1, NULL }
+};
+
+
 /***********************/
 /* PCI device handling */
 /***********************/
@@ -388,18 +405,41 @@ EXPORT_SYMBOL(bt878_device_control);
 static int __devinit bt878_probe(struct pci_dev *dev,
                                 const struct pci_device_id *pci_id)
 {
-       int result;
+       int result = 0, has_dvb = 0, i;
        unsigned char lat;
        struct bt878 *bt;
 #if defined(__powerpc__)
        unsigned int cmd;
 #endif
+       unsigned int cardid;
+       unsigned short id;
+       struct cards *dvb_cards;
 
        printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n",
               bt878_num);
        if (pci_enable_device(dev))
                return -EIO;
 
+       pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id);
+       cardid = id << 16;
+       pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id);
+       cardid |= id;
+
+       for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) {
+               if (cardid == dvb_cards->pci_id) {
+                       printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n",
+                               __func__, cardid, dvb_cards->name);
+                       has_dvb = 1;
+               }
+       }
+
+       if (!has_dvb) {
+               printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid);
+               result = -EINVAL;
+
+               goto fail0;
+       }
+
        bt = &bt878[bt878_num];
        bt->dev = dev;
        bt->nr = bt878_num;
@@ -416,6 +456,8 @@ static int __devinit bt878_probe(struct pci_dev *dev,
 
        pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
        pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+
+
        printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ",
               bt878_num, bt->id, bt->revision, dev->bus->number,
               PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
index a73baf0..9faf937 100644 (file)
 
 #define BT878_RISC_SYNC_MASK   (1 << 15)
 
+
+#define BTTV_BOARD_UNKNOWN                 0x00
+#define BTTV_BOARD_PINNACLESAT             0x5e
+#define BTTV_BOARD_NEBULA_DIGITV           0x68
+#define BTTV_BOARD_PC_HDTV                 0x70
+#define BTTV_BOARD_TWINHAN_DST             0x71
+#define BTTV_BOARD_AVDVBT_771              0x7b
+#define BTTV_BOARD_AVDVBT_761              0x7c
+#define BTTV_BOARD_DVICO_DVBT_LITE         0x80
+#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
+
+struct cards {
+       __u32 pci_id;
+       __u16 card_id;
+       char  *name;
+};
+
 extern int bt878_num;
 
 struct bt878 {
index 90a69d3..d3df120 100644 (file)
@@ -83,12 +83,18 @@ config DVB_USB_UMT_010
          Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
 
 config DVB_USB_CXUSB
-       tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
+       tristate "Conexant USB2.0 hybrid reference design support"
        depends on DVB_USB
        select DVB_CX22702
+       select DVB_LGDT330X
+       select DVB_MT352
        help
-         Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
-         only the DVB-T part is supported.
+         Say Y here to support the Conexant USB2.0 hybrid reference design.
+         Currently, only DVB and ATSC modes are supported, analog mode
+         shall be added in the future. Devices that require this module:
+
+         Medion MD95700 hybrid USB2.0 device.
+         DViCO FusionHDTV (Bluebird) USB2.0 devices
 
 config DVB_USB_DIGITV
        tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
index a7fb06f..f327fac 100644 (file)
@@ -184,7 +184,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
        return 0;
 }
 
-struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
+static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
        { 0xfe, 0x02, KEY_TV },
        { 0xfe, 0x0e, KEY_MP3 },
        { 0xfe, 0x1a, KEY_DVD },
@@ -234,7 +234,7 @@ struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
 
 static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
 {
-       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x38 };
+       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
        static u8 reset []         = { RESET,      0x80 };
        static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
        static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
@@ -255,7 +255,7 @@ static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
 
 static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
 {      /* used in both lgz201 and th7579 */
-       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
+       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x29 };
        static u8 reset []         = { RESET,      0x80 };
        static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
        static u8 agc_cfg []       = { AGC_TARGET, 0x24, 0x20 };
@@ -273,7 +273,7 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
        return 0;
 }
 
-struct cx22702_config cxusb_cx22702_config = {
+static struct cx22702_config cxusb_cx22702_config = {
        .demod_address = 0x63,
 
        .output_mode = CX22702_PARALLEL_OUTPUT,
@@ -282,13 +282,13 @@ struct cx22702_config cxusb_cx22702_config = {
        .pll_set  = dvb_usb_pll_set_i2c,
 };
 
-struct lgdt330x_config cxusb_lgdt330x_config = {
+static struct lgdt330x_config cxusb_lgdt330x_config = {
        .demod_address = 0x0e,
        .demod_chip    = LGDT3303,
        .pll_set       = dvb_usb_pll_set_i2c,
 };
 
-struct mt352_config cxusb_dee1601_config = {
+static struct mt352_config cxusb_dee1601_config = {
        .demod_address = 0x0f,
        .demod_init    = cxusb_dee1601_demod_init,
        .pll_set       = dvb_usb_pll_set,
index e6c55c9..caa1346 100644 (file)
@@ -175,11 +175,13 @@ static int digitv_probe(struct usb_interface *intf,
        if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) {
                u8 b[4] = { 0 };
 
-               b[0] = 1;
-               digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
+               if (d != NULL) { /* do that only when the firmware is loaded */
+                       b[0] = 1;
+                       digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
 
-               b[0] = 0;
-               digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+                       b[0] = 0;
+                       digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
+               }
        }
        return ret;
 }
@@ -194,7 +196,7 @@ static struct dvb_usb_properties digitv_properties = {
        .caps = DVB_USB_IS_AN_I2C_ADAPTER,
 
        .usb_ctrl = CYPRESS_FX2,
-       .firmware = "dvb-usb-digitv-01.fw",
+       .firmware = "dvb-usb-digitv-02.fw",
 
        .size_of_priv     = 0,
 
@@ -229,6 +231,7 @@ static struct dvb_usb_properties digitv_properties = {
                        { &digitv_table[0], NULL },
                        { NULL },
                },
+               { NULL },
        }
 };
 
index 130ea7f..12ebaf8 100644 (file)
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = {
                  .cold_ids = { &dtt200u_usb_table[0], NULL },
                  .warm_ids = { &dtt200u_usb_table[1], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = {
                  .cold_ids = { &dtt200u_usb_table[2], NULL },
                  .warm_ids = { &dtt200u_usb_table[3], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
index 8535895..9222b0a 100644 (file)
@@ -24,6 +24,9 @@ static struct usb_cypress_controller cypress[] = {
        { .id = CYPRESS_FX2,     .name = "Cypress FX2",     .cpu_cs_register = 0xe600 },
 };
 
+static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+                              int *pos);
+
 /*
  * load a firmware packet to the device
  */
@@ -112,7 +115,8 @@ int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties
        return ret;
 }
 
-int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos)
+static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
+                              int *pos)
 {
        u8 *b = (u8 *) &fw->data[*pos];
        int data_offs = 4;
@@ -142,5 +146,3 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos)
 
        return *pos;
 }
-EXPORT_SYMBOL(dvb_usb_get_hexline);
-
index dd56839..5e5d21a 100644 (file)
@@ -341,7 +341,6 @@ struct hexline {
        u8 data[255];
        u8 chk;
 };
-extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *);
 extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
 
 #endif
index afa00fd..4a95eca 100644 (file)
@@ -53,7 +53,8 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8
        return ret;
 }
 
-int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+                            u16 index, u8 *b, int blen)
 {
        deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
        debug_dump(b,blen,deb_xfer);
@@ -88,7 +89,8 @@ unlock:
        return ret;
 }
 
-int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec)
+static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
+                               int olen, u8 *i, int ilen, int msec)
 {
        u8 bout[olen+2];
        u8 bin[ilen+1];
index a808d48..c2f97f9 100644 (file)
@@ -101,8 +101,6 @@ extern int dvb_usb_vp702x_debug;
 extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
 
 extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
-extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec);
 extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
-extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
 
 #endif
index 5242cca..9999336 100644 (file)
 
 struct vp7045_fe_state {
        struct dvb_frontend fe;
+       struct dvb_frontend_ops ops;
+
        struct dvb_usb_device *d;
 };
 
-
 static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
 {
        struct vp7045_fe_state *state = fe->demodulator_priv;
@@ -150,7 +151,8 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
                goto error;
 
        s->d = d;
-       s->fe.ops = &vp7045_fe_ops;
+       memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
+       s->fe.ops = &s->ops;
        s->fe.demodulator_priv = s;
 
        goto success;
index 0282049..3835235 100644 (file)
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = {
                  .cold_ids = { &vp7045_usb_table[2], NULL },
                  .warm_ids = { &vp7045_usb_table[3], NULL },
                },
-               { 0 },
+               { NULL },
        }
 };
 
index db3a8b4..76b6a2a 100644 (file)
@@ -28,12 +28,6 @@ config DVB_TDA8083
        help
          A DVB-S tuner module. Say Y when you want to support this frontend.
 
-config DVB_TDA80XX
-       tristate "Philips TDA8044 or TDA8083 based"
-       depends on DVB_CORE
-       help
-         A DVB-S tuner module. Say Y when you want to support this frontend.
-
 config DVB_MT312
        tristate "Zarlink MT312 based"
        depends on DVB_CORE
@@ -139,12 +133,6 @@ config DVB_DIB3000MC
 comment "DVB-C (cable) frontends"
        depends on DVB_CORE
 
-config DVB_ATMEL_AT76C651
-       tristate "Atmel AT76C651 based"
-       depends on DVB_CORE
-       help
-         A DVB-C tuner module. Say Y when you want to support this frontend.
-
 config DVB_VES1820
        tristate "VLSI VES1820 based"
        depends on DVB_CORE
@@ -166,18 +154,6 @@ config DVB_STV0297
 comment "ATSC (North American/Korean Terresterial DTV) frontends"
        depends on DVB_CORE
 
-config DVB_NXT2002
-       tristate "Nxt2002 based"
-       depends on DVB_CORE
-       select FW_LOADER
-       help
-         An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
-
-         This driver needs external firmware. Please use the command
-         "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
-         download/extract it, and then copy it to /usr/lib/hotplug/firmware
-         or /lib/firmware (depending on configuration of firmware hotplug).
-
 config DVB_NXT200X
        tristate "Nextwave NXT2002/NXT2004 based"
        depends on DVB_CORE
index 615ec83..1af769c 100644 (file)
@@ -8,7 +8,6 @@ obj-$(CONFIG_DVB_CORE) += dvb-pll.o
 obj-$(CONFIG_DVB_STV0299) += stv0299.o
 obj-$(CONFIG_DVB_SP8870) += sp8870.o
 obj-$(CONFIG_DVB_CX22700) += cx22700.o
-obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o
 obj-$(CONFIG_DVB_CX24110) += cx24110.o
 obj-$(CONFIG_DVB_TDA8083) += tda8083.o
 obj-$(CONFIG_DVB_L64781) += l64781.o
@@ -22,10 +21,8 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o
 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
-obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
-obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
 obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
 obj-$(CONFIG_DVB_OR51211) += or51211.o
 obj-$(CONFIG_DVB_OR51132) += or51132.o
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
deleted file mode 100644 (file)
index 8e0f4b3..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * at76c651.c
- *
- * Atmel DVB-C Frontend Driver (at76c651/tua6010xs)
- *
- * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
- *             & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *             & 2003 Wolfram Joost <dbox2@frokaschwei.de>
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * AT76C651
- * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
- * http://www.atmel.com/atmel/acrobat/doc1320.pdf
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/bitops.h>
-#include "dvb_frontend.h"
-#include "at76c651.h"
-
-
-struct at76c651_state {
-
-       struct i2c_adapter* i2c;
-
-       struct dvb_frontend_ops ops;
-
-       const struct at76c651_config* config;
-
-       struct dvb_frontend frontend;
-
-       /* revision of the chip */
-       u8 revision;
-
-       /* last QAM value set */
-       u8 qam;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "at76c651: " args); \
-       } while (0)
-
-
-#if ! defined(__powerpc__)
-static __inline__ int __ilog2(unsigned long x)
-{
-       int i;
-
-       if (x == 0)
-               return -1;
-
-       for (i = 0; x != 0; i++)
-               x >>= 1;
-
-       return i - 1;
-}
-#endif
-
-static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data)
-{
-       int ret;
-       u8 buf[] = { reg, data };
-       struct i2c_msg msg =
-               { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: writereg error "
-                       "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-                       __FUNCTION__, reg, data, ret);
-
-       msleep(10);
-
-       return (ret != 1) ? -EREMOTEIO : 0;
-}
-
-static u8 at76c651_readreg(struct at76c651_state* state, u8 reg)
-{
-       int ret;
-       u8 val;
-       struct i2c_msg msg[] = {
-               { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
-               { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }
-       };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
-
-       return val;
-}
-
-static int at76c651_reset(struct at76c651_state* state)
-{
-       return at76c651_writereg(state, 0x07, 0x01);
-}
-
-static void at76c651_disable_interrupts(struct at76c651_state* state)
-{
-       at76c651_writereg(state, 0x0b, 0x00);
-}
-
-static int at76c651_set_auto_config(struct at76c651_state *state)
-{
-       /*
-        * Autoconfig
-        */
-
-       at76c651_writereg(state, 0x06, 0x01);
-
-       /*
-        * Performance optimizations, should be done after autoconfig
-        */
-
-       at76c651_writereg(state, 0x10, 0x06);
-       at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10);
-       at76c651_writereg(state, 0x15, 0x28);
-       at76c651_writereg(state, 0x20, 0x09);
-       at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90);
-       at76c651_writereg(state, 0x30, 0x90);
-       if (state->qam == 5)
-               at76c651_writereg(state, 0x35, 0x2A);
-
-       /*
-        * Initialize A/D-converter
-        */
-
-       if (state->revision == 0x11) {
-               at76c651_writereg(state, 0x2E, 0x38);
-               at76c651_writereg(state, 0x2F, 0x13);
-       }
-
-       at76c651_disable_interrupts(state);
-
-       /*
-        * Restart operation
-        */
-
-       at76c651_reset(state);
-
-       return 0;
-}
-
-static void at76c651_set_bbfreq(struct at76c651_state* state)
-{
-       at76c651_writereg(state, 0x04, 0x3f);
-       at76c651_writereg(state, 0x05, 0xee);
-}
-
-static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate)
-{
-       u8 exponent;
-       u32 mantissa;
-
-       if (symbol_rate > 9360000)
-               return -EINVAL;
-
-       /*
-        * FREF = 57800 kHz
-        * exponent = 10 + floor (log2(symbol_rate / FREF))
-        * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent))
-        */
-
-       exponent = __ilog2((symbol_rate << 4) / 903125);
-       mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289;
-
-       at76c651_writereg(state, 0x00, mantissa >> 13);
-       at76c651_writereg(state, 0x01, mantissa >> 5);
-       at76c651_writereg(state, 0x02, (mantissa << 3) | exponent);
-
-       return 0;
-}
-
-static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam)
-{
-       switch (qam) {
-       case QPSK:
-               state->qam = 0x02;
-               break;
-       case QAM_16:
-               state->qam = 0x04;
-               break;
-       case QAM_32:
-               state->qam = 0x05;
-               break;
-       case QAM_64:
-               state->qam = 0x06;
-               break;
-       case QAM_128:
-               state->qam = 0x07;
-               break;
-       case QAM_256:
-               state->qam = 0x08;
-               break;
-#if 0
-       case QAM_512:
-               state->qam = 0x09;
-               break;
-       case QAM_1024:
-               state->qam = 0x0A;
-               break;
-#endif
-       default:
-               return -EINVAL;
-
-       }
-
-       return at76c651_writereg(state, 0x03, state->qam);
-}
-
-static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion)
-{
-       u8 feciqinv = at76c651_readreg(state, 0x60);
-
-       switch (inversion) {
-       case INVERSION_OFF:
-               feciqinv |= 0x02;
-               feciqinv &= 0xFE;
-               break;
-
-       case INVERSION_ON:
-               feciqinv |= 0x03;
-               break;
-
-       case INVERSION_AUTO:
-               feciqinv &= 0xFC;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return at76c651_writereg(state, 0x60, feciqinv);
-}
-
-static int at76c651_set_parameters(struct dvb_frontend* fe,
-                                  struct dvb_frontend_parameters *p)
-{
-       int ret;
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       at76c651_writereg(state, 0x0c, 0xc3);
-       state->config->pll_set(fe, p);
-       at76c651_writereg(state, 0x0c, 0xc2);
-
-       if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate)))
-               return ret;
-
-       if ((ret = at76c651_set_inversion(state, p->inversion)))
-               return ret;
-
-       return at76c651_set_auto_config(state);
-}
-
-static int at76c651_set_defaults(struct dvb_frontend* fe)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       at76c651_set_symbol_rate(state, 6900000);
-       at76c651_set_qam(state, QAM_64);
-       at76c651_set_bbfreq(state);
-       at76c651_set_auto_config(state);
-
-       if (state->config->pll_init) {
-               at76c651_writereg(state, 0x0c, 0xc3);
-               state->config->pll_init(fe);
-               at76c651_writereg(state, 0x0c, 0xc2);
-       }
-
-       return 0;
-}
-
-static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-       u8 sync;
-
-       /*
-        * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0)
-        */
-       sync = at76c651_readreg(state, 0x80);
-       *status = 0;
-
-       if (sync & (0x04 | 0x10))       /* AGC1 || TIM */
-               *status |= FE_HAS_SIGNAL;
-       if (sync & 0x10)                /* TIM */
-               *status |= FE_HAS_CARRIER;
-       if (sync & 0x80)                /* FEC */
-               *status |= FE_HAS_VITERBI;
-       if (sync & 0x40)                /* CAR */
-               *status |= FE_HAS_SYNC;
-       if ((sync & 0xF0) == 0xF0)      /* TIM && EQU && CAR && FEC */
-               *status |= FE_HAS_LOCK;
-
-       return 0;
-}
-
-static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16;
-       *ber |= at76c651_readreg(state, 0x82) << 8;
-       *ber |= at76c651_readreg(state, 0x83);
-       *ber *= 10;
-
-       return 0;
-}
-
-static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       u8 gain = ~at76c651_readreg(state, 0x91);
-       *strength = (gain << 8) | gain;
-
-       return 0;
-}
-
-static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       *snr = 0xFFFF -
-           ((at76c651_readreg(state, 0x8F) << 8) |
-            at76c651_readreg(state, 0x90));
-
-       return 0;
-}
-
-static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-
-       *ucblocks = at76c651_readreg(state, 0x82);
-
-       return 0;
-}
-
-static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings)
-{
-       fesettings->min_delay_ms = 50;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void at76c651_release(struct dvb_frontend* fe)
-{
-       struct at76c651_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops at76c651_ops;
-
-struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
-                                    struct i2c_adapter* i2c)
-{
-       struct at76c651_state* state = NULL;
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->qam = 0;
-
-       /* check if the demod is there */
-       if (at76c651_readreg(state, 0x0e) != 0x65) goto error;
-
-       /* finalise state setup */
-       state->i2c = i2c;
-       state->revision = at76c651_readreg(state, 0x0f) & 0xfe;
-       memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops));
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops at76c651_ops = {
-
-       .info = {
-               .name = "Atmel AT76C651B DVB-C",
-               .type = FE_QAM,
-               .frequency_min = 48250000,
-               .frequency_max = 863250000,
-               .frequency_stepsize = 62500,
-               /*.frequency_tolerance = */     /* FIXME: 12% of SR */
-               .symbol_rate_min = 0,           /* FIXME */
-               .symbol_rate_max = 9360000,     /* FIXME */
-               .symbol_rate_tolerance = 4000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                   FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                   FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-                   FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                   FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 |
-                   FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER
-       },
-
-       .release = at76c651_release,
-
-       .init = at76c651_set_defaults,
-
-       .set_frontend = at76c651_set_parameters,
-       .get_tune_settings = at76c651_get_tune_settings,
-
-       .read_status = at76c651_read_status,
-       .read_ber = at76c651_read_ber,
-       .read_signal_strength = at76c651_read_signal_strength,
-       .read_snr = at76c651_read_snr,
-       .read_ucblocks = at76c651_read_ucblocks,
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver");
-MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(at76c651_attach);
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h
deleted file mode 100644 (file)
index 34054df..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * at76c651.c
- *
- * Atmel DVB-C Frontend Driver (at76c651)
- *
- * Copyright (C) 2001 fnbrd <fnbrd@gmx.de>
- *             & 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *             & 2003 Wolfram Joost <dbox2@frokaschwei.de>
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * AT76C651
- * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf
- * http://www.atmel.com/atmel/acrobat/doc1320.pdf
- */
-
-#ifndef AT76C651_H
-#define AT76C651_H
-
-#include <linux/dvb/frontend.h>
-
-struct at76c651_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* PLL maintenance */
-       int (*pll_init)(struct dvb_frontend* fe);
-       int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-};
-
-extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config,
-                                           struct i2c_adapter* i2c);
-
-#endif // AT76C651_H
index 1b9934e..4dcb605 100644 (file)
@@ -326,11 +326,11 @@ struct dvb_pll_desc dvb_pll_tuv1236d = {
 };
 EXPORT_SYMBOL(dvb_pll_tuv1236d);
 
-/* Samsung TBMV30111IN
+/* Samsung TBMV30111IN / TBMV30712IN1
  * used in Air2PC ATSC - 2nd generation (nxt2002)
  */
-struct dvb_pll_desc dvb_pll_tbmv30111in = {
-       .name = "Samsung TBMV30111IN",
+struct dvb_pll_desc dvb_pll_samsung_tbmv = {
+       .name = "Samsung TBMV30111IN / TBMV30712IN1",
        .min = 54000000,
        .max = 860000000,
        .count = 6,
@@ -343,7 +343,7 @@ struct dvb_pll_desc dvb_pll_tbmv30111in = {
                { 999999999, 44000000, 166666, 0xfc, 0x02 },
        }
 };
-EXPORT_SYMBOL(dvb_pll_tbmv30111in);
+EXPORT_SYMBOL(dvb_pll_samsung_tbmv);
 
 /*
  * Philips SD1878 Tuner.
index f682c09..bb8d4b4 100644 (file)
@@ -38,7 +38,7 @@ extern struct dvb_pll_desc dvb_pll_tded4;
 
 extern struct dvb_pll_desc dvb_pll_tuv1236d;
 extern struct dvb_pll_desc dvb_pll_tdhu2;
-extern struct dvb_pll_desc dvb_pll_tbmv30111in;
+extern struct dvb_pll_desc dvb_pll_samsung_tbmv;
 extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261;
 
 int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
deleted file mode 100644 (file)
index 4f263e6..0000000
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
-    Support for B2C2/BBTI Technisat Air2PC - ATSC
-
-    Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net>
-
-    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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/*
- * This driver needs external firmware. Please use the command
- * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to
- * download/extract it, and then copy it to /usr/lib/hotplug/firmware
- * or /lib/firmware (depending on configuration of firmware hotplug).
- */
-#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
-#define CRC_CCIT_MASK 0x1021
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/device.h>
-#include <linux/firmware.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-#include "dvb_frontend.h"
-#include "nxt2002.h"
-
-struct nxt2002_state {
-
-       struct i2c_adapter* i2c;
-       struct dvb_frontend_ops ops;
-       const struct nxt2002_config* config;
-       struct dvb_frontend frontend;
-
-       /* demodulator private data */
-       u8 initialised:1;
-};
-
-static int debug;
-#define dprintk(args...) \
-       do { \
-               if (debug) printk(KERN_DEBUG "nxt2002: " args); \
-       } while (0)
-
-static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len)
-{
-       /* probbably a much better way or doing this */
-       u8 buf2 [256],x;
-       int err;
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
-
-       buf2[0] = reg;
-       for (x = 0 ; x < len ; x++)
-               buf2[x+1] = buf[x];
-
-       if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
-               printk ("%s: i2c write error (addr %02x, err == %i)\n",
-                       __FUNCTION__, state->config->demod_address, err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len)
-{
-       u8 reg2 [] = { reg };
-
-       struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
-                       { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
-
-       int err;
-
-       if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
-               printk ("%s: i2c read error (addr %02x, err == %i)\n",
-                       __FUNCTION__, state->config->demod_address, err);
-               return -EREMOTEIO;
-       }
-
-       return 0;
-}
-
-static u16 nxt2002_crc(u16 crc, u8 c)
-{
-
-       u8 i;
-       u16 input = (u16) c & 0xFF;
-
-       input<<=8;
-       for(i=0 ;i<8 ;i++) {
-               if((crc ^ input) & 0x8000)
-                       crc=(crc<<1)^CRC_CCIT_MASK;
-               else
-                       crc<<=1;
-       input<<=1;
-       }
-       return crc;
-}
-
-static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
-{
-       u8 buf;
-       dprintk("%s\n", __FUNCTION__);
-
-       /* set multi register length */
-       i2c_writebytes(state,0x34,&len,1);
-
-       /* set mutli register register */
-       i2c_writebytes(state,0x35,&reg,1);
-
-       /* send the actual data */
-       i2c_writebytes(state,0x36,data,len);
-
-       /* toggle the multireg write bit*/
-       buf = 0x02;
-       i2c_writebytes(state,0x21,&buf,1);
-
-       i2c_readbytes(state,0x21,&buf,1);
-
-       if ((buf & 0x02) == 0)
-               return 0;
-
-       dprintk("Error writing multireg register %02X\n",reg);
-
-       return 0;
-}
-
-static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len)
-{
-       u8 len2;
-       dprintk("%s\n", __FUNCTION__);
-
-       /* set multi register length */
-       len2 = len & 0x80;
-       i2c_writebytes(state,0x34,&len2,1);
-
-       /* set mutli register register */
-       i2c_writebytes(state,0x35,&reg,1);
-
-       /* send the actual data */
-       i2c_readbytes(state,reg,data,len);
-
-       return 0;
-}
-
-static void nxt2002_microcontroller_stop (struct nxt2002_state* state)
-{
-       u8 buf[2],counter = 0;
-       dprintk("%s\n", __FUNCTION__);
-
-       buf[0] = 0x80;
-       i2c_writebytes(state,0x22,buf,1);
-
-       while (counter < 20) {
-               i2c_readbytes(state,0x31,buf,1);
-               if (buf[0] & 0x40)
-                       return;
-               msleep(10);
-               counter++;
-       }
-
-       dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n");
-       return;
-}
-
-static void nxt2002_microcontroller_start (struct nxt2002_state* state)
-{
-       u8 buf;
-       dprintk("%s\n", __FUNCTION__);
-
-       buf = 0x00;
-       i2c_writebytes(state,0x22,&buf,1);
-}
-
-static int nxt2002_writetuner (struct nxt2002_state* state, u8* data)
-{
-       u8 buf,count = 0;
-
-       dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]);
-
-       dprintk("%s\n", __FUNCTION__);
-       /* stop the micro first */
-       nxt2002_microcontroller_stop(state);
-
-       /* set the i2c transfer speed to the tuner */
-       buf = 0x03;
-       i2c_writebytes(state,0x20,&buf,1);
-
-       /* setup to transfer 4 bytes via i2c */
-       buf = 0x04;
-       i2c_writebytes(state,0x34,&buf,1);
-
-       /* write actual tuner bytes */
-       i2c_writebytes(state,0x36,data,4);
-
-       /* set tuner i2c address */
-       buf = 0xC2;
-       i2c_writebytes(state,0x35,&buf,1);
-
-       /* write UC Opmode to begin transfer */
-       buf = 0x80;
-       i2c_writebytes(state,0x21,&buf,1);
-
-       while (count < 20) {
-               i2c_readbytes(state,0x21,&buf,1);
-               if ((buf & 0x80)== 0x00)
-                       return 0;
-               msleep(100);
-               count++;
-       }
-
-       printk("nxt2002: timeout error writing tuner\n");
-       return 0;
-}
-
-static void nxt2002_agc_reset(struct nxt2002_state* state)
-{
-       u8 buf;
-       dprintk("%s\n", __FUNCTION__);
-
-       buf = 0x08;
-       i2c_writebytes(state,0x08,&buf,1);
-
-       buf = 0x00;
-       i2c_writebytes(state,0x08,&buf,1);
-
-       return;
-}
-
-static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
-{
-
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 buf[256],written = 0,chunkpos = 0;
-       u16 rambase,position,crc = 0;
-
-       dprintk("%s\n", __FUNCTION__);
-       dprintk("Firmware is %zu bytes\n",fw->size);
-
-       /* Get the RAM base for this nxt2002 */
-       i2c_readbytes(state,0x10,buf,1);
-
-       if (buf[0] & 0x10)
-               rambase = 0x1000;
-       else
-               rambase = 0x0000;
-
-       dprintk("rambase on this nxt2002 is %04X\n",rambase);
-
-       /* Hold the micro in reset while loading firmware */
-       buf[0] = 0x80;
-       i2c_writebytes(state,0x2B,buf,1);
-
-       for (position = 0; position < fw->size ; position++) {
-               if (written == 0) {
-                       crc = 0;
-                       chunkpos = 0x28;
-                       buf[0] = ((rambase + position) >> 8);
-                       buf[1] = (rambase + position) & 0xFF;
-                       buf[2] = 0x81;
-                       /* write starting address */
-                       i2c_writebytes(state,0x29,buf,3);
-               }
-               written++;
-               chunkpos++;
-
-               if ((written % 4) == 0)
-                       i2c_writebytes(state,chunkpos,&fw->data[position-3],4);
-
-               crc = nxt2002_crc(crc,fw->data[position]);
-
-               if ((written == 255) || (position+1 == fw->size)) {
-                       /* write remaining bytes of firmware */
-                       i2c_writebytes(state, chunkpos+4-(written %4),
-                               &fw->data[position-(written %4) + 1],
-                               written %4);
-                       buf[0] = crc << 8;
-                       buf[1] = crc & 0xFF;
-
-                       /* write crc */
-                       i2c_writebytes(state,0x2C,buf,2);
-
-                       /* do a read to stop things */
-                       i2c_readbytes(state,0x2A,buf,1);
-
-                       /* set transfer mode to complete */
-                       buf[0] = 0x80;
-                       i2c_writebytes(state,0x2B,buf,1);
-
-                       written = 0;
-               }
-       }
-
-       printk ("done.\n");
-       return 0;
-};
-
-static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe,
-                                            struct dvb_frontend_parameters *p)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u32 freq = 0;
-       u16 tunerfreq = 0;
-       u8 buf[4];
-
-       freq = 44000 + ( p->frequency / 1000 );
-
-       dprintk("freq = %d      p->frequency = %d\n",freq,p->frequency);
-
-       tunerfreq = freq * 24/4000;
-
-       buf[0] = (tunerfreq >> 8) & 0x7F;
-       buf[1] = (tunerfreq & 0xFF);
-
-       if (p->frequency <= 214000000) {
-               buf[2] = 0x84 + (0x06 << 3);
-               buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02;
-       } else if (p->frequency <= 721000000) {
-               buf[2] = 0x84 + (0x07 << 3);
-               buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08;
-       } else if (p->frequency <= 841000000) {
-               buf[2] = 0x84 + (0x0E << 3);
-               buf[3] = 0x08;
-       } else {
-               buf[2] = 0x84 + (0x0F << 3);
-               buf[3] = 0x02;
-       }
-
-       /* write frequency information */
-       nxt2002_writetuner(state,buf);
-
-       /* reset the agc now that tuning has been completed */
-       nxt2002_agc_reset(state);
-
-       /* set target power level */
-       switch (p->u.vsb.modulation) {
-               case QAM_64:
-               case QAM_256:
-                               buf[0] = 0x74;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x70;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       i2c_writebytes(state,0x42,buf,1);
-
-       /* configure sdm */
-       buf[0] = 0x87;
-       i2c_writebytes(state,0x57,buf,1);
-
-       /* write sdm1 input */
-       buf[0] = 0x10;
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x58,buf,2);
-
-       /* write sdmx input */
-       switch (p->u.vsb.modulation) {
-               case QAM_64:
-                               buf[0] = 0x68;
-                               break;
-               case QAM_256:
-                               buf[0] = 0x64;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x60;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x5C,buf,2);
-
-       /* write adc power lpf fc */
-       buf[0] = 0x05;
-       i2c_writebytes(state,0x43,buf,1);
-
-       /* write adc power lpf fc */
-       buf[0] = 0x05;
-       i2c_writebytes(state,0x43,buf,1);
-
-       /* write accumulator2 input */
-       buf[0] = 0x80;
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x4B,buf,2);
-
-       /* write kg1 */
-       buf[0] = 0x00;
-       i2c_writebytes(state,0x4D,buf,1);
-
-       /* write sdm12 lpf fc */
-       buf[0] = 0x44;
-       i2c_writebytes(state,0x55,buf,1);
-
-       /* write agc control reg */
-       buf[0] = 0x04;
-       i2c_writebytes(state,0x41,buf,1);
-
-       /* write agc ucgp0 */
-       switch (p->u.vsb.modulation) {
-               case QAM_64:
-                               buf[0] = 0x02;
-                               break;
-               case QAM_256:
-                               buf[0] = 0x03;
-                               break;
-               case VSB_8:
-                               buf[0] = 0x00;
-                               break;
-               default:
-                               return -EINVAL;
-                               break;
-       }
-       i2c_writebytes(state,0x30,buf,1);
-
-       /* write agc control reg */
-       buf[0] = 0x00;
-       i2c_writebytes(state,0x41,buf,1);
-
-       /* write accumulator2 input */
-       buf[0] = 0x80;
-       buf[1] = 0x00;
-       nxt2002_writereg_multibyte(state,0x49,buf,2);
-       nxt2002_writereg_multibyte(state,0x4B,buf,2);
-
-       /* write agc control reg */
-       buf[0] = 0x04;
-       i2c_writebytes(state,0x41,buf,1);
-
-       nxt2002_microcontroller_start(state);
-
-       /* adjacent channel detection should be done here, but I don't
-       have any stations with this need so I cannot test it */
-
-       return 0;
-}
-
-static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 lock;
-       i2c_readbytes(state,0x31,&lock,1);
-
-       *status = 0;
-       if (lock & 0x20) {
-               *status |= FE_HAS_SIGNAL;
-               *status |= FE_HAS_CARRIER;
-               *status |= FE_HAS_VITERBI;
-               *status |= FE_HAS_SYNC;
-               *status |= FE_HAS_LOCK;
-       }
-       return 0;
-}
-
-static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[3];
-
-       nxt2002_readreg_multibyte(state,0xE6,b,3);
-
-       *ber = ((b[0] << 8) + b[1]) * 8;
-
-       return 0;
-}
-
-static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[2];
-       u16 temp = 0;
-
-       /* setup to read cluster variance */
-       b[0] = 0x00;
-       i2c_writebytes(state,0xA1,b,1);
-
-       /* get multreg val */
-       nxt2002_readreg_multibyte(state,0xA6,b,2);
-
-       temp = (b[0] << 8) | b[1];
-       *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
-
-       return 0;
-}
-
-static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[2];
-       u16 temp = 0, temp2;
-       u32 snrdb = 0;
-
-       /* setup to read cluster variance */
-       b[0] = 0x00;
-       i2c_writebytes(state,0xA1,b,1);
-
-       /* get multreg val from 0xA6 */
-       nxt2002_readreg_multibyte(state,0xA6,b,2);
-
-       temp = (b[0] << 8) | b[1];
-       temp2 = 0x7FFF - temp;
-
-       /* snr will be in db */
-       if (temp2 > 0x7F00)
-               snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
-       else if (temp2 > 0x7EC0)
-               snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
-       else if (temp2 > 0x7C00)
-               snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
-       else
-               snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
-
-       /* the value reported back from the frontend will be FFFF=32db 0000=0db */
-
-       *snr = snrdb * (0xFFFF/32000);
-
-       return 0;
-}
-
-static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       u8 b[3];
-
-       nxt2002_readreg_multibyte(state,0xE6,b,3);
-       *ucblocks = b[2];
-
-       return 0;
-}
-
-static int nxt2002_sleep(struct dvb_frontend* fe)
-{
-       return 0;
-}
-
-static int nxt2002_init(struct dvb_frontend* fe)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       const struct firmware *fw;
-       int ret;
-       u8 buf[2];
-
-       if (!state->initialised) {
-               /* request the firmware, this will block until someone uploads it */
-               printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
-               ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE);
-               printk("nxt2002: Waiting for firmware upload(2)...\n");
-               if (ret) {
-                       printk("nxt2002: no firmware upload (timeout or file not found?)\n");
-                       return ret;
-               }
-
-               ret = nxt2002_load_firmware(fe, fw);
-               if (ret) {
-                       printk("nxt2002: writing firmware to device failed\n");
-                       release_firmware(fw);
-                       return ret;
-               }
-               printk("nxt2002: firmware upload complete\n");
-
-               /* Put the micro into reset */
-               nxt2002_microcontroller_stop(state);
-
-               /* ensure transfer is complete */
-               buf[0]=0;
-               i2c_writebytes(state,0x2B,buf,1);
-
-               /* Put the micro into reset for real this time */
-               nxt2002_microcontroller_stop(state);
-
-               /* soft reset everything (agc,frontend,eq,fec)*/
-               buf[0] = 0x0F;
-               i2c_writebytes(state,0x08,buf,1);
-               buf[0] = 0x00;
-               i2c_writebytes(state,0x08,buf,1);
-
-               /* write agc sdm configure */
-               buf[0] = 0xF1;
-               i2c_writebytes(state,0x57,buf,1);
-
-               /* write mod output format */
-               buf[0] = 0x20;
-               i2c_writebytes(state,0x09,buf,1);
-
-               /* write fec mpeg mode */
-               buf[0] = 0x7E;
-               buf[1] = 0x00;
-               i2c_writebytes(state,0xE9,buf,2);
-
-               /* write mux selection */
-               buf[0] = 0x00;
-               i2c_writebytes(state,0xCC,buf,1);
-
-               state->initialised = 1;
-       }
-
-       return 0;
-}
-
-static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
-{
-       fesettings->min_delay_ms = 500;
-       fesettings->step_size = 0;
-       fesettings->max_drift = 0;
-       return 0;
-}
-
-static void nxt2002_release(struct dvb_frontend* fe)
-{
-       struct nxt2002_state* state = fe->demodulator_priv;
-       kfree(state);
-}
-
-static struct dvb_frontend_ops nxt2002_ops;
-
-struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
-                                  struct i2c_adapter* i2c)
-{
-       struct nxt2002_state* state = NULL;
-       u8 buf [] = {0,0,0,0,0};
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
-       state->initialised = 0;
-
-       /* Check the first 5 registers to ensure this a revision we can handle */
-
-       i2c_readbytes(state, 0x00, buf, 5);
-       if (buf[0] != 0x04) goto error;         /* device id */
-       if (buf[1] != 0x02) goto error;         /* fab id */
-       if (buf[2] != 0x11) goto error;         /* month */
-       if (buf[3] != 0x20) goto error;         /* year msb */
-       if (buf[4] != 0x00) goto error;         /* year lsb */
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops nxt2002_ops = {
-
-       .info = {
-               .name = "Nextwave nxt2002 VSB/QAM frontend",
-               .type = FE_ATSC,
-               .frequency_min =  54000000,
-               .frequency_max = 860000000,
-               /* stepsize is just a guess */
-               .frequency_stepsize = 166666,
-               .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-                       FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
-       },
-
-       .release = nxt2002_release,
-
-       .init = nxt2002_init,
-       .sleep = nxt2002_sleep,
-
-       .set_frontend = nxt2002_setup_frontend_parameters,
-       .get_tune_settings = nxt2002_get_tune_settings,
-
-       .read_status = nxt2002_read_status,
-       .read_ber = nxt2002_read_ber,
-       .read_signal_strength = nxt2002_read_signal_strength,
-       .read_snr = nxt2002_read_snr,
-       .read_ucblocks = nxt2002_read_ucblocks,
-
-};
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
-MODULE_AUTHOR("Taylor Jacob");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(nxt2002_attach);
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h
deleted file mode 100644 (file)
index 462301f..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
-   Driver for the Nxt2002 demodulator
-*/
-
-#ifndef NXT2002_H
-#define NXT2002_H
-
-#include <linux/dvb/frontend.h>
-#include <linux/firmware.h>
-
-struct nxt2002_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* request firmware for device */
-       int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
-};
-
-extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config,
-                                          struct i2c_adapter* i2c);
-
-#endif // NXT2002_H
index 78d2b93..9e35353 100644 (file)
@@ -1,9 +1,10 @@
 /*
  *    Support for NXT2002 and NXT2004 - VSB/QAM
  *
- *    Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
+ *    Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
+ *    Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
  *    based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
- *    and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
+ *    and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com>
  *
  *    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
@@ -614,7 +615,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
        /* write sdm1 input */
        buf[0] = 0x10;
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x58, buf, 2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x58, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x58, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write sdmx input */
        switch (p->u.vsb.modulation) {
@@ -632,7 +643,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
                                break;
        }
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x5C, buf, 2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x5C, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write adc power lpf fc */
        buf[0] = 0x05;
@@ -648,7 +669,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
        /* write accumulator2 input */
        buf[0] = 0x80;
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x4B, buf, 2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x4B, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write kg1 */
        buf[0] = 0x00;
@@ -714,8 +745,19 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
        /* write accumulator2 input */
        buf[0] = 0x80;
        buf[1] = 0x00;
-       nxt200x_writebytes(state, 0x49, buf,2);
-       nxt200x_writebytes(state, 0x4B, buf,2);
+       switch (state->demod_chip) {
+               case NXT2002:
+                       nxt200x_writereg_multibyte(state, 0x49, buf, 2);
+                       nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
+                       break;
+               case NXT2004:
+                       nxt200x_writebytes(state, 0x49, buf, 2);
+                       nxt200x_writebytes(state, 0x4B, buf, 2);
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+       }
 
        /* write agc control reg */
        buf[0] = 0x04;
@@ -1199,7 +1241,7 @@ module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
 MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
-MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
+MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(nxt200x_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
deleted file mode 100644 (file)
index d1cabb6..0000000
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * tda80xx.c
- *
- * Philips TDA8044 / TDA8083 QPSK demodulator driver
- *
- * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/config.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <asm/irq.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "tda80xx.h"
-
-enum {
-       ID_TDA8044 = 0x04,
-       ID_TDA8083 = 0x05,
-};
-
-
-struct tda80xx_state {
-
-       struct i2c_adapter* i2c;
-
-       struct dvb_frontend_ops ops;
-
-       /* configuration settings */
-       const struct tda80xx_config* config;
-
-       struct dvb_frontend frontend;
-
-       u32 clk;
-       int afc_loop;
-       struct work_struct worklet;
-       fe_code_rate_t code_rate;
-       fe_spectral_inversion_t spectral_inversion;
-       fe_status_t status;
-       u8 id;
-};
-
-static int debug = 1;
-#define dprintk        if (debug) printk
-
-static u8 tda8044_inittab_pre[] = {
-       0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
-       0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58,
-       0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
-       0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00,
-       0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00
-};
-
-static u8 tda8044_inittab_post[] = {
-       0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea,
-       0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50,
-       0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68,
-       0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c,
-       0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00
-};
-
-static u8 tda8083_inittab[] = {
-       0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
-       0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
-       0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
-       0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
-       0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00
-};
-
-static __inline__ u32 tda80xx_div(u32 a, u32 b)
-{
-       return (a + (b / 2)) / b;
-}
-
-static __inline__ u32 tda80xx_gcd(u32 a, u32 b)
-{
-       u32 r;
-
-       while ((r = a % b)) {
-               a = b;
-               b = r;
-       }
-
-       return b;
-}
-
-static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len)
-{
-       int ret;
-       struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
-                         { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
-
-       ret = i2c_transfer(state->i2c, msg, 2);
-
-       if (ret != 2)
-               dprintk("%s: readreg error (reg %02x, ret == %i)\n",
-                               __FUNCTION__, reg, ret);
-
-       mdelay(10);
-
-       return (ret == 2) ? 0 : -EREMOTEIO;
-}
-
-static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len)
-{
-       int ret;
-       u8 wbuf[len + 1];
-       struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 };
-
-       wbuf[0] = reg;
-       memcpy(&wbuf[1], buf, len);
-
-       ret = i2c_transfer(state->i2c, &msg, 1);
-
-       if (ret != 1)
-               dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret);
-
-       mdelay(10);
-
-       return (ret == 1) ? 0 : -EREMOTEIO;
-}
-
-static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg)
-{
-       u8 val;
-
-       tda80xx_read(state, reg, &val, 1);
-
-       return val;
-}
-
-static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data)
-{
-       return tda80xx_write(state, reg, &data, 1);
-}
-
-static int tda80xx_set_parameters(struct tda80xx_state* state,
-                                 fe_spectral_inversion_t inversion,
-                                 u32 symbol_rate,
-                                 fe_code_rate_t fec_inner)
-{
-       u8 buf[15];
-       u64 ratio;
-       u32 clk;
-       u32 k;
-       u32 sr = symbol_rate;
-       u32 gcd;
-       u8 scd;
-
-       if (symbol_rate > (state->clk * 3) / 16)
-               scd = 0;
-       else if (symbol_rate > (state->clk * 3) / 32)
-               scd = 1;
-       else if (symbol_rate > (state->clk * 3) / 64)
-               scd = 2;
-       else
-               scd = 3;
-
-       clk = scd ? (state->clk / (scd * 2)) : state->clk;
-
-       /*
-        * Viterbi decoder:
-        * Differential decoding off
-        * Spectral inversion unknown
-        * QPSK modulation
-        */
-       if (inversion == INVERSION_ON)
-               buf[0] = 0x60;
-       else if (inversion == INVERSION_OFF)
-               buf[0] = 0x20;
-       else
-               buf[0] = 0x00;
-
-       /*
-        * CLK ratio:
-        * system clock frequency is up to 64 or 96 MHz
-        *
-        * formula:
-        * r = k * clk / symbol_rate
-        *
-        * k:   2^21 for caa 0..3,
-        *      2^20 for caa 4..5,
-        *      2^19 for caa 6..7
-        */
-       if (symbol_rate <= (clk * 3) / 32)
-               k = (1 << 19);
-       else if (symbol_rate <= (clk * 3) / 16)
-               k = (1 << 20);
-       else
-               k = (1 << 21);
-
-       gcd = tda80xx_gcd(clk, sr);
-       clk /= gcd;
-       sr /= gcd;
-
-       gcd = tda80xx_gcd(k, sr);
-       k /= gcd;
-       sr /= gcd;
-
-       ratio = (u64)k * (u64)clk;
-       do_div(ratio, sr);
-
-       buf[1] = ratio >> 16;
-       buf[2] = ratio >> 8;
-       buf[3] = ratio;
-
-       /* nyquist filter roll-off factor 35% */
-       buf[4] = 0x20;
-
-       clk = scd ? (state->clk / (scd * 2)) : state->clk;
-
-       /* Anti Alias Filter */
-       if (symbol_rate < (clk * 3) / 64)
-               printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate);
-       else if (symbol_rate <= clk / 16)
-               buf[4] |= 0x07;
-       else if (symbol_rate <= (clk * 3) / 32)
-               buf[4] |= 0x06;
-       else if (symbol_rate <= clk / 8)
-               buf[4] |= 0x05;
-       else if (symbol_rate <= (clk * 3) / 16)
-               buf[4] |= 0x04;
-       else if (symbol_rate <= clk / 4)
-               buf[4] |= 0x03;
-       else if (symbol_rate <= (clk * 3) / 8)
-               buf[4] |= 0x02;
-       else if (symbol_rate <= clk / 2)
-               buf[4] |= 0x01;
-       else
-               buf[4] |= 0x00;
-
-       /* Sigma Delta converter */
-       buf[5] = 0x00;
-
-       /* FEC: Possible puncturing rates */
-       if (fec_inner == FEC_NONE)
-               buf[6] = 0x00;
-       else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9))
-               buf[6] = (1 << (8 - fec_inner));
-       else if (fec_inner == FEC_AUTO)
-               buf[6] = 0xff;
-       else
-               return -EINVAL;
-
-       /* carrier lock detector threshold value */
-       buf[7] = 0x30;
-       /* AFC1: proportional part settings */
-       buf[8] = 0x42;
-       /* AFC1: integral part settings */
-       buf[9] = 0x98;
-       /* PD: Leaky integrator SCPC mode */
-       buf[10] = 0x28;
-       /* AFC2, AFC1 controls */
-       buf[11] = 0x30;
-       /* PD: proportional part settings */
-       buf[12] = 0x42;
-       /* PD: integral part settings */
-       buf[13] = 0x99;
-       /* AGC */
-       buf[14] = 0x50 | scd;
-
-       printk("symbol_rate=%u clk=%u\n", symbol_rate, clk);
-
-       return tda80xx_write(state, 0x01, buf, sizeof(buf));
-}
-
-static int tda80xx_set_clk(struct tda80xx_state* state)
-{
-       u8 buf[2];
-
-       /* CLK proportional part */
-       buf[0] = (0x06 << 5) | 0x08;    /* CMP[2:0], CSP[4:0] */
-       /* CLK integral part */
-       buf[1] = (0x04 << 5) | 0x1a;    /* CMI[2:0], CSI[4:0] */
-
-       return tda80xx_write(state, 0x17, buf, sizeof(buf));
-}
-
-#if 0
-static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state)
-{
-       /* a constant value is nonsense here imho */
-       return tda80xx_writereg(state, 0x22, 0xf9);
-}
-#endif
-
-static int tda80xx_close_loop(struct tda80xx_state* state)
-{
-       u8 buf[2];
-
-       /* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */
-       buf[0] = 0x68;
-       /* AFC1: Loop closed, CAR Feedback: 8192 */
-       buf[1] = 0x70;
-
-       return tda80xx_write(state, 0x0b, buf, sizeof(buf));
-}
-
-static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt)
-{
-       schedule_work(priv);
-
-       return IRQ_HANDLED;
-}
-
-static void tda80xx_read_status_int(struct tda80xx_state* state)
-{
-       u8 val;
-
-       static const fe_spectral_inversion_t inv_tab[] = {
-               INVERSION_OFF, INVERSION_ON
-       };
-
-       static const fe_code_rate_t fec_tab[] = {
-               FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
-               FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8,
-       };
-
-       val = tda80xx_readreg(state, 0x02);
-
-       state->status = 0;
-
-       if (val & 0x01) /* demodulator lock */
-               state->status |= FE_HAS_SIGNAL;
-       if (val & 0x02) /* clock recovery lock */
-               state->status |= FE_HAS_CARRIER;
-       if (val & 0x04) /* viterbi lock */
-               state->status |= FE_HAS_VITERBI;
-       if (val & 0x08) /* deinterleaver lock (packet sync) */
-               state->status |= FE_HAS_SYNC;
-       if (val & 0x10) /* derandomizer lock (frame sync) */
-               state->status |= FE_HAS_LOCK;
-       if (val & 0x20) /* frontend can not lock */
-               state->status |= FE_TIMEDOUT;
-
-       if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) {
-               printk("tda80xx: closing loop\n");
-               tda80xx_close_loop(state);
-               state->afc_loop = 0;
-       }
-
-       if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) {
-               val = tda80xx_readreg(state, 0x0e);
-               state->code_rate = fec_tab[val & 0x07];
-               if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK))
-                       state->spectral_inversion = inv_tab[(val >> 7) & 0x01];
-               else
-                       state->spectral_inversion = INVERSION_AUTO;
-       }
-       else {
-               state->code_rate = FEC_AUTO;
-       }
-}
-
-static void tda80xx_worklet(void *priv)
-{
-       struct tda80xx_state *state = priv;
-
-       tda80xx_writereg(state, 0x00, 0x04);
-       enable_irq(state->config->irq);
-
-       tda80xx_read_status_int(state);
-}
-
-static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state)
-{
-       size_t i;
-
-       for (i = 0; i < 100; i++) {
-               if (tda80xx_readreg(state, 0x02) & 0x80)
-                       break;
-               msleep(10);
-       }
-}
-
-static int tda8044_init(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-       int ret;
-
-       /*
-        * this function is a mess...
-        */
-
-       if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre))))
-               return ret;
-
-       tda80xx_writereg(state, 0x0f, 0x50);
-#if 1
-       tda80xx_writereg(state, 0x20, 0x8F);            /* FIXME */
-       tda80xx_writereg(state, 0x20, state->config->volt18setting);    /* FIXME */
-       //tda80xx_writereg(state, 0x00, 0x04);
-       tda80xx_writereg(state, 0x00, 0x0C);
-#endif
-       //tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */
-
-       tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post));
-
-       if (state->config->pll_init) {
-               tda80xx_writereg(state, 0x1c, 0x80);
-               state->config->pll_init(fe);
-               tda80xx_writereg(state, 0x1c, 0x00);
-       }
-
-       return 0;
-}
-
-static int tda8083_init(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab));
-
-       if (state->config->pll_init) {
-               tda80xx_writereg(state, 0x1c, 0x80);
-               state->config->pll_init(fe);
-               tda80xx_writereg(state, 0x1c, 0x00);
-       }
-
-       return 0;
-}
-
-static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch (voltage) {
-       case SEC_VOLTAGE_13:
-               return tda80xx_writereg(state, 0x20, state->config->volt13setting);
-       case SEC_VOLTAGE_18:
-               return tda80xx_writereg(state, 0x20, state->config->volt18setting);
-       case SEC_VOLTAGE_OFF:
-               return tda80xx_writereg(state, 0x20, 0);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch (tone) {
-       case SEC_TONE_OFF:
-               return tda80xx_writereg(state, 0x29, 0x00);
-       case SEC_TONE_ON:
-               return tda80xx_writereg(state, 0x29, 0x80);
-       default:
-               return -EINVAL;
-       }
-}
-
-static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (cmd->msg_len > 6)
-               return -EINVAL;
-
-       tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3));
-       tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len);
-       tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3));
-       tda80xx_wait_diseqc_fifo(state);
-
-       return 0;
-}
-
-static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch (cmd) {
-       case SEC_MINI_A:
-               tda80xx_writereg(state, 0x29, 0x14);
-               break;
-       case SEC_MINI_B:
-               tda80xx_writereg(state, 0x29, 0x1c);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       tda80xx_wait_diseqc_fifo(state);
-
-       return 0;
-}
-
-static int tda80xx_sleep(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       tda80xx_writereg(state, 0x00, 0x02);    /* enter standby */
-
-       return 0;
-}
-
-static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       tda80xx_writereg(state, 0x1c, 0x80);
-       state->config->pll_set(fe, p);
-       tda80xx_writereg(state, 0x1c, 0x00);
-
-       tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner);
-       tda80xx_set_clk(state);
-       //tda80xx_set_scpc_freq_offset(state);
-       state->afc_loop = 1;
-
-       return 0;
-}
-
-static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (!state->config->irq)
-               tda80xx_read_status_int(state);
-
-       p->inversion = state->spectral_inversion;
-       p->u.qpsk.fec_inner = state->code_rate;
-
-       return 0;
-}
-
-static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (!state->config->irq)
-               tda80xx_read_status_int(state);
-       *status = state->status;
-
-       return 0;
-}
-
-static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-       int ret;
-       u8 buf[3];
-
-       if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf))))
-               return ret;
-
-       *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
-
-       return 0;
-}
-
-static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       u8 gain = ~tda80xx_readreg(state, 0x01);
-       *strength = (gain << 8) | gain;
-
-       return 0;
-}
-
-static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       u8 quality = tda80xx_readreg(state, 0x08);
-       *snr = (quality << 8) | quality;
-
-       return 0;
-}
-
-static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       *ucblocks = tda80xx_readreg(state, 0x0f);
-       if (*ucblocks == 0xff)
-               *ucblocks = 0xffffffff;
-
-       return 0;
-}
-
-static int tda80xx_init(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       switch(state->id) {
-       case ID_TDA8044:
-               return tda8044_init(fe);
-
-       case ID_TDA8083:
-               return tda8083_init(fe);
-       }
-       return 0;
-}
-
-static void tda80xx_release(struct dvb_frontend* fe)
-{
-       struct tda80xx_state* state = fe->demodulator_priv;
-
-       if (state->config->irq)
-               free_irq(state->config->irq, &state->worklet);
-
-       kfree(state);
-}
-
-static struct dvb_frontend_ops tda80xx_ops;
-
-struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
-                                   struct i2c_adapter* i2c)
-{
-       struct tda80xx_state* state = NULL;
-       int ret;
-
-       /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL);
-       if (state == NULL) goto error;
-
-       /* setup the state */
-       state->config = config;
-       state->i2c = i2c;
-       memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops));
-       state->spectral_inversion = INVERSION_AUTO;
-       state->code_rate = FEC_AUTO;
-       state->status = 0;
-       state->afc_loop = 0;
-
-       /* check if the demod is there */
-       if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error;
-       state->id = tda80xx_readreg(state, 0x00);
-
-       switch (state->id) {
-       case ID_TDA8044:
-               state->clk = 96000000;
-               printk("tda80xx: Detected tda8044\n");
-               break;
-
-       case ID_TDA8083:
-               state->clk = 64000000;
-               printk("tda80xx: Detected tda8083\n");
-               break;
-
-       default:
-               goto error;
-       }
-
-       /* setup IRQ */
-       if (state->config->irq) {
-               INIT_WORK(&state->worklet, tda80xx_worklet, state);
-               if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) {
-                       printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret);
-                       goto error;
-               }
-       }
-
-       /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
-       return &state->frontend;
-
-error:
-       kfree(state);
-       return NULL;
-}
-
-static struct dvb_frontend_ops tda80xx_ops = {
-
-       .info = {
-               .name = "Philips TDA80xx DVB-S",
-               .type = FE_QPSK,
-               .frequency_min = 500000,
-               .frequency_max = 2700000,
-               .frequency_stepsize = 125,
-               .symbol_rate_min = 4500000,
-               .symbol_rate_max = 45000000,
-               .caps = FE_CAN_INVERSION_AUTO |
-                       FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-                       FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-                       FE_CAN_QPSK |
-                       FE_CAN_MUTE_TS
-       },
-
-       .release = tda80xx_release,
-
-       .init = tda80xx_init,
-       .sleep = tda80xx_sleep,
-
-       .set_frontend = tda80xx_set_frontend,
-       .get_frontend = tda80xx_get_frontend,
-
-       .read_status = tda80xx_read_status,
-       .read_ber = tda80xx_read_ber,
-       .read_signal_strength = tda80xx_read_signal_strength,
-       .read_snr = tda80xx_read_snr,
-       .read_ucblocks = tda80xx_read_ucblocks,
-
-       .diseqc_send_master_cmd = tda80xx_send_diseqc_msg,
-       .diseqc_send_burst = tda80xx_send_diseqc_burst,
-       .set_tone = tda80xx_set_tone,
-       .set_voltage = tda80xx_set_voltage,
-};
-
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver");
-MODULE_AUTHOR("Felix Domke, Andreas Oberritter");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(tda80xx_attach);
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h
deleted file mode 100644 (file)
index cd639a0..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * tda80xx.c
- *
- * Philips TDA8044 / TDA8083 QPSK demodulator driver
- *
- * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net>
- * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org>
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef TDA80XX_H
-#define TDA80XX_H
-
-#include <linux/dvb/frontend.h>
-
-struct tda80xx_config
-{
-       /* the demodulator's i2c address */
-       u8 demod_address;
-
-       /* IRQ to use (0=>no IRQ used) */
-       u32 irq;
-
-       /* Register setting to use for 13v */
-       u8 volt13setting;
-
-       /* Register setting to use for 18v */
-       u8 volt18setting;
-
-       /* PLL maintenance */
-       int (*pll_init)(struct dvb_frontend* fe);
-       int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
-};
-
-extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config,
-                                          struct i2c_adapter* i2c);
-
-#endif // TDA80XX_H
index 2749490..d36369e 100644 (file)
@@ -2329,6 +2329,17 @@ static int frontend_init(struct av7110 *av7110)
                        av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
                        break;
 
+               case 0x0004: // Galaxis DVB-S rev1.3
+                       /* ALPS BSRV2 */
+                       av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
+                       if (av7110->fe) {
+                               av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
+                               av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
+                               av7110->fe->ops->set_tone = av7110_set_tone;
+                               av7110->recover = dvb_s_recover;
+                       }
+                       break;
+
                case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
                        /* Grundig 29504-451 */
                        av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
@@ -2930,6 +2941,7 @@ MAKE_AV7110_INFO(tts_1_3se,  "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE");
 MAKE_AV7110_INFO(ttt,        "Technotrend/Hauppauge DVB-T");
 MAKE_AV7110_INFO(fsc,        "Fujitsu Siemens DVB-C");
 MAKE_AV7110_INFO(fss,        "Fujitsu Siemens DVB-S rev1.6");
+MAKE_AV7110_INFO(gxs_1_3,    "Galaxis DVB-S rev1.3");
 
 static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(fsc,         0x110a, 0x0000),
@@ -2937,13 +2949,13 @@ static struct pci_device_id pci_tbl[] = {
        MAKE_EXTENSION_PCI(ttt_1_X,     0x13c2, 0x0001),
        MAKE_EXTENSION_PCI(ttc_2_X,     0x13c2, 0x0002),
        MAKE_EXTENSION_PCI(tts_2_X,     0x13c2, 0x0003),
+       MAKE_EXTENSION_PCI(gxs_1_3,     0x13c2, 0x0004),
        MAKE_EXTENSION_PCI(fss,         0x13c2, 0x0006),
        MAKE_EXTENSION_PCI(ttt,         0x13c2, 0x0008),
        MAKE_EXTENSION_PCI(ttc_1_X,     0x13c2, 0x000a),
        MAKE_EXTENSION_PCI(tts_2_3,     0x13c2, 0x000e),
        MAKE_EXTENSION_PCI(tts_1_3se,   0x13c2, 0x1002),
 
-/*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
 /*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
 /*     MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
 
index 6ea30df..fafd25f 100644 (file)
@@ -273,8 +273,6 @@ struct av7110 {
 extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
                       u16 subpid, u16 pcrpid);
 
-extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
-
 extern int av7110_ir_init(struct av7110 *av7110);
 extern void av7110_ir_exit(struct av7110 *av7110);
 
index 9138132..617e4f6 100644 (file)
@@ -155,6 +155,19 @@ static void input_repeat_key(unsigned long data)
 }
 
 
+static int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
+{
+       int ret = 0;
+
+       dprintk(4, "%p\n", av7110);
+       if (av7110) {
+               ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
+               av7110->ir_config = ir_config;
+       }
+       return ret;
+}
+
+
 static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
                                unsigned long count, void *data)
 {
@@ -187,19 +200,6 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer,
 }
 
 
-int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
-{
-       int ret = 0;
-
-       dprintk(4, "%p\n", av7110);
-       if (av7110) {
-               ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
-               av7110->ir_config = ir_config;
-       }
-       return ret;
-}
-
-
 static void ir_handler(struct av7110 *av7110, u32 ircom)
 {
        dprintk(4, "ircommand = %08x\n", ircom);
index aa4c4c5..578b200 100644 (file)
@@ -214,7 +214,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                   we can capture, of the first and second field. */
                .vbistart       = { 7,320 },
        },{
-               .v4l2_id        = V4L2_STD_NTSC_M,
+               .v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
                .name           = "NTSC",
                .Fsc            = 28636363,
                .swidth         = 768,
index 297c32a..840fe01 100644 (file)
@@ -167,29 +167,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
        if (kp->clipcount > 2048)
                return -EINVAL;
        if (kp->clipcount) {
-               struct v4l2_clip32 *uclips = compat_ptr(up->clips);
-               struct v4l2_clip *kclips;
+               struct v4l2_clip32 __user *uclips;
+               struct v4l2_clip __user *kclips;
                int n = kp->clipcount;
+               compat_caddr_t p;
 
+               if (get_user(p, &up->clips))
+                       return -EFAULT;
+               uclips = compat_ptr(p);
                kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
                kp->clips = kclips;
                while (--n >= 0) {
-                       if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) ||
-                               copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
+                       if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
+                               return -EFAULT;
+                       if (put_user(n ? kclips + 1 : NULL, &kclips->next))
                                return -EFAULT;
-                       kclips->next = n ? kclips + 1 : 0;
                        uclips += 1;
                        kclips += 1;
                }
        } else
-               kp->clips = 0;
+               kp->clips = NULL;
        return 0;
 }
 
 static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) ||
-               copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
+       if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) ||
                put_user(kp->field, &up->field) ||
                put_user(kp->chromakey, &up->chromakey) ||
                put_user(kp->clipcount, &up->clipcount))
@@ -199,33 +202,29 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user
 
 static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
+               return -EFAULT;
        return 0;
 }
 
@@ -279,18 +278,16 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
 
 static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_standard)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_standard)))
+               return -EFAULT;
        return 0;
 
 }
 
 static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_standard)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_standard)))
+               return -EFAULT;
        return 0;
 }
 
@@ -328,18 +325,16 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
 
 static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_tuner)))
+               return -EFAULT;
        return 0;
 
 }
 
 static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_tuner)))
+               return -EFAULT;
        return 0;
 }
 
@@ -380,11 +375,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
                break;
        case V4L2_MEMORY_USERPTR:
                {
-               unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr);
+               compat_long_t tmp;
 
-               if(get_user(kp->length, &up->length) ||
-                       get_user(kp->m.userptr, &tmp))
-                               return -EFAULT;
+               if (get_user(kp->length, &up->length) ||
+                   get_user(tmp, &up->m.userptr))
+                       return -EFAULT;
+
+               kp->m.userptr = (unsigned long)compat_ptr(tmp);
                }
                break;
        case V4L2_MEMORY_OVERLAY:
@@ -468,33 +465,29 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame
 
 static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4))
+               return -EFAULT;
        return 0;
 }
 
 static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) ||
-               copy_from_user(kp, up, sizeof(struct v4l2_input)))
-                       return -EFAULT;
+       if (copy_from_user(kp, up, sizeof(struct v4l2_input)))
+               return -EFAULT;
        return 0;
 }
 
 static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up)
 {
-       if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) ||
-               copy_to_user(up, kp, sizeof(struct v4l2_input)))
-                       return -EFAULT;
+       if (copy_to_user(up, kp, sizeof(struct v4l2_input)))
+               return -EFAULT;
        return 0;
 }
 
index c66c2c1..08ffd1f 100644 (file)
@@ -220,33 +220,23 @@ static void input_change(struct i2c_client *client)
                cx25840_write(client, 0x808, 0xff);
                cx25840_write(client, 0x80b, 0x10);
        } else if (std & V4L2_STD_NTSC) {
-               /* NTSC */
-               if (state->pvr150_workaround) {
-                       /* Certain Hauppauge PVR150 models have a hardware bug
-                          that causes audio to drop out. For these models the
-                          audio standard must be set explicitly.
-                          To be precise: it affects cards with tuner models
-                          85, 99 and 112 (model numbers from tveeprom). */
-                       if (std == V4L2_STD_NTSC_M_JP) {
-                               /* Japan uses EIAJ audio standard */
-                               cx25840_write(client, 0x808, 0x2f);
-                       } else {
-                               /* Others use the BTSC audio standard */
-                               cx25840_write(client, 0x808, 0x1f);
-                       }
-                       /* South Korea uses the A2-M (aka Zweiton M) audio
-                          standard, and should set 0x808 to 0x3f, but I don't
-                          know how to detect this. */
-               } else if (std == V4L2_STD_NTSC_M_JP) {
+               /* Certain Hauppauge PVR150 models have a hardware bug
+                  that causes audio to drop out. For these models the
+                  audio standard must be set explicitly.
+                  To be precise: it affects cards with tuner models
+                  85, 99 and 112 (model numbers from tveeprom). */
+               int hw_fix = state->pvr150_workaround;
+
+               if (std == V4L2_STD_NTSC_M_JP) {
                        /* Japan uses EIAJ audio standard */
-                       cx25840_write(client, 0x808, 0xf7);
+                       cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);
+               } else if (std == V4L2_STD_NTSC_M_KR) {
+                       /* South Korea uses A2 audio standard */
+                       cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);
                } else {
                        /* Others use the BTSC audio standard */
-                       cx25840_write(client, 0x808, 0xf6);
+                       cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);
                }
-               /* South Korea uses the A2-M (aka Zweiton M) audio standard,
-                  and should set 0x808 to 0xf8, but I don't know how to
-                  detect this. */
                cx25840_write(client, 0x80b, 0x00);
        }
 
@@ -330,17 +320,17 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
        u8 fmt=0;       /* zero is autodetect */
 
        /* First tests should be against specific std */
-       if (std & V4L2_STD_NTSC_M_JP) {
+       if (std == V4L2_STD_NTSC_M_JP) {
                fmt=0x2;
-       } else if (std & V4L2_STD_NTSC_443) {
+       } else if (std == V4L2_STD_NTSC_443) {
                fmt=0x3;
-       } else if (std & V4L2_STD_PAL_M) {
+       } else if (std == V4L2_STD_PAL_M) {
                fmt=0x5;
-       } else if (std & V4L2_STD_PAL_N) {
+       } else if (std == V4L2_STD_PAL_N) {
                fmt=0x6;
-       } else if (std & V4L2_STD_PAL_Nc) {
+       } else if (std == V4L2_STD_PAL_Nc) {
                fmt=0x7;
-       } else if (std & V4L2_STD_PAL_60) {
+       } else if (std == V4L2_STD_PAL_60) {
                fmt=0x8;
        } else {
                /* Then, test against generic ones */
@@ -369,7 +359,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
        }
 
        switch (fmt) {
-       case 0x1: return V4L2_STD_NTSC_M;
+       case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR;
        case 0x2: return V4L2_STD_NTSC_M_JP;
        case 0x3: return V4L2_STD_NTSC_443;
        case 0x4: return V4L2_STD_PAL;
index 5330891..e99dfbb 100644 (file)
@@ -32,6 +32,7 @@ config VIDEO_CX88_DVB
 config VIDEO_CX88_ALSA
        tristate "ALSA DMA audio support"
        depends on VIDEO_CX88 && SND && EXPERIMENTAL
+       select SND_PCM
        ---help---
          This is a video4linux driver for direct (DMA) audio on
          Conexant 2388x based TV cards.
@@ -48,6 +49,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
        default y
        depends on VIDEO_CX88_DVB
        select DVB_MT352
+       select VIDEO_CX88_VP3054
        select DVB_OR51132
        select DVB_CX22702
        select DVB_LGDT330X
@@ -69,6 +71,16 @@ config VIDEO_CX88_DVB_MT352
          This adds DVB-T support for cards based on the
          Connexant 2388x chip and the MT352 demodulator.
 
+config VIDEO_CX88_VP3054
+       tristate "VP-3054 Secondary I2C Bus Support"
+       default m
+       depends on DVB_MT352
+       ---help---
+         This adds DVB-T support for cards based on the
+         Connexant 2388x chip and the MT352 demodulator,
+         which also require support for the VP-3054
+         Secondary I2C bus, such at DNTV Live! DVB-T Pro.
+
 config VIDEO_CX88_DVB_OR51132
        bool "OR51132 ATSC Support"
        default y
index 6e5eaa2..2b90278 100644 (file)
@@ -4,8 +4,9 @@ cx8800-objs     := cx88-video.o cx88-vbi.o
 cx8802-objs    := cx88-mpeg.o
 
 obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o
-obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o
+obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
 obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
+obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o
 
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
@@ -18,6 +19,6 @@ extra-cflags-$(CONFIG_DVB_LGDT330X)  += -DHAVE_LGDT330X=1
 extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
 extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
 extra-cflags-$(CONFIG_DVB_CX24123)   += -DHAVE_CX24123=1
-extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1
+extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1
 
 EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
index a2e36a1..2acccd6 100644 (file)
@@ -128,7 +128,7 @@ MODULE_PARM_DESC(debug,"enable debug messages");
  * BOARD Specific: Sets audio DMA
  */
 
-int _cx88_start_audio_dma(snd_cx88_card_t *chip)
+static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
 {
        struct cx88_buffer   *buf = chip->buf;
        struct cx88_core *core=chip->core;
@@ -173,7 +173,7 @@ int _cx88_start_audio_dma(snd_cx88_card_t *chip)
 /*
  * BOARD Specific: Resets audio DMA
  */
-int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
+static int _cx88_stop_audio_dma(snd_cx88_card_t *chip)
 {
        struct cx88_core *core=chip->core;
        dprintk(1, "Stopping audio DMA\n");
@@ -613,7 +613,7 @@ static snd_kcontrol_new_t snd_cx88_capture_volume = {
  * Only boards with eeprom and byte 1 at eeprom=1 have it
  */
 
-struct pci_device_id cx88_audio_pci_tbl[] = {
+static struct pci_device_id cx88_audio_pci_tbl[] = {
        {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
        {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
        {0, }
index ad2f565..1bc9992 100644 (file)
@@ -1244,6 +1244,11 @@ struct cx88_subid cx88_subids[] = {
                .subvendor = 0x18ac,
                .subdevice = 0xdb50,
                .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
+       },{
+               .subvendor = 0x18ac,
+               .subdevice = 0xdb54,
+               .card      = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL,
+               /* Re-branded DViCO: DigitalNow DVB-T Dual */
        },{
                .subvendor = 0x18ac,
                .subdevice = 0xdb11,
@@ -1293,6 +1298,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
        switch (tv.model)
        {
        case 28552: /* WinTV-PVR 'Roslyn' (No IR) */
+       case 34519: /* WinTV-PCI-FM */
        case 90002: /* Nova-T-PCI (9002) */
        case 92001: /* Nova-S-Plus (Video and IR) */
        case 92002: /* Nova-S-Plus (Video and IR) */
index 8d6d6a6..3720f24 100644 (file)
@@ -787,12 +787,14 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq)
 
 int cx88_start_audio_dma(struct cx88_core *core)
 {
+       /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */
+       int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4;
        /* setup fifo + format */
-       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
-       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
+       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0);
+       cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0);
 
-       cx_write(MO_AUDD_LNGTH,    128); /* fifo bpl size */
-       cx_write(MO_AUDR_LNGTH,    128); /* fifo bpl size */
+       cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */
+       cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */
 
        /* start dma */
        cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
index da2ad5c..165d948 100644 (file)
@@ -482,6 +482,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        switch (core->board) {
        case CX88_BOARD_DNTV_LIVE_DVB_T:
        case CX88_BOARD_KWORLD_DVB_T:
+       case CX88_BOARD_KWORLD_DVB_T_CX22702:
                ir_codes = ir_codes_dntv_live_dvb_t;
                ir->gpio_addr = MO_GP1_IO;
                ir->mask_keycode = 0x1f;
index dff3893..e5ee8bc 100644 (file)
@@ -139,6 +139,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
 {
        int ret, byte;
 
+       if (dev->state & DEV_DISCONNECTED)
+               return(-ENODEV);
+
        em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
 
        ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -165,6 +168,9 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
        u8 val;
        int ret;
 
+       if (dev->state & DEV_DISCONNECTED)
+               return(-ENODEV);
+
        em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
 
        ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
@@ -195,7 +201,12 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
        int ret;
 
        /*usb_control_msg seems to expect a kmalloced buffer */
-       unsigned char *bufs = kmalloc(len, GFP_KERNEL);
+       unsigned char *bufs;
+
+       if (dev->state & DEV_DISCONNECTED)
+               return(-ENODEV);
+
+       bufs = kmalloc(len, GFP_KERNEL);
 
        em28xx_regdbg("req=%02x reg=%02x:", req, reg);
 
@@ -212,7 +223,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
        ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
                              USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                              0x0000, reg, bufs, len, HZ);
-       mdelay(5);              /* FIXME: magic number */
+       msleep(5);              /* FIXME: magic number */
        kfree(bufs);
        return ret;
 }
@@ -253,7 +264,7 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
        if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
                return ret;
        else if (((u8) ret) & 0x01) {
-               em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
+               em28xx_warn ("AC97 command still being executed: not handled properly!\n");
        }
        return 0;
 }
index 0591a70..6ca8631 100644 (file)
@@ -78,7 +78,7 @@ static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
                ret = dev->em28xx_read_reg(dev, 0x05);
                if (ret == 0x80 + len - 1)
                        return len;
-               mdelay(5);
+               msleep(5);
        }
        em28xx_warn("i2c write timed out\n");
        return -EIO;
@@ -138,7 +138,7 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
                        return -ENODEV;
                else if (msg == 0x84)
                        return 0;
-               mdelay(5);
+               msleep(5);
        }
        return -ENODEV;
 }
@@ -278,9 +278,9 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
                                                           msgs[i].buf,
                                                           msgs[i].len,
                                                           i == num - 1);
-                       if (rc < 0)
-                               goto err;
                }
+               if (rc < 0)
+                       goto err;
                if (i2c_debug>=2)
                        printk("\n");
        }
index eea304f..94a14a2 100644 (file)
@@ -6,6 +6,9 @@
                      Mauro Carvalho Chehab <mchehab@brturbo.com.br>
                      Sascha Sommer <saschasommer@freenet.de>
 
+       Some parts based on SN9C10x PC Camera Controllers GPL driver made
+               by Luca Risolia <luca.risolia@studio.unibo.it>
+
    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
index c64718a..5a35d3b 100644 (file)
@@ -136,7 +136,7 @@ struct saa7134_board saa7134_boards[] = {
        },
        [SAA7134_BOARD_FLYVIDEO2000] = {
                /* "TC Wan" <tcwan@cs.usm.my> */
-               .name           = "LifeView FlyVIDEO2000",
+               .name           = "LifeView/Typhoon FlyVIDEO2000",
                .audio_clock    = 0x00200000,
                .tuner_type     = TUNER_LG_PAL_NEW_TAPC,
                .radio_type     = UNSET,
@@ -1884,44 +1884,38 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x000,
                },
        },
-       [SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS] = {
-               .name           = "Typhoon DVB-T Duo Digital/Analog Cardbus",
+       [SAA7134_BOARD_FLYDVBT_DUO_CARDBUS] = {
+               .name           = "LifeView/Typhoon FlyDVB-T Duo Cardbus",
                .audio_clock    = 0x00200000,
                .tuner_type     = TUNER_PHILIPS_TDA8290,
                .radio_type     = UNSET,
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
                .mpeg           = SAA7134_MPEG_DVB,
-               /* .gpiomask       = 0xe000, */
+               .gpiomask       = 0x00200000,
                .inputs         = {{
                        .name = name_tv,
                        .vmux = 1,
                        .amux = TV,
-               /*      .gpio = 0x0000,      */
+                       .gpio = 0x200000,       /* GPIO21=High for TV input */
                        .tv   = 1,
+               },{
+                       .name = name_svideo,    /* S-Video signal on S-Video input */
+                       .vmux = 8,
+                       .amux = LINE2,
                },{
                        .name = name_comp1,     /* Composite signal on S-Video input */
                        .vmux = 0,
                        .amux = LINE2,
-               /*      .gpio = 0x4000,      */
                },{
                        .name = name_comp2,     /* Composite input */
                        .vmux = 3,
                        .amux = LINE2,
-               /*      .gpio = 0x4000,      */
-               },{
-                       .name = name_svideo,    /* S-Video signal on S-Video input */
-                       .vmux = 8,
-                       .amux = LINE2,
-               /*      .gpio = 0x4000,      */
                }},
                .radio = {
                        .name = name_radio,
-                       .amux = LINE2,
-               },
-               .mute = {
-                       .name = name_mute,
-                       .amux = LINE1,
+                       .amux = TV,
+                       .gpio = 0x000000,       /* GPIO21=Low for FM radio antenna */
                },
        },
        [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = {
@@ -2699,6 +2693,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subvendor    = 0x5168,
                .subdevice    = 0x0138,
                .driver_data  = SAA7134_BOARD_FLYVIDEO2000,
+       },{
+               .vendor       = PCI_VENDOR_ID_PHILIPS,
+               .device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+               .subvendor    = 0x4e42,         /* Typhoon */
+               .subdevice    = 0x0138,         /* LifeView FlyTV Prime30 OEM */
+               .driver_data  = SAA7134_BOARD_FLYVIDEO2000,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -2935,7 +2935,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x5168,
                .subdevice    = 0x0502,                /* Cardbus version */
-               .driver_data  = SAA7134_BOARD_FLYDVBTDUO,
+               .driver_data  = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -2980,12 +2980,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .subdevice    = 0x1370,        /* cardbus version */
                .driver_data  = SAA7134_BOARD_ADS_INSTANT_TV,
 
-       },{     /* Typhoon DVB-T Duo Digital/Analog Cardbus */
+       },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-               .subvendor    = 0x4e42,
-               .subdevice    = 0x0502,
-               .driver_data  = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS,
+               .subvendor    = 0x4e42,         /* Typhoon */
+               .subdevice    = 0x0502,         /* LifeView LR502 OEM */
+               .driver_data  = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -3206,8 +3206,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00040000, 0x00040000);
                saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
                break;
-       case SAA7134_BOARD_FLYDVBTDUO:
-       case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+       case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
                /* turn the fan on */
                saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
                saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
index 399f995..1a536e8 100644 (file)
@@ -861,7 +861,7 @@ static int dvb_init(struct saa7134_dev *dev)
                dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
                                                    &dev->i2c_adap);
                break;
-       case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+       case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
                dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
                                                    &dev->i2c_adap);
                break;
index e70eae8..3261d8b 100644 (file)
@@ -185,7 +185,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
 #define SAA7134_BOARD_ADS_INSTANT_TV 58
 #define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
-#define SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS 60
+#define SAA7134_BOARD_FLYDVBT_DUO_CARDBUS 60
 #define SAA7134_BOARD_PHILIPS_TOUGH 61
 #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
 #define SAA7134_BOARD_KWORLD_XPERT 63
index 54fc330..9d76926 100644 (file)
@@ -2012,7 +2012,6 @@ static int __devinit init_saa7146(struct pci_dev *pdev)
 {
        struct saa7146 *saa = pci_get_drvdata(pdev);
 
-       memset(saa, 0, sizeof(*saa));
        saa->user = 0;
        /* reset the saa7146 */
        saawrite(0xffff0000, SAA7146_MC1);
@@ -2062,16 +2061,16 @@ static int __devinit init_saa7146(struct pci_dev *pdev)
        }
        if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) {
                dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
-               goto errvid;
+               goto errfree;
        }
        if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) {
                dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr);
-               goto erraud;
+               goto errfree;
        }
        /* allocate 81920 byte buffer for clipping */
        if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) {
                dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr);
-               goto errosd;
+               goto errfree;
        }
        /* setup clipping registers */
        saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2);
@@ -2085,15 +2084,11 @@ static int __devinit init_saa7146(struct pci_dev *pdev)
        I2CBusScan(saa);
 
        return 0;
-errosd:
+errfree:
        vfree(saa->osdbuf);
-       saa->osdbuf = NULL;
-erraud:
        vfree(saa->audbuf);
-       saa->audbuf = NULL;
-errvid:
        vfree(saa->vidbuf);
-       saa->vidbuf = NULL;
+       saa->audbuf = saa->osdbuf = saa->vidbuf = NULL;
 err:
        return -ENOMEM;
 }
index 5815649..0d54f6c 100644 (file)
@@ -231,7 +231,7 @@ static struct tvnorm tvnorms[] = {
                           cAudioIF_6_5   |
                           cVideoIF_38_90 ),
        },{
-               .std   = V4L2_STD_NTSC_M,
+               .std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
                .name  = "NTSC-M",
                .b     = ( cNegativeFmTV  |
                           cQSS           ),
@@ -619,6 +619,11 @@ static int tda9887_fixup_std(struct tda9887 *t)
                        tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
                        t->std = V4L2_STD_NTSC_M_JP;
                        break;
+               case 'k':
+               case 'K':
+                       tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+                       t->std = V4L2_STD_NTSC_M_KR;
+                       break;
                case '-':
                        /* default parameter, do nothing */
                        break;
@@ -876,7 +881,7 @@ static int tda9887_resume(struct device * dev)
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-       .id             = -1, /* FIXME */
+       .id             = I2C_DRIVERID_TDA9887,
        .attach_adapter = tda9887_probe,
        .detach_client  = tda9887_detach,
        .command        = tda9887_command,
index 2995b22..e7ee619 100644 (file)
@@ -216,6 +216,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
                buffer[3] = 0xa4;
                i2c_master_send(c,buffer,4);
                default_tuner_init(c);
+               break;
        default:
                default_tuner_init(c);
                break;
@@ -365,6 +366,11 @@ static int tuner_fixup_std(struct tuner *t)
                        tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
                        t->std = V4L2_STD_NTSC_M_JP;
                        break;
+               case 'k':
+               case 'K':
+                       tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
+                       t->std = V4L2_STD_NTSC_M_KR;
+                       break;
                case '-':
                        /* default parameter, do nothing */
                        break;
@@ -448,7 +454,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
                        printk("%02x ",buffer[i]);
                printk("\n");
        }
-       /* TEA5767 autodetection code - only for addr = 0xc0 */
+       /* autodetection code based on the i2c addr */
        if (!no_autodetect) {
                switch (addr) {
                case 0x42:
index 6d03b9b..c8e5ad0 100644 (file)
@@ -390,6 +390,14 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
                chip_write(chip, TDA9840_SW, t);
 }
 
+static int tda9840_checkit(struct CHIPSTATE *chip)
+{
+       int rc;
+       rc = chip_read(chip);
+       /* lower 5 bits should be 0 */
+       return ((rc & 0x1f) == 0) ? 1 : 0;
+}
+
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tda985x                */
 
@@ -1264,6 +1272,7 @@ static struct CHIPDESC chiplist[] = {
                .addr_hi    = I2C_TDA9840 >> 1,
                .registers  = 5,
 
+               .checkit    = tda9840_checkit,
                .getmode    = tda9840_getmode,
                .setmode    = tda9840_setmode,
                .checkmode  = generic_checkmode,
index fad9ea0..1864423 100644 (file)
@@ -746,24 +746,27 @@ static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std)
 
 static inline void tvp5150_reset(struct i2c_client *c)
 {
-       u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom;
+       u8 msb_id, lsb_id, msb_rom, lsb_rom;
        struct tvp5150 *decoder = i2c_get_clientdata(c);
 
-       type=tvp5150_read(c,TVP5150_AUTOSW_MSK);
        msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID);
        lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID);
        msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER);
        lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER);
 
-       if (type==0xdc) {
-               ver_656=tvp5150_read(c,TVP5150_REV_SELECT);
-               tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656);
-       } else if (type==0xfc) {
-               tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
+       if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */
+               tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id);
+
+               /* ITU-T BT.656.4 timing */
+               tvp5150_write(c,TVP5150_REV_SELECT,0);
        } else {
-               tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type);
+               if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */
+                       tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id);
+               } else {
+                       tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id);
+                       tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom);
+               }
        }
-       tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom);
 
        /* Initializes TVP5150 to its default values */
        tvp5150_write_inittab(c, tvp5150_init_default);
@@ -893,6 +896,17 @@ static int tvp5150_command(struct i2c_client *c,
                }
        case DECODER_GET_STATUS:
                {
+                       int *iarg = arg;
+                       int status;
+                       int res=0;
+                       status = tvp5150_read(c, 0x88);
+                       if(status&0x08){
+                               res |= DECODER_STATUS_COLOR;
+                       }
+                       if(status&0x04 && status&0x02){
+                               res |= DECODER_STATUS_GOOD;
+                       }
+                       *iarg=res;
                        break;
                }
 
index c483a86..5d397b7 100644 (file)
@@ -65,7 +65,7 @@ config MMC_AU1X
        depends on SOC_AU1X00 && MMC
        help
          This selects the AMD Alchemy(R) Multimedia card interface.
-         iIf you have a Alchemy platform with a MMC slot, say Y or M here.
+         If you have a Alchemy platform with a MMC slot, say Y or M here.
 
          If unsure, say N.
 
index effa0d7..205bb70 100644 (file)
@@ -301,7 +301,7 @@ config MTD_JEDEC
 
 config MTD_XIP
        bool "XIP aware MTD support"
-       depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM
+       depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP
        default y if XIP_KERNEL
        help
          This allows MTD support to work with flash memory which is also
index 3b1bef1..77411a0 100644 (file)
@@ -86,7 +86,6 @@
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
 
-#include <asm/bug.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
index 7ef4b04..c0998ef 100644 (file)
@@ -32,6 +32,8 @@
  */
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/etherdevice.h>
index 8dea07b..eba8e5c 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/netdevice.h>
 #include <linux/hdlc.h>
 #include <linux/pci.h>
-#include <asm/delay.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 #include "hd64572.h"
index 9c1e106..9d3b51c 100644 (file)
@@ -27,8 +27,8 @@
 #include <linux/hdlc.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/delay.h>
 #include <asm/io.h>
-#include <asm/delay.h>
 
 #include "wanxl.h"
 
index c5cd61c..e5bb9f5 100644 (file)
@@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
        if (essid->length) {
                dwrq->flags = 1;        /* set ESSID to ON for Wireless Extensions */
                /* if it is to big, trunk it */
-               dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length);
+               dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length);
        } else {
                dwrq->flags = 0;
                dwrq->length = 0;
index 38d6d00..014cc8d 100644 (file)
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <asm/semaphore.h>
-#include <asm/delay.h>
 
 #include "aacraid.h"
 
index 311a412..93edaa8 100644 (file)
@@ -537,9 +537,9 @@ static int mac53c94_remove(struct macio_dev *mdev)
        free_irq(fp->intr, fp);
 
        if (fp->regs)
-               iounmap((void *) fp->regs);
+               iounmap(fp->regs);
        if (fp->dma)
-               iounmap((void *) fp->dma);
+               iounmap(fp->dma);
        kfree(fp->dma_cmd_space);
 
        scsi_host_put(host);
index 59a1c9d..723f7ac 100644 (file)
@@ -463,7 +463,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb)
 }
 
 static void*
-mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
+mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
 {
        struct mempool_zone *zone = pool_data;
 
index 7d07000..2a54753 100644 (file)
@@ -1679,7 +1679,7 @@ static int
 sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
 {
        int sg_bufflen = tablesize * sizeof(struct scatterlist);
-       unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
+       gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
        /*
         * TODO: test without low_dma, we should not need it since
index 7aef751..8c5c276 100644 (file)
@@ -362,7 +362,7 @@ static struct uart_ops serial21285_ops = {
 
 static struct uart_port serial21285_port = {
        .mapbase        = 0x42000160,
-       .iotype         = SERIAL_IO_MEM,
+       .iotype         = UPIO_MEM,
        .irq            = NO_IRQ,
        .fifosize       = 16,
        .ops            = &serial21285_ops,
index 8cbf0fc..7f0f35a 100644 (file)
@@ -332,7 +332,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
                 * Make sure that we do not overflow the buffer
                 */
                if (tty_request_buffer_room(tty, 1) == 0) {
-                       schedule_work(&tty->flip.work);
+                       tty_schedule_flip(tty);
                        return;
                }
 
@@ -353,7 +353,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg
        } while((rx = uart->urx.w) & URX_DATA_READY);
 #endif
 
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 
 clear_and_exit:
        return;
index 60f5a5d..9843ae3 100644 (file)
@@ -509,7 +509,7 @@ static _INLINE_ void receive_chars(ser_info_t *info)
 
        info->rx_cur = (QUICC_BD *)bdp;
 
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 }
 
 static _INLINE_ void receive_break(ser_info_t *info)
@@ -521,7 +521,7 @@ static _INLINE_ void receive_break(ser_info_t *info)
         * the break.  If not, we exit now, losing the break.  FIXME
         */
        tty_insert_flip_char(tty, 0, TTY_BREAK);
-       schedule_work(&tty->flip.work);
+       tty_schedule_flip(tty);
 }
 
 static _INLINE_ void transmit_chars(ser_info_t *info)
index 179c1f0..b1fc97d 100644 (file)
@@ -2229,6 +2229,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
         *      and restore the IER
         */
        wait_for_xmitr(up, BOTH_EMPTY);
+       up->ier |= UART_IER_THRI;
        serial_out(up, UART_IER, ier | UART_IER_THRI);
 }
 
index 06ae8fb..8d8d7a7 100644 (file)
@@ -56,7 +56,6 @@ static struct plat_serial8250_port au1x00_data[] = {
 #elif defined(CONFIG_SOC_AU1550)
        PORT(UART0_ADDR, AU1550_UART0_INT),
        PORT(UART1_ADDR, AU1550_UART1_INT),
-       PORT(UART2_ADDR, AU1550_UART2_INT),
        PORT(UART3_ADDR, AU1550_UART3_INT),
 #elif defined(CONFIG_SOC_AU1200)
        PORT(UART0_ADDR, AU1200_UART0_INT),
index bb9ec28..94886c0 100644 (file)
@@ -1882,6 +1882,10 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_SUBVENDOR_ID_CONNECT_TECH,
                PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0,
                pbn_b0_4_1843200 },
+       {       PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+               PCI_VENDOR_ID_AFAVLAB,
+               PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0,
+               pbn_b0_4_1152000 },
        {       PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
                PCI_SUBVENDOR_ID_CONNECT_TECH,
                PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0,
index 429de27..321a3b3 100644 (file)
@@ -561,7 +561,7 @@ static struct uart_amba_port amba_ports[UART_NR] = {
                .port   = {
                        .membase        = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
                        .mapbase        = INTEGRATOR_UART0_BASE,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UARTINT0,
                        .uartclk        = 14745600,
                        .fifosize       = 16,
@@ -576,7 +576,7 @@ static struct uart_amba_port amba_ports[UART_NR] = {
                .port   = {
                        .membase        = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
                        .mapbase        = INTEGRATOR_UART1_BASE,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UARTINT1,
                        .uartclk        = 14745600,
                        .fifosize       = 16,
index ceb5d7f..344022f 100644 (file)
@@ -892,7 +892,7 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res
        int ret = 0;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                if (up->port.mapbase) {
                        *res = request_mem_region(up->port.mapbase, size, "serial");
                        if (!*res)
@@ -900,8 +900,8 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res
                }
                break;
 
-       case SERIAL_IO_HUB6:
-       case SERIAL_IO_PORT:
+       case UPIO_HUB6:
+       case UPIO_PORT:
                *res = request_region(up->port.iobase, size, "serial");
                if (!*res)
                        ret = -EBUSY;
@@ -919,7 +919,7 @@ static void serial8250_release_port(struct uart_port *port)
        size <<= up->port.regshift;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                if (up->port.mapbase) {
                        /*
                         * Unmap the area.
@@ -935,8 +935,8 @@ static void serial8250_release_port(struct uart_port *port)
                }
                break;
 
-       case SERIAL_IO_HUB6:
-       case SERIAL_IO_PORT:
+       case UPIO_HUB6:
+       case UPIO_PORT:
                start = up->port.iobase;
 
                if (size)
index 16af562..b7bf4c6 100644 (file)
@@ -252,12 +252,9 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
                /* If we have not enough room in tty flip buffer, then we try
                 * later, which will be the next rx-interrupt or a timeout
                 */
-               if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) {
-                       tty->flip.work.func((void *)tty);
-                       if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) {
-                               printk(KERN_WARNING "TTY_DONT_FLIP set\n");
-                               return;
-                       }
+               if(tty_buffer_request_room(tty, i) < i) {
+                       printk(KERN_WARNING "No room in flip buffer\n");
+                       return;
                }
 
                /* get pointer */
@@ -276,9 +273,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
                                continue;
 
                      error_return:
-                       *tty->flip.char_buf_ptr++ = ch;
-                       *tty->flip.flag_buf_ptr++ = flg;
-                       tty->flip.count++;
+                       tty_insert_flip_char(tty, ch, flg);
 
                }               /* End while (i--) */
 
@@ -908,7 +903,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SMC1_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .flags = FLAG_SMC,
@@ -922,7 +917,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SMC2_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .flags = FLAG_SMC,
@@ -939,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC1_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
@@ -953,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC2_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
@@ -967,7 +962,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC3_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
@@ -981,7 +976,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
                .port = {
                        .irq            = SCC4_IRQ,
                        .ops            = &cpm_uart_pops,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .lock           = SPIN_LOCK_UNLOCKED,
                },
                .tx_nrfifos = TX_NUM_FIFO,
index a64ba26..ba5541d 100644 (file)
@@ -262,6 +262,7 @@ static inline void dz_receive_chars(struct dz_port *dport)
                }
                tty_insert_flip_char(tty, ch, flag);
              ignore_char:
+                       ;
        } while (status & DZ_DVAL);
 
        if (tty)
@@ -650,7 +651,7 @@ static void __init dz_init_ports(void)
        for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
                spin_lock_init(&dport->port.lock);
                dport->port.membase     = (char *) base;
-               dport->port.iotype      = SERIAL_IO_PORT;
+               dport->port.iotype      = UPIO_PORT;
                dport->port.irq         = dec_interrupt[DEC_IRQ_DZ11];
                dport->port.line        = i;
                dport->port.fifosize    = 1;
index 858048e..4d53fb5 100644 (file)
@@ -668,7 +668,7 @@ static struct imx_port imx_ports[] = {
        .rtsirq = UART1_MINT_RTS,
        .port   = {
                .type           = PORT_IMX,
-               .iotype         = SERIAL_IO_MEM,
+               .iotype         = UPIO_MEM,
                .membase        = (void *)IMX_UART1_BASE,
                .mapbase        = IMX_UART1_BASE, /* FIXME */
                .irq            = UART1_MINT_RX,
@@ -684,7 +684,7 @@ static struct imx_port imx_ports[] = {
        .rtsirq = UART2_MINT_RTS,
        .port   = {
                .type           = PORT_IMX,
-               .iotype         = SERIAL_IO_MEM,
+               .iotype         = UPIO_MEM,
                .membase        = (void *)IMX_UART2_BASE,
                .mapbase        = IMX_UART2_BASE, /* FIXME */
                .irq            = UART2_MINT_RX,
index 66f117d..419dd3c 100644 (file)
@@ -215,7 +215,7 @@ static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs)
        /* Lower and upper byte of baud rate generator divisor.  */
        write_zsreg(channel, R12, regs[R12]);
        write_zsreg(channel, R13, regs[R13]);
-       
+
        /* Now rewrite R14, with BRENAB (if set).  */
        write_zsreg(channel, R14, regs[R14]);
 
@@ -571,7 +571,7 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
        else
                clear_bits |= DTR;
 
-       /* NOTE: Not subject to 'transmitter active' rule.  */ 
+       /* NOTE: Not subject to 'transmitter active' rule.  */
        up->curregs[R5] |= set_bits;
        up->curregs[R5] &= ~clear_bits;
        write_zsreg(channel, R5, up->curregs[R5]);
@@ -654,7 +654,7 @@ static void ip22zilog_enable_ms(struct uart_port *port)
        if (new_reg != up->curregs[R15]) {
                up->curregs[R15] = new_reg;
 
-               /* NOTE: Not subject to 'transmitter active' rule.  */ 
+               /* NOTE: Not subject to 'transmitter active' rule.  */
                write_zsreg(channel, R15, up->curregs[R15]);
        }
 }
@@ -680,7 +680,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state)
        if (new_reg != up->curregs[R5]) {
                up->curregs[R5] = new_reg;
 
-               /* NOTE: Not subject to 'transmitter active' rule.  */ 
+               /* NOTE: Not subject to 'transmitter active' rule.  */
                write_zsreg(channel, R5, up->curregs[R5]);
        }
 
index b48066a..242a041 100644 (file)
@@ -80,7 +80,7 @@
 #include <asm/serial.h>
 
 /* Standard COM flags */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST)
 
 /*
  * SERIAL_PORT_DFNS tells us about built-in ports that have no
index 07d0dd8..7c3ec24 100644 (file)
@@ -37,7 +37,7 @@ struct old_serial_port {
        unsigned int irq;
        unsigned int flags;
        unsigned char io_type;
-       unsigned char *iomem_base;
+       unsigned char __iomem *iomem_base;
        unsigned short iomem_reg_shift;
 };
 
index 0ef648f..8cbbb95 100644 (file)
@@ -57,20 +57,16 @@ struct timer_list mcfrs_timer_struct;
  *     keep going.  Perhaps one day the cflag settings for the
  *     console can be used instead.
  */
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
-    defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
-#define        CONSOLE_BAUD_RATE       19200
-#define        DEFAULT_CBAUD           B19200
-#endif
-
 #if defined(CONFIG_HW_FEITH)
 #define        CONSOLE_BAUD_RATE       38400
 #define        DEFAULT_CBAUD           B38400
-#endif
-
-#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
+#elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
 #define CONSOLE_BAUD_RATE      115200
 #define DEFAULT_CBAUD          B115200
+#elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+      defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#define        CONSOLE_BAUD_RATE       19200
+#define        DEFAULT_CBAUD           B19200
 #endif
 
 #ifndef CONSOLE_BAUD_RATE
@@ -350,7 +346,7 @@ static inline void receive_chars(struct mcf_serial *info)
                }
                tty_insert_flip_char(tty, ch, flag);
        }
-       tty_flip_buffer_push(tty);
+       tty_schedule_flip(tty);
        return;
 }
 
index 4e49168..868eaf4 100644 (file)
@@ -462,7 +462,7 @@ static int __init mux_probe(struct parisc_device *dev)
                port->mapbase   = dev->hpa.start + MUX_OFFSET +
                                                (i * MUX_LINE_OFFSET);
                port->membase   = ioremap(port->mapbase, MUX_LINE_OFFSET);
-               port->iotype    = SERIAL_IO_MEM;
+               port->iotype    = UPIO_MEM;
                port->type      = PORT_MUX;
                port->irq       = NO_IRQ;
                port->uartclk   = 0;
index 4e03a87..9b7ed58 100644 (file)
@@ -1492,7 +1492,7 @@ no_dma:
        /*
         * Init remaining bits of "port" structure
         */
-       uap->port.iotype = SERIAL_IO_MEM;
+       uap->port.iotype = UPIO_MEM;
        uap->port.irq = np->intrs[0].line;
        uap->port.uartclk = ZS_CLOCK;
        uap->port.fifosize = 1;
index 0a2dd6c..7410e09 100644 (file)
@@ -161,7 +161,11 @@ s3c24xx_serial_dbg(const char *fmt, ...)
 
 /* we can support 3 uarts, but not always use them */
 
+#ifdef CONFIG_CPU_S3C2400
+#define NR_PORTS (2)
+#else
 #define NR_PORTS (3)
+#endif
 
 /* port irq numbers */
 
index ff7b60b..2c00b86 100644 (file)
@@ -628,7 +628,7 @@ static void __init sa1100_init_ports(void)
                sa1100_ports[i].port.ops       = &sa1100_pops;
                sa1100_ports[i].port.fifosize  = 8;
                sa1100_ports[i].port.line      = i;
-               sa1100_ports[i].port.iotype    = SERIAL_IO_MEM;
+               sa1100_ports[i].port.iotype    = UPIO_MEM;
                init_timer(&sa1100_ports[i].timer);
                sa1100_ports[i].timer.function = sa1100_timeout;
                sa1100_ports[i].timer.data     = (unsigned long)&sa1100_ports[i];
index d0490f6..04186ea 100644 (file)
@@ -501,7 +501,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
                .port = {
                        .membase        = (void*) io_p2v (UART1_PHYS),
                        .mapbase        = UART1_PHYS,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UART1INTR,
                        .uartclk        = 14745600/2,
                        .fifosize       = 16,
@@ -514,7 +514,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
                .port = {
                        .membase        = (void*) io_p2v (UART2_PHYS),
                        .mapbase        = UART2_PHYS,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UART2INTR,
                        .uartclk        = 14745600/2,
                        .fifosize       = 16,
@@ -527,7 +527,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {
                .port = {
                        .membase        = (void*) io_p2v (UART3_PHYS),
                        .mapbase        = UART3_PHYS,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = IRQ_UART3INTR,
                        .uartclk        = 14745600/2,
                        .fifosize       = 16,
index 80737c1..44f6bf7 100644 (file)
@@ -1468,10 +1468,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xff923000,
                        .mapbase        = 0xff923000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 61,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 0,
                },
                .type           = PORT_SCIF,
@@ -1482,10 +1482,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xff924000,
                        .mapbase        = 0xff924000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 62,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 1,
                },
                .type           = PORT_SCIF,
@@ -1496,10 +1496,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xff925000,
                        .mapbase        = 0xff925000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 63,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 2,
                },
                .type           = PORT_SCIF,
@@ -1511,10 +1511,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xffe00000,
                        .mapbase        = 0xffe00000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 43,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 0,
                },
                .type           = PORT_SCIF,
@@ -1525,10 +1525,10 @@ static struct sci_port sci_ports[] = {
                .port   = {
                        .membase        = (void *)0xffe10000,
                        .mapbase        = 0xffe10000,
-                       .iotype         = SERIAL_IO_MEM,
+                       .iotype         = UPIO_MEM,
                        .irq            = 79,
                        .ops            = &sci_uart_ops,
-                       .flags          = ASYNC_BOOT_AUTOCONF,
+                       .flags          = UPF_BOOT_AUTOCONF,
                        .line           = 1,
                },
                .type           = PORT_SCIF,
index 8bcaebc..8566422 100644 (file)
@@ -1036,7 +1036,7 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg
                up->port.irq = edev->irqs[0];
                up->port.fifosize = SAB82532_XMIT_FIFO_SIZE;
                up->port.mapbase = (unsigned long)up->regs;
-               up->port.iotype = SERIAL_IO_MEM;
+               up->port.iotype = UPIO_MEM;
 
                writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc);
 
index bc67442..3087045 100644 (file)
@@ -109,11 +109,11 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset)
        offset <<= up->port.regshift;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_HUB6:
+       case UPIO_HUB6:
                outb(up->port.hub6 - 1 + offset, up->port.iobase);
                return inb(up->port.iobase + 1);
 
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                return readb(up->port.membase + offset);
 
        default:
@@ -139,12 +139,12 @@ serial_out(struct uart_sunsu_port *up, int offset, int value)
        offset <<= up->port.regshift;
 
        switch (up->port.iotype) {
-       case SERIAL_IO_HUB6:
+       case UPIO_HUB6:
                outb(up->port.hub6 - 1 + offset, up->port.iobase);
                outb(value, up->port.iobase + 1);
                break;
 
-       case SERIAL_IO_MEM:
+       case UPIO_MEM:
                writeb(value, up->port.membase + offset);
                break;
 
@@ -1052,7 +1052,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
                return;
 
        up->type_probed = PORT_UNKNOWN;
-       up->port.iotype = SERIAL_IO_MEM;
+       up->port.iotype = UPIO_MEM;
 
        /*
         * First we look for Ebus-bases su's
index 3c72484..5cc4d4c 100644 (file)
@@ -1487,7 +1487,7 @@ static void __init sunzilog_prepare(void)
                up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB;
 
                /* Channel A */
-               up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM;
+               up[(chip * 2) + 0].port.iotype = UPIO_MEM;
                up[(chip * 2) + 0].port.irq = zilog_irq;
                up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
                up[(chip * 2) + 0].port.fifosize = 1;
@@ -1498,7 +1498,7 @@ static void __init sunzilog_prepare(void)
                up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
 
                /* Channel B */
-               up[(chip * 2) + 1].port.iotype = SERIAL_IO_MEM;
+               up[(chip * 2) + 1].port.iotype = UPIO_MEM;
                up[(chip * 2) + 1].port.irq = zilog_irq;
                up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
                up[(chip * 2) + 1].port.fifosize = 1;
index 9378895..df705fd 100644 (file)
@@ -496,7 +496,7 @@ static int __init v850e_uart_init (void)
 
                        port->ops = &v850e_uart_ops;
                        port->line = chan;
-                       port->iotype = SERIAL_IO_MEM;
+                       port->iotype = UPIO_MEM;
                        port->flags = UPF_BOOT_AUTOCONF;
 
                        /* We actually use multiple IRQs, but the serial
index c70ae81..12357e1 100644 (file)
@@ -38,10 +38,10 @@ static inline unsigned mcr_pack(unsigned pulse, unsigned sample)
 
 static int nic_wait(struct ioc3_driver_data *idd)
 {
-       volatile unsigned mcr;
+       unsigned mcr;
 
         do {
-                mcr = (volatile unsigned)idd->vma->mcr;
+                mcr = readl(&idd->vma->mcr);
         } while (!(mcr & 2));
 
         return mcr & 1;
@@ -53,7 +53,7 @@ static int nic_reset(struct ioc3_driver_data *idd)
        unsigned long flags;
 
        local_irq_save(flags);
-       idd->vma->mcr = mcr_pack(500, 65);
+       writel(mcr_pack(500, 65), &idd->vma->mcr);
        presence = nic_wait(idd);
        local_irq_restore(flags);
 
@@ -68,7 +68,7 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd)
        unsigned long flags;
 
        local_irq_save(flags);
-       idd->vma->mcr = mcr_pack(6, 13);
+       writel(mcr_pack(6, 13), &idd->vma->mcr);
        result = nic_wait(idd);
        local_irq_restore(flags);
 
@@ -80,9 +80,9 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd)
 static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit)
 {
        if (bit)
-               idd->vma->mcr = mcr_pack(6, 110);
+               writel(mcr_pack(6, 110), &idd->vma->mcr);
        else
-               idd->vma->mcr = mcr_pack(80, 30);
+               writel(mcr_pack(80, 30), &idd->vma->mcr);
 
        nic_wait(idd);
 }
@@ -337,7 +337,7 @@ static void probe_nic(struct ioc3_driver_data *idd)
         int save = 0, loops = 3;
         unsigned long first, addr;
 
-        idd->vma->gpcr_s = GPCR_MLAN_EN;
+        writel(GPCR_MLAN_EN, &idd->vma->gpcr_s);
 
         while(loops>0) {
                 idd->nic_part[0] = 0;
@@ -408,7 +408,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs)
 
        read_lock_irqsave(&ioc3_submodules_lock, flags);
 
-       if(idd->dual_irq && idd->vma->eisr) {
+       if(idd->dual_irq && readb(&idd->vma->eisr)) {
                /* send Ethernet IRQ to the driver */
                if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
                                                ioc3_ethernet->intr) {
@@ -682,7 +682,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
        idd->id = ioc3_counter++;
        up_write(&ioc3_devices_rwsem);
 
-       idd->gpdr_shadow = idd->vma->gpdr;
+       idd->gpdr_shadow = readl(&idd->vma->gpdr);
 
        /* Read IOC3 NIC contents */
        probe_nic(idd);
index b77dbd6..7a75fae 100644 (file)
@@ -75,16 +75,6 @@ config SPI_BUTTERFLY
          inexpensive battery powered microcontroller evaluation board.
          This same cable can be used to flash new firmware.
 
-config SPI_BUTTERFLY
-       tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
-       depends on SPI_MASTER && PARPORT && EXPERIMENTAL
-       select SPI_BITBANG
-       help
-         This uses a custom parallel port cable to connect to an AVR
-         Butterfly <http://www.atmel.com/products/avr/butterfly>, an
-         inexpensive battery powered microcontroller evaluation board.
-         This same cable can be used to flash new firmware.
-
 #
 # Add new SPI master controllers in alphabetical order above this line
 #
index 79a3c59..ff9e5fa 100644 (file)
@@ -163,21 +163,20 @@ static void butterfly_chipselect(struct spi_device *spi, int value)
        struct butterfly        *pp = spidev_to_pp(spi);
 
        /* set default clock polarity */
-       if (value)
+       if (value != BITBANG_CS_INACTIVE)
                setsck(spi, spi->mode & SPI_CPOL);
 
        /* no chipselect on this USI link config */
        if (is_usidev(spi))
                return;
 
-       /* here, value == "activate or not" */
-
-       /* most PARPORT_CONTROL_* bits are negated */
+       /* here, value == "activate or not";
+        * most PARPORT_CONTROL_* bits are negated, so we must
+        * morph it to value == "bit value to write in control register"
+        */
        if (spi_cs_bit == PARPORT_CONTROL_INIT)
                value = !value;
 
-       /* here, value == "bit value to write in control register"  */
-
        parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0);
 }
 
@@ -202,7 +201,9 @@ butterfly_txrx_word_mode0(struct spi_device *spi,
 
 /* override default partitioning with cmdlinepart */
 static struct mtd_partition partitions[] = { {
-       /* JFFS2 wants partitions of 4*N blocks for this device ... */
+       /* JFFS2 wants partitions of 4*N blocks for this device,
+        * so sectors 0 and 1 can't be partitions by themselves.
+        */
 
        /* sector 0 = 8 pages * 264 bytes/page (1 block)
         * sector 1 = 248 pages * 264 bytes/page
@@ -316,8 +317,9 @@ static void butterfly_attach(struct parport *p)
        if (status < 0)
                goto clean2;
 
-       /* Bus 1 lets us talk to at45db041b (firmware disables AVR)
-        * or AVR (firmware resets at45, acts as spi slave)
+       /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR
+        * (firmware resets at45, acts as spi slave) or neither (we ignore
+        * both, AVR uses AT45).  Here we expect firmware for the first option.
         */
        pp->info[0].max_speed_hz = 15 * 1000 * 1000;
        strcpy(pp->info[0].modalias, "mtd_dataflash");
@@ -330,7 +332,9 @@ static void butterfly_attach(struct parport *p)
                                pp->dataflash->dev.bus_id);
 
 #ifdef HAVE_USI
-       /* even more custom AVR firmware */
+       /* Bus 2 is only for talking to the AVR, and it can work no
+        * matter who masters bus 1; needs appropriate AVR firmware.
+        */
        pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
        strcpy(pp->info[1].modalias, "butterfly");
        // pp->info[1].platform_data = ... TBD ... ;
@@ -378,13 +382,8 @@ static void butterfly_detach(struct parport *p)
        pp = butterfly;
        butterfly = NULL;
 
-#ifdef HAVE_USI
-       spi_unregister_device(pp->butterfly);
-       pp->butterfly = NULL;
-#endif
-       spi_unregister_device(pp->dataflash);
-       pp->dataflash = NULL;
-
+       /* stop() unregisters child devices too */
+       pdev = to_platform_device(pp->bitbang.master->cdev.dev);
        status = spi_bitbang_stop(&pp->bitbang);
 
        /* turn off VCC */
@@ -394,8 +393,6 @@ static void butterfly_detach(struct parport *p)
        parport_release(pp->pd);
        parport_unregister_device(pp->pd);
 
-       pdev = to_platform_device(pp->bitbang.master->cdev.dev);
-
        (void) spi_master_put(pp->bitbang.master);
 
        platform_device_unregister(pdev);
@@ -420,4 +417,5 @@ static void __exit butterfly_exit(void)
 }
 module_exit(butterfly_exit);
 
+MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly");
 MODULE_LICENSE("GPL");
index a0e5af6..4a51e56 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
-#include <asm/bug.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/paccess.h>
index 9d5015e..bd39bbd 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
-#include <asm/bug.h>
 
 static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
 {
index 68c6906..9e32485 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/ctype.h>
 #include <linux/err.h>
 #include <linux/fb.h>
-#include <asm/bug.h>
 
 static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
 {
index f3927b6..f5361cd 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include <asm/bug.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
index 25148de..eeeac92 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 
-#include <asm/bug.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
index 5dd0207..057e602 100644 (file)
@@ -931,8 +931,8 @@ struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
 static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
        int err, i;
-       sg_req_info_t *r;
-       struct compat_sg_req_info *o = (struct compat_sg_req_info *)arg;
+       sg_req_info_t __user *r;
+       struct compat_sg_req_info __user *o = (void __user *)arg;
        r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
        err = sys_ioctl(fd,cmd,(unsigned long)r);
        if (err < 0)
@@ -2739,8 +2739,8 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon
 static int
 lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
 {
-       struct compat_timeval *tc = (struct compat_timeval *)arg;
-       struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval));
+       struct compat_timeval __user *tc = (struct compat_timeval __user *)arg;
+       struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval));
        struct timeval ts;
        if (get_user(ts.tv_sec, &tc->tv_sec) ||
            get_user(ts.tv_usec, &tc->tv_usec) ||
index efc97d9..d575452 100644 (file)
@@ -56,7 +56,7 @@ static u64 debugfs_u8_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
 
 /**
- * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write an unsigned 8 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
@@ -98,7 +98,7 @@ static u64 debugfs_u16_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
 
 /**
- * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write an unsigned 16 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
@@ -140,7 +140,7 @@ static u64 debugfs_u32_get(void *data)
 DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
 
 /**
- * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
+ * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write an unsigned 32 bit value.
  *
  * @name: a pointer to a string containing the name of the file to create.
  * @mode: the permission that the file should have
index 878ccca..3041503 100644 (file)
@@ -967,7 +967,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
                mask_add = 1;
 
        /* don't let user-space set invalid bits: we don't want flags set */
-       mask &= IN_ALL_EVENTS;
+       mask &= IN_ALL_EVENTS | IN_ONESHOT;
        if (unlikely(!mask)) {
                ret = -EINVAL;
                goto out;
index faf61c3..e28de84 100644 (file)
@@ -1119,9 +1119,11 @@ static int fastcall do_path_lookup(int dfd, const char *name,
        current->total_link_count = 0;
        retval = link_path_walk(name, nd);
 out:
-       if (unlikely(current->audit_context
-                    && nd && nd->dentry && nd->dentry->d_inode))
+       if (likely(retval == 0)) {
+               if (unlikely(current->audit_context && nd && nd->dentry &&
+                               nd->dentry->d_inode))
                audit_inode(name, nd->dentry->d_inode, flags);
+       }
        return retval;
 
 fput_unlock_fail:
index ce97bec..058a448 100644 (file)
@@ -494,7 +494,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
                p->mnt_namespace = NULL;
                list_del_init(&p->mnt_child);
                if (p->mnt_parent != p)
-                       mnt->mnt_mountpoint->d_mounted--;
+                       p->mnt_mountpoint->d_mounted--;
                change_mnt_propagation(p, MS_PRIVATE);
        }
 }
@@ -1325,27 +1325,17 @@ dput_out:
        return retval;
 }
 
-int copy_namespace(int flags, struct task_struct *tsk)
+/*
+ * Allocate a new namespace structure and populate it with contents
+ * copied from the namespace of the passed in task structure.
+ */
+struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
 {
        struct namespace *namespace = tsk->namespace;
        struct namespace *new_ns;
        struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
-       struct fs_struct *fs = tsk->fs;
        struct vfsmount *p, *q;
 
-       if (!namespace)
-               return 0;
-
-       get_namespace(namespace);
-
-       if (!(flags & CLONE_NEWNS))
-               return 0;
-
-       if (!capable(CAP_SYS_ADMIN)) {
-               put_namespace(namespace);
-               return -EPERM;
-       }
-
        new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
        if (!new_ns)
                goto out;
@@ -1396,8 +1386,6 @@ int copy_namespace(int flags, struct task_struct *tsk)
        }
        up_write(&namespace_sem);
 
-       tsk->namespace = new_ns;
-
        if (rootmnt)
                mntput(rootmnt);
        if (pwdmnt)
@@ -1405,12 +1393,40 @@ int copy_namespace(int flags, struct task_struct *tsk)
        if (altrootmnt)
                mntput(altrootmnt);
 
-       put_namespace(namespace);
-       return 0;
+out:
+       return new_ns;
+}
+
+int copy_namespace(int flags, struct task_struct *tsk)
+{
+       struct namespace *namespace = tsk->namespace;
+       struct namespace *new_ns;
+       int err = 0;
+
+       if (!namespace)
+               return 0;
+
+       get_namespace(namespace);
+
+       if (!(flags & CLONE_NEWNS))
+               return 0;
+
+       if (!capable(CAP_SYS_ADMIN)) {
+               err = -EPERM;
+               goto out;
+       }
+
+       new_ns = dup_namespace(tsk, tsk->fs);
+       if (!new_ns) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       tsk->namespace = new_ns;
 
 out:
        put_namespace(namespace);
-       return -ENOMEM;
+       return err;
 }
 
 asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,
index e897e00..c0a754e 100644 (file)
@@ -465,10 +465,11 @@ static int __init root_nfs_ports(void)
                                        "number from server, using default\n");
                        port = nfsd_port;
                }
-               nfs_port = htons(port);
+               nfs_port = port;
                dprintk("Root-NFS: Portmapper on server returned %d "
                        "as nfsd port\n", port);
        }
+       nfs_port = htons(nfs_port);
 
        if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
                printk(KERN_ERR "Root-NFS: Unable to get mountd port "
index a00fe86..6d63f1d 100644 (file)
@@ -195,10 +195,12 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
 
        /* Openowner is now set, so sequence id will get bumped.  Now we need
         * these checks before we do any creates: */
+       status = nfserr_grace;
        if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
-               return nfserr_grace;
+               goto out;
+       status = nfserr_no_grace;
        if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
-               return nfserr_no_grace;
+               goto out;
 
        switch (open->op_claim_type) {
                case NFS4_OPEN_CLAIM_DELEGATE_CUR:
index a3ec238..e664ac1 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/reiserfs_fs.h>
 #include <asm/types.h>
-#include <asm/bug.h>
 
 #define DELTA 0x9E3779B9
 #define FULLROUNDS 10          /* 32 is overkill, 16 is strong crypto */
index c0f02d3..bc60a3e 100644 (file)
@@ -510,9 +510,9 @@ asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp,
 
        if (sig) {
                if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t))
-                   || __get_user(up, (sigset_t * __user *)sig)
+                   || __get_user(up, (sigset_t __user * __user *)sig)
                    || __get_user(sigsetsize,
-                               (size_t * __user)(sig+sizeof(void *))))
+                               (size_t __user *)(sig+sizeof(void *))))
                        return -EFAULT;
        }
 
index c177b92..3029421 100644 (file)
@@ -247,8 +247,9 @@ void generic_shutdown_super(struct super_block *sb)
 
                /* Forget any remaining inodes */
                if (invalidate_inodes(sb)) {
-                       printk("VFS: Busy inodes after unmount. "
-                          "Self-destruct in 5 seconds.  Have a nice day...\n");
+                       printk("VFS: Busy inodes after unmount of %s. "
+                          "Self-destruct in 5 seconds.  Have a nice day...\n",
+                          sb->s_id);
                }
 
                unlock_kernel();
index 9892268..8f2beec 100644 (file)
@@ -747,10 +747,11 @@ xfs_convert_page(
                        struct backing_dev_info *bdi;
 
                        bdi = inode->i_mapping->backing_dev_info;
+                       wbc->nr_to_write--;
                        if (bdi_write_congested(bdi)) {
                                wbc->encountered_congestion = 1;
                                done = 1;
-                       } else if (--wbc->nr_to_write <= 0) {
+                       } else if (wbc->nr_to_write <= 0) {
                                done = 1;
                        }
                }
index eda7919..d7f6f2d 100644 (file)
@@ -673,6 +673,8 @@ linvfs_setattr(
        if (ia_valid & ATTR_ATIME) {
                vattr.va_mask |= XFS_AT_ATIME;
                vattr.va_atime = attr->ia_atime;
+               if (ia_valid & ATTR_ATIME_SET)
+                       inode->i_atime = attr->ia_atime;
        }
        if (ia_valid & ATTR_MTIME) {
                vattr.va_mask |= XFS_AT_MTIME;
index cc9c7e8..f3b7b1a 100644 (file)
@@ -572,7 +572,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
    if something tries to do an invalid cmpxchg().  */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
-static inline unsigned long
+static __always_inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
        switch (size) {
index f5bcc9a..b726acf 100644 (file)
@@ -116,7 +116,11 @@ typedef struct { volatile u32 offset[4096]; } __regbase32;
                                        ->offset[((vaddr)&4095)>>2]
 #define __REG32(paddr)         __REGV32(io_p2v(paddr))
 
-extern void omap_map_common_io(void);
+extern void omap1_map_common_io(void);
+extern void omap1_init_common_hw(void);
+
+extern void omap2_map_common_io(void);
+extern void omap2_init_common_hw(void);
 
 #else
 
index 6caa59f..cb29d84 100644 (file)
  * simply bail out immediately through the slow path where the lock will be
  * reattempted until it succeeds.
  */
-#define __mutex_fastpath_lock(count, fail_fn)                          \
-do {                                                                   \
-       int __ex_flag, __res;                                           \
-                                                                       \
-       typecheck(atomic_t *, count);                                   \
-       typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);           \
-                                                                       \
-       __asm__ (                                                       \
-               "ldrex  %0, [%2]        \n"                             \
-               "sub    %0, %0, #1      \n"                             \
-               "strex  %1, %0, [%2]    \n"                             \
-                                                                       \
-               : "=&r" (__res), "=&r" (__ex_flag)                      \
-               : "r" (&(count)->counter)                               \
-               : "cc","memory" );                                      \
-                                                                       \
-       if (unlikely(__res || __ex_flag))                               \
-               fail_fn(count);                                         \
-} while (0)
-
-#define __mutex_fastpath_lock_retval(count, fail_fn)                   \
-({                                                                     \
-       int __ex_flag, __res;                                           \
-                                                                       \
-       typecheck(atomic_t *, count);                                   \
-       typecheck_fn(fastcall int (*)(atomic_t *), fail_fn);            \
-                                                                       \
-       __asm__ (                                                       \
-               "ldrex  %0, [%2]        \n"                             \
-               "sub    %0, %0, #1      \n"                             \
-               "strex  %1, %0, [%2]    \n"                             \
-                                                                       \
-               : "=&r" (__res), "=&r" (__ex_flag)                      \
-               : "r" (&(count)->counter)                               \
-               : "cc","memory" );                                      \
-                                                                       \
-       __res |= __ex_flag;                                             \
-       if (unlikely(__res != 0))                                       \
-               __res = fail_fn(count);                                 \
-       __res;                                                          \
-})
+static inline void
+__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
+{
+       int __ex_flag, __res;
+
+       __asm__ (
+
+               "ldrex  %0, [%2]        \n\t"
+               "sub    %0, %0, #1      \n\t"
+               "strex  %1, %0, [%2]    "
+
+               : "=&r" (__res), "=&r" (__ex_flag)
+               : "r" (&(count)->counter)
+               : "cc","memory" );
+
+       __res |= __ex_flag;
+       if (unlikely(__res != 0))
+               fail_fn(count);
+}
+
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
+{
+       int __ex_flag, __res;
+
+       __asm__ (
+
+               "ldrex  %0, [%2]        \n\t"
+               "sub    %0, %0, #1      \n\t"
+               "strex  %1, %0, [%2]    "
+
+               : "=&r" (__res), "=&r" (__ex_flag)
+               : "r" (&(count)->counter)
+               : "cc","memory" );
+
+       __res |= __ex_flag;
+       if (unlikely(__res != 0))
+               __res = fail_fn(count);
+       return __res;
+}
 
 /*
  * Same trick is used for the unlock fast path. However the original value,
  * rather than the result, is used to test for success in order to have
  * better generated assembly.
  */
-#define __mutex_fastpath_unlock(count, fail_fn)                                \
-do {                                                                   \
-       int __ex_flag, __res, __orig;                                   \
-                                                                       \
-       typecheck(atomic_t *, count);                                   \
-       typecheck_fn(fastcall void (*)(atomic_t *), fail_fn);           \
-                                                                       \
-       __asm__ (                                                       \
-               "ldrex  %0, [%3]        \n"                             \
-               "add    %1, %0, #1      \n"                             \
-               "strex  %2, %1, [%3]    \n"                             \
-                                                                       \
-               : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)      \
-               : "r" (&(count)->counter)                               \
-               : "cc","memory" );                                      \
-                                                                       \
-       if (unlikely(__orig || __ex_flag))                              \
-               fail_fn(count);                                         \
-} while (0)
+static inline void
+__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
+{
+       int __ex_flag, __res, __orig;
+
+       __asm__ (
+
+               "ldrex  %0, [%3]        \n\t"
+               "add    %1, %0, #1      \n\t"
+               "strex  %2, %1, [%3]    "
+
+               : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
+               : "r" (&(count)->counter)
+               : "cc","memory" );
+
+       __orig |= __ex_flag;
+       if (unlikely(__orig != 0))
+               fail_fn(count);
+}
 
 /*
  * If the unlock was done on a contended lock, or if the unlock simply fails
@@ -110,12 +109,12 @@ __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
 
        __asm__ (
 
-               "1: ldrex       %0, [%3]        \n"
-               "subs           %1, %0, #1      \n"
-               "strexeq        %2, %1, [%3]    \n"
-               "movlt          %0, #0          \n"
-               "cmpeq          %2, #0          \n"
-               "bgt            1b              \n"
+               "1: ldrex       %0, [%3]        \n\t"
+               "subs           %1, %0, #1      \n\t"
+               "strexeq        %2, %1, [%3]    \n\t"
+               "movlt          %0, #0          \n\t"
+               "cmpeq          %2, #0          \n\t"
+               "bgt            1b              "
 
                : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
                : "r" (&count->counter)
index 597496e..cf6f2cd 100644 (file)
 #define __NR_faccessat         307
 #define __NR_pselect6          308
 #define __NR_ppoll             309
+#define __NR_unshare           310
 
-#define NR_syscalls 310
+#define NR_syscalls 311
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
index e8659e7..476180f 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <linux/cache.h>
 #include <linux/threads.h>
+#include <asm/irq.h>
 
 typedef struct {
        unsigned int __softirq_pending;
index 2e7e651..1ce0518 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2005 by Ralf Baechle
+ * Copyright (C) 2005, 06 by Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 2005 MIPS Technologies, Inc.
  */
 #ifndef _ASM_ABI_H
@@ -13,7 +13,7 @@
 #include <asm/siginfo.h>
 
 struct mips_abi {
-       int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs);
+       void (* const do_signal)(struct pt_regs *regs);
        int (* const setup_frame)(struct k_sigaction * ka,
                                  struct pt_regs *regs, int signr,
                                  sigset_t *set);
index d426857..5a4c8a5 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 
 #include <asm/addrspace.h>
-#include <asm/bug.h>
 #include <asm/byteorder.h>
 #include <asm/cpu.h>
 #include <asm/cpu-features.h>
  * variations of functions: non-prefixed ones that preserve the value
  * and prefixed ones that preserve byte addresses.  The latters are
  * typically used for moving raw data between a peripheral and memory (cf.
- * string I/O functions), hence the "mem_" prefix.
+ * string I/O functions), hence the "__mem_" prefix.
  */
 #if defined(CONFIG_SWAP_IO_SPACE)
 
 # define ioswabb(x)            (x)
-# define mem_ioswabb(x)                (x)
+# define __mem_ioswabb(x)      (x)
 # ifdef CONFIG_SGI_IP22
 /*
  * IP22 seems braindead enough to swap 16bits values in hardware, but
  * not 32bits.  Go figure... Can't tell without documentation.
  */
 #  define ioswabw(x)           (x)
-#  define mem_ioswabw(x)       le16_to_cpu(x)
+#  define __mem_ioswabw(x)     le16_to_cpu(x)
 # else
 #  define ioswabw(x)           le16_to_cpu(x)
-#  define mem_ioswabw(x)       (x)
+#  define __mem_ioswabw(x)     (x)
 # endif
 # define ioswabl(x)            le32_to_cpu(x)
-# define mem_ioswabl(x)                (x)
+# define __mem_ioswabl(x)      (x)
 # define ioswabq(x)            le64_to_cpu(x)
-# define mem_ioswabq(x)                (x)
+# define __mem_ioswabq(x)      (x)
 
 #else
 
 # define ioswabb(x)            (x)
-# define mem_ioswabb(x)                (x)
+# define __mem_ioswabb(x)      (x)
 # define ioswabw(x)            (x)
-# define mem_ioswabw(x)                cpu_to_le16(x)
+# define __mem_ioswabw(x)      cpu_to_le16(x)
 # define ioswabl(x)            (x)
-# define mem_ioswabl(x)                cpu_to_le32(x)
+# define __mem_ioswabl(x)      cpu_to_le32(x)
 # define ioswabq(x)            (x)
-# define mem_ioswabq(x)                cpu_to_le32(x)
+# define __mem_ioswabq(x)      cpu_to_le32(x)
 
 #endif
 
@@ -343,7 +342,7 @@ static inline void pfx##write##bwlq(type val,                               \
                BUG();                                                  \
 }                                                                      \
                                                                        \
-static inline type pfx##read##bwlq(volatile void __iomem *mem)         \
+static inline type pfx##read##bwlq(const volatile void __iomem *mem)   \
 {                                                                      \
        volatile type *__mem;                                           \
        type __val;                                                     \
@@ -418,7 +417,7 @@ __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
                                                                        \
 __BUILD_MEMORY_PFX(__raw_, bwlq, type)                                 \
 __BUILD_MEMORY_PFX(, bwlq, type)                                       \
-__BUILD_MEMORY_PFX(mem_, bwlq, type)                                   \
+__BUILD_MEMORY_PFX(__mem_, bwlq, type)                                 \
 
 BUILDIO_MEM(b, u8)
 BUILDIO_MEM(w, u16)
@@ -431,7 +430,7 @@ BUILDIO_MEM(q, u64)
 
 #define BUILDIO_IOPORT(bwlq, type)                                     \
        __BUILD_IOPORT_PFX(, bwlq, type)                                \
-       __BUILD_IOPORT_PFX(mem_, bwlq, type)
+       __BUILD_IOPORT_PFX(__mem_, bwlq, type)
 
 BUILDIO_IOPORT(b, u8)
 BUILDIO_IOPORT(w, u16)
@@ -465,7 +464,7 @@ static inline void writes##bwlq(volatile void __iomem *mem,         \
        const volatile type *__addr = addr;                             \
                                                                        \
        while (count--) {                                               \
-               mem_write##bwlq(*__addr, mem);                          \
+               __mem_write##bwlq(*__addr, mem);                        \
                __addr++;                                               \
        }                                                               \
 }                                                                      \
@@ -476,7 +475,7 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr,      \
        volatile type *__addr = addr;                                   \
                                                                        \
        while (count--) {                                               \
-               *__addr = mem_read##bwlq(mem);                          \
+               *__addr = __mem_read##bwlq(mem);                        \
                __addr++;                                               \
        }                                                               \
 }
@@ -489,7 +488,7 @@ static inline void outs##bwlq(unsigned long port, const void *addr, \
        const volatile type *__addr = addr;                             \
                                                                        \
        while (count--) {                                               \
-               mem_out##bwlq(*__addr, port);                           \
+               __mem_out##bwlq(*__addr, port);                         \
                __addr++;                                               \
        }                                                               \
 }                                                                      \
@@ -500,7 +499,7 @@ static inline void ins##bwlq(unsigned long port, void *addr,                \
        volatile type *__addr = addr;                                   \
                                                                        \
        while (count--) {                                               \
-               *__addr = mem_in##bwlq(port);                           \
+               *__addr = __mem_in##bwlq(port);                         \
                __addr++;                                               \
        }                                                               \
 }
index 1612b3f..fa193f8 100644 (file)
@@ -114,6 +114,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define TIF_NEED_RESCHED       3       /* rescheduling necessary */
 #define TIF_SYSCALL_AUDIT      4       /* syscall auditing active */
 #define TIF_SECCOMP            5       /* secure computing */
+#define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal() */
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE             18
@@ -125,6 +126,7 @@ register struct thread_info *__current_thread_info __asm__("$28");
 #define _TIF_NEED_RESCHED      (1<<TIF_NEED_RESCHED)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP           (1<<TIF_SECCOMP)
+#define _TIF_RESTORE_SIGMASK   (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 
index 89ea8b6..e7ff9b1 100644 (file)
 #define __NR_inotify_init              (__NR_Linux + 284)
 #define __NR_inotify_add_watch         (__NR_Linux + 285)
 #define __NR_inotify_rm_watch          (__NR_Linux + 286)
-
+#define __NR_migrate_pages             (__NR_Linux + 287)
+#define __NR_openat                    (__NR_Linux + 288)
+#define __NR_mkdirat                   (__NR_Linux + 289)
+#define __NR_mknodat                   (__NR_Linux + 290)
+#define __NR_fchownat                  (__NR_Linux + 291)
+#define __NR_futimesat                 (__NR_Linux + 292)
+#define __NR_newfstatat                        (__NR_Linux + 293)
+#define __NR_unlinkat                  (__NR_Linux + 294)
+#define __NR_renameat                  (__NR_Linux + 295)
+#define __NR_linkat                    (__NR_Linux + 296)
+#define __NR_symlinkat                 (__NR_Linux + 297)
+#define __NR_readlinkat                        (__NR_Linux + 298)
+#define __NR_fchmodat                  (__NR_Linux + 299)
+#define __NR_faccessat                 (__NR_Linux + 300)
+#define __NR_pselect6                  (__NR_Linux + 301)
+#define __NR_ppoll                     (__NR_Linux + 302)
+#define __NR_unshare                   (__NR_Linux + 303)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls            286
+#define __NR_Linux_syscalls            303
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux                 4000
-#define __NR_O32_Linux_syscalls                283
+#define __NR_O32_Linux_syscalls                303
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 #define __NR_inotify_init              (__NR_Linux + 243)
 #define __NR_inotify_add_watch         (__NR_Linux + 244)
 #define __NR_inotify_rm_watch          (__NR_Linux + 245)
+#define __NR_migrate_pages             (__NR_Linux + 246)
+#define __NR_openat                    (__NR_Linux + 247)
+#define __NR_mkdirat                   (__NR_Linux + 248)
+#define __NR_mknodat                   (__NR_Linux + 249)
+#define __NR_fchownat                  (__NR_Linux + 250)
+#define __NR_futimesat                 (__NR_Linux + 251)
+#define __NR_newfstatat                        (__NR_Linux + 252)
+#define __NR_unlinkat                  (__NR_Linux + 253)
+#define __NR_renameat                  (__NR_Linux + 254)
+#define __NR_linkat                    (__NR_Linux + 255)
+#define __NR_symlinkat                 (__NR_Linux + 256)
+#define __NR_readlinkat                        (__NR_Linux + 257)
+#define __NR_fchmodat                  (__NR_Linux + 258)
+#define __NR_faccessat                 (__NR_Linux + 259)
+#define __NR_pselect6                  (__NR_Linux + 260)
+#define __NR_ppoll                     (__NR_Linux + 261)
+#define __NR_unshare                   (__NR_Linux + 262)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            245
+#define __NR_Linux_syscalls            262
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         242
+#define __NR_64_Linux_syscalls         262
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 #define __NR_inotify_init              (__NR_Linux + 247)
 #define __NR_inotify_add_watch         (__NR_Linux + 248)
 #define __NR_inotify_rm_watch          (__NR_Linux + 249)
+#define __NR_migrate_pages             (__NR_Linux + 250)
+#define __NR_openat                    (__NR_Linux + 251)
+#define __NR_mkdirat                   (__NR_Linux + 252)
+#define __NR_mknodat                   (__NR_Linux + 253)
+#define __NR_fchownat                  (__NR_Linux + 254)
+#define __NR_futimesat                 (__NR_Linux + 255)
+#define __NR_newfstatat                        (__NR_Linux + 256)
+#define __NR_unlinkat                  (__NR_Linux + 257)
+#define __NR_renameat                  (__NR_Linux + 258)
+#define __NR_linkat                    (__NR_Linux + 259)
+#define __NR_symlinkat                 (__NR_Linux + 260)
+#define __NR_readlinkat                        (__NR_Linux + 261)
+#define __NR_fchmodat                  (__NR_Linux + 262)
+#define __NR_faccessat                 (__NR_Linux + 263)
+#define __NR_pselect6                  (__NR_Linux + 264)
+#define __NR_ppoll                     (__NR_Linux + 265)
+#define __NR_unshare                   (__NR_Linux + 266)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls            249
+#define __NR_Linux_syscalls            266
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux                 6000
-#define __NR_N32_Linux_syscalls                246
+#define __NR_N32_Linux_syscalls                266
 
 #ifndef __ASSEMBLY__
 
index accb80c..aacaabd 100644 (file)
@@ -126,6 +126,11 @@ static inline void __user *compat_ptr(compat_uptr_t uptr)
        return (void __user *)(unsigned long)uptr;
 }
 
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+       return (u32)(unsigned long)uptr;
+}
+
 static inline void __user *compat_alloc_user_space(long len)
 {
        struct pt_regs *regs = current->thread.regs;
index 837756a..2ac63f5 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mm.h>
 #include <asm/scatterlist.h>
 #include <asm/io.h>
-#include <asm/bug.h>
 
 #define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
 
index 5b2bd4e..cbd297f 100644 (file)
@@ -222,5 +222,7 @@ extern int of_address_to_resource(struct device_node *dev, int index,
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
                                      struct resource *r);
 
+extern void kdump_move_device_tree(void);
+
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */
index 82ce476..2dc9363 100644 (file)
@@ -521,6 +521,11 @@ struct smu_sdbp_cpupiddata {
 extern struct smu_sdbp_header *smu_get_sdb_partition(int id,
                                        unsigned int *size);
 
+/* Get "sdb" partition data from an SMU satellite */
+extern struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id,
+                                       int id, unsigned int *size);
+
+
 #endif /* __KERNEL__ */
 
 
index 67cdaf3..c044ec1 100644 (file)
@@ -37,7 +37,7 @@ struct thread_info {
        int             preempt_count;          /* 0 => preemptable,
                                                   <0 => BUG */
        struct restart_block restart_block;
-       void *nvgprs_frame;
+       void __user *nvgprs_frame;
        /* low level flags - has atomic operations done on it */
        unsigned long   flags ____cacheline_aligned_in_smp;
 };
index be104f2..0b7c0ca 100644 (file)
@@ -61,7 +61,7 @@
 #define segment_eq(a,b) ((a).ar4 == (b).ar4)
 
 
-static inline int __access_ok(const void *addr, unsigned long size)
+static inline int __access_ok(const void __user *addr, unsigned long size)
 {
        return 1;
 }
@@ -208,25 +208,25 @@ extern int __put_user_bad(void) __attribute__((noreturn));
        case 1: {                                               \
                unsigned char __x;                              \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        case 2: {                                               \
                unsigned short __x;                             \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        case 4: {                                               \
                unsigned int __x;                               \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        case 8: {                                               \
                unsigned long long __x;                         \
                __get_user_asm(__x, ptr, __gu_err);             \
-               (x) = *(__typeof__(*(ptr)) *) &__x;             \
+               (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
                break;                                          \
        };                                                      \
        default:                                                \
index 2ac64e6..0615d60 100644 (file)
 #define __NR_faccessat         296
 #define __NR_pselect6          297
 #define __NR_ppoll             298
+#define __NR_unshare           299
 
-/* WARNING: You MAY NOT add syscall numbers larger than 298, since
+/* WARNING: You MAY NOT add syscall numbers larger than 299, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 298 entries (starting at zero).  Therefore
- *          find a free slot in the 0-298 range.
+ *          sized to have 299 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-299 range.
  */
 
 #define _syscall0(type,name) \
index 84ac2bd..c58ba8a 100644 (file)
 #define __NR_faccessat         296
 #define __NR_pselect6          297
 #define __NR_ppoll             298
+#define __NR_unshare           299
 
-/* WARNING: You MAY NOT add syscall numbers larger than 298, since
+/* WARNING: You MAY NOT add syscall numbers larger than 299, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 298 entries (starting at zero).  Therefore
- *          find a free slot in the 0-298 range.
+ *          sized to have 299 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-299 range.
  */
 
 #define _syscall0(type,name) \
index 9afc0c7..2046898 100644 (file)
 #define __NR_ia32_readlinkat           305
 #define __NR_ia32_fchmodat             306
 #define __NR_ia32_faccessat            307
+#define __NR_ia32_pselect6             308
+#define __NR_ia32_ppoll                        309
+#define __NR_ia32_unshare              310
 
-#define IA32_NR_syscalls 308   /* must be > than biggest syscall! */
+#define IA32_NR_syscalls 315   /* must be > than biggest syscall! */
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
index 34e434c..dffe276 100644 (file)
@@ -22,8 +22,15 @@ extern void numa_set_node(int cpu, int node);
 extern unsigned char apicid_to_node[256];
 #ifdef CONFIG_NUMA
 extern void __init init_cpu_to_node(void);
+
+static inline void clear_node_cpumask(int cpu)
+{
+       clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
+}
+
 #else
 #define init_cpu_to_node() do {} while (0)
+#define clear_node_cpumask(cpu) do {} while (0)
 #endif
 
 #define NUMA_NO_NODE 0xff
index 436d099..da0341c 100644 (file)
@@ -599,8 +599,14 @@ __SYSCALL(__NR_readlinkat, sys_readlinkat)
 __SYSCALL(__NR_fchmodat, sys_fchmodat)
 #define __NR_faccessat         269
 __SYSCALL(__NR_faccessat, sys_faccessat)
-
-#define __NR_syscall_max __NR_faccessat
+#define __NR_pselect6          270
+__SYSCALL(__NR_pselect6, sys_ni_syscall)       /* for now */
+#define __NR_ppoll             271
+__SYSCALL(__NR_ppoll,  sys_ni_syscall)         /* for now */
+#define __NR_unshare           272
+__SYSCALL(__NR_unshare,        sys_unshare)
+
+#define __NR_syscall_max __NR_unshare
 
 #ifndef __NO_STUBS
 
index 13e9f4a..20b446f 100644 (file)
@@ -84,7 +84,6 @@
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <linux/bitmap.h>
-#include <asm/bug.h>
 
 typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
 extern cpumask_t _unused_cpumask_arg_;
index a3f0994..4361f37 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/spinlock.h>
 #include <linux/cache.h>
 #include <linux/rcupdate.h>
-#include <asm/bug.h>
 
 struct nameidata;
 struct vfsmount;
index b1999bf..b81e58b 100644 (file)
@@ -135,7 +135,7 @@ typedef struct video_spu {
 
 typedef struct video_spu_palette {      /* SPU Palette information */
        int length;
-       uint8_t *palette;
+       uint8_t __user *palette;
 } video_spu_palette_t;
 
 
index 23fe746..18cf1f3 100644 (file)
@@ -82,6 +82,7 @@ struct elevator_queue
 extern void elv_dispatch_sort(request_queue_t *, struct request *);
 extern void elv_add_request(request_queue_t *, struct request *, int, int);
 extern void __elv_add_request(request_queue_t *, struct request *, int, int);
+extern void elv_insert(request_queue_t *, struct request *, int);
 extern int elv_merge(request_queue_t *, struct request **, struct bio *);
 extern void elv_merge_requests(request_queue_t *, struct request *,
                               struct request *);
index 7863a59..63f1d63 100644 (file)
@@ -100,6 +100,9 @@ extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
 /* Returns the number of read bytes */
 extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
                                         u8 command, u8 *values);
+extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
+                                         u8 command, u8 length,
+                                         u8 *values);
 
 /*
  * A driver is capable of handling one or more physical devices present on
index e7906a7..da7c09e 100644 (file)
@@ -27,7 +27,7 @@ struct ioc3_driver_data {
        int id;                         /* IOC3 sequence number */
        /* PCI mapping */
        unsigned long pma;              /* physical address */
-       struct __iomem ioc3 *vma;       /* pointer to registers */
+       struct ioc3 __iomem *vma;       /* pointer to registers */
        struct pci_dev *pdev;           /* PCI device */
        /* IRQ stuff */
        int dual_irq;                   /* set if separate IRQs are used */
index 751bb38..0fe4aa8 100644 (file)
@@ -239,7 +239,6 @@ typedef struct journal_superblock_s
 
 #include <linux/fs.h>
 #include <linux/sched.h>
-#include <asm/bug.h>
 
 #define JBD_ASSERTIONS
 #ifdef JBD_ASSERTIONS
index 85854b8..75e9f07 100644 (file)
@@ -303,7 +303,7 @@ struct page {
  */
 #define put_page_testzero(p)                           \
        ({                                              \
-               BUG_ON(page_count(p) == 0);             \
+               BUG_ON(atomic_read(&(p)->_count) == -1);\
                atomic_add_negative(-1, &(p)->_count);  \
        })
 
index fedfbc8..7dfd6e1 100644 (file)
@@ -15,7 +15,6 @@
 #include <asm/unaligned.h>
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/bug.h>
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
 #define map_bankwidth(map) 1
index 6731977..3abc8e3 100644 (file)
@@ -15,6 +15,7 @@ struct namespace {
 
 extern int copy_namespace(int, struct task_struct *);
 extern void __put_namespace(struct namespace *namespace);
+extern struct namespace *dup_namespace(struct task_struct *, struct fs_struct *);
 
 static inline void put_namespace(struct namespace *namespace)
 {
index 4726ef7..b959a45 100644 (file)
@@ -84,7 +84,6 @@
 #include <linux/threads.h>
 #include <linux/bitmap.h>
 #include <linux/numa.h>
-#include <asm/bug.h>
 
 typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
 extern nodemask_t _unused_nodemask_arg_;
index 92a619b..7a61ccd 100644 (file)
 #define PCI_VENDOR_ID_AFAVLAB          0x14db
 #define PCI_DEVICE_ID_AFAVLAB_P028     0x2180
 #define PCI_DEVICE_ID_AFAVLAB_P030     0x2182
+#define PCI_SUBDEVICE_ID_AFAVLAB_P061          0x2150
 
 #define PCI_VENDOR_ID_BROADCOM         0x14e4
 #define PCI_DEVICE_ID_TIGON3_5752      0x1600
index 9dfa3ee..44153fd 100644 (file)
@@ -17,7 +17,6 @@ extern void cpu_idle(void);
 #include <linux/compiler.h>
 #include <linux/thread_info.h>
 #include <asm/smp.h>
-#include <asm/bug.h>
 
 /*
  * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc.
index 43bcd13..37c1c76 100644 (file)
@@ -42,13 +42,21 @@ extern void mark_free_pages(struct zone *zone);
 #ifdef CONFIG_PM
 /* kernel/power/swsusp.c */
 extern int software_suspend(void);
+
+#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+extern int pm_prepare_console(void);
+extern void pm_restore_console(void);
+#else
+static inline int pm_prepare_console(void) { return 0; }
+static inline void pm_restore_console(void) {}
+#endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */
 #else
 static inline int software_suspend(void)
 {
        printk("Warning: fake suspend called\n");
        return -EPERM;
 }
-#endif
+#endif /* CONFIG_PM */
 
 #ifdef CONFIG_SUSPEND_SMP
 extern void disable_nonboot_cpus(void);
index 6f6c697..5208b12 100644 (file)
@@ -549,7 +549,7 @@ struct v4l2_framebuffer
 struct v4l2_clip
 {
        struct v4l2_rect        c;
-       struct v4l2_clip        *next;
+       struct v4l2_clip        __user *next;
 };
 
 struct v4l2_window
@@ -629,6 +629,7 @@ typedef __u64 v4l2_std_id;
 #define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
 #define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
 #define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)
 
 #define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
 #define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
@@ -661,7 +662,8 @@ typedef __u64 v4l2_std_id;
                                 V4L2_STD_PAL_H         |\
                                 V4L2_STD_PAL_I)
 #define V4L2_STD_NTSC           (V4L2_STD_NTSC_M       |\
-                                V4L2_STD_NTSC_M_JP)
+                                V4L2_STD_NTSC_M_JP     |\
+                                V4L2_STD_NTSC_M_KR)
 #define V4L2_STD_SECAM_DK              (V4L2_STD_SECAM_D       |\
                                 V4L2_STD_SECAM_K       |\
                                 V4L2_STD_SECAM_K1)
index 8b7abae..38416a1 100644 (file)
@@ -169,7 +169,6 @@ config SYSCTL
 config AUDIT
        bool "Auditing support"
        depends on NET
-       default y if SECURITY_SELINUX
        help
          Enable auditing infrastructure that can be used with another
          kernel subsystem, such as SELinux (which requires this for
index 1867290..8c9cd88 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/security.h>
 
 #include <asm/uaccess.h>
-#include <asm/bug.h>
 
 int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
 {
index 7f0ab5e..8e88b37 100644 (file)
@@ -446,6 +446,55 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
        }
 }
 
+/*
+ * Allocate a new mm structure and copy contents from the
+ * mm structure of the passed in task structure.
+ */
+static struct mm_struct *dup_mm(struct task_struct *tsk)
+{
+       struct mm_struct *mm, *oldmm = current->mm;
+       int err;
+
+       if (!oldmm)
+               return NULL;
+
+       mm = allocate_mm();
+       if (!mm)
+               goto fail_nomem;
+
+       memcpy(mm, oldmm, sizeof(*mm));
+
+       if (!mm_init(mm))
+               goto fail_nomem;
+
+       if (init_new_context(tsk, mm))
+               goto fail_nocontext;
+
+       err = dup_mmap(mm, oldmm);
+       if (err)
+               goto free_pt;
+
+       mm->hiwater_rss = get_mm_rss(mm);
+       mm->hiwater_vm = mm->total_vm;
+
+       return mm;
+
+free_pt:
+       mmput(mm);
+
+fail_nomem:
+       return NULL;
+
+fail_nocontext:
+       /*
+        * If init_new_context() failed, we cannot use mmput() to free the mm
+        * because it calls destroy_context()
+        */
+       mm_free_pgd(mm);
+       free_mm(mm);
+       return NULL;
+}
+
 static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
 {
        struct mm_struct * mm, *oldmm;
@@ -473,43 +522,17 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
        }
 
        retval = -ENOMEM;
-       mm = allocate_mm();
+       mm = dup_mm(tsk);
        if (!mm)
                goto fail_nomem;
 
-       /* Copy the current MM stuff.. */
-       memcpy(mm, oldmm, sizeof(*mm));
-       if (!mm_init(mm))
-               goto fail_nomem;
-
-       if (init_new_context(tsk,mm))
-               goto fail_nocontext;
-
-       retval = dup_mmap(mm, oldmm);
-       if (retval)
-               goto free_pt;
-
-       mm->hiwater_rss = get_mm_rss(mm);
-       mm->hiwater_vm = mm->total_vm;
-
 good_mm:
        tsk->mm = mm;
        tsk->active_mm = mm;
        return 0;
 
-free_pt:
-       mmput(mm);
 fail_nomem:
        return retval;
-
-fail_nocontext:
-       /*
-        * If init_new_context() failed, we cannot use mmput() to free the mm
-        * because it calls destroy_context()
-        */
-       mm_free_pgd(mm);
-       free_mm(mm);
-       return retval;
 }
 
 static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
@@ -597,32 +620,17 @@ out:
        return newf;
 }
 
-static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+/*
+ * Allocate a new files structure and copy contents from the
+ * passed in files structure.
+ */
+static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
 {
-       struct files_struct *oldf, *newf;
+       struct files_struct *newf;
        struct file **old_fds, **new_fds;
-       int open_files, size, i, error = 0, expand;
+       int open_files, size, i, expand;
        struct fdtable *old_fdt, *new_fdt;
 
-       /*
-        * A background process may not have any files ...
-        */
-       oldf = current->files;
-       if (!oldf)
-               goto out;
-
-       if (clone_flags & CLONE_FILES) {
-               atomic_inc(&oldf->count);
-               goto out;
-       }
-
-       /*
-        * Note: we may be using current for both targets (See exec.c)
-        * This works because we cache current->files (old) as oldf. Don't
-        * break this.
-        */
-       tsk->files = NULL;
-       error = -ENOMEM;
        newf = alloc_files();
        if (!newf)
                goto out;
@@ -651,9 +659,9 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
        if (expand) {
                spin_unlock(&oldf->file_lock);
                spin_lock(&newf->file_lock);
-               error = expand_files(newf, open_files-1);
+               *errorp = expand_files(newf, open_files-1);
                spin_unlock(&newf->file_lock);
-               if (error < 0)
+               if (*errorp < 0)
                        goto out_release;
                new_fdt = files_fdtable(newf);
                /*
@@ -702,10 +710,8 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
                memset(&new_fdt->close_on_exec->fds_bits[start], 0, left);
        }
 
-       tsk->files = newf;
-       error = 0;
 out:
-       return error;
+       return newf;
 
 out_release:
        free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset);
@@ -715,6 +721,40 @@ out_release:
        goto out;
 }
 
+static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
+{
+       struct files_struct *oldf, *newf;
+       int error = 0;
+
+       /*
+        * A background process may not have any files ...
+        */
+       oldf = current->files;
+       if (!oldf)
+               goto out;
+
+       if (clone_flags & CLONE_FILES) {
+               atomic_inc(&oldf->count);
+               goto out;
+       }
+
+       /*
+        * Note: we may be using current for both targets (See exec.c)
+        * This works because we cache current->files (old) as oldf. Don't
+        * break this.
+        */
+       tsk->files = NULL;
+       error = -ENOMEM;
+       newf = dup_fd(oldf, &error);
+       if (!newf)
+               goto out;
+
+       tsk->files = newf;
+       error = 0;
+out:
+       return error;
+}
+
 /*
  *     Helper to unshare the files of the current task.
  *     We don't want to expose copy_files internals to
@@ -1323,3 +1363,249 @@ void __init proc_caches_init(void)
                        sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
                        SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
 }
+
+
+/*
+ * Check constraints on flags passed to the unshare system call and
+ * force unsharing of additional process context as appropriate.
+ */
+static inline void check_unshare_flags(unsigned long *flags_ptr)
+{
+       /*
+        * If unsharing a thread from a thread group, must also
+        * unshare vm.
+        */
+       if (*flags_ptr & CLONE_THREAD)
+               *flags_ptr |= CLONE_VM;
+
+       /*
+        * If unsharing vm, must also unshare signal handlers.
+        */
+       if (*flags_ptr & CLONE_VM)
+               *flags_ptr |= CLONE_SIGHAND;
+
+       /*
+        * If unsharing signal handlers and the task was created
+        * using CLONE_THREAD, then must unshare the thread
+        */
+       if ((*flags_ptr & CLONE_SIGHAND) &&
+           (atomic_read(&current->signal->count) > 1))
+               *flags_ptr |= CLONE_THREAD;
+
+       /*
+        * If unsharing namespace, must also unshare filesystem information.
+        */
+       if (*flags_ptr & CLONE_NEWNS)
+               *flags_ptr |= CLONE_FS;
+}
+
+/*
+ * Unsharing of tasks created with CLONE_THREAD is not supported yet
+ */
+static int unshare_thread(unsigned long unshare_flags)
+{
+       if (unshare_flags & CLONE_THREAD)
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * Unshare the filesystem structure if it is being shared
+ */
+static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+{
+       struct fs_struct *fs = current->fs;
+
+       if ((unshare_flags & CLONE_FS) &&
+           (fs && atomic_read(&fs->count) > 1)) {
+               *new_fsp = __copy_fs_struct(current->fs);
+               if (!*new_fsp)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Unshare the namespace structure if it is being shared
+ */
+static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs)
+{
+       struct namespace *ns = current->namespace;
+
+       if ((unshare_flags & CLONE_NEWNS) &&
+           (ns && atomic_read(&ns->count) > 1)) {
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+
+               *new_nsp = dup_namespace(current, new_fs ? new_fs : current->fs);
+               if (!*new_nsp)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Unsharing of sighand for tasks created with CLONE_SIGHAND is not
+ * supported yet
+ */
+static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp)
+{
+       struct sighand_struct *sigh = current->sighand;
+
+       if ((unshare_flags & CLONE_SIGHAND) &&
+           (sigh && atomic_read(&sigh->count) > 1))
+               return -EINVAL;
+       else
+               return 0;
+}
+
+/*
+ * Unshare vm if it is being shared
+ */
+static int unshare_vm(unsigned long unshare_flags, struct mm_struct **new_mmp)
+{
+       struct mm_struct *mm = current->mm;
+
+       if ((unshare_flags & CLONE_VM) &&
+           (mm && atomic_read(&mm->mm_users) > 1)) {
+               *new_mmp = dup_mm(current);
+               if (!*new_mmp)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/*
+ * Unshare file descriptor table if it is being shared
+ */
+static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
+{
+       struct files_struct *fd = current->files;
+       int error = 0;
+
+       if ((unshare_flags & CLONE_FILES) &&
+           (fd && atomic_read(&fd->count) > 1)) {
+               *new_fdp = dup_fd(fd, &error);
+               if (!*new_fdp)
+                       return error;
+       }
+
+       return 0;
+}
+
+/*
+ * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not
+ * supported yet
+ */
+static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp)
+{
+       if (unshare_flags & CLONE_SYSVSEM)
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * unshare allows a process to 'unshare' part of the process
+ * context which was originally shared using clone.  copy_*
+ * functions used by do_fork() cannot be used here directly
+ * because they modify an inactive task_struct that is being
+ * constructed. Here we are modifying the current, active,
+ * task_struct.
+ */
+asmlinkage long sys_unshare(unsigned long unshare_flags)
+{
+       int err = 0;
+       struct fs_struct *fs, *new_fs = NULL;
+       struct namespace *ns, *new_ns = NULL;
+       struct sighand_struct *sigh, *new_sigh = NULL;
+       struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
+       struct files_struct *fd, *new_fd = NULL;
+       struct sem_undo_list *new_ulist = NULL;
+
+       check_unshare_flags(&unshare_flags);
+
+       if ((err = unshare_thread(unshare_flags)))
+               goto bad_unshare_out;
+       if ((err = unshare_fs(unshare_flags, &new_fs)))
+               goto bad_unshare_cleanup_thread;
+       if ((err = unshare_namespace(unshare_flags, &new_ns, new_fs)))
+               goto bad_unshare_cleanup_fs;
+       if ((err = unshare_sighand(unshare_flags, &new_sigh)))
+               goto bad_unshare_cleanup_ns;
+       if ((err = unshare_vm(unshare_flags, &new_mm)))
+               goto bad_unshare_cleanup_sigh;
+       if ((err = unshare_fd(unshare_flags, &new_fd)))
+               goto bad_unshare_cleanup_vm;
+       if ((err = unshare_semundo(unshare_flags, &new_ulist)))
+               goto bad_unshare_cleanup_fd;
+
+       if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) {
+
+               task_lock(current);
+
+               if (new_fs) {
+                       fs = current->fs;
+                       current->fs = new_fs;
+                       new_fs = fs;
+               }
+
+               if (new_ns) {
+                       ns = current->namespace;
+                       current->namespace = new_ns;
+                       new_ns = ns;
+               }
+
+               if (new_sigh) {
+                       sigh = current->sighand;
+                       current->sighand = new_sigh;
+                       new_sigh = sigh;
+               }
+
+               if (new_mm) {
+                       mm = current->mm;
+                       active_mm = current->active_mm;
+                       current->mm = new_mm;
+                       current->active_mm = new_mm;
+                       activate_mm(active_mm, new_mm);
+                       new_mm = mm;
+               }
+
+               if (new_fd) {
+                       fd = current->files;
+                       current->files = new_fd;
+                       new_fd = fd;
+               }
+
+               task_unlock(current);
+       }
+
+bad_unshare_cleanup_fd:
+       if (new_fd)
+               put_files_struct(new_fd);
+
+bad_unshare_cleanup_vm:
+       if (new_mm)
+               mmput(new_mm);
+
+bad_unshare_cleanup_sigh:
+       if (new_sigh)
+               if (atomic_dec_and_test(&new_sigh->count))
+                       kmem_cache_free(sighand_cachep, new_sigh);
+
+bad_unshare_cleanup_ns:
+       if (new_ns)
+               put_namespace(new_ns);
+
+bad_unshare_cleanup_fs:
+       if (new_fs)
+               put_fs_struct(new_fs);
+
+bad_unshare_cleanup_thread:
+bad_unshare_out:
+       return err;
+}
index e058aed..5aad477 100644 (file)
@@ -1670,6 +1670,9 @@ static struct module *load_module(void __user *umod,
                goto free_mod;
        }
 
+       /* Userspace could have altered the string after the strlen_user() */
+       args[arglen - 1] = '\0';
+
        if (find_module(mod->name)) {
                err = -EEXIST;
                goto free_mod;
index 579d239..623786d 100644 (file)
@@ -9,7 +9,9 @@
 #include <linux/console.h>
 #include "power.h"
 
-#ifdef SUSPEND_CONSOLE
+#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
+#define SUSPEND_CONSOLE        (MAX_NR_CONSOLES-1)
+
 static int orig_fgconsole, orig_kmsg;
 
 int pm_prepare_console(void)
index d8f0d1a..388dba6 100644 (file)
@@ -1,14 +1,6 @@
 #include <linux/suspend.h>
 #include <linux/utsname.h>
 
-/* With SUSPEND_CONSOLE defined suspend looks *really* cool, but
-   we probably do not take enough locks for switching consoles, etc,
-   so bad things might happen.
-*/
-#if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE)
-#define SUSPEND_CONSOLE        (MAX_NR_CONSOLES-1)
-#endif
-
 struct swsusp_info {
        struct new_utsname      uts;
        u32                     version_code;
@@ -42,14 +34,6 @@ static struct subsys_attribute _name##_attr = {      \
 
 extern struct subsystem power_subsys;
 
-#ifdef SUSPEND_CONSOLE
-extern int pm_prepare_console(void);
-extern void pm_restore_console(void);
-#else
-static int pm_prepare_console(void) { return 0; }
-static void pm_restore_console(void) {}
-#endif
-
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
 
index 59c91c1..4e90905 100644 (file)
@@ -743,7 +743,6 @@ static int submit(int rw, pgoff_t page_off, void *page)
        if (!bio)
                return -ENOMEM;
        bio->bi_sector = page_off * (PAGE_SIZE >> 9);
-       bio_get(bio);
        bio->bi_bdev = resume_bdev;
        bio->bi_end_io = end_io;
 
@@ -753,14 +752,13 @@ static int submit(int rw, pgoff_t page_off, void *page)
                goto Done;
        }
 
-       if (rw == WRITE)
-               bio_set_pages_dirty(bio);
 
        atomic_set(&io_done, 1);
        submit_bio(rw | (1 << BIO_RW_SYNC), bio);
        while (atomic_read(&io_done))
                yield();
-
+       if (rw == READ)
+               bio_set_pages_dirty(bio);
  Done:
        bio_put(bio);
        return error;
index 0929c69..f91218a 100644 (file)
@@ -428,7 +428,7 @@ void kernel_kexec(void)
 {
 #ifdef CONFIG_KEXEC
        struct kimage *image;
-       image = xchg(&kexec_image, 0);
+       image = xchg(&kexec_image, NULL);
        if (!image) {
                return;
        }
index 4f1cb0a..b9dad39 100644 (file)
@@ -495,7 +495,7 @@ unsigned long next_timer_interrupt(void)
        base = &__get_cpu_var(tvec_bases);
        spin_lock(&base->t_base.lock);
        expires = base->timer_jiffies + (LONG_MAX >> 1);
-       list = 0;
+       list = NULL;
 
        /* Look for timer events in tv1. */
        j = base->timer_jiffies & TVR_MASK;
index 7a0e680..efe67fa 100644 (file)
@@ -72,6 +72,8 @@ static int get_kobj_path_length(struct kobject *kobj)
         * Add 1 to strlen for leading '/' of each level.
         */
        do {
+               if (kobject_name(parent) == NULL)
+                       return 0;
                length += strlen(kobject_name(parent)) + 1;
                parent = parent->parent;
        } while (parent);
@@ -107,6 +109,8 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
        int len;
 
        len = get_kobj_path_length(kobj);
+       if (len == 0)
+               return NULL;
        path = kmalloc(len, gfp_mask);
        if (!path)
                return NULL;
@@ -162,6 +166,11 @@ int kobject_add(struct kobject * kobj)
                return -ENOENT;
        if (!kobj->k_name)
                kobj->k_name = kobj->name;
+       if (!kobj->k_name) {
+               pr_debug("kobject attempted to be registered with no name!\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
        parent = kobject_get(kobj->parent);
 
        pr_debug("kobject %s: registering. parent: %s, set: %s\n",
index f56e27a..1b1985c 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/kobject.h>
 #include <net/sock.h>
 
-#define BUFFER_SIZE    1024    /* buffer for the variables */
+#define BUFFER_SIZE    2048    /* buffer for the variables */
 #define NUM_ENVP       32      /* number of env pointers */
 
 #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
index c8bb8cc..d8b6bb4 100644 (file)
@@ -72,9 +72,9 @@ static void __spin_lock_debug(spinlock_t *lock)
 
        for (;;) {
                for (i = 0; i < loops_per_jiffy * HZ; i++) {
-                       cpu_relax();
                        if (__raw_spin_trylock(&lock->raw_lock))
                                return;
+                       __delay(1);
                }
                /* lockup suspected: */
                if (print_once) {
@@ -144,9 +144,9 @@ static void __read_lock_debug(rwlock_t *lock)
 
        for (;;) {
                for (i = 0; i < loops_per_jiffy * HZ; i++) {
-                       cpu_relax();
                        if (__raw_read_trylock(&lock->raw_lock))
                                return;
+                       __delay(1);
                }
                /* lockup suspected: */
                if (print_once) {
@@ -217,9 +217,9 @@ static void __write_lock_debug(rwlock_t *lock)
 
        for (;;) {
                for (i = 0; i < loops_per_jiffy * HZ; i++) {
-                       cpu_relax();
                        if (__raw_write_trylock(&lock->raw_lock))
                                return;
+                       __delay(1);
                }
                /* lockup suspected: */
                if (print_once) {
index ceb3ebb..67f2951 100644 (file)
@@ -107,7 +107,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr)
        set_page_count(page, 1);
        page[1].mapping = (void *)free_huge_page;
        for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i)
-               clear_highpage(&page[i]);
+               clear_user_highpage(&page[i], addr);
        return page;
 }
 
@@ -391,12 +391,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
 
        if (!new_page) {
                page_cache_release(old_page);
-
-               /* Logically this is OOM, not a SIGBUS, but an OOM
-                * could cause the kernel to go killing other
-                * processes which won't help the hugepage situation
-                * at all (?) */
-               return VM_FAULT_SIGBUS;
+               return VM_FAULT_OOM;
        }
 
        spin_unlock(&mm->page_table_lock);
@@ -444,15 +439,7 @@ retry:
                page = alloc_huge_page(vma, address);
                if (!page) {
                        hugetlb_put_quota(mapping);
-                       /*
-                        * No huge pages available. So this is an OOM
-                        * condition but we do not want to trigger the OOM
-                        * killer, so we return VM_FAULT_SIGBUS.
-                        *
-                        * A program using hugepages may fault with Bus Error
-                        * because no huge pages are available in the cpuset, per
-                        * memory policy or because all are in use!
-                        */
+                       ret = VM_FAULT_OOM;
                        goto out;
                }
 
index 1c240c4..a1f42bd 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -336,7 +336,7 @@ EXPORT_SYMBOL(slab_reclaim_pages);
 
 #ifdef CONFIG_SMP
 
-void *__alloc_percpu(size_t size, size_t align)
+void *__alloc_percpu(size_t size)
 {
        int i;
        struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);
index bc2442a..7624742 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
 /* How many pages do we try to swap or page in/out together? */
 int page_cluster;
 
-void put_page(struct page *page)
+static void put_compound_page(struct page *page)
 {
-       if (unlikely(PageCompound(page))) {
-               page = (struct page *)page_private(page);
-               if (put_page_testzero(page)) {
-                       void (*dtor)(struct page *page);
+       page = (struct page *)page_private(page);
+       if (put_page_testzero(page)) {
+               void (*dtor)(struct page *page);
 
-                       dtor = (void (*)(struct page *))page[1].mapping;
-                       (*dtor)(page);
-               }
-               return;
+               dtor = (void (*)(struct page *))page[1].mapping;
+               (*dtor)(page);
        }
-       if (put_page_testzero(page))
+}
+
+void put_page(struct page *page)
+{
+       if (unlikely(PageCompound(page)))
+               put_compound_page(page);
+       else if (put_page_testzero(page))
                __page_cache_release(page);
 }
 EXPORT_SYMBOL(put_page);
@@ -244,6 +247,15 @@ void release_pages(struct page **pages, int nr, int cold)
                struct page *page = pages[i];
                struct zone *pagezone;
 
+               if (unlikely(PageCompound(page))) {
+                       if (zone) {
+                               spin_unlock_irq(&zone->lru_lock);
+                               zone = NULL;
+                       }
+                       put_compound_page(page);
+                       continue;
+               }
+
                if (!put_page_testzero(page))
                        continue;
 
index d2b5933..add3cae 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/config.h>
 #include <linux/module.h>
 
-#include <asm/bug.h>
 #include <asm/div64.h>
 
 #include "tfrc.h"
index 0b4e95f..64ce52b 100644 (file)
@@ -1578,7 +1578,7 @@ static int sf_setstate(struct ip_mc_list *pmc)
                        new_in = psf->sf_count[MCAST_INCLUDE] != 0;
                if (new_in) {
                        if (!psf->sf_oldin) {
-                               struct ip_sf_list *prev = 0;
+                               struct ip_sf_list *prev = NULL;
 
                                for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) {
                                        if (dpsf->sf_inaddr == psf->sf_inaddr)
index 42196ba..45f7ae5 100644 (file)
@@ -8,7 +8,6 @@
  *     
  */
 
-#include <asm/bug.h>
 #include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/inetdevice.h>
index 1db5048..b7d8822 100644 (file)
@@ -2165,6 +2165,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                                        dev->name);
                                break;
                        }
+
+                       if (idev)
+                               idev->if_flags |= IF_READY;
                } else {
                        if (!netif_carrier_ok(dev)) {
                                /* device is still not ready. */
index 4420948..807c021 100644 (file)
@@ -1978,7 +1978,7 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
                        new_in = psf->sf_count[MCAST_INCLUDE] != 0;
                if (new_in) {
                        if (!psf->sf_oldin) {
-                               struct ip6_sf_list *prev = 0;
+                               struct ip6_sf_list *prev = NULL;
 
                                for (dpsf=pmc->mca_tomb; dpsf;
                                     dpsf=dpsf->sf_next) {
index 66f1d12..738376c 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
-#include <asm/bug.h>
 
 #include <net/ip.h>
 #include <net/sock.h>
index 69bd957..91cce8b 100644 (file)
@@ -11,7 +11,6 @@
  * 
  */
 
-#include <asm/bug.h>
 #include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/netdevice.h>
index 077bbf9..dbf4620 100644 (file)
@@ -13,7 +13,6 @@
  *
  */
 
-#include <asm/bug.h>
 #include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
index 502f78f..f636f53 100644 (file)
@@ -1,6 +1,6 @@
 config SECURITY_SELINUX
        bool "NSA SELinux Support"
-       depends on SECURITY_NETWORK && NET && INET
+       depends on SECURITY_NETWORK && AUDIT && NET && INET
        default n
        help
          This selects NSA Security-Enhanced Linux (SELinux).
index 53d6c7b..ac5d69b 100644 (file)
@@ -43,13 +43,11 @@ static const struct av_perm_to_string
 #undef S_
 };
 
-#ifdef CONFIG_AUDIT
 static const char *class_to_string[] = {
 #define S_(s) s,
 #include "class_to_string.h"
 #undef S_
 };
-#endif
 
 #define TB_(s) static const char * s [] = {
 #define TE_(s) };
index 3a6d486..0741c28 100644 (file)
@@ -178,10 +178,10 @@ tas_write_register(       struct tas_data_t *self,
        if (write_mode & WRITE_SHADOW)
                memcpy(self->shadow[reg_num],data,reg_width);
        if (write_mode & WRITE_HW) {
-               rc=i2c_smbus_write_block_data(self->client,
-                                             reg_num,
-                                             reg_width,
-                                             data);
+               rc=i2c_smbus_write_i2c_block_data(self->client,
+                                                 reg_num,
+                                                 reg_width,
+                                                 data);
                if (rc < 0) {
                        printk("tas: I2C block write failed \n");  
                        return rc; 
@@ -199,10 +199,10 @@ tas_sync_register(        struct tas_data_t *self,
 
        if (reg_width==0 || self==NULL)
                return -EINVAL;
-       rc=i2c_smbus_write_block_data(self->client,
-                                     reg_num,
-                                     reg_width,
-                                     self->shadow[reg_num]);
+       rc=i2c_smbus_write_i2c_block_data(self->client,
+                                         reg_num,
+                                         reg_width,
+                                         self->shadow[reg_num]);
        if (rc < 0) {
                printk("tas: I2C block write failed \n");
                return rc;
index 67c3fd0..2ce5618 100644 (file)
@@ -29,7 +29,7 @@
  **********************************************************************
  */
 
-#include <asm/delay.h>
+#include <linux/delay.h>
 #include "8010.h"
 #include "recmgr.h"
 
index 4988f87..aa57170 100644 (file)
@@ -66,7 +66,7 @@ static int snd_pmac_dbdma_alloc(struct snd_pmac *chip, struct pmac_dbdma *rec, i
 
 static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec)
 {
-       if (rec) {
+       if (rec->space) {
                unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
 
                dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
@@ -881,6 +881,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
        chip->can_capture = 1;
        chip->num_freqs = ARRAY_SIZE(awacs_freqs);
        chip->freq_table = awacs_freqs;
+       chip->pdev = NULL;
 
        chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
 
index 15c63cb..838fc11 100644 (file)
@@ -239,8 +239,8 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix)
        block[4] = (right_vol >> 8)  & 0xff;
        block[5] = (right_vol >> 0)  & 0xff;
   
-       if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL,
-                                      6, block) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6,
+                                          block) < 0) {
                snd_printk("failed to set volume \n");
                return -EINVAL;
        }
@@ -345,8 +345,8 @@ static int tumbler_set_drc(struct pmac_tumbler *mix)
                val[1] = 0;
        }
 
-       if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-                                      2, val) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+                                          2, val) < 0) {
                snd_printk("failed to set DRC\n");
                return -EINVAL;
        }
@@ -381,8 +381,8 @@ static int snapper_set_drc(struct pmac_tumbler *mix)
        val[4] = 0x60;
        val[5] = 0xa0;
 
-       if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-                                      6, val) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+                                          6, val) < 0) {
                snd_printk("failed to set DRC\n");
                return -EINVAL;
        }
@@ -492,8 +492,8 @@ static int tumbler_set_mono_volume(struct pmac_tumbler *mix,
        vol = info->table[vol];
        for (i = 0; i < info->bytes; i++)
                block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
-       if (i2c_smbus_write_block_data(mix->i2c.client, info->reg,
-                                      info->bytes, block) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg,
+                                          info->bytes, block) < 0) {
                snd_printk("failed to set mono volume %d\n", info->index);
                return -EINVAL;
        }
@@ -625,7 +625,8 @@ static int snapper_set_mix_vol1(struct pmac_tumbler *mix, int idx, int ch, int r
                for (j = 0; j < 3; j++)
                        block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
        }
-       if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) {
+       if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg,
+                                          9, block) < 0) {
                snd_printk("failed to set mono volume %d\n", reg);
                return -EINVAL;
        }