Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvar...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Dec 2009 16:12:16 +0000 (08:12 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Dec 2009 16:12:16 +0000 (08:12 -0800)
* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  i2c-stub: Documentation update
  i2c-stub: Allow user to disable some commands
  i2c-stub: Implement I2C block support
  i2c: Refactor for_each callbacks
  i2c-i801: Retry on lost arbitration
  i2c: Remove big kernel lock from i2cdev_open
  ics932s401: Clean up detect function
  i2c: Simplify i2c_detect_address
  i2c: Drop probe, ignore and force module parameters
  i2c: Add missing __devinit markers to old i2c adapter drivers
  i2c: Bus drivers don't have to support I2C_M_REV_DIR_ADDR
  i2c: Prevent priority inversion on top of bus lock
  i2c-voodoo3: Delete
  i2c-powermac: Drop temporary name buffer
  i2c-powermac: Include the i2c_adapter in struct pmac_i2c_bus
  i2c-powermac: Log errors
  i2c-powermac: Refactor i2c_powermac_smbus_xfer
  i2c-powermac: Reject unsupported I2C transactions
  i2c/chips: Move ds1682 to drivers/misc

28 files changed:
Documentation/feature-removal-schedule.txt
Documentation/i2c/busses/i2c-voodoo3 [deleted file]
Documentation/i2c/i2c-stub
Documentation/i2c/old-module-parameters [new file with mode: 0644]
arch/powerpc/include/asm/pmac_low_i2c.h
arch/powerpc/platforms/powermac/low_i2c.c
drivers/i2c/Kconfig
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-ali1535.c
drivers/i2c/busses/i2c-ali15x3.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-sis5595.c
drivers/i2c/busses/i2c-sis630.c
drivers/i2c/busses/i2c-stub.c
drivers/i2c/busses/i2c-voodoo3.c [deleted file]
drivers/i2c/chips/Kconfig
drivers/i2c/chips/Makefile
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/ds1682.c [moved from drivers/i2c/chips/ds1682.c with 100% similarity]
drivers/misc/ics932s401.c
include/linux/i2c.h

index a004b04ffd3a9afff7663e3413968e1eaa9a313d..591e94448e636edebab3791bdd69363b54a13895 100644 (file)
@@ -407,15 +407,6 @@ Who:       Alex Chiang <achiang@hp.com>
 
 ---------------------------
 
-What:  i2c-voodoo3 driver
-When:  October 2009
-Why:   Superseded by tdfxfb. I2C/DDC support used to live in a separate
-       driver but this caused driver conflicts.
-Who:   Jean Delvare <khali@linux-fr.org>
-       Krzysztof Helt <krzysztof.h1@wp.pl>
-
----------------------------
-
 What:  CONFIG_RFKILL_INPUT
 When:  2.6.33
 Why:   Should be implemented in userspace, policy daemon.
diff --git a/Documentation/i2c/busses/i2c-voodoo3 b/Documentation/i2c/busses/i2c-voodoo3
deleted file mode 100644 (file)
index 62d90a4..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-Kernel driver i2c-voodoo3
-
-Supported adapters:
-  * 3dfx Voodoo3 based cards
-  * Voodoo Banshee based cards
-
-Authors: 
-       Frodo Looijaard <frodol@dds.nl>, 
-       Philip Edelbrock <phil@netroedge.com>, 
-       Ralph Metzler <rjkm@thp.uni-koeln.de>,
-       Mark D. Studebaker <mdsxyz123@yahoo.com>
-
-Main contact: Philip Edelbrock <phil@netroedge.com>
-       
-The code is based upon Ralph's test code (he did the hard stuff ;')
-
-Description
------------
-
-The 3dfx Voodoo3 chip contains two I2C interfaces (aka a I2C 'master' or
-'host'). 
-
-The first interface is used for DDC (Data Display Channel) which is a
-serial channel through the VGA monitor connector to a DDC-compliant
-monitor. This interface is defined by the Video Electronics Standards
-Association (VESA). The standards are available for purchase at
-http://www.vesa.org .
-
-The second interface is a general-purpose I2C bus. The intent by 3dfx was
-to allow manufacturers to add extra chips to the video card such as a
-TV-out chip such as the BT869 or possibly even I2C based temperature
-sensors like the ADM1021 or LM75.
-
-Stability
----------
-
-Seems to be stable on the test machine, but needs more testing on other
-machines. Simultaneous accesses of the DDC and I2C busses may cause errors.
-
-Supported Devices
------------------
-
-Specifically, this driver was written and tested on the '3dfx Voodoo3 AGP
-3000' which has a tv-out feature (s-video or composite).  According to the
-docs and discussions, this code should work for any Voodoo3 based cards as
-well as Voodoo Banshee based cards.  The DDC interface has been tested on a
-Voodoo Banshee card.
-       
-Issues
-------
-
-Probably many, but it seems to work OK on my system. :')
-
-
-External Device Connection
---------------------------
-
-The digital video input jumpers give availability to the I2C bus. 
-Specifically, pins 13 and 25 (bottom row middle, and bottom right-end) are     
-the I2C clock and I2C data lines, respectively. +5V and GND are probably
-also easily available making the addition of extra I2C/SMBus devices easy
-to implement.
index 0d8be1c20c16b6bf96a95f42e7855d635e3a32b8..fa4b669c166b3a0145f070f935964a403dc85428 100644 (file)
@@ -2,9 +2,9 @@ MODULE: i2c-stub
 
 DESCRIPTION:
 
-This module is a very simple fake I2C/SMBus driver.  It implements four
-types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, and
-(r/w) word data.
+This module is a very simple fake I2C/SMBus driver.  It implements five
+types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, (r/w)
+word data, and (r/w) I2C block data.
 
 You need to provide chip addresses as a module parameter when loading this
 driver, which will then only react to SMBus commands to these addresses.
@@ -21,8 +21,8 @@ EEPROMs, among others.
 
 The typical use-case is like this:
        1. load this module
-       2. use i2cset (from lm_sensors project) to pre-load some data
-       3. load the target sensors chip driver module
+       2. use i2cset (from the i2c-tools project) to pre-load some data
+       3. load the target chip driver module
        4. observe its behavior in the kernel log
 
 There's a script named i2c-stub-from-dump in the i2c-tools package which
@@ -33,6 +33,12 @@ PARAMETERS:
 int chip_addr[10]:
        The SMBus addresses to emulate chips at.
 
+unsigned long functionality:
+       Functionality override, to disable some commands. See I2C_FUNC_*
+       constants in <linux/i2c.h> for the suitable values. For example,
+       value 0x1f0000 would only enable the quick, byte and byte data
+       commands.
+
 CAVEATS:
 
 If your target driver polls some byte or word waiting for it to change, the
