{
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) {
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));
ref->con_id ?: "(none)");
ret = gpio_shared_make_adev(gdev, entry, ref);
- if (ret)
+ if (ret) {
+ gpiod_free_commit(desc);
return ret;
+ }
}
}
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);
* 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;
return ret;
}
-static void gpiod_free_commit(struct gpio_desc *desc)
+void gpiod_free_commit(struct gpio_desc *desc)
{
unsigned long flags;
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)
{