Patch "led: qcom-lpg: Fix sleeping in atomic" has been added to the 6.0-stable tree

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

 



This is a note to let you know that I've just added the patch titled

    led: qcom-lpg: Fix sleeping in atomic

to the 6.0-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     led-qcom-lpg-fix-sleeping-in-atomic.patch
and it can be found in the queue-6.0 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 75db3cb70eae5f3ce8ccd11671d3179f0b43e379
Author: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx>
Date:   Fri Oct 21 22:19:40 2022 +0300

    led: qcom-lpg: Fix sleeping in atomic
    
    [ Upstream commit 3031993b3474794ecb71b6f969a3e60e4bda9d8a ]
    
    lpg_brighness_set() function can sleep, while led's brightness_set()
    callback must be non-blocking. Change LPG driver to use
    brightness_set_blocking() instead.
    
    BUG: sleeping function called from invalid context at kernel/locking/mutex.c:580
    in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/0
    preempt_count: 101, expected: 0
    INFO: lockdep is turned off.
    CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W          6.1.0-rc1-00014-gbe99b089c6fc-dirty #85
    Hardware name: Qualcomm Technologies, Inc. DB820c (DT)
    Call trace:
     dump_backtrace.part.0+0xe4/0xf0
     show_stack+0x18/0x40
     dump_stack_lvl+0x88/0xb4
     dump_stack+0x18/0x34
     __might_resched+0x170/0x254
     __might_sleep+0x48/0x9c
     __mutex_lock+0x4c/0x400
     mutex_lock_nested+0x2c/0x40
     lpg_brightness_single_set+0x40/0x90
     led_set_brightness_nosleep+0x34/0x60
     led_heartbeat_function+0x80/0x170
     call_timer_fn+0xb8/0x340
     __run_timers.part.0+0x20c/0x254
     run_timer_softirq+0x3c/0x7c
     _stext+0x14c/0x578
     ____do_softirq+0x10/0x20
     call_on_irq_stack+0x2c/0x5c
     do_softirq_own_stack+0x1c/0x30
     __irq_exit_rcu+0x164/0x170
     irq_exit_rcu+0x10/0x40
     el1_interrupt+0x38/0x50
     el1h_64_irq_handler+0x18/0x2c
     el1h_64_irq+0x64/0x68
     cpuidle_enter_state+0xc8/0x380
     cpuidle_enter+0x38/0x50
     do_idle+0x244/0x2d0
     cpu_startup_entry+0x24/0x30
     rest_init+0x128/0x1a0
     arch_post_acpi_subsys_init+0x0/0x18
     start_kernel+0x6f4/0x734
     __primary_switched+0xbc/0xc4
    
    Fixes: 24e2d05d1b68 ("leds: Add driver for Qualcomm LPG")
    Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx>
    Signed-off-by: Pavel Machek <pavel@xxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
index 02f51cc61837..c1a56259226f 100644
--- a/drivers/leds/rgb/leds-qcom-lpg.c
+++ b/drivers/leds/rgb/leds-qcom-lpg.c
@@ -602,8 +602,8 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
 		lpg_lut_sync(lpg, lut_mask);
 }
 
-static void lpg_brightness_single_set(struct led_classdev *cdev,
-				      enum led_brightness value)
+static int lpg_brightness_single_set(struct led_classdev *cdev,
+				     enum led_brightness value)
 {
 	struct lpg_led *led = container_of(cdev, struct lpg_led, cdev);
 	struct mc_subled info;
@@ -614,10 +614,12 @@ static void lpg_brightness_single_set(struct led_classdev *cdev,
 	lpg_brightness_set(led, cdev, &info);
 
 	mutex_unlock(&led->lpg->lock);
+
+	return 0;
 }
 
-static void lpg_brightness_mc_set(struct led_classdev *cdev,
-				  enum led_brightness value)
+static int lpg_brightness_mc_set(struct led_classdev *cdev,
+				 enum led_brightness value)
 {
 	struct led_classdev_mc *mc = lcdev_to_mccdev(cdev);
 	struct lpg_led *led = container_of(mc, struct lpg_led, mcdev);
@@ -628,6 +630,8 @@ static void lpg_brightness_mc_set(struct led_classdev *cdev,
 	lpg_brightness_set(led, cdev, mc->subled_info);
 
 	mutex_unlock(&led->lpg->lock);
+
+	return 0;
 }
 
 static int lpg_blink_set(struct lpg_led *led,
@@ -1118,7 +1122,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
 		led->mcdev.num_colors = num_channels;
 
 		cdev = &led->mcdev.led_cdev;
-		cdev->brightness_set = lpg_brightness_mc_set;
+		cdev->brightness_set_blocking = lpg_brightness_mc_set;
 		cdev->blink_set = lpg_blink_mc_set;
 
 		/* Register pattern accessors only if we have a LUT block */
@@ -1132,7 +1136,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
 			return ret;
 
 		cdev = &led->cdev;
-		cdev->brightness_set = lpg_brightness_single_set;
+		cdev->brightness_set_blocking = lpg_brightness_single_set;
 		cdev->blink_set = lpg_blink_single_set;
 
 		/* Register pattern accessors only if we have a LUT block */
@@ -1151,7 +1155,7 @@ static int lpg_add_led(struct lpg *lpg, struct device_node *np)
 	else
 		cdev->brightness = LED_OFF;
 
-	cdev->brightness_set(cdev, cdev->brightness);
+	cdev->brightness_set_blocking(cdev, cdev->brightness);
 
 	init_data.fwnode = of_fwnode_handle(np);
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux