aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-08-11 13:44:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-08-11 13:44:13 -0400
commit29bb1bdb260cd504c6ec0f567cc0cba6a4cf40e7 (patch)
tree5091868c0aadabf85773a462ff5bd95cac28c434
parent3f1ae223902834d81b54b5d333f9efca07ad656b (diff)
parent8ff69eebf5bf8a123a117b78412d5efb85765d8b (diff)
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
-rw-r--r--drivers/hwmon/lm75.c114
-rw-r--r--drivers/i2c/Kconfig14
-rw-r--r--drivers/i2c/algos/Kconfig11
-rw-r--r--drivers/i2c/busses/i2c-amd756-s4882.c9
-rw-r--r--drivers/i2c/busses/i2c-nforce2-s4985.c5
-rw-r--r--drivers/i2c/chips/at24.c8
-rw-r--r--drivers/i2c/i2c-core.c11
-rw-r--r--drivers/i2c/i2c-dev.c4
8 files changed, 66 insertions, 110 deletions
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 7880c273c2c5..8f9595f2fb53 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -54,11 +54,11 @@ enum lm75_type { /* keep sorted in alphabetical order */
54 tmp75, 54 tmp75,
55}; 55};
56 56
57/* Addresses scanned by legacy style driver binding */ 57/* Addresses scanned */
58static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 58static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
59 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; 59 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
60 60
61/* Insmod parameters (only for legacy style driver binding) */ 61/* Insmod parameters */
62I2C_CLIENT_INSMOD_1(lm75); 62I2C_CLIENT_INSMOD_1(lm75);
63 63
64 64
@@ -72,7 +72,6 @@ static const u8 LM75_REG_TEMP[3] = {
72 72
73/* Each client has this additional data */ 73/* Each client has this additional data */
74struct lm75_data { 74struct lm75_data {
75 struct i2c_client *client;
76 struct device *hwmon_dev; 75 struct device *hwmon_dev;
77 struct mutex update_lock; 76 struct mutex update_lock;
78 u8 orig_conf; 77 u8 orig_conf;
@@ -138,7 +137,7 @@ static const struct attribute_group lm75_group = {
138 137
139/*-----------------------------------------------------------------------*/ 138/*-----------------------------------------------------------------------*/
140 139
141/* "New style" I2C driver binding -- following the driver model */ 140/* device probe and removal */
142 141
143static int 142static int
144lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) 143lm75_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)
157 return -ENOMEM; 156 return -ENOMEM;
158 157
159 i2c_set_clientdata(client, data); 158 i2c_set_clientdata(client, data);
160
161 data->client = client;
162 mutex_init(&data->update_lock); 159 mutex_init(&data->update_lock);
163 160
164 /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. 161 /* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
@@ -236,45 +233,16 @@ static const struct i2c_device_id lm75_ids[] = {
236}; 233};
237MODULE_DEVICE_TABLE(i2c, lm75_ids); 234MODULE_DEVICE_TABLE(i2c, lm75_ids);
238 235
239static struct i2c_driver lm75_driver = { 236/* Return 0 if detection is successful, -ENODEV otherwise */
240 .driver = { 237static int lm75_detect(struct i2c_client *new_client, int kind,
241 .name = "lm75", 238 struct i2c_board_info *info)
242 },
243 .probe = lm75_probe,
244 .remove = lm75_remove,
245 .id_table = lm75_ids,
246};
247
248/*-----------------------------------------------------------------------*/
249
250/* "Legacy" I2C driver binding */
251
252static struct i2c_driver lm75_legacy_driver;
253
254/* This function is called by i2c_probe */
255static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
256{ 239{
240 struct i2c_adapter *adapter = new_client->adapter;
257 int i; 241 int i;
258 struct i2c_client *new_client;
259 int err = 0;
260 242
261 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 243 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
262 I2C_FUNC_SMBUS_WORD_DATA)) 244 I2C_FUNC_SMBUS_WORD_DATA))
263 goto exit; 245 return -ENODEV;
264
265 /* OK. For now, we presume we have a valid address. We create the
266 client structure, even though there may be no sensor present.
267 But it allows us to use i2c_smbus_read_*_data() calls. */
268 new_client = kzalloc(sizeof *new_client, GFP_KERNEL);
269 if (!new_client) {
270 err = -ENOMEM;
271 goto exit;
272 }
273
274 new_client->addr = address;
275 new_client->adapter = adapter;
276 new_client->driver = &lm75_legacy_driver;
277 new_client->flags = 0;
278 246
279 /* Now, we do the remaining detection. There is no identification- 247 /* Now, we do the remaining detection. There is no identification-
280 dedicated register so we have to rely on several tricks: 248 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)
294 || i2c_smbus_read_word_data(new_client, 5) != hyst 262 || i2c_smbus_read_word_data(new_client, 5) != hyst
295 || i2c_smbus_read_word_data(new_client, 6) != hyst 263 || i2c_smbus_read_word_data(new_client, 6) != hyst
296 || i2c_smbus_read_word_data(new_client, 7) != hyst) 264 || i2c_smbus_read_word_data(new_client, 7) != hyst)
297 goto exit_free; 265 return -ENODEV;
298 os = i2c_smbus_read_word_data(new_client, 3); 266 os = i2c_smbus_read_word_data(new_client, 3);
299 if (i2c_smbus_read_word_data(new_client, 4) != os 267 if (i2c_smbus_read_word_data(new_client, 4) != os
300 || i2c_smbus_read_word_data(new_client, 5) != os 268 || i2c_smbus_read_word_data(new_client, 5) != os
301 || i2c_smbus_read_word_data(new_client, 6) != os 269 || i2c_smbus_read_word_data(new_client, 6) != os
302 || i2c_smbus_read_word_data(new_client, 7) != os) 270 || i2c_smbus_read_word_data(new_client, 7) != os)
303 goto exit_free; 271 return -ENODEV;
304 272
305 /* Unused bits */ 273 /* Unused bits */
306 if (conf & 0xe0) 274 if (conf & 0xe0)
307 goto exit_free; 275 return -ENODEV;
308 276
309 /* Addresses cycling */ 277 /* Addresses cycling */
310 for (i = 8; i < 0xff; i += 8) 278 for (i = 8; i < 0xff; i += 8)
311 if (i2c_smbus_read_byte_data(new_client, i + 1) != conf 279 if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
312 || i2c_smbus_read_word_data(new_client, i + 2) != hyst 280 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
313 || i2c_smbus_read_word_data(new_client, i + 3) != os) 281 || i2c_smbus_read_word_data(new_client, i + 3) != os)
314 goto exit_free; 282 return -ENODEV;
315 } 283 }
316 284
317 /* NOTE: we treat "force=..." and "force_lm75=..." the same. 285 /* NOTE: we treat "force=..." and "force_lm75=..." the same.
318 * Only new-style driver binding distinguishes chip types. 286 * Only new-style driver binding distinguishes chip types.
319 */ 287 */
320 strlcpy(new_client->name, "lm75", I2C_NAME_SIZE); 288 strlcpy(info->type, "lm75", I2C_NAME_SIZE);
321
322 /* Tell the I2C layer a new client has arrived */
323 err = i2c_attach_client(new_client);
324 if (err)
325 goto exit_free;
326
327 err = lm75_probe(new_client, NULL);
328 if (err < 0)
329 goto exit_detach;
330 289
331 return 0; 290 return 0;
332
333exit_detach:
334 i2c_detach_client(new_client);
335exit_free:
336 kfree(new_client);
337exit:
338 return err;
339}
340
341static int lm75_attach_adapter(struct i2c_adapter *adapter)
342{
343 if (!(adapter->class & I2C_CLASS_HWMON))
344 return 0;
345 return i2c_probe(adapter, &addr_data, lm75_detect);
346} 291}
347 292
348static int lm75_detach_client(struct i2c_client *client) 293static struct i2c_driver lm75_driver = {
349{ 294 .class = I2C_CLASS_HWMON,
350 lm75_remove(client);
351 i2c_detach_client(client);
352 kfree(client);
353 return 0;
354}
355
356static struct i2c_driver lm75_legacy_driver = {
357 .driver = { 295 .driver = {
358 .name = "lm75_legacy", 296 .name = "lm75",
359 }, 297 },
360 .attach_adapter = lm75_attach_adapter, 298 .probe = lm75_probe,
361 .detach_client = lm75_detach_client, 299 .remove = lm75_remove,
300 .id_table = lm75_ids,
301 .detect = lm75_detect,
302 .address_data = &addr_data,
362}; 303};
363 304
364/*-----------------------------------------------------------------------*/ 305/*-----------------------------------------------------------------------*/
@@ -424,22 +365,11 @@ static struct lm75_data *lm75_update_device(struct device *dev)
424 365
425static int __init sensors_lm75_init(void) 366static int __init sensors_lm75_init(void)
426{ 367{
427 int status; 368 return i2c_add_driver(&lm75_driver);
428
429 status = i2c_add_driver(&lm75_driver);
430 if (status < 0)
431 return status;
432
433 status = i2c_add_driver(&lm75_legacy_driver);
434 if (status < 0)
435 i2c_del_driver(&lm75_driver);
436
437 return status;
438} 369}
439 370
440static void __exit sensors_lm75_exit(void) 371static void __exit sensors_lm75_exit(void)
441{ 372{
442 i2c_del_driver(&lm75_legacy_driver);
443 i2c_del_driver(&lm75_driver); 373 i2c_del_driver(&lm75_driver);
444} 374}
445 375
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 96867347bcbf..711ca08ab776 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -38,6 +38,20 @@ config I2C_CHARDEV
38 This support is also available as a module. If so, the module 38 This support is also available as a module. If so, the module
39 will be called i2c-dev. 39 will be called i2c-dev.
40 40
41config I2C_HELPER_AUTO
42 bool "Autoselect pertinent helper modules"
43 default y
44 help
45 Some I2C bus drivers require so-called "I2C algorithm" modules
46 to work. These are basically software-only abstractions of generic
47 I2C interfaces. This option will autoselect them so that you don't
48 have to care.
49
50 Unselect this only if you need to enable additional helper
51 modules, for example for use with external I2C bus drivers.
52
53 In doubt, say Y.
54
41source drivers/i2c/algos/Kconfig 55source drivers/i2c/algos/Kconfig
42source drivers/i2c/busses/Kconfig 56source drivers/i2c/busses/Kconfig
43source drivers/i2c/chips/Kconfig 57source drivers/i2c/chips/Kconfig
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index 7137a17402fe..b788579b8227 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -2,15 +2,20 @@
2# I2C algorithm drivers configuration 2# I2C algorithm drivers configuration
3# 3#
4 4
5menu "I2C Algorithms"
6 depends on !I2C_HELPER_AUTO
7
5config I2C_ALGOBIT 8config I2C_ALGOBIT
6 tristate 9 tristate "I2C bit-banging interfaces"
7 10
8config I2C_ALGOPCF 11config I2C_ALGOPCF
9 tristate 12 tristate "I2C PCF 8584 interfaces"
10 13
11config I2C_ALGOPCA 14config I2C_ALGOPCA
12 tristate 15 tristate "I2C PCA 9564 interfaces"
13 16
14config I2C_ALGO_SGI 17config I2C_ALGO_SGI
15 tristate 18 tristate
16 depends on SGI_IP22 || SGI_IP32 || X86_VISWS 19 depends on SGI_IP22 || SGI_IP32 || X86_VISWS
20
21endmenu
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c
index 72872d1e63ef..8ba2bcf727d3 100644
--- a/drivers/i2c/busses/i2c-amd756-s4882.c
+++ b/drivers/i2c/busses/i2c-amd756-s4882.c
@@ -155,6 +155,9 @@ static int __init amd756_s4882_init(void)
155 int i, error; 155 int i, error;
156 union i2c_smbus_data ioconfig; 156 union i2c_smbus_data ioconfig;
157 157
158 if (!amd756_smbus.dev.parent)
159 return -ENODEV;
160
158 /* Configure the PCA9556 multiplexer */ 161 /* Configure the PCA9556 multiplexer */
159 ioconfig.byte = 0x00; /* All I/O to output mode */ 162 ioconfig.byte = 0x00; /* All I/O to output mode */
160 error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, 163 error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
@@ -168,11 +171,7 @@ static int __init amd756_s4882_init(void)
168 /* Unregister physical bus */ 171 /* Unregister physical bus */
169 error = i2c_del_adapter(&amd756_smbus); 172 error = i2c_del_adapter(&amd756_smbus);
170 if (error) { 173 if (error) {
171 if (error == -EINVAL) 174 dev_err(&amd756_smbus.dev, "Physical bus removal failed\n");
172 error = -ENODEV;
173 else
174 dev_err(&amd756_smbus.dev, "Physical bus removal "
175 "failed\n");
176 goto ERROR0; 175 goto ERROR0;
177 } 176 }
178 177
diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c
index d1a4cbcf2aa4..29015eb9ca46 100644
--- a/drivers/i2c/busses/i2c-nforce2-s4985.c
+++ b/drivers/i2c/busses/i2c-nforce2-s4985.c
@@ -150,6 +150,9 @@ static int __init nforce2_s4985_init(void)
150 int i, error; 150 int i, error;
151 union i2c_smbus_data ioconfig; 151 union i2c_smbus_data ioconfig;
152 152
153 if (!nforce2_smbus)
154 return -ENODEV;
155
153 /* Configure the PCA9556 multiplexer */ 156 /* Configure the PCA9556 multiplexer */
154 ioconfig.byte = 0x00; /* All I/O to output mode */ 157 ioconfig.byte = 0x00; /* All I/O to output mode */
155 error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03, 158 error = i2c_smbus_xfer(nforce2_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
@@ -161,8 +164,6 @@ static int __init nforce2_s4985_init(void)
161 } 164 }
162 165
163 /* Unregister physical bus */ 166 /* Unregister physical bus */
164 if (!nforce2_smbus)
165 return -ENODEV;
166 error = i2c_del_adapter(nforce2_smbus); 167 error = i2c_del_adapter(nforce2_smbus);
167 if (error) { 168 if (error) {
168 dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n"); 169 dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n");
diff --git a/drivers/i2c/chips/at24.c b/drivers/i2c/chips/at24.c
index e764c94f3e3d..2a4acb269569 100644
--- a/drivers/i2c/chips/at24.c
+++ b/drivers/i2c/chips/at24.c
@@ -188,7 +188,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
188 count = I2C_SMBUS_BLOCK_MAX; 188 count = I2C_SMBUS_BLOCK_MAX;
189 status = i2c_smbus_read_i2c_block_data(client, offset, 189 status = i2c_smbus_read_i2c_block_data(client, offset,
190 count, buf); 190 count, buf);
191 dev_dbg(&client->dev, "smbus read %zd@%d --> %d\n", 191 dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
192 count, offset, status); 192 count, offset, status);
193 return (status < 0) ? -EIO : status; 193 return (status < 0) ? -EIO : status;
194 } 194 }
@@ -214,7 +214,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
214 msg[1].len = count; 214 msg[1].len = count;
215 215
216 status = i2c_transfer(client->adapter, msg, 2); 216 status = i2c_transfer(client->adapter, msg, 2);
217 dev_dbg(&client->dev, "i2c read %zd@%d --> %d\n", 217 dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
218 count, offset, status); 218 count, offset, status);
219 219
220 if (status == 2) 220 if (status == 2)
@@ -334,7 +334,7 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
334 if (status == 1) 334 if (status == 1)
335 status = count; 335 status = count;
336 } 336 }
337 dev_dbg(&client->dev, "write %zd@%d --> %zd (%ld)\n", 337 dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n",
338 count, offset, status, jiffies); 338 count, offset, status, jiffies);
339 339
340 if (status == count) 340 if (status == count)
@@ -512,7 +512,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
512 512
513 i2c_set_clientdata(client, at24); 513 i2c_set_clientdata(client, at24);
514 514
515 dev_info(&client->dev, "%Zd byte %s EEPROM %s\n", 515 dev_info(&client->dev, "%zu byte %s EEPROM %s\n",
516 at24->bin.size, client->name, 516 at24->bin.size, client->name,
517 writable ? "(writable)" : "(read-only)"); 517 writable ? "(writable)" : "(read-only)");
518 dev_dbg(&client->dev, 518 dev_dbg(&client->dev,
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 7bf38c418086..550853f79ae8 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -813,7 +813,12 @@ static int i2c_check_addr(struct i2c_adapter *adapter, int addr)
813int i2c_attach_client(struct i2c_client *client) 813int i2c_attach_client(struct i2c_client *client)
814{ 814{
815 struct i2c_adapter *adapter = client->adapter; 815 struct i2c_adapter *adapter = client->adapter;
816 int res = 0; 816 int res;
817
818 /* Check for address business */
819 res = i2c_check_addr(adapter, client->addr);
820 if (res)
821 return res;
817 822
818 client->dev.parent = &client->adapter->dev; 823 client->dev.parent = &client->adapter->dev;
819 client->dev.bus = &i2c_bus_type; 824 client->dev.bus = &i2c_bus_type;
@@ -1451,9 +1456,11 @@ i2c_new_probed_device(struct i2c_adapter *adap,
1451 if ((addr_list[i] & ~0x07) == 0x30 1456 if ((addr_list[i] & ~0x07) == 0x30
1452 || (addr_list[i] & ~0x0f) == 0x50 1457 || (addr_list[i] & ~0x0f) == 0x50
1453 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) { 1458 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
1459 union i2c_smbus_data data;
1460
1454 if (i2c_smbus_xfer(adap, addr_list[i], 0, 1461 if (i2c_smbus_xfer(adap, addr_list[i], 0,
1455 I2C_SMBUS_READ, 0, 1462 I2C_SMBUS_READ, 0,
1456 I2C_SMBUS_BYTE, NULL) >= 0) 1463 I2C_SMBUS_BYTE, &data) >= 0)
1457 break; 1464 break;
1458 } else { 1465 } else {
1459 if (i2c_smbus_xfer(adap, addr_list[i], 0, 1466 if (i2c_smbus_xfer(adap, addr_list[i], 0,
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 9d55c6383b23..af4491fa7e34 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -147,7 +147,7 @@ static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count,
147 if (tmp==NULL) 147 if (tmp==NULL)
148 return -ENOMEM; 148 return -ENOMEM;
149 149
150 pr_debug("i2c-dev: i2c-%d reading %zd bytes.\n", 150 pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
151 iminor(file->f_path.dentry->d_inode), count); 151 iminor(file->f_path.dentry->d_inode), count);
152 152
153 ret = i2c_master_recv(client,tmp,count); 153 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
175 return -EFAULT; 175 return -EFAULT;
176 } 176 }
177 177
178 pr_debug("i2c-dev: i2c-%d writing %zd bytes.\n", 178 pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
179 iminor(file->f_path.dentry->d_inode), count); 179 iminor(file->f_path.dentry->d_inode), count);
180 180
181 ret = i2c_master_send(client,tmp,count); 181 ret = i2c_master_send(client,tmp,count);