diff --git a/Documentation/i2c/old-module-parameters b/Documentation/i2c/old-module-parameters
new file mode 100644 (file)
index 0000000..8e2b629
--- /dev/null
@@ -0,0 +1,44 @@
+I2C device driver binding control from user-space
+=================================================
+
+Up to kernel 2.6.32, many i2c drivers used helper macros provided by
+<linux/i2c.h> which created standard module parameters to let the user
+control how the driver would probe i2c buses and attach to devices. These
+parameters were known as "probe" (to let the driver probe for an extra
+address), "force" (to forcibly attach the driver to a given device) and
+"ignore" (to prevent a driver from probing a given address).
+
+With the conversion of the i2c subsystem to the standard device driver
+binding model, it became clear that these per-module parameters were no
+longer needed, and that a centralized implementation was possible. The new,
+sysfs-based interface is described in the documentation file
+"instantiating-devices", section "Method 4: Instantiate from user-space".
+
+Below is a mapping from the old module parameters to the new interface.
+
+Attaching a driver to an I2C device
+-----------------------------------
+
+Old method (module parameters):
+# modprobe <driver> probe=1,0x2d
+# modprobe <driver> force=1,0x2d
+# modprobe <driver> force_<device>=1,0x2d
+
+New method (sysfs interface):
+# echo <device> 0x2d > /sys/bus/i2c/devices/i2c-1/new_device
+
+Preventing a driver from attaching to an I2C device
+---------------------------------------------------
+
+Old method (module parameters):
+# modprobe <driver> ignore=1,0x2f
+
+New method (sysfs interface):
+# echo dummy 0x2f > /sys/bus/i2c/devices/i2c-1/new_device
+# modprobe <driver>
+
+Of course, it is important to instantiate the "dummy" device before loading
+the driver. The dummy device will be handled by i2c-core itself, preventing
+other drivers from binding to it later on. If there is a real device at the
+problematic address, and you want another driver to bind to it, then simply
+pass the name of the device in question instead of "dummy".
index 131011bd7e7682236434235b5081934b6ab5e5cf..01d71826d92f7a94e40cab35d8adefff466cec02 100644 (file)
@@ -72,11 +72,7 @@ extern int pmac_i2c_get_type(struct pmac_i2c_bus *bus);
 extern int pmac_i2c_get_flags(struct pmac_i2c_bus *bus);
 extern int pmac_i2c_get_channel(struct pmac_i2c_bus *bus);
 
-/* i2c layer adapter attach/detach */
-extern void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus,
-                                   struct i2c_adapter *adapter);
-extern void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus,
-                                   struct i2c_adapter *adapter);
+/* i2c layer adapter helpers */
 extern struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus);
 extern struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter);
 
index 414ca9849f239f365b136cf05742144a7c6ddc0a..345e2da56767998e3f3af53c23d9cc643d59514b 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/mutex.h>
+#include <linux/i2c.h>
 #include <asm/keylargo.h>
 #include <asm/uninorth.h>
 #include <asm/io.h>
@@ -80,7 +81,7 @@ struct pmac_i2c_bus
        struct device_node      *busnode;
        int                     type;
        int                     flags;
-       struct i2c_adapter      *adapter;
+       struct i2c_adapter      adapter;
        void                    *hostdata;
        int                     channel;        /* some hosts have multiple */
        int                     mode;           /* current mode */
@@ -1014,25 +1015,9 @@ int pmac_i2c_get_channel(struct pmac_i2c_bus *bus)
 EXPORT_SYMBOL_GPL(pmac_i2c_get_channel);
 
 
-void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus,
-                            struct i2c_adapter *adapter)
-{
-       WARN_ON(bus->adapter != NULL);
-       bus->adapter = adapter;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter);
-
-void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus,
-                            struct i2c_adapter *adapter)
-{
-       WARN_ON(bus->adapter != adapter);
-       bus->adapter = NULL;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter);
-
 struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus)
 {
-       return bus->adapter;
+       return &bus->adapter;
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter);
 
@@ -1041,7 +1026,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter)
        struct pmac_i2c_bus *bus;
 
        list_for_each_entry(bus, &pmac_i2c_busses, link)
-               if (bus->adapter == adapter)
+               if (&bus->adapter == adapter)
                        return bus;
        return NULL;
 }
@@ -1053,7 +1038,7 @@ int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter)
 
        if (bus == NULL)
                return 0;
-       return (bus->adapter == adapter);
+       return (&bus->adapter == adapter);
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter);
 
index d7ece131b4f4bd64af82fd80160279ffd99a1db5..8d8a00e5a30e307fbc474aa33cd154fb683b0fc2 100644 (file)
@@ -5,6 +5,7 @@
 menuconfig I2C
        tristate "I2C support"
        depends on HAS_IOMEM
+       select RT_MUTEXES
        ---help---
          I2C (pronounce: I-square-C) is a slow serial bus protocol used in
          many micro controller applications and developed by Philips.  SMBus,
index e8fe7f169e25773612a37774218e3231d21ba964..5f318ce29770228dfe7c179ee7fc4f79fbb38805 100644 (file)
@@ -640,22 +640,6 @@ config I2C_TINY_USB
          This driver can also be built as a module.  If so, the module
          will be called i2c-tiny-usb.
 
-comment "Graphics adapter I2C/DDC channel drivers"
-       depends on PCI
-
-config I2C_VOODOO3
-       tristate "Voodoo 3 (DEPRECATED)"
-       depends on PCI
-       select I2C_ALGOBIT
-       help
-         If you say yes to this option, support will be included for the
-         Voodoo 3 I2C interface. This driver is deprecated and you should
-         use the tdfxfb driver instead, which additionally provides
-         framebuffer support.
-
-         This driver can also be built as a module.  If so, the module
-         will be called i2c-voodoo3.
-
 comment "Other I2C/SMBus bus drivers"
 
 config I2C_ACORN
index ff937ac69f5b817c35bf7546006efe4735b8f8b8..302c551977bbd871ccae1f0684814b6bea4b6e10 100644 (file)
@@ -61,9 +61,6 @@ obj-$(CONFIG_I2C_PARPORT_LIGHT)       += i2c-parport-light.o
 obj-$(CONFIG_I2C_TAOS_EVM)     += i2c-taos-evm.o
 obj-$(CONFIG_I2C_TINY_USB)     += i2c-tiny-usb.o
 
-# Graphics adapter I2C/DDC channel drivers
-obj-$(CONFIG_I2C_VOODOO3)      += i2c-voodoo3.o
-
 # Other I2C/SMBus bus drivers
 obj-$(CONFIG_I2C_ACORN)                += i2c-acorn.o
 obj-$(CONFIG_I2C_ELEKTOR)      += i2c-elektor.o
index d108450df064552b56f5886200231f3e53e8c57b..8de7d7b87bb07f26aecf2f2bb6ac79b2952bc3f9 100644 (file)
@@ -138,7 +138,7 @@ static unsigned short ali1535_smba;
    Note the differences between kernels with the old PCI BIOS interface and
    newer kernels with the real PCI interface. In compat.h some things are
    defined to make the transition easier. */
