2019-09-10 14:19:54

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: [RESEND,v2 0/2] leds: tlc591xx: switch to OF and managed API

This mini-series updates the tlc591xx driver to use the managed API. The
driver is also modified to pass the DT node to the LED core layer.
The goal is to be able to the generic led-backlight [0] driver on top of
it.

changes in v2:
- fixed LED indexing. Previous version did not allow for holes: if n LEDs
were used, they had to be led(0) to led(n-1)

Jean-Jacques Hiblot (2):
leds: tlc591xx: simplify driver by using the managed led API
leds: tlc591xx: Use the OF version of the LED registration function

drivers/leds/leds-tlc591xx.c | 79 +++++++++---------------------------
1 file changed, 20 insertions(+), 59 deletions(-)

--
2.17.1


2019-09-10 19:01:54

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: [RESEND,v2 2/2] leds: tlc591xx: Use the OF version of the LED registration function

The driver parses the device-tree to identify which LED should be handled.
Since the information about the device node is known at this time, we can
provide the LED core with it. It may be useful later.

Signed-off-by: Jean-Jacques Hiblot <[email protected]>
Reviewed-by: Tomi Valkeinen <[email protected]>
Acked-by: Pavel Machek <[email protected]>
---
drivers/leds/leds-tlc591xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/leds/leds-tlc591xx.c b/drivers/leds/leds-tlc591xx.c
index 3d5a4b92f016..10764a62cb71 100644
--- a/drivers/leds/leds-tlc591xx.c
+++ b/drivers/leds/leds-tlc591xx.c
@@ -207,7 +207,7 @@ tlc591xx_probe(struct i2c_client *client,
led->led_no = reg;
led->ldev.brightness_set_blocking = tlc591xx_brightness_set;
led->ldev.max_brightness = LED_FULL;
- err = devm_led_classdev_register(dev, &led->ldev);
+ err = devm_of_led_classdev_register(dev, child, &led->ldev);
if (err < 0) {
dev_err(dev, "couldn't register LED %s\n",
led->ldev.name);
--
2.17.1

2019-09-10 20:15:37

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: [RESEND,v2 1/2] leds: tlc591xx: simplify driver by using the managed led API

Use the managed API of the LED class (devm_led_classdev_register()
instead of led_classdev_register()).
This allows us to remove the code used to track-and-destroy the LED devices

Signed-off-by: Jean-Jacques Hiblot <[email protected]>
Reviewed-by: Tomi Valkeinen <[email protected]>
---
drivers/leds/leds-tlc591xx.c | 79 +++++++++---------------------------
1 file changed, 20 insertions(+), 59 deletions(-)

diff --git a/drivers/leds/leds-tlc591xx.c b/drivers/leds/leds-tlc591xx.c
index 59ff088c7d75..3d5a4b92f016 100644
--- a/drivers/leds/leds-tlc591xx.c
+++ b/drivers/leds/leds-tlc591xx.c
@@ -128,51 +128,6 @@ tlc591xx_brightness_set(struct led_classdev *led_cdev,
return err;
}

-static void
-tlc591xx_destroy_devices(struct tlc591xx_priv *priv, unsigned int j)
-{
- int i = j;
-
- while (--i >= 0) {
- if (priv->leds[i].active)
- led_classdev_unregister(&priv->leds[i].ldev);
- }
-}
-
-static int
-tlc591xx_configure(struct device *dev,
- struct tlc591xx_priv *priv,
- const struct tlc591xx *tlc591xx)
-{
- unsigned int i;
- int err = 0;
-
- tlc591xx_set_mode(priv->regmap, MODE2_DIM);
- for (i = 0; i < TLC591XX_MAX_LEDS; i++) {
- struct tlc591xx_led *led = &priv->leds[i];
-
- if (!led->active)
- continue;
-
- led->priv = priv;
- led->led_no = i;
- led->ldev.brightness_set_blocking = tlc591xx_brightness_set;
- led->ldev.max_brightness = LED_FULL;
- err = led_classdev_register(dev, &led->ldev);
- if (err < 0) {
- dev_err(dev, "couldn't register LED %s\n",
- led->ldev.name);
- goto exit;
- }
- }
-
- return 0;
-
-exit:
- tlc591xx_destroy_devices(priv, i);
- return err;
-}
-
static const struct regmap_config tlc591xx_regmap = {
.reg_bits = 8,
.val_bits = 8,
@@ -225,7 +180,11 @@ tlc591xx_probe(struct i2c_client *client,

i2c_set_clientdata(client, priv);

+ tlc591xx_set_mode(priv->regmap, MODE2_DIM);
+
for_each_child_of_node(np, child) {
+ struct tlc591xx_led *led;
+
err = of_property_read_u32(child, "reg", &reg);
if (err) {
of_node_put(child);
@@ -236,22 +195,25 @@ tlc591xx_probe(struct i2c_client *client,
of_node_put(child);
return -EINVAL;
}
- priv->leds[reg].active = true;
- priv->leds[reg].ldev.name =
+ led = &priv->leds[reg];
+
+ led->active = true;
+ led->ldev.name =
of_get_property(child, "label", NULL) ? : child->name;
- priv->leds[reg].ldev.default_trigger =
+ led->ldev.default_trigger =
of_get_property(child, "linux,default-trigger", NULL);
- }
- return tlc591xx_configure(dev, priv, tlc591xx);
-}
-
-static int
-tlc591xx_remove(struct i2c_client *client)
-{
- struct tlc591xx_priv *priv = i2c_get_clientdata(client);
-
- tlc591xx_destroy_devices(priv, TLC591XX_MAX_LEDS);

+ led->priv = priv;
+ led->led_no = reg;
+ led->ldev.brightness_set_blocking = tlc591xx_brightness_set;
+ led->ldev.max_brightness = LED_FULL;
+ err = devm_led_classdev_register(dev, &led->ldev);
+ if (err < 0) {
+ dev_err(dev, "couldn't register LED %s\n",
+ led->ldev.name);
+ return err;
+ }
+ }
return 0;
}

@@ -268,7 +230,6 @@ static struct i2c_driver tlc591xx_driver = {
.of_match_table = of_match_ptr(of_tlc591xx_leds_match),
},
.probe = tlc591xx_probe,
- .remove = tlc591xx_remove,
.id_table = tlc591xx_id,
};

--
2.17.1

2019-09-10 20:23:17

by Jacek Anaszewski

[permalink] [raw]
Subject: Re: [RESEND,v2 2/2] leds: tlc591xx: Use the OF version of the LED registration function

Hi Jean,

Thank you the patch.

On 9/10/19 3:38 PM, Jean-Jacques Hiblot wrote:
> The driver parses the device-tree to identify which LED should be handled.
> Since the information about the device node is known at this time, we can
> provide the LED core with it. It may be useful later.
>
> Signed-off-by: Jean-Jacques Hiblot <[email protected]>
> Reviewed-by: Tomi Valkeinen <[email protected]>
> Acked-by: Pavel Machek <[email protected]>
> ---
> drivers/leds/leds-tlc591xx.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/leds/leds-tlc591xx.c b/drivers/leds/leds-tlc591xx.c
> index 3d5a4b92f016..10764a62cb71 100644
> --- a/drivers/leds/leds-tlc591xx.c
> +++ b/drivers/leds/leds-tlc591xx.c
> @@ -207,7 +207,7 @@ tlc591xx_probe(struct i2c_client *client,
> led->led_no = reg;
> led->ldev.brightness_set_blocking = tlc591xx_brightness_set;
> led->ldev.max_brightness = LED_FULL;
> - err = devm_led_classdev_register(dev, &led->ldev);
> + err = devm_of_led_classdev_register(dev, child, &led->ldev);

devm_of_led_classdev_register() has been replaced with
devm_led_classdev_register_ext() recently. Do you have some specific
reason for passing OF node to the LED registration function?

Currently this is beneficial only for generic LED name composition
mechanism basing on 'function' and 'color' DT properties so if you
want you can convert the driver to that. Please compare such recent
conversions in linux-leds.git for-next branch [0][1].

> if (err < 0) {
> dev_err(dev, "couldn't register LED %s\n",
> led->ldev.name);
>

[0]
https://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git/commit/?h=for-next&id=a50ff28348934913c46feb7945571329e46c70b3
[1]
https://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git/commit/?h=for-next&id=4dcbc8f8c59f4b618d651f5ba884ee5bf562c8de

--
Best regards,
Jacek Anaszewski

2019-09-11 08:23:57

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: Re: [RESEND,v2 2/2] leds: tlc591xx: Use the OF version of the LED registration function


On 10/09/2019 22:08, Jacek Anaszewski wrote:
> Hi Jean,
>
> Thank you the patch.
>
> On 9/10/19 3:38 PM, Jean-Jacques Hiblot wrote:
>> The driver parses the device-tree to identify which LED should be handled.
>> Since the information about the device node is known at this time, we can
>> provide the LED core with it. It may be useful later.
>>
>> Signed-off-by: Jean-Jacques Hiblot <[email protected]>
>> Reviewed-by: Tomi Valkeinen <[email protected]>
>> Acked-by: Pavel Machek <[email protected]>
>> ---
>> drivers/leds/leds-tlc591xx.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/leds/leds-tlc591xx.c b/drivers/leds/leds-tlc591xx.c
>> index 3d5a4b92f016..10764a62cb71 100644
>> --- a/drivers/leds/leds-tlc591xx.c
>> +++ b/drivers/leds/leds-tlc591xx.c
>> @@ -207,7 +207,7 @@ tlc591xx_probe(struct i2c_client *client,
>> led->led_no = reg;
>> led->ldev.brightness_set_blocking = tlc591xx_brightness_set;
>> led->ldev.max_brightness = LED_FULL;
>> - err = devm_led_classdev_register(dev, &led->ldev);
>> + err = devm_of_led_classdev_register(dev, child, &led->ldev);
> devm_of_led_classdev_register() has been replaced with
> devm_led_classdev_register_ext() recently. Do you have some specific
> reason for passing OF node to the LED registration function?

Not anymore at this point.

I used the OF because the other patchset I posted (leds: Add control of
the voltage/current regulator to the LED core) uses the of_node to find
a regulator in the node of the LED. Since the regulator stuff is going
to need some rework, we can drop this patch.

Thanks

JJ

> Currently this is beneficial only for generic LED name composition
> mechanism basing on 'function' and 'color' DT properties so if you
> want you can convert the driver to that. Please compare such recent
> conversions in linux-leds.git for-next branch [0][1].
>
>> if (err < 0) {
>> dev_err(dev, "couldn't register LED %s\n",
>> led->ldev.name);
>>
> [0]
> https://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git/commit/?h=for-next&id=a50ff28348934913c46feb7945571329e46c70b3
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git/commit/?h=for-next&id=4dcbc8f8c59f4b618d651f5ba884ee5bf562c8de
>