Dan, On 7/31/19 8:55 PM, Dan Murphy wrote: > Jacek > > Thanks for looking You're welcome. > On 7/31/19 1:45 PM, Jacek Anaszewski wrote: >> Hi Dan, >> >> Thank you for the patch. My comments are below. >> >> On 7/25/19 8:28 PM, Dan Murphy wrote: >>> Update the lp5523 to use the multi color framework. >>> >>> Signed-off-by: Dan Murphy <dmurphy@xxxxxx> >>> --- >>> drivers/leds/leds-lp5523.c | 13 ++ >>> drivers/leds/leds-lp55xx-common.c | 153 ++++++++++++++++++---- >>> drivers/leds/leds-lp55xx-common.h | 10 ++ >>> include/linux/platform_data/leds-lp55xx.h | 6 + >>> modules.builtin.modinfo | Bin 0 -> 43550 bytes >>> 5 files changed, 159 insertions(+), 23 deletions(-) >>> create mode 100644 modules.builtin.modinfo >>> >>> diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c >>> index d0b931a136b9..45380b32563f 100644 >>> --- a/drivers/leds/leds-lp5523.c >>> +++ b/drivers/leds/leds-lp5523.c [...] > >>> + if (ret) >>> + break; >>> + } >>> + } else { >>> + led->brightness = (u8)brightness; >> What benefit stems actually from having the copy of brightness >> in struct lp55xx_led, when we already have struct led_classdev >> there? I know that this is pre-existing, but could be optimized away >> while at it. We can have local u8 variable in the op setting brightness >> and cast enum_led_brightness to it before passing to lp55xx_write(). >> > This was a carry over from the original driver. Ln 140. > > I am not looking to change existing code functionality. > > First pass was just to introduce mc_fw with no disruption or regression > > to the base functionality. Sure thing. Just wanted to mention that for a record. [...] >>> - led->cdev.brightness_set_blocking = lp55xx_set_brightness; >>> - led->cdev.groups = lp55xx_led_groups; >>> - >>> - if (pdata->led_config[chan].name) { >>> - led->cdev.name = pdata->led_config[chan].name; >>> - } else { >>> - snprintf(name, sizeof(name), "%s:channel%d", >>> - pdata->label ? : chip->cl->name, chan); >>> - led->cdev.name = name; >>> - } >>> + if (pdata->led_config[chan].num_colors > 1) >>> + ret = led_classdev_multicolor_register(dev, &led->mc_cdev); >>> + else >>> + ret = led_classdev_register(dev, &led->cdev); >> Why not devm ? > > I will call the devm_ for multicolor but conversion for not MC should be > done separately > > Again not trying to regress original functionality. Then it's better to switch to devm later. Only then it will allow to optimize the error paths. >>> - ret = led_classdev_register(dev, &led->cdev); >>> if (ret) { >>> dev_err(dev, "led register err: %d\n", ret); >>> return ret; >>> @@ -466,7 +526,6 @@ int lp55xx_register_leds(struct lp55xx_led *led, >>> struct lp55xx_chip *chip) >>> dev_err(&chip->cl->dev, "empty brightness configuration\n"); >>> return -EINVAL; >>> } >>> - >>> for (i = 0; i < num_channels; i++) { >>> /* do not initialize channels that are not connected */ >>> @@ -538,6 +597,39 @@ void lp55xx_unregister_sysfs(struct lp55xx_chip >>> *chip) >>> } >>> EXPORT_SYMBOL_GPL(lp55xx_unregister_sysfs); >>> +static int lp5xx_parse_channel_child(struct device_node *np, >>> + struct lp55xx_led_config *cfg, >>> + int chan_num) >>> +{ >>> + struct device_node *child; >>> + int num_colors = 0; >>> + u32 color_id; >>> + u32 led_number; >>> + int ret; >>> + >>> + cfg[chan_num].default_trigger = >>> + of_get_property(np, "linux,default-trigger", NULL); >>> + >>> + for_each_child_of_node(np, child) { >>> + of_property_read_string(child, "chan-name", >>> + &cfg[chan_num].name); >>> + of_property_read_u8(child, "led-cur", >>> + &cfg[chan_num].led_current); >>> + of_property_read_u8(child, "max-cur", >>> + &cfg[chan_num].max_current); >>> + of_property_read_u32(child, "color", &color_id); >>> + cfg[chan_num].channel_color[num_colors] = color_id; >>> + cfg[chan_num].available_colors |= 1 << color_id; >> set_bit(color_id, &cfg[chan_num].available_colors); > > Ack > > >> >>> + ret = of_property_read_u32(child, "reg", &led_number); >>> + cfg[chan_num].grouped_channels[num_colors] = led_number; >>> + num_colors++; >>> + } >>> + >>> + cfg->num_colors = num_colors; >>> + >>> + return 0; >>> +} >>> + >>> struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device >>> *dev, >>> struct device_node *np) >>> { >>> @@ -545,6 +637,8 @@ struct lp55xx_platform_data >>> *lp55xx_of_populate_pdata(struct device *dev, >>> struct lp55xx_platform_data *pdata; >>> struct lp55xx_led_config *cfg; >>> int num_channels; >>> + int num_chan_children; >>> + u32 led_number; >>> int i = 0; >>> pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); >>> @@ -565,13 +659,26 @@ struct lp55xx_platform_data >>> *lp55xx_of_populate_pdata(struct device *dev, >>> pdata->num_channels = num_channels; >>> for_each_child_of_node(np, child) { >>> - cfg[i].chan_nr = i; >>> - >>> - of_property_read_string(child, "chan-name", &cfg[i].name); >>> - of_property_read_u8(child, "led-cur", &cfg[i].led_current); >>> - of_property_read_u8(child, "max-cur", &cfg[i].max_current); >>> - cfg[i].default_trigger = >>> - of_get_property(child, "linux,default-trigger", NULL); >>> + num_chan_children = of_get_child_count(child); >>> + if (num_chan_children != 0) >> You're already parsing color. If it is present and equals >> LED_COLOR_ID_MULTI then we should expect children in the node. > > I don't see any parsing for color here but I suppose that I can add that > now I thought about that occurrence in lp5xx_parse_channel_child(). [...] -- Best regards, Jacek Anaszewski