Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 14 Feb 2007 01:34:23 +0000 (17:34 -0800)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Wed, 14 Feb 2007 01:34:23 +0000 (17:34 -0800)
* master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc: (61 commits)
  [POWERPC] Use udbg_early_init() on ppc32
  [POWERPC] Open Firmware serial port driver
  [POWERPC] Move MPIC smp routines into mpic.c
  [POWERPC] Cleanup pseries kexec code
  [POWERPC] Cleanup pseries smp initialisation code
  [POWERPC] Consolidate pseries platform header files into pseries.h
  [POWERPC] 85xx: Drop use of SYNC macro in head_fsl_booke.S
  [POWERPC] cell: pm_rtas_activat_signals routine cleanup
  [POWERPC] cell: PPU Oprofile cleanup patch
  [POWERPC] spufs: avoid accessing kernel memory through mmapped /mem node
  [POWERPC] spu sched: static timeslicing for SCHED_RR contexts
  [POWERPC] spu sched: use DECLARE_BITMAP
  [POWERPC] spu sched: forced preemption at execution
  [POWERPC] spu sched: update some comments
  [POWERPC] spu sched: simplity spu_remove_from_active_list
  [POWERPC] spufs: optimize spu_run
  [POWERPC] spufs: runqueue simplification
  [POWERPC] spufs: move prio to spu_context
  [POWERPC] spufs: state_mutex cleanup
  [POWERPC] spufs: simplify state_mutex
  ...

128 files changed:
Documentation/i2c/busses/i2c-i801
Documentation/i2c/busses/i2c-parport
Documentation/i2c/busses/i2c-piix4
Documentation/i2c/busses/i2c-viapro
Documentation/i2c/porting-clients
Documentation/i2c/smbus-protocol
Documentation/i2c/writing-clients
MAINTAINERS
arch/mips/Kconfig
arch/mips/configs/ip27_defconfig
arch/mips/dec/int-handler.S
arch/mips/kernel/entry.S
arch/mips/kernel/linux32.c
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/signal-common.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/mm/Makefile
arch/mips/mm/c-sb1.c
arch/mips/mm/dma-coherent.c [deleted file]
arch/mips/mm/dma-default.c [new file with mode: 0644]
arch/mips/mm/dma-ip27.c [deleted file]
arch/mips/mm/dma-ip32.c [deleted file]
arch/mips/mm/dma-noncoherent.c [deleted file]
arch/mips/pci/Makefile
arch/mips/pci/pci-dac.c [new file with mode: 0644]
drivers/acpi/i2c_ec.c
drivers/char/keyboard.c
drivers/char/sysrq.c
drivers/char/tty_io.c
drivers/char/vt.c
drivers/char/watchdog/acquirewdt.c
drivers/char/watchdog/advantechwdt.c
drivers/char/watchdog/alim1535_wdt.c
drivers/char/watchdog/alim7101_wdt.c
drivers/char/watchdog/cpu5wdt.c
drivers/char/watchdog/eurotechwdt.c
drivers/char/watchdog/i6300esb.c
drivers/char/watchdog/i8xx_tco.c
drivers/char/watchdog/iTCO_wdt.c
drivers/char/watchdog/ib700wdt.c
drivers/char/watchdog/ibmasr.c
drivers/char/watchdog/indydog.c
drivers/char/watchdog/machzwd.c
drivers/char/watchdog/mixcomwd.c
drivers/char/watchdog/pc87413_wdt.c
drivers/char/watchdog/pcwd.c
drivers/char/watchdog/pcwd_pci.c
drivers/char/watchdog/pcwd_usb.c
drivers/char/watchdog/pnx4008_wdt.c
drivers/char/watchdog/s3c2410_wdt.c
drivers/char/watchdog/sbc60xxwdt.c
drivers/char/watchdog/sbc8360.c
drivers/char/watchdog/sbc_epx_c3.c
drivers/char/watchdog/sc1200wdt.c
drivers/char/watchdog/sc520_wdt.c
drivers/char/watchdog/shwdt.c
drivers/char/watchdog/smsc37b787_wdt.c
drivers/char/watchdog/softdog.c
drivers/char/watchdog/w83627hf_wdt.c
drivers/char/watchdog/w83697hf_wdt.c
drivers/char/watchdog/w83877f_wdt.c
drivers/char/watchdog/w83977f_wdt.c
drivers/char/watchdog/wafer5823wdt.c
drivers/char/watchdog/wdt.c
drivers/char/watchdog/wdt977.c
drivers/char/watchdog/wdt_pci.c
drivers/hwmon/vt8231.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali1563.c
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-amd756-s4882.c
drivers/i2c/busses/i2c-amd756.c
drivers/i2c/busses/i2c-amd8111.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-i810.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-isa.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-nforce2.c
drivers/i2c/busses/i2c-parport.h
drivers/i2c/busses/i2c-pasemi.c [new file with mode: 0644]
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-savage4.c
drivers/i2c/busses/i2c-sis5595.c
drivers/i2c/busses/i2c-sis630.c
drivers/i2c/busses/i2c-sis96x.c
drivers/i2c/busses/i2c-via.c
drivers/i2c/busses/i2c-viapro.c
drivers/i2c/busses/i2c-voodoo3.c
drivers/i2c/busses/scx200_acb.c
drivers/i2c/busses/scx200_i2c.c
drivers/i2c/i2c-core.c
drivers/ieee1394/pcilynx.c
drivers/media/dvb/b2c2/flexcop-i2c.c
drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/video/cafe_ccic.c
drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
drivers/media/video/usbvision/usbvision-i2c.c
drivers/media/video/w9968cf.c
drivers/media/video/zoran_card.c
drivers/rtc/rtc-ds1672.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-rs5c372.c
drivers/rtc/rtc-x1205.c
drivers/video/matrox/i2c-matroxfb.c
fs/dcache.c
include/asm-mips/atomic.h
include/asm-mips/bitops.h
include/asm-mips/compat-signal.h [new file with mode: 0644]
include/asm-mips/dma-mapping.h
include/asm-mips/mach-generic/dma-coherence.h [new file with mode: 0644]
include/asm-mips/mach-generic/kmalloc.h
include/asm-mips/mach-ip27/dma-coherence.h [new file with mode: 0644]
include/asm-mips/mach-ip32/dma-coherence.h [new file with mode: 0644]
include/asm-mips/mach-jazz/dma-coherence.h [new file with mode: 0644]
include/asm-mips/spinlock.h
include/asm-mips/system.h
include/asm-mips/uaccess.h
include/linux/i2c-id.h
include/linux/i2c.h
include/linux/pci_ids.h

index 3db69a086c41d466afa26dfc6132c82b304a57e7..c34f0db78a30f9f66b22f055f92cd95ae024c6dc 100644 (file)
@@ -48,14 +48,9 @@ following:
 The SMBus controller is function 3 in device 1f. Class 0c05 is SMBus Serial
 Controller.
 
-If you do NOT see the 24x3 device at function 3, and you can't figure out
-any way in the BIOS to enable it,
-
 The ICH chips are quite similar to Intel's PIIX4 chip, at least in the
 SMBus controller.
 
-See the file i2c-piix4 for some additional information.
-
 
 Process Call Support
 --------------------
@@ -74,6 +69,61 @@ SMBus 2.0 Support
 
 The 82801DB (ICH4) and later chips support several SMBus 2.0 features.
 
+
+Hidden ICH SMBus
+----------------
+
+If your system has an Intel ICH south bridge, but you do NOT see the
+SMBus device at 00:1f.3 in lspci, and you can't figure out any way in the
+BIOS to enable it, it means it has been hidden by the BIOS code. Asus is
+well known for first doing this on their P4B motherboard, and many other
+boards after that. Some vendor machines are affected as well.
+
+The first thing to try is the "i2c_ec" ACPI driver. It could be that the
+SMBus was hidden on purpose because it'll be driven by ACPI. If the
+i2c_ec driver works for you, just forget about the i2c-i801 driver and
+don't try to unhide the ICH SMBus. Even if i2c_ec doesn't work, you
+better make sure that the SMBus isn't used by the ACPI code. Try loading
+the "fan" and "thermal" drivers, and check in /proc/acpi/fan and
+/proc/acpi/thermal_zone. If you find anything there, it's likely that
+the ACPI is accessing the SMBus and it's safer not to unhide it. Only
+once you are certain that ACPI isn't using the SMBus, you can attempt
+to unhide it.
+
+In order to unhide the SMBus, we need to change the value of a PCI
+register before the kernel enumerates the PCI devices. This is done in
+drivers/pci/quirks.c, where all affected boards must be listed (see
+function asus_hides_smbus_hostbridge.) If the SMBus device is missing,
+and you think there's something interesting on the SMBus (e.g. a
+hardware monitoring chip), you need to add your board to the list.
+
+The motherboard is identified using the subvendor and subdevice IDs of the
+host bridge PCI device. Get yours with "lspci -n -v -s 00:00.0":
+
+00:00.0 Class 0600: 8086:2570 (rev 02)
+        Subsystem: 1043:80f2
+        Flags: bus master, fast devsel, latency 0
+        Memory at fc000000 (32-bit, prefetchable) [size=32M]
+        Capabilities: [e4] #09 [2106]
+        Capabilities: [a0] AGP version 3.0
+
+Here the host bridge ID is 2570 (82865G/PE/P), the subvendor ID is 1043
+(Asus) and the subdevice ID is 80f2 (P4P800-X). You can find the symbolic
+names for the bridge ID and the subvendor ID in include/linux/pci_ids.h,
+and then add a case for your subdevice ID at the right place in
+drivers/pci/quirks.c. Then please give it very good testing, to make sure
+that the unhidden SMBus doesn't conflict with e.g. ACPI.
+
+If it works, proves useful (i.e. there are usable chips on the SMBus)
+and seems safe, please submit a patch for inclusion into the kernel.
+
+Note: There's a useful script in lm_sensors 2.10.2 and later, named
+unhide_ICH_SMBus (in prog/hotplug), which uses the fakephp driver to
+temporarily unhide the SMBus without having to patch and recompile your
+kernel. It's very convenient if you just want to check if there's
+anything interesting on your hidden ICH SMBus.
+
+
 **********************
 The lm_sensors project gratefully acknowledges the support of Texas
 Instruments in the initial development of this driver.
index 77b995dfca22652bc94532a9145047d444b8baec..dceaba1ad930733e04d95dca441ec3c411f7f0be 100644 (file)
@@ -19,6 +19,7 @@ It currently supports the following devices:
  * (type=4) Analog Devices ADM1032 evaluation board
  * (type=5) Analog Devices evaluation boards: ADM1025, ADM1030, ADM1031
  * (type=6) Barco LPT->DVI (K5800236) adapter
+ * (type=7) One For All JP1 parallel port adapter
 
 These devices use different pinout configurations, so you have to tell
 the driver what you have, using the type module parameter. There is no
@@ -157,3 +158,17 @@ many more, using /dev/velleman.
   http://home.wanadoo.nl/hihihi/libk8005.htm
   http://struyve.mine.nu:8080/index.php?block=k8000
   http://sourceforge.net/projects/libk8005/
+
+
+One For All JP1 parallel port adapter
+-------------------------------------
+
+The JP1 project revolves around a set of remote controls which expose
+the I2C bus their internal configuration EEPROM lives on via a 6 pin
+jumper in the battery compartment. More details can be found at:
+
+http://www.hifi-remote.com/jp1/
+
+Details of the simple parallel port hardware can be found at:
+
+http://www.hifi-remote.com/jp1/hardware.shtml
index 921476333235b3b207c30458f97986956c372b68..7cbe43fa2701dfb875a7eae69754ecb557e5c043 100644 (file)
@@ -6,7 +6,7 @@ Supported adapters:
     Datasheet: Publicly available at the Intel website
   * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
     Datasheet: Only available via NDA from ServerWorks
-  * ATI IXP southbridges IXP200, IXP300, IXP400
+  * ATI IXP200, IXP300, IXP400 and SB600 southbridges
     Datasheet: Not publicly available
   * Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
     Datasheet: Publicly available at the SMSC website http://www.smsc.com
index 25680346e0acd2059bf23608f5982b8bb2163eaf..775f489e86f63162d9abe00b1588f4b515704521 100644 (file)
@@ -13,6 +13,9 @@ Supported adapters:
   * VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8251
     Datasheet: available on request and under NDA from VIA
 
+  * VIA Technologies, Inc. CX700
+    Datasheet: available on request and under NDA from VIA
+
 Authors:
        Kyösti Mälkki <kmalkki@cc.hut.fi>,
        Mark D. Studebaker <mdsxyz123@yahoo.com>,
@@ -44,6 +47,7 @@ Your lspci -n listing must show one of these :
  device 1106:3227   (VT8237R)
  device 1106:3337   (VT8237A)
  device 1106:3287   (VT8251)
+ device 1106:8324   (CX700)
 
 If none of these show up, you should look in the BIOS for settings like
 enable ACPI / SMBus or even USB.
@@ -51,3 +55,6 @@ enable ACPI / SMBus or even USB.
 Except for the oldest chips (VT82C596A/B, VT82C686A and most probably
 VT8231), this driver supports I2C block transactions. Such transactions
 are mainly useful to read from and write to EEPROMs.
+
+The CX700 additionally appears to support SMBus PEC, although this driver
+doesn't implement it yet.
index f03c2a02f806684c39c0cd8459eaab71a661496b..ca272b263a92e5f2aefaf0158c30145ba7119a9f 100644 (file)
@@ -129,6 +129,12 @@ Technical changes:
   structure, those name member should be initialized to a driver name
   string. i2c_driver itself has no name member anymore.
 
+* [Driver model] Instead of shutdown or reboot notifiers, provide a
+  shutdown() method in your driver.
+
+* [Power management] Use the driver model suspend() and resume()
+  callbacks instead of the obsolete pm_register() calls.
+
 Coding policy:
 
 * [Copyright] Use (C), not (c), for copyright.
index 09f5e5ca49272544002b862d0b61af21bc66ce70..8a653c60d25a22d1bde489b947e58b0847d6e324 100644 (file)
@@ -97,7 +97,7 @@ SMBus Write Word Data
 =====================
 
 This is the opposite operation of the Read Word Data command. 16 bits
-of data is read from a device, from a designated register that is 
+of data is written to a device, to the designated register that is
 specified through the Comm byte. 
 
 S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
index 3a057c8e5507c4d1ef8620b93fff8bfe1f208702..fbcff96f4ca1f8881d8459ff94c74ac1e38e6417 100644 (file)
@@ -21,20 +21,26 @@ The driver structure
 
 Usually, you will implement a single driver structure, and instantiate
 all clients from it. Remember, a driver structure contains general access 
-routines, a client structure specific information like the actual I2C
-address.
+routines, and should be zero-initialized except for fields with data you
+provide.  A client structure holds device-specific information like the
+driver model device node, and its I2C address.
 
 static struct i2c_driver foo_driver = {
        .driver = {
                .name   = "foo",
        },
-       .attach_adapter = &foo_attach_adapter,
-       .detach_client  = &foo_detach_client,
-       .command        = &foo_command /* may be NULL */
+       .attach_adapter = foo_attach_adapter,
+       .detach_client  = foo_detach_client,
+       .shutdown       = foo_shutdown, /* optional */
+       .suspend        = foo_suspend,  /* optional */
+       .resume         = foo_resume,   /* optional */
+       .command        = foo_command,  /* optional */
 }
  
-The name field must match the driver name, including the case. It must not
-contain spaces, and may be up to 31 characters long.
+The name field is the driver name, and must not contain spaces.  It
+should match the module name (if the driver can be compiled as a module),
+although you can use MODULE_ALIAS (passing "foo" in this example) to add
+another name for the module.
 
 All other fields are for call-back functions which will be explained 
 below.
@@ -43,11 +49,18 @@ below.
 Extra client data
 =================
 
-The client structure has a special `data' field that can point to any
-structure at all. You can use this to keep client-specific data. You
+Each client structure has a special `data' field that can point to any
+structure at all.  You should use this to keep device-specific data,
+especially in drivers that handle multiple I2C or SMBUS devices.  You
 do not always need this, but especially for `sensors' drivers, it can
 be very useful.
 
+       /* store the value */
+       void i2c_set_clientdata(struct i2c_client *client, void *data);
+
+       /* retrieve the value */
+       void *i2c_get_clientdata(struct i2c_client *client);
+
 An example structure is below.
 
   struct foo_data {
@@ -493,6 +506,33 @@ by `__init_data'.  Hose functions and structures can be removed after
 kernel booting (or module loading) is completed.
 
 
+Power Management
+================
+
+If your I2C device needs special handling when entering a system low
+power state -- like putting a transceiver into a low power mode, or
+activating a system wakeup mechanism -- do that in the suspend() method.
+The resume() method should reverse what the suspend() method does.
+
+These are standard driver model calls, and they work just like they
+would for any other driver stack.  The calls can sleep, and can use
+I2C messaging to the device being suspended or resumed (since their
+parent I2C adapter is active when these calls are issued, and IRQs
+are still enabled).
+
+
+System Shutdown
+===============
+
+If your I2C device needs special handling when the system shuts down
+or reboots (including kexec) -- like turning something off -- use a
+shutdown() method.
+
+Again, this is a standard driver model call, working just like it
+would for any other driver stack:  the calls can sleep, and can use
+I2C messaging.
+
+
 Command function
 ================
 
index f85c603b02a335aa9bf0bae7eec28f7e44ef68b3..93a338daedd83b5168bf891a85305167043dd124 100644 (file)
@@ -2523,6 +2523,12 @@ M:       olof@lixom.net
 L:     netdev@vger.kernel.org
 S:     Maintained
 
+PA SEMI SMBUS DRIVER
+P:     Olof Johansson
+M:     olof@lixom.net
+L:     i2c@lm-sensors.org
+S:     Maintained
+
 PARALLEL PORT SUPPORT
 P:     Phil Blundell
 M:     philb@gnu.org
index 5fe195a41a804025a838a7d33e40dfbee6d91998..a92ce6bd7cf1c89fa867e08126e8d573b61cbb06 100644 (file)
@@ -598,8 +598,6 @@ config SGI_IP32
        select ARC
        select ARC32
        select BOOT_ELF32
-       select OWN_DMA
-       select DMA_IP32
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select R5000_CPU_SCACHE
@@ -883,9 +881,6 @@ config DMA_NONCOHERENT
 config DMA_NEED_PCI_MAP_STATE
        bool
 
-config OWN_DMA
-       bool
-
 config EARLY_PRINTK
        bool
 
index 96090f28373bbfe025871a72dc7adf0c5fa88a77..f21186c12d81f41fae2ca403d59a5d87ec0bc399 100644 (file)
@@ -264,7 +264,7 @@ CONFIG_BINFMT_ELF=y
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
 CONFIG_MIPS32_O32=y
-# CONFIG_MIPS32_N32 is not set
+CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 
 #
index b251ef864c33b281fa899a295c266f10f48db98d..00cecdcc75f215cb6e5a6581442774996fcc26f3 100644 (file)
                 srlv   t3,t1,t2
 
 handle_it:
-               LONG_L  s0, TI_REGS($28)
-               LONG_S  sp, TI_REGS($28)
-               PTR_LA  ra, ret_from_irq
                j       dec_irq_dispatch
                 nop
 
@@ -277,7 +274,6 @@ fpu:
 #endif
 
 spurious:
-               PTR_LA  ra, _ret_from_irq
                j       spurious_interrupt
                 nop
                END(plat_irq_dispatch)
index f10b6a19f8bf7b672242dbf2dcf9bf1f495c7c13..0b78fcbf044ab563453850fe8d404ca3615b6053 100644 (file)
 #endif
 
 #ifndef CONFIG_PREEMPT
-       .macro  preempt_stop
-       local_irq_disable
-       .endm
 #define resume_kernel  restore_all
+#else
+#define __ret_from_irq ret_from_exception
 #endif
 
        .text
        .align  5
-FEXPORT(ret_from_irq)
-       LONG_S  s0, TI_REGS($28)
-#ifdef CONFIG_PREEMPT
-FEXPORT(ret_from_exception)
-#else
-       b       _ret_from_irq
+#ifndef CONFIG_PREEMPT
 FEXPORT(ret_from_exception)
-       preempt_stop
+       local_irq_disable                       # preempt stop
+       b       __ret_from_irq
 #endif
-FEXPORT(_ret_from_irq)
+FEXPORT(ret_from_irq)
+       LONG_S  s0, TI_REGS($28)
+FEXPORT(__ret_from_irq)
        LONG_L  t0, PT_STATUS(sp)               # returning to kernel mode?
        andi    t0, t0, KU_USER
        beqz    t0, resume_kernel
index ca7ad78f4def1fea27de9142b1ffd17d91900337..fc4dd6c9dd802c8308f16f422b7f93cc15734905 100644 (file)
@@ -39,6 +39,7 @@
 #include <net/sock.h>
 #include <net/scm.h>
 
+#include <asm/compat-signal.h>
 #include <asm/ipc.h>
 #include <asm/sim.h>
 #include <asm/uaccess.h>
@@ -736,3 +737,49 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
        return do_fork(clone_flags, newsp, &regs, 0,
                       parent_tidptr, child_tidptr);
 }
+
+/*
+ * Implement the event wait interface for the eventpoll file. It is the kernel
+ * part of the user space epoll_pwait(2).
+ */
+asmlinkage long compat_sys_epoll_pwait(int epfd,
+       struct epoll_event __user *events, int maxevents, int timeout,
+       const compat_sigset_t __user *sigmask, size_t sigsetsize)
+{
+       int error;
+       sigset_t ksigmask, sigsaved;
+
+       /*
+        * If the caller wants a certain signal mask to be set during the wait,
+        * we apply it here.
+        */
+       if (sigmask) {
+               if (sigsetsize != sizeof(sigset_t))
+                       return -EINVAL;
+               if (!access_ok(VERIFY_READ, sigmask, sizeof(ksigmask)))
+                       return -EFAULT;
+               if (__copy_conv_sigset_from_user(&ksigmask, sigmask))
+                       return -EFAULT;
+               sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP));
+               sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
+       }
+
+       error = sys_epoll_wait(epfd, events, maxevents, timeout);
+
+       /*
+        * If we changed the signal mask, we need to restore the original one.
+        * In case we've got a signal while waiting, we do not restore the
+        * signal mask yet, and we allow do_signal() to deliver the signal on
+        * the way back to userspace, before the signal mask is restored.
+        */
+       if (sigmask) {
+               if (error == -EINTR) {
+                       memcpy(&current->saved_sigmask, &sigsaved,
+                               sizeof(sigsaved));
+                       set_thread_flag(TIF_RESTORE_SIGMASK);
+               } else
+                       sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+       }
+
+       return error;
+}
index e569b846e9a380ff96e65507f6e13ec3d5f6e414..10e9a18630aa47b168c8140b99f80875e5c76c32 100644 (file)
@@ -470,4 +470,4 @@ sys_call_table:
        PTR     sys_get_robust_list
        PTR     sys_kexec_load                  /* 5270 */
        PTR     sys_getcpu
-       PTR     sys_epoll_pwait
+       PTR     compat_sys_epoll_pwait
index ee8802b597582ef1a71458dfeb93ad0de5412a74..2ceda4644a4d7b4ee64d778753b8fcd0c9dce170 100644 (file)
@@ -396,4 +396,4 @@ EXPORT(sysn32_call_table)
        PTR     compat_sys_get_robust_list
        PTR     compat_sys_kexec_load
        PTR     sys_getcpu
