Ver Fonte

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:
  therm_windtunnel: Convert to a new-style i2c driver
  therm_adt746x: Convert to a new-style i2c driver
  windfarm: Convert to new-style i2c drivers
  therm_pm72: Convert to a new-style i2c driver
  i2c-viapro: Add new PCI device ID for VX855
  i2c/chips: Move max6875 to drivers/misc/eeprom
  i2c: Do not give adapters a default parent
  i2c: Do not probe for TV chips on Voodoo3 adapters
  i2c: Retry automatically on arbitration loss
  i2c: Remove void casts
Linus Torvalds há 16 anos atrás
pai
commit
4858704da7

+ 4 - 0
Documentation/i2c/busses/i2c-viapro

@@ -19,6 +19,9 @@ Supported adapters:
   * VIA Technologies, Inc. VX800/VX820
   * VIA Technologies, Inc. VX800/VX820
     Datasheet: available on http://linux.via.com.tw
     Datasheet: available on http://linux.via.com.tw
 
 
+  * VIA Technologies, Inc. VX855/VX875
+    Datasheet: Availability unknown
+
 Authors:
 Authors:
 	Kyösti Mälkki <kmalkki@cc.hut.fi>,
 	Kyösti Mälkki <kmalkki@cc.hut.fi>,
 	Mark D. Studebaker <mdsxyz123@yahoo.com>,
 	Mark D. Studebaker <mdsxyz123@yahoo.com>,
@@ -53,6 +56,7 @@ Your lspci -n listing must show one of these :
  device 1106:3287   (VT8251)
  device 1106:3287   (VT8251)
  device 1106:8324   (CX700)
  device 1106:8324   (CX700)
  device 1106:8353   (VX800/VX820)
  device 1106:8353   (VX800/VX820)
+ device 1106:8409   (VX855/VX875)
 
 
 If none of these show up, you should look in the BIOS for settings like
 If none of these show up, you should look in the BIOS for settings like
 enable ACPI / SMBus or even USB.
 enable ACPI / SMBus or even USB.

+ 1 - 1
arch/mips/configs/bigsur_defconfig

@@ -963,7 +963,7 @@ CONFIG_EEPROM_LEGACY=y
 CONFIG_SENSORS_PCF8574=y
 CONFIG_SENSORS_PCF8574=y
 # CONFIG_PCF8575 is not set
 # CONFIG_PCF8575 is not set
 CONFIG_SENSORS_PCF8591=y
 CONFIG_SENSORS_PCF8591=y
-CONFIG_SENSORS_MAX6875=y
+CONFIG_EEPROM_MAX6875=y
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_ALGO=y

+ 1 - 1
arch/mips/configs/mtx1_defconfig

@@ -1849,7 +1849,7 @@ CONFIG_EEPROM_LEGACY=m
 CONFIG_SENSORS_PCF8574=m
 CONFIG_SENSORS_PCF8574=m
 CONFIG_SENSORS_PCA9539=m
 CONFIG_SENSORS_PCA9539=m
 CONFIG_SENSORS_PCF8591=m
 CONFIG_SENSORS_PCF8591=m
-CONFIG_SENSORS_MAX6875=m
+CONFIG_EEPROM_MAX6875=m
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_ALGO is not set

+ 1 - 1
arch/powerpc/configs/ppc6xx_defconfig

@@ -1808,7 +1808,7 @@ CONFIG_PCF8575=m
 CONFIG_SENSORS_PCA9539=m
 CONFIG_SENSORS_PCA9539=m
 CONFIG_SENSORS_PCF8591=m
 CONFIG_SENSORS_PCF8591=m
 # CONFIG_TPS65010 is not set
 # CONFIG_TPS65010 is not set
-CONFIG_SENSORS_MAX6875=m
+CONFIG_EEPROM_MAX6875=m
 CONFIG_SENSORS_TSL2550=m
 CONFIG_SENSORS_TSL2550=m
 CONFIG_MCU_MPC8349EMITX=m
 CONFIG_MCU_MPC8349EMITX=m
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_CORE is not set

+ 3 - 3
drivers/i2c/busses/Kconfig

@@ -211,7 +211,7 @@ config I2C_VIA
 	  will be called i2c-via.
 	  will be called i2c-via.
 
 
 config I2C_VIAPRO
 config I2C_VIAPRO
-	tristate "VIA VT82C596/82C686/82xx and CX700/VX800/VX820"
+	tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx"
 	depends on PCI
 	depends on PCI
 	help
 	help
 	  If you say yes to this option, support will be included for the VIA
 	  If you say yes to this option, support will be included for the VIA
@@ -225,8 +225,8 @@ config I2C_VIAPRO
 	    VT8237R/A/S
 	    VT8237R/A/S
 	    VT8251
 	    VT8251
 	    CX700
 	    CX700
-	    VX800
-	    VX820
+	    VX800/VX820
+	    VX855/VX875
 
 
 	  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-viapro.
 	  will be called i2c-viapro.

+ 4 - 0
drivers/i2c/busses/i2c-viapro.c

@@ -37,6 +37,7 @@
    VT8251             0x3287             yes
    VT8251             0x3287             yes
    CX700              0x8324             yes
    CX700              0x8324             yes
    VX800/VX820        0x8353             yes
    VX800/VX820        0x8353             yes
+   VX855/VX875        0x8409             yes
 
 
    Note: we assume there can only be one device, with one SMBus interface.
    Note: we assume there can only be one device, with one SMBus interface.
 */
 */
@@ -404,6 +405,7 @@ found:
 	switch (pdev->device) {
 	switch (pdev->device) {
 	case PCI_DEVICE_ID_VIA_CX700:
 	case PCI_DEVICE_ID_VIA_CX700:
 	case PCI_DEVICE_ID_VIA_VX800:
 	case PCI_DEVICE_ID_VIA_VX800:
+	case PCI_DEVICE_ID_VIA_VX855:
 	case PCI_DEVICE_ID_VIA_8251:
 	case PCI_DEVICE_ID_VIA_8251:
 	case PCI_DEVICE_ID_VIA_8237:
 	case PCI_DEVICE_ID_VIA_8237:
 	case PCI_DEVICE_ID_VIA_8237A:
 	case PCI_DEVICE_ID_VIA_8237A:
@@ -469,6 +471,8 @@ static struct pci_device_id vt596_ids[] = {
 	  .driver_data = SMBBA3 },
 	  .driver_data = SMBBA3 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800),
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800),
 	  .driver_data = SMBBA3 },
 	  .driver_data = SMBBA3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855),
+	  .driver_data = SMBBA3 },
 	{ 0, }
 	{ 0, }
 };
 };
 
 

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

@@ -163,7 +163,6 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = {
 
 
 static struct i2c_adapter voodoo3_i2c_adapter = {
 static struct i2c_adapter voodoo3_i2c_adapter = {
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
-	.class		= I2C_CLASS_TV_ANALOG, 
 	.name		= "I2C Voodoo3/Banshee adapter",
 	.name		= "I2C Voodoo3/Banshee adapter",
 	.algo_data	= &voo_i2c_bit_data,
 	.algo_data	= &voo_i2c_bit_data,
 };
 };

+ 0 - 15
drivers/i2c/chips/Kconfig

@@ -64,21 +64,6 @@ config SENSORS_PCA9539
 	  This driver is deprecated and will be dropped soon. Use
 	  This driver is deprecated and will be dropped soon. Use
 	  drivers/gpio/pca953x.c instead.
 	  drivers/gpio/pca953x.c instead.
 
 
-config SENSORS_MAX6875
-	tristate "Maxim MAX6875 Power supply supervisor"
-	depends on EXPERIMENTAL
-	help
-	  If you say yes here you get support for the Maxim MAX6875
-	  EEPROM-programmable, quad power-supply sequencer/supervisor.
-
-	  This provides an interface to program the EEPROM and reset the chip.
-
-	  This driver also supports the Maxim MAX6874 hex power-supply
-	  sequencer/supervisor if found at a compatible address.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called max6875.
-
 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

@@ -11,7 +11,6 @@
 #
 #
 
 
 obj-$(CONFIG_DS1682)		+= ds1682.o
 obj-$(CONFIG_DS1682)		+= ds1682.o
-obj-$(CONFIG_SENSORS_MAX6875)	+= max6875.o
 obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
 obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_PCF8575)		+= pcf8575.o
 obj-$(CONFIG_PCF8575)		+= pcf8575.o

+ 27 - 16
drivers/i2c/i2c-core.c

@@ -29,7 +29,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/idr.h>
-#include <linux/platform_device.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/completion.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
 #include <linux/hardirq.h>
@@ -451,16 +450,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 
 
 	mutex_lock(&core_lock);
 	mutex_lock(&core_lock);
 
 
-	/* Add the adapter to the driver core.
-	 * If the parent pointer is not set up,
-	 * we add this adapter to the host bus.
-	 */
-	if (adap->dev.parent == NULL) {
-		adap->dev.parent = &platform_bus;
-		pr_debug("I2C adapter driver [%s] forgot to specify "
-			 "physical device\n", adap->name);
-	}
-
 	/* 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)
 		adap->timeout = HZ;
 		adap->timeout = HZ;
@@ -1022,7 +1011,8 @@ module_exit(i2c_exit);
  */
  */
 int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 {
 {
-	int ret;
+	unsigned long orig_jiffies;
+	int ret, try;
 
 
 	/* REVISIT the fault reporting model here is weak:
 	/* REVISIT the fault reporting model here is weak:
 	 *
 	 *
@@ -1060,7 +1050,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 			mutex_lock_nested(&adap->bus_lock, adap->level);
 			mutex_lock_nested(&adap->bus_lock, adap->level);
 		}
 		}
 
 
-		ret = adap->algo->master_xfer(adap,msgs,num);
+		/* Retry automatically on arbitration loss */
+		orig_jiffies = jiffies;
+		for (ret = 0, try = 0; try <= adap->retries; try++) {
+			ret = adap->algo->master_xfer(adap, msgs, num);
+			if (ret != -EAGAIN)
+				break;
+			if (time_after(jiffies, orig_jiffies + adap->timeout))
+				break;
+		}
 		mutex_unlock(&adap->bus_lock);
 		mutex_unlock(&adap->bus_lock);
 
 
 		return ret;
 		return ret;
@@ -1509,7 +1507,7 @@ struct i2c_adapter* i2c_get_adapter(int id)
 	struct i2c_adapter *adapter;
 	struct i2c_adapter *adapter;
 
 
 	mutex_lock(&core_lock);
 	mutex_lock(&core_lock);
-	adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
+	adapter = idr_find(&i2c_adapter_idr, id);
 	if (adapter && !try_module_get(adapter->owner))
 	if (adapter && !try_module_get(adapter->owner))
 		adapter = NULL;
 		adapter = NULL;
 
 
@@ -1995,14 +1993,27 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
 		   char read_write, u8 command, int protocol,
 		   char read_write, u8 command, int protocol,
 		   union i2c_smbus_data *data)
 		   union i2c_smbus_data *data)
 {
 {
+	unsigned long orig_jiffies;
+	int try;
 	s32 res;
 	s32 res;
 
 
 	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);
 		mutex_lock(&adapter->bus_lock);
-		res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
-						command, protocol, data);
+
+		/* Retry automatically on arbitration loss */
+		orig_jiffies = jiffies;
+		for (res = 0, try = 0; try <= adapter->retries; try++) {
+			res = adapter->algo->smbus_xfer(adapter, addr, flags,
+							read_write, command,
+							protocol, data);
+			if (res != -EAGAIN)
+				break;
+			if (time_after(jiffies,
+				       orig_jiffies + adapter->timeout))
+				break;
+		}
 		mutex_unlock(&adapter->bus_lock);
 		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,

+ 42 - 42
drivers/macintosh/therm_adt746x.c

@@ -72,7 +72,7 @@ MODULE_PARM_DESC(verbose,"Verbose log operations "
 		 "(default 0)");
 		 "(default 0)");
 
 
 struct thermostat {
 struct thermostat {
-	struct i2c_client	clt;
+	struct i2c_client	*clt;
 	u8			temps[3];
 	u8			temps[3];
 	u8			cached_temp[3];
 	u8			cached_temp[3];
 	u8			initial_limits[3];
 	u8			initial_limits[3];
@@ -87,9 +87,6 @@ static struct of_device * of_dev;
 static struct thermostat* thermostat;
 static struct thermostat* thermostat;
 static struct task_struct *thread_therm = NULL;
 static struct task_struct *thread_therm = NULL;
 
 
-static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
-				 int busno);
-
 static void write_both_fan_speed(struct thermostat *th, int speed);
 static void write_both_fan_speed(struct thermostat *th, int speed);
 static void write_fan_speed(struct thermostat *th, int speed, int fan);
 static void write_fan_speed(struct thermostat *th, int speed, int fan);
 
 
@@ -101,7 +98,7 @@ write_reg(struct thermostat* th, int reg, u8 data)
 	
 	
 	tmp[0] = reg;
 	tmp[0] = reg;
 	tmp[1] = data;
 	tmp[1] = data;
-	rc = i2c_master_send(&th->clt, (const char *)tmp, 2);
+	rc = i2c_master_send(th->clt, (const char *)tmp, 2);
 	if (rc < 0)
 	if (rc < 0)
 		return rc;
 		return rc;
 	if (rc != 2)
 	if (rc != 2)
@@ -116,12 +113,12 @@ read_reg(struct thermostat* th, int reg)
 	int rc;
 	int rc;
 
 
 	reg_addr = (u8)reg;
 	reg_addr = (u8)reg;
-	rc = i2c_master_send(&th->clt, &reg_addr, 1);
+	rc = i2c_master_send(th->clt, &reg_addr, 1);
 	if (rc < 0)
 	if (rc < 0)
 		return rc;
 		return rc;
 	if (rc != 1)
 	if (rc != 1)
 		return -ENODEV;
 		return -ENODEV;
-	rc = i2c_master_recv(&th->clt, (char *)&data, 1);
+	rc = i2c_master_recv(th->clt, (char *)&data, 1);
 	if (rc < 0)
 	if (rc < 0)
 		return rc;
 		return rc;
 	return data;
 	return data;
@@ -131,26 +128,36 @@ static int
 attach_thermostat(struct i2c_adapter *adapter)
 attach_thermostat(struct i2c_adapter *adapter)
 {
 {
 	unsigned long bus_no;
 	unsigned long bus_no;
+	struct i2c_board_info info;
+	struct i2c_client *client;
 
 
 	if (strncmp(adapter->name, "uni-n", 5))
 	if (strncmp(adapter->name, "uni-n", 5))
 		return -ENODEV;
 		return -ENODEV;
 	bus_no = simple_strtoul(adapter->name + 6, NULL, 10);
 	bus_no = simple_strtoul(adapter->name + 6, NULL, 10);
 	if (bus_no != therm_bus)
 	if (bus_no != therm_bus)
 		return -ENODEV;
 		return -ENODEV;
-	return attach_one_thermostat(adapter, therm_address, bus_no);
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE);
+	info.addr = therm_address;
+	client = i2c_new_device(adapter, &info);
+	if (!client)
+		return -ENODEV;
+
+	/*
+	 * Let i2c-core delete that device on driver removal.
+	 * This is safe because i2c-core holds the core_lock mutex for us.
+	 */
+	list_add_tail(&client->detected, &client->driver->clients);
+	return 0;
 }
 }
 
 
 static int
 static int
-detach_thermostat(struct i2c_adapter *adapter)
+remove_thermostat(struct i2c_client *client)
 {
 {
-	struct thermostat* th;
+	struct thermostat *th = i2c_get_clientdata(client);
 	int i;
 	int i;
 	
 	
-	if (thermostat == NULL)
-		return 0;
-
-	th = thermostat;
-
 	if (thread_therm != NULL) {
 	if (thread_therm != NULL) {
 		kthread_stop(thread_therm);
 		kthread_stop(thread_therm);
 	}
 	}
@@ -166,8 +173,6 @@ detach_thermostat(struct i2c_adapter *adapter)
 
 
 	write_both_fan_speed(th, -1);
 	write_both_fan_speed(th, -1);
 
 
-	i2c_detach_client(&th->clt);
-
 	thermostat = NULL;
 	thermostat = NULL;
 
 
 	kfree(th);
 	kfree(th);
@@ -175,14 +180,6 @@ detach_thermostat(struct i2c_adapter *adapter)
 	return 0;
 	return 0;
 }
 }
 
 
-static struct i2c_driver thermostat_driver = {  
-	.driver = {
-		.name	= "therm_adt746x",
-	},
-	.attach_adapter	= attach_thermostat,
-	.detach_adapter	= detach_thermostat,
-};
-
 static int read_fan_speed(struct thermostat *th, u8 addr)
 static int read_fan_speed(struct thermostat *th, u8 addr)
 {
 {
 	u8 tmp[2];
 	u8 tmp[2];
@@ -371,8 +368,8 @@ static void set_limit(struct thermostat *th, int i)
 		th->limits[i] = default_limits_local[i] + limit_adjust;
 		th->limits[i] = default_limits_local[i] + limit_adjust;
 }
 }
 
 
-static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
-				 int busno)
+static int probe_thermostat(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
 {
 	struct thermostat* th;
 	struct thermostat* th;
 	int rc;
 	int rc;
@@ -385,16 +382,12 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
 	if (!th)
 	if (!th)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	th->clt.addr = addr;
-	th->clt.adapter = adapter;
-	th->clt.driver = &thermostat_driver;
-	strcpy(th->clt.name, "thermostat");
+	i2c_set_clientdata(client, th);
+	th->clt = client;
 
 
 	rc = read_reg(th, 0);
 	rc = read_reg(th, 0);
 	if (rc < 0) {
 	if (rc < 0) {
-		printk(KERN_ERR "adt746x: Thermostat failed to read config "
-				"from bus %d !\n",
-				busno);
+		dev_err(&client->dev, "Thermostat failed to read config!\n");
 		kfree(th);
 		kfree(th);
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
@@ -423,14 +416,6 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
 
 
 	thermostat = th;
 	thermostat = th;
 
 
-	if (i2c_attach_client(&th->clt)) {
-		printk(KERN_INFO "adt746x: Thermostat failed to attach "
-				 "client !\n");
-		thermostat = NULL;
-		kfree(th);
-		return -ENODEV;
-	}
-
 	/* be sure to really write fan speed the first time */
 	/* be sure to really write fan speed the first time */
 	th->last_speed[0] = -2;
 	th->last_speed[0] = -2;
 	th->last_speed[1] = -2;
 	th->last_speed[1] = -2;
@@ -456,6 +441,21 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
 	return 0;
 	return 0;
 }
 }
 
 
+static const struct i2c_device_id therm_adt746x_id[] = {
+	{ "therm_adt746x", 0 },
+	{ }
+};
+
+static struct i2c_driver thermostat_driver = {
+	.driver = {
+		.name	= "therm_adt746x",
+	},
+	.attach_adapter	= attach_thermostat,
+	.probe = probe_thermostat,
+	.remove = remove_thermostat,
+	.id_table = therm_adt746x_id,
+};
+
 /* 
 /* 
  * Now, unfortunately, sysfs doesn't give us a nice void * we could
  * Now, unfortunately, sysfs doesn't give us a nice void * we could
  * pass around to the attribute functions, so we don't really have
  * pass around to the attribute functions, so we don't really have

+ 47 - 48
drivers/macintosh/therm_pm72.c

@@ -286,22 +286,6 @@ struct fcu_fan_table	fcu_fans[] = {
 	},
 	},
 };
 };
 
 
-/*
- * i2c_driver structure to attach to the host i2c controller
- */
-
-static int therm_pm72_attach(struct i2c_adapter *adapter);
-static int therm_pm72_detach(struct i2c_adapter *adapter);
-
-static struct i2c_driver therm_pm72_driver =
-{
-	.driver = {
-		.name	= "therm_pm72",
-	},
-	.attach_adapter	= therm_pm72_attach,
-	.detach_adapter	= therm_pm72_detach,
-};
-
 /*
 /*
  * Utility function to create an i2c_client structure and
  * Utility function to create an i2c_client structure and
  * attach it to one of u3 adapters
  * attach it to one of u3 adapters
@@ -310,6 +294,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
 {
 {
 	struct i2c_client *clt;
 	struct i2c_client *clt;
 	struct i2c_adapter *adap;
 	struct i2c_adapter *adap;
+	struct i2c_board_info info;
 
 
 	if (id & 0x200)
 	if (id & 0x200)
 		adap = k2;
 		adap = k2;
@@ -320,31 +305,21 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
 	if (adap == NULL)
 	if (adap == NULL)
 		return NULL;
 		return NULL;
 
 
-	clt = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (clt == NULL)
-		return NULL;
-
-	clt->addr = (id >> 1) & 0x7f;
-	clt->adapter = adap;
-	clt->driver = &therm_pm72_driver;
-	strncpy(clt->name, name, I2C_NAME_SIZE-1);
-
-	if (i2c_attach_client(clt)) {
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.addr = (id >> 1) & 0x7f;
+	strlcpy(info.type, "therm_pm72", I2C_NAME_SIZE);
+	clt = i2c_new_device(adap, &info);
+	if (!clt) {
 		printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id);
 		printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id);
-		kfree(clt);
 		return NULL;
 		return NULL;
 	}
 	}
-	return clt;
-}
 
 
-/*
- * Utility function to get rid of the i2c_client structure
- * (will also detach from the adapter hopepfully)
- */
-static void detach_i2c_chip(struct i2c_client *clt)
-{
-	i2c_detach_client(clt);
-	kfree(clt);
+	/*
+	 * Let i2c-core delete that device on driver removal.
+	 * This is safe because i2c-core holds the core_lock mutex for us.
+	 */
+	list_add_tail(&clt->detected, &clt->driver->clients);
+	return clt;
 }
 }
 
 
 /*
 /*
@@ -1203,8 +1178,6 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
 
 
 	return 0;
 	return 0;
  fail:
  fail:
-	if (state->monitor)
-		detach_i2c_chip(state->monitor);
 	state->monitor = NULL;
 	state->monitor = NULL;
 	
 	
 	return -ENODEV;
 	return -ENODEV;
@@ -1232,7 +1205,6 @@ static void dispose_cpu_state(struct cpu_pid_state *state)
 		device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm);
 		device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm);
 	}
 	}
 
 
-	detach_i2c_chip(state->monitor);
 	state->monitor = NULL;
 	state->monitor = NULL;
 }
 }
 
 
@@ -1407,7 +1379,6 @@ static void dispose_backside_state(struct backside_pid_state *state)
 	device_remove_file(&of_dev->dev, &dev_attr_backside_temperature);
 	device_remove_file(&of_dev->dev, &dev_attr_backside_temperature);
 	device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm);
 	device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm);
 
 
-	detach_i2c_chip(state->monitor);
 	state->monitor = NULL;
 	state->monitor = NULL;
 }
 }
  
  
@@ -1532,7 +1503,6 @@ static void dispose_drives_state(struct drives_pid_state *state)
 	device_remove_file(&of_dev->dev, &dev_attr_drives_temperature);
 	device_remove_file(&of_dev->dev, &dev_attr_drives_temperature);
 	device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm);
 	device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm);
 
 
-	detach_i2c_chip(state->monitor);
 	state->monitor = NULL;
 	state->monitor = NULL;
 }
 }
 
 
@@ -1654,7 +1624,6 @@ static void dispose_dimms_state(struct dimm_pid_state *state)
 
 
 	device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature);
 	device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature);
 
 
-	detach_i2c_chip(state->monitor);
 	state->monitor = NULL;
 	state->monitor = NULL;
 }
 }
 
 
@@ -1779,7 +1748,6 @@ static void dispose_slots_state(struct slots_pid_state *state)
 	device_remove_file(&of_dev->dev, &dev_attr_slots_temperature);
 	device_remove_file(&of_dev->dev, &dev_attr_slots_temperature);
 	device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
 	device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
 
 
-	detach_i2c_chip(state->monitor);
 	state->monitor = NULL;
 	state->monitor = NULL;
 }
 }
 
 
@@ -2008,8 +1976,6 @@ static int attach_fcu(void)
  */
  */
 static void detach_fcu(void)
 static void detach_fcu(void)
 {
 {
-	if (fcu)
-		detach_i2c_chip(fcu);
 	fcu = NULL;
 	fcu = NULL;
 }
 }
 
 
@@ -2060,12 +2026,21 @@ static int therm_pm72_attach(struct i2c_adapter *adapter)
 	return 0;
 	return 0;
 }
 }
 
 
