Commit 1979a280 authored by Bartosz Golaszewski's avatar Bartosz Golaszewski

gpiolib: replace the GPIO device mutex with a read-write semaphore

There are only two spots where we modify (add to or remove objects from)
the GPIO device list. Readers should be able to access it concurrently.
Replace the mutex with a read-write semaphore and adjust the locking
operations accordingly.
Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 48e1b4d3
......@@ -773,7 +773,7 @@ int gpiochip_sysfs_register_all(void)
struct gpio_device *gdev;
int ret;
guard(mutex)(&gpio_devices_lock);
guard(rwsem_read)(&gpio_devices_sem);
list_for_each_entry(gdev, &gpio_devices, list) {
if (gdev->mockdev)
......
......@@ -85,7 +85,7 @@ static DEFINE_MUTEX(gpio_lookup_lock);
static LIST_HEAD(gpio_lookup_list);
LIST_HEAD(gpio_devices);
DEFINE_MUTEX(gpio_devices_lock);
DECLARE_RWSEM(gpio_devices_sem);
static DEFINE_MUTEX(gpio_machine_hogs_mutex);
static LIST_HEAD(gpio_machine_hogs);
......@@ -118,7 +118,7 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
{
struct gpio_device *gdev;
scoped_guard(mutex, &gpio_devices_lock) {
scoped_guard(rwsem_read, &gpio_devices_sem) {
list_for_each_entry(gdev, &gpio_devices, list) {
if (gdev->base <= gpio &&
gdev->base + gdev->ngpio > gpio)
......@@ -402,7 +402,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)
if (!name)
return NULL;
guard(mutex)(&gpio_devices_lock);
guard(rwsem_read)(&gpio_devices_sem);
list_for_each_entry(gdev, &gpio_devices, list) {
struct gpio_desc *desc;
......@@ -871,7 +871,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gdev->ngpio = gc->ngpio;
scoped_guard(mutex, &gpio_devices_lock) {
scoped_guard(rwsem_write, &gpio_devices_sem) {
/*
* TODO: this allocates a Linux GPIO number base in the global
* GPIO numberspace for this chip. In the long run we want to
......@@ -1001,7 +1001,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
goto err_print_message;
}
err_remove_from_list:
scoped_guard(mutex, &gpio_devices_lock)
scoped_guard(rwsem_write, &gpio_devices_sem)
list_del(&gdev->list);
err_free_label:
kfree_const(gdev->label);
......@@ -1065,7 +1065,7 @@ void gpiochip_remove(struct gpio_chip *gc)
dev_crit(&gdev->dev,
"REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n");
scoped_guard(mutex, &gpio_devices_lock)
scoped_guard(rwsem_write, &gpio_devices_sem)
list_del(&gdev->list);
/*
......@@ -1114,7 +1114,7 @@ struct gpio_device *gpio_device_find(void *data,
*/
might_sleep();
guard(mutex)(&gpio_devices_lock);
guard(rwsem_read)(&gpio_devices_sem);
list_for_each_entry(gdev, &gpio_devices, list) {
if (gdev->chip && match(gdev->chip, data))
......@@ -4730,7 +4730,7 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)
s->private = "";
guard(mutex)(&gpio_devices_lock);
guard(rwsem_read)(&gpio_devices_sem);
list_for_each_entry(gdev, &gpio_devices, list) {
if (index-- == 0)
......@@ -4745,7 +4745,7 @@ static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)
struct gpio_device *gdev = v;
void *ret = NULL;
scoped_guard(mutex, &gpio_devices_lock) {
scoped_guard(rwsem_read, &gpio_devices_sem) {
if (list_is_last(&gdev->list, &gpio_devices))
ret = NULL;
else
......
......@@ -137,7 +137,7 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
extern spinlock_t gpio_lock;
extern struct list_head gpio_devices;
extern struct mutex gpio_devices_lock;
extern struct rw_semaphore gpio_devices_sem;
void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment