From 1cf92b453a405f6e452737962933a19ec1582029 Mon Sep 17 00:00:00 2001 From: Jack Stone Date: Mon, 15 Jun 2009 18:01:46 +0200 Subject: i2c: Remove void casts Remove uneeded void casts. Signed-off-by: Jack Stone Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 85e2e919d1c..dfd7bc8094b 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1509,7 +1509,7 @@ struct i2c_adapter* i2c_get_adapter(int id) struct i2c_adapter *adapter; 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)) adapter = NULL; -- cgit v1.2.3 From 66b650f04576a6737579ec404446450026ff2e0b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 15 Jun 2009 18:01:46 +0200 Subject: i2c: Retry automatically on arbitration loss Some small changes in i2c core to retry i2c xfers until either the maximum number of retries or the timeout is hit. Signed-off-by: Clifford Wolf Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index dfd7bc8094b..635c488262c 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1022,7 +1022,8 @@ module_exit(i2c_exit); */ 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: * @@ -1060,7 +1061,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 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); return ret; @@ -1995,14 +2004,27 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags, char read_write, u8 command, int protocol, union i2c_smbus_data *data) { + unsigned long orig_jiffies; + int try; s32 res; flags &= I2C_M_TEN | I2C_CLIENT_PEC; if (adapter->algo->smbus_xfer) { 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); } else res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, -- cgit v1.2.3 From fa1b2ca4fa271f9300a764b9d505a027156f749b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 15 Jun 2009 18:01:48 +0200 Subject: i2c: Do not probe for TV chips on Voodoo3 adapters There's no point in giving the I2C bus of Voodoo3 adapters a class value, there's no video chip driver checking for it anymore. If support is ever needed, the video device should be instantiated explicitly rather than probed. To the best of my knowledge the only video chip that can be found on these boards is a BT869 video encoder, for which no support exists currently. Signed-off-by: Jean Delvare Acked-by: Krzysztof Helt --- drivers/i2c/busses/i2c-voodoo3.c | 1 - drivers/video/tdfxfb.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c index 1a474acc0dd..7663d57833a 100644 --- a/drivers/i2c/busses/i2c-voodoo3.c +++ b/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 = { .owner = THIS_MODULE, - .class = I2C_CLASS_TV_ANALOG, .name = "I2C Voodoo3/Banshee adapter", .algo_data = &voo_i2c_bit_data, }; diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 89f231dc443..ff43c888502 100644 --- a/drivers/video/tdfxfb.c +++ b/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)); chan->adapter.owner = THIS_MODULE; - chan->adapter.class = I2C_CLASS_TV_ANALOG; chan->adapter.algo_data = &chan->algo; chan->adapter.dev.parent = dev; chan->algo.setsda = tdfxfb_i2c_setsda; -- cgit v1.2.3 From c52cf01f5b35d77b2a918c319e22567de5c3c15f Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 15 Jun 2009 18:01:48 +0200 Subject: i2c: Do not give adapters a default parent We don't need to give adapters a parent if they don't have one. The driver core will put them in the virtual device directory and all will be fine. Signed-off-by: Jean Delvare --- drivers/i2c/i2c-core.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 635c488262c..5ed622ee65c 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -451,16 +450,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) 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 */ if (adap->timeout == 0) adap->timeout = HZ; -- cgit v1.2.3 From 4b364f230a5ef984818837ec7c2be0884eac191c Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 15 Jun 2009 18:01:49 +0200 Subject: i2c/chips: Move max6875 to drivers/misc/eeprom This driver only reads the user EEPROM of that chip, so we can move it to the eeprom-directory in order to further clean up (and later remove) drivers/i2c/chips. The Kconfig text was updated to match the current functionality, dropping the meanwhile obsoleted parts. Defconfigs have been adapted. Signed-off-by: Wolfram Sang Acked-by: Ben Gardner Signed-off-by: Jean Delvare --- drivers/i2c/chips/Kconfig | 15 --- drivers/i2c/chips/Makefile | 1 - drivers/i2c/chips/max6875.c | 246 ------------------------------------------ drivers/misc/eeprom/Kconfig | 14 +++ drivers/misc/eeprom/Makefile | 1 + drivers/misc/eeprom/max6875.c | 246 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 261 insertions(+), 262 deletions(-) delete mode 100644 drivers/i2c/chips/max6875.c create mode 100644 drivers/misc/eeprom/max6875.c (limited to 'drivers') diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index 8f8c81eb0ae..02d746c9c47 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -64,21 +64,6 @@ config SENSORS_PCA9539 This driver is deprecated and will be dropped soon. Use 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 tristate "Taos TSL2550 ambient light sensor" depends on EXPERIMENTAL diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 55a37603718..f4680d16ee3 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -11,7 +11,6 @@ # obj-$(CONFIG_DS1682) += ds1682.o -obj-$(CONFIG_SENSORS_MAX6875) += max6875.o obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_PCF8575) += pcf8575.o diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c deleted file mode 100644 index 033d9d81ec8..00000000000 --- a/drivers/i2c/chips/max6875.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - max6875.c - driver for MAX6874/MAX6875 - - Copyright (C) 2005 Ben Gardner - - Based on i2c/chips/eeprom.c - - The MAX6875 has a bank of registers and two banks of EEPROM. - Address ranges are defined as follows: - * 0x0000 - 0x0046 = configuration registers - * 0x8000 - 0x8046 = configuration EEPROM - * 0x8100 - 0x82FF = user EEPROM - - This driver makes the user EEPROM available for read. - - The registers & config EEPROM should be accessed via i2c-dev. - - The MAX6875 ignores the lowest address bit, so each chip responds to - two addresses - 0x50/0x51 and 0x52/0x53. - - Note that the MAX6875 uses i2c_smbus_write_byte_data() to set the read - address, so this driver is destructive if loaded for the wrong EEPROM chip. - - 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; version 2 of the License. -*/ - -#include -#include -#include -#include -#include -#include - -/* Do not scan - the MAX6875 access method will write to some EEPROM chips */ -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Insmod parameters */ -I2C_CLIENT_INSMOD_1(max6875); - -/* The MAX6875 can only read/write 16 bytes at a time */ -#define SLICE_SIZE 16 -#define SLICE_BITS 4 - -/* USER EEPROM is at addresses 0x8100 - 0x82FF */ -#define USER_EEPROM_BASE 0x8100 -#define USER_EEPROM_SIZE 0x0200 -#define USER_EEPROM_SLICES 32 - -/* MAX6875 commands */ -#define MAX6875_CMD_BLK_READ 0x84 - -/* Each client has this additional data */ -struct max6875_data { - struct i2c_client *fake_client; - struct mutex update_lock; - - u32 valid; - u8 data[USER_EEPROM_SIZE]; - unsigned long last_updated[USER_EEPROM_SLICES]; -}; - -static void max6875_update_slice(struct i2c_client *client, int slice) -{ - struct max6875_data *data = i2c_get_clientdata(client); - int i, j, addr; - u8 *buf; - - if (slice >= USER_EEPROM_SLICES) - return; - - mutex_lock(&data->update_lock); - - buf = &data->data[slice << SLICE_BITS]; - - if (!(data->valid & (1 << slice)) || - time_after(jiffies, data->last_updated[slice])) { - - dev_dbg(&client->dev, "Starting update of slice %u\n", slice); - - data->valid &= ~(1 << slice); - - addr = USER_EEPROM_BASE + (slice << SLICE_BITS); - - /* select the eeprom address */ - if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) { - dev_err(&client->dev, "address set failed\n"); - goto exit_up; - } - - if (i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { - if (i2c_smbus_read_i2c_block_data(client, - MAX6875_CMD_BLK_READ, - SLICE_SIZE, - buf) != SLICE_SIZE) { - goto exit_up; - } - } else { - for (i = 0; i < SLICE_SIZE; i++) { - j = i2c_smbus_read_byte(client); - if (j < 0) { - goto exit_up; - } - buf[i] = j; - } - } - data->last_updated[slice] = jiffies; - data->valid |= (1 << slice); - } -exit_up: - mutex_unlock(&data->update_lock); -} - -static ssize_t max6875_read(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) -{ - struct i2c_client *client = kobj_to_i2c_client(kobj); - struct max6875_data *data = i2c_get_clientdata(client); - int slice, max_slice; - - if (off > USER_EEPROM_SIZE) - return 0; - - if (off + count > USER_EEPROM_SIZE) - count = USER_EEPROM_SIZE - off; - - /* refresh slices which contain requested bytes */ - max_slice = (off + count - 1) >> SLICE_BITS; - for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++) - max6875_update_slice(client, slice); - - memcpy(buf, &data->data[off], count); - - return count; -} - -static struct bin_attribute user_eeprom_attr = { - .attr = { - .name = "eeprom", - .mode = S_IRUGO, - }, - .size = USER_EEPROM_SIZE, - .read = max6875_read, -}; - -/* Return 0 if detection is successful, -ENODEV otherwise */ -static int max6875_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) -{ - struct i2c_adapter *adapter = client->adapter; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA - | I2C_FUNC_SMBUS_READ_BYTE)) - return -ENODEV; - - /* Only check even addresses */ - if (client->addr & 1) - return -ENODEV; - - strlcpy(info->type, "max6875", I2C_NAME_SIZE); - - return 0; -} - -static int max6875_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct max6875_data *data; - int err; - - if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) - return -ENOMEM; - - /* A fake client is created on the odd address */ - data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); - if (!data->fake_client) { - err = -ENOMEM; - goto exit_kfree; - } - - /* Init real i2c_client */ - i2c_set_clientdata(client, data); - mutex_init(&data->update_lock); - - err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr); - if (err) - goto exit_remove_fake; - - return 0; - -exit_remove_fake: - i2c_unregister_device(data->fake_client); -exit_kfree: - kfree(data); - return err; -} - -static int max6875_remove(struct i2c_client *client) -{ - struct max6875_data *data = i2c_get_clientdata(client); - - i2c_unregister_device(data->fake_client); - - sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr); - kfree(data); - - return 0; -} - -static const struct i2c_device_id max6875_id[] = { - { "max6875", 0 }, - { } -}; - -static struct i2c_driver max6875_driver = { - .driver = { - .name = "max6875", - }, - .probe = max6875_probe, - .remove = max6875_remove, - .id_table = max6875_id, - - .detect = max6875_detect, - .address_data = &addr_data, -}; - -static int __init max6875_init(void) -{ - return i2c_add_driver(&max6875_driver); -} - -static void __exit max6875_exit(void) -{ - i2c_del_driver(&max6875_driver); -} - - -MODULE_AUTHOR("Ben Gardner "); -MODULE_DESCRIPTION("MAX6875 driver"); -MODULE_LICENSE("GPL"); - -module_init(max6875_init); -module_exit(max6875_exit); diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig index 89fec052f3b..9118613af32 100644 --- a/drivers/misc/eeprom/Kconfig +++ b/drivers/misc/eeprom/Kconfig @@ -48,6 +48,20 @@ config EEPROM_LEGACY This driver can also be built as a module. If so, the module 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 tristate "EEPROM 93CX6 support" help diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile index 539dd8f8812..df3d68ffa9d 100644 --- a/drivers/misc/eeprom/Makefile +++ b/drivers/misc/eeprom/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_EEPROM_AT24) += at24.o obj-$(CONFIG_EEPROM_AT25) += at25.o obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o +obj-$(CONFIG_EEPROM_MAX6875) += max6875.o obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c new file mode 100644 index 00000000000..3c0c58eed34 --- /dev/null +++ b/drivers/misc/eeprom/max6875.c @@ -0,0 +1,246 @@ +/* + max6875.c - driver for MAX6874/MAX6875 + + Copyright (C) 2005 Ben Gardner + + Based on eeprom.c + + The MAX6875 has a bank of registers and two banks of EEPROM. + Address ranges are defined as follows: + * 0x0000 - 0x0046 = configuration registers + * 0x8000 - 0x8046 = configuration EEPROM + * 0x8100 - 0x82FF = user EEPROM + + This driver makes the user EEPROM available for read. + + The registers & config EEPROM should be accessed via i2c-dev. + + The MAX6875 ignores the lowest address bit, so each chip responds to + two addresses - 0x50/0x51 and 0x52/0x53. + + Note that the MAX6875 uses i2c_smbus_write_byte_data() to set the read + address, so this driver is destructive if loaded for the wrong EEPROM chip. + + 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; version 2 of the License. +*/ + +#include +#include +#include +#include +#include +#include + +/* Do not scan - the MAX6875 access method will write to some EEPROM chips */ +static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; + +/* Insmod parameters */ +I2C_CLIENT_INSMOD_1(max6875); + +/* The MAX6875 can only read/write 16 bytes at a time */ +#define SLICE_SIZE 16 +#define SLICE_BITS 4 + +/* USER EEPROM is at addresses 0x8100 - 0x82FF */ +#define USER_EEPROM_BASE 0x8100 +#define USER_EEPROM_SIZE 0x0200 +#define USER_EEPROM_SLICES 32 + +/* MAX6875 commands */ +#define MAX6875_CMD_BLK_READ 0x84 + +/* Each client has this additional data */ +struct max6875_data { + struct i2c_client *fake_client; + struct mutex update_lock; + + u32 valid; + u8 data[USER_EEPROM_SIZE]; + unsigned long last_updated[USER_EEPROM_SLICES]; +}; + +static void max6875_update_slice(struct i2c_client *client, int slice) +{ + struct max6875_data *data = i2c_get_clientdata(client); + int i, j, addr; + u8 *buf; + + if (slice >= USER_EEPROM_SLICES) + return; + + mutex_lock(&data->update_lock); + + buf = &data->data[slice << SLICE_BITS]; + + if (!(data->valid & (1 << slice)) || + time_after(jiffies, data->last_updated[slice])) { + + dev_dbg(&client->dev, "Starting update of slice %u\n", slice); + + data->valid &= ~(1 << slice); + + addr = USER_EEPROM_BASE + (slice << SLICE_BITS); + + /* select the eeprom address */ + if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) { + dev_err(&client->dev, "address set failed\n"); + goto exit_up; + } + + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + if (i2c_smbus_read_i2c_block_data(client, + MAX6875_CMD_BLK_READ, + SLICE_SIZE, + buf) != SLICE_SIZE) { + goto exit_up; + } + } else { + for (i = 0; i < SLICE_SIZE; i++) { + j = i2c_smbus_read_byte(client); + if (j < 0) { + goto exit_up; + } + buf[i] = j; + } + } + data->last_updated[slice] = jiffies; + data->valid |= (1 << slice); + } +exit_up: + mutex_unlock(&data->update_lock); +} + +static ssize_t max6875_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct max6875_data *data = i2c_get_clientdata(client); + int slice, max_slice; + + if (off > USER_EEPROM_SIZE) + return 0; + + if (off + count > USER_EEPROM_SIZE) + count = USER_EEPROM_SIZE - off; + + /* refresh slices which contain requested bytes */ + max_slice = (off + count - 1) >> SLICE_BITS; + for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++) + max6875_update_slice(client, slice); + + memcpy(buf, &data->data[off], count); + + return count; +} + +static struct bin_attribute user_eeprom_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO, + }, + .size = USER_EEPROM_SIZE, + .read = max6875_read, +}; + +/* Return 0 if detection is successful, -ENODEV otherwise */ +static int max6875_detect(struct i2c_client *client, int kind, + struct i2c_board_info *info) +{ + struct i2c_adapter *adapter = client->adapter; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -ENODEV; + + /* Only check even addresses */ + if (client->addr & 1) + return -ENODEV; + + strlcpy(info->type, "max6875", I2C_NAME_SIZE); + + return 0; +} + +static int max6875_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max6875_data *data; + int err; + + if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) + return -ENOMEM; + + /* A fake client is created on the odd address */ + data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1); + if (!data->fake_client) { + err = -ENOMEM; + goto exit_kfree; + } + + /* Init real i2c_client */ + i2c_set_clientdata(client, data); + mutex_init(&data->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr); + if (err) + goto exit_remove_fake; + + return 0; + +exit_remove_fake: + i2c_unregister_device(data->fake_client); +exit_kfree: + kfree(data); + return err; +} + +static int max6875_remove(struct i2c_client *client) +{ + struct max6875_data *data = i2c_get_clientdata(client); + + i2c_unregister_device(data->fake_client); + + sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr); + kfree(data); + + return 0; +} + +static const struct i2c_device_id max6875_id[] = { + { "max6875", 0 }, + { } +}; + +static struct i2c_driver max6875_driver = { + .driver = { + .name = "max6875", + }, + .probe = max6875_probe, + .remove = max6875_remove, + .id_table = max6875_id, + + .detect = max6875_detect, + .address_data = &addr_data, +}; + +static int __init max6875_init(void) +{ + return i2c_add_driver(&max6875_driver); +} + +static void __exit max6875_exit(void) +{ + i2c_del_driver(&max6875_driver); +} + + +MODULE_AUTHOR("Ben Gardner "); +MODULE_DESCRIPTION("MAX6875 driver"); +MODULE_LICENSE("GPL"); + +module_init(max6875_init); +module_exit(max6875_exit); -- cgit v1.2.3 From a231591f0427cfb91ae247be974a7fa0e6b37389 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 15 Jun 2009 18:01:49 +0200 Subject: i2c-viapro: Add new PCI device ID for VX855 The south bridge of the VIA VX855 chipset has a different PCI Device ID so i2c-viapro.c needs to be updated with this. Signed-off-by: Harald Welte Signed-off-by: Jean Delvare --- drivers/i2c/busses/Kconfig | 6 +++--- drivers/i2c/busses/i2c-viapro.c | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index c8460fa9cfa..0d04d3ebfc2 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -211,7 +211,7 @@ config I2C_VIA will be called i2c-via. config I2C_VIAPRO - tristate "VIA VT82C596/82C686/82xx and CX700/VX800/VX820" + tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx" depends on PCI help If you say yes to this option, support will be included for the VIA @@ -225,8 +225,8 @@ config I2C_VIAPRO VT8237R/A/S VT8251 CX700 - VX800 - VX820 + VX800/VX820 + VX855/VX875 This driver can also be built as a module. If so, the module will be called i2c-viapro. diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 02e6f724b05..54d810a4d00 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -37,6 +37,7 @@ VT8251 0x3287 yes CX700 0x8324 yes VX800/VX820 0x8353 yes + VX855/VX875 0x8409 yes Note: we assume there can only be one device, with one SMBus interface. */ @@ -404,6 +405,7 @@ found: switch (pdev->device) { case PCI_DEVICE_ID_VIA_CX700: case PCI_DEVICE_ID_VIA_VX800: + case PCI_DEVICE_ID_VIA_VX855: case PCI_DEVICE_ID_VIA_8251: case PCI_DEVICE_ID_VIA_8237: case PCI_DEVICE_ID_VIA_8237A: @@ -469,6 +471,8 @@ static struct pci_device_id vt596_ids[] = { .driver_data = SMBBA3 }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800), .driver_data = SMBBA3 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855), + .driver_data = SMBBA3 }, { 0, } }; -- cgit v1.2.3 From 1b9f37d488f09342610b29ac1c8e734e540932ab Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 15 Jun 2009 18:01:50 +0200 Subject: therm_pm72: Convert to a new-style i2c driver The legacy i2c binding model is going away soon, so convert the macintosh therm_pm72 driver to the new model or it will break. This is really a quick and dirty conversion, that should do the trick for now, but no doubt that something cleaner can be done if anyone is interested. Signed-off-by: Jean Delvare Cc: Benjamin Herrenschmidt Tested-by: Paul Mackerras --- drivers/macintosh/therm_pm72.c | 95 +++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 817607e2af6..a028598af2d 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/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 * 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_adapter *adap; + struct i2c_board_info info; if (id & 0x200) adap = k2; @@ -320,31 +305,21 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name) if (adap == 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); - kfree(clt); 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; fail: - if (state->monitor) - detach_i2c_chip(state->monitor); state->monitor = NULL; 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); } - detach_i2c_chip(state->monitor); 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_fan_pwm); - detach_i2c_chip(state->monitor); 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_fan_rpm); - detach_i2c_chip(state->monitor); 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); - detach_i2c_chip(state->monitor); 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_fan_pwm); - detach_i2c_chip(state->monitor); state->monitor = NULL; } @@ -2008,8 +1976,6 @@ static int attach_fcu(void) */ static void detach_fcu(void) { - if (fcu) - detach_i2c_chip(fcu); fcu = NULL; } @@ -2060,12 +2026,21 @@ static int therm_pm72_attach(struct i2c_adapter *adapter) 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. */ -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); if (state != state_detached) @@ -2096,6 +2071,30 @@ static int therm_pm72_detach(struct i2c_adapter *adapter) 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) { char tmp[64]; -- cgit v1.2.3 From 351ca3e31197929535418f5affc761cd9fb07428 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 15 Jun 2009 18:01:51 +0200 Subject: windfarm: Convert to new-style i2c drivers The legacy i2c binding model is going away soon, so convert the macintosh windfarm drivers to the new model or they will break. Signed-off-by: Jean Delvare Tested-by: Johannes Berg Tested-by: Paul Mackerras Cc: Benjamin Herrenschmidt --- drivers/macintosh/windfarm_lm75_sensor.c | 129 ++++++++++++++++------------ drivers/macintosh/windfarm_max6690_sensor.c | 103 +++++++++++++--------- drivers/macintosh/windfarm_smu_sat.c | 109 +++++++++++++---------- 3 files changed, 197 insertions(+), 144 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index b92b959fe16..529886c7a82 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -37,34 +37,22 @@ struct wf_lm75_sensor { int ds1775 : 1; int inited : 1; - struct i2c_client i2c; + struct i2c_client *i2c; struct wf_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) { struct wf_lm75_sensor *lm = wf_to_lm75(sr); s32 data; - if (lm->i2c.adapter == NULL) + if (lm->i2c == NULL) return -ENODEV; /* Init chip if necessary */ 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", sr->name, cfg); @@ -73,7 +61,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value) * the firmware for now */ 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; /* 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 */ - 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; *value = data; @@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *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); } @@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = { .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; 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); 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 * the device-tree, oh well ... * Add more entries below as you deal with more setups */ if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) - lm->sens.name = "hd-temp"; + name = "hd-temp"; else if (!strcmp(loc, "Incoming Air Temp")) - lm->sens.name = "incoming-air-temp"; + name = "incoming-air-temp"; else if (!strcmp(loc, "ODD Temp")) - lm->sens.name = "optical-drive-temp"; + name = "optical-drive-temp"; else if (!strcmp(loc, "HD Temp")) - lm->sens.name = "hard-drive-temp"; + name = "hard-drive-temp"; else 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; } - 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: - kfree(lm); return NULL; } @@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) 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); /* Mark client detached */ - lm->i2c.adapter = NULL; + lm->i2c = NULL; /* release sensor */ wf_unregister_sensor(&lm->sens); + i2c_set_clientdata(client, NULL); 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) { /* Don't register on old machines that use therm_pm72 for now */ diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index e207a90d6b2..e2a55ecda2b 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -26,34 +26,22 @@ #define MAX6690_EXTERNAL_TEMP 1 struct wf_6690_sensor { - struct i2c_client i2c; + struct i2c_client *i2c; struct wf_sensor sens; }; #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) -#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) - -static int wf_max6690_attach(struct i2c_adapter *adapter); -static int wf_max6690_detach(struct i2c_client *client); - -static struct i2c_driver wf_max6690_driver = { - .driver = { - .name = "wf_max6690", - }, - .attach_adapter = wf_max6690_attach, - .detach_client = wf_max6690_detach, -}; static int wf_max6690_get(struct wf_sensor *sr, s32 *value) { struct wf_6690_sensor *max = wf_to_6690(sr); s32 data; - if (max->i2c.adapter == NULL) + if (max->i2c == NULL) return -ENODEV; /* 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) return data; *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); - if (max->i2c.adapter) { - i2c_detach_client(&max->i2c); - max->i2c.adapter = NULL; - } kfree(max); } @@ -77,19 +61,40 @@ static struct wf_sensor_ops wf_max6690_ops = { .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; - char *name; + int rc; max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); if (max == NULL) { - printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " - "no memory\n", 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")) name = "backside-temp"; else if (!strcmp(loc, "NB Ambient")) @@ -99,27 +104,26 @@ static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr, else 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"); 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: - kfree(max); + return NULL; } static int wf_max6690_attach(struct i2c_adapter *adapter) @@ -154,16 +158,31 @@ static int wf_max6690_attach(struct i2c_adapter *adapter) 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); 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) { /* Don't register on old machines that use therm_pm72 for now */ diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 7847e981ac3..5da729e58f9 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -39,7 +39,7 @@ struct wf_sat { struct mutex mutex; unsigned long last_read; /* jiffies when cache last updated */ u8 cache[16]; - struct i2c_client i2c; + struct i2c_client *i2c; 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 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, 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) 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) { printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); return NULL; } - err = i2c_smbus_read_word_data(&sat->i2c, 9); + err = i2c_smbus_read_word_data(sat->i2c, 9); if (err < 0) { printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); return NULL; @@ -105,7 +93,7 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, return NULL; 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) { printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", err); @@ -138,7 +126,7 @@ static int wf_sat_read_cache(struct wf_sat *sat) { 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) return err; sat->last_read = jiffies; @@ -161,7 +149,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value) int i, err; s32 val; - if (sat->i2c.adapter == NULL) + if (sat->i2c == NULL) return -ENODEV; mutex_lock(&sat->mutex); @@ -193,10 +181,6 @@ static void wf_sat_release(struct wf_sensor *sr) struct wf_sat *sat = sens->sat; if (atomic_dec_and_test(&sat->refcnt)) { - if (sat->i2c.adapter) { - i2c_detach_client(&sat->i2c); - sat->i2c.adapter = NULL; - } if (sat->nr >= 0) sats[sat->nr] = NULL; kfree(sat); @@ -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) { + 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_sensor *sens; const u32 *reg; const char *loc, *type; - u8 addr, chip, core; + u8 chip, core; struct device_node *child; int shift, cpu, index; char *name; 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); if (sat == NULL) - return; + return -ENOMEM; sat->nr = -1; sat->node = of_node_get(dev); atomic_set(&sat->refcnt, 0); 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; 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) sats[sat->nr] = sat; - return; - - fail: - kfree(sat); + return 0; } static int wf_sat_attach(struct i2c_adapter *adapter) @@ -366,16 +367,32 @@ static int wf_sat_attach(struct i2c_adapter *adapter) 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 */ - sat->i2c.adapter = NULL; + sat->i2c = NULL; + i2c_set_clientdata(client, NULL); 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) { return i2c_add_driver(&wf_sat_driver); -- cgit v1.2.3 From 2e613e7f69226bd020987bbf0c2ee251c019ab33 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 15 Jun 2009 18:01:51 +0200 Subject: therm_adt746x: Convert to a new-style i2c driver The legacy i2c binding model is going away soon, so convert the ppc therm_adt746x driver to the new model or it will break. Signed-off-by: Jean Delvare Tested-by: Andreas Schwab Tested-by: Paul Mackerras Cc: Benjamin Herrenschmidt --- drivers/macintosh/therm_adt746x.c | 84 +++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index c0621d50c8a..4a8bf467ff4 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -71,7 +71,7 @@ MODULE_PARM_DESC(verbose,"Verbose log operations " "(default 0)"); struct thermostat { - struct i2c_client clt; + struct i2c_client *clt; u8 temps[3]; u8 cached_temp[3]; u8 initial_limits[3]; @@ -86,9 +86,6 @@ static struct of_device * of_dev; static struct thermostat* thermostat; 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_fan_speed(struct thermostat *th, int speed, int fan); @@ -100,7 +97,7 @@ write_reg(struct thermostat* th, int reg, u8 data) tmp[0] = reg; 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) return rc; if (rc != 2) @@ -115,12 +112,12 @@ read_reg(struct thermostat* th, int reg) int rc; reg_addr = (u8)reg; - rc = i2c_master_send(&th->clt, ®_addr, 1); + rc = i2c_master_send(th->clt, ®_addr, 1); if (rc < 0) return rc; if (rc != 1) return -ENODEV; - rc = i2c_master_recv(&th->clt, (char *)&data, 1); + rc = i2c_master_recv(th->clt, (char *)&data, 1); if (rc < 0) return rc; return data; @@ -130,26 +127,36 @@ static int attach_thermostat(struct i2c_adapter *adapter) { unsigned long bus_no; + struct i2c_board_info info; + struct i2c_client *client; if (strncmp(adapter->name, "uni-n", 5)) return -ENODEV; bus_no = simple_strtoul(adapter->name + 6, NULL, 10); if (bus_no != therm_bus) 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 -detach_thermostat(struct i2c_adapter *adapter) +remove_thermostat(struct i2c_client *client) { - struct thermostat* th; + struct thermostat *th = i2c_get_clientdata(client); int i; - if (thermostat == NULL) - return 0; - - th = thermostat; - if (thread_therm != NULL) { kthread_stop(thread_therm); } @@ -165,8 +172,6 @@ detach_thermostat(struct i2c_adapter *adapter) write_both_fan_speed(th, -1); - i2c_detach_client(&th->clt); - thermostat = NULL; kfree(th); @@ -174,14 +179,6 @@ detach_thermostat(struct i2c_adapter *adapter) 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) { u8 tmp[2]; @@ -369,8 +366,8 @@ static void set_limit(struct thermostat *th, int i) 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; int rc; @@ -383,16 +380,12 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, if (!th) 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); 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); return -ENODEV; } @@ -421,14 +414,6 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, 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 */ th->last_speed[0] = -2; th->last_speed[1] = -2; @@ -454,6 +439,21 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, 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 * pass around to the attribute functions, so we don't really have -- cgit v1.2.3 From 036533e232922ec6667817de9b037d0b1ebd062e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 15 Jun 2009 18:01:52 +0200 Subject: therm_windtunnel: Convert to a new-style i2c driver The legacy i2c binding model is going away soon, so convert the ppc therm_windtunnel driver to the new model or it will break. Signed-off-by: Jean Delvare Cc: Benjamin Herrenschmidt Cc: Paul Mackerras --- drivers/macintosh/therm_windtunnel.c | 126 +++++++++++++++++------------------ 1 file changed, 60 insertions(+), 66 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 3da0a02efd7..40023313a76 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -48,16 +48,6 @@ #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 { volatile int running; struct task_struct *poll_task; @@ -315,53 +305,54 @@ static int control_loop(void *dummy) static int 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) ) return 0; 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 ) { x.running = 1; x.poll_task = kthread_run(control_loop, NULL, "g4fand"); } } - return ret; + return 0; } 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 attach_fan( struct i2c_client *cl ) @@ -374,13 +365,8 @@ attach_fan( struct i2c_client *cl ) goto out; 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: - if( cl != x.fan ) - kfree( cl ); return 0; } @@ -412,39 +398,47 @@ attach_thermostat( struct i2c_client *cl ) x.temp = temp; x.overheat_temp = os_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: - if( cl != x.thermostat ) - kfree( cl ); return 0; } +enum chip { ds1775, adm1030 }; + +static const struct i2c_device_id therm_windtunnel_id[] = { + { "therm_ds1775", ds1775 }, + { "therm_adm1030", adm1030 }, + { } +}; + 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 | I2C_FUNC_SMBUS_WRITE_BYTE) ) 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_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 */ -- cgit v1.2.3