-static int ali1535_setup(struct pci_dev *dev)
+static int __devinit ali1535_setup(struct pci_dev *dev)
 {
        int retval = -ENODEV;
        unsigned char temp;
index d627fceb790b9e16c3fb2b15c1e544a653e1a46d..e7e3205f1286e146a4b6630768cbf640484b5822 100644 (file)
@@ -131,7 +131,7 @@ MODULE_PARM_DESC(force_addr,
 static struct pci_driver ali15x3_driver;
 static unsigned short ali15x3_smba;
 
-static int ali15x3_setup(struct pci_dev *ALI15X3_dev)
+static int __devinit ali15x3_setup(struct pci_dev *ALI15X3_dev)
 {
        u16 a;
        unsigned char temp;
index 55edcfe5b851abe5676d1d3c857eed93c233e458..df6ab553f975c98ed078475454d35a58d272aef7 100644 (file)
@@ -767,6 +767,9 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
        /* set up the sysfs linkage to our parent device */
        i801_adapter.dev.parent = &dev->dev;
 
+       /* Retry up to 3 times on lost arbitration */
+       i801_adapter.retries = 3;
+
        snprintf(i801_adapter.name, sizeof(i801_adapter.name),
                "SMBus I801 adapter at %04lx", i801_smba);
        err = i2c_add_adapter(&i801_adapter);
index a75c75e77b926417f94524274c256d02fcf7b16b..5901707fc66accbef77b71be68df99da24b1183d 100644 (file)
@@ -56,12 +56,6 @@ iic_cook_addr(struct i2c_msg *msg)
        if (msg->flags & I2C_M_RD)
                addr |= 1;
 
-       /*
-        * Read or Write?
-        */
-       if (msg->flags & I2C_M_REV_DIR_ADDR)
-               addr ^= 1;
-
        return addr;   
 }
 
index bbab0e16663037955f162f467c3f43a48e3c175f..ed387ffa47307b1a28b90f9646e4d8dd3b6262c9 100644 (file)
@@ -338,9 +338,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
        if (msg->flags & I2C_M_RD)
                dir = 1;
 
-       if (msg->flags & I2C_M_REV_DIR_ADDR)
-               dir ^= 1;
-
        if (msg->flags & I2C_M_TEN) {
                drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
                drv_data->addr2 = (u32)msg->addr & 0xff;
index 3c9d71f60187ac6f979027238e31d4230cd5a764..1c440a70ec6139c8c6bfe5b1fd9195608dd9de71 100644 (file)
@@ -49,48 +49,38 @@ static s32 i2c_powermac_smbus_xfer( struct i2c_adapter*     adap,
        int                     rc = 0;
        int                     read = (read_write == I2C_SMBUS_READ);
        int                     addrdir = (addr << 1) | read;
+       int                     mode, subsize, len;
+       u32                     subaddr;
+       u8                      *buf;
        u8                      local[2];
 
-       rc = pmac_i2c_open(bus, 0);
-       if (rc)
-               return rc;
+       if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE) {
+               mode = pmac_i2c_mode_std;
+               subsize = 0;
+               subaddr = 0;
+       } else {
+               mode = read ? pmac_i2c_mode_combined : pmac_i2c_mode_stdsub;
+               subsize = 1;
+               subaddr = command;
+       }
 
        switch (size) {
         case I2C_SMBUS_QUICK:
-               rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
-               if (rc)
-                       goto bail;
-               rc = pmac_i2c_xfer(bus, addrdir, 0, 0, NULL, 0);
+               buf = NULL;
+               len = 0;
                break;
         case I2C_SMBUS_BYTE:
-               rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
-               if (rc)
-                       goto bail;
-               rc = pmac_i2c_xfer(bus, addrdir, 0, 0, &data->byte, 1);
-               break;
         case I2C_SMBUS_BYTE_DATA:
-               rc = pmac_i2c_setmode(bus, read ?
-                                     pmac_i2c_mode_combined :
-                                     pmac_i2c_mode_stdsub);
-               if (rc)
-                       goto bail;
-               rc = pmac_i2c_xfer(bus, addrdir, 1, command, &data->byte, 1);
+               buf = &data->byte;
+               len = 1;
                break;
         case I2C_SMBUS_WORD_DATA:
-               rc = pmac_i2c_setmode(bus, read ?
-                                     pmac_i2c_mode_combined :
-                                     pmac_i2c_mode_stdsub);
-               if (rc)
-                       goto bail;
                if (!read) {
                        local[0] = data->word & 0xff;
                        local[1] = (data->word >> 8) & 0xff;
                }
-               rc = pmac_i2c_xfer(bus, addrdir, 1, command, local, 2);
-               if (rc == 0 && read) {
-                       data->word = ((u16)local[1]) << 8;
-                       data->word |= local[0];
-               }
+               buf = local;
+               len = 2;
                break;
 
        /* Note that these are broken vs. the expected smbus API where
@@ -105,28 +95,44 @@ static s32 i2c_powermac_smbus_xfer(        struct i2c_adapter*     adap,
         * a repeat start/addr phase (but not stop in between)
         */
         case I2C_SMBUS_BLOCK_DATA:
-               rc = pmac_i2c_setmode(bus, read ?
-                                     pmac_i2c_mode_combined :
-                                     pmac_i2c_mode_stdsub);
-               if (rc)
-                       goto bail;
-               rc = pmac_i2c_xfer(bus, addrdir, 1, command, data->block,
-                                  data->block[0] + 1);
-
+               buf = data->block;
+               len = data->block[0] + 1;
                break;
        case I2C_SMBUS_I2C_BLOCK_DATA:
-               rc = pmac_i2c_setmode(bus, read ?
-                                     pmac_i2c_mode_combined :
-                                     pmac_i2c_mode_stdsub);
-               if (rc)
-                       goto bail;
-               rc = pmac_i2c_xfer(bus, addrdir, 1, command,
-                                  &data->block[1], data->block[0]);
+               buf = &data->block[1];
+               len = data->block[0];
                break;
 
         default:
-               rc = -EINVAL;
+               return -EINVAL;
+       }
+
+       rc = pmac_i2c_open(bus, 0);
+       if (rc) {
+               dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
+               return rc;
+       }
+
+       rc = pmac_i2c_setmode(bus, mode);
+       if (rc) {
+               dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
+                       mode, rc);
+               goto bail;
        }
+
+       rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len);
+       if (rc) {
+               dev_err(&adap->dev,
+                       "I2C transfer at 0x%02x failed, size %d, err %d\n",
+                       addrdir >> 1, size, rc);
+               goto bail;
+       }
+
+       if (size == I2C_SMBUS_WORD_DATA && read) {
+               data->word = ((u16)local[1]) << 8;
+               data->word |= local[0];
+       }
+
  bail:
        pmac_i2c_close(bus);
        return rc;
@@ -146,20 +152,33 @@ static int i2c_powermac_master_xfer(      struct i2c_adapter *adap,
        int                     read;
        int                     addrdir;
 
+       if (num != 1) {
+               dev_err(&adap->dev,
+                       "Multi-message I2C transactions not supported\n");
+               return -EOPNOTSUPP;
+       }
+
        if (msgs->flags & I2C_M_TEN)
                return -EINVAL;
        read = (msgs->flags & I2C_M_RD) != 0;
        addrdir = (msgs->addr << 1) | read;
-       if (msgs->flags & I2C_M_REV_DIR_ADDR)
-               addrdir ^= 1;
 
        rc = pmac_i2c_open(bus, 0);
-       if (rc)
+       if (rc) {
+               dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
                return rc;
+       }
        rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
-       if (rc)
+       if (rc) {
+               dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n",
+                       pmac_i2c_mode_std, rc);
                goto bail;
+       }
        rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
+       if (rc < 0)
+               dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n",
+                       addrdir & 1 ? "read from" : "write to", addrdir >> 1,
+                       rc);
  bail:
        pmac_i2c_close(bus);
        return rc < 0 ? rc : 1;
