Message ID | 20230120114524.408368-6-hdegoede@redhat.com |
---|---|
State | New |
Headers | show |
Series | leds: lookup-table support + int3472/media privacy LED support | expand |
On Fri, 20 Jan 2023, Hans de Goede wrote: > Turn of_led_get() into a more generic __of_led_get() helper function, > which can lookup LEDs in devicetree by either name or index. > > And use this new helper to add devicetree support to the generic > (non devicetree specific) [devm_]led_get() function. > > This uses the standard devicetree pattern of adding a -names string array > to map names to the indexes for an array of resources. > > Note the new led-names property for LED consumers is not added > to the devicetree documentation because there seems to be no > documentation for the leds property itself to extend it with this. > It seems that how LED consumers should be described is not documented > at all ATM. > > This patch is marked as RFC because of both the missing devicetree > documentation and because there are no devicetree users of > the generic [devm_]led_get() function for now. > > Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> > Reviewed-by: Linus Walleij <linus.walleij@linaro.org> > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > drivers/leds/led-class.c | 37 ++++++++++++++++++++++++++++--------- > 1 file changed, 28 insertions(+), 9 deletions(-) Reviewed-by: Lee Jones <lee@kernel.org> > > diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c > index 0c4b8d8d2b4f..2f3af6e30208 100644 > --- a/drivers/leds/led-class.c > +++ b/drivers/leds/led-class.c > @@ -234,19 +234,18 @@ static struct led_classdev *led_module_get(struct device *led_dev) > return led_cdev; > } > > -/** > - * of_led_get() - request a LED device via the LED framework > - * @np: device node to get the LED device from > - * @index: the index of the LED > - * > - * Returns the LED device parsed from the phandle specified in the "leds" > - * property of a device tree node or a negative error-code on failure. > - */ > -struct led_classdev *of_led_get(struct device_node *np, int index) > +static struct led_classdev *__of_led_get(struct device_node *np, int index, > + const char *name) > { > struct device *led_dev; > struct device_node *led_node; > > + /* > + * For named LEDs, first look up the name in the "led-names" property. > + * If it cannot be found, then of_parse_phandle() will propagate the error. > + */ > + if (name) > + index = of_property_match_string(np, "led-names", name); > led_node = of_parse_phandle(np, "leds", index); > if (!led_node) > return ERR_PTR(-ENOENT); > @@ -256,6 +255,19 @@ struct led_classdev *of_led_get(struct device_node *np, int index) > > return led_module_get(led_dev); > } > + > +/** > + * of_led_get() - request a LED device via the LED framework > + * @np: device node to get the LED device from > + * @index: the index of the LED > + * > + * Returns the LED device parsed from the phandle specified in the "leds" > + * property of a device tree node or a negative error-code on failure. > + */ > +struct led_classdev *of_led_get(struct device_node *np, int index) > +{ > + return __of_led_get(np, index, NULL); > +} > EXPORT_SYMBOL_GPL(of_led_get); > > /** > @@ -329,9 +341,16 @@ EXPORT_SYMBOL_GPL(devm_of_led_get); > struct led_classdev *led_get(struct device *dev, char *con_id) > { > struct led_lookup_data *lookup; > + struct led_classdev *led_cdev; > const char *provider = NULL; > struct device *led_dev; > > + if (dev->of_node) { > + led_cdev = __of_led_get(dev->of_node, -1, con_id); > + if (!IS_ERR(led_cdev) || PTR_ERR(led_cdev) != -ENOENT) > + return led_cdev; > + } > + > mutex_lock(&leds_lookup_lock); > list_for_each_entry(lookup, &leds_lookup_list, list) { > if (!strcmp(lookup->dev_id, dev_name(dev)) && > -- > 2.39.0 >
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 0c4b8d8d2b4f..2f3af6e30208 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -234,19 +234,18 @@ static struct led_classdev *led_module_get(struct device *led_dev) return led_cdev; } -/** - * of_led_get() - request a LED device via the LED framework - * @np: device node to get the LED device from - * @index: the index of the LED - * - * Returns the LED device parsed from the phandle specified in the "leds" - * property of a device tree node or a negative error-code on failure. - */ -struct led_classdev *of_led_get(struct device_node *np, int index) +static struct led_classdev *__of_led_get(struct device_node *np, int index, + const char *name) { struct device *led_dev; struct device_node *led_node; + /* + * For named LEDs, first look up the name in the "led-names" property. + * If it cannot be found, then of_parse_phandle() will propagate the error. + */ + if (name) + index = of_property_match_string(np, "led-names", name); led_node = of_parse_phandle(np, "leds", index); if (!led_node) return ERR_PTR(-ENOENT); @@ -256,6 +255,19 @@ struct led_classdev *of_led_get(struct device_node *np, int index) return led_module_get(led_dev); } + +/** + * of_led_get() - request a LED device via the LED framework + * @np: device node to get the LED device from + * @index: the index of the LED + * + * Returns the LED device parsed from the phandle specified in the "leds" + * property of a device tree node or a negative error-code on failure. + */ +struct led_classdev *of_led_get(struct device_node *np, int index) +{ + return __of_led_get(np, index, NULL); +} EXPORT_SYMBOL_GPL(of_led_get); /** @@ -329,9 +341,16 @@ EXPORT_SYMBOL_GPL(devm_of_led_get); struct led_classdev *led_get(struct device *dev, char *con_id) { struct led_lookup_data *lookup; + struct led_classdev *led_cdev; const char *provider = NULL; struct device *led_dev; + if (dev->of_node) { + led_cdev = __of_led_get(dev->of_node, -1, con_id); + if (!IS_ERR(led_cdev) || PTR_ERR(led_cdev) != -ENOENT) + return led_cdev; + } + mutex_lock(&leds_lookup_lock); list_for_each_entry(lookup, &leds_lookup_list, list) { if (!strcmp(lookup->dev_id, dev_name(dev)) &&