[RFC PATCH v1 0/1] Support to use own workqueue for each LED

From: Arseniy Krasnov
Date: Sun Oct 30 2022 - 02:06:35 EST


This allows to use own workqueue for each LED. This could be useful when we
have multiple LEDs which must work mutually (from user's point of view), for
example when complex animation must be played. Problem is that default wq -
'system_wq' does not guarantee order of callbacks execution, which control
brightness of every LED. So when userspace or pattern logic wants to change
brightness in one order, kworkers may do it in random way, thus breaking
smoothness of animation.

Here is example how to use this patch:

--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -264,11 +264,17 @@ static int aw2013_probe_dt(struct aw2013 *chip)
struct device_node *np = dev_of_node(&chip->client->dev), *child;
int count, ret = 0, i = 0;
struct aw2013_led *led;
+ struct workqueue_struct *wq;

count = of_get_available_child_count(np);
if (!count || count > AW2013_MAX_LEDS)
return -EINVAL;

+ wq = alloc_ordered_workqueue("aw2013_wq", 0);
+
+ if (!wq)
+ return -ENOMEM;
+
regmap_write(chip->regmap, AW2013_RSTR, AW2013_RSTR_RESET);

for_each_available_child_of_node(np, child) {
@@ -299,6 +305,7 @@ static int aw2013_probe_dt(struct aw2013 *chip)

led->cdev.brightness_set_blocking = aw2013_brightness_set;
led->cdev.blink_set = aw2013_blink_set;
+ led->cdev.set_brightness_wq = wq;

ret = devm_led_classdev_register_ext(&chip->client->dev,
&led->cdev, &init_data);

E.g. special workqueue must be allocated and set for each LED during init of
'led_classdev'. Then later in 'led_init_core()', 'system_wq' won't be used for
such LEDs.

Arseniy Krasnov(1):
drivers/leds/led-core.c | 8 ++++++--
include/linux/leds.h | 1 +
2 files changed, 7 insertions(+), 2 deletions(-)

--
2.35.0