Commit f18c41daea14baee11252da268cdf5dcd57c7c10
Committed by
Jean Delvare
1 parent
99cd8e2587
Exists in
master
and in
39 other branches
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>
Showing 3 changed files with 10 additions and 6 deletions Side-by-side Diff
drivers/i2c/i2c-boardinfo.c
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | |
19 | 19 | #include <linux/kernel.h> |
20 | 20 | #include <linux/i2c.h> |
21 | +#include <linux/rwsem.h> | |
21 | 22 | |
22 | 23 | #include "i2c-core.h" |
23 | 24 | |
... | ... | @@ -25,7 +26,7 @@ |
25 | 26 | /* These symbols are exported ONLY FOR the i2c core. |
26 | 27 | * No other users will be supported. |
27 | 28 | */ |
28 | -DEFINE_MUTEX(__i2c_board_lock); | |
29 | +DECLARE_RWSEM(__i2c_board_lock); | |
29 | 30 | EXPORT_SYMBOL_GPL(__i2c_board_lock); |
30 | 31 | |
31 | 32 | LIST_HEAD(__i2c_board_list); |
... | ... | @@ -63,7 +64,7 @@ |
63 | 64 | { |
64 | 65 | int status; |
65 | 66 | |
66 | - mutex_lock(&__i2c_board_lock); | |
67 | + down_write(&__i2c_board_lock); | |
67 | 68 | |
68 | 69 | /* dynamic bus numbers will be assigned after the last static one */ |
69 | 70 | if (busnum >= __i2c_first_dynamic_bus_num) |
... | ... | @@ -84,7 +85,7 @@ |
84 | 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 | 90 | return status; |
90 | 91 | } |
drivers/i2c/i2c-core.c
... | ... | @@ -33,6 +33,7 @@ |
33 | 33 | #include <linux/completion.h> |
34 | 34 | #include <linux/hardirq.h> |
35 | 35 | #include <linux/irqflags.h> |
36 | +#include <linux/rwsem.h> | |
36 | 37 | #include <asm/uaccess.h> |
37 | 38 | |
38 | 39 | #include "i2c-core.h" |
... | ... | @@ -509,7 +510,7 @@ |
509 | 510 | { |
510 | 511 | struct i2c_devinfo *devinfo; |
511 | 512 | |
512 | - mutex_lock(&__i2c_board_lock); | |
513 | + down_read(&__i2c_board_lock); | |
513 | 514 | list_for_each_entry(devinfo, &__i2c_board_list, list) { |
514 | 515 | if (devinfo->busnum == adapter->nr |
515 | 516 | && !i2c_new_device(adapter, |
... | ... | @@ -518,7 +519,7 @@ |
518 | 519 | "Can't create device at 0x%02x\n", |
519 | 520 | devinfo->board_info.addr); |
520 | 521 | } |
521 | - mutex_unlock(&__i2c_board_lock); | |
522 | + up_read(&__i2c_board_lock); | |
522 | 523 | } |
523 | 524 | |
524 | 525 | static int i2c_do_add_adapter(struct device_driver *d, void *data) |
drivers/i2c/i2c-core.h
... | ... | @@ -16,6 +16,8 @@ |
16 | 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 | 17 | */ |
18 | 18 | |
19 | +#include <linux/rwsem.h> | |
20 | + | |
19 | 21 | struct i2c_devinfo { |
20 | 22 | struct list_head list; |
21 | 23 | int busnum; |
... | ... | @@ -25,7 +27,7 @@ |
25 | 27 | /* board_lock protects board_list and first_dynamic_bus_num. |
26 | 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 | 31 | extern struct list_head __i2c_board_list; |
30 | 32 | extern int __i2c_first_dynamic_bus_num; |