Browse Source

Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging

* '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
Linus Torvalds 15 years ago
parent
commit
41440ffe21

+ 0 - 9
Documentation/feature-removal-schedule.txt

@@ -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
 What:	CONFIG_RFKILL_INPUT
 When:	2.6.33
 When:	2.6.33
 Why:	Should be implemented in userspace, policy daemon.
 Why:	Should be implemented in userspace, policy daemon.

+ 0 - 62
Documentation/i2c/busses/i2c-voodoo3

@@ -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.

+ 11 - 5
Documentation/i2c/i2c-stub

@@ -2,9 +2,9 @@ MODULE: i2c-stub
 
 
 DESCRIPTION:
 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
 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.
 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:
 The typical use-case is like this:
 	1. load this module
 	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
 	4. observe its behavior in the kernel log
 
 
 There's a script named i2c-stub-from-dump in the i2c-tools package which
 There's a script named i2c-stub-from-dump in the i2c-tools package which
@@ -33,6 +33,12 @@ PARAMETERS:
 int chip_addr[10]:
 int chip_addr[10]:
 	The SMBus addresses to emulate chips at.
 	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:
 CAVEATS:
 
 
 If your target driver polls some byte or word waiting for it to change, the
 If your target driver polls some byte or word waiting for it to change, the

+ 44 - 0
Documentation/i2c/old-module-parameters

@@ -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".

+ 1 - 5
arch/powerpc/include/asm/pmac_low_i2c.h

@@ -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_flags(struct pmac_i2c_bus *bus);
 extern int pmac_i2c_get_channel(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 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);
 extern struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter);
 
 

+ 5 - 20
arch/powerpc/platforms/powermac/low_i2c.c

@@ -42,6 +42,7 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/timer.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
+#include <linux/i2c.h>
 #include <asm/keylargo.h>
 #include <asm/keylargo.h>
 #include <asm/uninorth.h>
 #include <asm/uninorth.h>
 #include <asm/io.h>
 #include <asm/io.h>
@@ -80,7 +81,7 @@ struct pmac_i2c_bus
 	struct device_node	*busnode;
 	struct device_node	*busnode;
 	int			type;
 	int			type;
 	int			flags;
 	int			flags;
-	struct i2c_adapter	*adapter;
+	struct i2c_adapter	adapter;
 	void			*hostdata;
 	void			*hostdata;
 	int			channel;	/* some hosts have multiple */
 	int			channel;	/* some hosts have multiple */
 	int			mode;		/* current mode */
 	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);
 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)
 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);
 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;
 	struct pmac_i2c_bus *bus;
 
 
 	list_for_each_entry(bus, &pmac_i2c_busses, link)
 	list_for_each_entry(bus, &pmac_i2c_busses, link)
-		if (bus->adapter == adapter)
+		if (&bus->adapter == adapter)
 			return bus;
 			return bus;
 	return NULL;
 	return NULL;
 }
 }
@@ -1053,7 +1038,7 @@ int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter)
 
 
 	if (bus == NULL)
 	if (bus == NULL)
 		return 0;
 		return 0;
-	return (bus->adapter == adapter);
+	return (&bus->adapter == adapter);
 }
 }
 EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter);
 EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter);
 
 

+ 1 - 0
drivers/i2c/Kconfig

@@ -5,6 +5,7 @@
 menuconfig I2C
 menuconfig I2C
 	tristate "I2C support"
 	tristate "I2C support"
 	depends on HAS_IOMEM
 	depends on HAS_IOMEM
+	select RT_MUTEXES
 	---help---
 	---help---
 	  I2C (pronounce: I-square-C) is a slow serial bus protocol used in
 	  I2C (pronounce: I-square-C) is a slow serial bus protocol used in
 	  many micro controller applications and developed by Philips.  SMBus,
 	  many micro controller applications and developed by Philips.  SMBus,

+ 0 - 16
drivers/i2c/busses/Kconfig

@@ -640,22 +640,6 @@ config I2C_TINY_USB
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-tiny-usb.
 	  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"
 comment "Other I2C/SMBus bus drivers"
 
 
 config I2C_ACORN
 config I2C_ACORN