-       PTR     sys_epoll_pwait
+       PTR     compat_sys_epoll_pwait
index 9a8abd67ec5c94a0bad855251f296d2f07be8bf3..fdbdbdc65b543b6333610afcdf0f68d318b1151e 100644 (file)
 #  define DEBUGP(fmt, args...)
 #endif
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
-struct sigframe {
-       u32 sf_ass[4];          /* argument save space for o32 */
-       u32 sf_code[2];         /* signal trampoline */
-       struct sigcontext sf_sc;
-       sigset_t sf_mask;
-};
-
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
-struct sigframe {
-       u32 sf_ass[4];                  /* argument save space for o32 */
-       u32 sf_pad[2];
-       struct sigcontext sf_sc;        /* hw context */
-       sigset_t sf_mask;
-       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
-/*
- * handle hardware context
- */
-extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
-extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 /*
  * Determine which stack to use..
index 54398af2371f9b33d834cfc70b9916fc4337d0d6..b2e9ab1bb10152b6c3c712c1b27adbddd021ff8a 100644 (file)
 
 #include "signal-common.h"
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
+/*
+ * Horribly complicated - with the bloody RM9000 workarounds enabled
+ * the signal trampolines is moving to the end of the structure so we can
+ * increase the alignment without breaking software compatibility.
+ */
 #if ICACHE_REFILLS_WORKAROUND_WAR == 0
 
+struct sigframe {
+       u32 sf_ass[4];          /* argument save space for o32 */
+       u32 sf_code[2];         /* signal trampoline */
+       struct sigcontext sf_sc;
+       sigset_t sf_mask;
+};
+
 struct rt_sigframe {
        u32 rs_ass[4];          /* argument save space for o32 */
        u32 rs_code[2];         /* signal trampoline */
@@ -47,6 +57,14 @@ struct rt_sigframe {
 
 #else
 
+struct sigframe {
+       u32 sf_ass[4];                  /* argument save space for o32 */
+       u32 sf_pad[2];
+       struct sigcontext sf_sc;        /* hw context */
+       sigset_t sf_mask;
+       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
+};
+
 struct rt_sigframe {
        u32 rs_ass[4];                  /* argument save space for o32 */
        u32 rs_pad[2];
index 183fc7e55f34cff2b38c88e5c8ec4f7412446d46..c28cb21514c858dc856918f22211f4036565b7c7 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #include <linux/cache.h>
+#include <linux/compat.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -24,6 +25,7 @@
 
 #include <asm/abi.h>
 #include <asm/asm.h>
+#include <asm/compat-signal.h>
 #include <linux/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/sim.h>
@@ -104,8 +106,6 @@ typedef struct compat_siginfo {
 #define __NR_O32_rt_sigreturn          4193
 #define __NR_O32_restart_syscall       4253
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
 /* 32-bit compatibility types */
 
 #define _NSIG_BPW32    32
@@ -139,8 +139,20 @@ struct ucontext32 {
        sigset_t32          uc_sigmask;   /* mask last for extensibility */
 };
 
+/*
+ * Horribly complicated - with the bloody RM9000 workarounds enabled
+ * the signal trampolines is moving to the end of the structure so we can
+ * increase the alignment without breaking software compatibility.
+ */
 #if ICACHE_REFILLS_WORKAROUND_WAR == 0
 
+struct sigframe32 {
+       u32 sf_ass[4];          /* argument save space for o32 */
+       u32 sf_code[2];         /* signal trampoline */
+       struct sigcontext32 sf_sc;
+       sigset_t sf_mask;
+};
+
 struct rt_sigframe32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
        u32 rs_code[2];                 /* signal trampoline */
@@ -150,6 +162,14 @@ struct rt_sigframe32 {
 
 #else  /* ICACHE_REFILLS_WORKAROUND_WAR */
 
+struct sigframe32 {
+       u32 sf_ass[4];                  /* argument save space for o32 */
+       u32 sf_pad[2];
+       struct sigcontext32 sf_sc;      /* hw context */
+       sigset_t sf_mask;
+       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
+};
+
 struct rt_sigframe32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
        u32 rs_pad[2];
@@ -493,13 +513,13 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 
 asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 {
-       struct sigframe __user *frame;
+       struct sigframe32 __user *frame;
        sigset_t blocked;
 
-       frame = (struct sigframe __user *) regs.regs[29];
+       frame = (struct sigframe32 __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
-       if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
+       if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
                goto badframe;
 
        sigdelsetmask(&blocked, ~_BLOCKABLE);
@@ -536,7 +556,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
        frame = (struct rt_sigframe32 __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
-       if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+       if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
                goto badframe;
 
        sigdelsetmask(&set, ~_BLOCKABLE);
@@ -581,7 +601,7 @@ badframe:
 int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        int signr, sigset_t *set)
 {
-       struct sigframe __user *frame;
+       struct sigframe32 __user *frame;
        int err = 0;
 
        frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -591,7 +611,8 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
 
        err |= setup_sigcontext32(regs, &frame->sf_sc);
-       err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+       err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
+
        if (err)
                goto give_sigsegv;
 
@@ -650,7 +671,7 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        err |= __put_user(current->sas_ss_size,
                          &frame->rs_uc.uc_stack.ss_size);
        err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
-       err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+       err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 
        if (err)
                goto give_sigsegv;
index 57456e6a0c628e005b4be025f1ad5c28860947ad..7ca2a078841fb65253d5e9aeec70b8dfcebbd5c9 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <asm/asm.h>
 #include <asm/cacheflush.h>
+#include <asm/compat-signal.h>
 #include <asm/sim.h>
 #include <asm/uaccess.h>
 #include <asm/ucontext.h>
@@ -47,7 +48,9 @@
 #define __NR_N32_rt_sigreturn          6211
 #define __NR_N32_restart_syscall       6214
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
+extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
+
 
 /* IRIX compatible stack_t  */
 typedef struct sigaltstack32 {
@@ -61,7 +64,7 @@ struct ucontextn32 {
        s32                 uc_link;
        stack32_t           uc_stack;
        struct sigcontext   uc_mcontext;
-       sigset_t            uc_sigmask;   /* mask last for extensibility */
+       compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
 #if ICACHE_REFILLS_WORKAROUND_WAR == 0
@@ -127,7 +130,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
        frame = (struct rt_sigframe_n32 __user *) regs.regs[29];
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
-       if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+       if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
                goto badframe;
 
        sigdelsetmask(&set, ~_BLOCKABLE);
@@ -193,7 +196,7 @@ int setup_rt_frame_n32(struct k_sigaction * ka,
        err |= __put_user(current->sas_ss_size,
                          &frame->rs_uc.uc_stack.ss_size);
        err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
-       err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+       err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 
        if (err)
                goto give_sigsegv;
index 19e41fd186c4e0c8a9d4ab3646c5897aa359514b..de5727385bc67c2a03a91845a1d66c86fa61cfcb 100644 (file)
@@ -2,8 +2,8 @@
 # Makefile for the Linux/MIPS-specific parts of the memory manager.
 #
 
-obj-y                          += cache.o extable.o fault.o init.o pgtable.o \
-                                  tlbex.o tlbex-fault.o
+obj-y                          += cache.o dma-default.o extable.o fault.o \
+                                  init.o pgtable.o tlbex.o tlbex-fault.o
 
 obj-$(CONFIG_32BIT)            += ioremap.o pgtable-32.o
 obj-$(CONFIG_64BIT)            += pgtable-64.o
@@ -32,14 +32,4 @@ obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
 obj-$(CONFIG_RM7000_CPU_SCACHE)        += sc-rm7k.o
 obj-$(CONFIG_MIPS_CPU_SCACHE)  += sc-mips.o
 
-#
-# Choose one DMA coherency model
-#
-ifndef CONFIG_OWN_DMA
-obj-$(CONFIG_DMA_COHERENT)     += dma-coherent.o
-obj-$(CONFIG_DMA_NONCOHERENT)  += dma-noncoherent.o
-endif
-obj-$(CONFIG_DMA_IP27)         += dma-ip27.o
-obj-$(CONFIG_DMA_IP32)         += dma-ip32.o
-
 EXTRA_AFLAGS := $(CFLAGS)
index 3a8afd47feaab8b3f1e98e5be73b563acd612282..9ea460b16bda3e3e2b25614621bd332093e14982 100644 (file)
@@ -259,6 +259,12 @@ static void sb1_flush_cache_data_page(unsigned long addr)
                on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1);
 }
 #else
+
+static void local_sb1_flush_cache_data_page(unsigned long addr)
+{
+       __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE);
+}
+
 void sb1_flush_cache_data_page(unsigned long)
        __attribute__((alias("local_sb1_flush_cache_data_page")));
 #endif
diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c
deleted file mode 100644 (file)
index 5697c6e..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
- * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
- */
-#include <linux/types.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-#include <asm/cache.h>
-#include <asm/io.h>
-
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-{
-       void *ret;
-       /* ignore region specifiers */
-       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
-       if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
-               gfp |= GFP_DMA;
-       ret = (void *) __get_free_pages(gfp, get_order(size));
-
-       if (ret != NULL) {
-               memset(ret, 0, size);
-               *dma_handle = virt_to_phys(ret);
-       }
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dma_alloc_noncoherent);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-       __attribute__((alias("dma_alloc_noncoherent")));
-
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle)
-{
-       unsigned long addr = (unsigned long) vaddr;
-
-       free_pages(addr, get_order(size));
-}
-
-EXPORT_SYMBOL(dma_free_noncoherent);
-
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle) __attribute__((alias("dma_free_noncoherent")));
-
-EXPORT_SYMBOL(dma_free_coherent);
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-       enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       return __pa(ptr);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_unmap_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       for (i = 0; i < nents; i++, sg++) {
-               sg->dma_address = (dma_addr_t)page_to_phys(sg->page) + sg->offset;
-       }
-
-       return nents;
-}
-
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       return page_to_phys(page) + offset;
-}
-
-EXPORT_SYMBOL(dma_map_page);
-
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_unmap_page);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-            enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                     unsigned long offset, size_t size,
-                     enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                     unsigned long offset, size_t size,
-                     enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-int dma_mapping_error(dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-EXPORT_SYMBOL(dma_mapping_error);
-
-int dma_supported(struct device *dev, u64 mask)
-{
-       /*
-        * we fall back to GFP_DMA when the mask isn't all 1s,
-        * so we can't guarantee allocations that must be
-        * within a tighter range than GFP_DMA..
-        */
-       if (mask < 0x00ffffff)
-               return 0;
-
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_supported);
-
-int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_is_consistent);
-
-void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_cache_sync);
-
-/* The DAC routines are a PCIism.. */
-
-#ifdef CONFIG_PCI
-
-#include <linux/pci.h>
-
-dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
-       struct page *page, unsigned long offset, int direction)
-{
-       return (dma64_addr_t)page_to_phys(page) + offset;
-}
-
-EXPORT_SYMBOL(pci_dac_page_to_dma);
-
-struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       return mem_map + (dma_addr >> PAGE_SHIFT);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_page);
-
-unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       return dma_addr & ~PAGE_MASK;
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_offset);
-
-void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
-
-void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
-
-#endif /* CONFIG_PCI */
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
new file mode 100644 (file)
index 0000000..4a32e93
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001, 06  Ralf Baechle <ralf@linux-mips.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+
+#include <dma-coherence.h>
+
+/*
+ * Warning on the terminology - Linux calls an uncached area coherent;
+ * MIPS terminology calls memory areas with hardware maintained coherency
+ * coherent.
+ */
+
+static inline int cpu_is_noncoherent_r10000(struct device *dev)
+{
+       return !plat_device_is_coherent(dev) &&
+              (current_cpu_data.cputype == CPU_R10000 &&
+              current_cpu_data.cputype == CPU_R12000);
+}
+
+void *dma_alloc_noncoherent(struct device *dev, size_t size,
+       dma_addr_t * dma_handle, gfp_t gfp)
+{
+       void *ret;
+
+       /* ignore region specifiers */
+       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+       if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+               gfp |= GFP_DMA;
+       ret = (void *) __get_free_pages(gfp, get_order(size));
+
+       if (ret != NULL) {
+               memset(ret, 0, size);
+               *dma_handle = plat_map_dma_mem(dev, ret, size);
+       }
+
+       return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_noncoherent);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+       dma_addr_t * dma_handle, gfp_t gfp)
+{
+       void *ret;
+
+       /* ignore region specifiers */
+       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+       if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+               gfp |= GFP_DMA;
+       ret = (void *) __get_free_pages(gfp, get_order(size));
+
+       if (ret) {
+               memset(ret, 0, size);
+               *dma_handle = plat_map_dma_mem(dev, ret, size);
+
+               if (!plat_device_is_coherent(dev)) {
+                       dma_cache_wback_inv((unsigned long) ret, size);
+                       ret = UNCAC_ADDR(ret);
+               }
+       }
+
+       return ret;
+}
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+       dma_addr_t dma_handle)
+{
+       free_pages((unsigned long) vaddr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_noncoherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
+       dma_addr_t dma_handle)
+{
+       unsigned long addr = (unsigned long) vaddr;
+
+       if (!plat_device_is_coherent(dev))
+               addr = CAC_ADDR(addr);
+
+       free_pages(addr, get_order(size));
+}
+
+EXPORT_SYMBOL(dma_free_coherent);
+
+static inline void __dma_sync(unsigned long addr, size_t size,
+       enum dma_data_direction direction)
+{
+       switch (direction) {
+       case DMA_TO_DEVICE:
+               dma_cache_wback(addr, size);
+               break;
+
+       case DMA_FROM_DEVICE:
+               dma_cache_inv(addr, size);
+               break;
+
+       case DMA_BIDIRECTIONAL:
+               dma_cache_wback_inv(addr, size);
+               break;
+
+       default:
+               BUG();
+       }
+}
+
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+       enum dma_data_direction direction)
+{
+       unsigned long addr = (unsigned long) ptr;
+
+       if (!plat_device_is_coherent(dev))
+               __dma_sync(addr, size, direction);
+
+       return plat_map_dma_mem(dev, ptr, size);
+}
+
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+       enum dma_data_direction direction)
+{
+       if (cpu_is_noncoherent_r10000(dev))
+               __dma_sync(plat_dma_addr_to_phys(dma_addr) + PAGE_OFFSET, size,
+                          direction);
+
+       plat_unmap_dma_mem(dma_addr);
+}
+
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+       enum dma_data_direction direction)
+{
+       int i;
+
+       BUG_ON(direction == DMA_NONE);
+
+       for (i = 0; i < nents; i++, sg++) {
+               unsigned long addr;
+
+               addr = (unsigned long) page_address(sg->page);
+               if (!plat_device_is_coherent(dev) && addr)
+                       __dma_sync(addr + sg->offset, sg->length, direction);
+               sg->dma_address = plat_map_dma_mem_page(dev, sg->page) +
+                                 sg->offset;
+       }
+
+       return nents;
+}
+
+EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+       unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       if (!plat_device_is_coherent(dev)) {
+               unsigned long addr;
+
+               addr = (unsigned long) page_address(page) + offset;
+               dma_cache_wback_inv(addr, size);
+       }
+
+       return plat_map_dma_mem_page(dev, page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+       enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       if (!plat_device_is_coherent(dev) && direction != DMA_TO_DEVICE) {
+               unsigned long addr;
+
+               addr = plat_dma_addr_to_phys(dma_address);
+               dma_cache_wback_inv(addr, size);
+       }
+
+       plat_unmap_dma_mem(dma_address);
+}
+
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+       enum dma_data_direction direction)
+{
+       unsigned long addr;
+       int i;
+
+       BUG_ON(direction == DMA_NONE);
+
+       for (i = 0; i < nhwentries; i++, sg++) {
+               if (!plat_device_is_coherent(dev) &&
+                   direction != DMA_TO_DEVICE) {
+                       addr = (unsigned long) page_address(sg->page);
+                       if (addr)
+                               __dma_sync(addr + sg->offset, sg->length,
+                                          direction);
+               }
+               plat_unmap_dma_mem(sg->dma_address);
+       }
+}
+
+EXPORT_SYMBOL(dma_unmap_sg);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+       size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       if (cpu_is_noncoherent_r10000(dev)) {
+               unsigned long addr;
+
+               addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+               __dma_sync(addr, size, direction);
+       }
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+       size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       if (cpu_is_noncoherent_r10000(dev)) {
+               unsigned long addr;
+
+               addr = plat_dma_addr_to_phys(dma_handle);
+               __dma_sync(addr, size, direction);
+       }
+}
+
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+       unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       if (cpu_is_noncoherent_r10000(dev)) {
+               unsigned long addr;
+
+               addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+               __dma_sync(addr + offset, size, direction);
+       }
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+       unsigned long offset, size_t size, enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       if (cpu_is_noncoherent_r10000(dev)) {
+               unsigned long addr;
+
+               addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+               __dma_sync(addr + offset, size, direction);
+       }
+}
+
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+       enum dma_data_direction direction)
+{
+       int i;
+
+       BUG_ON(direction == DMA_NONE);
+
+       /* Make sure that gcc doesn't leave the empty loop body.  */
+       for (i = 0; i < nelems; i++, sg++) {
+               if (!plat_device_is_coherent(dev))
+                       __dma_sync((unsigned long)page_address(sg->page),
+                                  sg->length, direction);
+               plat_unmap_dma_mem(sg->dma_address);
+       }
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+       enum dma_data_direction direction)
+{
+       int i;
+
+       BUG_ON(direction == DMA_NONE);
+
+       /* Make sure that gcc doesn't leave the empty loop body.  */
+       for (i = 0; i < nelems; i++, sg++) {
+               if (!plat_device_is_coherent(dev))
+                       __dma_sync((unsigned long)page_address(sg->page),
+                                  sg->length, direction);
+               plat_unmap_dma_mem(sg->dma_address);
+       }
+}
+
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+int dma_mapping_error(dma_addr_t dma_addr)
+{
+       return 0;
+}
+
+EXPORT_SYMBOL(dma_mapping_error);
+
+int dma_supported(struct device *dev, u64 mask)
+{
+       /*
+        * we fall back to GFP_DMA when the mask isn't all 1s,
+        * so we can't guarantee allocations that must be
+        * within a tighter range than GFP_DMA..
+        */
+       if (mask < 0x00ffffff)
+               return 0;
+
+       return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
+{
+       return plat_device_is_coherent(dev);
+}
+
+EXPORT_SYMBOL(dma_is_consistent);
+
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG_ON(direction == DMA_NONE);
+
+       if (!plat_device_is_coherent(dev))
+               dma_cache_wback_inv((unsigned long)vaddr, size);
+}
+
+EXPORT_SYMBOL(dma_cache_sync);
diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c
deleted file mode 100644 (file)
index f088344..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
- * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-
-#include <asm/cache.h>
-#include <asm/pci/bridge.h>
-
-#define pdev_to_baddr(pdev, addr) \
-       (BRIDGE_CONTROLLER(pdev->bus)->baddr + (addr))
-#define dev_to_baddr(dev, addr) \
-       pdev_to_baddr(to_pci_dev(dev), (addr))
-
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-{
-       void *ret;
-
-       /* ignore region specifiers */
-       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
-       if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
-               gfp |= GFP_DMA;
-       ret = (void *) __get_free_pages(gfp, get_order(size));
-
-       if (ret != NULL) {
-               memset(ret, 0, size);
-               *dma_handle = dev_to_baddr(dev, virt_to_phys(ret));
-       }
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dma_alloc_noncoherent);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-       __attribute__((alias("dma_alloc_noncoherent")));
-
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle)
-{
-       unsigned long addr = (unsigned long) vaddr;
-
-       free_pages(addr, get_order(size));
-}
-
-EXPORT_SYMBOL(dma_free_noncoherent);
-
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle) __attribute__((alias("dma_free_noncoherent")));
-
-EXPORT_SYMBOL(dma_free_coherent);
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-       enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       return dev_to_baddr(dev, __pa(ptr));
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_unmap_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       for (i = 0; i < nents; i++, sg++) {
-               sg->dma_address = (dma_addr_t) dev_to_baddr(dev,
-                       page_to_phys(sg->page) + sg->offset);
-       }
-
-       return nents;
-}
-
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       return dev_to_baddr(dev, page_to_phys(page) + offset);
-}
-
-EXPORT_SYMBOL(dma_map_page);
-
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_unmap_page);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-            enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
-               enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
-               enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                     unsigned long offset, size_t size,
-                     enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                     unsigned long offset, size_t size,
-                     enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-int dma_mapping_error(dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-EXPORT_SYMBOL(dma_mapping_error);
-
-int dma_supported(struct device *dev, u64 mask)
-{
-       /*
-        * we fall back to GFP_DMA when the mask isn't all 1s,
-        * so we can't guarantee allocations that must be
-        * within a tighter range than GFP_DMA..
-        */
-       if (mask < 0x00ffffff)
-               return 0;
-
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_supported);
-
-int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_is_consistent);
-
-void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-}
-
-EXPORT_SYMBOL(dma_cache_sync);
-
-dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
-       struct page *page, unsigned long offset, int direction)
-{
-       dma64_addr_t addr = page_to_phys(page) + offset;
-
-       return (dma64_addr_t) pdev_to_baddr(pdev, addr);
-}
-
-EXPORT_SYMBOL(pci_dac_page_to_dma);
-
-struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus);
-
-       return pfn_to_page((dma_addr - bc->baddr) >> PAGE_SHIFT);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_page);
-
-unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       return dma_addr & ~PAGE_MASK;
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_offset);
-
-void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
-
-void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c
deleted file mode 100644 (file)
index b42b6f7..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
- * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
- * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
- * IP32 changes by Ilya.
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/cache.h>
-#include <asm/io.h>
-#include <asm/ip32/crime.h>
-
-/*
- * Warning on the terminology - Linux calls an uncached area coherent;
- * MIPS terminology calls memory areas with hardware maintained coherency
- * coherent.
- */
-
-/*
- * Few notes.
- * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M
- * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for native-endian)
- * 3. All other devices see memory as one big chunk at 0x40000000
- * 4. Non-PCI devices will pass NULL as struct device*
- * Thus we translate differently, depending on device.
- */
-
-#define RAM_OFFSET_MASK        0x3fffffff
-
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-{
-       void *ret;
-       /* ignore region specifiers */
-       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
-       if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
-               gfp |= GFP_DMA;
-       ret = (void *) __get_free_pages(gfp, get_order(size));
-
-       if (ret != NULL) {
-               unsigned long addr = virt_to_phys(ret)&RAM_OFFSET_MASK;
-               memset(ret, 0, size);
-               if(dev==NULL)
-                   addr+= CRIME_HI_MEM_BASE;
-               *dma_handle = addr;
-       }
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dma_alloc_noncoherent);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-{
-       void *ret;
-
-       ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
-       if (ret) {
-               dma_cache_wback_inv((unsigned long) ret, size);
-               ret = UNCAC_ADDR(ret);
-       }
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle)
-{
-       free_pages((unsigned long) vaddr, get_order(size));
-}
-
-EXPORT_SYMBOL(dma_free_noncoherent);
-
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle)
-{
-       unsigned long addr = (unsigned long) vaddr;
-
-       addr = CAC_ADDR(addr);
-       free_pages(addr, get_order(size));
-}
-
-EXPORT_SYMBOL(dma_free_coherent);
-
-static inline void __dma_sync(unsigned long addr, size_t size,
-       enum dma_data_direction direction)
-{
-       switch (direction) {
-       case DMA_TO_DEVICE:
-               dma_cache_wback(addr, size);
-               break;
-
-       case DMA_FROM_DEVICE:
-               dma_cache_inv(addr, size);
-               break;
-
-       case DMA_BIDIRECTIONAL:
-               dma_cache_wback_inv(addr, size);
-               break;
-
-       default:
-               BUG();
-       }
-}
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-       enum dma_data_direction direction)
-{
-       unsigned long addr = (unsigned long) ptr;
-
-       switch (direction) {
-       case DMA_TO_DEVICE:
-               dma_cache_wback(addr, size);
-               break;
-
-       case DMA_FROM_DEVICE:
-               dma_cache_inv(addr, size);
-               break;
-
-       case DMA_BIDIRECTIONAL:
-               dma_cache_wback_inv(addr, size);
-               break;
-
-       default:
-               BUG();
-       }
-
-       addr = virt_to_phys(ptr)&RAM_OFFSET_MASK;
-       if(dev == NULL)
-           addr+=CRIME_HI_MEM_BASE;
-       return (dma_addr_t)addr;
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-       enum dma_data_direction direction)
-{
-       switch (direction) {
-       case DMA_TO_DEVICE:
-               break;
-
-       case DMA_FROM_DEVICE:
-               break;
-
-       case DMA_BIDIRECTIONAL:
-               break;
-
-       default:
-               BUG();
-       }
-}
-
-EXPORT_SYMBOL(dma_unmap_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       for (i = 0; i < nents; i++, sg++) {
-               unsigned long addr;
-
-               addr = (unsigned long) page_address(sg->page)+sg->offset;
-               if (addr)
-                       __dma_sync(addr, sg->length, direction);
-               addr = __pa(addr)&RAM_OFFSET_MASK;
-               if(dev == NULL)
-                       addr +=  CRIME_HI_MEM_BASE;
-               sg->dma_address = (dma_addr_t)addr;
-       }
-
-       return nents;
-}
-
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       addr = (unsigned long) page_address(page) + offset;
-       dma_cache_wback_inv(addr, size);
-       addr = __pa(addr)&RAM_OFFSET_MASK;
-       if(dev == NULL)
-               addr +=  CRIME_HI_MEM_BASE;
-
-       return (dma_addr_t)addr;
-}
-
-EXPORT_SYMBOL(dma_map_page);
-
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-       enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       if (direction != DMA_TO_DEVICE) {
-               unsigned long addr;
-
-               dma_address&=RAM_OFFSET_MASK;
-               addr = dma_address + PAGE_OFFSET;
-               if(dma_address>=256*1024*1024)
-                       addr+=CRIME_HI_MEM_BASE;
-               dma_cache_wback_inv(addr, size);
-       }
-}
-
-EXPORT_SYMBOL(dma_unmap_page);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-       enum dma_data_direction direction)
-{
-       unsigned long addr;
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       if (direction == DMA_TO_DEVICE)
-               return;
-
-       for (i = 0; i < nhwentries; i++, sg++) {
-               addr = (unsigned long) page_address(sg->page);
-               if (!addr)
-                       continue;
-               dma_cache_wback_inv(addr + sg->offset, sg->length);
-       }
-}
-
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       dma_handle&=RAM_OFFSET_MASK;
-       addr = dma_handle + PAGE_OFFSET;
-       if(dma_handle>=256*1024*1024)
-           addr+=CRIME_HI_MEM_BASE;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       dma_handle&=RAM_OFFSET_MASK;
-       addr = dma_handle + PAGE_OFFSET;
-       if(dma_handle>=256*1024*1024)
-           addr+=CRIME_HI_MEM_BASE;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       dma_handle&=RAM_OFFSET_MASK;
-       addr = dma_handle + offset + PAGE_OFFSET;
-       if(dma_handle>=256*1024*1024)
-           addr+=CRIME_HI_MEM_BASE;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       dma_handle&=RAM_OFFSET_MASK;
-       addr = dma_handle + offset + PAGE_OFFSET;
-       if(dma_handle>=256*1024*1024)
-           addr+=CRIME_HI_MEM_BASE;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       /* Make sure that gcc doesn't leave the empty loop body.  */
-       for (i = 0; i < nelems; i++, sg++)
-               __dma_sync((unsigned long)page_address(sg->page),
-                          sg->length, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       /* Make sure that gcc doesn't leave the empty loop body.  */
-       for (i = 0; i < nelems; i++, sg++)
-               __dma_sync((unsigned long)page_address(sg->page),
-                          sg->length, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-int dma_mapping_error(dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-EXPORT_SYMBOL(dma_mapping_error);
-
-int dma_supported(struct device *dev, u64 mask)
-{
-       /*
-        * we fall back to GFP_DMA when the mask isn't all 1s,
-        * so we can't guarantee allocations that must be
-        * within a tighter range than GFP_DMA..
-        */
-       if (mask < 0x00ffffff)
-               return 0;
-
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_supported);
-
-int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_is_consistent);
-
-void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-       enum dma_data_direction direction)
-{
-       if (direction == DMA_NONE)
-               return;
-
-       dma_cache_wback_inv((unsigned long)vaddr, size);
-}
-
-EXPORT_SYMBOL(dma_cache_sync);
-
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c
deleted file mode 100644 (file)
index 8cecef0..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
- * Copyright (C) 2000, 2001  Ralf Baechle <ralf@gnu.org>
- * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
- */
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/cache.h>
-#include <asm/io.h>
-
-/*
- * Warning on the terminology - Linux calls an uncached area coherent;
- * MIPS terminology calls memory areas with hardware maintained coherency
- * coherent.
- */
-
-void *dma_alloc_noncoherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-{
-       void *ret;
-       /* ignore region specifiers */
-       gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
-       if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
-               gfp |= GFP_DMA;
-       ret = (void *) __get_free_pages(gfp, get_order(size));
-
-       if (ret != NULL) {
-               memset(ret, 0, size);
-               *dma_handle = virt_to_phys(ret);
-       }
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dma_alloc_noncoherent);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-       dma_addr_t * dma_handle, gfp_t gfp)
-{
-       void *ret;
-
-       ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
-       if (ret) {
-               dma_cache_wback_inv((unsigned long) ret, size);
-               ret = UNCAC_ADDR(ret);
-       }
-
-       return ret;
-}
-
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle)
-{
-       free_pages((unsigned long) vaddr, get_order(size));
-}
-
-EXPORT_SYMBOL(dma_free_noncoherent);
-
-void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
-       dma_addr_t dma_handle)
-{
-       unsigned long addr = (unsigned long) vaddr;
-
-       addr = CAC_ADDR(addr);
-       free_pages(addr, get_order(size));
-}
-
-EXPORT_SYMBOL(dma_free_coherent);
-
-static inline void __dma_sync(unsigned long addr, size_t size,
-       enum dma_data_direction direction)
-{
-       switch (direction) {
-       case DMA_TO_DEVICE:
-               dma_cache_wback(addr, size);
-               break;
-
-       case DMA_FROM_DEVICE:
-               dma_cache_inv(addr, size);
-               break;
-
-       case DMA_BIDIRECTIONAL:
-               dma_cache_wback_inv(addr, size);
-               break;
-
-       default:
-               BUG();
-       }
-}
-
-dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
-       enum dma_data_direction direction)
-{
-       unsigned long addr = (unsigned long) ptr;
-
-       __dma_sync(addr, size, direction);
-
-       return virt_to_phys(ptr);
-}
-
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-       enum dma_data_direction direction)
-{
-       unsigned long addr;
-       addr = dma_addr + PAGE_OFFSET;
-
-       //__dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_unmap_single);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       for (i = 0; i < nents; i++, sg++) {
-               unsigned long addr;
-
-               addr = (unsigned long) page_address(sg->page);
-               if (addr) {
-                       __dma_sync(addr + sg->offset, sg->length, direction);
-                       sg->dma_address = (dma_addr_t)page_to_phys(sg->page)
-                                         + sg->offset;
-               }
-       }
-
-       return nents;
-}
-
-EXPORT_SYMBOL(dma_map_sg);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       addr = (unsigned long) page_address(page) + offset;
-       dma_cache_wback_inv(addr, size);
-
-       return page_to_phys(page) + offset;
-}
-
-EXPORT_SYMBOL(dma_map_page);
-
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-       enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-
-       if (direction != DMA_TO_DEVICE) {
-               unsigned long addr;
-
-               addr = dma_address + PAGE_OFFSET;
-               dma_cache_wback_inv(addr, size);
-       }
-}
-
-EXPORT_SYMBOL(dma_unmap_page);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-       enum dma_data_direction direction)
-{
-       unsigned long addr;
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       if (direction == DMA_TO_DEVICE)
-               return;
-
-       for (i = 0; i < nhwentries; i++, sg++) {
-               addr = (unsigned long) page_address(sg->page);
-               if (addr)
-                       __dma_sync(addr + sg->offset, sg->length, direction);
-       }
-}
-
-EXPORT_SYMBOL(dma_unmap_sg);
-
-void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       addr = dma_handle + PAGE_OFFSET;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_cpu);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
-       size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       addr = dma_handle + PAGE_OFFSET;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       addr = dma_handle + offset + PAGE_OFFSET;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
-
-void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-       unsigned long offset, size_t size, enum dma_data_direction direction)
-{
-       unsigned long addr;
-
-       BUG_ON(direction == DMA_NONE);
-
-       addr = dma_handle + offset + PAGE_OFFSET;
-       __dma_sync(addr, size, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_single_range_for_device);
-
-void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       /* Make sure that gcc doesn't leave the empty loop body.  */
-       for (i = 0; i < nelems; i++, sg++)
-               __dma_sync((unsigned long)page_address(sg->page),
-                          sg->length, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_cpu);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-       enum dma_data_direction direction)
-{
-       int i;
-
-       BUG_ON(direction == DMA_NONE);
-
-       /* Make sure that gcc doesn't leave the empty loop body.  */
-       for (i = 0; i < nelems; i++, sg++)
-               __dma_sync((unsigned long)page_address(sg->page),
-                          sg->length, direction);
-}
-
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-int dma_mapping_error(dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-EXPORT_SYMBOL(dma_mapping_error);
-
-int dma_supported(struct device *dev, u64 mask)
-{
-       /*
-        * we fall back to GFP_DMA when the mask isn't all 1s,
-        * so we can't guarantee allocations that must be
-        * within a tighter range than GFP_DMA..
-        */
-       if (mask < 0x00ffffff)
-               return 0;
-
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_supported);
-
-int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
-       return 1;
-}
-
-EXPORT_SYMBOL(dma_is_consistent);
-
-void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
-       enum dma_data_direction direction)
-{
-       if (direction == DMA_NONE)
-               return;
-
-       dma_cache_wback_inv((unsigned long)vaddr, size);
-}
-
-EXPORT_SYMBOL(dma_cache_sync);
-
-/* The DAC routines are a PCIism.. */
-
-#ifdef CONFIG_PCI
-
-#include <linux/pci.h>
-
-dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
-       struct page *page, unsigned long offset, int direction)
-{
-       return (dma64_addr_t)page_to_phys(page) + offset;
-}
-
-EXPORT_SYMBOL(pci_dac_page_to_dma);
-
-struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       return mem_map + (dma_addr >> PAGE_SHIFT);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_page);
-
-unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
-       dma64_addr_t dma_addr)
-{
-       return dma_addr & ~PAGE_MASK;
-}
-
-EXPORT_SYMBOL(pci_dac_dma_to_offset);
-
-void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-
-       dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
-
-void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
-       dma64_addr_t dma_addr, size_t len, int direction)
-{
-       BUG_ON(direction == PCI_DMA_NONE);
-
-       dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
-}
-
-EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
-
-#endif /* CONFIG_PCI */
index 82b20c28bef8f8782a83ef4495728b12a119325b..bf85995ca042fecf18f6250a5683fa93f6e70683 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for the PCI specific kernel interface routines under Linux.
 #
 
-obj-y                          += pci.o
+obj-y                          += pci.o pci-dac.o
 
 #
 # PCI bus host bridge specific code
diff --git a/arch/mips/pci/pci-dac.c b/arch/mips/pci/pci-dac.c
new file mode 100644 (file)
index 0000000..0f0ea1b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2000  Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001, 06  Ralf Baechle <ralf@linux-mips.org>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ */
+
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <asm/cache.h>
+#include <asm/io.h>
+
+#include <dma-coherence.h>
+
+#include <linux/pci.h>
+
+dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev,
+       struct page *page, unsigned long offset, int direction)
+{
+       struct device *dev = &pdev->dev;
+
+       BUG_ON(direction == DMA_NONE);
+
+       if (!plat_device_is_coherent(dev)) {
+               unsigned long addr;
+
+               addr = (unsigned long) page_address(page) + offset;
+               dma_cache_wback_inv(addr, PAGE_SIZE);
+       }
+
+       return plat_map_dma_mem_page(dev, page) + offset;
+}
+
+EXPORT_SYMBOL(pci_dac_page_to_dma);
+
+struct page *pci_dac_dma_to_page(struct pci_dev *pdev,
+       dma64_addr_t dma_addr)
+{
+       return pfn_to_page(plat_dma_addr_to_phys(dma_addr) >> PAGE_SHIFT);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_page);
+
+unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev,
+       dma64_addr_t dma_addr)
+{
+       return dma_addr & ~PAGE_MASK;
+}
+
+EXPORT_SYMBOL(pci_dac_dma_to_offset);
+
+void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
+       dma64_addr_t dma_addr, size_t len, int direction)
+{
+       BUG_ON(direction == PCI_DMA_NONE);
+
+       if (!plat_device_is_coherent(&pdev->dev))
+               dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu);
+
+void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
+       dma64_addr_t dma_addr, size_t len, int direction)
+{
+       BUG_ON(direction == PCI_DMA_NONE);
+
+       if (!plat_device_is_coherent(&pdev->dev))
+               dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len);
+}
+
+EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device);
index 8338be0990bce2854078bfef18e45ccef0836ca2..bb54b6cdb30b8a1ed42bfe0f9b9f78cb3739ed2f 100644 (file)
@@ -340,6 +340,7 @@ static int acpi_ec_hc_add(struct acpi_device *device)
        smbus->adapter.owner = THIS_MODULE;
        smbus->adapter.algo = &acpi_ec_smbus_algorithm;
        smbus->adapter.algo_data = smbus;
+       smbus->adapter.dev.parent = &device->dev;
 
        if (i2c_add_adapter(&smbus->adapter)) {
                ACPI_DEBUG_PRINT((ACPI_DB_WARN,
index c654a3e0c697b36f008b934a8ed276bb6c110373..cb8d691576da5c30a084db075686c7286158b048 100644 (file)
@@ -596,7 +596,6 @@ static void fn_spawn_con(struct vc_data *vc)
 static void fn_SAK(struct vc_data *vc)
 {
        struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
-       PREPARE_WORK(SAK_work, vc_SAK);
        schedule_work(SAK_work);
 }
 
index 3757610b7835d4952e992563821293e6cc781fcd..be73c80d699d5edc4570a5e09c83af3727bc333d 100644 (file)
@@ -89,7 +89,6 @@ static struct sysrq_key_op sysrq_loglevel_op = {
 static void sysrq_handle_SAK(int key, struct tty_struct *tty)
 {
        struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
-       PREPARE_WORK(SAK_work, vc_SAK);
        schedule_work(SAK_work);
 }
 static struct sysrq_key_op sysrq_SAK_op = {
index 65672c57470b87282c3f4a73d261564310ca5565..5289254e7ab3f1e0d0fdfbf48e411e07fdc9c31a 100644 (file)
@@ -3442,7 +3442,6 @@ void do_SAK(struct tty_struct *tty)
 {
        if (!tty)
                return;
-       PREPARE_WORK(&tty->SAK_work, do_SAK_work);
        schedule_work(&tty->SAK_work);
 }
 
@@ -3568,7 +3567,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
        mutex_init(&tty->atomic_write_lock);
        spin_lock_init(&tty->read_lock);
        INIT_LIST_HEAD(&tty->tty_files);
-       INIT_WORK(&tty->SAK_work, NULL);
+       INIT_WORK(&tty->SAK_work, do_SAK_work);
 }
 
 /*
index 94ce3e7fc9e419be797bcd46647586d30a4457b5..c3f8e383933bbb957ffd2f50982558eb5cf08b81 100644 (file)
@@ -2635,6 +2635,7 @@ static int __init con_init(void)
         */
        for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
                vc_cons[currcons].d = vc = alloc_bootmem(sizeof(struct vc_data));
+               INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
                visual_init(vc, currcons, 1);
                vc->vc_screenbuf = (unsigned short *)alloc_bootmem(vc->vc_screenbuf_size);
                vc->vc_kmalloced = 0;
index 154d67e591e5c928b6cd59b97a746e994c46b8d8..85269c365a101986d631cd6f0cabdb71272a6fa2 100644 (file)
  *             It can be 1, 2, 10, 20, 110 or 220 seconds.
  */
 
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/fs.h>
-#include <linux/ioport.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
+/*
+ *     Includes, defines, variables, module parameters, ...
+ */
 
+/* Includes */
+#include <linux/module.h>              /* For module specific items */
+#include <linux/moduleparam.h>         /* For new moduleparam's */
+#include <linux/types.h>               /* For standard types (like size_t) */
+#include <linux/errno.h>               /* For the -ENODEV/... values */
+#include <linux/kernel.h>              /* For printk/panic/... */
+#include <linux/miscdevice.h>          /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
+#include <linux/watchdog.h>            /* For the watchdog specific items */
+#include <linux/fs.h>                  /* For file operations */
+#include <linux/ioport.h>              /* For io-port access */
+#include <linux/platform_device.h>     /* For platform_driver framework */
+#include <linux/init.h>                        /* For __init/__exit/... */
+
+#include <asm/uaccess.h>               /* For copy_to_user/put_user/... */
+#include <asm/io.h>                    /* For inb/outb/... */
+
+/* Module information */
+#define DRV_NAME "acquirewdt"
+#define PFX DRV_NAME ": "
 #define WATCHDOG_NAME "Acquire WDT"
-#define PFX WATCHDOG_NAME ": "
 #define WATCHDOG_HEARTBEAT 0   /* There is no way to see what the correct time-out period is */
 
+/* internal variables */
+static struct platform_device *acq_platform_device;    /* the watchdog platform device */
 static unsigned long acq_is_open;
 static char expect_close;
 
-/*
- *     You must set these - there is no sane way to probe for this board.
- */
-
-static int wdt_stop = 0x43;
+/* module parameters */
+static int wdt_stop = 0x43;    /* You must set this - there is no sane way to probe for this board. */
 module_param(wdt_stop, int, 0);
 MODULE_PARM_DESC(wdt_stop, "Acquire WDT 'stop' io port (default 0x43)");
 
-static int wdt_start = 0x443;
+static int wdt_start = 0x443;  /* You must set this - there is no sane way to probe for this board. */
 module_param(wdt_start, int, 0);
 MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
- *     Kernel methods.
+ *     Watchdog Operations
  */
 
 static void acq_keepalive(void)
@@ -103,7 +109,7 @@ static void acq_stop(void)
 }
 
 /*
- *     /dev/watchdog handling.
+ *     /dev/watchdog handling
  */
 
 static ssize_t acq_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
@@ -143,7 +149,7 @@ static int acq_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        {
                .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
                .firmware_version = 1,
-               .identity = "Acquire WDT",
+               .identity = WATCHDOG_NAME,
        };
 
        switch(cmd)
@@ -213,20 +219,6 @@ static int acq_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-/*
- *     Notifier for system down
- */
-
-static int acq_notify_sys(struct notifier_block *this, unsigned long code,
-       void *unused)
-{
-       if(code==SYS_DOWN || code==SYS_HALT) {
-               /* Turn the WDT off */
-               acq_stop();
-       }
-       return NOTIFY_DONE;
-}
-
 /*
  *     Kernel Interfaces
  */
@@ -240,29 +232,20 @@ static const struct file_operations acq_fops = {
        .release        = acq_close,
 };
 
-static struct miscdevice acq_miscdev=
-{
-       .minor = WATCHDOG_MINOR,
-       .name = "watchdog",
-       .fops = &acq_fops,
+static struct miscdevice acq_miscdev = {
+       .minor  = WATCHDOG_MINOR,
+       .name   = "watchdog",
+       .fops   = &acq_fops,
 };
 
 /*
- *     The WDT card needs to learn about soft shutdowns in order to
- *     turn the timebomb registers off.
+ *     Init & exit routines
  */
 
-static struct notifier_block acq_notifier =
-{
-       .notifier_call = acq_notify_sys,
-};
-
-static int __init acq_init(void)
+static int __devinit acq_probe(struct platform_device *dev)
 {
        int ret;
 
-       printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n");
-
        if (wdt_stop != wdt_start) {
                if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
                        printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
@@ -279,18 +262,11 @@ static int __init acq_init(void)
                goto unreg_stop;
        }
 
-       ret = register_reboot_notifier(&acq_notifier);
-       if (ret != 0) {
-               printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
-                       ret);
-               goto unreg_regions;
-       }
-
        ret = misc_register(&acq_miscdev);
        if (ret != 0) {
                printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
                        WATCHDOG_MINOR, ret);
-               goto unreg_reboot;
+               goto unreg_regions;
        }
 
        printk (KERN_INFO PFX "initialized. (nowayout=%d)\n",
@@ -298,8 +274,6 @@ static int __init acq_init(void)
 
        return 0;
 
-unreg_reboot:
-       unregister_reboot_notifier(&acq_notifier);
 unreg_regions:
        release_region(wdt_start, 1);
 unreg_stop:
@@ -309,13 +283,60 @@ out:
        return ret;
 }
 
-static void __exit acq_exit(void)
+static int __devexit acq_remove(struct platform_device *dev)
 {
        misc_deregister(&acq_miscdev);
-       unregister_reboot_notifier(&acq_notifier);
+       release_region(wdt_start,1);
        if(wdt_stop != wdt_start)
                release_region(wdt_stop,1);
-       release_region(wdt_start,1);
+
+       return 0;
+}
+
+static void acq_shutdown(struct platform_device *dev)
+{
+       /* Turn the WDT off if we have a soft shutdown */
+       acq_stop();
+}
+
+static struct platform_driver acquirewdt_driver = {
+       .probe          = acq_probe,
+       .remove         = __devexit_p(acq_remove),
+       .shutdown       = acq_shutdown,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = DRV_NAME,
+       },
+};
+
+static int __init acq_init(void)
+{
+       int err;
+
+       printk(KERN_INFO "WDT driver for Acquire single board computer initialising.\n");
+
+       err = platform_driver_register(&acquirewdt_driver);
+       if (err)
+               return err;
+
+       acq_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+       if (IS_ERR(acq_platform_device)) {
+               err = PTR_ERR(acq_platform_device);
+               goto unreg_platform_driver;
+       }
+
+       return 0;
+
+unreg_platform_driver:
+       platform_driver_unregister(&acquirewdt_driver);
+       return err;
+}
+
+static void __exit acq_exit(void)
+{
+       platform_device_unregister(acq_platform_device);
+       platform_driver_unregister(&acquirewdt_driver);
+       printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
 }
 
 module_init(acq_init);
index 9d732769ba0144bd36a720d4362185dc0bb651d1..8121cc247343a220f7f3a21cda05e0cdb6ea0650 100644 (file)
 #include <linux/watchdog.h>
 #include <linux/fs.h>
 #include <linux/ioport.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+#define DRV_NAME "advantechwdt"
+#define PFX DRV_NAME ": "
 #define WATCHDOG_NAME "Advantech WDT"
-#define PFX WATCHDOG_NAME ": "
 #define WATCHDOG_TIMEOUT 60            /* 60 sec default timeout */
 
+static struct platform_device *advwdt_platform_device; /* the watchdog platform device */
 static unsigned long advwdt_is_open;
 static char adv_expect_close;
 
@@ -75,10 +76,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, defaul
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
- *     Kernel methods.
+ *     Watchdog Operations
  */
 
 static void
@@ -94,6 +95,20 @@ advwdt_disable(void)
        inb_p(wdt_stop);
 }
 
+static int
+advwdt_set_heartbeat(int t)
+{
+       if ((t < 1) || (t > 63))
+               return -EINVAL;
+
+       timeout = t;
+       return 0;
+}
+
+/*
+ *     /dev/watchdog handling
+ */
+
 static ssize_t
 advwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
@@ -126,7 +141,7 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        static struct watchdog_info ident = {
                .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
                .firmware_version = 1,
-               .identity = "Advantech WDT",
+               .identity = WATCHDOG_NAME,
        };
 
        switch (cmd) {
@@ -146,9 +161,8 @@ advwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        case WDIOC_SETTIMEOUT:
          if (get_user(new_timeout, p))
                  return -EFAULT;
-         if ((new_timeout < 1) || (new_timeout > 63))
+         if (advwdt_set_heartbeat(new_timeout))
                  return -EINVAL;
-         timeout = new_timeout;
          advwdt_ping();
          /* Fall */
 
@@ -208,21 +222,6 @@ advwdt_close(struct inode *inode, struct file *file)
        return 0;
 }
 
-/*
- *     Notifier for system down
- */
-
-static int
-advwdt_notify_sys(struct notifier_block *this, unsigned long code,
-       void *unused)
-{
-       if (code == SYS_DOWN || code == SYS_HALT) {
-               /* Turn the WDT off */
-               advwdt_disable();
-       }
-       return NOTIFY_DONE;
-}
-
 /*
  *     Kernel Interfaces
  */
@@ -237,33 +236,20 @@ static const struct file_operations advwdt_fops = {
 };
 
 static struct miscdevice advwdt_miscdev = {
-       .minor = WATCHDOG_MINOR,
-       .name = "watchdog",
-       .fops = &advwdt_fops,
+       .minor  = WATCHDOG_MINOR,
+       .name   = "watchdog",
+       .fops   = &advwdt_fops,
 };
 
 /*
- *     The WDT needs to learn about soft shutdowns in order to
- *     turn the timebomb registers off.
+ *     Init & exit routines
  */
 
-static struct notifier_block advwdt_notifier = {
-       .notifier_call = advwdt_notify_sys,
-};
-
-static int __init
-advwdt_init(void)
+static int __devinit
+advwdt_probe(struct platform_device *dev)
 {
        int ret;
 
-       printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
-
-       if (timeout < 1 || timeout > 63) {
-               timeout = WATCHDOG_TIMEOUT;
-               printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
-                       timeout);
-       }
-
        if (wdt_stop != wdt_start) {
                if (!request_region(wdt_stop, 1, WATCHDOG_NAME)) {
                        printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
@@ -280,18 +266,18 @@ advwdt_init(void)
                goto unreg_stop;
        }
 
-       ret = register_reboot_notifier(&advwdt_notifier);
-       if (ret != 0) {
-               printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
-                       ret);
-               goto unreg_regions;
+       /* Check that the heartbeat value is within it's range ; if not reset to the default */
+       if (advwdt_set_heartbeat(timeout)) {
+               advwdt_set_heartbeat(WATCHDOG_TIMEOUT);
+               printk (KERN_INFO PFX "timeout value must be 1<=x<=63, using %d\n",
+                       timeout);
        }
 
        ret = misc_register(&advwdt_miscdev);
        if (ret != 0) {
                printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
                        WATCHDOG_MINOR, ret);
-               goto unreg_reboot;
+               goto unreg_regions;
        }
 
        printk (KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d)\n",
@@ -299,8 +285,6 @@ advwdt_init(void)
 
 out:
        return ret;
-unreg_reboot:
-       unregister_reboot_notifier(&advwdt_notifier);
 unreg_regions:
        release_region(wdt_start, 1);
 unreg_stop:
@@ -309,14 +293,64 @@ unreg_stop:
        goto out;
 }
 
-static void __exit
-advwdt_exit(void)
+static int __devexit
+advwdt_remove(struct platform_device *dev)
 {
        misc_deregister(&advwdt_miscdev);
-       unregister_reboot_notifier(&advwdt_notifier);
+       release_region(wdt_start,1);
        if(wdt_stop != wdt_start)
                release_region(wdt_stop,1);
-       release_region(wdt_start,1);
+
+       return 0;
+}
+
+static void
+advwdt_shutdown(struct platform_device *dev)
+{
+       /* Turn the WDT off if we have a soft shutdown */
+       advwdt_disable();
+}
+
+static struct platform_driver advwdt_driver = {
+       .probe          = advwdt_probe,
+       .remove         = __devexit_p(advwdt_remove),
+       .shutdown       = advwdt_shutdown,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = DRV_NAME,
+       },
+};
+
+static int __init
+advwdt_init(void)
+{
+       int err;
+
+       printk(KERN_INFO "WDT driver for Advantech single board computer initialising.\n");
+
+       err = platform_driver_register(&advwdt_driver);
+       if (err)
+               return err;
+
+       advwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+       if (IS_ERR(advwdt_platform_device)) {
+               err = PTR_ERR(advwdt_platform_device);
+               goto unreg_platform_driver;
+       }
+
+       return 0;
+
+unreg_platform_driver:
+       platform_driver_unregister(&advwdt_driver);
+       return err;
+}
+
+static void __exit
+advwdt_exit(void)
+{
+       platform_device_unregister(advwdt_platform_device);
+       platform_driver_unregister(&advwdt_driver);
+       printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
 }
 
 module_init(advwdt_init);