+static int therm_pm72_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
+{
+	/* Always succeed, the real work was done in therm_pm72_attach() */
+	return 0;
+}
+
 /*
 /*
- * Called on every adapter when the driver or the i2c controller
+ * Called when any of the devices which participates into thermal management
  * is going away.
  * is going away.
  */
  */
-static int therm_pm72_detach(struct i2c_adapter *adapter)
+static int therm_pm72_remove(struct i2c_client *client)
 {
 {
+	struct i2c_adapter *adapter = client->adapter;
+
 	mutex_lock(&driver_lock);
 	mutex_lock(&driver_lock);
 
 
 	if (state != state_detached)
 	if (state != state_detached)
@@ -2096,6 +2071,30 @@ static int therm_pm72_detach(struct i2c_adapter *adapter)
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * i2c_driver structure to attach to the host i2c controller
+ */
+
+static const struct i2c_device_id therm_pm72_id[] = {
+	/*
+	 * Fake device name, thermal management is done by several
+	 * chips but we don't need to differentiate between them at
+	 * this point.
+	 */
+	{ "therm_pm72", 0 },
+	{ }
+};
+
+static struct i2c_driver therm_pm72_driver = {
+	.driver = {
+		.name	= "therm_pm72",
+	},
+	.attach_adapter	= therm_pm72_attach,
+	.probe		= therm_pm72_probe,
+	.remove		= therm_pm72_remove,
+	.id_table	= therm_pm72_id,
+};
+
 static int fan_check_loc_match(const char *loc, int fan)
 static int fan_check_loc_match(const char *loc, int fan)
 {
 {
 	char	tmp[64];
 	char	tmp[64];

+ 60 - 66
drivers/macintosh/therm_windtunnel.c

@@ -48,16 +48,6 @@
 
 
 #define LOG_TEMP		0			/* continously log temperature */
 #define LOG_TEMP		0			/* continously log temperature */
 
 
-static int 			do_probe( struct i2c_adapter *adapter, int addr, int kind);
-
-/* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
-static const unsigned short	normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
-						 0x4c, 0x4d, 0x4e, 0x4f,
-						 0x2c, 0x2d, 0x2e, 0x2f,
-						 I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
 static struct {
 static struct {
 	volatile int		running;
 	volatile int		running;
 	struct task_struct	*poll_task;
 	struct task_struct	*poll_task;
@@ -315,53 +305,54 @@ static int control_loop(void *dummy)
 static int
 static int
 do_attach( struct i2c_adapter *adapter )
 do_attach( struct i2c_adapter *adapter )
 {
 {
-	int ret = 0;
+	/* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
+	static const unsigned short scan_ds1775[] = {
+		0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+		I2C_CLIENT_END
+	};
+	static const unsigned short scan_adm1030[] = {
+		0x2c, 0x2d, 0x2e, 0x2f,
+		I2C_CLIENT_END
+	};
 
 
 	if( strncmp(adapter->name, "uni-n", 5) )
 	if( strncmp(adapter->name, "uni-n", 5) )
 		return 0;
 		return 0;
 
 
 	if( !x.running ) {
 	if( !x.running ) {
-		ret = i2c_probe( adapter, &addr_data, &do_probe );
+		struct i2c_board_info info;
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE);
+		i2c_new_probed_device(adapter, &info, scan_ds1775);
+
+		strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE);
+		i2c_new_probed_device(adapter, &info, scan_adm1030);
+
 		if( x.thermostat && x.fan ) {
 		if( x.thermostat && x.fan ) {
 			x.running = 1;
 			x.running = 1;
 			x.poll_task = kthread_run(control_loop, NULL, "g4fand");
 			x.poll_task = kthread_run(control_loop, NULL, "g4fand");
 		}
 		}
 	}
 	}
-	return ret;
+	return 0;
 }
 }
 
 
 static int
 static int
-do_detach( struct i2c_client *client )
+do_remove(struct i2c_client *client)
 {
 {
-	int err;
-
-	if( (err=i2c_detach_client(client)) )
-		printk(KERN_ERR "failed to detach thermostat client\n");
-	else {
-		if( x.running ) {
-			x.running = 0;
-			kthread_stop(x.poll_task);
-			x.poll_task = NULL;
-		}
-		if( client == x.thermostat )
-			x.thermostat = NULL;
-		else if( client == x.fan )
-			x.fan = NULL;
-		else {
-			printk(KERN_ERR "g4fan: bad client\n");
-		}
-		kfree( client );
+	if (x.running) {
+		x.running = 0;
+		kthread_stop(x.poll_task);
+		x.poll_task = NULL;
 	}
 	}
-	return err;
-}
+	if (client == x.thermostat)
+		x.thermostat = NULL;
+	else if (client == x.fan)
+		x.fan = NULL;
+	else
+		printk(KERN_ERR "g4fan: bad client\n");
 
 
-static struct i2c_driver g4fan_driver = {  
-	.driver = {
-		.name	= "therm_windtunnel",
-	},
-	.attach_adapter = do_attach,
-	.detach_client	= do_detach,
-};
+	return 0;
+}
 
 
 static int
 static int
 attach_fan( struct i2c_client *cl )
 attach_fan( struct i2c_client *cl )
@@ -374,13 +365,8 @@ attach_fan( struct i2c_client *cl )
 		goto out;
 		goto out;
 	printk("ADM1030 fan controller [@%02x]\n", cl->addr );
 	printk("ADM1030 fan controller [@%02x]\n", cl->addr );
 
 
-	strlcpy( cl->name, "ADM1030 fan controller", sizeof(cl->name) );
-
-	if( !i2c_attach_client(cl) )
-		x.fan = cl;
+	x.fan = cl;
  out:
  out:
-	if( cl != x.fan )
-		kfree( cl );
 	return 0;
 	return 0;
 }
 }
 
 
@@ -412,39 +398,47 @@ attach_thermostat( struct i2c_client *cl )
 	x.temp = temp;
 	x.temp = temp;
 	x.overheat_temp = os_temp;
 	x.overheat_temp = os_temp;
 	x.overheat_hyst = hyst_temp;
 	x.overheat_hyst = hyst_temp;
-	
-	strlcpy( cl->name, "DS1775 thermostat", sizeof(cl->name) );
-
-	if( !i2c_attach_client(cl) )
-		x.thermostat = cl;
+	x.thermostat = cl;
 out:
 out:
-	if( cl != x.thermostat )
-		kfree( cl );
 	return 0;
 	return 0;
 }
 }
 
 
+enum chip { ds1775, adm1030 };
+
+static const struct i2c_device_id therm_windtunnel_id[] = {
+	{ "therm_ds1775", ds1775 },
+	{ "therm_adm1030", adm1030 },
+	{ }
+};
+
 static int
 static int
-do_probe( struct i2c_adapter *adapter, int addr, int kind )
+do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
 {
 {
-	struct i2c_client *cl;
+	struct i2c_adapter *adapter = cl->adapter;
 
 
 	if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA
 	if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA
 				     | I2C_FUNC_SMBUS_WRITE_BYTE) )
 				     | I2C_FUNC_SMBUS_WRITE_BYTE) )
 		return 0;
 		return 0;
 
 
-	if( !(cl=kzalloc(sizeof(*cl), GFP_KERNEL)) )
-		return -ENOMEM;
-
-	cl->addr = addr;
-	cl->adapter = adapter;
-	cl->driver = &g4fan_driver;
-	cl->flags = 0;
-
-	if( addr < 0x48 )
+	switch (id->driver_data) {
+	case adm1030:
 		return attach_fan( cl );
 		return attach_fan( cl );
-	return attach_thermostat( cl );
+	case ds1775:
+		return attach_thermostat(cl);
+	}
+	return 0;
 }
 }
 
 
+static struct i2c_driver g4fan_driver = {
+	.driver = {
+		.name	= "therm_windtunnel",
+	},
+	.attach_adapter = do_attach,
+	.probe		= do_probe,
+	.remove		= do_remove,
+	.id_table	= therm_windtunnel_id,
+};
+
 
 
 /************************************************************************/
 /************************************************************************/
 /*	initialization / cleanup					*/
 /*	initialization / cleanup					*/

+ 73 - 56
drivers/macintosh/windfarm_lm75_sensor.c

@@ -37,34 +37,22 @@
 struct wf_lm75_sensor {
 struct wf_lm75_sensor {
 	int			ds1775 : 1;
 	int			ds1775 : 1;
 	int			inited : 1;
 	int			inited : 1;
-	struct 	i2c_client	i2c;
+	struct 	i2c_client	*i2c;
 	struct 	wf_sensor	sens;
 	struct 	wf_sensor	sens;
 };
 };
 #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens)
 #define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens)
-#define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c)
-
-static int wf_lm75_attach(struct i2c_adapter *adapter);
-static int wf_lm75_detach(struct i2c_client *client);
-
-static struct i2c_driver wf_lm75_driver = {
-	.driver = {
-		.name	= "wf_lm75",
-	},
-	.attach_adapter	= wf_lm75_attach,
-	.detach_client	= wf_lm75_detach,
-};
 
 
 static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
 static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
 {
 {
 	struct wf_lm75_sensor *lm = wf_to_lm75(sr);
 	struct wf_lm75_sensor *lm = wf_to_lm75(sr);
 	s32 data;
 	s32 data;
 
 
-	if (lm->i2c.adapter == NULL)
+	if (lm->i2c == NULL)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	/* Init chip if necessary */
 	/* Init chip if necessary */
 	if (!lm->inited) {
 	if (!lm->inited) {
-		u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1);
+		u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(lm->i2c, 1);
 
 
 		DBG("wf_lm75: Initializing %s, cfg was: %02x\n",
 		DBG("wf_lm75: Initializing %s, cfg was: %02x\n",
 		    sr->name, cfg);
 		    sr->name, cfg);
@@ -73,7 +61,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
 		 * the firmware for now
 		 * the firmware for now
 		 */
 		 */
 		cfg_new = cfg & ~0x01;
 		cfg_new = cfg & ~0x01;
-		i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new);
+		i2c_smbus_write_byte_data(lm->i2c, 1, cfg_new);
 		lm->inited = 1;
 		lm->inited = 1;
 
 
 		/* If we just powered it up, let's wait 200 ms */
 		/* If we just powered it up, let's wait 200 ms */
@@ -81,7 +69,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
 	}
 	}
 
 
 	/* Read temperature register */
 	/* Read temperature register */
-	data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0));
+	data = (s32)le16_to_cpu(i2c_smbus_read_word_data(lm->i2c, 0));
 	data <<= 8;
 	data <<= 8;
 	*value = data;
 	*value = data;
 
 
@@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *sr)
 {
 {
 	struct wf_lm75_sensor *lm = wf_to_lm75(sr);
 	struct wf_lm75_sensor *lm = wf_to_lm75(sr);
 
 
-	/* check if client is registered and detach from i2c */
-	if (lm->i2c.adapter) {
-		i2c_detach_client(&lm->i2c);
-		lm->i2c.adapter = NULL;
-	}
-
 	kfree(lm);
 	kfree(lm);
 }
 }
 
 
@@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = {
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 };
 };
 
 
