diff mbox series

[RFC,v1,1/1] leds: support to use own workqueue for each LED

Message ID 33d05330-7c52-e873-bf32-209d40c77632@sberdevices.ru
State New
Headers show
Series [RFC,v1,1/1] leds: support to use own workqueue for each LED | expand

Commit Message

Arseniy Krasnov Oct. 30, 2022, 6:07 a.m. UTC
This allows to set own workqueue for each LED. This may be useful, because
default 'system_wq' does not guarantee execution order of each work_struct,
thus for several brightness update requests (for multiple leds), real
brightness switch could be in random order.

Signed-off-by: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
---
 drivers/leds/led-core.c | 8 ++++++--
 include/linux/leds.h    | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

Comments

Pavel Machek Oct. 30, 2022, 12:20 p.m. UTC | #1
On Sun 2022-10-30 06:07:05, Arseniy Krasnov wrote:
> This allows to set own workqueue for each LED. This may be useful, because
> default 'system_wq' does not guarantee execution order of each work_struct,
> thus for several brightness update requests (for multiple leds), real
> brightness switch could be in random order.

So.. what?

Even if execution order is switched, human eye will not be able to
tell the difference.
								Pavel
diff mbox series

Patch

diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 4a97cb745788..e8ecf332793a 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -188,6 +188,9 @@  static void led_blink_setup(struct led_classdev *led_cdev,
 
 void led_init_core(struct led_classdev *led_cdev)
 {
+	if (!led_cdev->set_brightness_wq)
+		led_cdev->set_brightness_wq = system_wq;
+
 	INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
 
 	timer_setup(&led_cdev->blink_timer, led_timer_function, 0);
@@ -252,7 +255,8 @@  void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness)
 		 */
 		if (!brightness) {
 			set_bit(LED_BLINK_DISABLE, &led_cdev->work_flags);
-			schedule_work(&led_cdev->set_brightness_work);
+			queue_work(led_cdev->set_brightness_wq,
+				   &led_cdev->set_brightness_work);
 		} else {
 			set_bit(LED_BLINK_BRIGHTNESS_CHANGE,
 				&led_cdev->work_flags);
@@ -273,7 +277,7 @@  void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value)
 
 	/* If brightness setting can sleep, delegate it to a work queue task */
 	led_cdev->delayed_set_value = value;
-	schedule_work(&led_cdev->set_brightness_work);
+	queue_work(led_cdev->set_brightness_wq, &led_cdev->set_brightness_work);
 }
 EXPORT_SYMBOL_GPL(led_set_brightness_nopm);
 
diff --git a/include/linux/leds.h b/include/linux/leds.h
index ba4861ec73d3..1121bae21fed 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -140,6 +140,7 @@  struct led_classdev {
 	void			(*flash_resume)(struct led_classdev *led_cdev);
 
 	struct work_struct	set_brightness_work;
+	struct workqueue_struct *set_brightness_wq;
 	int			delayed_set_value;
 
 #ifdef CONFIG_LEDS_TRIGGERS