index 01b0d132ee41b3890b58cb3a983b87742bf69dff..e3f6a7d0c83d35a84732e2b59203ed3ff03cb234 100644 (file)
@@ -40,7 +40,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, defaul
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     ali_start       -       start watchdog countdown
index e5b2c2ee292cb810470a55f71253fcdcb92c7a57..67aed9f8c362e7a9f87f50aedf93717bad7c345b 100644 (file)
@@ -69,7 +69,7 @@ module_param(use_gpio, int, 0);
 MODULE_PARM_DESC(use_gpio, "Use the gpio watchdog.  (required by old cobalt boards)");
 
 static void wdt_timer_ping(unsigned long);
-static struct timer_list timer;
+static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1);
 static unsigned long next_heartbeat;
 static unsigned long wdt_is_open;
 static char wdt_expect_close;
@@ -78,7 +78,7 @@ static struct pci_dev *alim7101_pmu;
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
-                __stringify(CONFIG_WATCHDOG_NOWAYOUT) ")");
+                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Whack the dog
@@ -108,8 +108,7 @@ static void wdt_timer_ping(unsigned long data)
                printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
        }
        /* Re-set the timer interval */
-       timer.expires = jiffies + WDT_INTERVAL;
-       add_timer(&timer);
+       mod_timer(&timer, jiffies + WDT_INTERVAL);
 }
 
 /*
@@ -147,9 +146,7 @@ static void wdt_startup(void)
        wdt_change(WDT_ENABLE);
 
        /* Start the timer */
-       timer.expires = jiffies + WDT_INTERVAL;
-       add_timer(&timer);
-
+       mod_timer(&timer, jiffies + WDT_INTERVAL);
 
        printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
 }
@@ -380,10 +377,6 @@ static int __init alim7101_wdt_init(void)
                        timeout);
        }
 
-       init_timer(&timer);
-       timer.function = wdt_timer_ping;
-       timer.data = 1;
-
        rc = misc_register(&wdt_miscdev);
        if (rc) {
                printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
index 00bdabb90f27b958a76ab7b8d39c4b505892411e..bcd7e36ca0aa67b8f9e6e3c461d2b3f12912d0ab 100644 (file)
@@ -80,10 +80,8 @@ static void cpu5wdt_trigger(unsigned long unused)
        outb(1, port + CPU5WDT_TRIGGER_REG);
 
        /* requeue?? */
-       if( cpu5wdt_device.queue && ticks ) {
-               cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL;
-               add_timer(&cpu5wdt_device.timer);
-       }
+       if (cpu5wdt_device.queue && ticks)
+               mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL);
        else {
                /* ticks doesn't matter anyway */
                complete(&cpu5wdt_device.stop);
@@ -109,8 +107,7 @@ static void cpu5wdt_start(void)
                outb(1, port + CPU5WDT_MODE_REG);
                outb(0, port + CPU5WDT_RESET_REG);
                outb(0, port + CPU5WDT_ENABLE_REG);
-               cpu5wdt_device.timer.expires = jiffies + CPU5WDT_INTERVAL;
-               add_timer(&cpu5wdt_device.timer);
+               mod_timer(&cpu5wdt_device.timer, jiffies + CPU5WDT_INTERVAL);
        }
        /* if process dies, counter is not decremented */
        cpu5wdt_device.running++;
@@ -245,9 +242,7 @@ static int __devinit cpu5wdt_init(void)
 
        clear_bit(0, &cpu5wdt_device.inuse);
 
-       init_timer(&cpu5wdt_device.timer);
-       cpu5wdt_device.timer.function = cpu5wdt_trigger;
-       cpu5wdt_device.timer.data = 0;
+       setup_timer(&cpu5wdt_device.timer, cpu5wdt_trigger, 0);
 
        cpu5wdt_device.default_ticks = ticks;
 
index e228d6e173cead6243232be6a137c6f275776caa..f70387f01b2b1880ffcbb26b9982d2ba68f55f48 100644 (file)
@@ -73,7 +73,7 @@ static char *ev = "int";
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  * Some symbolic names
index fb64df4d7c8720107f16e360047c93ef2deac0b4..c5982502c03d45a8def683ac7c06cf4d83ad3719 100644 (file)
@@ -91,7 +91,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, d
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  * Some i6300ESB specific functions
index e0627d79707b27f6b91d8ccb47506a29f1fad451..a62ef48a15ae8f91c12bf27ba0bc0f2f8cc87fac 100644 (file)
@@ -109,7 +109,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39, def
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  * Some TCO specific functions
index fd8a44a08cd3604c07d70d8cd4cef8cd7f757cd9..3c9684ccd2f936ff248c6efc69abdb6025d90b03 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets)
  *
- *     (c) Copyright 2006 Wim Van Sebroeck <wim@iguana.be>.
+ *     (c) Copyright 2006-2007 Wim Van Sebroeck <wim@iguana.be>.
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -49,7 +49,7 @@
 /* Module and version information */
 #define DRV_NAME        "iTCO_wdt"
 #define DRV_VERSION     "1.01"
-#define DRV_RELDATE     "11-Nov-2006"
+#define DRV_RELDATE     "21-Jan-2007"
 #define PFX            DRV_NAME ": "
 
 /* Includes */
@@ -187,7 +187,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39 (TCO
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /* iTCO Vendor Specific Support hooks */
 #ifdef CONFIG_ITCO_VENDOR_SUPPORT
index c1ed209a138ca3176313abcf3fa4bdcc2de33b9f..c3a60f52ccb97d26931e66ea29384ef43a80c464 100644 (file)
@@ -3,8 +3,8 @@
  *
  *     (c) Copyright 2001 Charles Howes <chowes@vsol.net>
  *
- *      Based on advantechwdt.c which is based on acquirewdt.c which
- *       is based on wdt.c.
+ *     Based on advantechwdt.c which is based on acquirewdt.c which
+ *     is based on wdt.c.
  *
  *     (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
  *
@@ -25,9 +25,9 @@
  *
  *     (c) Copyright 1995    Alan Cox <alan@redhat.com>
  *
- *      14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
- *           Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
- *           Added timeout module option to override default
+ *     14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ *          Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ *          Added timeout module option to override default
  *
  */
 
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
 #include <linux/ioport.h>
-#include <linux/notifier.h>
 #include <linux/fs.h>
-#include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/moduleparam.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+static struct platform_device *ibwdt_platform_device;
 static unsigned long ibwdt_is_open;
 static spinlock_t ibwdt_lock;
 static char expect_close;
 
-#define PFX "ib700wdt: "
+/* Module information */
+#define DRV_NAME "ib700wdt"
+#define PFX DRV_NAME ": "
 
 /*
  *
@@ -118,20 +120,51 @@ static int wd_margin = WD_TIMO;
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 
 /*
- *     Kernel methods.
+ *     Watchdog Operations
  */
 
 static void
 ibwdt_ping(void)
 {
+       spin_lock(&ibwdt_lock);
+
        /* Write a watchdog value */
        outb_p(wd_margin, WDT_START);
+
+       spin_unlock(&ibwdt_lock);
 }
 
+static void
+ibwdt_disable(void)
+{
+       spin_lock(&ibwdt_lock);
+       outb_p(0, WDT_STOP);
+       spin_unlock(&ibwdt_lock);
+}
+
+static int
+ibwdt_set_heartbeat(int t)
+{
+       int i;
+
+       if ((t < 0) || (t > 30))
+               return -EINVAL;
+
+       for (i = 0x0F; i > -1; i--)
+               if (wd_times[i] > t)
+                       break;
+       wd_margin = i;
+       return 0;
+}
+
+/*
+ *     /dev/watchdog handling
+ */
+
 static ssize_t
 ibwdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
@@ -159,7 +192,7 @@ static int
 ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          unsigned long arg)
 {
-       int i, new_margin;
+       int new_margin;
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
 
@@ -176,6 +209,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
          break;
 
        case WDIOC_GETSTATUS:
+       case WDIOC_GETBOOTSTATUS:
          return put_user(0, p);
 
        case WDIOC_KEEPALIVE:
@@ -185,18 +219,33 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        case WDIOC_SETTIMEOUT:
          if (get_user(new_margin, p))
                  return -EFAULT;
-         if ((new_margin < 0) || (new_margin > 30))
+         if (ibwdt_set_heartbeat(new_margin))
                  return -EINVAL;
-         for (i = 0x0F; i > -1; i--)
-                 if (wd_times[i] > new_margin)
-                         break;
-         wd_margin = i;
          ibwdt_ping();
          /* Fall */
 
        case WDIOC_GETTIMEOUT:
          return put_user(wd_times[wd_margin], p);
-         break;
+
+       case WDIOC_SETOPTIONS:
+       {
+         int options, retval = -EINVAL;
+
+         if (get_user(options, p))
+           return -EFAULT;
+
+         if (options & WDIOS_DISABLECARD) {
+           ibwdt_disable();
+           retval = 0;
+         }
+
+         if (options & WDIOS_ENABLECARD) {
+           ibwdt_ping();
+           retval = 0;
+         }
+
+         return retval;
+       }
 
        default:
          return -ENOTTY;
@@ -207,9 +256,7 @@ ibwdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 static int
 ibwdt_open(struct inode *inode, struct file *file)
 {
-       spin_lock(&ibwdt_lock);
        if (test_and_set_bit(0, &ibwdt_is_open)) {
-               spin_unlock(&ibwdt_lock);
                return -EBUSY;
        }
        if (nowayout)
@@ -217,40 +264,23 @@ ibwdt_open(struct inode *inode, struct file *file)
 
        /* Activate */
        ibwdt_ping();
-       spin_unlock(&ibwdt_lock);
        return nonseekable_open(inode, file);
 }
 
 static int
 ibwdt_close(struct inode *inode, struct file *file)
 {
-       spin_lock(&ibwdt_lock);
-       if (expect_close == 42)
-               outb_p(0, WDT_STOP);
-       else
+       if (expect_close == 42) {
+               ibwdt_disable();
+       } else {
                printk(KERN_CRIT PFX "WDT device closed unexpectedly.  WDT will not stop!\n");
-
+               ibwdt_ping();
+       }
        clear_bit(0, &ibwdt_is_open);
        expect_close = 0;
-       spin_unlock(&ibwdt_lock);
        return 0;
 }
 
-/*
- *     Notifier for system down
- */
-
-static int
-ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
-       void *unused)
-{
-       if (code == SYS_DOWN || code == SYS_HALT) {
-               /* Turn the WDT off */
-               outb_p(0, WDT_STOP);
-       }
-       return NOTIFY_DONE;
-}
-
 /*
  *     Kernel Interfaces
  */
@@ -271,26 +301,14 @@ static struct miscdevice ibwdt_miscdev = {
 };
 
 /*
- *     The WDT needs to learn about soft shutdowns in order to
- *     turn the timebomb registers off.
+ *     Init & exit routines
  */
 
-static struct notifier_block ibwdt_notifier = {
-       .notifier_call = ibwdt_notify_sys,
-};
-
-static int __init ibwdt_init(void)
+static int __devinit ibwdt_probe(struct platform_device *dev)
 {
        int res;
 
-       printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n");
-
        spin_lock_init(&ibwdt_lock);
-       res = misc_register(&ibwdt_miscdev);
-       if (res) {
-               printk (KERN_ERR PFX "failed to register misc device\n");
-               goto out_nomisc;
-       }
 
 #if WDT_START != WDT_STOP
        if (!request_region(WDT_STOP, 1, "IB700 WDT")) {
@@ -305,34 +323,78 @@ static int __init ibwdt_init(void)
                res = -EIO;
                goto out_nostartreg;
        }
-       res = register_reboot_notifier(&ibwdt_notifier);
+
+       res = misc_register(&ibwdt_miscdev);
        if (res) {
-               printk (KERN_ERR PFX "Failed to register reboot notifier.\n");
-               goto out_noreboot;
+               printk (KERN_ERR PFX "failed to register misc device\n");
+               goto out_nomisc;
        }
        return 0;
 
-out_noreboot:
+out_nomisc:
        release_region(WDT_START, 1);
 out_nostartreg:
 #if WDT_START != WDT_STOP
        release_region(WDT_STOP, 1);
 #endif
 out_nostopreg:
-       misc_deregister(&ibwdt_miscdev);
-out_nomisc:
        return res;
 }
 
-static void __exit
-ibwdt_exit(void)
+static int __devexit ibwdt_remove(struct platform_device *dev)
 {
        misc_deregister(&ibwdt_miscdev);
-       unregister_reboot_notifier(&ibwdt_notifier);
+       release_region(WDT_START,1);
 #if WDT_START != WDT_STOP
        release_region(WDT_STOP,1);
 #endif
-       release_region(WDT_START,1);
+       return 0;
+}
+
+static void ibwdt_shutdown(struct platform_device *dev)
+{
+       /* Turn the WDT off if we have a soft shutdown */
+       ibwdt_disable();
+}
+
+static struct platform_driver ibwdt_driver = {
+       .probe          = ibwdt_probe,
+       .remove         = __devexit_p(ibwdt_remove),
+       .shutdown       = ibwdt_shutdown,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = DRV_NAME,
+       },
+};
+
+static int __init ibwdt_init(void)
+{
+       int err;
+
+       printk(KERN_INFO PFX "WDT driver for IB700 single board computer initialising.\n");
+
+       err = platform_driver_register(&ibwdt_driver);
+       if (err)
+               return err;
+
+       ibwdt_platform_device = platform_device_register_simple(DRV_NAME, -1, NULL, 0);
+       if (IS_ERR(ibwdt_platform_device)) {
+               err = PTR_ERR(ibwdt_platform_device);
+               goto unreg_platform_driver;
+       }
+
+       return 0;
+
+unreg_platform_driver:
+       platform_driver_unregister(&ibwdt_driver);
+       return err;
+}
+
+static void __exit ibwdt_exit(void)
+{
+       platform_device_unregister(ibwdt_platform_device);
+       platform_driver_unregister(&ibwdt_driver);
+       printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
 }
 
 module_init(ibwdt_init);
index dd6760f1a23ba43ecc40342cc9c1d9da3ef13e9c..8195f5023d853c23406f3cd0abe319b68e745d2c 100644 (file)
@@ -396,7 +396,7 @@ module_init(ibmasr_init);
 module_exit(ibmasr_exit);
 
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 MODULE_DESCRIPTION("IBM Automatic Server Restart driver");
 MODULE_AUTHOR("Andrey Panin");
index 0bc239308989d53dbf7adf8ad537ada06e086b12..788245bdaa7f88635593d4f70ac0d8ee164a4945 100644 (file)
@@ -32,7 +32,7 @@ static int indydog_alive;
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 static void indydog_start(void)
 {
index 4d730fdbd528cac4f84d78997045771a930d7b7b..81fb3dec180f5be0b5076568b3c140caa6393d4f 100644 (file)
@@ -95,7 +95,7 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 #define PFX "machzwd"
 
@@ -118,12 +118,14 @@ static int action = 0;
 module_param(action, int, 0);
 MODULE_PARM_DESC(action, "after watchdog resets, generate: 0 = RESET(*)  1 = SMI  2 = NMI  3 = SCI");
 
+static void zf_ping(unsigned long data);
+
 static int zf_action = GEN_RESET;
 static unsigned long zf_is_open;
 static char zf_expect_close;
 static spinlock_t zf_lock;
 static spinlock_t zf_port_lock;
-static struct timer_list zf_timer;
+static DEFINE_TIMER(zf_timer, zf_ping, 0, 0);
 static unsigned long next_heartbeat = 0;
 
 
@@ -220,9 +222,7 @@ static void zf_timer_on(void)
        next_heartbeat = jiffies + ZF_USER_TIMEO;
 
        /* start the timer for internal ping */
-       zf_timer.expires = jiffies + ZF_HW_TIMEO;
-
-       add_timer(&zf_timer);
+       mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
 
        /* start watchdog timer */
        ctrl_reg = zf_get_control();
@@ -260,8 +260,7 @@ static void zf_ping(unsigned long data)
                zf_set_control(ctrl_reg);
                spin_unlock_irqrestore(&zf_port_lock, flags);
 
-               zf_timer.expires = jiffies + ZF_HW_TIMEO;
-               add_timer(&zf_timer);
+               mod_timer(&zf_timer, jiffies + ZF_HW_TIMEO);
        }else{
                printk(KERN_CRIT PFX ": I will reset your machine\n");
        }
@@ -465,11 +464,6 @@ static int __init zf_init(void)
        zf_set_status(0);
        zf_set_control(0);
 
-       /* this is the timer that will do the hard work */
-       init_timer(&zf_timer);
-       zf_timer.function = zf_ping;
-       zf_timer.data = 0;
-
        return 0;
 
 no_reboot:
index c2dac0aa1d6254906468a35dcbaea932197b416f..f35e2848aa3eb35fd4fb49fc5ade7ced904c2a45 100644 (file)
@@ -56,16 +56,18 @@ static int mixcomwd_ioports[] = { 0x180, 0x280, 0x380, 0x000 };
 #define FLASHCOM_WATCHDOG_OFFSET 0x4
 #define FLASHCOM_ID 0x18
 
+static void mixcomwd_timerfun(unsigned long d);
+
 static unsigned long mixcomwd_opened; /* long req'd for setbit --RR */
 
 static int watchdog_port;
 static int mixcomwd_timer_alive;
-static DEFINE_TIMER(mixcomwd_timer, NULL, 0, 0);
+static DEFINE_TIMER(mixcomwd_timer, mixcomwd_timerfun, 0, 0);
 static char expect_close;
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 static void mixcomwd_ping(void)
 {
@@ -77,7 +79,7 @@ static void mixcomwd_timerfun(unsigned long d)
 {
        mixcomwd_ping();
 
-       mod_timer(&mixcomwd_timer,jiffies+ 5*HZ);
+       mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
 }
 
 /*
@@ -114,12 +116,8 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
                        printk(KERN_ERR "mixcomwd: release called while internal timer alive");
                        return -EBUSY;
                }
-               init_timer(&mixcomwd_timer);
-               mixcomwd_timer.expires=jiffies + 5 * HZ;
-               mixcomwd_timer.function=mixcomwd_timerfun;
-               mixcomwd_timer.data=0;
                mixcomwd_timer_alive=1;
-               add_timer(&mixcomwd_timer);
+               mod_timer(&mixcomwd_timer, jiffies + 5 * HZ);
        } else {
                printk(KERN_CRIT "mixcomwd: WDT device closed unexpectedly.  WDT will not stop!\n");
        }
@@ -285,7 +283,7 @@ static void __exit mixcomwd_exit(void)
                if(mixcomwd_timer_alive) {
                        printk(KERN_WARNING "mixcomwd: I quit now, hardware will"
                               " probably reboot!\n");
-                       del_timer(&mixcomwd_timer);
+                       del_timer_sync(&mixcomwd_timer);
                        mixcomwd_timer_alive=0;
                }
        }
index a77a90717ad21cca1f2c553c4cbc2d3bac7f14ec..3d3deae0d64ba0668f28fb275a082531a7e62e1c 100644 (file)
@@ -631,5 +631,5 @@ module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" __MODULE_STRING(timeout) ").");
 
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
index 8e1e6e48e0a70733f8768a95cce8901409a8d9e0..6e8b5705b5b78f94f77071217b01494c035f5b34 100644 (file)
@@ -2,7 +2,7 @@
  * PC Watchdog Driver
  * by Ken Hollis (khollis@bitgate.com)
  *
- * Permission granted from Simon Machell (73244.1270@compuserve.com)
+ * Permission granted from Simon Machell (smachell@berkprod.com)
  * Written for the Linux Kernel, and GPLed by Ken Hollis
  *
  * 960107      Added request_region routines, modulized the whole thing.
@@ -70,8 +70,8 @@
 #include <asm/io.h>            /* For inb/outb/... */
 
 /* Module and version information */
-#define WATCHDOG_VERSION "1.17"
-#define WATCHDOG_DATE "12 Feb 2006"
+#define WATCHDOG_VERSION "1.18"
+#define WATCHDOG_DATE "21 Jan 2007"
 #define WATCHDOG_DRIVER_NAME "ISA-PC Watchdog"
 #define WATCHDOG_NAME "pcwd"
 #define PFX WATCHDOG_NAME ": "
 #define CMD_ISA_DELAY_TIME_8SECS       0x0C
 #define CMD_ISA_RESET_RELAYS           0x0D
 
+/* Watchdog's Dip Switch heartbeat values */
+static const int heartbeat_tbl [] = {
+       20,     /* OFF-OFF-OFF  = 20 Sec  */
+       40,     /* OFF-OFF-ON   = 40 Sec  */
+       60,     /* OFF-ON-OFF   =  1 Min  */
+       300,    /* OFF-ON-ON    =  5 Min  */
+       600,    /* ON-OFF-OFF   = 10 Min  */
+       1800,   /* ON-OFF-ON    = 30 Min  */
+       3600,   /* ON-ON-OFF    =  1 Hour */
+       7200,   /* ON-ON-ON     =  2 hour */
+};
+
 /*
  * We are using an kernel timer to do the pinging of the watchdog
  * every ~500ms. We try to set the internal heartbeat of the
@@ -167,14 +179,14 @@ static int debug = QUIET;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
 
-#define WATCHDOG_HEARTBEAT 60          /* 60 sec default heartbeat */
+#define WATCHDOG_HEARTBEAT 0           /* default heartbeat = delay-time from dip-switches */
 static int heartbeat = WATCHDOG_HEARTBEAT;
 module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Internal functions
@@ -831,9 +843,7 @@ static int __devinit pcwatchdog_init(int base_addr)
        /* clear the "card caused reboot" flag */
        pcwd_clear_status();
 
-       init_timer(&pcwd_private.timer);
-       pcwd_private.timer.function = pcwd_timer_ping;
-       pcwd_private.timer.data = 0;
+       setup_timer(&pcwd_private.timer, pcwd_timer_ping, 0);
 
        /*  Disable the board  */
        pcwd_stop();
@@ -844,6 +854,10 @@ static int __devinit pcwatchdog_init(int base_addr)
        /* Show info about the card itself */
        pcwd_show_card_info();
 
+       /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
+       if (heartbeat == 0)
+               heartbeat = heartbeat_tbl[(pcwd_get_option_switches() & 0x07)];
+
        /* Check that the heartbeat value is within it's range ; if not reset to the default */
        if (pcwd_set_heartbeat(heartbeat)) {
                pcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
index f4872c87106393786bf1d5be663877a8bbe61fca..61a89e9596421376d2047686f7177e32b073ca41 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     Berkshire PCI-PC Watchdog Card Driver
  *
- *     (c) Copyright 2003-2005 Wim Van Sebroeck <wim@iguana.be>.
+ *     (c) Copyright 2003-2007 Wim Van Sebroeck <wim@iguana.be>.
  *
  *     Based on source code of the following authors:
  *       Ken Hollis <kenji@bitgate.com>,
@@ -51,8 +51,8 @@
 #include <asm/io.h>            /* For inb/outb/... */
 
 /* Module and version information */
-#define WATCHDOG_VERSION "1.02"
-#define WATCHDOG_DATE "03 Sep 2005"
+#define WATCHDOG_VERSION "1.03"
+#define WATCHDOG_DATE "21 Jan 2007"
 #define WATCHDOG_DRIVER_NAME "PCI-PC Watchdog"
 #define WATCHDOG_NAME "pcwd_pci"
 #define PFX WATCHDOG_NAME ": "
 #define CMD_WRITE_WATCHDOG_TIMEOUT             0x19
 #define CMD_GET_CLEAR_RESET_COUNT              0x84
 
+/* Watchdog's Dip Switch heartbeat values */
+static const int heartbeat_tbl [] = {
+       5,      /* OFF-OFF-OFF  =  5 Sec  */
+       10,     /* OFF-OFF-ON   = 10 Sec  */
+       30,     /* OFF-ON-OFF   = 30 Sec  */
+       60,     /* OFF-ON-ON    =  1 Min  */
+       300,    /* ON-OFF-OFF   =  5 Min  */
+       600,    /* ON-OFF-ON    = 10 Min  */
+       1800,   /* ON-ON-OFF    = 30 Min  */
+       3600,   /* ON-ON-ON     =  1 hour */
+};
+
 /* We can only use 1 card due to the /dev/watchdog restriction */
 static int cards_found;
 
@@ -119,14 +131,14 @@ static int debug = QUIET;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level: 0=Quiet, 1=Verbose, 2=Debug (default=0)");
 
-#define WATCHDOG_HEARTBEAT 2   /* 2 sec default heartbeat */
+#define WATCHDOG_HEARTBEAT 0   /* default heartbeat = delay-time from dip-switches */
 static int heartbeat = WATCHDOG_HEARTBEAT;
 module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Internal functions
@@ -286,7 +298,9 @@ static int pcipcwd_stop(void)
 static int pcipcwd_keepalive(void)
 {
        /* Re-trigger watchdog by writing to port 0 */
+       spin_lock(&pcipcwd_private.io_lock);
        outb_p(0x42, pcipcwd_private.io_addr);  /* send out any data */
+       spin_unlock(&pcipcwd_private.io_lock);
 
        if (debug >= DEBUG)
                printk(KERN_DEBUG PFX "Watchdog keepalive signal send\n");
@@ -373,7 +387,9 @@ static int pcipcwd_get_temperature(int *temperature)
        if (!pcipcwd_private.supports_temp)
                return -ENODEV;
 
+       spin_lock(&pcipcwd_private.io_lock);
        *temperature = inb_p(pcipcwd_private.io_addr);
+       spin_unlock(&pcipcwd_private.io_lock);
 
        /*
         * Convert celsius to fahrenheit, since this was
@@ -711,6 +727,10 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
        /* Show info about the card itself */
        pcipcwd_show_card_info();
 
+       /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
+       if (heartbeat == 0)
+               heartbeat = heartbeat_tbl[(pcipcwd_get_option_switches() & 0x07)];
+
        /* Check that the heartbeat value is within it's range ; if not reset to the default */
        if (pcipcwd_set_heartbeat(heartbeat)) {
                pcipcwd_set_heartbeat(WATCHDOG_HEARTBEAT);
@@ -798,6 +818,8 @@ static int __init pcipcwd_init_module(void)
 static void __exit pcipcwd_cleanup_module(void)
 {
        pci_unregister_driver(&pcipcwd_driver);
+
+       printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
 }
 
 module_init(pcipcwd_init_module);
index 2da5ac99687c60fba0660c713fc34370d6762c5c..31037f9c9ffe8b7a2b41e79f512bfeb3eadf202b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     Berkshire USB-PC Watchdog Card Driver
  *
- *     (c) Copyright 2004 Wim Van Sebroeck <wim@iguana.be>.
+ *     (c) Copyright 2004-2007 Wim Van Sebroeck <wim@iguana.be>.
  *
  *     Based on source code of the following authors:
  *       Ken Hollis <kenji@bitgate.com>,
  *     http://www.berkprod.com/ or http://www.pcwatchdog.com/
  */
 
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/fs.h>
-#include <linux/smp_lock.h>
-#include <linux/completion.h>
-#include <asm/uaccess.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
+#include <linux/module.h>      /* For module specific items */
+#include <linux/moduleparam.h> /* For new moduleparam's */
+#include <linux/types.h>       /* For standard types (like size_t) */
+#include <linux/errno.h>       /* For the -ENODEV/... values */
+#include <linux/kernel.h>      /* For printk/panic/... */
+#include <linux/delay.h>       /* For mdelay function */
+#include <linux/miscdevice.h>  /* For MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR) */
+#include <linux/watchdog.h>    /* For the watchdog specific items */
+#include <linux/notifier.h>    /* For notifier support */
+#include <linux/reboot.h>      /* For reboot_notifier stuff */
+#include <linux/init.h>                /* For __init/__exit/... */
+#include <linux/fs.h>          /* For file operations */
+#include <linux/usb.h>         /* For USB functions */
+#include <linux/slab.h>                /* For kmalloc, ... */
+#include <linux/mutex.h>       /* For mutex locking */
 #include <linux/hid.h>         /* For HID_REQ_SET_REPORT & HID_DT_REPORT */
 
+#include <asm/uaccess.h>       /* For copy_to_user/put_user/... */
+
 
 #ifdef CONFIG_USB_DEBUG
        static int debug = 1;
@@ -57,8 +56,8 @@
 
 
 /* Module and Version Information */
-#define DRIVER_VERSION "1.01"
-#define DRIVER_DATE "15 Mar 2005"
+#define DRIVER_VERSION "1.02"
+#define DRIVER_DATE "21 Jan 2007"
 #define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
 #define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
 #define DRIVER_LICENSE "GPL"
@@ -75,14 +74,14 @@ MODULE_ALIAS_MISCDEV(TEMP_MINOR);
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
-#define WATCHDOG_HEARTBEAT 2   /* 2 sec default heartbeat */
+#define WATCHDOG_HEARTBEAT 0   /* default heartbeat = delay-time from dip-switches */
 static int heartbeat = WATCHDOG_HEARTBEAT;
 module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536 or 0=delay-time from dip-switches, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /* The vendor and product id's for the USB-PC Watchdog card */
 #define USB_PCWD_VENDOR_ID     0x0c98
@@ -110,6 +109,18 @@ MODULE_DEVICE_TABLE (usb, usb_pcwd_table);
 #define CMD_ENABLE_WATCHDOG            0x30    /* Enable / Disable Watchdog */
 #define CMD_DISABLE_WATCHDOG           CMD_ENABLE_WATCHDOG
 
+/* Watchdog's Dip Switch heartbeat values */
+static const int heartbeat_tbl [] = {
+       5,      /* OFF-OFF-OFF  =  5 Sec  */
+       10,     /* OFF-OFF-ON   = 10 Sec  */
+       30,     /* OFF-ON-OFF   = 30 Sec  */
+       60,     /* OFF-ON-ON    =  1 Min  */
+       300,    /* ON-OFF-OFF   =  5 Min  */
+       600,    /* ON-OFF-ON    = 10 Min  */
+       1800,   /* ON-ON-OFF    = 30 Min  */
+       3600,   /* ON-ON-ON     =  1 hour */
+};
+
 /* We can only use 1 card due to the /dev/watchdog restriction */
 static int cards_found;
 
@@ -682,6 +693,10 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
                ((option_switches & 0x10) ? "ON" : "OFF"),
                ((option_switches & 0x08) ? "ON" : "OFF"));
 
+       /* If heartbeat = 0 then we use the heartbeat from the dip-switches */
+       if (heartbeat == 0)
+               heartbeat = heartbeat_tbl[(option_switches & 0x07)];
+
        /* Check that the heartbeat value is within it's range ; if not reset to the default */
        if (usb_pcwd_set_heartbeat(usb_pcwd, heartbeat)) {
                usb_pcwd_set_heartbeat(usb_pcwd, WATCHDOG_HEARTBEAT);
index ff6f1ca1e5e7119b48ace7d55843b0b6871367c6..5991add702b00e32efaf83711ebdb2a60dc8b832 100644 (file)
@@ -283,7 +283,8 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
        wdt_base = (void __iomem *)IO_ADDRESS(res->start);
 
        wdt_clk = clk_get(&pdev->dev, "wdt_ck");
-       if (!wdt_clk) {
+       if (IS_ERR(wdt_clk)) {
+               ret = PTR_ERR(wdt_clk);
                release_resource(wdt_mem);
                kfree(wdt_mem);
                goto out;
index 18cb050c38624b6eb76bc658849c8cecd107c950..dff6cb5dc9a7a0700c6dc09f2110736505701b06 100644 (file)
@@ -78,7 +78,7 @@ MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default=" __MODULE
 
 MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT));
 
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)");
 
@@ -366,13 +366,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
        wdt_mem = request_mem_region(res->start, size, pdev->name);
        if (wdt_mem == NULL) {
                printk(KERN_INFO PFX "failed to get memory region\n");
-               return -ENOENT;
+               ret = -ENOENT;
+               goto err_req;
        }
 
        wdt_base = ioremap(res->start, size);
        if (wdt_base == 0) {
                printk(KERN_INFO PFX "failed to ioremap() region\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_req;
        }
 
        DBG("probe: mapped wdt_base=%p\n", wdt_base);
@@ -380,22 +382,21 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (res == NULL) {
                printk(KERN_INFO PFX "failed to get irq resource\n");
-               iounmap(wdt_base);
-               return -ENOENT;
+               ret = -ENOENT;
+               goto err_map;
        }
 
        ret = request_irq(res->start, s3c2410wdt_irq, 0, pdev->name, pdev);
        if (ret != 0) {
                printk(KERN_INFO PFX "failed to install irq (%d)\n", ret);
-               iounmap(wdt_base);
-               return ret;
+               goto err_map;
        }
 
        wdt_clock = clk_get(&pdev->dev, "watchdog");
-       if (wdt_clock == NULL) {
+       if (IS_ERR(wdt_clock)) {
                printk(KERN_INFO PFX "failed to find watchdog clock source\n");
-               iounmap(wdt_base);
-               return -ENOENT;
+               ret = PTR_ERR(wdt_clock);
+               goto err_irq;
        }
 
        clk_enable(wdt_clock);
@@ -418,8 +419,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
        if (ret) {
                printk (KERN_ERR PFX "cannot register miscdev on minor=%d (%d)\n",
                        WATCHDOG_MINOR, ret);
-               iounmap(wdt_base);
-               return ret;
+               goto err_clk;
        }
 
        if (tmr_atboot && started == 0) {
@@ -434,26 +434,36 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
        }
 
        return 0;
+
+ err_clk:
+       clk_disable(wdt_clock);
+       clk_put(wdt_clock);
+
+ err_irq:
+       free_irq(wdt_irq->start, pdev);
+
+ err_map:
+       iounmap(wdt_base);
+
+ err_req:
+       release_resource(wdt_mem);
+       kfree(wdt_mem);
+
+       return ret;
 }
 
 static int s3c2410wdt_remove(struct platform_device *dev)
 {
-       if (wdt_mem != NULL) {
-               release_resource(wdt_mem);
-               kfree(wdt_mem);
-               wdt_mem = NULL;
-       }
+       release_resource(wdt_mem);
+       kfree(wdt_mem);
+       wdt_mem = NULL;
 
-       if (wdt_irq != NULL) {
-               free_irq(wdt_irq->start, dev);
-               wdt_irq = NULL;
-       }
+       free_irq(wdt_irq->start, dev);
+       wdt_irq = NULL;
 
-       if (wdt_clock != NULL) {
-               clk_disable(wdt_clock);
-               clk_put(wdt_clock);
-               wdt_clock = NULL;
-       }
+       clk_disable(wdt_clock);
+       clk_put(wdt_clock);
+       wdt_clock = NULL;
 
        iounmap(wdt_base);
        misc_deregister(&s3c2410wdt_miscdev);
index c7b2045bc76b5196f6aa04c732c2dd95a4912704..b6282039198c6cdcef656098d31a4570125c721e 100644 (file)
@@ -100,10 +100,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 static void wdt_timer_ping(unsigned long);
-static struct timer_list timer;
+static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
 static unsigned long next_heartbeat;
 static unsigned long wdt_is_open;
 static char wdt_expect_close;
@@ -122,8 +122,7 @@ static void wdt_timer_ping(unsigned long data)
                /* Ping the WDT by reading from wdt_start */
                inb_p(wdt_start);
                /* Re-set the timer interval */
-               timer.expires = jiffies + WDT_INTERVAL;
-               add_timer(&timer);
+               mod_timer(&timer, jiffies + WDT_INTERVAL);
        } else {
                printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
        }
@@ -138,8 +137,7 @@ static void wdt_startup(void)
        next_heartbeat = jiffies + (timeout * HZ);
 
        /* Start the timer */
-       timer.expires = jiffies + WDT_INTERVAL;
-       add_timer(&timer);
+       mod_timer(&timer, jiffies + WDT_INTERVAL);
        printk(KERN_INFO PFX "Watchdog timer is now enabled.\n");
 }
 
@@ -363,10 +361,6 @@ static int __init sbc60xxwdt_init(void)
                }
        }
 
-       init_timer(&timer);
-       timer.function = wdt_timer_ping;
-       timer.data = 0;
-
        rc = misc_register(&wdt_miscdev);
        if (rc)
        {
index 41fc6f80c493bef6c83052f8fd44121ec974e483..67ae42685e752f94d5feb19c7c4684467fa296af 100644 (file)
@@ -204,7 +204,7 @@ module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))");
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout,
-                "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+                "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Kernel methods.
index 8882b427d24f44d988bd2682fee1559a305eecec..82cbd8809a69b0cc863752f43f8fad58a3164bcf 100644 (file)
@@ -35,7 +35,7 @@ static int epx_c3_alive;
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 #define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */
 #define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */
index e3239833e4b0be839bb0223c2fce7f55a34309d6..1e4a8d751a71e8513e8bd23c42f253813bb92447 100644 (file)
@@ -92,7 +92,7 @@ MODULE_PARM_DESC(timeout, "range is 0-255 minutes, default is 1");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 
 
index caec37ba750a6810e7ea54abb6f73a6e72ef8e69..2676a43895a71f640c19f5120a0d8ff7f2523dbb 100644 (file)
@@ -97,7 +97,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  * AMD Elan SC520 - Watchdog Timer Registers
@@ -121,7 +121,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON
 static __u16 __iomem *wdtmrctl;
 
 static void wdt_timer_ping(unsigned long);
-static struct timer_list timer;
+static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
 static unsigned long next_heartbeat;
 static unsigned long wdt_is_open;
 static char wdt_expect_close;
@@ -145,8 +145,7 @@ static void wdt_timer_ping(unsigned long data)
                spin_unlock(&wdt_spinlock);
 
                /* Re-set the timer interval */
-               timer.expires = jiffies + WDT_INTERVAL;
-               add_timer(&timer);
+               mod_timer(&timer, jiffies + WDT_INTERVAL);
        } else {
                printk(KERN_WARNING PFX "Heartbeat lost! Will not ping the watchdog\n");
        }
@@ -179,8 +178,7 @@ static int wdt_startup(void)
        next_heartbeat = jiffies + (timeout * HZ);
 
        /* Start the timer */
-       timer.expires = jiffies + WDT_INTERVAL;
-       add_timer(&timer);
+       mod_timer(&timer, jiffies + WDT_INTERVAL);
 
        /* Start the watchdog */
        wdt_config(WDT_ENB | WDT_WRST_ENB | WDT_EXP_SEL_04);
@@ -389,10 +387,6 @@ static int __init sc520_wdt_init(void)
 
        spin_lock_init(&wdt_spinlock);
 
-       init_timer(&timer);
-       timer.function = wdt_timer_ping;
-       timer.data = 0;
-
        /* Check that the timeout value is within it's range ; if not reset to the default */
        if (wdt_set_heartbeat(timeout)) {
                wdt_set_heartbeat(WATCHDOG_TIMEOUT);
index dc403629aeb3d79a4e112798fe4ababfd2751070..cecbedd473a4392436ea150e1446b66c0a4c4601 100644 (file)
@@ -65,10 +65,12 @@ static int clock_division_ratio = WTCSR_CKS_4096;
 
 #define next_ping_period(cks)  msecs_to_jiffies(cks - 4)
 
+static void sh_wdt_ping(unsigned long data);
+
 static unsigned long shwdt_is_open;
 static struct watchdog_info sh_wdt_info;
 static char shwdt_expect_close;
-static struct timer_list timer;
+static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0);
 static unsigned long next_heartbeat;
 
 #define WATCHDOG_HEARTBEAT 30                  /* 30 sec default heartbeat */
@@ -433,10 +435,6 @@ static int __init sh_wdt_init(void)
                       "be 1<=x<=3600, using %d\n", heartbeat);
        }
 
-       init_timer(&timer);
-       timer.function = sh_wdt_ping;
-       timer.data = 0;
-
        rc = register_reboot_notifier(&sh_wdt_notifier);
        if (unlikely(rc)) {
                printk(KERN_ERR PFX "Can't register reboot notifier (err=%d)\n",
index a9681d580dd355dbb2753202fead86fec358e695..d3cb0a76602036a679e5f242ecaffb026bc93f51 100644 (file)
@@ -624,4 +624,4 @@ module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60");
 
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
index 4067e1f8a36878c7fa6665175051231b2710542f..9c3694909243e80c6877cde927722c260dd246c5 100644 (file)
@@ -59,7 +59,7 @@ MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<6
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 #ifdef ONLY_TESTING
 static int soft_noboot = 1;
index 07d4bff27226b378a6d88d3c1fb0abe9f9f8172a..337ee42c90dd757644913cd5a42330f3c20330cc 100644 (file)
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, defaul
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Kernel methods.
index c960ec110dd7c07c0464c840234f1f4957eb81da..d9e821d08deb3b7ea21b36be0ec4682389e807e5 100644 (file)
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, defau
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  *     Kernel methods.
index b0e5f84d6bafdc24fb9c21742f35b3b0bcdcc965..3c88fe18f4f437e01e88264e340ddea12fe0d207 100644 (file)
@@ -87,10 +87,10 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, defau
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 static void wdt_timer_ping(unsigned long);
-static struct timer_list timer;
+static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
 static unsigned long next_heartbeat;
 static unsigned long wdt_is_open;
 static char wdt_expect_close;
@@ -114,8 +114,7 @@ static void wdt_timer_ping(unsigned long data)
                inb_p(WDT_PING);
 
                /* Re-set the timer interval */
-               timer.expires = jiffies + WDT_INTERVAL;
-               add_timer(&timer);
+               mod_timer(&timer, jiffies + WDT_INTERVAL);
 
                spin_unlock(&wdt_spinlock);
 
@@ -155,8 +154,7 @@ static void wdt_startup(void)
        next_heartbeat = jiffies + (timeout * HZ);
 
        /* Start the timer */
-       timer.expires = jiffies + WDT_INTERVAL;
-       add_timer(&timer);
+       mod_timer(&timer, jiffies + WDT_INTERVAL);
 
        wdt_change(WDT_ENABLE);
 
@@ -377,10 +375,6 @@ static int __init w83877f_wdt_init(void)
                goto err_out_region1;
        }
 
-       init_timer(&timer);
-       timer.function = wdt_timer_ping;
-       timer.data = 0;
-
        rc = misc_register(&wdt_miscdev);
        if (rc)
        {
index 2c8d5d8bd4e85303750274d1e9b2907b66c0bdad..15796844289121d9ed3bc2833a6cd6eecb2c9b81 100644 (file)
@@ -59,7 +59,7 @@ MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  * Start the watchdog
index 163e028ef9ed6cee052ee4aa643d8659e17e5bc8..950905d3c39f298ae00b1094b17ddec60231d331 100644 (file)
@@ -65,7 +65,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, defau
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 static void wafwdt_ping(void)
 {
index 517fbd8643f8f00a2b1970f8b7a63fb023f1fc38..0a3de6a024420b52369b00f19a55ba3844a8b12e 100644 (file)
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536,
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /* You must set these - there is no sane way to probe for this board. */
 static int io=0x240;
index 6253041b235bb2ae0c1260e772f86b659bd799cb..7d300ff7ab07ed65df9ce6e8006a449c01dd4600 100644 (file)
@@ -68,7 +68,7 @@ MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 /*
  * Start the watchdog
index ce1261c5cbce9a7423ad0b0d3babcf74cc69dd59..6baf4ae42c9d0e831cfa87e4470c72a7b2b15a4d 100644 (file)
@@ -90,7 +90,7 @@ MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536,
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
 #ifdef CONFIG_WDT_501_PCI
 /* Support for the Fan Tachometer on the PCI-WDT501 */
index 93f93d4fb8aec2126e86131e9077703c4e1e171d..a6a4aa0eee166d3ac029d2e7c49c8a4c714fe2bf 100644 (file)
@@ -727,7 +727,6 @@ int vt8231_detect(struct i2c_adapter *adapter)
        client->addr = isa_address;
        client->adapter = adapter;
        client->driver = &vt8231_driver;
-       client->dev.parent = &adapter->dev;
 
        /* Fill in the remaining client fields and put into the global list */
        strlcpy(client->name, "vt8231", I2C_NAME_SIZE);
index 9367c4cfe936f533f9500cd10f73a2b293dfd538..4d44a2db29ddca1bb0964100d995091b37f26b91 100644 (file)
@@ -183,6 +183,7 @@ config I2C_PIIX4
            ATI IXP200
            ATI IXP300
            ATI IXP400
+           ATI SB600
            Serverworks OSB4
            Serverworks CSB5
            Serverworks CSB6
@@ -341,6 +342,13 @@ config I2C_PARPORT_LIGHT
          This support is also available as a module.  If so, the module 
          will be called i2c-parport-light.
 
+config I2C_PASEMI
+       tristate "PA Semi SMBus interface"
+#      depends on PPC_PASEMI && I2C && PCI
+       depends on I2C && PCI
+       help
+         Supports the PA Semi PWRficient on-chip SMBus interfaces.
+
 config I2C_PROSAVAGE
        tristate "S3/VIA (Pro)Savage"
        depends on I2C && PCI
@@ -499,11 +507,11 @@ config I2C_VIA
          will be called i2c-via.
 
 config I2C_VIAPRO
-       tristate "VIA 82C596/82C686/82xx"
+       tristate "VIA VT82C596/82C686/82xx and CX700"
        depends on I2C && PCI
        help
          If you say yes to this option, support will be included for the VIA
-         82C596/82C686/82xx I2C interfaces.  Specifically, the following
+         VT82C596 and later SMBus interface.  Specifically, the following
          chipsets are supported:
            VT82C596A/B
            VT82C686A/B
@@ -512,6 +520,7 @@ config I2C_VIAPRO
            VT8235
            VT8237R/A
            VT8251
+           CX700
 
          This driver can also be built as a module.  If so, the module
          will be called i2c-viapro.
index 37196c1d0794e830b34b7c16f41ea68774a38940..03505aa44bbf0a8590dbb71f2e78584c3660a992 100644 (file)
@@ -27,6 +27,7 @@ obj-$(CONFIG_I2C_OCORES)      += i2c-ocores.o
 obj-$(CONFIG_I2C_OMAP)         += i2c-omap.o
 obj-$(CONFIG_I2C_PARPORT)      += i2c-parport.o
 obj-$(CONFIG_I2C_PARPORT_LIGHT)        += i2c-parport-light.o
+obj-$(CONFIG_I2C_PASEMI)       += i2c-pasemi.o
 obj-$(CONFIG_I2C_PCA_ISA)      += i2c-pca-isa.o
 obj-$(CONFIG_I2C_PIIX4)                += i2c-piix4.o
 obj-$(CONFIG_I2C_PNX)          += i2c-pnx.o
index e75d339a3481e9dcd03acb7dda20d14ba73352ae..0b0a87b8d1079f2755a3bfd902d1cb6e4a130f53 100644 (file)
@@ -475,6 +475,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter ali1535_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_ALI1535,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
index 8e1e3f8e40a41faff644d63072271edf409dba25..6b68074e518a072d1239c1e1f8ba61287cc4b456 100644 (file)
@@ -314,35 +314,11 @@ static u32 ali1563_func(struct i2c_adapter * a)
 }
 
 
-static void ali1563_enable(struct pci_dev * dev)
-{
-       u16 ctrl;
-
-       pci_read_config_word(dev,ALI1563_SMBBA,&ctrl);
-       ctrl |= 0x7;
-       pci_write_config_word(dev,ALI1563_SMBBA,ctrl);
-}
-
 static int __devinit ali1563_setup(struct pci_dev * dev)
 {
        u16 ctrl;
 
        pci_read_config_word(dev,ALI1563_SMBBA,&ctrl);
-       printk("ali1563: SMBus control = %04x\n",ctrl);
-
-       /* Check if device is even enabled first */
-       if (!(ctrl & ALI1563_SMB_IOEN)) {
-               dev_warn(&dev->dev,"I/O space not enabled, trying manually\n");
-               ali1563_enable(dev);
-       }
-       if (!(ctrl & ALI1563_SMB_IOEN)) {
-               dev_warn(&dev->dev,"I/O space still not enabled, giving up\n");
-               goto Err;
-       }
-       if (!(ctrl & ALI1563_SMB_HOSTEN)) {
-               dev_warn(&dev->dev,"Host Controller not enabled\n");
-               goto Err;
-       }
 
        /* SMB I/O Base in high 12 bits and must be aligned with the
         * size of the I/O space. */
@@ -351,11 +327,31 @@ static int __devinit ali1563_setup(struct pci_dev * dev)
                dev_warn(&dev->dev,"ali1563_smba Uninitialized\n");
                goto Err;
        }
+
+       /* Check if device is enabled */
+       if (!(ctrl & ALI1563_SMB_HOSTEN)) {
+               dev_warn(&dev->dev, "Host Controller not enabled\n");
+               goto Err;
+       }
+       if (!(ctrl & ALI1563_SMB_IOEN)) {
+               dev_warn(&dev->dev, "I/O space not enabled, trying manually\n");
+               pci_write_config_word(dev, ALI1563_SMBBA,
+                                     ctrl | ALI1563_SMB_IOEN);
+               pci_read_config_word(dev, ALI1563_SMBBA, &ctrl);
+               if (!(ctrl & ALI1563_SMB_IOEN)) {
+                       dev_err(&dev->dev, "I/O space still not enabled, "
+                               "giving up\n");
+                       goto Err;
+               }
+       }
+
        if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
                            ali1563_pci_driver.name)) {
-               dev_warn(&dev->dev,"Could not allocate I/O space");
+               dev_err(&dev->dev, "Could not allocate I/O space at 0x%04x\n",
+                       ali1563_smba);
                goto Err;
        }
