summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpiolib-shared.c16
-rw-r--r--drivers/gpio/gpiolib.c4
-rw-r--r--drivers/gpio/gpiolib.h2
3 files changed, 15 insertions, 7 deletions
diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c
index 17343fdc9758..9e6544203439 100644
--- a/drivers/gpio/gpiolib-shared.c
+++ b/drivers/gpio/gpiolib-shared.c
@@ -515,7 +515,7 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
{
struct gpio_shared_entry *entry;
struct gpio_shared_ref *ref;
- unsigned long *flags;
+ struct gpio_desc *desc;
int ret;
list_for_each_entry(entry, &gpio_shared_list, list) {
@@ -543,15 +543,17 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
if (list_count_nodes(&entry->refs) <= 1)
continue;
- flags = &gdev->descs[entry->offset].flags;
+ desc = &gdev->descs[entry->offset];
- __set_bit(GPIOD_FLAG_SHARED, flags);
+ __set_bit(GPIOD_FLAG_SHARED, &desc->flags);
/*
* Shared GPIOs are not requested via the normal path. Make
* them inaccessible to anyone even before we register the
* chip.
*/
- __set_bit(GPIOD_FLAG_REQUESTED, flags);
+ ret = gpiod_request_commit(desc, "shared");
+ if (ret)
+ return ret;
pr_debug("GPIO %u owned by %s is shared by multiple consumers\n",
entry->offset, gpio_device_get_label(gdev));
@@ -562,8 +564,10 @@ int gpio_device_setup_shared(struct gpio_device *gdev)
ref->con_id ?: "(none)");
ret = gpio_shared_make_adev(gdev, entry, ref);
- if (ret)
+ if (ret) {
+ gpiod_free_commit(desc);
return ret;
+ }
}
}
@@ -579,6 +583,8 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)
if (!device_match_fwnode(&gdev->dev, entry->fwnode))
continue;
+ gpiod_free_commit(&gdev->descs[entry->offset]);
+
list_for_each_entry(ref, &entry->refs, list) {
guard(mutex)(&ref->lock);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index fe2d107b0a84..1578cf3a8c74 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2453,7 +2453,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
* on each other, and help provide better diagnostics in debugfs.
* They're called even less than the "set direction" calls.
*/
-static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
+int gpiod_request_commit(struct gpio_desc *desc, const char *label)
{
unsigned int offset;
int ret;
@@ -2515,7 +2515,7 @@ int gpiod_request(struct gpio_desc *desc, const char *label)
return ret;
}
-static void gpiod_free_commit(struct gpio_desc *desc)
+void gpiod_free_commit(struct gpio_desc *desc)
{
unsigned long flags;
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 77f6f2936dc2..3abb90385829 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -244,7 +244,9 @@ DEFINE_CLASS(gpio_chip_guard,
struct gpio_desc *desc)
int gpiod_request(struct gpio_desc *desc, const char *label);
+int gpiod_request_commit(struct gpio_desc *desc, const char *label);
void gpiod_free(struct gpio_desc *desc);
+void gpiod_free_commit(struct gpio_desc *desc);
static inline int gpiod_request_user(struct gpio_desc *desc, const char *label)
{