@@ -183,19 +202,16 @@ static const struct i2c_algorithm i2c_powermac_algorithm = {
 static int __devexit i2c_powermac_remove(struct platform_device *dev)
 {
        struct i2c_adapter      *adapter = platform_get_drvdata(dev);
-       struct pmac_i2c_bus     *bus = i2c_get_adapdata(adapter);
        int                     rc;
 
        rc = i2c_del_adapter(adapter);
-       pmac_i2c_detach_adapter(bus, adapter);
-       i2c_set_adapdata(adapter, NULL);
        /* We aren't that prepared to deal with this... */
        if (rc)
                printk(KERN_WARNING
                       "i2c-powermac.c: Failed to remove bus %s !\n",
                       adapter->name);
        platform_set_drvdata(dev, NULL);
-       kfree(adapter);
+       memset(adapter, 0, sizeof(*adapter));
 
        return 0;
 }
@@ -206,12 +222,12 @@ static int __devinit i2c_powermac_probe(struct platform_device *dev)
        struct pmac_i2c_bus *bus = dev->dev.platform_data;
        struct device_node *parent = NULL;
        struct i2c_adapter *adapter;
-       char name[32];
        const char *basename;
        int rc;
 
        if (bus == NULL)
                return -EINVAL;
+       adapter = pmac_i2c_get_adapter(bus);
 
        /* Ok, now we need to make up a name for the interface that will
         * match what we used to do in the past, that is basically the
@@ -237,29 +253,22 @@ static int __devinit i2c_powermac_probe(struct platform_device *dev)
        default:
                return -EINVAL;
        }
-       snprintf(name, 32, "%s %d", basename, pmac_i2c_get_channel(bus));
+       snprintf(adapter->name, sizeof(adapter->name), "%s %d", basename,
+                pmac_i2c_get_channel(bus));
        of_node_put(parent);
 
-       adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-       if (adapter == NULL) {
-               printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n");
-               return -ENOMEM;
-       }
        platform_set_drvdata(dev, adapter);
-       strcpy(adapter->name, name);
        adapter->algo = &i2c_powermac_algorithm;
        i2c_set_adapdata(adapter, bus);
        adapter->dev.parent = &dev->dev;
-       pmac_i2c_attach_adapter(bus, adapter);
        rc = i2c_add_adapter(adapter);
        if (rc) {
                printk(KERN_ERR "i2c-powermac: Adapter %s registration "
-                      "failed\n", name);
-               i2c_set_adapdata(adapter, NULL);
-               pmac_i2c_detach_adapter(bus, adapter);
+                      "failed\n", adapter->name);
+               memset(adapter, 0, sizeof(*adapter));
        }
 
-       printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
+       printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name);
 
        if (!strncmp(basename, "uni-n", 5)) {
                struct device_node *np;
index 139f0c7f12a406db35d9b73f08ce4ab2f47132a3..844569f7d8b789d1ef4f5755332bc36ac0bef3df 100644 (file)
@@ -142,7 +142,7 @@ static void sis5595_write(u8 reg, u8 data)
        outb(data, sis5595_base + SMB_DAT);
 }
 
-static int sis5595_setup(struct pci_dev *SIS5595_dev)
+static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev)
 {
        u16 a;
        u8 val;
index 70ca41e90e58741d9e0a1cce9088e380f69fa48c..68cff7af7013453f1f72a345adacdf28ed09cf9b 100644 (file)
@@ -389,7 +389,7 @@ static u32 sis630_func(struct i2c_adapter *adapter)
                I2C_FUNC_SMBUS_BLOCK_DATA;
 }
 
-static int sis630_setup(struct pci_dev *sis630_dev)
+static int __devinit sis630_setup(struct pci_dev *sis630_dev)
 {
        unsigned char b;
        struct pci_dev *dummy = NULL;
index 1b7b2af94036ca448ff226f49bd1e14ff45068c4..0c770eabe85e15e3bec6c1bb662a635af8fedc23 100644 (file)
@@ -35,6 +35,10 @@ module_param_array(chip_addr, ushort, NULL, S_IRUGO);
 MODULE_PARM_DESC(chip_addr,
                 "Chip addresses (up to 10, between 0x03 and 0x77)");
 
+static unsigned long functionality = ~0UL;
+module_param(functionality, ulong, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(functionality, "Override functionality bitfield");
+
 struct stub_chip {
        u8 pointer;
        u16 words[256];         /* Byte operations use the LSB as per SMBus
@@ -48,7 +52,7 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
        char read_write, u8 command, int size, union i2c_smbus_data * data)
 {
        s32 ret;
-       int i;
+       int i, len;
        struct stub_chip *chip = NULL;
 
        /* Search for the right chip */
@@ -118,6 +122,29 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
                ret = 0;
                break;
 
+       case I2C_SMBUS_I2C_BLOCK_DATA:
+               len = data->block[0];
+               if (read_write == I2C_SMBUS_WRITE) {
+                       for (i = 0; i < len; i++) {
+                               chip->words[command + i] &= 0xff00;
+                               chip->words[command + i] |= data->block[1 + i];
+                       }
+                       dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
+                                       "wrote %d bytes at 0x%02x.\n",
+                                       addr, len, command);
+               } else {
+                       for (i = 0; i < len; i++) {
+                               data->block[1 + i] =
+                                       chip->words[command + i] & 0xff;
+                       }
+                       dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, "
+                                       "read  %d bytes at 0x%02x.\n",
+                                       addr, len, command);
+               }
+
+               ret = 0;
+               break;
+
        default:
                dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
                ret = -EOPNOTSUPP;
