Skip to content

Commit 1979a28

Browse files
author
Bartosz Golaszewski
committed
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: Bartosz Golaszewski <[email protected]> Reviewed-by: Linus Walleij <[email protected]>
1 parent 48e1b4d commit 1979a28

File tree

3 files changed

+11
-11
lines changed

3 files changed

+11
-11
lines changed

drivers/gpio/gpiolib-sysfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ int gpiochip_sysfs_register_all(void)
773773
struct gpio_device *gdev;
774774
int ret;
775775

776-
guard(mutex)(&gpio_devices_lock);
776+
guard(rwsem_read)(&gpio_devices_sem);
777777

778778
list_for_each_entry(gdev, &gpio_devices, list) {
779779
if (gdev->mockdev)

drivers/gpio/gpiolib.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static DEFINE_MUTEX(gpio_lookup_lock);
8585
static LIST_HEAD(gpio_lookup_list);
8686

8787
LIST_HEAD(gpio_devices);
88-
DEFINE_MUTEX(gpio_devices_lock);
88+
DECLARE_RWSEM(gpio_devices_sem);
8989

9090
static DEFINE_MUTEX(gpio_machine_hogs_mutex);
9191
static LIST_HEAD(gpio_machine_hogs);
@@ -118,7 +118,7 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
118118
{
119119
struct gpio_device *gdev;
120120

121-
scoped_guard(mutex, &gpio_devices_lock) {
121+
scoped_guard(rwsem_read, &gpio_devices_sem) {
122122
list_for_each_entry(gdev, &gpio_devices, list) {
123123
if (gdev->base <= gpio &&
124124
gdev->base + gdev->ngpio > gpio)
@@ -402,7 +402,7 @@ static struct gpio_desc *gpio_name_to_desc(const char * const name)
402402
if (!name)
403403
return NULL;
404404

405-
guard(mutex)(&gpio_devices_lock);
405+
guard(rwsem_read)(&gpio_devices_sem);
406406

407407
list_for_each_entry(gdev, &gpio_devices, list) {
408408
struct gpio_desc *desc;
@@ -871,7 +871,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
871871

872872
gdev->ngpio = gc->ngpio;
873873

874-
scoped_guard(mutex, &gpio_devices_lock) {
874+
scoped_guard(rwsem_write, &gpio_devices_sem) {
875875
/*
876876
* TODO: this allocates a Linux GPIO number base in the global
877877
* 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,
10011001
goto err_print_message;
10021002
}
10031003
err_remove_from_list:
1004-
scoped_guard(mutex, &gpio_devices_lock)
1004+
scoped_guard(rwsem_write, &gpio_devices_sem)
10051005
list_del(&gdev->list);
10061006
err_free_label:
10071007
kfree_const(gdev->label);
@@ -1065,7 +1065,7 @@ void gpiochip_remove(struct gpio_chip *gc)
10651065
dev_crit(&gdev->dev,
10661066
"REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n");
10671067

1068-
scoped_guard(mutex, &gpio_devices_lock)
1068+
scoped_guard(rwsem_write, &gpio_devices_sem)
10691069
list_del(&gdev->list);
10701070

10711071
/*
@@ -1114,7 +1114,7 @@ struct gpio_device *gpio_device_find(void *data,
11141114
*/
11151115
might_sleep();
11161116

1117-
guard(mutex)(&gpio_devices_lock);
1117+
guard(rwsem_read)(&gpio_devices_sem);
11181118

11191119
list_for_each_entry(gdev, &gpio_devices, list) {
11201120
if (gdev->chip && match(gdev->chip, data))
@@ -4730,7 +4730,7 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos)
47304730

47314731
s->private = "";
47324732

4733-
guard(mutex)(&gpio_devices_lock);
4733+
guard(rwsem_read)(&gpio_devices_sem);
47344734

47354735
list_for_each_entry(gdev, &gpio_devices, list) {
47364736
if (index-- == 0)
@@ -4745,7 +4745,7 @@ static void *gpiolib_seq_next(struct seq_file *s, void *v, loff_t *pos)
47454745
struct gpio_device *gdev = v;
47464746
void *ret = NULL;
47474747

4748-
scoped_guard(mutex, &gpio_devices_lock) {
4748+
scoped_guard(rwsem_read, &gpio_devices_sem) {
47494749
if (list_is_last(&gdev->list, &gpio_devices))
47504750
ret = NULL;
47514751
else

drivers/gpio/gpiolib.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ int gpiod_set_transitory(struct gpio_desc *desc, bool transitory);
137137

138138
extern spinlock_t gpio_lock;
139139
extern struct list_head gpio_devices;
140-
extern struct mutex gpio_devices_lock;
140+
extern struct rw_semaphore gpio_devices_sem;
141141

142142
void gpiod_line_state_notify(struct gpio_desc *desc, unsigned long action);
143143

0 commit comments

Comments
 (0)