summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>2024-01-02 16:59:48 +0100
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>2024-01-04 10:29:16 +0100
commit1979a28075470ef82472a5656ecc969f901e0d3b (patch)
tree12b01c23e316fe05b646bad05b66d5e03127789a /drivers/gpio/gpiolib.c
parent48e1b4d369cfe2729138a128afa6b8a55d093eaf (diff)
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 <bartosz.golaszewski@linaro.org> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e019c4243809..4c93cf73a826 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -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 @@ err_free_gpiochip_mask:
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