+ 0 - 3
drivers/i2c/busses/Makefile

@@ -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_TAOS_EVM)	+= i2c-taos-evm.o
 obj-$(CONFIG_I2C_TINY_USB)	+= i2c-tiny-usb.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
 # Other I2C/SMBus bus drivers
 obj-$(CONFIG_I2C_ACORN)		+= i2c-acorn.o
 obj-$(CONFIG_I2C_ACORN)		+= i2c-acorn.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o

+ 1 - 1
drivers/i2c/busses/i2c-ali1535.c

@@ -138,7 +138,7 @@ static unsigned short ali1535_smba;
    Note the differences between kernels with the old PCI BIOS interface and
    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
    newer kernels with the real PCI interface. In compat.h some things are
    defined to make the transition easier. */
    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;
 	int retval = -ENODEV;
 	unsigned char temp;
 	unsigned char temp;

+ 1 - 1
drivers/i2c/busses/i2c-ali15x3.c

@@ -131,7 +131,7 @@ MODULE_PARM_DESC(force_addr,
 static struct pci_driver ali15x3_driver;
 static struct pci_driver ali15x3_driver;
 static unsigned short ali15x3_smba;
 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;
 	u16 a;
 	unsigned char temp;
 	unsigned char temp;

+ 3 - 0
drivers/i2c/busses/i2c-i801.c

@@ -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 */
 	/* set up the sysfs linkage to our parent device */
 	i801_adapter.dev.parent = &dev->dev;
 	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),
 	snprintf(i801_adapter.name, sizeof(i801_adapter.name),
 		"SMBus I801 adapter at %04lx", i801_smba);
 		"SMBus I801 adapter at %04lx", i801_smba);
 	err = i2c_add_adapter(&i801_adapter);
 	err = i2c_add_adapter(&i801_adapter);

+ 0 - 6
drivers/i2c/busses/i2c-iop3xx.c

@@ -56,12 +56,6 @@ iic_cook_addr(struct i2c_msg *msg)
 	if (msg->flags & I2C_M_RD)
 	if (msg->flags & I2C_M_RD)
 		addr |= 1;
 		addr |= 1;
 
 
-	/*
-	 * Read or Write?
-	 */
-	if (msg->flags & I2C_M_REV_DIR_ADDR)
-		addr ^= 1;
-
 	return addr;   
 	return addr;   
 }
 }
 
 

+ 0 - 3
drivers/i2c/busses/i2c-mv64xxx.c

@@ -338,9 +338,6 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
 	if (msg->flags & I2C_M_RD)
 	if (msg->flags & I2C_M_RD)
 		dir = 1;
 		dir = 1;
 
 