-static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
-					     u8 addr, int ds1775,
-					     const char *loc)
+static int wf_lm75_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 {
 	struct wf_lm75_sensor *lm;
 	struct wf_lm75_sensor *lm;
 	int rc;
 	int rc;
 
 
-	DBG("wf_lm75: creating  %s device at address 0x%02x\n",
-	    ds1775 ? "ds1775" : "lm75", addr);
-
 	lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
 	lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
 	if (lm == NULL)
 	if (lm == NULL)
-		return NULL;
+		return -ENODEV;
+
+	lm->inited = 0;
+	lm->ds1775 = id->driver_data;
+	lm->i2c = client;
+	lm->sens.name = client->dev.platform_data;
+	lm->sens.ops = &wf_lm75_ops;
+	i2c_set_clientdata(client, lm);
+
+	rc = wf_register_sensor(&lm->sens);
+	if (rc) {
+		i2c_set_clientdata(client, NULL);
+		kfree(lm);
+	}
+
+	return rc;
+}
+
+static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
+					     u8 addr, int ds1775,
+					     const char *loc)
+{
+	struct i2c_board_info info;
+	struct i2c_client *client;
+	char *name;
+
+	DBG("wf_lm75: creating  %s device at address 0x%02x\n",
+	    ds1775 ? "ds1775" : "lm75", addr);
 
 
 	/* Usual rant about sensor names not beeing very consistent in
 	/* Usual rant about sensor names not beeing very consistent in
 	 * the device-tree, oh well ...
 	 * the device-tree, oh well ...
 	 * Add more entries below as you deal with more setups
 	 * Add more entries below as you deal with more setups
 	 */
 	 */
 	if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
 	if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
-		lm->sens.name = "hd-temp";
+		name = "hd-temp";
 	else if (!strcmp(loc, "Incoming Air Temp"))
 	else if (!strcmp(loc, "Incoming Air Temp"))
-		lm->sens.name = "incoming-air-temp";
+		name = "incoming-air-temp";
 	else if (!strcmp(loc, "ODD Temp"))
 	else if (!strcmp(loc, "ODD Temp"))
-		lm->sens.name = "optical-drive-temp";
+		name = "optical-drive-temp";
 	else if (!strcmp(loc, "HD Temp"))
 	else if (!strcmp(loc, "HD Temp"))
-		lm->sens.name = "hard-drive-temp";
+		name = "hard-drive-temp";
 	else
 	else
 		goto fail;
 		goto fail;
 
 
-	lm->inited = 0;
-	lm->sens.ops = &wf_lm75_ops;
-	lm->ds1775 = ds1775;
-	lm->i2c.addr = (addr >> 1) & 0x7f;
-	lm->i2c.adapter = adapter;
-	lm->i2c.driver = &wf_lm75_driver;
-	strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);
-
-	rc = i2c_attach_client(&lm->i2c);
-	if (rc) {
-		printk(KERN_ERR "windfarm: failed to attach %s %s to i2c,"
-		       " err %d\n", ds1775 ? "ds1775" : "lm75",
-		       lm->i2c.name, rc);
-		goto fail;
-	}
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.addr = (addr >> 1) & 0x7f;
+	info.platform_data = name;
+	strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE);
 
 
-	if (wf_register_sensor(&lm->sens)) {
-		i2c_detach_client(&lm->i2c);
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL) {
+		printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
+		       ds1775 ? "ds1775" : "lm75", name);
 		goto fail;
 		goto fail;
 	}
 	}
 
 