+       dev_info(&dev->dev, "Found ALi1563 SMBus at 0x%04x\n", ali1563_smba);
 
        return 0;
 Err:
@@ -374,6 +370,7 @@ static const struct i2c_algorithm ali1563_algorithm = {
 
 static struct i2c_adapter ali1563_adapter = {
        .owner  = THIS_MODULE,
+       .id     = I2C_HW_SMBUS_ALI1563,
        .class  = I2C_CLASS_HWMON,
        .algo   = &ali1563_algorithm,
 };
@@ -384,13 +381,18 @@ static int __devinit ali1563_probe(struct pci_dev * dev,
        int error;
 
        if ((error = ali1563_setup(dev)))
-               return error;
+               goto exit;
        ali1563_adapter.dev.parent = &dev->dev;
        sprintf(ali1563_adapter.name,"SMBus ALi 1563 Adapter @ %04x",
                ali1563_smba);
        if ((error = i2c_add_adapter(&ali1563_adapter)))
-               ali1563_shutdown(dev);
-       printk("%s: Returning %d\n",__FUNCTION__,error);
+               goto exit_shutdown;
+       return 0;
+
+exit_shutdown:
+       ali1563_shutdown(dev);
+exit:
+       dev_warn(&dev->dev, "ALi1563 SMBus probe failed (%d)\n", error);
        return error;
 }
 
index 3f11b6e1a3418c5bc5dad86681b7eae67c429af7..c537441ac0383ca825ca60b15bfae9d8bcd08b47 100644 (file)
@@ -470,6 +470,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter ali15x3_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_ALI15X3,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
index 08e915730caf94505e44bd27845c193c50dd394f..e5e96c8175660b15f006d9517a2866248e5a4a62 100644 (file)
@@ -184,12 +184,14 @@ static int __init amd756_s4882_init(void)
        s4882_algo[0].smbus_xfer = amd756_access_virt0;
        s4882_adapter[0] = amd756_smbus;
        s4882_adapter[0].algo = s4882_algo;
+       s4882_adapter[0].dev.parent = amd756_smbus.dev.parent;
        for (i = 1; i < 5; i++) {
                s4882_algo[i] = *(amd756_smbus.algo);
                s4882_adapter[i] = amd756_smbus;
                sprintf(s4882_adapter[i].name,
                        "SMBus 8111 adapter (CPU%d)", i-1);
                s4882_adapter[i].algo = s4882_algo+i;
+               s4882_adapter[i].dev.parent = amd756_smbus.dev.parent;
        }
        s4882_algo[1].smbus_xfer = amd756_access_virt1;
        s4882_algo[2].smbus_xfer = amd756_access_virt2;
index 2d21afdc5b1cc7f3961c3e4f480de0444ec4292f..91fbc0ee439cc85b94b30fb3818b53790a164bb3 100644 (file)
@@ -301,6 +301,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 struct i2c_adapter amd756_smbus = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_AMD756,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
index 0fbc7186c91ab63f8ac8f6b32365db3a850efc6f..14ad9912f204550e88624e7b643c782f1e2f6af8 100644 (file)
@@ -76,7 +76,8 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
                udelay(1);
 
        if (!timeout) {
-               dev_warn(&smbus->dev->dev, "Timeout while waiting for IBF to clear\n");
+               dev_warn(&smbus->dev->dev,
+                        "Timeout while waiting for IBF to clear\n");
                return -1;
        }
 
@@ -91,14 +92,16 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
                udelay(1);
 
        if (!timeout) {
-               dev_warn(&smbus->dev->dev, "Timeout while waiting for OBF to set\n");
+               dev_warn(&smbus->dev->dev,
+                        "Timeout while waiting for OBF to set\n");
                return -1;
        }
 
        return 0;
 }
 
-static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address, unsigned char *data)
+static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
+               unsigned char *data)
 {
        if (amd_ec_wait_write(smbus))
                return -1;
@@ -115,7 +118,8 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
        return 0;
 }
 
-static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address, unsigned char data)
+static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
+               unsigned char data)
 {
        if (amd_ec_wait_write(smbus))
                return -1;
@@ -175,18 +179,19 @@ static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
 #define AMD_SMB_PRTCL_PEC              0x80
 
 
-static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-               char read_write, u8 command, int size, union i2c_smbus_data * data)
+static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
+               unsigned short flags, char read_write, u8 command, int size,
+               union i2c_smbus_data * data)
 {
        struct amd_smbus *smbus = adap->algo_data;
        unsigned char protocol, len, pec, temp[2];
        int i;
 
-       protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ : AMD_SMB_PRTCL_WRITE;
+       protocol = (read_write == I2C_SMBUS_READ) ? AMD_SMB_PRTCL_READ
+                                                 : AMD_SMB_PRTCL_WRITE;
        pec = (flags & I2C_CLIENT_PEC) ? AMD_SMB_PRTCL_PEC : 0;
 
        switch (size) {
-
                case I2C_SMBUS_QUICK:
                        protocol |= AMD_SMB_PRTCL_QUICK;
                        read_write = I2C_SMBUS_WRITE;
@@ -208,8 +213,10 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                case I2C_SMBUS_WORD_DATA:
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        if (read_write == I2C_SMBUS_WRITE) {
-                               amd_ec_write(smbus, AMD_SMB_DATA, data->word);
-                               amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8);
+                               amd_ec_write(smbus, AMD_SMB_DATA,
+                                            data->word & 0xff);
+                               amd_ec_write(smbus, AMD_SMB_DATA + 1,
+                                            data->word >> 8);
                        }
                        protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
                        break;
@@ -217,27 +224,31 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                case I2C_SMBUS_BLOCK_DATA:
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        if (read_write == I2C_SMBUS_WRITE) {
-                               len = min_t(u8, data->block[0], 32);
+                               len = min_t(u8, data->block[0],
+                                           I2C_SMBUS_BLOCK_MAX);
                                amd_ec_write(smbus, AMD_SMB_BCNT, len);
                                for (i = 0; i < len; i++)
-                                       amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
+                                       amd_ec_write(smbus, AMD_SMB_DATA + i,
+                                                    data->block[i + 1]);
                        }
                        protocol |= AMD_SMB_PRTCL_BLOCK_DATA | pec;
                        break;
 
                case I2C_SMBUS_I2C_BLOCK_DATA:
-                       len = min_t(u8, data->block[0], 32);
+                       len = min_t(u8, data->block[0],
+                                   I2C_SMBUS_BLOCK_MAX);
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        amd_ec_write(smbus, AMD_SMB_BCNT, len);
                        if (read_write == I2C_SMBUS_WRITE)
                                for (i = 0; i < len; i++)
-                                       amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
+                                       amd_ec_write(smbus, AMD_SMB_DATA + i,
+                                                    data->block[i + 1]);
                        protocol |= AMD_SMB_PRTCL_I2C_BLOCK_DATA;
                        break;
 
                case I2C_SMBUS_PROC_CALL:
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
-                       amd_ec_write(smbus, AMD_SMB_DATA, data->word);
+                       amd_ec_write(smbus, AMD_SMB_DATA, data->word & 0xff);
                        amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8);
                        protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
                        read_write = I2C_SMBUS_READ;
@@ -248,7 +259,8 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                        amd_ec_write(smbus, AMD_SMB_CMD, command);
                        amd_ec_write(smbus, AMD_SMB_BCNT, len);
                        for (i = 0; i < len; i++)
-                               amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
+                               amd_ec_write(smbus, AMD_SMB_DATA + i,
+                                            data->block[i + 1]);
                        protocol = AMD_SMB_PRTCL_BLOCK_PROC_CALL | pec;
                        read_write = I2C_SMBUS_READ;
                        break;
@@ -280,7 +292,6 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                return 0;
 
        switch (size) {
-
                case I2C_SMBUS_BYTE:
                case I2C_SMBUS_BYTE_DATA:
                        amd_ec_read(smbus, AMD_SMB_DATA, &data->byte);
@@ -296,10 +307,11 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
                case I2C_SMBUS_BLOCK_DATA:
                case I2C_SMBUS_BLOCK_PROC_CALL:
                        amd_ec_read(smbus, AMD_SMB_BCNT, &len);
-                       len = min_t(u8, len, 32);
+                       len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
                case I2C_SMBUS_I2C_BLOCK_DATA:
                        for (i = 0; i < len; i++)
-                               amd_ec_read(smbus, AMD_SMB_DATA + i, data->block + i + 1);
+                               amd_ec_read(smbus, AMD_SMB_DATA + i,
+                                           data->block + i + 1);
                        data->block[0] = len;
                        break;
        }
@@ -310,7 +322,8 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short fl
 
 static u32 amd8111_func(struct i2c_adapter *adapter)
 {
-       return  I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
+       return  I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+               I2C_FUNC_SMBUS_BYTE_DATA |
                I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
                I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
                I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC;
@@ -329,12 +342,13 @@ static struct pci_device_id amd8111_ids[] = {
 
 MODULE_DEVICE_TABLE (pci, amd8111_ids);
 
-static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit amd8111_probe(struct pci_dev *dev,
+               const struct pci_device_id *id)
 {
        struct amd_smbus *smbus;
-       int error = -ENODEV;
+       int error;
 
-       if (~pci_resource_flags(dev, 0) & IORESOURCE_IO)
+       if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
                return -ENODEV;
 
        smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL);
@@ -345,12 +359,15 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
        smbus->base = pci_resource_start(dev, 0);
        smbus->size = pci_resource_len(dev, 0);
 
-       if (!request_region(smbus->base, smbus->size, amd8111_driver.name))
+       if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
+               error = -EBUSY;
                goto out_kfree;
+       }
 
        smbus->adapter.owner = THIS_MODULE;
        snprintf(smbus->adapter.name, I2C_NAME_SIZE,
                "SMBus2 AMD8111 adapter at %04x", smbus->base);
+       smbus->adapter.id = I2C_HW_SMBUS_AMD8111;
        smbus->adapter.class = I2C_CLASS_HWMON;
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
@@ -358,11 +375,11 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
        /* set up the driverfs linkage to our parent device */
        smbus->adapter.dev.parent = &dev->dev;
 
+       pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
        error = i2c_add_adapter(&smbus->adapter);
        if (error)
                goto out_release_region;
 
-       pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
        pci_set_drvdata(dev, smbus);
        return 0;
 
@@ -370,10 +387,9 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
        release_region(smbus->base, smbus->size);
  out_kfree:
        kfree(smbus);
-       return -1;
+       return error;
 }
 
-
 static void __devexit amd8111_remove(struct pci_dev *dev)
 {
        struct amd_smbus *smbus = pci_get_drvdata(dev);
@@ -395,7 +411,6 @@ static int __init i2c_amd8111_init(void)
        return pci_register_driver(&amd8111_driver);
 }
 
-
 static void __exit i2c_amd8111_exit(void)
 {
        pci_unregister_driver(&amd8111_driver);
index ae625b85447074ee958e734ece3c3761bc4022a2..8c3569a9775b79d1d9cb935c505abd07856a3669 100644 (file)
@@ -123,7 +123,7 @@ static int i801_transaction(void)
                        dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
                        return -1;
                } else {
-                       dev_dbg(&I801_dev->dev, "Successfull!\n");
+                       dev_dbg(&I801_dev->dev, "Successful!\n");
                }
        }
 
@@ -442,6 +442,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter i801_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_I801,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
index 10c98bc88aa6c57465299165f245eaf5270f6469..42e8d94c276fde7e278016aef70d6ffdf23e2baa 100644 (file)
@@ -171,6 +171,7 @@ static struct i2c_algo_bit_data i810_i2c_bit_data = {
 
 static struct i2c_adapter i810_i2c_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_B_I810,
        .name           = "I810/I815 I2C Adapter",
        .algo_data      = &i810_i2c_bit_data,
 };
@@ -186,6 +187,7 @@ static struct i2c_algo_bit_data i810_ddc_bit_data = {
 
 static struct i2c_adapter i810_ddc_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_B_I810,
        .name           = "I810/I815 DDC Adapter",
        .algo_data      = &i810_ddc_bit_data,
 };
index 1898e9987021606c78af90c3b97869066355aa7d..8b14d14e60cad3e3cd1099df6d221dc6ab1b475e 100644 (file)
@@ -727,6 +727,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){
        
        /* Register it with i2c layer */
        adap = &dev->adap;
+       adap->dev.parent = &ocp->dev;
        strcpy(adap->name, "IBM IIC");
        i2c_set_adapdata(adap, dev);
        adap->id = I2C_HW_OCP;
index 8ed59a2dff532124afc6e899f1df3d6a4622f106..5f33bc9c1e02ba7c134121c5beb8880c51f79eb3 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/i2c.h>
 #include <linux/i2c-isa.h>
 #include <linux/platform_device.h>
+#include <linux/completion.h>
 
 static u32 isa_func(struct i2c_adapter *adapter);
 
index 490173611d6b615013b2d87a7984af9aec7b04d2..a3283b907eb87a947fe30979e27867c34811cfaf 100644 (file)
@@ -520,6 +520,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
                rc = -ENXIO;
                goto exit_unmap_regs;
        }
+       drv_data->adapter.dev.parent = &pd->dev;
        drv_data->adapter.id = I2C_HW_MV64XXX;
        drv_data->adapter.algo = &mv64xxx_i2c_algo;
        drv_data->adapter.owner = THIS_MODULE;
index ad37c10e7fec38aaea6e2103647f5c0ca895e5ab..653555184a6467d19db716ca7cd4ff97a8ef71dc 100644 (file)
@@ -57,7 +57,6 @@ MODULE_DESCRIPTION("nForce2/3/4/5xx SMBus driver");
 
 
 struct nforce2_smbus {
-       struct pci_dev *dev;
        struct i2c_adapter adapter;
        int base;
        int size;
@@ -230,7 +229,6 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
                smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
                smbus->size = 64;
        }
-       smbus->dev = dev;
 
        if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
                dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
@@ -238,6 +236,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
                return -1;
        }
        smbus->adapter.owner = THIS_MODULE;
+       smbus->adapter.id = I2C_HW_SMBUS_NFORCE2;
        smbus->adapter.class = I2C_CLASS_HWMON;
        smbus->adapter.algo = &smbus_algorithm;
        smbus->adapter.algo_data = smbus;
index 9ddd816d5d0f6609eec3ecddf640f15e2839e24e..ed69d846cb950c18248c5b5d1a3d4335f872efc3 100644 (file)
@@ -88,6 +88,13 @@ static struct adapter_parm adapter_parm[] = {
                .getscl = { 0x40, STAT, 0 },
                .init   = { 0xfc, DATA, 0 },
        },
+       /* type 7: One For All JP1 parallel port adapter */
+       {
+               .setsda = { 0x01, DATA, 0 },
+               .setscl = { 0x02, DATA, 0 },
+               .getsda = { 0x80, STAT, 1 },
+               .init   = { 0x04, DATA, 1 },
+       },
 };
 
 static int type = -1;
@@ -101,4 +108,5 @@ MODULE_PARM_DESC(type,
        " 4 = ADM1032 evaluation board\n"
        " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"
        " 6 = Barco LPT->DVI (K5800236) adapter\n"
+       " 7 = One For All JP1 parallel port adapter\n"
 );
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c
new file mode 100644 (file)
index 0000000..f54fb5d
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2006-2007 PA Semi, Inc
+ *
+ * SMBus host driver for PA Semi PWRficient
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+static struct pci_driver pasemi_smb_driver;
+
+struct pasemi_smbus {
+       struct pci_dev          *dev;
+       struct i2c_adapter       adapter;
+       unsigned long            base;
+       int                      size;
+};
+
+/* Register offsets */
+#define REG_MTXFIFO    0x00
+#define REG_MRXFIFO    0x04
+#define REG_SMSTA      0x14
+#define REG_CTL                0x1c
+
+/* Register defs */
+#define MTXFIFO_READ   0x00000400
+#define MTXFIFO_STOP   0x00000200
+#define MTXFIFO_START  0x00000100
+#define MTXFIFO_DATA_M 0x000000ff
+
+#define MRXFIFO_EMPTY  0x00000100
+#define MRXFIFO_DATA_M 0x000000ff
+
+#define SMSTA_XEN      0x08000000
+
+#define CTL_MRR                0x00000400
+#define CTL_MTR                0x00000200
+#define CTL_CLK_M      0x000000ff
+
+#define CLK_100K_DIV   84
+#define CLK_400K_DIV   21
+
+static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
+{
+       dev_dbg(&smbus->dev->dev, "smbus write reg %lx val %08x\n",
+               smbus->base + reg, val);
+       outl(val, smbus->base + reg);
+}
+
+static inline int reg_read(struct pasemi_smbus *smbus, int reg)
+{
+       int ret;
+       ret = inl(smbus->base + reg);
+       dev_dbg(&smbus->dev->dev, "smbus read reg %lx val %08x\n",
+               smbus->base + reg, ret);
+       return ret;
+}
+
+#define TXFIFO_WR(smbus, reg)  reg_write((smbus), REG_MTXFIFO, (reg))
+#define RXFIFO_RD(smbus)       reg_read((smbus), REG_MRXFIFO)
+
+static void pasemi_smb_clear(struct pasemi_smbus *smbus)
+{
+       unsigned int status;
+
+       status = reg_read(smbus, REG_SMSTA);
+       reg_write(smbus, REG_SMSTA, status);
+}
+
+static unsigned int pasemi_smb_waitready(struct pasemi_smbus *smbus)
+{
+       int timeout = 10;
+       unsigned int status;
+
+       status = reg_read(smbus, REG_SMSTA);
+
+       while (!(status & SMSTA_XEN) && timeout--) {
+               msleep(1);
+               status = reg_read(smbus, REG_SMSTA);
+       }
+
+       if (timeout < 0) {
+               dev_warn(&smbus->dev->dev, "Timeout, status 0x%08x\n", status);
+               reg_write(smbus, REG_SMSTA, status);
+               return -ETIME;
+       }
+
+       /* Clear XEN */
+       reg_write(smbus, REG_SMSTA, SMSTA_XEN);
+
+       return 0;
+}
+
+static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter,
+                              struct i2c_msg *msg, int stop)
+{
+       struct pasemi_smbus *smbus = adapter->algo_data;
+       int read, i, err;
+       u32 rd;
+
+       read = msg->flags & I2C_M_RD ? 1 : 0;
+
+       TXFIFO_WR(smbus, MTXFIFO_START | (msg->addr << 1) | read);
+
+       if (read) {
+               TXFIFO_WR(smbus, msg->len | MTXFIFO_READ |
+                                (stop ? MTXFIFO_STOP : 0));
+
+               err = pasemi_smb_waitready(smbus);
+               if (err)
+                       goto reset_out;
+
+               for (i = 0; i < msg->len; i++) {
+                       rd = RXFIFO_RD(smbus);
+                       if (rd & MRXFIFO_EMPTY) {
+                               err = -ENODATA;
+                               goto reset_out;
+                       }
+                       msg->buf[i] = rd & MRXFIFO_DATA_M;
+               }
+       } else {
+               for (i = 0; i < msg->len - 1; i++)
+                       TXFIFO_WR(smbus, msg->buf[i]);
+
+               TXFIFO_WR(smbus, msg->buf[msg->len] |
+                         (stop ? MTXFIFO_STOP : 0));
+       }
+
+       return 0;
+
+ reset_out:
+       reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
+                 (CLK_100K_DIV & CTL_CLK_M)));
+       return err;
+}
+
+static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
+                          struct i2c_msg *msgs, int num)
+{
+       struct pasemi_smbus *smbus = adapter->algo_data;
+       int ret, i;
+
+       pasemi_smb_clear(smbus);
+
+       ret = 0;
+
+       for (i = 0; i < num && !ret; i++)
+               ret = pasemi_i2c_xfer_msg(adapter, &msgs[i], (i == (num - 1)));
+
+       return ret ? ret : num;
+}
+
+static int pasemi_smb_xfer(struct i2c_adapter *adapter,
+               u16 addr, unsigned short flags, char read_write, u8 command,
+               int size, union i2c_smbus_data *data)
+{
+       struct pasemi_smbus *smbus = adapter->algo_data;
+       unsigned int rd;
+       int read_flag, err;
+       int len = 0, i;
+
+       /* All our ops take 8-bit shifted addresses */
+       addr <<= 1;
+       read_flag = read_write == I2C_SMBUS_READ;
+
+       pasemi_smb_clear(smbus);
+
+       switch (size) {
+       case I2C_SMBUS_QUICK:
+               TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START |
+                         MTXFIFO_STOP);
+               break;
+       case I2C_SMBUS_BYTE:
+               TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START);
+               if (read_write)
+                       TXFIFO_WR(smbus, 1 | MTXFIFO_STOP | MTXFIFO_READ);
+               else
+                       TXFIFO_WR(smbus, MTXFIFO_STOP | command);
+               break;
+       case I2C_SMBUS_BYTE_DATA:
+               TXFIFO_WR(smbus, addr | MTXFIFO_START);
+               TXFIFO_WR(smbus, command);
+               if (read_write) {
+                       TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
+                       TXFIFO_WR(smbus, 1 | MTXFIFO_READ | MTXFIFO_STOP);
+               } else {
+                       TXFIFO_WR(smbus, MTXFIFO_STOP | data->byte);
+               }
+               break;
+       case I2C_SMBUS_WORD_DATA:
+               TXFIFO_WR(smbus, addr | MTXFIFO_START);
+               TXFIFO_WR(smbus, command);
+               if (read_write) {
+                       TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
+                       TXFIFO_WR(smbus, 2 | MTXFIFO_READ | MTXFIFO_STOP);
+               } else {
+                       TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
+                       TXFIFO_WR(smbus, MTXFIFO_STOP | (data->word >> 8));
+               }
+               break;
+       case I2C_SMBUS_BLOCK_DATA:
+               TXFIFO_WR(smbus, addr | MTXFIFO_START);
+               TXFIFO_WR(smbus, command);
+               if (read_write) {
+                       TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
+                       TXFIFO_WR(smbus, 1 | MTXFIFO_READ);
+                       rd = RXFIFO_RD(smbus);
+                       len = min_t(u8, (rd & MRXFIFO_DATA_M),
+                                   I2C_SMBUS_BLOCK_MAX);
+                       TXFIFO_WR(smbus, (len + 1) | MTXFIFO_READ |
+                                        MTXFIFO_STOP);
+               } else {
+                       len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX);
+                       TXFIFO_WR(smbus, len);
+                       for (i = 1; i < len; i++)
+                               TXFIFO_WR(smbus, data->block[i]);
+                       TXFIFO_WR(smbus, data->block[len] | MTXFIFO_STOP);
+               }
+               break;
+       case I2C_SMBUS_PROC_CALL:
+               read_write = I2C_SMBUS_READ;
+               TXFIFO_WR(smbus, addr | MTXFIFO_START);
+               TXFIFO_WR(smbus, command);
+               TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
+               TXFIFO_WR(smbus, (data->word >> 8) & MTXFIFO_DATA_M);
+               TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
+               TXFIFO_WR(smbus, 2 | MTXFIFO_STOP | MTXFIFO_READ);
+               break;
+       case I2C_SMBUS_BLOCK_PROC_CALL:
+               len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX - 1);
+               read_write = I2C_SMBUS_READ;
+               TXFIFO_WR(smbus, addr | MTXFIFO_START);
+               TXFIFO_WR(smbus, command);
+               TXFIFO_WR(smbus, len);
+               for (i = 1; i <= len; i++)
+                       TXFIFO_WR(smbus, data->block[i]);
+               TXFIFO_WR(smbus, addr | I2C_SMBUS_READ);
+               TXFIFO_WR(smbus, MTXFIFO_READ | 1);
+               rd = RXFIFO_RD(smbus);
+               len = min_t(u8, (rd & MRXFIFO_DATA_M),
+                           I2C_SMBUS_BLOCK_MAX - len);
+               TXFIFO_WR(smbus, (len + 1) | MTXFIFO_READ | MTXFIFO_STOP);
+               break;
+
+       default:
+               dev_warn(&adapter->dev, "Unsupported transaction %d\n", size);
+               return -EINVAL;
+       }
+
+       err = pasemi_smb_waitready(smbus);
+       if (err)
+               goto reset_out;
+
+       if (read_write == I2C_SMBUS_WRITE)
+               return 0;
+
+       switch (size) {
+       case I2C_SMBUS_BYTE:
+       case I2C_SMBUS_BYTE_DATA:
+               rd = RXFIFO_RD(smbus);
+               if (rd & MRXFIFO_EMPTY) {
+                       err = -ENODATA;
+                       goto reset_out;
+               }
+               data->byte = rd & MRXFIFO_DATA_M;
+               break;
+       case I2C_SMBUS_WORD_DATA:
+       case I2C_SMBUS_PROC_CALL:
+               rd = RXFIFO_RD(smbus);
+               if (rd & MRXFIFO_EMPTY) {
+                       err = -ENODATA;
+                       goto reset_out;
+               }
+               data->word = rd & MRXFIFO_DATA_M;
+               rd = RXFIFO_RD(smbus);
+               if (rd & MRXFIFO_EMPTY) {
+                       err = -ENODATA;
+                       goto reset_out;
+               }
+               data->word |= (rd & MRXFIFO_DATA_M) << 8;
+               break;
+       case I2C_SMBUS_BLOCK_DATA:
+       case I2C_SMBUS_BLOCK_PROC_CALL:
+               data->block[0] = len;
+               for (i = 1; i <= len; i ++) {
+                       rd = RXFIFO_RD(smbus);
+                       if (rd & MRXFIFO_EMPTY) {
+                               err = -ENODATA;
+                               goto reset_out;
+                       }
+                       data->block[i] = rd & MRXFIFO_DATA_M;
+               }
+               break;
+       }
+
+       return 0;
+
+ reset_out:
+       reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
+                 (CLK_100K_DIV & CTL_CLK_M)));
+       return err;
+}
+
+static u32 pasemi_smb_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+              I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+              I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
+              I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_I2C;
+}
+
+static const struct i2c_algorithm smbus_algorithm = {
+       .master_xfer    = pasemi_i2c_xfer,
+       .smbus_xfer     = pasemi_smb_xfer,
+       .functionality  = pasemi_smb_func,
+};
+
+static int __devinit pasemi_smb_probe(struct pci_dev *dev,
+                                     const struct pci_device_id *id)
+{
+       struct pasemi_smbus *smbus;
+       int error;
+
+       if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
+               return -ENODEV;
+
+       smbus = kzalloc(sizeof(struct pasemi_smbus), GFP_KERNEL);
+       if (!smbus)
+               return -ENOMEM;
+
+       smbus->dev = dev;
+       smbus->base = pci_resource_start(dev, 0);
+       smbus->size = pci_resource_len(dev, 0);
+
+       if (!request_region(smbus->base, smbus->size,
+                           pasemi_smb_driver.name)) {
+               error = -EBUSY;
+               goto out_kfree;
+       }
+
+       smbus->adapter.owner = THIS_MODULE;
+       snprintf(smbus->adapter.name, I2C_NAME_SIZE,
+                "PA Semi SMBus adapter at 0x%lx", smbus->base);
+       smbus->adapter.class = I2C_CLASS_HWMON;
+       smbus->adapter.algo = &smbus_algorithm;
+       smbus->adapter.algo_data = smbus;
+
+       /* set up the driverfs linkage to our parent device */
+       smbus->adapter.dev.parent = &dev->dev;
+
+       reg_write(smbus, REG_CTL, (CTL_MTR | CTL_MRR |
+                 (CLK_100K_DIV & CTL_CLK_M)));
+
+       error = i2c_add_adapter(&smbus->adapter);
+       if (error)
+               goto out_release_region;
+
+       pci_set_drvdata(dev, smbus);
+
+       return 0;
+
+ out_release_region:
+       release_region(smbus->base, smbus->size);
+ out_kfree:
+       kfree(smbus);
+       return error;
+}
+
+static void __devexit pasemi_smb_remove(struct pci_dev *dev)
+{
+       struct pasemi_smbus *smbus = pci_get_drvdata(dev);
+
+       i2c_del_adapter(&smbus->adapter);
+       release_region(smbus->base, smbus->size);
+       kfree(smbus);
+}
+
+static struct pci_device_id pasemi_smb_ids[] = {
+       { PCI_DEVICE(0x1959, 0xa003) },
+       { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, pasemi_smb_ids);
+
+static struct pci_driver pasemi_smb_driver = {
+       .name           = "i2c-pasemi",
+       .id_table       = pasemi_smb_ids,
+       .probe          = pasemi_smb_probe,
+       .remove         = __devexit_p(pasemi_smb_remove),
+};
+
+static int __init pasemi_smb_init(void)
+{
+       return pci_register_driver(&pasemi_smb_driver);
+}
+
+static void __exit pasemi_smb_exit(void)
+{
+       pci_unregister_driver(&pasemi_smb_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
+MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");
+
+module_init(pasemi_smb_init);
+module_exit(pasemi_smb_exit);
index 30c7a1b38cbd7e5202106b8f060bb55a83f29e5d..03d0aeea0189baadf42de61c5fecc44cb5de9087 100644 (file)
@@ -23,6 +23,7 @@
    Supports:
        Intel PIIX4, 440MX
        Serverworks OSB4, CSB5, CSB6, HT-1000
+       ATI IXP200, IXP300, IXP400, SB600
        SMSC Victory66
 
    Note: we assume there can only be one device, with one SMBus interface.
@@ -383,6 +384,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter piix4_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_PIIX4,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
@@ -396,6 +398,8 @@ static struct pci_device_id piix4_ids[] = {
          .driver_data = 0 },
        { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_SMBUS),
          .driver_data = 0 },
+       { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SMBUS),
+         .driver_data = 0 },
        { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4),
          .driver_data = 0 },
        { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5),
index 648d55533d87e1a53a9b1d6a58bd21a7f17a77ab..1425d2245c827f8f9a103a3f74dfb3a7cfb70df3 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
-#include <linux/completion.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <asm/prom.h>
index 844b4ff908934895d5be8e8f58162b1e3b28f6ca..b7fb65c301124eb54e786bc5ef33153737028f06 100644 (file)
@@ -145,6 +145,7 @@ static struct i2c_algo_bit_data sav_i2c_bit_data = {
 
 static struct i2c_adapter savage4_i2c_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_B_SAVAGE,
        .name           = "I2C Savage4 adapter",
        .algo_data      = &sav_i2c_bit_data,
 };
index 38bbfd840b6b181c51aab35856ceebfdfb737cdf..d333babe4ad36161a860967e5624519f4c1ec4ba 100644 (file)
@@ -365,6 +365,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter sis5595_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_SIS5595,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
index dec0bafb52ab5cd5f241b7675800048a790c7cd8..172bacf932a6807c21333f2cb3b594b8ed47b855 100644 (file)
@@ -457,6 +457,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter sis630_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_SIS630,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
index 7fd07fbac33681c3f81f49e66acad11660aa3533..869a635d37e9d5d3a6da7e93f777609a61bc5f4a 100644 (file)
@@ -249,6 +249,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter sis96x_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_SIS96X,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
index 15d7e00e47e6a7b3edb93d9321eefdcee01f6847..bbcc62151f7c4cf542478bcf6ee8768254aaba64 100644 (file)
@@ -86,6 +86,7 @@ static struct i2c_algo_bit_data bit_data = {
 
 static struct i2c_adapter vt586b_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_B_VIA,
        .class          = I2C_CLASS_HWMON,
        .name           = "VIA i2c",
        .algo_data      = &bit_data,
index efc6bbf0cc0a49818b569208f92f92062acefaf2..03c5fc868548d3d121aca6d879b06e13031594c2 100644 (file)
@@ -4,7 +4,7 @@
     Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
     Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
     Mark D. Studebaker <mdsxyz123@yahoo.com>
-    Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+    Copyright (C) 2005 - 2007  Jean Delvare <khali@linux-fr.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
@@ -36,6 +36,7 @@
    VT8237R            0x3227             yes
    VT8237A            0x3337             yes
    VT8251             0x3287             yes
+   CX700              0x8324             yes
 
    Note: we assume there can only be one device, with one SMBus interface.
 */
@@ -306,6 +307,7 @@ static const struct i2c_algorithm smbus_algorithm = {
 
 static struct i2c_adapter vt596_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_SMBUS_VIA2,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
 };
@@ -383,6 +385,7 @@ found:
        dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
 
        switch (pdev->device) {
+       case PCI_DEVICE_ID_VIA_CX700:
        case PCI_DEVICE_ID_VIA_8251:
        case PCI_DEVICE_ID_VIA_8237:
        case PCI_DEVICE_ID_VIA_8237A:
@@ -442,6 +445,8 @@ static struct pci_device_id vt596_ids[] = {
          .driver_data = SMBBA1 },
        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8251),
          .driver_data = SMBBA3 },
+       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700),
+         .driver_data = SMBBA3 },
        { 0, }
 };
 
index b0377b81744bcc4d525460b9a8ca8e2eb839d8e2..88a3447e11e1eaf47fb9ddc0b29fc0ab8fb0048f 100644 (file)
@@ -165,6 +165,7 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = {
 
 static struct i2c_adapter voodoo3_i2c_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_B_VOO,
        .class          = I2C_CLASS_TV_ANALOG, 
        .name           = "I2C Voodoo3/Banshee adapter",
        .algo_data      = &voo_i2c_bit_data,
@@ -181,6 +182,7 @@ static struct i2c_algo_bit_data voo_ddc_bit_data = {
 
 static struct i2c_adapter voodoo3_ddc_adapter = {
        .owner          = THIS_MODULE,
+       .id             = I2C_HW_B_VOO,
        .class          = I2C_CLASS_DDC, 
        .name           = "DDC Voodoo3/Banshee adapter",
        .algo_data      = &voo_ddc_bit_data,
index 714bae780953c821792ec410597411f722c7df87..0b082c5a01956d7e98b52329ad920b69693793e3 100644 (file)
@@ -428,7 +428,7 @@ static __init int scx200_acb_probe(struct scx200_acb_iface *iface)
 }
 
 static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
-               int index)
+               struct device *dev, int index)
 {
        struct scx200_acb_iface *iface;
        struct i2c_adapter *adapter;
@@ -446,6 +446,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text,
        adapter->id = I2C_HW_SMBUS_SCX200;
        adapter->algo = &scx200_acb_algorithm;
        adapter->class = I2C_CLASS_HWMON;
+       adapter->dev.parent = dev;
 
        mutex_init(&iface->mutex);
 
@@ -486,7 +487,7 @@ static __init int scx200_create_pci(const char *text, struct pci_dev *pdev,
        struct scx200_acb_iface *iface;
        int rc;
 
-       iface = scx200_create_iface(text, 0);
+       iface = scx200_create_iface(text, &pdev->dev, 0);
 
        if (iface == NULL)
                return -ENOMEM;
@@ -524,7 +525,7 @@ static int __init scx200_create_isa(const char *text, unsigned long base,
        struct scx200_acb_iface *iface;
        int rc;
 
-       iface = scx200_create_iface(text, index);
+       iface = scx200_create_iface(text, NULL, index);
 
        if (iface == NULL)
                return -ENOMEM;
index 6cd96e43aa72a9d50ebbc8eb8a66c327bca761dc..c3022a023449ec2012b7911c0be94d8f7446869b 100644 (file)
@@ -81,6 +81,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
 
 static struct i2c_adapter scx200_i2c_ops = {
        .owner             = THIS_MODULE,
+       .id                = I2C_HW_B_SCX200,
        .algo_data         = &scx200_i2c_data,
        .name   = "NatSemi SCx200 I2C",
 };
index b05378a3d673fb67de094c3c0e4c33e9c7836d87..21fe1406c8b4276b6c0faca6c0ba00826464664c 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/seq_file.h>
 #include <linux/platform_device.h>
 #include <linux/mutex.h>
+#include <linux/completion.h>
 #include <asm/uaccess.h>
 
 
@@ -40,49 +41,72 @@ static LIST_HEAD(drivers);
 static DEFINE_MUTEX(core_lists);
 static DEFINE_IDR(i2c_adapter_idr);
 
+
+/* ------------------------------------------------------------------------- */
+
 /* match always succeeds, as we want the probe() to tell if we really accept this match */
 static int i2c_device_match(struct device *dev, struct device_driver *drv)
 {
        return 1;
 }
 
-static int i2c_bus_suspend(struct device * dev, pm_message_t state)
+static int i2c_device_probe(struct device *dev)
 {
-       int rc = 0;
+       return -ENODEV;
+}
 
-       if (dev->driver && dev->driver->suspend)
-               rc = dev->driver->suspend(dev, state);
-       return rc;
+static int i2c_device_remove(struct device *dev)
+{
+       return 0;
 }
 
-static int i2c_bus_resume(struct device * dev)
+static void i2c_device_shutdown(struct device *dev)
 {
-       int rc = 0;
-       
-       if (dev->driver && dev->driver->resume)
-               rc = dev->driver->resume(dev);
-       return rc;
+       struct i2c_driver *driver;
+
+       if (!dev->driver)
+               return;
+       driver = to_i2c_driver(dev->driver);
+       if (driver->shutdown)
+               driver->shutdown(to_i2c_client(dev));
 }
 
-static int i2c_device_probe(struct device *dev)
+static int i2c_device_suspend(struct device * dev, pm_message_t mesg)
 {
-       return -ENODEV;
+       struct i2c_driver *driver;
+
+       if (!dev->driver)
+               return 0;
+       driver = to_i2c_driver(dev->driver);
+       if (!driver->suspend)
+               return 0;
+       return driver->suspend(to_i2c_client(dev), mesg);
 }
 
-static int i2c_device_remove(struct device *dev)
+static int i2c_device_resume(struct device * dev)
 {
-       return 0;
+       struct i2c_driver *driver;
+
+       if (!dev->driver)
+               return 0;
+       driver = to_i2c_driver(dev->driver);
+       if (!driver->resume)
+               return 0;
+       return driver->resume(to_i2c_client(dev));
 }
 
 struct bus_type i2c_bus_type = {
-       .name =         "i2c",
-       .match =        i2c_device_match,
-       .probe =        i2c_device_probe,
-       .remove =       i2c_device_remove,
-       .suspend =      i2c_bus_suspend,
-       .resume =       i2c_bus_resume,
+       .name           = "i2c",
+       .match          = i2c_device_match,
+       .probe          = i2c_device_probe,
+       .remove         = i2c_device_remove,
+       .shutdown       = i2c_device_shutdown,
+       .suspend        = i2c_device_suspend,
+       .resume         = i2c_device_resume,
 };
 
+/* ------------------------------------------------------------------------- */
+
 void i2c_adapter_dev_release(struct device *dev)
 {
        struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
@@ -193,9 +217,8 @@ int i2c_add_adapter(struct i2c_adapter *adap)
         */
        if (adap->dev.parent == NULL) {
                adap->dev.parent = &platform_bus;
-               printk(KERN_WARNING "**WARNING** I2C adapter driver [%s] "
-                      "forgot to specify physical device; fix it!\n",
-                      adap->name);
+               pr_debug("I2C adapter driver [%s] forgot to specify "
+                        "physical device\n", adap->name);
        }
        sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);
        adap->dev.driver = &i2c_adapter_driver;
index fbb7f14ec5097455c628e08c0b4b4910d557af5e..0742befe92270f0d9557072dc59a6b2771e5197c 100644 (file)
@@ -1434,6 +1434,7 @@ static int __devinit add_card(struct pci_dev *dev,
                 i2c_adapter_data = bit_data;
                 i2c_ad->algo_data = &i2c_adapter_data;
                 i2c_adapter_data.data = lynx;
+               i2c_ad->dev.parent = &dev->dev;
 
                PRINTD(KERN_DEBUG, lynx->id,"original eeprom control: %d",
                       reg_read(lynx, SERIAL_EEPROM_CONTROL));
index e0bd2d8f0f0c92e08235aa9e15db650d43723f21..5347a406fff7e0e73abe885eff3562ca747a10a6 100644 (file)
@@ -190,6 +190,7 @@ int flexcop_i2c_init(struct flexcop_device *fc)
        fc->i2c_adap.class          = I2C_CLASS_TV_DIGITAL;
        fc->i2c_adap.algo       = &flexcop_algo;
        fc->i2c_adap.algo_data  = NULL;
+       fc->i2c_adap.dev.parent = fc->dev;
 
        if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0)
                return ret;
index 55ba020386c97d32db99f288250c5d603a382789..70df31b0a8a9cdecfae95d3f4dea2efc07ad0b5f 100644 (file)
@@ -27,6 +27,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
 #endif
        d->i2c_adap.algo      = d->props.i2c_algo;
        d->i2c_adap.algo_data = NULL;
+       d->i2c_adap.dev.parent = &d->udev->dev;
 
        i2c_set_adapdata(&d->i2c_adap, d);
 
index 60820deb900b3958e2cc0c43faaa1b5360eab34f..b60cdc93d6dbddab7031a69128acb3114c5f9852 100644 (file)
@@ -1690,6 +1690,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
 #endif
        ttusb->i2c_adap.algo              = &ttusb_dec_algo;
        ttusb->i2c_adap.algo_data         = NULL;
+       ttusb->i2c_adap.dev.parent        = &udev->dev;
 
        result = i2c_add_adapter(&ttusb->i2c_adap);
        if (result) {
index fb1410c6f864be4d89e8dd9573787554d68f8e49..4dae8925667f77cd2cbfb9919321b3d00d87d265 100644 (file)
@@ -549,6 +549,7 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
        adap->client_unregister = cafe_smbus_detach;
        adap->algo = &cafe_smbus_algo;
        strcpy(adap->name, "cafe_ccic");
+       adap->dev.parent = &cam->pdev->dev;
        i2c_set_adapdata(adap, cam);
        ret = i2c_add_adapter(adap);
        if (ret)
index f9bb41d8f4f3375896fe3580ad8ac815a6c3b172..62a7cfca837dae7846a5faf299f88ccb4977527e 100644 (file)
@@ -977,6 +977,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
        memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap));
        memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo));
        strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name));
+       hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
        hdw->i2c_adap.algo = &hdw->i2c_algo;
        hdw->i2c_adap.algo_data = hdw;
        hdw->i2c_pend_mask = 0;
index 858252c15084a3d562d3cb1c981e4c8853c6823f..a242b76aea894c8b0b7e16282c063b5733f0fe0d 100644 (file)
@@ -258,6 +258,7 @@ int usbvision_init_i2c(struct usb_usbvision *usbvision)
        sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
                " #%d", usbvision->vdev->minor & 0x1f);
        PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
+       usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
 
        i2c_set_adapdata(&usbvision->i2c_adap, usbvision);
        i2c_set_clientdata(&usbvision->i2c_client, usbvision);
index 6e64af293be58e905b266b12845161f1f7be55d3..8f31613b9903897b52fe42f12c9533559d120a5f 100644 (file)
@@ -1573,6 +1573,7 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam)
 
        memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
        strcpy(cam->i2c_adapter.name, "w9968cf");
+       cam->i2c_adapter.dev.parent = &cam->usbdev->dev;
        i2c_set_adapdata(&cam->i2c_adapter, cam);
 
        DBG(6, "Registering I2C adapter with kernel...")
index 4d1eb2fba34a8c7d5ec8edd30d76adf1376645fc..73162a3a61dd4182c03921c76595fbdcc53b93ec 100644 (file)
@@ -843,6 +843,7 @@ zoran_register_i2c (struct zoran *zr)
                sizeof(I2C_NAME(&zr->i2c_adapter)) - 1);
        i2c_set_adapdata(&zr->i2c_adapter, zr);
        zr->i2c_adapter.algo_data = &zr->i2c_algo;
+       zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
        return i2c_bit_add_bus(&zr->i2c_adapter);
 }
 
index 205fa28593b769820f966ec25e5f122a6745bdaa..dfef1637bfb8a1a69dc1848d75e2b490a458ddaf 100644 (file)
@@ -199,7 +199,7 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
        struct i2c_client *client;
        struct rtc_device *rtc;
 
-       dev_dbg(adapter->class_dev.dev, "%s\n", __FUNCTION__);
+       dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
                err = -ENODEV;
index 038118bbfaea3f512c756414a68e5f27818a1d9c..0242d803ebe5b21d43c42d6954d601ed05372194 100644 (file)
@@ -279,7 +279,7 @@ static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
 
        int err = 0;
 
-       dev_dbg(adapter->class_dev.dev, "%s\n", __FUNCTION__);
+       dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
                err = -ENODEV;
index e7851e3739abd11030cdf0a724da2436315164dd..09bbe575647b09bd9a5acdfb94cd78c97807fe94 100644 (file)
@@ -499,7 +499,7 @@ static int rs5c372_probe(struct i2c_adapter *adapter, int address, int kind)
        struct rs5c372 *rs5c372;
        struct rtc_time tm;
 
-       dev_dbg(adapter->class_dev.dev, "%s\n", __FUNCTION__);
+       dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
                err = -ENODEV;
index 019ae255b0c8b2d143aae18a6d5ebbdb05b135d2..513d1a611aaba46edb1343ae0bb2ceab58683680 100644 (file)
@@ -506,7 +506,7 @@ static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
        struct i2c_client *client;
        struct rtc_device *rtc;
 
-       dev_dbg(adapter->class_dev.dev, "%s\n", __FUNCTION__);
+       dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
                err = -ENODEV;
index f64c4a0984cd22857eb81f56eb9195b4f86d20bf..5ec718a5fe2257c093ccaf74f550ba9100bf4c27 100644 (file)
@@ -115,6 +115,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
                minfo->fbcon.node);
        i2c_set_adapdata(&b->adapter, b);
        b->adapter.algo_data = &b->bac;
+       b->adapter.dev.parent = &ACCESS_FBINFO(pcidev)->dev;
        b->bac = matrox_i2c_algo_template;
        b->bac.data = b;
        err = i2c_bit_add_bus(&b->adapter);
index b5f613932912436da57d062d6ffbe91c2c5e139a..d68631f18df122824a0d36a307c647f15931c7bd 100644 (file)
@@ -1739,41 +1739,45 @@ shouldnt_be_hashed:
  * @rootmnt: vfsmnt to which the root dentry belongs
  * @buffer: buffer to return value in
  * @buflen: buffer length
- * @fail_deleted: what to return for deleted files
  *
- * Convert a dentry into an ASCII path name. If the entry has been deleted,
- * then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise,
- * the the string " (deleted)" is appended. Note that this is ambiguous.
+ * Convert a dentry into an ASCII path name. If the entry has been deleted
+ * the string " (deleted)" is appended. Note that this is ambiguous.
  *
- * Returns the buffer or an error code.
+ * Returns the buffer or an error code if the path was too long.
+ *
+ * "buflen" should be positive. Caller holds the dcache_lock.
  */
-static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
-                     struct dentry *root, struct vfsmount *rootmnt,
-                     char *buffer, int buflen, int fail_deleted)
+static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
+                       struct dentry *root, struct vfsmount *rootmnt,
+                       char *buffer, int buflen)
 {
-       int namelen, is_slash;
-
-       if (buflen < 2)
-               return ERR_PTR(-ENAMETOOLONG);
-       buffer += --buflen;
-       *buffer = '\0';
+       char * end = buffer+buflen;
+       char * retval;
+       int namelen;
 
-       spin_lock(&dcache_lock);
+       *--end = '\0';
+       buflen--;
        if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
-               if (fail_deleted) {
-                       buffer = ERR_PTR(-ENOENT);
-                       goto out;
-               }
-               if (buflen < 10)
-                       goto Elong;
                buflen -= 10;
-               buffer -= 10;
-               memcpy(buffer, " (deleted)", 10);
+               end -= 10;
+               if (buflen < 0)
+                       goto Elong;
+               memcpy(end, " (deleted)", 10);
        }
-       while (dentry != root || vfsmnt != rootmnt) {
+
+       if (buflen < 1)
+               goto Elong;
+       /* Get '/' right */
+       retval = end-1;
+       *retval = '/';
+
+       for (;;) {
                struct dentry * parent;
 
+               if (dentry == root && vfsmnt == rootmnt)
+                       break;
                if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+                       /* Global root? */
                        spin_lock(&vfsmount_lock);
                        if (vfsmnt->mnt_parent == vfsmnt) {
                                spin_unlock(&vfsmount_lock);
@@ -1787,60 +1791,33 @@ static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
                parent = dentry->d_parent;
                prefetch(parent);
                namelen = dentry->d_name.len;
-               if (buflen <= namelen)
-                       goto Elong;
                buflen -= namelen + 1;
-               buffer -= namelen;
-               memcpy(buffer, dentry->d_name.name, namelen);
-               *--buffer = '/';
+               if (buflen < 0)
+                       goto Elong;
+               end -= namelen;
+               memcpy(end, dentry->d_name.name, namelen);
+               *--end = '/';
+               retval = end;
                dentry = parent;
        }
-       /* Get '/' right */
-       if (*buffer != '/')
-               *--buffer = '/';
 
-out:
-       spin_unlock(&dcache_lock);
-       return buffer;
+       return retval;
 
 global_root:
-       /*
-        * We went past the (vfsmount, dentry) we were looking for and have
-        * either hit a root dentry, a lazily unmounted dentry, an
-        * unconnected dentry, or the file is on a pseudo filesystem.
-        */
        namelen = dentry->d_name.len;
-       is_slash = (namelen == 1 && *dentry->d_name.name == '/');
-       if (is_slash || (dentry->d_sb->s_flags & MS_NOUSER)) {
-               /*
-                * Make sure we won't return a pathname starting with '/'.
-                *
-                * Historically, we also glue together the root dentry and
-                * remaining name for pseudo filesystems like pipefs, which
-                * have the MS_NOUSER flag set. This results in pathnames
-                * like "pipe:[439336]".
-                */
-               if (*buffer == '/') {
-                       buffer++;
-                       buflen++;
-               }
-               if (is_slash)
-                       goto out;
-       }
-       if (buflen < namelen)
+       buflen -= namelen;
+       if (buflen < 0)
                goto Elong;
-       buffer -= namelen;
-       memcpy(buffer, dentry->d_name.name, namelen);
-       goto out;
-
+       retval -= namelen-1;    /* hit the slash */
+       memcpy(retval, dentry->d_name.name, namelen);
+       return retval;
 Elong:
-       buffer = ERR_PTR(-ENAMETOOLONG);
-       goto out;
+       return ERR_PTR(-ENAMETOOLONG);
 }
 
 /* write full pathname into buffer and return start of pathname */
-char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf,
-            int buflen)
+char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
+                               char *buf, int buflen)
 {
        char *res;
        struct vfsmount *rootmnt;
@@ -1850,7 +1827,9 @@ char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf,
        rootmnt = mntget(current->fs->rootmnt);
        root = dget(current->fs->root);
        read_unlock(&current->fs->lock);
-       res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, 0);
+       spin_lock(&dcache_lock);
+       res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
+       spin_unlock(&dcache_lock);
        dput(root);
        mntput(rootmnt);
        return res;
@@ -1876,10 +1855,10 @@ char *d_path(struct dentry *dentry, struct vfsmount *vfsmnt, char *buf,
  */
 asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
 {
-       int error, len;
+       int error;
        struct vfsmount *pwdmnt, *rootmnt;
        struct dentry *pwd, *root;
-       char *page = (char *) __get_free_page(GFP_USER), *cwd;
+       char *page = (char *) __get_free_page(GFP_USER);
 
        if (!page)
                return -ENOMEM;
@@ -1891,18 +1870,29 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
        root = dget(current->fs->root);
        read_unlock(&current->fs->lock);
 
-       cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 1);
-       error = PTR_ERR(cwd);
-       if (IS_ERR(cwd))
-               goto out;
+       error = -ENOENT;
+       /* Has the current directory has been unlinked? */
+       spin_lock(&dcache_lock);
+       if (pwd->d_parent == pwd || !d_unhashed(pwd)) {
+               unsigned long len;
+               char * cwd;
 
-       error = -ERANGE;
-       len = PAGE_SIZE + page - cwd;
-       if (len <= size) {
-               error = len;
-               if (copy_to_user(buf, cwd, len))
-                       error = -EFAULT;
-       }
+               cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
+               spin_unlock(&dcache_lock);
+
+               error = PTR_ERR(cwd);
+               if (IS_ERR(cwd))
+                       goto out;
+
+               error = -ERANGE;
+               len = PAGE_SIZE + page - cwd;
+               if (len <= size) {
+                       error = len;
+                       if (copy_to_user(buf, cwd, len))
+                               error = -EFAULT;
+               }
+       } else
+               spin_unlock(&dcache_lock);
 
 out:
        dput(pwd);
index c1a2409bb52a171fc1c1c0b9070b7791f350e812..8578869a8bcfb4556d3e50a62312b0c5abc3f8ee 100644 (file)
@@ -69,7 +69,10 @@ static __inline__ void atomic_add(int i, atomic_t * v)
                "1:     ll      %0, %1          # atomic_add            \n"
                "       addu    %0, %2                                  \n"
                "       sc      %0, %1                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
@@ -111,7 +114,10 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
                "1:     ll      %0, %1          # atomic_sub            \n"
                "       subu    %0, %2                                  \n"
                "       sc      %0, %1                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
@@ -155,8 +161,11 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
                "1:     ll      %1, %2          # atomic_add_return     \n"
                "       addu    %0, %1, %3                              \n"
                "       sc      %0, %2                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
                "       addu    %0, %1, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -204,8 +213,11 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
                "1:     ll      %1, %2          # atomic_sub_return     \n"
                "       subu    %0, %1, %3                              \n"
                "       sc      %0, %2                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
                "       subu    %0, %1, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -267,10 +279,13 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
                "       bltz    %0, 1f                                  \n"
                "       sc      %0, %2                                  \n"
                "       .set    noreorder                               \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
                "        subu   %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
                "1:                                                     \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -429,7 +444,10 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
                "1:     lld     %0, %1          # atomic64_add          \n"
                "       addu    %0, %2                                  \n"
                "       scd     %0, %1                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
@@ -471,7 +489,10 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
                "1:     lld     %0, %1          # atomic64_sub          \n"
                "       subu    %0, %2                                  \n"
                "       scd     %0, %1                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter));
@@ -515,8 +536,11 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
                "1:     lld     %1, %2          # atomic64_add_return   \n"
                "       addu    %0, %1, %3                              \n"
                "       scd     %0, %2                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
                "       addu    %0, %1, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -564,8 +588,11 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
                "1:     lld     %1, %2          # atomic64_sub_return   \n"
                "       subu    %0, %1, %3                              \n"
                "       scd     %0, %2                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
                "       subu    %0, %1, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
@@ -627,10 +654,13 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
                "       bltz    %0, 1f                                  \n"
                "       scd     %0, %2                                  \n"
                "       .set    noreorder                               \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
                "        dsubu  %0, %1, %3                              \n"
                "       .set    reorder                                 \n"
                "1:                                                     \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (result), "=&r" (temp), "=m" (v->counter)
                : "Ir" (i), "m" (v->counter)
index 06445de1324bd3c058a507d08d0c747d6ab571ae..06c08228a5256cbb3fa9320b102b09eb6e21774d 100644 (file)
@@ -68,7 +68,10 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
                "1:     " __LL "%0, %1                  # set_bit       \n"
                "       or      %0, %2                                  \n"
                "       " __SC  "%0, %1                                 \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (*m)
                : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
@@ -116,7 +119,10 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
                "1:     " __LL "%0, %1                  # clear_bit     \n"
                "       and     %0, %2                                  \n"
                "       " __SC "%0, %1                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       beqz    %0, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (temp), "=m" (*m)
                : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m));
@@ -166,7 +172,10 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
                "1:     " __LL "%0, %1          # change_bit    \n"
                "       xor     %0, %2                          \n"
                "       " __SC  "%0, %1                         \n"
-               "       beqz    %0, 1b                          \n"
+               "       beqz    %0, 2f                          \n"
+               "       .subsection 2                           \n"
+               "2:     b       1b                              \n"
+               "       .previous                               \n"
                "       .set    mips0                           \n"
                : "=&r" (temp), "=m" (*m)
                : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m));
@@ -222,8 +231,12 @@ static inline int test_and_set_bit(unsigned long nr,
                "1:     " __LL "%0, %1          # test_and_set_bit      \n"
                "       or      %2, %0, %3                              \n"
                "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 1b                                  \n"
+               "       beqz    %2, 2f                                  \n"
                "        and    %2, %0, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    pop                                     \n"
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -290,8 +303,12 @@ static inline int test_and_clear_bit(unsigned long nr,
                "       or      %2, %0, %3                              \n"
                "       xor     %2, %3                                  \n"
                "       " __SC  "%2, %1                                 \n"
-               "       beqz    %2, 1b                                  \n"
+               "       beqz    %2, 2f                                  \n"
                "        and    %2, %0, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    pop                                     \n"
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -356,8 +373,12 @@ static inline int test_and_change_bit(unsigned long nr,
                "1:     " __LL  "%0, %1         # test_and_change_bit   \n"
                "       xor     %2, %0, %3                              \n"
                "       " __SC  "\t%2, %1                               \n"
-               "       beqz    %2, 1b                                  \n"
+               "       beqz    %2, 2f                                  \n"
                "        and    %2, %0, %3                              \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    pop                                     \n"
                : "=&r" (temp), "=m" (*m), "=&r" (res)
                : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
diff --git a/include/asm-mips/compat-signal.h b/include/asm-mips/compat-signal.h
new file mode 100644 (file)
index 0000000..6720770
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __ASM_COMPAT_SIGNAL_H
+#define __ASM_COMPAT_SIGNAL_H
+
+#include <linux/bug.h>
+#include <linux/compat.h>
+#include <linux/compiler.h>
+
+static inline int __copy_conv_sigset_to_user(compat_sigset_t __user *d,
+       const sigset_t *s)
+{
+       int err;
+
+       BUG_ON(sizeof(*d) != sizeof(*s));
+       BUG_ON(_NSIG_WORDS != 2);
+
+       err  = __put_user(s->sig[0],       &d->sig[0]);
+       err |= __put_user(s->sig[0] >> 32, &d->sig[1]);
+       err |= __put_user(s->sig[1],       &d->sig[2]);
+       err |= __put_user(s->sig[1] >> 32, &d->sig[3]);
+
+       return err;
+}
+
+static inline int __copy_conv_sigset_from_user(sigset_t *d,
+       const compat_sigset_t __user *s)
+{
+       int err;
+       union sigset_u {
+               sigset_t        s;
+               compat_sigset_t c;
+       } *u = (union sigset_u *) d;
+
+       BUG_ON(sizeof(*d) != sizeof(*s));
+       BUG_ON(_NSIG_WORDS != 2);
+
+       if (unlikely(!access_ok(VERIFY_READ, d, sizeof(*d))))
+               return -EFAULT;
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+       err  = __get_user(u->c.sig[1], &s->sig[0]);
+       err |= __get_user(u->c.sig[0], &s->sig[1]);
+       err |= __get_user(u->c.sig[3], &s->sig[2]);
+       err |= __get_user(u->c.sig[2], &s->sig[3]);
+#endif
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       err  = __get_user(u->c.sig[0], &s->sig[0]);
+       err |= __get_user(u->c.sig[1], &s->sig[1]);
+       err |= __get_user(u->c.sig[2], &s->sig[2]);
+       err |= __get_user(u->c.sig[3], &s->sig[3]);
+#endif
+
+       return err;
+}
+
+#endif /* __ASM_COMPAT_SIGNAL_H */
index 236d1a467cc7fb49ae8dd028c8b66c1d2e3cd471..230b3f1b69b1015b3d639691200f97ebad45052e 100644 (file)
@@ -68,6 +68,7 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr);
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
               enum dma_data_direction direction);
 
+#if 0
 #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
 
 extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
@@ -75,5 +76,6 @@ extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
 extern void dma_release_declared_memory(struct device *dev);
 extern void * dma_mark_declared_memory_occupied(struct device *dev,
        dma_addr_t device_addr, size_t size);
+#endif
 
 #endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-mips/mach-generic/dma-coherence.h b/include/asm-mips/mach-generic/dma-coherence.h
new file mode 100644 (file)
index 0000000..df71822
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+#ifndef __ASM_MACH_GENERIC_DMA_COHERENCE_H
+#define __ASM_MACH_GENERIC_DMA_COHERENCE_H
+
+struct device;
+
+static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+{
+       return virt_to_phys(addr);
+}
+
+static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+{
+       return page_to_phys(page);
+}
+
+static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+{
+       return dma_addr;
+}
+
+static void plat_unmap_dma_mem(dma_addr_t dma_addr)
+{
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+#ifdef CONFIG_DMA_COHERENT
+       return 1;
+#endif
+#ifdef CONFIG_DMA_NONCOHERENT
+       return 0;
+#endif
+}
+
+#endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
index 410ab5f6c5636b519c6ecc8c56932e4abcf08d95..b8e6deba352fd90f6685e736a25df7ac5689c912 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef CONFIG_DMA_COHERENT
 /*
  * Total overkill for most systems but need as a safe default.
+ * Set this one if any device in the system might do non-coherent DMA.
  */
 #define ARCH_KMALLOC_MINALIGN  128
 #endif
diff --git a/include/asm-mips/mach-ip27/dma-coherence.h b/include/asm-mips/mach-ip27/dma-coherence.h
new file mode 100644 (file)
index 0000000..659816e
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+#ifndef __ASM_MACH_IP27_DMA_COHERENCE_H
+#define __ASM_MACH_IP27_DMA_COHERENCE_H
+
+#include <asm/pci/bridge.h>
+
+#define pdev_to_baddr(pdev, addr) \
+       (BRIDGE_CONTROLLER(pdev->bus)->baddr + (addr))
+#define dev_to_baddr(dev, addr) \
+       pdev_to_baddr(to_pci_dev(dev), (addr))
+
+struct device;
+
+static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+{
+       dma_addr_t pa = dev_to_baddr(dev, virt_to_phys(addr));
+
+       return pa;
+}
+
+static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+{
+       dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page));
+
+       return pa;
+}
+
+static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+{
+       return dma_addr & (0xffUL << 56);
+}
+
+static void plat_unmap_dma_mem(dma_addr_t dma_addr)
+{
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+       return 1;               /* IP27 non-cohernet mode is unsupported */
+}
+
+#endif /* __ASM_MACH_IP27_DMA_COHERENCE_H */
diff --git a/include/asm-mips/mach-ip32/dma-coherence.h b/include/asm-mips/mach-ip32/dma-coherence.h
new file mode 100644 (file)
index 0000000..950be17
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>
+ *
+ */
+#ifndef __ASM_MACH_IP35_DMA_COHERENCE_H
+#define __ASM_MACH_IP35_DMA_COHERENCE_H
+
+#include <asm/ip32/crime.h>
+
+struct device;
+
+/*
+ * Few notes.
+ * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x40000000+256M
+ * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for
+ *    native-endian)
+ * 3. All other devices see memory as one big chunk at 0x40000000
+ * 4. Non-PCI devices will pass NULL as struct device*
+ *
+ * Thus we translate differently, depending on device.
+ */
+
+#define RAM_OFFSET_MASK 0x3fffffffUL
+
+static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+{
+       dma_addr_t pa = virt_to_phys(addr) & RAM_OFFSET_MASK;
+
+       if (dev == NULL)
+               pa += CRIME_HI_MEM_BASE;
+
+       return pa;
+}
+
+static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+{
+       dma_addr_t pa;
+
+       pa = page_to_phys(page) & RAM_OFFSET_MASK;
+
+       if (dev == NULL)
+               pa += CRIME_HI_MEM_BASE;
+
+       return pa;
+}
+
+/* This is almost certainly wrong but it's what dma-ip32.c used to use  */
+static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+{
+       unsigned long addr = dma_addr & RAM_OFFSET_MASK;
+
+       if (dma_addr >= 256*1024*1024)
+               addr += CRIME_HI_MEM_BASE;
+
+       return addr;
+}
+
+static void plat_unmap_dma_mem(dma_addr_t dma_addr)
+{
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+       return 0;               /* IP32 is non-cohernet */
+}
+
+#endif /* __ASM_MACH_IP35_DMA_COHERENCE_H */
diff --git a/include/asm-mips/mach-jazz/dma-coherence.h b/include/asm-mips/mach-jazz/dma-coherence.h
new file mode 100644 (file)
index 0000000..d66979a
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006  Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_JAZZ_DMA_COHERENCE_H
+#define __ASM_MACH_JAZZ_DMA_COHERENCE_H
+
+#include <asm/jazzdma.h>
+
+struct device;
+
+static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size)
+{
+       return vdma_alloc(virt_to_phys(addr), size);
+}
+
+static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page)
+{
+       return vdma_alloc(page_to_phys(page), PAGE_SIZE);
+}
+
+static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+{
+       return vdma_log2phys(dma_addr);
+}
+
+static void plat_unmap_dma_mem(dma_addr_t dma_addr)
+{
+       vdma_free(dma_addr);
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+       return 0;
+}
+
+#endif /* __ASM_MACH_JAZZ_DMA_COHERENCE_H */
index fc3217fc1118deabd9c4c40cb3442cdf1573c2ab..f1755d28a36a6f3a44f44bebd3f2f061617e8695 100644 (file)
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999, 2000, 06 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SPINLOCK_H
@@ -49,11 +49,18 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
                __asm__ __volatile__(
                "       .set    noreorder       # __raw_spin_lock       \n"
                "1:     ll      %1, %2                                  \n"
-               "       bnez    %1, 1b                                  \n"
+               "       bnez    %1, 2f                                  \n"
                "        li     %1, 1                                   \n"
                "       sc      %1, %0                                  \n"
-               "       beqz    %1, 1b                                  \n"
+               "       beqz    %1, 2f                                  \n"
                "        nop                                            \n"
+               "       .subsection 2                                   \n"
+               "2:     ll      %1, %2                                  \n"
+               "       bnez    %1, 2b                                  \n"
+               "        li     %1, 1                                   \n"
+               "       b       1b                                      \n"
+               "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    reorder                                 \n"
                : "=m" (lock->lock), "=&r" (tmp)
                : "m" (lock->lock)
@@ -99,8 +106,12 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
                "1:     ll      %0, %3                                  \n"
                "       ori     %2, %0, 1                               \n"
                "       sc      %2, %1                                  \n"
-               "       beqz    %2, 1b                                  \n"
+               "       beqz    %2, 2f                                  \n"
                "        andi   %2, %0, 1                               \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    reorder"
                : "=&r" (temp), "=m" (lock->lock), "=&r" (res)
                : "m" (lock->lock)
@@ -154,11 +165,18 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
                __asm__ __volatile__(
                "       .set    noreorder       # __raw_read_lock       \n"
                "1:     ll      %1, %2                                  \n"
-               "       bltz    %1, 1b                                  \n"
+               "       bltz    %1, 2f                                  \n"
                "        addu   %1, 1                                   \n"
                "       sc      %1, %0                                  \n"
                "       beqz    %1, 1b                                  \n"
                "        nop                                            \n"
+               "       .subsection 2                                   \n"
+               "2:     ll      %1, %2                                  \n"
+               "       bltz    %1, 2b                                  \n"
+               "        addu   %1, 1                                   \n"
+               "       b       1b                                      \n"
+               "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    reorder                                 \n"
                : "=m" (rw->lock), "=&r" (tmp)
                : "m" (rw->lock)
@@ -192,8 +210,12 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
                "1:     ll      %1, %2                                  \n"
                "       sub     %1, 1                                   \n"
                "       sc      %1, %0                                  \n"
-               "       beqz    %1, 1b                                  \n"
+               "       beqz    %1, 2f                                  \n"
+               "        nop                                            \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
                "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    reorder                                 \n"
                : "=m" (rw->lock), "=&r" (tmp)
                : "m" (rw->lock)
@@ -222,11 +244,18 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
                __asm__ __volatile__(
                "       .set    noreorder       # __raw_write_lock      \n"
                "1:     ll      %1, %2                                  \n"
-               "       bnez    %1, 1b                                  \n"
+               "       bnez    %1, 2f                                  \n"
                "        lui    %1, 0x8000                              \n"
                "       sc      %1, %0                                  \n"
-               "       beqz    %1, 1b                                  \n"
+               "       beqz    %1, 2f                                  \n"
+               "        nop                                            \n"
+               "       .subsection 2                                   \n"
+               "2:     ll      %1, %2                                  \n"
+               "       bnez    %1, 2b                                  \n"
+               "        lui    %1, 0x8000                              \n"
+               "       b       1b                                      \n"
                "        nop                                            \n"
+               "       .previous                                       \n"
                "       .set    reorder                                 \n"
                : "=m" (rw->lock), "=&r" (tmp)
                : "m" (rw->lock)
@@ -322,12 +351,15 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
                "       bnez    %1, 2f                                  \n"
                "       lui     %1, 0x8000                              \n"
                "       sc      %1, %0                                  \n"
-               "       beqz    %1, 1b                                  \n"
-               "        nop                                            \n"
+               "       beqz    %1, 3f                                  \n"
+               "        li     %2, 1                                   \n"
+               "2:                                                     \n"
                __WEAK_ORDERING_MB
-               "       li      %2, 1                                   \n"
+               "       .subsection 2                                   \n"
+               "3:     b       1b                                      \n"
+               "        li     %2, 0                                   \n"
+               "       .previous                                       \n"
                "       .set    reorder                                 \n"
-               "2:                                                     \n"
                : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
                : "m" (rw->lock)
                : "memory");
index 5e1289c85ed958f414ec673a535e48b1c056e221..597a3743f6a1896aedf1369afabeb11ebe632c6d 100644 (file)
@@ -110,7 +110,10 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
                "       move    %2, %z4                                 \n"
                "       .set    mips3                                   \n"
                "       sc      %2, %1                                  \n"
-               "       beqz    %2, 1b                                  \n"
+               "       beqz    %2, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (retval), "=m" (*m), "=&r" (dummy)
                : "R" (*m), "Jr" (val)
@@ -155,7 +158,10 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
                "1:     lld     %0, %3                  # xchg_u64      \n"
                "       move    %2, %z4                                 \n"
                "       scd     %2, %1                                  \n"
-               "       beqz    %2, 1b                                  \n"
+               "       beqz    %2, 2f                                  \n"
+               "       .subsection 2                                   \n"
+               "2:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    mips0                                   \n"
                : "=&r" (retval), "=m" (*m), "=&r" (dummy)
                : "R" (*m), "Jr" (val)
@@ -232,8 +238,11 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
                "       move    $1, %z4                                 \n"
                "       .set    mips3                                   \n"
                "       sc      $1, %1                                  \n"
-               "       beqz    $1, 1b                                  \n"
+               "       beqz    $1, 3f                                  \n"
                "2:                                                     \n"
+               "       .subsection 2                                   \n"
+               "3:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    pop                                     \n"
                : "=&r" (retval), "=R" (*m)
                : "R" (*m), "Jr" (old), "Jr" (new)
@@ -283,8 +292,11 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
                "       bne     %0, %z3, 2f                             \n"
                "       move    $1, %z4                                 \n"
                "       scd     $1, %1                                  \n"
-               "       beqz    $1, 1b                                  \n"
+               "       beqz    $1, 3f                                  \n"
                "2:                                                     \n"
+               "       .subsection 2                                   \n"
+               "3:     b       1b                                      \n"
+               "       .previous                                       \n"
                "       .set    pop                                     \n"
                : "=&r" (retval), "=R" (*m)
                : "R" (*m), "Jr" (old), "Jr" (new)
index 825fcbd9eabd30e0924002bc3a039ae2ace4d5ab..3eff8d8fe28a1fff10417fba1518a5d63fac9d48 100644 (file)
@@ -265,10 +265,14 @@ do {                                                                      \
  */
 #define __get_user_asm_ll32(val, addr)                                 \
 {                                                                      \
+       union {                                                         \
+               unsigned long long      l;                              \
+               __typeof__(*(addr))     t;                              \
+       } __gu_tmp;                                                     \
+                                                                       \
        __asm__ __volatile__(                                           \
        "1:     lw      %1, (%3)                                \n"     \
        "2:     lw      %D1, 4(%3)                              \n"     \
-       "       move    %0, $0                                  \n"     \
        "3:     .section        .fixup,\"ax\"                   \n"     \
        "4:     li      %0, %4                                  \n"     \
        "       move    %1, $0                                  \n"     \
@@ -279,8 +283,10 @@ do {                                                                       \
        "       " __UA_ADDR "   1b, 4b                          \n"     \
        "       " __UA_ADDR "   2b, 4b                          \n"     \
        "       .previous                                       \n"     \
-       : "=r" (__gu_err), "=&r" (val)                                  \
+       : "=r" (__gu_err), "=&r" (__gu_tmp.l)                           \
        : "0" (0), "r" (addr), "i" (-EFAULT));                          \
+                                                                       \
+       (val) = __gu_tmp.t;                                             \
 }
 
 /*
index 6e7ec4c76178d9bd535de52762bc9017496c7797..9c21dc793d7b160d525a78841ecdc98f6cf89dca 100644 (file)
 #define I2C_HW_SMBUS_PIIX4     0x040000
 #define I2C_HW_SMBUS_ALI15X3   0x040001
 #define I2C_HW_SMBUS_VIA2      0x040002
-#define I2C_HW_SMBUS_VOODOO3   0x040003
 #define I2C_HW_SMBUS_I801      0x040004
 #define I2C_HW_SMBUS_AMD756    0x040005
 #define I2C_HW_SMBUS_SIS5595   0x040006
 #define I2C_HW_SMBUS_OV519     0x040010 /* OV519 USB 1.1 webcam IC */
 #define I2C_HW_SMBUS_OVFX2     0x040011 /* Cypress/OmniVision FX2 webcam */
 #define I2C_HW_SMBUS_CAFE      0x040012 /* Marvell 88ALP01 "CAFE" cam  */
+#define I2C_HW_SMBUS_ALI1563   0x040013
 
 /* --- ISA pseudo-adapter                                              */
 #define I2C_HW_ISA             0x050000
 
-/* --- IPMI pseudo-adapter                                             */
-#define I2C_HW_IPMI            0x0b0000
-
 /* --- IPMB adapter                                            */
 #define I2C_HW_IPMB            0x0c0000
 
index 71e50d3e492f2ccd1ed852ae959c759c67ed8830..9428092017e346dea02ca6442da258859ff39342 100644 (file)
@@ -125,7 +125,12 @@ struct i2c_driver {
         * it must be freed here.
         */
        int (*detach_client)(struct i2c_client *);
-       
+
+       /* driver model interfaces that don't relate to enumeration  */
+       void (*shutdown)(struct i2c_client *);
+       int (*suspend)(struct i2c_client *, pm_message_t mesg);
+       int (*resume)(struct i2c_client *);
+
        /* a ioctl like command that can be used to perform specific functions
         * with the device.
         */
index 8fb9c3e06eefa62e778a3d09f2f54b94c58003e2..182a96f77c8437d28987bd93a12dcb2eccef98ab 100644 (file)
 #define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a
 #define PCI_DEVICE_ID_ATI_IXP600_SATA  0x4380
 #define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381
+#define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE   0x438c
 
 #define PCI_VENDOR_ID_VLSI             0x1004