-	if (msg->flags & I2C_M_REV_DIR_ADDR)
-		dir ^= 1;
-
 	if (msg->flags & I2C_M_TEN) {
 	if (msg->flags & I2C_M_TEN) {
 		drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
 		drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
 		drv_data->addr2 = (u32)msg->addr & 0xff;
 		drv_data->addr2 = (u32)msg->addr & 0xff;

+ 74 - 65
drivers/i2c/busses/i2c-powermac.c

@@ -49,48 +49,38 @@ static s32 i2c_powermac_smbus_xfer(	struct i2c_adapter*	adap,
 	int			rc = 0;
 	int			rc = 0;
 	int			read = (read_write == I2C_SMBUS_READ);
 	int			read = (read_write == I2C_SMBUS_READ);
 	int			addrdir = (addr << 1) | read;
 	int			addrdir = (addr << 1) | read;
+	int			mode, subsize, len;
+	u32			subaddr;
+	u8			*buf;
 	u8			local[2];
 	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) {
 	switch (size) {
         case I2C_SMBUS_QUICK:
         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;
 	    	break;
         case I2C_SMBUS_BYTE:
         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:
         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;
 	    	break;
         case I2C_SMBUS_WORD_DATA:
         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) {
 		if (!read) {
 			local[0] = data->word & 0xff;
 			local[0] = data->word & 0xff;
 			local[1] = (data->word >> 8) & 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;
 	    	break;
 
 
 	/* Note that these are broken vs. the expected smbus API where
 	/* 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)
 	 * a repeat start/addr phase (but not stop in between)
 	 */
 	 */
         case I2C_SMBUS_BLOCK_DATA:
         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;
 		break;
 	case I2C_SMBUS_I2C_BLOCK_DATA:
 	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;
 		break;
 
 
         default:
         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:
  bail:
 	pmac_i2c_close(bus);
 	pmac_i2c_close(bus);
 	return rc;
 	return rc;
@@ -146,20 +152,33 @@ static int i2c_powermac_master_xfer(	struct i2c_adapter *adap,
 	int			read;
 	int			read;
 	int			addrdir;
 	int			addrdir;
 
 
+	if (num != 1) {
+		dev_err(&adap->dev,
+			"Multi-message I2C transactions not supported\n");
+		return -EOPNOTSUPP;
+	}
+
 	if (msgs->flags & I2C_M_TEN)
 	if (msgs->flags & I2C_M_TEN)
 		return -EINVAL;
 		return -EINVAL;
 	read = (msgs->flags & I2C_M_RD) != 0;
 	read = (msgs->flags & I2C_M_RD) != 0;
 	addrdir = (msgs->addr << 1) | read;
 	addrdir = (msgs->addr << 1) | read;
-	if (msgs->flags & I2C_M_REV_DIR_ADDR)
-		addrdir ^= 1;
 
 
 	rc = pmac_i2c_open(bus, 0);
 	rc = pmac_i2c_open(bus, 0);
-	if (rc)
+	if (rc) {
+		dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc);
 		return rc;
 		return rc;
+	}
 	rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std);
 	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;
 		goto bail;
+	}
 	rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len);
 	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:
  bail:
 	pmac_i2c_close(bus);
 	pmac_i2c_close(bus);
 	return rc < 0 ? rc : 1;
 	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)
 static int __devexit i2c_powermac_remove(struct platform_device *dev)
 {
 {
 	struct i2c_adapter	*adapter = platform_get_drvdata(dev);
 	struct i2c_adapter	*adapter = platform_get_drvdata(dev);
-	struct pmac_i2c_bus	*bus = i2c_get_adapdata(adapter);
 	int			rc;
 	int			rc;
 
 
 	rc = i2c_del_adapter(adapter);
 	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... */
 	/* We aren't that prepared to deal with this... */
 	if (rc)
 	if (rc)
 		printk(KERN_WARNING
 		printk(KERN_WARNING
 		       "i2c-powermac.c: Failed to remove bus %s !\n",
 		       "i2c-powermac.c: Failed to remove bus %s !\n",
 		       adapter->name);
 		       adapter->name);
 	platform_set_drvdata(dev, NULL);
 	platform_set_drvdata(dev, NULL);
-	kfree(adapter);
+	memset(adapter, 0, sizeof(*adapter));
 
 
 	return 0;
 	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 pmac_i2c_bus *bus = dev->dev.platform_data;
 	struct device_node *parent = NULL;
 	struct device_node *parent = NULL;
 	struct i2c_adapter *adapter;
 	struct i2c_adapter *adapter;
-	char name[32];
 	const char *basename;
 	const char *basename;
 	int rc;
 	int rc;
 
 
 	if (bus == NULL)
 	if (bus == NULL)
 		return -EINVAL;
 		return -EINVAL;
+	adapter = pmac_i2c_get_adapter(bus);
 
 
 	/* Ok, now we need to make up a name for the interface that will
 	/* 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
 	 * 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:
 	default:
 		return -EINVAL;
 		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);
 	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);
 	platform_set_drvdata(dev, adapter);
-	strcpy(adapter->name, name);
 	adapter->algo = &i2c_powermac_algorithm;
 	adapter->algo = &i2c_powermac_algorithm;
 	i2c_set_adapdata(adapter, bus);
 	i2c_set_adapdata(adapter, bus);
 	adapter->dev.parent = &dev->dev;
 	adapter->dev.parent = &dev->dev;
-	pmac_i2c_attach_adapter(bus, adapter);
 	rc = i2c_add_adapter(adapter);
 	rc = i2c_add_adapter(adapter);
 	if (rc) {
 	if (rc) {
 		printk(KERN_ERR "i2c-powermac: Adapter %s registration "
 		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)) {
 	if (!strncmp(basename, "uni-n", 5)) {
 		struct device_node *np;
 		struct device_node *np;

+ 1 - 1
drivers/i2c/busses/i2c-sis5595.c

@@ -142,7 +142,7 @@ static void sis5595_write(u8 reg, u8 data)
 	outb(data, sis5595_base + SMB_DAT);
 	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;
 	u16 a;
 	u8 val;
 	u8 val;

+ 1 - 1
drivers/i2c/busses/i2c-sis630.c

@@ -389,7 +389,7 @@ static u32 sis630_func(struct i2c_adapter *adapter)
 		I2C_FUNC_SMBUS_BLOCK_DATA;
 		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;
 	unsigned char b;
 	struct pci_dev *dummy = NULL;
 	struct pci_dev *dummy = NULL;

+ 31 - 3
drivers/i2c/busses/i2c-stub.c

@@ -35,6 +35,10 @@ module_param_array(chip_addr, ushort, NULL, S_IRUGO);
 MODULE_PARM_DESC(chip_addr,
 MODULE_PARM_DESC(chip_addr,
 		 "Chip addresses (up to 10, between 0x03 and 0x77)");
 		 "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 {
 struct stub_chip {
 	u8 pointer;
 	u8 pointer;
 	u16 words[256];		/* Byte operations use the LSB as per SMBus
 	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)
 	char read_write, u8 command, int size, union i2c_smbus_data * data)
 {
 {
 	s32 ret;
 	s32 ret;
-	int i;
+	int i, len;
 	struct stub_chip *chip = NULL;
 	struct stub_chip *chip = NULL;
 
 
 	/* Search for the right chip */
 	/* Search for the right chip */
@@ -118,6 +122,29 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
 		ret = 0;
 		ret = 0;
 		break;
 		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:
 	default:
 		dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
 		dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
 		ret = -EOPNOTSUPP;
 		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)
 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 = {
 static const struct i2c_algorithm smbus_algorithm = {

+ 0 - 248
drivers/i2c/busses/i2c-voodoo3.c

@@ -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);

+ 0 - 10
drivers/i2c/chips/Kconfig

@@ -6,16 +6,6 @@
 
 
 menu "Miscellaneous I2C Chip support"
 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
 config SENSORS_TSL2550
 	tristate "Taos TSL2550 ambient light sensor"
 	tristate "Taos TSL2550 ambient light sensor"
 	depends on EXPERIMENTAL
 	depends on EXPERIMENTAL

+ 0 - 1
drivers/i2c/chips/Makefile

@@ -10,7 +10,6 @@
 # * I/O expander drivers go to drivers/gpio
 # * I/O expander drivers go to drivers/gpio
 #
 #
 
 
-obj-$(CONFIG_DS1682)		+= ds1682.o
 obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
 obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
 
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)

+ 38 - 131
drivers/i2c/i2c-core.c

@@ -558,11 +558,9 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
 	up_read(&__i2c_board_lock);
 	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 */
 	/* Detect supported devices on that bus, and instantiate them */
 	i2c_detect(adap, driver);
 	i2c_detect(adap, driver);
 
 
@@ -574,6 +572,11 @@ static int i2c_do_add_adapter(struct device_driver *d, void *data)
 	return 0;
 	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)
 static int i2c_register_adapter(struct i2c_adapter *adap)
 {
 {
 	int res = 0, dummy;
 	int res = 0, dummy;
@@ -584,7 +587,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 		goto out_list;
 		goto out_list;
 	}
 	}
 
 
-	mutex_init(&adap->bus_lock);
+	rt_mutex_init(&adap->bus_lock);
 
 
 	/* Set default timeout to 1 second if not already set */
 	/* Set default timeout to 1 second if not already set */
 	if (adap->timeout == 0)
 	if (adap->timeout == 0)
@@ -614,7 +617,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 	/* Notify drivers */
 	/* Notify drivers */
 	mutex_lock(&core_lock);
 	mutex_lock(&core_lock);
 	dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
 	dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
-				 i2c_do_add_adapter);
+				 __process_new_adapter);
 	mutex_unlock(&core_lock);
 	mutex_unlock(&core_lock);
 
 
 	return 0;
 	return 0;
@@ -715,10 +718,9 @@ retry:
 }
 }
 EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter);
 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;
 	struct i2c_client *client, *_n;
 	int res;
 	int res;
 
 
@@ -750,6 +752,11 @@ static int __unregister_client(struct device *dev, void *dummy)
 	return 0;
 	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
  * i2c_del_adapter - unregister I2C adapter
  * @adap: the adapter being unregistered
  * @adap: the adapter being unregistered
@@ -777,7 +784,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
 	/* Tell drivers about this removal */
 	/* Tell drivers about this removal */
 	mutex_lock(&core_lock);
 	mutex_lock(&core_lock);
 	res = bus_for_each_drv(&i2c_bus_type, NULL, adap,
 	res = bus_for_each_drv(&i2c_bus_type, NULL, adap,
-			       i2c_do_del_adapter);
+			       __process_removed_adapter);
 	mutex_unlock(&core_lock);
 	mutex_unlock(&core_lock);
 	if (res)
 	if (res)
 		return 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)
 	if (dev->type != &i2c_adapter_type)
 		return 0;
 		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);
 	INIT_LIST_HEAD(&driver->clients);
 	/* Walk the adapters that are already present */
 	/* Walk the adapters that are already present */
 	mutex_lock(&core_lock);
 	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);
 	mutex_unlock(&core_lock);
 
 
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL(i2c_register_driver);
 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)
 	if (dev->type != &i2c_adapter_type)
 		return 0;
 		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)
 void i2c_del_driver(struct i2c_driver *driver)
 {
 {
 	mutex_lock(&core_lock);
 	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);
 	mutex_unlock(&core_lock);
 
 
 	driver_unregister(&driver->driver);
 	driver_unregister(&driver->driver);
@@ -1092,12 +1066,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 #endif
 #endif
 
 
 		if (in_atomic() || irqs_disabled()) {
 		if (in_atomic() || irqs_disabled()) {
-			ret = mutex_trylock(&adap->bus_lock);
+			ret = rt_mutex_trylock(&adap->bus_lock);
 			if (!ret)
 			if (!ret)
 				/* I2C activity is ongoing. */
 				/* I2C activity is ongoing. */
 				return -EAGAIN;
 				return -EAGAIN;
 		} else {
 		} else {
-			mutex_lock_nested(&adap->bus_lock, adap->level);
+			rt_mutex_lock(&adap->bus_lock);
 		}
 		}
 
 
 		/* Retry automatically on arbitration loss */
 		/* 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))
 			if (time_after(jiffies, orig_jiffies + adap->timeout))
 				break;
 				break;
 		}
 		}
-		mutex_unlock(&adap->bus_lock);
+		rt_mutex_unlock(&adap->bus_lock);
 
 
 		return ret;
 		return ret;
 	} else {
 	} 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_driver *driver)
 {
 {
 	struct i2c_board_info info;
 	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))
 	if (i2c_check_addr(adapter, addr))
 		return 0;
 		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 */
 	/* Finally call the custom detection function */
 	memset(&info, 0, sizeof(struct i2c_board_info));
 	memset(&info, 0, sizeof(struct i2c_board_info));
 	info.addr = addr;
 	info.addr = addr;
-	err = driver->detect(temp_client, kind, &info);
+	err = driver->detect(temp_client, -1, &info);
 	if (err) {
 	if (err) {
 		/* -ENODEV is returned if the detection fails. We catch it
 		/* -ENODEV is returned if the detection fails. We catch it
 		   here as this isn't an error. */
 		   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;
 		return -ENOMEM;
 	temp_client->adapter = adapter;
 	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 */
 	/* Stop here if the classes do not match */
 	if (!(adapter->class & driver->class))
 	if (!(adapter->class & driver->class))
 		goto exit_free;
 		goto exit_free;
 
 
 	/* Stop here if we can't use SMBUS_QUICK */
 	/* Stop here if we can't use SMBUS_QUICK */
 	if (!i2c_check_functionality(adapter, I2C_FUNC_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;
 			goto exit_free;
 
 
 		dev_warn(&adapter->dev, "SMBus Quick command not supported, "
 		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;
 		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) {
 	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, "
 		dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
 			"addr 0x%02x\n", adap_id,
 			"addr 0x%02x\n", adap_id,
 			address_data->normal_i2c[i]);
 			address_data->normal_i2c[i]);
 		temp_client->addr = 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)
 		if (err)
 			goto exit_free;
 			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;
 	flags &= I2C_M_TEN | I2C_CLIENT_PEC;
 
 
 	if (adapter->algo->smbus_xfer) {
 	if (adapter->algo->smbus_xfer) {
-		mutex_lock(&adapter->bus_lock);
+		rt_mutex_lock(&adapter->bus_lock);
 
 
 		/* Retry automatically on arbitration loss */
 		/* Retry automatically on arbitration loss */
 		orig_jiffies = jiffies;
 		orig_jiffies = jiffies;
@@ -1927,7 +1834,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
 				       orig_jiffies + adapter->timeout))
 				       orig_jiffies + adapter->timeout))
 				break;
 				break;
 		}
 		}