-	return lm;
+	/*
+	 * Let i2c-core delete that device on driver removal.
+	 * This is safe because i2c-core holds the core_lock mutex for us.
+	 */
+	list_add_tail(&client->detected, &client->driver->clients);
+	return client;
  fail:
  fail:
-	kfree(lm);
 	return NULL;
 	return NULL;
 }
 }
 
 
@@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter)
 	return 0;
 	return 0;
 }
 }
 
 
-static int wf_lm75_detach(struct i2c_client *client)
+static int wf_lm75_remove(struct i2c_client *client)
 {
 {
-	struct wf_lm75_sensor *lm = i2c_to_lm75(client);
+	struct wf_lm75_sensor *lm = i2c_get_clientdata(client);
 
 
 	DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name);
 	DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name);
 
 
 	/* Mark client detached */
 	/* Mark client detached */
-	lm->i2c.adapter = NULL;
+	lm->i2c = NULL;
 
 
 	/* release sensor */
 	/* release sensor */
 	wf_unregister_sensor(&lm->sens);
 	wf_unregister_sensor(&lm->sens);
 
 
+	i2c_set_clientdata(client, NULL);
 	return 0;
 	return 0;
 }
 }
 
 
+static const struct i2c_device_id wf_lm75_id[] = {
+	{ "wf_lm75", 0 },
+	{ "wf_ds1775", 1 },
+	{ }
+};
+
+static struct i2c_driver wf_lm75_driver = {
+	.driver = {
+		.name	= "wf_lm75",
+	},
+	.attach_adapter	= wf_lm75_attach,
+	.probe		= wf_lm75_probe,
+	.remove		= wf_lm75_remove,
+	.id_table	= wf_lm75_id,
+};
+
 static int __init wf_lm75_sensor_init(void)
 static int __init wf_lm75_sensor_init(void)
 {
 {
 	/* Don't register on old machines that use therm_pm72 for now */
 	/* Don't register on old machines that use therm_pm72 for now */

+ 61 - 42
drivers/macintosh/windfarm_max6690_sensor.c

@@ -26,34 +26,22 @@
 #define MAX6690_EXTERNAL_TEMP	1
 #define MAX6690_EXTERNAL_TEMP	1
 
 
 struct wf_6690_sensor {
 struct wf_6690_sensor {
-	struct i2c_client	i2c;
+	struct i2c_client	*i2c;
 	struct wf_sensor	sens;
 	struct wf_sensor	sens;
 };
 };
 
 
 #define wf_to_6690(x)	container_of((x), struct wf_6690_sensor, sens)
 #define wf_to_6690(x)	container_of((x), struct wf_6690_sensor, sens)
-#define i2c_to_6690(x)	container_of((x), struct wf_6690_sensor, i2c)
-
-static int wf_max6690_attach(struct i2c_adapter *adapter);
-static int wf_max6690_detach(struct i2c_client *client);
-
-static struct i2c_driver wf_max6690_driver = {
-	.driver = {
-		.name		= "wf_max6690",
-	},
-	.attach_adapter	= wf_max6690_attach,
-	.detach_client	= wf_max6690_detach,
-};
 
 
 static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
 static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
 {
 {
 	struct wf_6690_sensor *max = wf_to_6690(sr);
 	struct wf_6690_sensor *max = wf_to_6690(sr);
 	s32 data;
 	s32 data;
 
 
-	if (max->i2c.adapter == NULL)
+	if (max->i2c == NULL)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	/* chip gets initialized by firmware */
 	/* chip gets initialized by firmware */
-	data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP);
+	data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP);
 	if (data < 0)
 	if (data < 0)
 		return data;
 		return data;
 	*value = data << 16;
 	*value = data << 16;
@@ -64,10 +52,6 @@ static void wf_max6690_release(struct wf_sensor *sr)
 {
 {
 	struct wf_6690_sensor *max = wf_to_6690(sr);
 	struct wf_6690_sensor *max = wf_to_6690(sr);
 
 
-	if (max->i2c.adapter) {
-		i2c_detach_client(&max->i2c);
-		max->i2c.adapter = NULL;
-	}
 	kfree(max);
 	kfree(max);
 }
 }
 
 
@@ -77,19 +61,40 @@ static struct wf_sensor_ops wf_max6690_ops = {
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 };
 };
 
 
-static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
-			      const char *loc)
+static int wf_max6690_probe(struct i2c_client *client,
+			    const struct i2c_device_id *id)
 {
 {
 	struct wf_6690_sensor *max;
 	struct wf_6690_sensor *max;
-	char *name;
+	int rc;
 
 
 	max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
 	max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
 	if (max == NULL) {
 	if (max == NULL) {
-		printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: "
-		       "no memory\n", loc);
-		return;
+		printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "
+		       "no memory\n");
+		return -ENOMEM;
+	}
+
+	max->i2c = client;
+	max->sens.name = client->dev.platform_data;
+	max->sens.ops = &wf_max6690_ops;
+	i2c_set_clientdata(client, max);
+
+	rc = wf_register_sensor(&max->sens);
+	if (rc) {
+		i2c_set_clientdata(client, NULL);
+		kfree(max);
 	}
 	}
 
 
+	return rc;
+}
+
+static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
+					    u8 addr, const char *loc)
+{
+	struct i2c_board_info info;
+	struct i2c_client *client;
+	char *name;
+
 	if (!strcmp(loc, "BACKSIDE"))
 	if (!strcmp(loc, "BACKSIDE"))
 		name = "backside-temp";
 		name = "backside-temp";
 	else if (!strcmp(loc, "NB Ambient"))
 	else if (!strcmp(loc, "NB Ambient"))
@@ -99,27 +104,26 @@ static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
 	else
 	else
 		goto fail;
 		goto fail;
 
 
-	max->sens.ops = &wf_max6690_ops;
-	max->sens.name = name;
-	max->i2c.addr = addr >> 1;
-	max->i2c.adapter = adapter;
-	max->i2c.driver = &wf_max6690_driver;
-	strncpy(max->i2c.name, name, I2C_NAME_SIZE-1);
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.addr = addr >> 1;
+	info.platform_data = name;
+	strlcpy(info.type, "wf_max6690", I2C_NAME_SIZE);
 
 
-	if (i2c_attach_client(&max->i2c)) {
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL) {
 		printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
 		printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
 		goto fail;
 		goto fail;
 	}
 	}
 
 
-	if (wf_register_sensor(&max->sens)) {
-		i2c_detach_client(&max->i2c);
-		goto fail;
-	}
-
-	return;
+	/*
+	 * Let i2c-core delete that device on driver removal.
+	 * This is safe because i2c-core holds the core_lock mutex for us.
+	 */
+	list_add_tail(&client->detected, &client->driver->clients);
+	return client;
 
 
  fail:
  fail:
-	kfree(max);
+	return NULL;
 }
 }
 
 
 static int wf_max6690_attach(struct i2c_adapter *adapter)
 static int wf_max6690_attach(struct i2c_adapter *adapter)
@@ -154,16 +158,31 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
 	return 0;
 	return 0;
 }
 }
 
 
-static int wf_max6690_detach(struct i2c_client *client)
+static int wf_max6690_remove(struct i2c_client *client)
 {
 {
-	struct wf_6690_sensor *max = i2c_to_6690(client);
+	struct wf_6690_sensor *max = i2c_get_clientdata(client);
 
 
-	max->i2c.adapter = NULL;
+	max->i2c = NULL;
 	wf_unregister_sensor(&max->sens);
 	wf_unregister_sensor(&max->sens);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
+static const struct i2c_device_id wf_max6690_id[] = {
+	{ "wf_max6690", 0 },
+	{ }
+};
+
+static struct i2c_driver wf_max6690_driver = {
+	.driver = {
+		.name		= "wf_max6690",
+	},
+	.attach_adapter	= wf_max6690_attach,
+	.probe		= wf_max6690_probe,
+	.remove		= wf_max6690_remove,
+	.id_table	= wf_max6690_id,
+};
+
 static int __init wf_max6690_sensor_init(void)
 static int __init wf_max6690_sensor_init(void)
 {
 {
 	/* Don't register on old machines that use therm_pm72 for now */
 	/* Don't register on old machines that use therm_pm72 for now */

+ 63 - 46
drivers/macintosh/windfarm_smu_sat.c

@@ -39,7 +39,7 @@ struct wf_sat {
 	struct mutex		mutex;
 	struct mutex		mutex;
 	unsigned long		last_read; /* jiffies when cache last updated */
 	unsigned long		last_read; /* jiffies when cache last updated */
 	u8			cache[16];
 	u8			cache[16];
-	struct i2c_client	i2c;
+	struct i2c_client	*i2c;
 	struct device_node	*node;
 	struct device_node	*node;
 };
 };
 
 
@@ -54,18 +54,6 @@ struct wf_sat_sensor {
 };
 };
 
 
 #define wf_to_sat(c)	container_of(c, struct wf_sat_sensor, sens)
 #define wf_to_sat(c)	container_of(c, struct wf_sat_sensor, sens)
-#define i2c_to_sat(c)	container_of(c, struct wf_sat, i2c)
-
-static int wf_sat_attach(struct i2c_adapter *adapter);
-static int wf_sat_detach(struct i2c_client *client);
-
-static struct i2c_driver wf_sat_driver = {
-	.driver = {
-		.name		= "wf_smu_sat",
-	},
-	.attach_adapter	= wf_sat_attach,
-	.detach_client	= wf_sat_detach,
-};
 
 
 struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
 struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
 						  unsigned int *size)
 						  unsigned int *size)
@@ -81,13 +69,13 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
 	if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
 	if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
 		return NULL;
 		return NULL;
 
 
-	err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8);
+	err = i2c_smbus_write_word_data(sat->i2c, 8, id << 8);
 	if (err) {
 	if (err) {
 		printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
 		printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
 		return NULL;
 		return NULL;
 	}
 	}
 
 
