From f18c41daea14baee11252da268cdf5dcd57c7c10 Mon Sep 17 00:00:00 2001 From: Rodolfo Giometti <giometti@linux.it> Date: Fri, 19 Jun 2009 16:58:20 +0200 Subject: [PATCH] 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> --- drivers/i2c/i2c-boardinfo.c | 7 ++++--- drivers/i2c/i2c-core.c | 5 +++-- 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 ffb35f09df0380..a26a34a06641bd 100644 --- a/drivers/i2c/i2c-boardinfo.c +++ b/drivers/i2c/i2c-boardinfo.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/i2c.h> +#include <linux/rwsem.h> #include "i2c-core.h" @@ -25,7 +26,7 @@ /* These symbols are exported ONLY FOR the i2c core. * No other users will be supported. */ -DEFINE_MUTEX(__i2c_board_lock); +DECLARE_RWSEM(__i2c_board_lock); EXPORT_SYMBOL_GPL(__i2c_board_lock); LIST_HEAD(__i2c_board_list); @@ -63,7 +64,7 @@ i2c_register_board_info(int busnum, { int status; - mutex_lock(&__i2c_board_lock); + down_write(&__i2c_board_lock); /* dynamic bus numbers will be assigned after the last static one */ if (busnum >= __i2c_first_dynamic_bus_num) @@ -84,7 +85,7 @@ i2c_register_board_info(int busnum, list_add_tail(&devinfo->list, &__i2c_board_list); } - mutex_unlock(&__i2c_board_lock); + up_write(&__i2c_board_lock); return status; } diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index eb084fa0df8328..0e45c296d3d22b 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -33,6 +33,7 @@ #include <linux/completion.h> #include <linux/hardirq.h> #include <linux/irqflags.h> +#include <linux/rwsem.h> #include <asm/uaccess.h> #include "i2c-core.h" @@ -509,7 +510,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) { struct i2c_devinfo *devinfo; - mutex_lock(&__i2c_board_lock); + down_read(&__i2c_board_lock); list_for_each_entry(devinfo, &__i2c_board_list, list) { if (devinfo->busnum == adapter->nr && !i2c_new_device(adapter, @@ -518,7 +519,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter) "Can't create device at 0x%02x\n", devinfo->board_info.addr); } - mutex_unlock(&__i2c_board_lock); + up_read(&__i2c_board_lock); } 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 cd5bff87485573..9f9c57ff670850 100644 --- a/drivers/i2c/i2c-core.h +++ b/drivers/i2c/i2c-core.h @@ -16,6 +16,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/rwsem.h> + struct i2c_devinfo { struct list_head list; int busnum; @@ -25,7 +27,7 @@ struct i2c_devinfo { /* board_lock protects board_list and first_dynamic_bus_num. * only i2c core components are allowed to use these symbols. */ -extern struct mutex __i2c_board_lock; +extern struct rw_semaphore __i2c_board_lock; extern struct list_head __i2c_board_list; extern int __i2c_first_dynamic_bus_num; -- GitLab