-		mutex_unlock(&adapter->bus_lock);
+		rt_mutex_unlock(&adapter->bus_lock);
 	} else
 	} else
 		res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
 		res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
 					      command, protocol, data);
 					      command, protocol, data);

+ 6 - 16
drivers/i2c/i2c-dev.c

@@ -34,7 +34,6 @@
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
 #include <linux/i2c-dev.h>
-#include <linux/smp_lock.h>
 #include <linux/jiffies.h>
 #include <linux/jiffies.h>
 #include <asm/uaccess.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_client *client;
 	struct i2c_adapter *adap;
 	struct i2c_adapter *adap;
 	struct i2c_dev *i2c_dev;
 	struct i2c_dev *i2c_dev;
-	int ret = 0;
 
 
-	lock_kernel();
 	i2c_dev = i2c_dev_get_by_minor(minor);
 	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);
 	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
 	/* This creates an anonymous i2c_client, which may later be
 	 * pointed to some address using I2C_SLAVE or I2C_SLAVE_FORCE.
 	 * 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);
 	client = kzalloc(sizeof(*client), GFP_KERNEL);
 	if (!client) {
 	if (!client) {
 		i2c_put_adapter(adap);
 		i2c_put_adapter(adap);
-		ret = -ENOMEM;
-		goto out;
+		return -ENOMEM;
 	}
 	}
 	snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
 	snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
 	client->driver = &i2cdev_driver;
 	client->driver = &i2cdev_driver;
@@ -479,9 +471,7 @@ static int i2cdev_open(struct inode *inode, struct file *file)
 	client->adapter = adap;
 	client->adapter = adap;
 	file->private_data = client;
 	file->private_data = client;
 
 
-out:
-	unlock_kernel();
-	return ret;
+	return 0;
 }
 }
 
 
 static int i2cdev_release(struct inode *inode, struct file *file)
 static int i2cdev_release(struct inode *inode, struct file *file)

+ 10 - 0
drivers/misc/Kconfig

@@ -246,6 +246,16 @@ config EP93XX_PWM
 	  To compile this driver as a module, choose M here: the module will
 	  To compile this driver as a module, choose M here: the module will
 	  be called ep93xx_pwm.
 	  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/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
 source "drivers/misc/cb710/Kconfig"

+ 1 - 0
drivers/misc/Makefile

@@ -20,6 +20,7 @@ obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
 obj-$(CONFIG_ISL29003)		+= isl29003.o
 obj-$(CONFIG_ISL29003)		+= isl29003.o
 obj-$(CONFIG_EP93XX_PWM)	+= ep93xx_pwm.o
 obj-$(CONFIG_EP93XX_PWM)	+= ep93xx_pwm.o
+obj-$(CONFIG_DS1682)		+= ds1682.o
 obj-$(CONFIG_C2PORT)		+= c2port/
 obj-$(CONFIG_C2PORT)		+= c2port/
 obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-$(CONFIG_IWMC3200TOP)      += iwmc3200top/
 obj-y				+= eeprom/
 obj-y				+= eeprom/

+ 0 - 0
drivers/i2c/chips/ds1682.c → drivers/misc/ds1682.c


+ 15 - 22
drivers/misc/ics932s401.c

@@ -417,32 +417,25 @@ static int ics932s401_detect(struct i2c_client *client, int kind,
 			  struct i2c_board_info *info)
 			  struct i2c_board_info *info)
 {
 {
 	struct i2c_adapter *adapter = client->adapter;
 	struct i2c_adapter *adapter = client->adapter;
+	int vendor, device, revision;
 
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 		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);
 	strlcpy(info->type, "ics932s401", I2C_NAME_SIZE);
 
 

+ 4 - 94
include/linux/i2c.h

@@ -110,7 +110,7 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
  * @driver: Device driver model driver
  * @driver: Device driver model driver
  * @id_table: List of I2C devices supported by this driver
  * @id_table: List of I2C devices supported by this driver
  * @detect: Callback for device detection
  * @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)
  * @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.
  * The driver.owner field should be set to the module owner of this driver.
@@ -338,8 +338,7 @@ struct i2c_adapter {
 	void *algo_data;
 	void *algo_data;
 
 
 	/* data fields that are valid for all devices	*/
 	/* 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 timeout;			/* in jiffies */
 	int retries;
 	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)
 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)
 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: */
 /*flags for the client struct: */
