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.c70
1 files changed, 24 insertions, 46 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 82ea1b7ec914..52b77477df57 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -197,7 +197,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
197 /* inform drivers of new adapters */ 197 /* inform drivers of new adapters */
198 list_for_each(item,&drivers) { 198 list_for_each(item,&drivers) {
199 driver = list_entry(item, struct i2c_driver, list); 199 driver = list_entry(item, struct i2c_driver, list);
200 if (driver->flags & I2C_DF_NOTIFY) 200 if (driver->attach_adapter)
201 /* We ignore the return code; if it fails, too bad */ 201 /* We ignore the return code; if it fails, too bad */
202 driver->attach_adapter(adap); 202 driver->attach_adapter(adap);
203 } 203 }
@@ -235,7 +235,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)
235 if (driver->detach_adapter) 235 if (driver->detach_adapter)
236 if ((res = driver->detach_adapter(adap))) { 236 if ((res = driver->detach_adapter(adap))) {
237 dev_err(&adap->dev, "detach_adapter failed " 237 dev_err(&adap->dev, "detach_adapter failed "
238 "for driver [%s]\n", driver->name); 238 "for driver [%s]\n",
239 driver->driver.name);
239 goto out_unlock; 240 goto out_unlock;
240 } 241 }
241 } 242 }
@@ -245,10 +246,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)
245 list_for_each_safe(item, _n, &adap->clients) { 246 list_for_each_safe(item, _n, &adap->clients) {
246 client = list_entry(item, struct i2c_client, list); 247 client = list_entry(item, struct i2c_client, list);
247 248
248 /* detaching devices is unconditional of the set notify
249 * flag, as _all_ clients that reside on the adapter
250 * must be deleted, as this would cause invalid states.
251 */
252 if ((res=client->driver->detach_client(client))) { 249 if ((res=client->driver->detach_client(client))) {
253 dev_err(&adap->dev, "detach_client failed for client " 250 dev_err(&adap->dev, "detach_client failed for client "
254 "[%s] at address 0x%02x\n", client->name, 251 "[%s] at address 0x%02x\n", client->name,
@@ -286,7 +283,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
286 * chips. 283 * chips.
287 */ 284 */
288 285
289int i2c_add_driver(struct i2c_driver *driver) 286int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
290{ 287{
291 struct list_head *item; 288 struct list_head *item;
292 struct i2c_adapter *adapter; 289 struct i2c_adapter *adapter;
@@ -295,8 +292,7 @@ int i2c_add_driver(struct i2c_driver *driver)
295 down(&core_lists); 292 down(&core_lists);
296 293
297 /* add the driver to the list of i2c drivers in the driver core */ 294 /* add the driver to the list of i2c drivers in the driver core */
298 driver->driver.owner = driver->owner; 295 driver->driver.owner = owner;
299 driver->driver.name = driver->name;
300 driver->driver.bus = &i2c_bus_type; 296 driver->driver.bus = &i2c_bus_type;
301 driver->driver.probe = i2c_device_probe; 297 driver->driver.probe = i2c_device_probe;
302 driver->driver.remove = i2c_device_remove; 298 driver->driver.remove = i2c_device_remove;
@@ -306,10 +302,10 @@ int i2c_add_driver(struct i2c_driver *driver)
306 goto out_unlock; 302 goto out_unlock;
307 303
308 list_add_tail(&driver->list,&drivers); 304 list_add_tail(&driver->list,&drivers);
309 pr_debug("i2c-core: driver [%s] registered\n", driver->name); 305 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
310 306
311 /* now look for instances of driver on our adapters */ 307 /* now look for instances of driver on our adapters */
312 if (driver->flags & I2C_DF_NOTIFY) { 308 if (driver->attach_adapter) {
313 list_for_each(item,&adapters) { 309 list_for_each(item,&adapters) {
314 adapter = list_entry(item, struct i2c_adapter, list); 310 adapter = list_entry(item, struct i2c_adapter, list);
315 driver->attach_adapter(adapter); 311 driver->attach_adapter(adapter);
@@ -320,6 +316,7 @@ int i2c_add_driver(struct i2c_driver *driver)
320 up(&core_lists); 316 up(&core_lists);
321 return res; 317 return res;
322} 318}
319EXPORT_SYMBOL(i2c_register_driver);
323 320
324int i2c_del_driver(struct i2c_driver *driver) 321int i2c_del_driver(struct i2c_driver *driver)
325{ 322{
@@ -334,17 +331,14 @@ int i2c_del_driver(struct i2c_driver *driver)
334 /* Have a look at each adapter, if clients of this driver are still 331 /* Have a look at each adapter, if clients of this driver are still
335 * attached. If so, detach them to be able to kill the driver 332 * attached. If so, detach them to be able to kill the driver
336 * afterwards. 333 * afterwards.
337 *
338 * Removing clients does not depend on the notify flag, else
339 * invalid operation might (will!) result, when using stale client
340 * pointers.
341 */ 334 */
342 list_for_each(item1,&adapters) { 335 list_for_each(item1,&adapters) {
343 adap = list_entry(item1, struct i2c_adapter, list); 336 adap = list_entry(item1, struct i2c_adapter, list);
344 if (driver->detach_adapter) { 337 if (driver->detach_adapter) {
345 if ((res = driver->detach_adapter(adap))) { 338 if ((res = driver->detach_adapter(adap))) {
346 dev_err(&adap->dev, "detach_adapter failed " 339 dev_err(&adap->dev, "detach_adapter failed "
347 "for driver [%s]\n", driver->name); 340 "for driver [%s]\n",
341 driver->driver.name);
348 goto out_unlock; 342 goto out_unlock;
349 } 343 }
350 } else { 344 } else {
@@ -368,7 +362,7 @@ int i2c_del_driver(struct i2c_driver *driver)
368 362
369 driver_unregister(&driver->driver); 363 driver_unregister(&driver->driver);
370 list_del(&driver->list); 364 list_del(&driver->list);
371 pr_debug("i2c-core: driver [%s] unregistered\n", driver->name); 365 pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
372 366
373 out_unlock: 367 out_unlock:
374 up(&core_lists); 368 up(&core_lists);
@@ -419,8 +413,7 @@ int i2c_attach_client(struct i2c_client *client)
419 } 413 }
420 } 414 }
421 415
422 if (client->flags & I2C_CLIENT_ALLOW_USE) 416 client->usage_count = 0;
423 client->usage_count = 0;
424 417
425 client->dev.parent = &client->adapter->dev; 418 client->dev.parent = &client->adapter->dev;
426 client->dev.driver = &client->driver->driver; 419 client->dev.driver = &client->driver->driver;
@@ -443,8 +436,7 @@ int i2c_detach_client(struct i2c_client *client)
443 struct i2c_adapter *adapter = client->adapter; 436 struct i2c_adapter *adapter = client->adapter;
444 int res = 0; 437 int res = 0;
445 438
446 if ((client->flags & I2C_CLIENT_ALLOW_USE) 439 if (client->usage_count > 0) {
447 && (client->usage_count > 0)) {
448 dev_warn(&client->dev, "Client [%s] still busy, " 440 dev_warn(&client->dev, "Client [%s] still busy, "
449 "can't detach\n", client->name); 441 "can't detach\n", client->name);
450 return -EBUSY; 442 return -EBUSY;
@@ -475,10 +467,10 @@ int i2c_detach_client(struct i2c_client *client)
475static int i2c_inc_use_client(struct i2c_client *client) 467static int i2c_inc_use_client(struct i2c_client *client)
476{ 468{
477 469
478 if (!try_module_get(client->driver->owner)) 470 if (!try_module_get(client->driver->driver.owner))
479 return -ENODEV; 471 return -ENODEV;
480 if (!try_module_get(client->adapter->owner)) { 472 if (!try_module_get(client->adapter->owner)) {
481 module_put(client->driver->owner); 473 module_put(client->driver->driver.owner);
482 return -ENODEV; 474 return -ENODEV;
483 } 475 }
484 476
@@ -487,7 +479,7 @@ static int i2c_inc_use_client(struct i2c_client *client)
487 479
488static void i2c_dec_use_client(struct i2c_client *client) 480static void i2c_dec_use_client(struct i2c_client *client)
489{ 481{
490 module_put(client->driver->owner); 482 module_put(client->driver->driver.owner);
491 module_put(client->adapter->owner); 483 module_put(client->adapter->owner);
492} 484}
493 485
@@ -499,33 +491,20 @@ int i2c_use_client(struct i2c_client *client)
499 if (ret) 491 if (ret)
500 return ret; 492 return ret;
501 493
502 if (client->flags & I2C_CLIENT_ALLOW_USE) { 494 client->usage_count++;
503 if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
504 client->usage_count++;
505 else if (client->usage_count > 0)
506 goto busy;
507 else
508 client->usage_count++;
509 }
510 495
511 return 0; 496 return 0;
512 busy:
513 i2c_dec_use_client(client);
514 return -EBUSY;
515} 497}
516 498
517int i2c_release_client(struct i2c_client *client) 499int i2c_release_client(struct i2c_client *client)
518{ 500{
519 if(client->flags & I2C_CLIENT_ALLOW_USE) { 501 if (!client->usage_count) {
520 if(client->usage_count>0) 502 pr_debug("i2c-core: %s used one too many times\n",
521 client->usage_count--; 503 __FUNCTION__);
522 else { 504 return -EPERM;
523 pr_debug("i2c-core: %s used one too many times\n",
524 __FUNCTION__);
525 return -EPERM;
526 }
527 } 505 }
528 506
507 client->usage_count--;
529 i2c_dec_use_client(client); 508 i2c_dec_use_client(client);
530 509
531 return 0; 510 return 0;
@@ -539,14 +518,14 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
539 down(&adap->clist_lock); 518 down(&adap->clist_lock);
540 list_for_each(item,&adap->clients) { 519 list_for_each(item,&adap->clients) {
541 client = list_entry(item, struct i2c_client, list); 520 client = list_entry(item, struct i2c_client, list);
542 if (!try_module_get(client->driver->owner)) 521 if (!try_module_get(client->driver->driver.owner))
543 continue; 522 continue;
544 if (NULL != client->driver->command) { 523 if (NULL != client->driver->command) {
545 up(&adap->clist_lock); 524 up(&adap->clist_lock);
546 client->driver->command(client,cmd,arg); 525 client->driver->command(client,cmd,arg);
547 down(&adap->clist_lock); 526 down(&adap->clist_lock);
548 } 527 }
549 module_put(client->driver->owner); 528 module_put(client->driver->driver.owner);
550 } 529 }
551 up(&adap->clist_lock); 530 up(&adap->clist_lock);
552} 531}
@@ -1147,7 +1126,6 @@ EXPORT_SYMBOL_GPL(i2c_bus_type);
1147 1126
1148EXPORT_SYMBOL(i2c_add_adapter); 1127EXPORT_SYMBOL(i2c_add_adapter);
1149EXPORT_SYMBOL(i2c_del_adapter); 1128EXPORT_SYMBOL(i2c_del_adapter);
1150EXPORT_SYMBOL(i2c_add_driver);
1151EXPORT_SYMBOL(i2c_del_driver); 1129EXPORT_SYMBOL(i2c_del_driver);
1152EXPORT_SYMBOL(i2c_attach_client); 1130EXPORT_SYMBOL(i2c_attach_client);
1153EXPORT_SYMBOL(i2c_detach_client); 1131EXPORT_SYMBOL(i2c_detach_client);