<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/drivers/leds/led-core.c, branch v6.6.141</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v6.6.141</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v6.6.141'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2025-04-10T12:37:32+00:00</updated>
<entry>
<title>leds: Fix LED_OFF brightness race</title>
<updated>2025-04-10T12:37:32+00:00</updated>
<author>
<name>Remi Pommarel</name>
<email>repk@triplefau.lt</email>
</author>
<published>2025-02-20T11:23:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=966fdfc45373b7d55ff1a47a25e623f01e4c802a'/>
<id>urn:sha1:966fdfc45373b7d55ff1a47a25e623f01e4c802a</id>
<content type='text'>
[ Upstream commit 2c70953b6f535f7698ccbf22c1f5ba26cb6c2816 ]

While commit fa15d8c69238 ("leds: Fix set_brightness_delayed() race")
successfully forces led_set_brightness() to be called with LED_OFF at
least once when switching from blinking to LED on state so that
hw-blinking can be disabled, another race remains. Indeed in
led_set_brightness(LED_OFF) followed by led_set_brightness(any)
scenario the following CPU scheduling can happen:

    CPU0                                     CPU1
    ----                                     ----
 set_brightness_delayed() {
   test_and_clear_bit(BRIGHTNESS_OFF)
                                         led_set_brightness(LED_OFF) {
                                           set_bit(BRIGHTNESS_OFF)
					   queue_work()
                                         }
                                         led_set_brightness(any) {
                                           set_bit(BRIGHTNESS)
					   queue_work() //already queued
                                         }
   test_and_clear_bit(BRIGHTNESS)
     /* LED set with brightness any */
 }

 /* From previous CPU1 queue_work() */
 set_brightness_delayed() {
   test_and_clear_bit(BRIGHTNESS_OFF)
     /* LED turned off */
   test_and_clear_bit(BRIGHTNESS)
     /* Clear from previous run, LED remains off */

In that case the led_set_brightness(LED_OFF)/led_set_brightness(any)
sequence will be effectively executed in reverse order and LED will
remain off.

With the introduction of commit 32360bf6a5d4 ("leds: Introduce ordered
workqueue for LEDs events instead of system_wq") the race is easier to
trigger as sysfs brightness configuration does not wait for
set_brightness_delayed() work to finish (flush_work() removal).

Use delayed_set_value to optionnally re-configure brightness after a
LED_OFF. That way a LED state could be configured more that once but
final state will always be as expected. Ensure that delayed_set_value
modification is seen before set_bit() using smp_mb__before_atomic().

Fixes: fa15d8c69238 ("leds: Fix set_brightness_delayed() race")
Signed-off-by: Remi Pommarel &lt;repk@triplefau.lt&gt;
Reviewed-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
Link: https://lore.kernel.org/r/19c81177059dab7b656c42063958011a8e4d1a66.1740050412.git.repk@triplefau.lt
Signed-off-by: Lee Jones &lt;lee@kernel.org&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>leds: Drop BUG_ON check for LED_COLOR_ID_MULTI</title>
<updated>2023-09-19T14:16:23+00:00</updated>
<author>
<name>Marek Behún</name>
<email>kabel@kernel.org</email>
</author>
<published>2023-09-18T14:07:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=9dc1664fab2246bc2c3e9bf2cf21518a857f9b5b'/>
<id>urn:sha1:9dc1664fab2246bc2c3e9bf2cf21518a857f9b5b</id>
<content type='text'>
Commit c3f853184bed ("leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that
is always false") fixed a no-op BUG_ON. This turned out to cause a
regression, since some in-tree device-tree files already use
LED_COLOR_ID_MULTI.

Drop the BUG_ON altogether.

Fixes: c3f853184bed ("leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that is always false")
Reported-by: Da Xue &lt;da@libre.computer&gt;
Closes: https://lore.kernel.org/linux-leds/ZQLelWcNjjp2xndY@duo.ucw.cz/T/
Signed-off-by: Marek Behún &lt;kabel@kernel.org&gt;
Link: https://lore.kernel.org/r/20230918140724.18634-1-kabel@kernel.org
Signed-off-by: Lee Jones &lt;lee@kernel.org&gt;
</content>
</entry>
<entry>
<title>leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that is always false</title>
<updated>2023-08-17T10:26:36+00:00</updated>
<author>
<name>Marek Behún</name>
<email>kabel@kernel.org</email>
</author>
<published>2023-08-01T15:16:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c3f853184bed04105682383c2971798c572226b5'/>
<id>urn:sha1:c3f853184bed04105682383c2971798c572226b5</id>
<content type='text'>
At the time we call
    BUG_ON(props.color == LED_COLOR_ID_MULTI);
the props variable is still initialized to zero.

Call the BUG_ON only after we parse fwnode into props.

Fixes: 77dce3a22e89 ("leds: disallow /sys/class/leds/*:multi:* for now")
Signed-off-by: Marek Behún &lt;kabel@kernel.org&gt;
Link: https://lore.kernel.org/r/20230801151623.30387-1-kabel@kernel.org
Signed-off-by: Lee Jones &lt;lee@kernel.org&gt;
</content>
</entry>
<entry>
<title>leds: Fix oops about sleeping in led_trigger_blink()</title>
<updated>2023-05-25T11:16:31+00:00</updated>
<author>
<name>Hans de Goede</name>
<email>hdegoede@redhat.com</email>
</author>
<published>2023-05-10T16:22:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=22720a87d0a9667c003bcffd38d15228b3a40f8c'/>
<id>urn:sha1:22720a87d0a9667c003bcffd38d15228b3a40f8c</id>
<content type='text'>
led_trigger_blink() calls led_blink_set() from a RCU read-side critical
section so led_blink_set() must not sleep. Note sleeping was not allowed
before the switch to RCU either because a spinlock was held before.

led_blink_set() does not sleep when sw-blinking is used, but
many LED controller drivers with hw blink support have a blink_set
function which may sleep, leading to an oops like this one:

[  832.605062] ------------[ cut here ]------------
[  832.605085] Voluntary context switch within RCU read-side critical section!
[  832.605119] WARNING: CPU: 2 PID: 370 at kernel/rcu/tree_plugin.h:318 rcu_note_context_switch+0x4ee/0x690
&lt;snip&gt;
[  832.606453] Call Trace:
[  832.606466]  &lt;TASK&gt;
[  832.606487]  __schedule+0x9f/0x1480
[  832.606527]  schedule+0x5d/0xe0
[  832.606549]  schedule_timeout+0x79/0x140
[  832.606572]  ? __pfx_process_timeout+0x10/0x10
[  832.606599]  wait_for_completion_timeout+0x6f/0x140
[  832.606627]  i2c_dw_xfer+0x101/0x460
[  832.606659]  ? psi_group_change+0x168/0x400
[  832.606680]  __i2c_transfer+0x172/0x6d0
[  832.606709]  i2c_smbus_xfer_emulated+0x27d/0x9c0
[  832.606732]  ? __schedule+0x430/0x1480
[  832.606753]  ? preempt_count_add+0x6a/0xa0
[  832.606778]  ? get_nohz_timer_target+0x18/0x190
[  832.606796]  ? lock_timer_base+0x61/0x80
[  832.606817]  ? preempt_count_add+0x6a/0xa0
[  832.606842]  __i2c_smbus_xfer+0xa2/0x3f0
[  832.606862]  i2c_smbus_xfer+0x66/0xf0
[  832.606882]  i2c_smbus_read_byte_data+0x41/0x70
[  832.606901]  ? _raw_spin_unlock_irqrestore+0x23/0x40
[  832.606922]  ? __pm_runtime_suspend+0x46/0xc0
[  832.606946]  cht_wc_byte_reg_read+0x2e/0x60
[  832.606972]  _regmap_read+0x5c/0x120
[  832.606997]  _regmap_update_bits+0x96/0xc0
[  832.607023]  regmap_update_bits_base+0x5b/0x90
[  832.607053]  cht_wc_leds_brightness_get+0x412/0x910 [leds_cht_wcove]
[  832.607094]  led_blink_setup+0x28/0x100
[  832.607119]  led_trigger_blink+0x40/0x70
[  832.607145]  power_supply_update_leds+0x1b7/0x1c0
[  832.607174]  power_supply_changed_work+0x67/0xe0
[  832.607198]  process_one_work+0x1c8/0x3c0
[  832.607222]  worker_thread+0x4d/0x380
[  832.607243]  ? __pfx_worker_thread+0x10/0x10
[  832.607258]  kthread+0xe9/0x110
[  832.607279]  ? __pfx_kthread+0x10/0x10
[  832.607300]  ret_from_fork+0x2c/0x50
[  832.607337]  &lt;/TASK&gt;
[  832.607344] ---[ end trace 0000000000000000 ]---

Add a new led_blink_set_nosleep() function which defers the actual
led_blink_set() call to a workqueue when necessary to fix this.

This also fixes an existing race where a pending led_set_brightness() has
been deferred to set_brightness_work and might then race with a later
led_cdev-&gt;blink_set() call. Note this race is only an issue with triggers
mixing led_trigger_event() and led_trigger_blink() calls, sysfs API
calls and led_trigger_blink_oneshot() are not affected.

Note rather then adding a separate blink_set_blocking callback this uses
the presence of the already existing brightness_set_blocking callback to
detect if the blinking call should be deferred to set_brightness_work.

Signed-off-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
Reviewed-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
Tested-by: Yauhen Kharuzhy &lt;jekhor@gmail.com&gt;
Link: https://lore.kernel.org/r/20230510162234.291439-4-hdegoede@redhat.com
Signed-off-by: Lee Jones &lt;lee@kernel.org&gt;
</content>
</entry>
<entry>
<title>leds: Fix set_brightness_delayed() race</title>
<updated>2023-05-25T11:16:30+00:00</updated>
<author>
<name>Hans de Goede</name>
<email>hdegoede@redhat.com</email>
</author>
<published>2023-05-10T16:22:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=fa15d8c69238b352cc143cb9d8f2ca4594b94022'/>
<id>urn:sha1:fa15d8c69238b352cc143cb9d8f2ca4594b94022</id>
<content type='text'>
When a trigger wants to switch from blinking to LED on it needs to call:
	led_set_brightness(LED_OFF);
	led_set_brightness(LED_FULL);

To first call disables blinking and the second then turns the LED on
(the power-supply charging-blink-full-solid triggers do this).

These calls happen immediately after each other, so it is possible
that set_brightness_delayed() from the first call has not run yet
when the led_set_brightness(LED_FULL) call finishes.

If this race hits then this is causing problems for both
sw- and hw-blinking:

For sw-blinking set_brightness_delayed() clears delayed_set_value
when LED_BLINK_DISABLE is set causing the led_set_brightness(LED_FULL)
call effects to get lost when hitting the race, resulting in the LED
turning off instead of on.

For hw-blinking if the race hits delayed_set_value has been
set to LED_FULL by the time set_brightness_delayed() runs.
So led_cdev-&gt;brightness_set_blocking() is never called with
LED_OFF as argument and the hw-blinking is never disabled leaving
the LED blinking instead of on.

Fix both issues by adding LED_SET_BRIGHTNESS and LED_SET_BRIGHTNESS_OFF
work_flags making this 2 separate actions to be run by
set_brightness_delayed().

Signed-off-by: Hans de Goede &lt;hdegoede@redhat.com&gt;
Reviewed-by: Jacek Anaszewski &lt;jacek.anaszewski@gmail.com&gt;
Tested-by: Yauhen Kharuzhy &lt;jekhor@gmail.com&gt;
Link: https://lore.kernel.org/r/20230510162234.291439-3-hdegoede@redhat.com
Signed-off-by: Lee Jones &lt;lee@kernel.org&gt;
</content>
</entry>
<entry>
<title>leds: move default_state read from fwnode to core</title>
<updated>2021-08-18T06:27:30+00:00</updated>
<author>
<name>Denis Osterland-Heim</name>
<email>Denis.Osterland@diehl.com</email>
</author>
<published>2021-06-08T06:35:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=791bc41163c51f870972d6c6b82d971ce951096c'/>
<id>urn:sha1:791bc41163c51f870972d6c6b82d971ce951096c</id>
<content type='text'>
This patch introduces a new function to read initial
default_state from fwnode.

Suggested-by: Pavel Machek &lt;pavel@ucw.cz&gt;
Signed-off-by: Denis Osterland-Heim &lt;Denis.Osterland@diehl.com&gt;
Signed-off-by: Pavel Machek &lt;pavel@ucw.cz&gt;
</content>
</entry>
<entry>
<title>leds: led-core: Get rid of enum led_brightness</title>
<updated>2021-02-19T10:35:28+00:00</updated>
<author>
<name>Abanoub Sameh</name>
<email>abanoubsameh8@gmail.com</email>
</author>
<published>2020-12-11T20:42:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=af0bfab907a011e146304d20d81dddce4e4d62d0'/>
<id>urn:sha1:af0bfab907a011e146304d20d81dddce4e4d62d0</id>
<content type='text'>
This gets rid of enum led_brightness in the main led files,
because it is deprecated, and an unsigned int can be used instead.

We can get rid of led_brightness completely and
patches can also be supplied for the other drivers' files.

Signed-off-by: Abanoub Sameh &lt;abanoubsameh@protonmail.com&gt;
Signed-off-by: Pavel Machek &lt;pavel@ucw.cz&gt;
</content>
</entry>
<entry>
<title>leds: disallow /sys/class/leds/*:multi:* for now</title>
<updated>2020-08-03T12:00:06+00:00</updated>
<author>
<name>Pavel Machek</name>
<email>pavel@ucw.cz</email>
</author>
<published>2020-08-03T12:00:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=77dce3a22e8941552a15046d4113df9ce132fb3d'/>
<id>urn:sha1:77dce3a22e8941552a15046d4113df9ce132fb3d</id>
<content type='text'>
All the LEDs in the queue are RGB, so they should not use multi for
their color.

Make sure we don't add such LED by mistake (and make it part of ABI).

Signed-off-by: Pavel Machek &lt;pavel@ucw.cz&gt;
</content>
</entry>
<entry>
<title>leds: add RGB color option, as that is different from multicolor.</title>
<updated>2020-08-03T11:26:15+00:00</updated>
<author>
<name>Pavel Machek</name>
<email>pavel@ucw.cz</email>
</author>
<published>2020-08-03T11:20:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=54212f5a1ba3123281877e54c1e5f672bf7563d8'/>
<id>urn:sha1:54212f5a1ba3123281877e54c1e5f672bf7563d8</id>
<content type='text'>
Multicolor is a bit too abstract. Yes, we can have
Green-Magenta-Ultraviolet LED, but so far all the LEDs we support are
RGB, and not even RGB-White or RGB-Yellow variants emerged.

Multicolor is not a good fit for RGB LED. It does not really know
about LED color.  In particular, there's no way to make LED "white".

Userspace is interested in knowing "this LED can produce arbitrary
color", which not all multicolor LEDs can.

Signed-off-by: Pavel Machek &lt;pavel@ucw.cz&gt;
</content>
</entry>
<entry>
<title>leds: Add multicolor ID to the color ID list</title>
<updated>2020-07-15T17:33:16+00:00</updated>
<author>
<name>Dan Murphy</name>
<email>dmurphy@ti.com</email>
</author>
<published>2020-07-13T15:45:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=10d3e0d815879129e916cd83e1034438e06efdaa'/>
<id>urn:sha1:10d3e0d815879129e916cd83e1034438e06efdaa</id>
<content type='text'>
Add a new color ID that is declared as MULTICOLOR as with the
multicolor framework declaring a definitive color is not accurate
as the node can contain multiple colors.

Signed-off-by: Dan Murphy &lt;dmurphy@ti.com&gt;
Reviewed-by: Marek Behún &lt;marek.behun@nic.cz&gt;
Signed-off-by: Pavel Machek &lt;pavel@ucw.cz&gt;
</content>
</entry>
</feed>
