aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-06-19 10:58:19 -0400
committerJean Delvare <khali@linux-fr.org>2009-06-19 10:58:19 -0400
commit35fc37f8188177e3ba3e7f99a6e3300e490e9181 (patch)
treeed2e7f589cb33b0b8bb81aa0a7958c3d6c0cb002 /drivers/i2c/i2c-core.c
parente549c2b54dd90a056d6824b885d438b7437874f0 (diff)
i2c: Limit core locking to the necessary sections
The i2c-core code tends to hold the core lock for longer than it should. Limit locking to the necessary sections for both performance and clarity. This is also a requirement to support I2C multiplexers in the future. Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: Rodolfo Giometti <giometti@linux.it> Cc: David Brownell <dbrownell@users.sourceforge.net>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index b1fd00d9a5c..a2f1cd3766f 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -38,6 +38,9 @@
38#include "i2c-core.h" 38#include "i2c-core.h"
39 39
40 40
41/* core_lock protects i2c_adapter_idr, and guarantees
42 that device detection, deletion of detected devices, and attach_adapter
43 and detach_adapter calls are serialized */
41static DEFINE_MUTEX(core_lock); 44static DEFINE_MUTEX(core_lock);
42static DEFINE_IDR(i2c_adapter_idr); 45static DEFINE_IDR(i2c_adapter_idr);
43 46
@@ -418,13 +421,13 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
418 int res = 0, dummy; 421 int res = 0, dummy;
419 422
420 /* Can't register until after driver model init */ 423 /* Can't register until after driver model init */
421 if (unlikely(WARN_ON(!i2c_bus_type.p))) 424 if (unlikely(WARN_ON(!i2c_bus_type.p))) {
422 return -EAGAIN; 425 res = -EAGAIN;
426 goto out_list;
427 }
423 428
424 mutex_init(&adap->bus_lock); 429 mutex_init(&adap->bus_lock);
425 430
426 mutex_lock(&core_lock);
427
428 /* Set default timeout to 1 second if not already set */ 431 /* Set default timeout to 1 second if not already set */
429 if (adap->timeout == 0) 432 if (adap->timeout == 0)
430 adap->timeout = HZ; 433 adap->timeout = HZ;
@@ -443,16 +446,18 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
443 i2c_scan_static_board_info(adap); 446 i2c_scan_static_board_info(adap);
444 447
445 /* Notify drivers */ 448 /* Notify drivers */
449 mutex_lock(&core_lock);
446 dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, 450 dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
447 i2c_do_add_adapter); 451 i2c_do_add_adapter);
448
449out_unlock:
450 mutex_unlock(&core_lock); 452 mutex_unlock(&core_lock);
451 return res; 453
454 return 0;
452 455
453out_list: 456out_list:
457 mutex_lock(&core_lock);
454 idr_remove(&i2c_adapter_idr, adap->nr); 458 idr_remove(&i2c_adapter_idr, adap->nr);
455 goto out_unlock; 459 mutex_unlock(&core_lock);
460 return res;
456} 461}
457 462
458/** 463/**
@@ -590,22 +595,25 @@ static int __unregister_client(struct device *dev, void *dummy)
590int i2c_del_adapter(struct i2c_adapter *adap) 595int i2c_del_adapter(struct i2c_adapter *adap)
591{ 596{
592 int res = 0; 597 int res = 0;
593 598 struct i2c_adapter *found;
594 mutex_lock(&core_lock);
595 599
596 /* First make sure that this adapter was ever added */ 600 /* First make sure that this adapter was ever added */
597 if (idr_find(&i2c_adapter_idr, adap->nr) != adap) { 601 mutex_lock(&core_lock);
602 found = idr_find(&i2c_adapter_idr, adap->nr);
603 mutex_unlock(&core_lock);
604 if (found != adap) {
598 pr_debug("i2c-core: attempting to delete unregistered " 605 pr_debug("i2c-core: attempting to delete unregistered "
599 "adapter [%s]\n", adap->name); 606 "adapter [%s]\n", adap->name);
600 res = -EINVAL; 607 return -EINVAL;
601 goto out_unlock;
602 } 608 }
603 609
604 /* Tell drivers about this removal */ 610 /* Tell drivers about this removal */
611 mutex_lock(&core_lock);
605 res = bus_for_each_drv(&i2c_bus_type, NULL, adap, 612 res = bus_for_each_drv(&i2c_bus_type, NULL, adap,
606 i2c_do_del_adapter); 613 i2c_do_del_adapter);
614 mutex_unlock(&core_lock);
607 if (res) 615 if (res)
608 goto out_unlock; 616 return res;
609 617
610 /* Detach any active clients. This can't fail, thus we do not 618 /* Detach any active clients. This can't fail, thus we do not
611 checking the returned value. */ 619 checking the returned value. */
@@ -619,7 +627,9 @@ int i2c_del_adapter(struct i2c_adapter *adap)
619 wait_for_completion(&adap->dev_released); 627 wait_for_completion(&adap->dev_released);
620 628
621 /* free bus id */ 629 /* free bus id */
630 mutex_lock(&core_lock);
622 idr_remove(&i2c_adapter_idr, adap->nr); 631 idr_remove(&i2c_adapter_idr, adap->nr);
632 mutex_unlock(&core_lock);
623 633
624 dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); 634 dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
625 635
@@ -627,9 +637,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
627 added again */ 637 added again */
628 memset(&adap->dev, 0, sizeof(adap->dev)); 638 memset(&adap->dev, 0, sizeof(adap->dev));
629 639
630 out_unlock: 640 return 0;
631 mutex_unlock(&core_lock);
632 return res;
633} 641}
634EXPORT_SYMBOL(i2c_del_adapter); 642EXPORT_SYMBOL(i2c_del_adapter);
635 643
@@ -674,16 +682,15 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
674 if (res) 682 if (res)
675 return res; 683 return res;
676 684
677 mutex_lock(&core_lock);
678
679 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); 685 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
680 686
681 INIT_LIST_HEAD(&driver->clients); 687 INIT_LIST_HEAD(&driver->clients);
682 /* Walk the adapters that are already present */ 688 /* Walk the adapters that are already present */
689 mutex_lock(&core_lock);
683 class_for_each_device(&i2c_adapter_class, NULL, driver, 690 class_for_each_device(&i2c_adapter_class, NULL, driver,
684 __attach_adapter); 691 __attach_adapter);
685
686 mutex_unlock(&core_lock); 692 mutex_unlock(&core_lock);
693
687 return 0; 694 return 0;
688} 695}
689EXPORT_SYMBOL(i2c_register_driver); 696EXPORT_SYMBOL(i2c_register_driver);
@@ -721,14 +728,12 @@ static int __detach_adapter(struct device *dev, void *data)
721void i2c_del_driver(struct i2c_driver *driver) 728void i2c_del_driver(struct i2c_driver *driver)
722{ 729{
723 mutex_lock(&core_lock); 730 mutex_lock(&core_lock);
724
725 class_for_each_device(&i2c_adapter_class, NULL, driver, 731 class_for_each_device(&i2c_adapter_class, NULL, driver,
726 __detach_adapter); 732 __detach_adapter);
733 mutex_unlock(&core_lock);
727 734
728 driver_unregister(&driver->driver); 735 driver_unregister(&driver->driver);
729 pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); 736 pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
730
731 mutex_unlock(&core_lock);
732} 737}
733EXPORT_SYMBOL(i2c_del_driver); 738EXPORT_SYMBOL(i2c_del_driver);
734 739