@@ -129,8 +156,9 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
 
 static u32 stub_func(struct i2c_adapter *adapter)
 {
-       return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-               I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA;
+       return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+               I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+               I2C_FUNC_SMBUS_I2C_BLOCK) & functionality;
 }
 
 static const struct i2c_algorithm smbus_algorithm = {
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
deleted file mode 100644 (file)
index 7663d57..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>,
-    Ralph Metzler <rjkm@thp.uni-koeln.de>, and
-    Mark D. Studebaker <mdsxyz123@yahoo.com>
-    
-    Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and
-    Simon Vogl
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* This interfaces to the I2C bus of the Voodoo3 to gain access to
-    the BT869 and possibly other I2C devices. */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-/* the only registers we use */
-#define REG            0x78
-#define REG2           0x70
-
-/* bit locations in the register */
-#define DDC_ENAB       0x00040000
-#define DDC_SCL_OUT    0x00080000
-#define DDC_SDA_OUT    0x00100000
-#define DDC_SCL_IN     0x00200000
-#define DDC_SDA_IN     0x00400000
-#define I2C_ENAB       0x00800000
-#define I2C_SCL_OUT    0x01000000
-#define I2C_SDA_OUT    0x02000000
-#define I2C_SCL_IN     0x04000000
-#define I2C_SDA_IN     0x08000000
-
-/* initialization states */
-#define INIT2          0x2
-#define INIT3          0x4
-
-/* delays */
-#define CYCLE_DELAY    10
-#define TIMEOUT                (HZ / 2)
-
-
-static void __iomem *ioaddr;
-
-/* The voo GPIO registers don't have individual masks for each bit
-   so we always have to read before writing. */
-
-static void bit_vooi2c_setscl(void *data, int val)
-{
-       unsigned int r;
-       r = readl(ioaddr + REG);
-       if (val)
-               r |= I2C_SCL_OUT;
-       else
-               r &= ~I2C_SCL_OUT;
-       writel(r, ioaddr + REG);
-       readl(ioaddr + REG);    /* flush posted write */
-}
-
-static void bit_vooi2c_setsda(void *data, int val)
-{
-       unsigned int r;
-       r = readl(ioaddr + REG);
-       if (val)
-               r |= I2C_SDA_OUT;
-       else
-               r &= ~I2C_SDA_OUT;
-       writel(r, ioaddr + REG);
-       readl(ioaddr + REG);    /* flush posted write */
-}
-
-/* The GPIO pins are open drain, so the pins always remain outputs.
-   We rely on the i2c-algo-bit routines to set the pins high before
-   reading the input from other chips. */
-
-static int bit_vooi2c_getscl(void *data)
-{
-       return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
-}
-
-static int bit_vooi2c_getsda(void *data)
-{
-       return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
-}
-
-static void bit_vooddc_setscl(void *data, int val)
-{
-       unsigned int r;
-       r = readl(ioaddr + REG);
-       if (val)
-               r |= DDC_SCL_OUT;
-       else
-               r &= ~DDC_SCL_OUT;
-       writel(r, ioaddr + REG);
-       readl(ioaddr + REG);    /* flush posted write */
-}
-
-static void bit_vooddc_setsda(void *data, int val)
-{
-       unsigned int r;
-       r = readl(ioaddr + REG);
-       if (val)
-               r |= DDC_SDA_OUT;
-       else
-               r &= ~DDC_SDA_OUT;
-       writel(r, ioaddr + REG);
-       readl(ioaddr + REG);    /* flush posted write */
-}
-
-static int bit_vooddc_getscl(void *data)
-{
-       return (0 != (readl(ioaddr + REG) & DDC_SCL_IN));
-}
-
-static int bit_vooddc_getsda(void *data)
-{
-       return (0 != (readl(ioaddr + REG) & DDC_SDA_IN));
-}
-
-static int config_v3(struct pci_dev *dev)
-{
-       unsigned long cadr;
-
-       /* map Voodoo3 memory */
-       cadr = dev->resource[0].start;
-       cadr &= PCI_BASE_ADDRESS_MEM_MASK;
-       ioaddr = ioremap_nocache(cadr, 0x1000);
-       if (ioaddr) {
-               writel(0x8160, ioaddr + REG2);
-               writel(0xcffc0020, ioaddr + REG);
-               dev_info(&dev->dev, "Using Banshee/Voodoo3 I2C device at %p\n", ioaddr);
-               return 0;
-       }
-       return -ENODEV;
-}
-
-static struct i2c_algo_bit_data voo_i2c_bit_data = {
-       .setsda         = bit_vooi2c_setsda,
-       .setscl         = bit_vooi2c_setscl,
-       .getsda         = bit_vooi2c_getsda,
-       .getscl         = bit_vooi2c_getscl,
-       .udelay         = CYCLE_DELAY,
-       .timeout        = TIMEOUT
-};
-
-static struct i2c_adapter voodoo3_i2c_adapter = {
-       .owner          = THIS_MODULE,
-       .name           = "I2C Voodoo3/Banshee adapter",
-       .algo_data      = &voo_i2c_bit_data,
-};
-
-static struct i2c_algo_bit_data voo_ddc_bit_data = {
-       .setsda         = bit_vooddc_setsda,
-       .setscl         = bit_vooddc_setscl,
-       .getsda         = bit_vooddc_getsda,
-       .getscl         = bit_vooddc_getscl,
-       .udelay         = CYCLE_DELAY,
-       .timeout        = TIMEOUT
-};
-
-static struct i2c_adapter voodoo3_ddc_adapter = {
-       .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_DDC, 
-       .name           = "DDC Voodoo3/Banshee adapter",
-       .algo_data      = &voo_ddc_bit_data,
-};
-
-static struct pci_device_id voodoo3_ids[] __devinitdata = {
-       { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3) },
-       { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE) },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE (pci, voodoo3_ids);
-
-static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-       int retval;
-
-       retval = config_v3(dev);
-       if (retval)
-               return retval;
-
-       /* set up the sysfs linkage to our parent device */
-       voodoo3_i2c_adapter.dev.parent = &dev->dev;
-       voodoo3_ddc_adapter.dev.parent = &dev->dev;
-
-       retval = i2c_bit_add_bus(&voodoo3_i2c_adapter);
-       if (retval)
-               return retval;
-       retval = i2c_bit_add_bus(&voodoo3_ddc_adapter);
-       if (retval)
-               i2c_del_adapter(&voodoo3_i2c_adapter);
-       return retval;
-}
-
-static void __devexit voodoo3_remove(struct pci_dev *dev)
-{
-       i2c_del_adapter(&voodoo3_i2c_adapter);
-       i2c_del_adapter(&voodoo3_ddc_adapter);
-       iounmap(ioaddr);
-}
-
-static struct pci_driver voodoo3_driver = {
-       .name           = "voodoo3_smbus",
-       .id_table       = voodoo3_ids,
-       .probe          = voodoo3_probe,
-       .remove         = __devexit_p(voodoo3_remove),
-};
-
-static int __init i2c_voodoo3_init(void)
-{
-       return pci_register_driver(&voodoo3_driver);
-}
-
-static void __exit i2c_voodoo3_exit(void)
-{
-       pci_unregister_driver(&voodoo3_driver);
-}
-
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-               "Philip Edelbrock <phil@netroedge.com>, "
-               "Ralph Metzler <rjkm@thp.uni-koeln.de>, "
-               "and Mark D. Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("Voodoo3 I2C/SMBus driver");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_voodoo3_init);
-module_exit(i2c_voodoo3_exit);
index f9618f4d4e476a3530f6023fe400c1e7e038f835..ae4539d99befa8349c046a9f60789eb5935671fe 100644 (file)
@@ -6,16 +6,6 @@
 
 menu "Miscellaneous I2C Chip support"
 
-config DS1682
-       tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
-       depends on EXPERIMENTAL
-       help
-         If you say yes here you get support for Dallas Semiconductor
-         DS1682 Total Elapsed Time Recorder.
-
-         This driver can also be built as a module.  If so, the module
-         will be called ds1682.
-
 config SENSORS_TSL2550
        tristate "Taos TSL2550 ambient light sensor"
        depends on EXPERIMENTAL
index 749cf360629416bd734c031ce268b6b4254b0a86..fe0af0f81f2d74261dfd39661499c54062ea2ffc 100644 (file)
@@ -10,7 +10,6 @@
 # * I/O expander drivers go to drivers/gpio
 #
 
-obj-$(CONFIG_DS1682)           += ds1682.o
 obj-$(CONFIG_SENSORS_TSL2550)  += tsl2550.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
index 296504355142f2f7bb5f3338a30fe79d37f36b8f..4f34823e86b103ffbac7b9f51bb753ddcacf52ba 100644 (file)
@@ -558,11 +558,9 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
        up_read(&__i2c_board_lock);
 }
 
-static int i2c_do_add_adapter(struct device_driver *d, void *data)
+static int i2c_do_add_adapter(struct i2c_driver *driver,
+                             struct i2c_adapter *adap)
 {
-       struct i2c_driver *driver = to_i2c_driver(d);
-       struct i2c_adapter *adap = data;
-
        /* Detect supported devices on that bus, and instantiate them */
        i2c_detect(adap, driver);
 
@@ -574,6 +572,11 @@ static int i2c_do_add_adapter(struct device_driver *d, void *data)
        return 0;
 }
 
+static int __process_new_adapter(struct device_driver *d, void *data)
+{
+       return i2c_do_add_adapter(to_i2c_driver(d), data);
+}
+
 static int i2c_register_adapter(struct i2c_adapter *adap)
 {
        int res = 0, dummy;
@@ -584,7 +587,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
                goto out_list;
        }
 
-       mutex_init(&adap->bus_lock);
+       rt_mutex_init(&adap->bus_lock);
 
        /* Set default timeout to 1 second if not already set */
        if (adap->timeout == 0)
@@ -614,7 +617,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
        /* Notify drivers */
        mutex_lock(&core_lock);
        dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
-                                i2c_do_add_adapter);
+                                __process_new_adapter);
        mutex_unlock(&core_lock);
 
        return 0;
@@ -715,10 +718,9 @@ retry:
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 
-static int i2c_do_del_adapter(struct device_driver *d, void *data)
+static int i2c_do_del_adapter(struct i2c_driver *driver,
+                             struct i2c_adapter *adapter)
 {
-       struct i2c_driver *driver = to_i2c_driver(d);
-       struct i2c_adapter *adapter = data;
        struct i2c_client *client, *_n;
        int res;
 
@@ -750,6 +752,11 @@ static int __unregister_client(struct device *dev, void *dummy)
        return 0;
 }
 
+static int __process_removed_adapter(struct device_driver *d, void *data)
+{
+       return i2c_do_del_adapter(to_i2c_driver(d), data);
+}
+
 /**
  * i2c_del_adapter - unregister I2C adapter
  * @adap: the adapter being unregistered
@@ -777,7 +784,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
        /* Tell drivers about this removal */
        mutex_lock(&core_lock);
        res = bus_for_each_drv(&i2c_bus_type, NULL, adap,
-                              i2c_do_del_adapter);
+                              __process_removed_adapter);
        mutex_unlock(&core_lock);
        if (res)
                return res;
@@ -826,22 +833,11 @@ EXPORT_SYMBOL(i2c_del_adapter);
 
 /* ------------------------------------------------------------------------- */
 
-static int __attach_adapter(struct device *dev, void *data)
+static int __process_new_driver(struct device *dev, void *data)
 {
-       struct i2c_adapter *adapter;
-       struct i2c_driver *driver = data;
-
        if (dev->type != &i2c_adapter_type)
                return 0;
-       adapter = to_i2c_adapter(dev);
-
-       i2c_detect(adapter, driver);
-
-       /* Legacy drivers scan i2c busses directly */
-       if (driver->attach_adapter)
-               driver->attach_adapter(adapter);
-
-       return 0;
+       return i2c_do_add_adapter(data, to_i2c_adapter(dev));
 }
 
 /*
@@ -873,40 +869,18 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
        INIT_LIST_HEAD(&driver->clients);
        /* Walk the adapters that are already present */
        mutex_lock(&core_lock);
-       bus_for_each_dev(&i2c_bus_type, NULL, driver, __attach_adapter);
+       bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver);
        mutex_unlock(&core_lock);
 
        return 0;
 }
 EXPORT_SYMBOL(i2c_register_driver);
 
-static int __detach_adapter(struct device *dev, void *data)
+static int __process_removed_driver(struct device *dev, void *data)
 {
-       struct i2c_adapter *adapter;
-       struct i2c_driver *driver = data;
-       struct i2c_client *client, *_n;
-
        if (dev->type != &i2c_adapter_type)
                return 0;
-       adapter = to_i2c_adapter(dev);
-
-       /* Remove the devices we created ourselves as the result of hardware
-        * probing (using a driver's detect method) */
-       list_for_each_entry_safe(client, _n, &driver->clients, detected) {
-               dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
-                       client->name, client->addr);
-               list_del(&client->detected);
-               i2c_unregister_device(client);
-       }
-
-       if (driver->detach_adapter) {
-               if (driver->detach_adapter(adapter))
-                       dev_err(&adapter->dev,
-                               "detach_adapter failed for driver [%s]\n",
-                               driver->driver.name);
-       }
-
-       return 0;
+       return i2c_do_del_adapter(data, to_i2c_adapter(dev));
 }
 
 /**
@@ -917,7 +891,7 @@ static int __detach_adapter(struct device *dev, void *data)
 void i2c_del_driver(struct i2c_driver *driver)
 {
        mutex_lock(&core_lock);
-       bus_for_each_dev(&i2c_bus_type, NULL, driver, __detach_adapter);
+       bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_removed_driver);
        mutex_unlock(&core_lock);
 
        driver_unregister(&driver->driver);
@@ -1092,12 +1066,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 #endif
 
                if (in_atomic() || irqs_disabled()) {
-                       ret = mutex_trylock(&adap->bus_lock);
+                       ret = rt_mutex_trylock(&adap->bus_lock);
                        if (!ret)
                                /* I2C activity is ongoing. */
                                return -EAGAIN;
                } else {
-                       mutex_lock_nested(&adap->bus_lock, adap->level);
+                       rt_mutex_lock(&adap->bus_lock);
                }
 
                /* Retry automatically on arbitration loss */
@@ -1109,7 +1083,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
                        if (time_after(jiffies, orig_jiffies + adap->timeout))
                                break;
                }
-               mutex_unlock(&adap->bus_lock);
+               rt_mutex_unlock(&adap->bus_lock);
 
                return ret;
        } else {
@@ -1180,7 +1154,7 @@ EXPORT_SYMBOL(i2c_master_recv);
  * ----------------------------------------------------
  */
 
-static int i2c_detect_address(struct i2c_client *temp_client, int kind,
+static int i2c_detect_address(struct i2c_client *temp_client,
                              struct i2c_driver *driver)
 {
        struct i2c_board_info info;
@@ -1199,22 +1173,18 @@ static int i2c_detect_address(struct i2c_client *temp_client, int kind,
        if (i2c_check_addr(adapter, addr))
                return 0;
 
-       /* Make sure there is something at this address, unless forced */
-       if (kind < 0) {
-               if (i2c_smbus_xfer(adapter, addr, 0, 0, 0,
-                                  I2C_SMBUS_QUICK, NULL) < 0)
-                       return 0;
+       /* Make sure there is something at this address */
+       if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
+               return 0;
 
-               /* prevent 24RF08 corruption */
-               if ((addr & ~0x0f) == 0x50)
-                       i2c_smbus_xfer(adapter, addr, 0, 0, 0,
-                                      I2C_SMBUS_QUICK, NULL);
-       }
+       /* Prevent 24RF08 corruption */
+       if ((addr & ~0x0f) == 0x50)
+               i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL);
 
        /* Finally call the custom detection function */
        memset(&info, 0, sizeof(struct i2c_board_info));
        info.addr = addr;
-       err = driver->detect(temp_client, kind, &info);
+       err = driver->detect(temp_client, -1, &info);
        if (err) {
                /* -ENODEV is returned if the detection fails. We catch it
                   here as this isn't an error. */
@@ -1259,40 +1229,13 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
                return -ENOMEM;
        temp_client->adapter = adapter;
 
-       /* Force entries are done first, and are not affected by ignore
-          entries */
-       if (address_data->forces) {
-               const unsigned short * const *forces = address_data->forces;
-               int kind;
-
-               for (kind = 0; forces[kind]; kind++) {
-                       for (i = 0; forces[kind][i] != I2C_CLIENT_END;
-                            i += 2) {
-                               if (forces[kind][i] == adap_id
-                                || forces[kind][i] == ANY_I2C_BUS) {
-                                       dev_dbg(&adapter->dev, "found force "
-                                               "parameter for adapter %d, "
-                                               "addr 0x%02x, kind %d\n",
-                                               adap_id, forces[kind][i + 1],
-                                               kind);
-                                       temp_client->addr = forces[kind][i + 1];
-                                       err = i2c_detect_address(temp_client,
-                                               kind, driver);
-                                       if (err)
-                                               goto exit_free;
-                               }
-                       }
-               }
-       }
-
        /* Stop here if the classes do not match */
        if (!(adapter->class & driver->class))
                goto exit_free;
 
        /* Stop here if we can't use SMBUS_QUICK */
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {
-               if (address_data->probe[0] == I2C_CLIENT_END
-                && address_data->normal_i2c[0] == I2C_CLIENT_END)
+               if (address_data->normal_i2c[0] == I2C_CLIENT_END)
                        goto exit_free;
 
                dev_warn(&adapter->dev, "SMBus Quick command not supported, "
@@ -1301,48 +1244,12 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
                goto exit_free;
        }
 
-       /* Probe entries are done second, and are not affected by ignore
-          entries either */
-       for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) {
-               if (address_data->probe[i] == adap_id
-                || address_data->probe[i] == ANY_I2C_BUS) {
-                       dev_dbg(&adapter->dev, "found probe parameter for "
-                               "adapter %d, addr 0x%02x\n", adap_id,
-                               address_data->probe[i + 1]);
-                       temp_client->addr = address_data->probe[i + 1];
-                       err = i2c_detect_address(temp_client, -1, driver);
-                       if (err)
-                               goto exit_free;
-               }
-       }
-
-       /* Normal entries are done last, unless shadowed by an ignore entry */
        for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) {
-               int j, ignore;
-
-               ignore = 0;
-               for (j = 0; address_data->ignore[j] != I2C_CLIENT_END;
-                    j += 2) {
-                       if ((address_data->ignore[j] == adap_id ||
-                            address_data->ignore[j] == ANY_I2C_BUS)
-                        && address_data->ignore[j + 1]
-                           == address_data->normal_i2c[i]) {
-                               dev_dbg(&adapter->dev, "found ignore "
-                                       "parameter for adapter %d, "
-                                       "addr 0x%02x\n", adap_id,
-                                       address_data->ignore[j + 1]);
-                               ignore = 1;
-                               break;
-                       }
-               }
-               if (ignore)
-                       continue;
-
                dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
                        "addr 0x%02x\n", adap_id,
                        address_data->normal_i2c[i]);
                temp_client->addr = address_data->normal_i2c[i];
-               err = i2c_detect_address(temp_client, -1, driver);
+               err = i2c_detect_address(temp_client, driver);
                if (err)
                        goto exit_free;
        }
@@ -1913,7 +1820,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
        flags &= I2C_M_TEN | I2C_CLIENT_PEC;
 
        if (adapter->algo->smbus_xfer) {
-               mutex_lock(&adapter->bus_lock);
+               rt_mutex_lock(&adapter->bus_lock);
 
                /* Retry automatically on arbitration loss */
                orig_jiffies = jiffies;
@@ -1927,7 +1834,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
                                       orig_jiffies + adapter->timeout))
                                break;
                }
-               mutex_unlock(&adapter->bus_lock);
+               rt_mutex_unlock(&adapter->bus_lock);
        } else
                res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
                                              command, protocol, data);
index 7e13d2df9af384f0b048faa36c427171dab30fa0..f4110aa49600ea5379ba7fc7f7ab7d6ba7b47983 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/list.h>
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
-#include <linux/smp_lock.h>
 #include <linux/jiffies.h>
 #include <asm/uaccess.h>
 
@@ -445,20 +444,14 @@ static int i2cdev_open(struct inode *inode, struct file *file)
        struct i2c_client *client;
        struct i2c_adapter *adap;
        struct i2c_dev *i2c_dev;
-       int ret = 0;
 
-       lock_kernel();
        i2c_dev = i2c_dev_get_by_minor(minor);
-       if (!i2c_dev) {
-               ret = -ENODEV;
-               goto out;
-       }
+       if (!i2c_dev)
+               return -ENODEV;
 
        adap = i2c_get_adapter(i2c_dev->adap->nr);
-       if (!adap) {
-               ret = -ENODEV;
-               goto out;
-       }
+       if (!adap)
+               return -ENODEV;
 
        /* This creates an anonymous i2c_client, which may later be
         * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
@@ -470,8 +463,7 @@ static int i2cdev_open(struct inode *inode, struct file *file)
        client = kzalloc(sizeof(*client), GFP_KERNEL);
        if (!client) {
                i2c_put_adapter(adap);
-               ret = -ENOMEM;
-               goto out;
+               return -ENOMEM;
        }
        snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
        client->driver = &i2cdev_driver;
@@ -479,9 +471,7 @@ static int i2cdev_open(struct inode *inode, struct file *file)
        client->adapter = adap;
        file->private_data = client;
 
-out:
-       unlock_kernel();
-       return ret;
+       return 0;
 }
 
 static int i2cdev_release(struct inode *inode, struct file *file)
index a2ea383105a61199557e9319679a52729f78ec07..2c16ca6501d5f58ab9ab66c9f718be22042a8126 100644 (file)
@@ -246,6 +246,16 @@ config EP93XX_PWM
          To compile this driver as a module, choose M here: the module will
          be called ep93xx_pwm.
 
+config DS1682
+       tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
+       depends on I2C && EXPERIMENTAL
+       help
+         If you say yes here you get support for Dallas Semiconductor
+         DS1682 Total Elapsed Time Recorder.
+
+         This driver can also be built as a module.  If so, the module
+         will be called ds1682.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
index e311267a355fa04144e72f33b82489a731f1cec5..906a0edcea40e16f79d7af76c1635edd995fd684 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_SGI_GRU)         += sgi-gru/
 obj-$(CONFIG_HP_ILO)           += hpilo.o
 obj-$(CONFIG_ISL29003)         += isl29003.o
 obj-$(CONFIG_EP93XX_PWM)       += ep93xx_pwm.o
+obj-$(CONFIG_DS1682)           += ds1682.o
 obj-$(CONFIG_C2PORT)           += c2port/
 obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-y                          += eeprom/
index 6e43ab4231ae9924661d0f3b663e20cb5577c6c0..4bb7a3af9ad97bb1e5e8a2e02a03ebf54165e135 100644 (file)
@@ -417,32 +417,25 @@ static int ics932s401_detect(struct i2c_client *client, int kind,
                          struct i2c_board_info *info)
 {
        struct i2c_adapter *adapter = client->adapter;
+       int vendor, device, revision;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -ENODEV;
 
-       if (kind <= 0) {
-               int vendor, device, revision;
-
-               vendor = i2c_smbus_read_word_data(client,
-                                                 ICS932S401_REG_VENDOR_REV);
-               vendor >>= 8;
-               revision = vendor >> ICS932S401_REV_SHIFT;
-               vendor &= ICS932S401_VENDOR_MASK;
-               if (vendor != ICS932S401_VENDOR)
-                       return -ENODEV;
-
-               device = i2c_smbus_read_word_data(client,
-                                                 ICS932S401_REG_DEVICE);
-               device >>= 8;
-               if (device != ICS932S401_DEVICE)
-                       return -ENODEV;
-
-               if (revision != ICS932S401_REV)
-                       dev_info(&adapter->dev, "Unknown revision %d\n",
-                                revision);
-       } else
-               dev_dbg(&adapter->dev, "detection forced\n");
+       vendor = i2c_smbus_read_word_data(client, ICS932S401_REG_VENDOR_REV);
+       vendor >>= 8;
+       revision = vendor >> ICS932S401_REV_SHIFT;
+       vendor &= ICS932S401_VENDOR_MASK;
+       if (vendor != ICS932S401_VENDOR)
+               return -ENODEV;
+
+       device = i2c_smbus_read_word_data(client, ICS932S401_REG_DEVICE);
+       device >>= 8;
+       if (device != ICS932S401_DEVICE)
+               return -ENODEV;
+
+       if (revision != ICS932S401_REV)
+               dev_info(&adapter->dev, "Unknown revision %d\n", revision);
 
        strlcpy(info->type, "ics932s401", I2C_NAME_SIZE);
 
index 7b40cda57a702273fcbdeb7ba7487fdfe1406aff..419ab546b2661909149eed8f362e40f75c240898 100644 (file)
@@ -110,7 +110,7 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
  * @driver: Device driver model driver
  * @id_table: List of I2C devices supported by this driver
  * @detect: Callback for device detection
- * @address_data: The I2C addresses to probe, ignore or force (for detect)
+ * @address_data: The I2C addresses to probe (for detect)
  * @clients: List of detected clients we created (for i2c-core use only)
  *
  * The driver.owner field should be set to the module owner of this driver.
@@ -338,8 +338,7 @@ struct i2c_adapter {
        void *algo_data;
 
        /* data fields that are valid for all devices   */