@@ -398,9 +397,6 @@ static inline void i2c_unlock_adapter(struct i2c_adapter *adapter)
  */
  */
 struct i2c_client_address_data {
 struct i2c_client_address_data {
 	const unsigned short *normal_i2c;
 	const unsigned short *normal_i2c;
-	const unsigned short *probe;
-	const unsigned short *ignore;
-	const unsigned short * const *forces;
 };
 };
 
 
 /* Internal numbers to terminate lists */
 /* Internal numbers to terminate lists */
@@ -614,134 +610,48 @@ union i2c_smbus_data {
   module_param_array(var, short, &var##_num, 0); \
   module_param_array(var, short, &var##_num, 0); \
   MODULE_PARM_DESC(var, desc)
   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					\
 #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 = {		\
 static const struct i2c_client_address_data addr_data = {		\
 	.normal_i2c	= normal_i2c,					\
 	.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
 /* 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. */
    which matches the number of devices the driver differenciates between. */
 #define I2C_CLIENT_INSMOD						\
 #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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_1(chip1)					\
 #define I2C_CLIENT_INSMOD_1(chip1)					\
 enum chips { any_chip, 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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_2(chip1, chip2)				\
 #define I2C_CLIENT_INSMOD_2(chip1, chip2)				\
 enum chips { any_chip, 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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3)			\
 #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3)			\
 enum chips { any_chip, 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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4)			\
 #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4)			\
 enum chips { any_chip, 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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5)		\
 #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5)		\
 enum chips { any_chip, 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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6)	\
 #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6)	\
 enum chips { any_chip, 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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \
 #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,	\
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,	\
 	     chip7 };							\
 	     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
 I2C_CLIENT_INSMOD_COMMON
 
 
 #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \
 #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,	\
 enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6,	\
 	     chip7, chip8 };						\
 	     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
 I2C_CLIENT_INSMOD_COMMON
 #endif /* __KERNEL__ */
 #endif /* __KERNEL__ */
 #endif /* _LINUX_I2C_H */
 #endif /* _LINUX_I2C_H */