Saravana needs to look at this patch too, so I am top-posting. Yours, Linus Walleij On Tue, Feb 20, 2024 at 12:11 PM Herve Codina <herve.codina@xxxxxxxxxxx> wrote: > When a gpio is removed, the gpio leds consumer need to be removed first. > This dependency consumer/supplier can be described by devlink links. > In case of device-tree, even if some devlinks are created due to the > presence of gpio phandles in the gpio leds children, these links do not > help in removing the gpio leds device (i.e. the real consumer) before > the consumed gpio. > We can reach cases where the gpio are no more present and the gpio leds > driver continue to have leds using these gpio. > Further more, when the gpio come back, the gpio leds still use the old > removed one. > > Indeed, the gpio are consumed by the parent of the consumer used in the > devlink creation due to phandles. A link is missing between the gpio and > the real gpio consumer, the gpio leds device itself. > > Use the newly introduced gpiod_device_add_link() to create this > missing link between the gpio leds devices and the gpios. > With that done, if a gpio is removed, the gpio leds is removed and the > resources are correctly released. > > Signed-off-by: Herve Codina <herve.codina@xxxxxxxxxxx> > --- > drivers/leds/leds-gpio.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c > index 83fcd7b6afff..b3ec8ecbe5da 100644 > --- a/drivers/leds/leds-gpio.c > +++ b/drivers/leds/leds-gpio.c > @@ -150,6 +150,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev) > { > struct fwnode_handle *child; > struct gpio_leds_priv *priv; > + struct device_link *link; > int count, ret; > > count = device_get_child_node_count(dev); > @@ -197,6 +198,20 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev) > /* Set gpiod label to match the corresponding LED name. */ > gpiod_set_consumer_name(led_dat->gpiod, > led_dat->cdev.dev->kobj.name); > + > + /* > + * Create a link between the GPIO and the gpio-leds device. > + * This allow to have a relationship between the gpio used and > + * the gpio-leds device in order to automatically remove the > + * gpio-leds device (consumer) when a GPIO (supplier) is removed. > + */ > + link = gpiod_device_add_link(dev, led_dat->gpiod, > + DL_FLAG_AUTOREMOVE_CONSUMER); > + if (IS_ERR(link)) { > + fwnode_handle_put(child); > + return ERR_CAST(link); > + } > + > priv->num_leds++; > } > > -- > 2.43.0 >