Re: [PATCH 3/3] gpio: TODO: track the removal of GPIOD_FLAGS_BIT_NONEXCLUSIVE
From: Linus Walleij
Date: Fri Apr 04 2025 - 05:04:02 EST
On Tue, Apr 1, 2025 at 10:57 AM Bartosz Golaszewski <brgl@xxxxxxxx> wrote:
> > If several providers with their own struct device is using one
> > and the same GPIO line, the devres consumer is unclear: which
> > struct device should own the GPIO line?
> >
>
> Well, other subsystems just use reference-counted resources in this
> case but see above - this is not a good fit for GPIOs.
So to rehash, for example clocks and regulators are by definition the
equivalent to NONEXCLUSIVE, that is their default behaviour.
Two devices can surely request the same clock.
They can independently issue clk_enable() and clk_disable(),
and the semantics is a reference count increase/decrease.
They can have the same phandle in the device tree.
But GPIOs can not. They can only have one owner.
Technically this is because the only reference count we have in a gpio
descriptor is the boolean flag FLAG_REQUESTED, and it
happens like this in gpiod_request_commit():
if (test_and_set_bit(FLAG_REQUESTED, &desc->flags))
return -EBUSY;
This semantic is in a way natural because what would you do when
two owners make something a GPIO cannot do, such as
one does gpiod_set_value(1) and the other does gpiod_set_value(0)?
This issue does not exist in resources such as clocks or
regulators that only do enable/disable and that is why GPIOs
are different from other resources.
Then we can think of solutions to that.
One way would be to add a new type of refcounted GPIO
descriptor for this specific usecase, like (OTOMH):
struct gpio_desc_shared {
struct gpio_desc *gpiod;
struct device *devs[MAX_OWNERS];
u32 use_count;
};
struct gpio_desc_shared *gpiod_shared_get(struct device *dev ...);
void gpiod_shared_put(struct gpio_desc_shared *gds);
int gpiod_shared_enable(struct gpio_desc_shared *gds);
int gpiod_shared_disable(struct gpio_desc_shared *gds);
So this compound struct will not be able to set value
directly.
The gpiod inside that shared descriptor need to be obtained with
some gpiolib-internal quirk, not with gpiod_request().
It will issue gpiod_set_value(1) on the first enable and
gpiod_set_value(0) on last disable its internal descriptor.
If existing valid users are switched over to that then the
NONEXCLUSIVE stuff can be deleted.
Yours,
Linus Walleij