Re: [PATCH 02/24] leds: core: Add support for composing LED class device names

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jacek,

On 9 November 2018 at 04:47, Jacek Anaszewski
<jacek.anaszewski@xxxxxxxxx> wrote:
> Hi Baolin,
>
> Thanks for the review.
>
> On 11/07/2018 08:20 AM, Baolin Wang wrote:
>> Hi Jacek,
>>
>> On 7 November 2018 at 06:07, Jacek Anaszewski
>> <jacek.anaszewski@xxxxxxxxx> wrote:
>>> Add public led_compose_name() API for composing LED class device
>>> name basing on fwnode_handle data. The function composes device name
>>> according to either a new <color:function> pattern or the legacy
>>> <devicename:color:function> pattern. The decision on using the
>>> particular pattern is made basing on whether fwnode contains new
>>> "function" and "color" properties, or the legacy "label" proeprty.
>>>
>>> Backwards compatibility with in-driver hard-coded LED class device
>>> names is assured thanks to the default_desc argument.
>>>
>>> In case none of the aformentioned properties was found, then, for OF
>>> nodes, the node name is adopted for LED class device name.
>>>
>>> Signed-off-by: Jacek Anaszewski <jacek.anaszewski@xxxxxxxxx>
>>> Cc: Baolin Wang <baolin.wang@xxxxxxxxxx>
>>> Cc: Daniel Mack <daniel@xxxxxxxxxx>
>>> Cc: Dan Murphy <dmurphy@xxxxxx>
>>> Cc: Linus Walleij <linus.walleij@xxxxxxxxxx>
>>> Cc: Oleh Kravchenko <oleg@xxxxxxxxxx>
>>> Cc: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
>>> Cc: Simon Shields <simon@xxxxxxxxxxxxx>
>>> Cc: Xiaotong Lu <xiaotong.lu@xxxxxxxxxxxxxx>
>>> ---
>>>  Documentation/leds/leds-class.txt |  2 +-
>>>  drivers/leds/led-core.c           | 71 +++++++++++++++++++++++++++++++++++++++
>>>  include/linux/leds.h              | 32 ++++++++++++++++++
>>>  3 files changed, 104 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/leds/leds-class.txt b/Documentation/leds/leds-class.txt
>>> index 836cb16..e9009c4 100644
>>> --- a/Documentation/leds/leds-class.txt
>>> +++ b/Documentation/leds/leds-class.txt
>>> @@ -43,7 +43,7 @@ LED Device Naming
>>>
>>>  Is currently of the form:
>>>
>>> -"devicename:colour:function"
>>> +"colour:function"
>>>
>>>  There have been calls for LED properties such as colour to be exported as
>>>  individual led class attributes. As a solution which doesn't incur as much
>>> diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
>>> index ede4fa0..f7371fc 100644
>>> --- a/drivers/leds/led-core.c
>>> +++ b/drivers/leds/led-core.c
>>> @@ -16,6 +16,8 @@
>>>  #include <linux/list.h>
>>>  #include <linux/module.h>
>>>  #include <linux/mutex.h>
>>> +#include <linux/of.h>
>>> +#include <linux/property.h>
>>>  #include <linux/rwsem.h>
>>>  #include "leds.h"
>>>
>>> @@ -327,3 +329,72 @@ void led_sysfs_enable(struct led_classdev *led_cdev)
>>>         led_cdev->flags &= ~LED_SYSFS_DISABLE;
>>>  }
>>>  EXPORT_SYMBOL_GPL(led_sysfs_enable);
>>> +
>>> +static void led_parse_properties(struct fwnode_handle *fwnode,
>>> +                                struct led_properties *props)
>>> +{
>>> +       int ret;
>>> +
>>> +       if (!fwnode)
>>> +               return;
>>> +
>>> +       ret = fwnode_property_read_string(fwnode, "label", &props->label);
>>> +       if (!ret)
>>> +               return;
>>> +
>>> +       ret = fwnode_property_read_string(fwnode, "function", &props->function);
>>> +       if (ret)
>>> +               pr_info("Failed to parse function property\n");
>>> +
>>> +       ret = fwnode_property_read_string(fwnode, "color", &props->color);
>>> +       if (ret)
>>> +               pr_info("Failed to parse color property\n");
>>
>> Now the color and function properties can be optional, so we should
>> deal with different return errors.
>> -EINVAL means we have not set color or function property, which means
>> we should not give failure message for users (maybe "not supply color
>> property\n") and return 0 as success.
>
> The lack of any of these properties is not critical, therefore this
> function does not return the error code, but only prints the status.
> Please note that I'm not using pr_error(), but pr_info().
> Related to the message text - I agree, I will change it to e.g.
> "color property not found"

Yes, that's reasonable.

>
>> For other errors, we should not ignore them, instead we should give
>> failure messages and return errors.
>
> I've skimmed through other kernel drivers and vast majority of
> them don't check exact failure code in case of non-zero return,
> but assume that property is missing, and eventually report
> error code. I'd do the same here.

Fair enough. You can still add my tested tag. Thanks.

>> Tested-by: Baolin Wang <baolin.wang@xxxxxxxxxx>
>>
>>> +}
>>> +
>>> +int led_compose_name(struct fwnode_handle *fwnode, const char *led_hw_name,
>>> +                    const char *default_desc, char *led_classdev_name)
>>> +{
>>> +       struct led_properties props = {};
>>> +
>>> +       if (!led_classdev_name)
>>> +               return -EINVAL;
>>> +
>>> +       led_parse_properties(fwnode, &props);
>>> +
>>> +       if (props.label) {
>>> +               /*
>>> +                * Presence of 'label' DT property implies legacy LED name,
>>> +                * formatted as <devicename:color:function>, with possible
>>> +                * section omission if doesn't apply to given device.
>>> +                *
>>> +                * If no led_hw_name has been passed, then it indicates that
>>> +                * DT label should be used as-is for LED class device name.
>>> +                * Otherwise the label is prepended with led_hw_name to compose
>>> +                * the final LED class device name.
>>> +                */
>>> +               if (!led_hw_name) {
>>> +                       strncpy(led_classdev_name, props.label,
>>> +                               LED_MAX_NAME_SIZE);
>>> +               } else {
>>> +                       snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
>>> +                                led_hw_name, props.label);
>>> +               }
>>> +       } else if (props.function || props.color) {
>>> +               snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
>>> +                        props.color ?: "", props.function ?: "");
>>> +       } else if (default_desc) {
>>> +               if (!led_hw_name) {
>>> +                       pr_err("Legacy LED naming requires devicename segment");
>>> +                       return -EINVAL;
>>> +               }
>>> +               snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
>>> +                        led_hw_name, default_desc);
>>> +       } else if (is_of_node(fwnode)) {
>>> +               strncpy(led_classdev_name, to_of_node(fwnode)->name,
>>> +                       LED_MAX_NAME_SIZE);
>>> +       } else
>>> +               return -EINVAL;
>>> +
>>> +       return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(led_compose_name);
>>> diff --git a/include/linux/leds.h b/include/linux/leds.h
>>> index 646c49a..ddb4001 100644
>>> --- a/include/linux/leds.h
>>> +++ b/include/linux/leds.h
>>> @@ -238,6 +238,32 @@ extern void led_sysfs_disable(struct led_classdev *led_cdev);
>>>  extern void led_sysfs_enable(struct led_classdev *led_cdev);
>>>
>>>  /**
>>> + * led_compose_name - compose LED class device name
>>> + * @child: child fwnode_handle describing a LED,
>>> + *        or a group of synchronized LEDs.
>>> + * @led_hw_name: name of the LED controller, used when falling back to legacy
>>> + *              LED naming; it should be set to NULL in new LED class drivers
>>> + * @default_desc: default <color:function> tuple, for backwards compatibility
>>> + *               with in-driver hard-coded LED names used as a fallback when
>>> + *               "label" DT property was absent; it should be set to NULL
>>> + *               in new LED class drivers
>>> + * @led_classdev_name: composed LED class device name
>>> + *
>>> + * Create LED class device name basing on the configuration provided by the
>>> + * board firmware. The name can have a legacy form <devicename:color:function>,
>>> + * or a new form <color:function>. The latter is chosen if at least one of
>>> + * "color" or "function" properties is present in the fwnode, leaving the
>>> + * section blank if the related property is absent. The former is applied
>>> + * when legacy "label" property is present in the fwnode. In case none of the
>>> + * aformentioned properties was found, then, for OF nodes, the node name
>>> + * is adopted for LED class device name.
>>> + *
>>> + * Returns: 0 on success or negative error value on failure
>>> + */
>>> +extern int led_compose_name(struct fwnode_handle *child, const char *led_hw_name,
>>> +                           const char *default_desc, char *led_classdev_name);
>>> +
>>> +/**
>>>   * led_sysfs_is_disabled - check if LED sysfs interface is disabled
>>>   * @led_cdev: the LED to query
>>>   *
>>> @@ -414,6 +440,12 @@ struct led_platform_data {
>>>         struct led_info *leds;
>>>  };
>>>
>>> +struct led_properties {
>>> +       const char *color;
>>> +       const char *function;
>>> +       const char *label;
>>> +};
>>> +
>>>  struct gpio_desc;
>>>  typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state,
>>>                                 unsigned long *delay_on,
>>> --
>>> 2.1.4
>>>
>>
>>
>>
>
> --
> Best regards,
> Jacek Anaszewski



-- 
Baolin Wang
Best Regards



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux