diff options
author | Rodolfo Giometti <giometti@linux.it> | 2009-06-19 10:58:20 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-06-19 10:58:20 -0400 |
commit | f18c41daea14baee11252da268cdf5dcd57c7c10 (patch) | |
tree | ec42ed7000fa64925db3cd596737bd54d9fa71ca /drivers/i2c | |
parent | 99cd8e25875a109455b709b5a41d4891b8d8e58e (diff) |
i2c: Use rwsem instead of mutex for board info
By using rwsem we can easily manage recursive calls of
i2c_scan_static_board_info() function without breaking the locking.
Signed-off-by: Rodolfo Giometti <giometti@linux.it>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/i2c-boardinfo.c | 7 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 5 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.h | 4 |
3 files changed, 10 insertions, 6 deletions
diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c index ffb35f09df03..a26a34a06641 100644 --- a/drivers/i2c/i2c-boardinfo.c +++ b/drivers/i2c/i2c-boardinfo.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/rwsem.h> | ||
21 | 22 | ||
22 | #include "i2c-core.h" | 23 | #include "i2c-core.h" |
23 | 24 | ||
@@ -25,7 +26,7 @@ | |||
25 | /* These symbols are exported ONLY FOR the i2c core. | 26 | /* These symbols are exported ONLY FOR the i2c core. |
26 | * No other users will be supported. | 27 | * No other users will be supported. |
27 | */ | 28 | */ |
28 | DEFINE_MUTEX(__i2c_board_lock); | 29 | DECLARE_RWSEM(__i2c_board_lock); |
29 | EXPORT_SYMBOL_GPL(__i2c_board_lock); | 30 | EXPORT_SYMBOL_GPL(__i2c_board_lock); |
30 | 31 | ||
31 | LIST_HEAD(__i2c_board_list); | 32 | LIST_HEAD(__i2c_board_list); |
@@ -63,7 +64,7 @@ i2c_register_board_info(int busnum, | |||
63 | { | 64 | { |
64 | int status; | 65 | int status; |
65 | 66 | ||
66 | mutex_lock(&__i2c_board_lock); | 67 | down_write(&__i2c_board_lock); |
67 | 68 | ||
68 | /* dynamic bus numbers will be assigned after the last static one */ | 69 | /* dynamic bus numbers will be assigned after the last static one */ |
69 | if (busnum >= __i2c_first_dynamic_bus_num) | 70 | if (busnum >= __i2c_first_dynamic_bus_num) |
@@ -84,7 +85,7 @@ i2c_register_board_info(int busnum, | |||
84 | list_add_tail(&devinfo->list, &__i2c_board_list); | 85 | list_add_tail(&devinfo->list, &__i2c_board_list); |
85 | } | 86 | } |
86 | 87 | ||
87 | mutex_unlock(&__i2c_board_lock); | 88 | up_write(&__i2c_board_lock); |
88 | 89 | ||
89 | return status; | 90 | return status; |
90 | } | 91 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index eb084fa0df83..0e45c296d3d2 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
34 | #include <linux/hardirq.h> | 34 | #include <linux/hardirq.h> |
35 | #include <linux/irqflags.h> | 35 | #include <linux/irqflags.h> |
36 | #include <linux/rwsem.h> | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | 38 | ||
38 | #include "i2c-core.h" | 39 | #include "i2c-core.h" |
@@ -509,7 +510,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) | |||
509 | { | 510 | { |
510 | struct i2c_devinfo *devinfo; | 511 | struct i2c_devinfo *devinfo; |
511 | 512 | ||
512 | mutex_lock(&__i2c_board_lock); | 513 | down_read(&__i2c_board_lock); |
513 | list_for_each_entry(devinfo, &__i2c_board_list, list) { | 514 | list_for_each_entry(devinfo, &__i2c_board_list, list) { |
514 | if (devinfo->busnum == adapter->nr | 515 | if (devinfo->busnum == adapter->nr |
515 | && !i2c_new_device(adapter, | 516 | && !i2c_new_device(adapter, |
@@ -518,7 +519,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) | |||
518 | "Can't create device at 0x%02x\n", | 519 | "Can't create device at 0x%02x\n", |
519 | devinfo->board_info.addr); | 520 | devinfo->board_info.addr); |
520 | } | 521 | } |
521 | mutex_unlock(&__i2c_board_lock); | 522 | up_read(&__i2c_board_lock); |
522 | } | 523 | } |
523 | 524 | ||
524 | static int i2c_do_add_adapter(struct device_driver *d, void *data) | 525 | static int i2c_do_add_adapter(struct device_driver *d, void *data) |
diff --git a/drivers/i2c/i2c-core.h b/drivers/i2c/i2c-core.h index cd5bff874855..9f9c57ff6708 100644 --- a/drivers/i2c/i2c-core.h +++ b/drivers/i2c/i2c-core.h | |||
@@ -16,6 +16,8 @@ | |||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/rwsem.h> | ||
20 | |||
19 | struct i2c_devinfo { | 21 | struct i2c_devinfo { |
20 | struct list_head list; | 22 | struct list_head list; |
21 | int busnum; | 23 | int busnum; |
@@ -25,7 +27,7 @@ struct i2c_devinfo { | |||
25 | /* board_lock protects board_list and first_dynamic_bus_num. | 27 | /* board_lock protects board_list and first_dynamic_bus_num. |
26 | * only i2c core components are allowed to use these symbols. | 28 | * only i2c core components are allowed to use these symbols. |
27 | */ | 29 | */ |
28 | extern struct mutex __i2c_board_lock; | 30 | extern struct rw_semaphore __i2c_board_lock; |
29 | extern struct list_head __i2c_board_list; | 31 | extern struct list_head __i2c_board_list; |
30 | extern int __i2c_first_dynamic_bus_num; | 32 | extern int __i2c_first_dynamic_bus_num; |
31 | 33 | ||