Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f18c41da authored by Rodolfo Giometti's avatar Rodolfo Giometti Committed by Jean Delvare
Browse files

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: default avatarRodolfo Giometti <giometti@linux.it>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 99cd8e25
Loading
Loading
Loading
Loading
+4 −3
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@


#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/i2c.h>
#include <linux/rwsem.h>


#include "i2c-core.h"
#include "i2c-core.h"


@@ -25,7 +26,7 @@
/* These symbols are exported ONLY FOR the i2c core.
/* These symbols are exported ONLY FOR the i2c core.
 * No other users will be supported.
 * No other users will be supported.
 */
 */
DEFINE_MUTEX(__i2c_board_lock);
DECLARE_RWSEM(__i2c_board_lock);
EXPORT_SYMBOL_GPL(__i2c_board_lock);
EXPORT_SYMBOL_GPL(__i2c_board_lock);


LIST_HEAD(__i2c_board_list);
LIST_HEAD(__i2c_board_list);
@@ -63,7 +64,7 @@ i2c_register_board_info(int busnum,
{
{
	int status;
	int status;


	mutex_lock(&__i2c_board_lock);
	down_write(&__i2c_board_lock);


	/* dynamic bus numbers will be assigned after the last static one */
	/* dynamic bus numbers will be assigned after the last static one */
	if (busnum >= __i2c_first_dynamic_bus_num)
	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);
		list_add_tail(&devinfo->list, &__i2c_board_list);
	}
	}


	mutex_unlock(&__i2c_board_lock);
	up_write(&__i2c_board_lock);


	return status;
	return status;
}
}
+3 −2
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@
#include <linux/completion.h>
#include <linux/completion.h>
#include <linux/hardirq.h>
#include <linux/hardirq.h>
#include <linux/irqflags.h>
#include <linux/irqflags.h>
#include <linux/rwsem.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>


#include "i2c-core.h"
#include "i2c-core.h"
@@ -509,7 +510,7 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
{
{
	struct i2c_devinfo	*devinfo;
	struct i2c_devinfo	*devinfo;


	mutex_lock(&__i2c_board_lock);
	down_read(&__i2c_board_lock);
	list_for_each_entry(devinfo, &__i2c_board_list, list) {
	list_for_each_entry(devinfo, &__i2c_board_list, list) {
		if (devinfo->busnum == adapter->nr
		if (devinfo->busnum == adapter->nr
				&& !i2c_new_device(adapter,
				&& !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",
				"Can't create device at 0x%02x\n",
				devinfo->board_info.addr);
				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)
static int i2c_do_add_adapter(struct device_driver *d, void *data)
+3 −1
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 */


#include <linux/rwsem.h>

struct i2c_devinfo {
struct i2c_devinfo {
	struct list_head	list;
	struct list_head	list;
	int			busnum;
	int			busnum;
@@ -25,7 +27,7 @@ struct i2c_devinfo {
/* board_lock protects board_list and first_dynamic_bus_num.
/* board_lock protects board_list and first_dynamic_bus_num.
 * only i2c core components are allowed to use these symbols.
 * 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 struct list_head	__i2c_board_list;
extern int		__i2c_first_dynamic_bus_num;
extern int		__i2c_first_dynamic_bus_num;