-       u8 level;                       /* nesting level for lockdep */
-       struct mutex bus_lock;
+       struct rt_mutex bus_lock;
 
        int timeout;                    /* in jiffies */
        int retries;
@@ -367,7 +366,7 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
  */
 static inline void i2c_lock_adapter(struct i2c_adapter *adapter)
 {
-       mutex_lock(&adapter->bus_lock);
+       rt_mutex_lock(&adapter->bus_lock);
 }
 
 /**
@@ -376,7 +375,7 @@ static inline void i2c_lock_adapter(struct i2c_adapter *adapter)
  */
 static inline void i2c_unlock_adapter(struct i2c_adapter *adapter)
 {
-       mutex_unlock(&adapter->bus_lock);
+       rt_mutex_unlock(&adapter->bus_lock);
 }
 
 /*flags for the client struct: */
@@ -398,9 +397,6 @@ static inline void i2c_unlock_adapter(struct i2c_adapter *adapter)
  */
 struct i2c_client_address_data {
        const unsigned short *normal_i2c;
-       const unsigned short *probe;
-       const unsigned short *ignore;
-       const unsigned short * const *forces;
 };
 
 /* Internal numbers to terminate lists */
@@ -614,134 +610,48 @@ union i2c_smbus_data {
   module_param_array(var, short, &var##_num, 0); \
   MODULE_PARM_DESC(var, desc)
 
-#define I2C_CLIENT_MODULE_PARM_FORCE(name)                             \
-I2C_CLIENT_MODULE_PARM(force_##name,                                   \
-                      "List of adapter,address pairs which are "       \
-                      "unquestionably assumed to contain a `"          \
-                      # name "' chip")
-
-
 #define I2C_CLIENT_INSMOD_COMMON                                       \
-I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \
-                      "additionally");                                 \
-I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \
-                      "scan");                                         \
 static const struct i2c_client_address_data addr_data = {              \
        .normal_i2c     = normal_i2c,                                   \
-       .probe          = probe,                                        \
-       .ignore         = ignore,                                       \
-       .forces         = forces,                                       \
 }
 
-#define I2C_CLIENT_FORCE_TEXT \
-       "List of adapter,address pairs to boldly assume to be present"
-
 /* These are the ones you want to use in your own drivers. Pick the one
    which matches the number of devices the driver differenciates between. */
 #define I2C_CLIENT_INSMOD                                              \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-static const unsigned short * const forces[] = { force, NULL };                \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_1(chip1)                                     \
 enum chips { any_chip, chip1 };                                                \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-static const unsigned short * const forces[] = { force,                \
-       force_##chip1, NULL };                                          \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_2(chip1, chip2)                              \
 enum chips { any_chip, chip1, chip2 };                                 \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip2);                                   \
-static const unsigned short * const forces[] = { force,                \
-       force_##chip1, force_##chip2, NULL };                           \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3)                       \
 enum chips { any_chip, chip1, chip2, chip3 };                          \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip2);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip3);                                   \
-static const unsigned short * const forces[] = { force,                \
-       force_##chip1, force_##chip2, force_##chip3, NULL };            \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4)                        \
 enum chips { any_chip, chip1, chip2, chip3, chip4 };                   \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip2);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip3);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip4);                                   \
-static const unsigned short * const forces[] = { force,                \
-       force_##chip1, force_##chip2, force_##chip3,                    \
-       force_##chip4, NULL};                                           \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5)         \
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 };            \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip2);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip3);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip4);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip5);                                   \
-static const unsigned short * const forces[] = { force,                        \
-       force_##chip1, force_##chip2, force_##chip3,                    \
-       force_##chip4, force_##chip5, NULL };                           \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6)  \
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 };     \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip2);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip3);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip4);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip5);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip6);                                   \
-static const unsigned short * const forces[] = { force,                        \
-       force_##chip1, force_##chip2, force_##chip3,                    \
-       force_##chip4, force_##chip5, force_##chip6, NULL };            \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,       \
             chip7 };                                                   \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip2);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip3);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip4);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip5);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip6);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip7);                                   \
-static const unsigned short * const forces[] = { force,                        \
-       force_##chip1, force_##chip2, force_##chip3,                    \
-       force_##chip4, force_##chip5, force_##chip6,                    \
-       force_##chip7, NULL };                                          \
 I2C_CLIENT_INSMOD_COMMON
 
 #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,       \
             chip7, chip8 };                                            \
-I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT);                  \
-I2C_CLIENT_MODULE_PARM_FORCE(chip1);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip2);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip3);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip4);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip5);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip6);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip7);                                   \
-I2C_CLIENT_MODULE_PARM_FORCE(chip8);                                   \
-static const unsigned short * const forces[] = { force,                        \
-       force_##chip1, force_##chip2, force_##chip3,                    \
-       force_##chip4, force_##chip5, force_##chip6,                    \
-       force_##chip7, force_##chip8, NULL };                           \
 I2C_CLIENT_INSMOD_COMMON
 #endif /* __KERNEL__ */
 #endif /* _LINUX_I2C_H */