-	err = i2c_smbus_read_word_data(&sat->i2c, 9);
+	err = i2c_smbus_read_word_data(sat->i2c, 9);
 	if (err < 0) {
 	if (err < 0) {
 		printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
 		printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
 		return NULL;
 		return NULL;
@@ -105,7 +93,7 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
 		return NULL;
 		return NULL;
 
 
 	for (i = 0; i < len; i += 4) {
 	for (i = 0; i < len; i += 4) {
-		err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0xa, 4, data);
+		err = i2c_smbus_read_i2c_block_data(sat->i2c, 0xa, 4, data);
 		if (err < 0) {
 		if (err < 0) {
 			printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
 			printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
 			       err);
 			       err);
@@ -138,7 +126,7 @@ static int wf_sat_read_cache(struct wf_sat *sat)
 {
 {
 	int err;
 	int err;
 
 
-	err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0x3f, 16, sat->cache);
+	err = i2c_smbus_read_i2c_block_data(sat->i2c, 0x3f, 16, sat->cache);
 	if (err < 0)
 	if (err < 0)
 		return err;
 		return err;
 	sat->last_read = jiffies;
 	sat->last_read = jiffies;
@@ -161,7 +149,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value)
 	int i, err;
 	int i, err;
 	s32 val;
 	s32 val;
 
 
-	if (sat->i2c.adapter == NULL)
+	if (sat->i2c == NULL)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	mutex_lock(&sat->mutex);
 	mutex_lock(&sat->mutex);
@@ -193,10 +181,6 @@ static void wf_sat_release(struct wf_sensor *sr)
 	struct wf_sat *sat = sens->sat;
 	struct wf_sat *sat = sens->sat;
 
 
 	if (atomic_dec_and_test(&sat->refcnt)) {
 	if (atomic_dec_and_test(&sat->refcnt)) {
-		if (sat->i2c.adapter) {
-			i2c_detach_client(&sat->i2c);
-			sat->i2c.adapter = NULL;
-		}
 		if (sat->nr >= 0)
 		if (sat->nr >= 0)
 			sats[sat->nr] = NULL;
 			sats[sat->nr] = NULL;
 		kfree(sat);
 		kfree(sat);
@@ -212,38 +196,58 @@ static struct wf_sensor_ops wf_sat_ops = {
 
 
 static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
 static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
 {
 {
+	struct i2c_board_info info;
+	struct i2c_client *client;
+	const u32 *reg;
+	u8 addr;
+
+	reg = of_get_property(dev, "reg", NULL);
+	if (reg == NULL)
+		return;
+	addr = *reg;
+	DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	info.addr = (addr >> 1) & 0x7f;
+	info.platform_data = dev;
+	strlcpy(info.type, "wf_sat", I2C_NAME_SIZE);
+
+	client = i2c_new_device(adapter, &info);
+	if (client == NULL) {
+		printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
+		return;
+	}
+
+	/*
+	 * Let i2c-core delete that device on driver removal.
+	 * This is safe because i2c-core holds the core_lock mutex for us.
+	 */
+	list_add_tail(&client->detected, &client->driver->clients);
+}
+
+static int wf_sat_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct device_node *dev = client->dev.platform_data;
 	struct wf_sat *sat;
 	struct wf_sat *sat;
 	struct wf_sat_sensor *sens;
 	struct wf_sat_sensor *sens;
 	const u32 *reg;
 	const u32 *reg;
 	const char *loc, *type;
 	const char *loc, *type;
-	u8 addr, chip, core;
+	u8 chip, core;
 	struct device_node *child;
 	struct device_node *child;
 	int shift, cpu, index;
 	int shift, cpu, index;
 	char *name;
 	char *name;
 	int vsens[2], isens[2];
 	int vsens[2], isens[2];
 
 
-	reg = of_get_property(dev, "reg", NULL);
-	if (reg == NULL)
-		return;
-	addr = *reg;
-	DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
-
 	sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
 	sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
 	if (sat == NULL)
 	if (sat == NULL)
-		return;
+		return -ENOMEM;
 	sat->nr = -1;
 	sat->nr = -1;
 	sat->node = of_node_get(dev);
 	sat->node = of_node_get(dev);
 	atomic_set(&sat->refcnt, 0);
 	atomic_set(&sat->refcnt, 0);
 	mutex_init(&sat->mutex);
 	mutex_init(&sat->mutex);
-	sat->i2c.addr = (addr >> 1) & 0x7f;
-	sat->i2c.adapter = adapter;
-	sat->i2c.driver = &wf_sat_driver;
-	strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1);
-
-	if (i2c_attach_client(&sat->i2c)) {
-		printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
-		goto fail;
-	}
+	sat->i2c = client;
+	i2c_set_clientdata(client, sat);
 
 
 	vsens[0] = vsens[1] = -1;
 	vsens[0] = vsens[1] = -1;
 	isens[0] = isens[1] = -1;
 	isens[0] = isens[1] = -1;
@@ -344,10 +348,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
 	if (sat->nr >= 0)
 	if (sat->nr >= 0)
 		sats[sat->nr] = sat;
 		sats[sat->nr] = sat;
 
 
-	return;
-
- fail:
-	kfree(sat);
+	return 0;
 }
 }
 
 
 static int wf_sat_attach(struct i2c_adapter *adapter)
 static int wf_sat_attach(struct i2c_adapter *adapter)
@@ -366,16 +367,32 @@ static int wf_sat_attach(struct i2c_adapter *adapter)
 	return 0;
 	return 0;
 }
 }
 
 
-static int wf_sat_detach(struct i2c_client *client)
+static int wf_sat_remove(struct i2c_client *client)
 {
 {
-	struct wf_sat *sat = i2c_to_sat(client);
+	struct wf_sat *sat = i2c_get_clientdata(client);
 
 
 	/* XXX TODO */
 	/* XXX TODO */
 
 
-	sat->i2c.adapter = NULL;
+	sat->i2c = NULL;
+	i2c_set_clientdata(client, NULL);
 	return 0;
 	return 0;
 }
 }
 
 
+static const struct i2c_device_id wf_sat_id[] = {
+	{ "wf_sat", 0 },
+	{ }
+};
+
+static struct i2c_driver wf_sat_driver = {
+	.driver = {
+		.name		= "wf_smu_sat",
+	},
+	.attach_adapter	= wf_sat_attach,
+	.probe		= wf_sat_probe,
+	.remove		= wf_sat_remove,
+	.id_table	= wf_sat_id,
+};
+
 static int __init sat_sensors_init(void)
 static int __init sat_sensors_init(void)
 {
 {
 	return i2c_add_driver(&wf_sat_driver);
 	return i2c_add_driver(&wf_sat_driver);

+ 14 - 0
drivers/misc/eeprom/Kconfig

@@ -48,6 +48,20 @@ config EEPROM_LEGACY
 	  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 eeprom.
 	  will be called eeprom.
 
 
+config EEPROM_MAX6875
+	tristate "Maxim MAX6874/5 power supply supervisor"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get read-only support for the user EEPROM of
+	  the Maxim MAX6874/5 EEPROM-programmable, quad power-supply
+	  sequencer/supervisor.
+
+	  All other features of this chip should be accessed via i2c-dev.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max6875.
+
+
 config EEPROM_93CX6
 config EEPROM_93CX6
 	tristate "EEPROM 93CX6 support"
 	tristate "EEPROM 93CX6 support"
 	help
 	help

+ 1 - 0
drivers/misc/eeprom/Makefile

@@ -1,4 +1,5 @@
 obj-$(CONFIG_EEPROM_AT24)	+= at24.o
 obj-$(CONFIG_EEPROM_AT24)	+= at24.o
 obj-$(CONFIG_EEPROM_AT25)	+= at25.o
 obj-$(CONFIG_EEPROM_AT25)	+= at25.o
 obj-$(CONFIG_EEPROM_LEGACY)	+= eeprom.o
 obj-$(CONFIG_EEPROM_LEGACY)	+= eeprom.o
+obj-$(CONFIG_EEPROM_MAX6875)	+= max6875.o
 obj-$(CONFIG_EEPROM_93CX6)	+= eeprom_93cx6.o
 obj-$(CONFIG_EEPROM_93CX6)	+= eeprom_93cx6.o

+ 1 - 1
drivers/i2c/chips/max6875.c → drivers/misc/eeprom/max6875.c

@@ -3,7 +3,7 @@
 
 
     Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
     Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
 
 
-    Based on i2c/chips/eeprom.c
+    Based on eeprom.c
 
 
     The MAX6875 has a bank of registers and two banks of EEPROM.
     The MAX6875 has a bank of registers and two banks of EEPROM.
     Address ranges are defined as follows:
     Address ranges are defined as follows:

+ 0 - 1
drivers/video/tdfxfb.c

@@ -1315,7 +1315,6 @@ static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan,
 
 
 	strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
 	strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
 	chan->adapter.owner		= THIS_MODULE;
 	chan->adapter.owner		= THIS_MODULE;
-	chan->adapter.class		= I2C_CLASS_TV_ANALOG;
 	chan->adapter.algo_data		= &chan->algo;
 	chan->adapter.algo_data		= &chan->algo;
 	chan->adapter.dev.parent	= dev;
 	chan->adapter.dev.parent	= dev;
 	chan->algo.setsda		= tdfxfb_i2c_setsda;
 	chan->algo.setsda		= tdfxfb_i2c_setsda;