Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
  hwmon: (lm75) Drop legacy i2c driver
  i2c: correct some size_t printk formats
  i2c: Check for address business before creating clients
  i2c: Let users select algorithm drivers manually again
  i2c: Fix NULL pointer dereference in i2c_new_probed_device
  i2c: Fix oops on bus multiplexer driver loading
This commit is contained in:
Linus Torvalds 2008-08-11 10:44:13 -07:00
commit 29bb1bdb26
8 changed files with 66 additions and 110 deletions

View File

@ -54,11 +54,11 @@ enum lm75_type { /* keep sorted in alphabetical order */
tmp75,
};
/* Addresses scanned by legacy style driver binding */
/* Addresses scanned */
static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
/* Insmod parameters (only for legacy style driver binding) */
/* Insmod parameters */
I2C_CLIENT_INSMOD_1(lm75);
@ -72,7 +72,6 @@ static const u8 LM75_REG_TEMP[3] = {
/* Each client has this additional data */
struct lm75_data {
struct i2c_client *client;
struct device *hwmon_dev;
struct mutex update_lock;
u8 orig_conf;
@ -138,7 +137,7 @@ static const struct attribute_group lm75_group = {
/*-----------------------------------------------------------------------*/
/* "New style" I2C driver binding -- following the driver model */
/* device probe and removal */
static int
lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
@ -157,8 +156,6 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
return -ENOMEM;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->update_lock);
/* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
@ -236,45 +233,16 @@ static const struct i2c_device_id lm75_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, lm75_ids);
static struct i2c_driver lm75_driver = {
.driver = {
.name = "lm75",
},
.probe = lm75_probe,
.remove = lm75_remove,
.id_table = lm75_ids,
};
/*-----------------------------------------------------------------------*/
/* "Legacy" I2C driver binding */
static struct i2c_driver lm75_legacy_driver;
/* This function is called by i2c_probe */
static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm75_detect(struct i2c_client *new_client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = new_client->adapter;
int i;
struct i2c_client *new_client;
int err = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
goto exit;
/* OK. For now, we presume we have a valid address. We create the
client structure, even though there may be no sensor present.
But it allows us to use i2c_smbus_read_*_data() calls. */
new_client = kzalloc(sizeof *new_client, GFP_KERNEL);
if (!new_client) {
err = -ENOMEM;
goto exit;
}
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &lm75_legacy_driver;
new_client->flags = 0;
return -ENODEV;
/* Now, we do the remaining detection. There is no identification-
dedicated register so we have to rely on several tricks:
@ -294,71 +262,44 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
|| i2c_smbus_read_word_data(new_client, 5) != hyst
|| i2c_smbus_read_word_data(new_client, 6) != hyst
|| i2c_smbus_read_word_data(new_client, 7) != hyst)
goto exit_free;
return -ENODEV;
os = i2c_smbus_read_word_data(new_client, 3);
if (i2c_smbus_read_word_data(new_client, 4) != os
|| i2c_smbus_read_word_data(new_client, 5) != os
|| i2c_smbus_read_word_data(new_client, 6) != os
|| i2c_smbus_read_word_data(new_client, 7) != os)
goto exit_free;
return -ENODEV;
/* Unused bits */
if (conf & 0xe0)
goto exit_free;
return -ENODEV;
/* Addresses cycling */
for (i = 8; i < 0xff; i += 8)
if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
|| i2c_smbus_read_word_data(new_client, i + 2) != hyst
|| i2c_smbus_read_word_data(new_client, i + 3) != os)
goto exit_free;
return -ENODEV;
}
/* NOTE: we treat "force=..." and "force_lm75=..." the same.
* Only new-style driver binding distinguishes chip types.
*/
strlcpy(new_client->name, "lm75", I2C_NAME_SIZE);
/* Tell the I2C layer a new client has arrived */
err = i2c_attach_client(new_client);
if (err)
goto exit_free;
err = lm75_probe(new_client, NULL);
if (err < 0)
goto exit_detach;
strlcpy(info->type, "lm75", I2C_NAME_SIZE);
return 0;
exit_detach:
i2c_detach_client(new_client);
exit_free:
kfree(new_client);
exit:
return err;
}
static int lm75_attach_adapter(struct i2c_adapter *adapter)
{
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
return i2c_probe(adapter, &addr_data, lm75_detect);
}
static int lm75_detach_client(struct i2c_client *client)
{
lm75_remove(client);
i2c_detach_client(client);
kfree(client);
return 0;
}
static struct i2c_driver lm75_legacy_driver = {
static struct i2c_driver lm75_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm75_legacy",
.name = "lm75",
},
.attach_adapter = lm75_attach_adapter,
.detach_client = lm75_detach_client,
.probe = lm75_probe,
.remove = lm75_remove,
.id_table = lm75_ids,
.detect = lm75_detect,
.address_data = &addr_data,
};
/*-----------------------------------------------------------------------*/
@ -424,22 +365,11 @@ static struct lm75_data *lm75_update_device(struct device *dev)
static int __init sensors_lm75_init(void)
{
int status;
status = i2c_add_driver(&lm75_driver);
if (status < 0)
return status;
status = i2c_add_driver(&lm75_legacy_driver);
if (status < 0)
i2c_del_driver(&lm75_driver);
return status;
return i2c_add_driver(&lm75_driver);
}
static void __exit sensors_lm75_exit(void)
{
i2c_del_driver(&lm75_legacy_driver);
i2c_del_driver(&lm75_driver);
}

View File

@ -38,6 +38,20 @@ config I2C_CHARDEV
This support is also available as a module. If so, the module
will be called i2c-dev.
config I2C_HELPER_AUTO
bool "Autoselect pertinent helper modules"
default y
help
Some I2C bus drivers require so-called "I2C algorithm" modules
to work. These are basically software-only abstractions of generic
I2C interfaces. This option will autoselect them so that you don't
have to care.
Unselect this only if you need to enable additional helper
modules, for example for use with external I2C bus drivers.
In doubt, say Y.
source drivers/i2c/algos/Kconfig
source drivers/i2c/busses/Kconfig
source drivers/i2c/chips/Kconfig

View File

@ -2,15 +2,20 @@
# I2C algorithm drivers configuration
#
menu "I2C Algorithms"
depends on !I2C_HELPER_AUTO
config I2C_ALGOBIT
tristate
tristate "I2C bit-banging interfaces"
config I2C_ALGOPCF
tristate
tristate "I2C PCF 8584 interfaces"
config I2C_ALGOPCA
tristate
tristate "I2C PCA 9564 interfaces"
config I2C_ALGO_SGI
tristate
depends on SGI_IP22 || SGI_IP32 || X86_VISWS
endmenu

View File

@ -155,6 +155,9 @@ static int __init amd756_s4882_init(void)
int i, error;
union i2c_smbus_data ioconfig;
if (!amd756_smbus.dev.parent)
return -ENODEV;
/* Configure the PCA9556 multiplexer */
ioconfig.byte = 0x00; /* All I/O to output mode */
error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
@ -168,11 +171,7 @@ static int __init amd756_s4882_init(void)
/* Unregister physical bus */
error = i2c_del_adapter(&amd756_smbus);
if (error) {
if (error == -EINVAL)
error = -ENODEV;
else
dev_err(&amd756_smbus.dev, "Physical bus removal "
"failed\n");
dev_err(&amd756_smbus.dev, "Physical bus removal failed\n");
goto ERROR0;
}

View File

@ -150,6 +150,9 @@ static int __init nforce2_s4985_init(void)
int i, error;
union i2c_smbus_data ioconfig;
if (!nforce2_smbus)
return -ENODEV;
/* Configure the PCA9556 multiplexer */
ioconfig.byte = 0x00; /* All I/O to output mode */
error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
@ -161,8 +164,6 @@ static int __init nforce2_s4985_init(void)
}
/* Unregister physical bus */
if (!nforce2_smbus)
return -ENODEV;
error = i2c_del_adapter(nforce2_smbus);
if (error) {
dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n");

View File

@ -188,7 +188,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
count = I2C_SMBUS_BLOCK_MAX;
status = i2c_smbus_read_i2c_block_data(client, offset,
count, buf);
dev_dbg(&client->dev, "smbus read %zd@%d --> %d\n",
dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
count, offset, status);
return (status < 0) ? -EIO : status;
}
@ -214,7 +214,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
msg[1].len = count;
status = i2c_transfer(client->adapter, msg, 2);
dev_dbg(&client->dev, "i2c read %zd@%d --> %d\n",
dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
count, offset, status);
if (status == 2)
@ -334,7 +334,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
if (status == 1)
status = count;
}
dev_dbg(&client->dev, "write %zd@%d --> %zd (%ld)\n",
dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n",
count, offset, status, jiffies);
if (status == count)
@ -512,7 +512,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
i2c_set_clientdata(client, at24);
dev_info(&client->dev, "%Zd byte %s EEPROM %s\n",
dev_info(&client->dev, "%zu byte %s EEPROM %s\n",
at24->bin.size, client->name,
writable ? "(writable)" : "(read-only)");
dev_dbg(&client->dev,

View File

@ -813,7 +813,12 @@ static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
int i2c_attach_client(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
int res = 0;
int res;
/* Check for address business */
res = i2c_check_addr(adapter, client->addr);
if (res)
return res;
client->dev.parent = &client->adapter->dev;
client->dev.bus = &i2c_bus_type;
@ -1451,9 +1456,11 @@ i2c_new_probed_device(struct i2c_adapter *adap,
if ((addr_list[i] & ~0x07) == 0x30
|| (addr_list[i] & ~0x0f) == 0x50
|| !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
union i2c_smbus_data data;
if (i2c_smbus_xfer(adap, addr_list[i], 0,
I2C_SMBUS_READ, 0,
I2C_SMBUS_BYTE, NULL) >= 0)
I2C_SMBUS_BYTE, &data) >= 0)
break;
} else {
if (i2c_smbus_xfer(adap, addr_list[i], 0,

View File

@ -147,7 +147,7 @@ static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
if (tmp==NULL)
return -ENOMEM;
pr_debug("i2c-dev: i2c-%d reading %zd bytes.\n",
pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
iminor(file->f_path.dentry->d_inode), count);
ret = i2c_master_recv(client,tmp,count);
@ -175,7 +175,7 @@ static ssize_t i2cdev_write (struct file *file, const char __user *buf, size_t c
return -EFAULT;
}
pr_debug("i2c-dev: i2c-%d writing %zd bytes.\n",
pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
iminor(file->f_path.dentry->d_inode), count);
ret = i2c_master_send(client,tmp,count);