aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c81
1 files changed, 39 insertions, 42 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 1a2c9ab5d9e3..45e2cdf54736 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -31,12 +31,13 @@
31#include <linux/idr.h> 31#include <linux/idr.h>
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34#include <linux/mutex.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35 36
36 37
37static LIST_HEAD(adapters); 38static LIST_HEAD(adapters);
38static LIST_HEAD(drivers); 39static LIST_HEAD(drivers);
39static DECLARE_MUTEX(core_lists); 40static DEFINE_MUTEX(core_lists);
40static DEFINE_IDR(i2c_adapter_idr); 41static DEFINE_IDR(i2c_adapter_idr);
41 42
42/* match always succeeds, as we want the probe() to tell if we really accept this match */ 43/* match always succeeds, as we want the probe() to tell if we really accept this match */
@@ -153,7 +154,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
153 struct list_head *item; 154 struct list_head *item;
154 struct i2c_driver *driver; 155 struct i2c_driver *driver;
155 156
156 down(&core_lists); 157 mutex_lock(&core_lists);
157 158
158 if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) { 159 if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) {
159 res = -ENOMEM; 160 res = -ENOMEM;
@@ -168,8 +169,8 @@ int i2c_add_adapter(struct i2c_adapter *adap)
168 } 169 }
169 170
170 adap->nr = id & MAX_ID_MASK; 171 adap->nr = id & MAX_ID_MASK;
171 init_MUTEX(&adap->bus_lock); 172 mutex_init(&adap->bus_lock);
172 init_MUTEX(&adap->clist_lock); 173 mutex_init(&adap->clist_lock);
173 list_add_tail(&adap->list,&adapters); 174 list_add_tail(&adap->list,&adapters);
174 INIT_LIST_HEAD(&adap->clients); 175 INIT_LIST_HEAD(&adap->clients);
175 176
@@ -203,7 +204,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
203 } 204 }
204 205
205out_unlock: 206out_unlock:
206 up(&core_lists); 207 mutex_unlock(&core_lists);
207 return res; 208 return res;
208} 209}
209 210
@@ -216,7 +217,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
216 struct i2c_client *client; 217 struct i2c_client *client;
217 int res = 0; 218 int res = 0;
218 219
219 down(&core_lists); 220 mutex_lock(&core_lists);
220 221
221 /* First make sure that this adapter was ever added */ 222 /* First make sure that this adapter was ever added */
222 list_for_each_entry(adap_from_list, &adapters, list) { 223 list_for_each_entry(adap_from_list, &adapters, list) {
@@ -272,7 +273,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
272 dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); 273 dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
273 274
274 out_unlock: 275 out_unlock:
275 up(&core_lists); 276 mutex_unlock(&core_lists);
276 return res; 277 return res;
277} 278}
278 279
@@ -287,9 +288,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
287{ 288{
288 struct list_head *item; 289 struct list_head *item;
289 struct i2c_adapter *adapter; 290 struct i2c_adapter *adapter;
290 int res = 0; 291 int res;
291
292 down(&core_lists);
293 292
294 /* add the driver to the list of i2c drivers in the driver core */ 293 /* add the driver to the list of i2c drivers in the driver core */
295 driver->driver.owner = owner; 294 driver->driver.owner = owner;
@@ -297,8 +296,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
297 296
298 res = driver_register(&driver->driver); 297 res = driver_register(&driver->driver);
299 if (res) 298 if (res)
300 goto out_unlock; 299 return res;
301 300
301 mutex_lock(&core_lists);
302
302 list_add_tail(&driver->list,&drivers); 303 list_add_tail(&driver->list,&drivers);
303 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); 304 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
304 305
@@ -310,9 +311,8 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
310 } 311 }
311 } 312 }
312 313
313 out_unlock: 314 mutex_unlock(&core_lists);
314 up(&core_lists); 315 return 0;
315 return res;
316} 316}
317EXPORT_SYMBOL(i2c_register_driver); 317EXPORT_SYMBOL(i2c_register_driver);
318 318
@@ -324,7 +324,7 @@ int i2c_del_driver(struct i2c_driver *driver)
324 324
325 int res = 0; 325 int res = 0;
326 326
327 down(&core_lists); 327 mutex_lock(&core_lists);
328 328
329 /* Have a look at each adapter, if clients of this driver are still 329 /* Have a look at each adapter, if clients of this driver are still
330 * attached. If so, detach them to be able to kill the driver 330 * attached. If so, detach them to be able to kill the driver
@@ -363,7 +363,7 @@ int i2c_del_driver(struct i2c_driver *driver)
363 pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); 363 pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
364 364
365 out_unlock: 365 out_unlock:
366 up(&core_lists); 366 mutex_unlock(&core_lists);
367 return 0; 367 return 0;
368} 368}
369 369
@@ -384,9 +384,9 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
384{ 384{
385 int rval; 385 int rval;
386 386
387 down(&adapter->clist_lock); 387 mutex_lock(&adapter->clist_lock);
388 rval = __i2c_check_addr(adapter, addr); 388 rval = __i2c_check_addr(adapter, addr);
389 up(&adapter->clist_lock); 389 mutex_unlock(&adapter->clist_lock);
390 390
391 return rval; 391 return rval;
392} 392}
@@ -395,13 +395,13 @@ int i2c_attach_client(struct i2c_client *client)
395{ 395{
396 struct i2c_adapter *adapter = client->adapter; 396 struct i2c_adapter *adapter = client->adapter;
397 397
398 down(&adapter->clist_lock); 398 mutex_lock(&adapter->clist_lock);
399 if (__i2c_check_addr(client->adapter, client->addr)) { 399 if (__i2c_check_addr(client->adapter, client->addr)) {
400 up(&adapter->clist_lock); 400 mutex_unlock(&adapter->clist_lock);
401 return -EBUSY; 401 return -EBUSY;
402 } 402 }
403 list_add_tail(&client->list,&adapter->clients); 403 list_add_tail(&client->list,&adapter->clients);
404 up(&adapter->clist_lock); 404 mutex_unlock(&adapter->clist_lock);
405 405
406 if (adapter->client_register) { 406 if (adapter->client_register) {
407 if (adapter->client_register(client)) { 407 if (adapter->client_register(client)) {
@@ -450,12 +450,12 @@ int i2c_detach_client(struct i2c_client *client)
450 } 450 }
451 } 451 }
452 452
453 down(&adapter->clist_lock); 453 mutex_lock(&adapter->clist_lock);
454 list_del(&client->list); 454 list_del(&client->list);
455 init_completion(&client->released); 455 init_completion(&client->released);
456 device_remove_file(&client->dev, &dev_attr_client_name); 456 device_remove_file(&client->dev, &dev_attr_client_name);
457 device_unregister(&client->dev); 457 device_unregister(&client->dev);
458 up(&adapter->clist_lock); 458 mutex_unlock(&adapter->clist_lock);
459 wait_for_completion(&client->released); 459 wait_for_completion(&client->released);
460 460
461 out: 461 out:
@@ -513,19 +513,19 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
513 struct list_head *item; 513 struct list_head *item;
514 struct i2c_client *client; 514 struct i2c_client *client;
515 515
516 down(&adap->clist_lock); 516 mutex_lock(&adap->clist_lock);
517 list_for_each(item,&adap->clients) { 517 list_for_each(item,&adap->clients) {
518 client = list_entry(item, struct i2c_client, list); 518 client = list_entry(item, struct i2c_client, list);
519 if (!try_module_get(client->driver->driver.owner)) 519 if (!try_module_get(client->driver->driver.owner))
520 continue; 520 continue;
521 if (NULL != client->driver->command) { 521 if (NULL != client->driver->command) {
522 up(&adap->clist_lock); 522 mutex_unlock(&adap->clist_lock);
523 client->driver->command(client,cmd,arg); 523 client->driver->command(client,cmd,arg);
524 down(&adap->clist_lock); 524 mutex_lock(&adap->clist_lock);
525 } 525 }
526 module_put(client->driver->driver.owner); 526 module_put(client->driver->driver.owner);
527 } 527 }
528 up(&adap->clist_lock); 528 mutex_unlock(&adap->clist_lock);
529} 529}
530 530
531static int __init i2c_init(void) 531static int __init i2c_init(void)
@@ -569,9 +569,9 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
569 } 569 }
570#endif 570#endif
571 571
572 down(&adap->bus_lock); 572 mutex_lock(&adap->bus_lock);
573 ret = adap->algo->master_xfer(adap,msgs,num); 573 ret = adap->algo->master_xfer(adap,msgs,num);
574 up(&adap->bus_lock); 574 mutex_unlock(&adap->bus_lock);
575 575
576 return ret; 576 return ret;
577 } else { 577 } else {
@@ -779,12 +779,12 @@ struct i2c_adapter* i2c_get_adapter(int id)
779{ 779{
780 struct i2c_adapter *adapter; 780 struct i2c_adapter *adapter;
781 781
782 down(&core_lists); 782 mutex_lock(&core_lists);
783 adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); 783 adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
784 if (adapter && !try_module_get(adapter->owner)) 784 if (adapter && !try_module_get(adapter->owner))
785 adapter = NULL; 785 adapter = NULL;
786 786
787 up(&core_lists); 787 mutex_unlock(&core_lists);
788 return adapter; 788 return adapter;
789} 789}
790 790
@@ -919,12 +919,11 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
919 u8 length, u8 *values) 919 u8 length, u8 *values)
920{ 920{
921 union i2c_smbus_data data; 921 union i2c_smbus_data data;
922 int i; 922
923 if (length > I2C_SMBUS_BLOCK_MAX) 923 if (length > I2C_SMBUS_BLOCK_MAX)
924 length = I2C_SMBUS_BLOCK_MAX; 924 length = I2C_SMBUS_BLOCK_MAX;
925 for (i = 1; i <= length; i++)
926 data.block[i] = values[i-1];
927 data.block[0] = length; 925 data.block[0] = length;
926 memcpy(&data.block[1], values, length);
928 return i2c_smbus_xfer(client->adapter,client->addr,client->flags, 927 return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
929 I2C_SMBUS_WRITE,command, 928 I2C_SMBUS_WRITE,command,
930 I2C_SMBUS_BLOCK_DATA,&data); 929 I2C_SMBUS_BLOCK_DATA,&data);
@@ -934,16 +933,14 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
934s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values) 933s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values)
935{ 934{
936 union i2c_smbus_data data; 935 union i2c_smbus_data data;
937 int i; 936
938 if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, 937 if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
939 I2C_SMBUS_READ,command, 938 I2C_SMBUS_READ,command,
940 I2C_SMBUS_I2C_BLOCK_DATA,&data)) 939 I2C_SMBUS_I2C_BLOCK_DATA,&data))
941 return -1; 940 return -1;
942 else { 941
943 for (i = 1; i <= data.block[0]; i++) 942 memcpy(values, &data.block[1], data.block[0]);
944 values[i-1] = data.block[i]; 943 return data.block[0];
945 return data.block[0];
946 }
947} 944}
948 945
949s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, 946s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
@@ -1118,10 +1115,10 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
1118 flags &= I2C_M_TEN | I2C_CLIENT_PEC; 1115 flags &= I2C_M_TEN | I2C_CLIENT_PEC;
1119 1116
1120 if (adapter->algo->smbus_xfer) { 1117 if (adapter->algo->smbus_xfer) {
1121 down(&adapter->bus_lock); 1118 mutex_lock(&adapter->bus_lock);
1122 res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, 1119 res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
1123 command,size,data); 1120 command,size,data);
1124 up(&adapter->bus_lock); 1121 mutex_unlock(&adapter->bus_lock);
1125 } else 1122 } else
1126 res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, 1123 res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
1127 command,size,data); 1124 command,size,data);