Pull backlight updates from Lee Jones:
"Framebuffer Subsystem (fbdev):
- The display's blanking status is now tracked in 'struct fb_info'
- 'framebuffer_alloc()' initializes the blank state to FB_BLANK_UNBLANK
- 'register_framebuffer()' sets the state to 'FB_BLANK_POWERDOWN' if
an 'fb_blank' callback exists, ensuring 'FB_EVENT_BLANK' listeners
correctly see the display being turned on during the first modeset
- The 'FB_EVENT_BLANK' event data now includes both the new and the
old blank states
- 'fb_blank()' has been reworked to return early on errors, without
functional changes, in preparation for further state tracking
improvements
- Fbdev now calls dedicated functions in the backlight subsystems to
notify them of blank state changes, instead of relying on fbdev
event notifiers
- For LCDs, fbdev also calls a dedicated function to notify of mode
changes
- Removed the definitions for the unused fbdev event constants
'FB_EVENT_MODE_CHANGE' and 'FB_EVENT_BLANK' from the header file
Backlight Subsystem:
- Implemented fbdev blank state tracking using the (newly enhanced)
blank state information provided directly by 'FB_EVENT_BLANK'
- Removed internal blank state tracking fields ('fb_bl_on') from
'struct backlight_device'
- Moved the handling of blank-state updates into a separate internal
helper function, 'backlight_notify_blank()'
- Removed support for fbdev events and replaced it with a dedicated
function call interface ('backlight_notify_blank()' and
'backlight_notify_blank_all()') for display drivers to update
backlight status
LCD Subsystem:
- Moved the handling of display updates (blank events and mode
changes) from fbdev event notifiers to separate internal helper
functions ('lcd_notify_blank',
'lcd_notify_mode_change')
- Removed support for fbdev events and replaced it with dedicated
function call interfaces ('lcd_notify_blank_all()',
'lcd_notify_mode_change_all()')
- The LCD subsystem now maintains its own internal list of LCD
devices instead of relying on fbdev notifiers
LED Backlight Trigger:
- Moved the handling of blank-state updates into a separate internal
helper, 'ledtrig_backlight_notify_blank()'
- Removed support for fbdev events and replaced it with a dedicated
function call, 'ledtrig_backlight_blank()', for fbdev to notify
trigger of blank state changes
- The LED backlight trigger now maintains its own internal list of
triggers instead of relying on fbdev notifiers
Qualcomm WLED Backlight:
- Added a NULL check after 'devm_kasprintf()' in 'wled_configure()'
to prevent a potential NULL pointer dereference if memory
allocation fails"
* tag 'backlight-next-6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight:
backlight: pm8941: Add NULL check in wled_configure()
fbdev: Remove constants of unused events
leds: backlight trigger: Replace fb events with a dedicated function call
leds: backlight trigger: Move blank-state handling into helper
backlight: lcd: Replace fb events with a dedicated function call
backlight: lcd: Move event handling into helpers
backlight: Replace fb events with a dedicated function call
backlight: Move blank-state handling into helper
backlight: Implement fbdev tracking with blank state from event
fbdev: Send old blank state in FB_EVENT_BLANK
fbdev: Track display blanking state
fbdev: Rework fb_blank()
The TPS61310/TPS61311 is a flash LED driver with I2C interface. Its power
stage is capable of supplying a maximum total current of roughly 1500mA.
The TPS6131x provides three constant-current sinks, capable of sinking up
to 2 x 400mA (LED1 and LED3) and 800mA (LED2) in flash mode. In torch mode
each sink (LED1, LED2, LED3) supports currents up to 175mA.
Signed-off-by: Matthias Fend <matthias.fend@emfend.at>
Link: https://lore.kernel.org/r/20250514-leds-tps6131x-v5-2-a4fb9e7f2c47@emfend.at
Signed-off-by: Lee Jones <lee@kernel.org>
This API allows providers to offer an specific LED to be looked-up by a
consumer. Consumers are then able to describe the aforementioned LED
and take a reference on it.
For convenience, we're testing both sides of the API in just one test
function here. In reality, both the provider and the consumer would be
logistically orthogonal.
CMD:
tools/testing/kunit/kunit.py run --kunitconfig drivers/leds
RESULTS:
[16:38:57] Configuring KUnit Kernel ...
[16:38:57] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=20
[16:39:02] Starting KUnit Kernel (1/1)...
[16:39:02] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[16:39:03] ===================== led (2 subtests) =====================
[16:39:03] [PASSED] led_test_class_register
[16:39:03] [PASSED] led_test_class_add_lookup_and_get
[16:39:03] ======================= [PASSED] led =======================
[16:39:03] ============================================================
[16:39:03] Testing complete. Ran 2 tests: passed: 2
[16:39:03] Elapsed time: 6.255s total, 0.001s configuring, 5.131s building, 1.106s running
Link: https://lore.kernel.org/r/20250501081918.3621432-3-lee@kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
Upon successful LED class device registration, it is expected that
certain attributes are filled out in pre-defined ways. For instance, if
provided, the .brightness_get() call-back should be called to populate
the class device 'brightness' attribute, 'max_brightness' should be
initialised as LED_FULL (at least until we can rid these pesky enums)
and the sysfs group should be created with the class device name
supplied by the caller.
If subsequent registrations take place that would result in name
conflicts, various outcomes are expected depending on which flags are
set. If LED_REJECT_NAME_CONFLICT is disabled, registration should
succeed resulting in an iteration on the provided name. Conversely, if
it's enabled, then registration is expected to fail outright.
We test for all of these scenarios here.
Link: https://lore.kernel.org/r/20250501081918.3621432-2-lee@kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
If a KUNIT_ASSERT_*() call ends up in an assertion, the test is marked
as a failure and the subsequent error checking is never executed, making
it superfluous. Remove it for simplicity and to avoid confusion.
Link: https://lore.kernel.org/r/20250501081918.3621432-1-lee@kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
This helps prevent mistakes like disable out of order in cleanup functions
and forgetting to free on error paths (as was done here).
This was the last thing the .remove() function did, so remove that too.
Signed-off-by: Andrew Davis <afd@ti.com>
Link: https://lore.kernel.org/r/20250407183555.409687-6-afd@ti.com
Signed-off-by: Lee Jones <lee@kernel.org>
GCC compiler (Debian 14.2.0-17) is not happy about printing
into a too short buffer (when build with `make W=1`):
drivers/leds/leds-pca955x.c:554:33: note: ‘snprintf’ output between 2 and 12 bytes into a destination of size 8
Indeed, the buffer size is chosen based on some assumptions,
while in general the assigned value might not fit (GCC can't
prove it does).
Fix this by changing the bits field in the struct pca955x_chipdef to u8,
with a positive side effect of the better memory footprint, and convert
loop iterator to be unsigned. With that done, update format specifiers
accordingly.
In one case join back string literal as it improves the grepping over the code
based on the message and remove duplicating information (the driver name is
printed as pert of the dev_*() output [1]) as we touch the same line anyway.
Link: https://lore.kernel.org/r/4ac527f2-c59e-70a2-efd4-da52370ea557@dave.eu/ [1]
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20250407151441.706378-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Lee Jones <lee@kernel.org>
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
getting ready to enable it, globally.
Replace an on-stack definition of a flexible structure with a call
to utility function cros_ec_cmd().
So, with these changes, fix the following warning:
drivers/leds/leds-cros_ec.c:70:40: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
Signed-off-by: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Acked-by: Thomas Weißschuh <linux@weissschuh.net>
Link: https://lore.kernel.org/r/Z-rKcgFjsyKvd58q@kspp
Signed-off-by: Lee Jones <lee@kernel.org>
GCC compiler complains about snprintf() calls that may potentially cut
the output:
drivers/leds/led-core.c:551:78: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=]
drivers/leds/led-core.c:554:78: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=]
...
Fix these by checking for the potential overflow. This requires
to align all the branches to use the same callee, i.e. snprintf(),
otherwise the code will be blown up and return different error codes
for the different branches.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20250318160524.2979982-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Lee Jones <lee@kernel.org>
Accept "default" written to sysfs trigger attr.
If the text "default" is written to the LED's sysfs 'trigger' attr, then
call led_trigger_set_default() to set the LED to its default trigger.
If the default trigger is set to "none", then led_trigger_set_default()
will remove a trigger. This is in contrast to the default trigger being
unset, in which case led_trigger_set_default() does nothing.
Signed-off-by: Craig McQueen <craig@mcqueen.au>
Reviewed-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Link: https://lore.kernel.org/r/20250317022630.424015-1-craig@mcqueen.au
Signed-off-by: Lee Jones <lee@kernel.org>
Remove support for fb events from the led backlight trigger. Provide
the helper ledtrig_backlight_blank() instead. Call it from fbdev to
inform the trigger of changes to a display's blank state.
Fbdev maintains a list of all installed notifiers. Instead of the fbdev
notifiers, maintain an internal list of led backlight triggers.
v3:
- export ledtrig_backlight_blank()
v2:
- maintain global list of led backlight triggers (Lee)
- avoid IS_REACHABLE() in source file (Lee)
- notify on changes to blank state instead of display state
- use lock guards
- initialize led list and list mutex
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Simona Vetter <simona.vetter@ffwll.ch>
Link: https://lore.kernel.org/r/20250321095517.313713-11-tzimmermann@suse.de
Signed-off-by: Lee Jones <lee@kernel.org>
timer_delete[_sync]() replaces del_timer[_sync](). Convert the whole tree
over and remove the historical wrapper inlines.
Conversion was done with coccinelle plus manual fixups where necessary.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Pull LED updates from Lee Jones:
- pca955x: Add HW blink support, utilizing PWM0. It supports one
frequency across all blinking LEDs and falls back to software blink
if different frequencies are requested.
- trigger: netdev: Allow configuring LED blink interval via .blink_set
even when HW offload (.hw_control) is enabled.
- led-core: Fix a race condition where a quick LED_OFF followed by
another brightness set could leave the LED off incorrectly,
especially noticeable after the introduction of the ordered
workqueue.
- qcom-lpg: Add support for 6-bit PWM resolution alongside the existing
9-bit support.
- qcom-lpg: Fix PWM value capping to respect the selected resolution
(6-bit or 9-bit) for normal PWMs.
- qcom-lpg: Fix PWM value capping to respect the selected resolution
for Hi-Res PWMs.
- qcom-lpg: Fix calculation of the best period for Hi-Res PWMs to
prevent requested duty cycles from exceeding the maximum allowed by
the selected resolution.
- st1202: Add a check for the error code returned by devm_mutex_init().
- pwm-multicolor: Add a check for the return value of
fwnode_property_read_u32().
- st1202: Ensure hardware initialization (st1202_setup) happens before
DT node processing (st1202_dt_init).
- Kconfig: leds-st1202: Add select LEDS_TRIGGER_PATTERN as it's
required by the driver.
- lp8860: Drop unneeded explicit assignment to REGCACHE_NONE.
- pca955x: Refactor code with helper functions and rename some
functions/variables for clarity.
- pca955x: Pass driver data pointers instead of the I2C client to
helper functions.
- pca955x: Optimize probe LED selection logic to reduce I2C operations.
- pca955x: Revert the removal of pca95xx_num_led_regs() (renaming it to
pca955x_num_led_regs) as it's needed for HW blink support.
- st1202: Refactor st1202_led_set() to use the !! operator for boolean
conversion.
- st1202: Minor spacing and proofreading edits in comments.
- Directory Rename: Rename the drivers/leds/simple directory to
drivers/leds/simatic as the drivers within are not simple.
- mlxcpld: Remove unused include of acpi.h.
- nic78bx: Tidy up the ACPI ID table (remove ACPI_PTR, use
mod_devicetable.h, remove explicit driver_data initializer).
- tlc591xx: Convert text binding to YAML format, add child node
constraints, and fix typos/formatting in the example.
- qcom-lpg: Document the qcom,pm8937-pwm compatible string as a
fallback for qcom,pm8916-pwm.
* tag 'leds-next-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (23 commits)
leds: nic78bx: Tidy up ACPI ID table
leds: mlxcpld: Remove unused ACPI header inclusion
leds: rgb: leds-qcom-lpg: Fix calculation of best period Hi-Res PWMs
leds: rgb: leds-qcom-lpg: Fix pwm resolution max for Hi-Res PWMs
leds: rgb: leds-qcom-lpg: Fix pwm resolution max for normal PWMs
leds: Rename simple directory to simatic
leds: Kconfig: leds-st1202: Add select for required LEDS_TRIGGER_PATTERN
leds: leds-st1202: Spacing and proofreading editing
leds: leds-st1202: Initialize hardware before DT node child operations
leds: pwm-multicolor: Add check for fwnode_property_read_u32
leds: rgb: leds-qcom-lpg: Add support for 6-bit PWM resolution
leds: Fix LED_OFF brightness race
Revert "leds-pca955x: Remove the unused function pca95xx_num_led_regs()"
leds: st1202: Refactor st1202_led_set() to use !! operator for boolean conversion
dt-bindings: leds: qcom-lpg: Document PM8937 PWM compatible
leds: pca955x: Add HW blink support
leds: pca955x: Optimize probe LED selection
leds: pca955x: Use pointers to driver data rather than I2C client
leds: pca955x: Refactor with helper functions and renaming
dt-bindings: leds: Convert leds-tlc591xx.txt to yaml format
...
Pull gpio updates from Bartosz Golaszewski:
"There are no new drivers this time but several changes to the core
GPIO framework and various driver updates.
This release cycle, we're starting a relatively straightforward but
tedious rework of the GPIO consumer API: for historical reasons, the
gpiod_set_value() variants would return void. Not only that but the
GPIO provider interface does not even allow drivers to return a value
to GPIO core. This is because initial GPIO controllers would be MMIO
based and could not fail. We've had I2C, SPI and USB controllers for
years too but no way of indicating failures to callers.
This changes the consumer interface, adds new provider callbacks and
starts converting the drivers under drivers/gpio/ to using them. Once
this gets upstream, we'll keep on converting GPIO drivers that live
elsewhere and once there are no more users of the old callbacks, we'll
remove them and rename the new ones to the previous name. I imagine
the last step would happen in one sweeping change like what you did
for the remove_new() -> remove() renaming.
We've also addressed an issue where invalid return values from GPIO
drivers would get propagated to user-space by adding some
GPIO-core-level sanitization. Again: not a complex change but way
overdue.
Other than that: lots of driver and core refactoring, DT-bindings
changes and some other minor changes like coding style fixes or header
reordering.
GPIO core:
- add sanitization of return values of GPIO provider callbacks so
that invalid ones don't get propagated to user-space
- add new variants of the line setter callbacks for GPIO providers
that return an integer and allow to indicate driver errors to the
GPIO core
- change the interface of all gpiod_set_value() variants to return an
integer thus becoming able to indicate failures in the underlying
layer to callers
- drop unneeded ERR_CAST in gpiolib-acpi
- use for_each_if() where applicable
- provide gpiod_multi_set_value_cansleep() as a new, simpler
interface to gpiod_set_array_value_cansleep() and use it across
several drivers treewide
- reduce the number of atomic reads of the descriptor flags in
gpiolib debugfs code
- simplify for_each_hwgpio_in_range() and
for_each_requested_gpio_in_range()
- add support for three-cell GPIO specifiers in GPIO OF code
- don't build HTE (hardware timestamp engine) GPIO code with the HTE
subsystem disabled in Kconfig
- unduplicate calls to gpiod_direction_input_nonotify()
- rework the handling of the valid_mask property of GPIO chips: don't
allow drivers to set it as it should only be handled by GPIO core
and start actually enforcing it in GPIO core for *all* drivers, not
only the ones implementing a custom request() callback
- get the `ngpios` property from the fwnode of the GPIO chip, not its
device in order to handle multi-bank GPIO chips
Driver improvements:
- convert a part of the GPIO drivers under drivers/gpio/ to using the
new value setter callbacks
- convert several drivers to using automatic lock guards from
cleanup.h
- allow building gpio-bt8xx with COMPILE_TEST=y
- refactor gpio-74x164 (use devres, cleanup helpers, __counted_by()
and bits.h macros)
- refactor gpio-latch (use generic device properties, lock guards and
some local variables for better readability)
- refactor gpio-xilinx (improve the usage of the bitmap API)
- support multiple virtual GPIO controller instances in gpio-virtio
- allow gpio-regmap to use the standard `ngpios` property from
GPIOLIB
- factor out the common code for synchronous probing of virtual GPIO
devices into its own library
- use str_enable_disable(), str_high_low() and other string helpers
where applicable
- extend the gpio-mmio abstraction layer to allow calling into the
pinctrl back-end when setting direction
- convert gpio-vf610 to using the gpio-mmio library
- use more devres in gpio-adnp
- add support for reset-gpios in gpio-pcf857x
- add support for more models to gpio-loongson-64bit
DT bindings:
- add new compatibles to gpio-vf610 and gpio-loongson
- add missing gpio-ranges property to gpio-mvebu
- add reset-gpios to nxp,pcf8575
- enable gpio-hog parsing in ast2400-gpio
Misc:
- coding style improvements
- kerneldoc fixes
- includes reordering
- updates to the TODO list"
* tag 'gpio-updates-for-v6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (119 commits)
gpio: TODO: add an item to track reworking the sysfs interface
gpio: TODO: add an item to track the conversion to the new value setters
gpio: TODO: add delimiters between tasks for better readability
gpio: TODO: remove the pinctrl integration task
gpio: TODO: remove task duplication
gpio: TODO: remove the item about the new debugfs interface
gpio: da9055: use new line value setter callbacks
gpio: da9052: use new line value setter callbacks
gpio: cs5535: use new line value setter callbacks
gpio: crystalcove: use new line value setter callbacks
gpio: cros-ec: use new line value setter callbacks
gpio: creg-snps: use new line value setter callbacks
gpio: cgbc: use new line value setter callbacks
gpio: bt8xx: use new line value setter callbacks
gpio: bt8xx: use lock guards
gpio: bt8xx: allow to build the module with COMPILE_TEST=y
gpio: bd9571mwv: use new line value setter callbacks
gpio: bd71828: use new line value setter callbacks
gpio: bd71815: use new line value setter callbacks
gpio: bcm-kona: use new line value setter callbacks
...
Pull timer cleanups from Thomas Gleixner:
"A treewide hrtimer timer cleanup
hrtimers are initialized with hrtimer_init() and a subsequent store to
the callback pointer. This turned out to be suboptimal for the
upcoming Rust integration and is obviously a silly implementation to
begin with.
This cleanup replaces the hrtimer_init(T); T->function = cb; sequence
with hrtimer_setup(T, cb);
The conversion was done with Coccinelle and a few manual fixups.
Once the conversion has completely landed in mainline, hrtimer_init()
will be removed and the hrtimer::function becomes a private member"
* tag 'timers-cleanups-2025-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (100 commits)
wifi: rt2x00: Switch to use hrtimer_update_function()
io_uring: Use helper function hrtimer_update_function()
serial: xilinx_uartps: Use helper function hrtimer_update_function()
ASoC: fsl: imx-pcm-fiq: Switch to use hrtimer_setup()
RDMA: Switch to use hrtimer_setup()
virtio: mem: Switch to use hrtimer_setup()
drm/vmwgfx: Switch to use hrtimer_setup()
drm/xe/oa: Switch to use hrtimer_setup()
drm/vkms: Switch to use hrtimer_setup()
drm/msm: Switch to use hrtimer_setup()
drm/i915/request: Switch to use hrtimer_setup()
drm/i915/uncore: Switch to use hrtimer_setup()
drm/i915/pmu: Switch to use hrtimer_setup()
drm/i915/perf: Switch to use hrtimer_setup()
drm/i915/gvt: Switch to use hrtimer_setup()
drm/i915/huc: Switch to use hrtimer_setup()
drm/amdgpu: Switch to use hrtimer_setup()
stm class: heartbeat: Switch to use hrtimer_setup()
i2c: Switch to use hrtimer_setup()
iio: Switch to use hrtimer_setup()
...
When determining the actual best period by looping through all
possible PWM configs, the resolution currently used is based on
bit shift value which is off-by-one above the possible maximum
PWM value allowed.
So subtract one from the resolution before determining the best
period so that the maximum duty cycle requested by the PWM user
won't result in a value above the maximum allowed by the selected
resolution.
Cc: stable@vger.kernel.org # 6.4
Fixes: b00d2ed376 ("leds: rgb: leds-qcom-lpg: Add support for high resolution PWM")
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Link: https://lore.kernel.org/r/20250305-leds-qcom-lpg-fix-max-pwm-on-hi-res-v4-3-bfe124a53a9f@linaro.org
Signed-off-by: Lee Jones <lee@kernel.org>
Ideally, the requested duty cycle should never translate to a PWM
value higher than the selected resolution (PWM size), but currently the
best matched period is never reported back to the PWM consumer, so the
consumer will still be using the requested period which is higher than
the best matched one. This will result in PWM consumer requesting
duty cycle values higher than the allowed PWM value.
For example, a consumer might request a period of 5ms while the best
(closest) period the PWM hardware will do is 4.26ms. For this best
matched resolution, if the selected resolution is 8-bit wide, when
the consumer asks for a duty cycle of 5ms, the PWM value will be 300,
which is outside of what the resolution allows. This will happen with
all possible resolutions when selected.
Since for these Hi-Res PWMs, the current implementation is capping the PWM
value at a 15-bit resolution, even when lower resolutions are selected,
the value will be wrapped around by the HW internal logic to the selected
resolution.
Fix the issue by capping the PWM value to the maximum value allowed by
the selected resolution.
Cc: stable@vger.kernel.org # 6.4
Fixes: b00d2ed376 ("leds: rgb: leds-qcom-lpg: Add support for high resolution PWM")
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Link: https://lore.kernel.org/r/20250305-leds-qcom-lpg-fix-max-pwm-on-hi-res-v4-2-bfe124a53a9f@linaro.org
Signed-off-by: Lee Jones <lee@kernel.org>
Ideally, the requested duty cycle should never translate to a PWM
value higher than the selected resolution (PWM size), but currently the
best matched period is never reported back to the PWM consumer, so the
consumer will still be using the requested period which is higher than
the best matched one. This will result in PWM consumer requesting
duty cycle values higher than the allowed PWM value.
For example, a consumer might request a period of 5ms while the best
(closest) period the PWM hardware will do is 4.26ms. For this best
matched resolution, if the selected resolution is 9-bit wide, when
the consumer asks for a duty cycle of 5ms, the PWM value will be 600,
which is outside of what the resolution allows. Similar will happen
if the 6-bit resolution is selected.
Since for these normal PWMs (non Hi-Res), the current implementation is
capping the PWM value at a 9-bit resolution, even when the 6-bit
resolution is selected, the value will be wrapped around to 6-bit value
by the HW internal logic.
Fix the issue by capping the PWM value to the maximum value allowed by
the selected resolution.
Fixes: 7a3350495d ("leds: rgb: leds-qcom-lpg: Add support for 6-bit PWM resolution")
Suggested-by: Anjelique Melendez <anjelique.melendez@oss.qualcomm.com>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Link: https://lore.kernel.org/r/20250305-leds-qcom-lpg-fix-max-pwm-on-hi-res-v4-1-bfe124a53a9f@linaro.org
Signed-off-by: Lee Jones <lee@kernel.org>
leds-st1202 requires the LED Pattern Trigger (LEDS_TRIGGER_PATTERN), which
is not selected when LED Trigger support is (LEDS_TRIGGERS).
To reproduce this:
- make menuconfig KCONFIG_CONFIG=
- select LEDS_ST1202 dependencies OF, I2C and LEDS_CLASS.
- select LEDS_ST1202
- LEDS_TRIGGERS is selected but LEDS_TRIGGER_PATTERN isn't.
The absence of LEDS_TRIGGER_PATTERN explicitly required can lead to builds
in which LEDS_ST1202 is selected while LEDS_TRIGGER_PATTERN isn't. The direct
result of that would be that /sys/class/leds/<led>/hw_pattern wouldn't be
available and there would be no way of interacting with the driver and
hardware from user space.
Add select LEDS_TRIGGER_PATTERN to Kconfig to meet the requirement and
indirectly document it as well.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Link: https://lore.kernel.org/r/CWLP123MB5473F4DF3A668F7DD057A280C5C22@CWLP123MB5473.GBRP123.PROD.OUTLOOK.COM
Signed-off-by: Lee Jones <lee@kernel.org>
Arguably, there are more chances of errors occurring during the
initialization of the hardware, so this should complete successfully
before the devicetree node's children are initialized.
st1202_dt_init() fills the led_classdev struct.
st1202_setup() initializes the hardware. Specifically, resets the chip,
enables its phase-shift delay feature, enables the device and disables all
the LEDs channels. All that writing to registers, with no input from
st1202_dt_init().
Real-world testing corroborates that calling st1202_setup() before
st1202_dt_init() doesn't cause any issue during initialization.
Switch the order of st1202_dt_init() and st1202_setup() to ensure the
hardware is correctly initialized before the led_classdev struct is
filled.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Link: https://lore.kernel.org/r/CWLP123MB54731877A8DC54EDD33F0229C5C22@CWLP123MB5473.GBRP123.PROD.OUTLOOK.COM
Signed-off-by: Lee Jones <lee@kernel.org>
st1202_dt_init() calls devm_led_classdev_register_ext() before the
internal data structures are properly set up, so the LEDs become visible
to user space while being partially initialized, leading to a window
where trying to access them causes a NULL pointer access.
Move devm_led_classdev_register_ext() from DT initialization
to the end of the probe function when DT and hardware are fully
initialized and ready to interact with user space.
Fixes: 259230378c ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Link: https://lore.kernel.org/r/CWLP123MB54732771AC0CE5491B3C84DCC5C32@CWLP123MB5473.GBRP123.PROD.OUTLOOK.COM
Signed-off-by: Lee Jones <lee@kernel.org>
While commit fa15d8c692 ("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 32360bf6a5 ("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: fa15d8c692 ("leds: Fix set_brightness_delayed() race")
Signed-off-by: Remi Pommarel <repk@triplefau.lt>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/19c81177059dab7b656c42063958011a8e4d1a66.1740050412.git.repk@triplefau.lt
Signed-off-by: Lee Jones <lee@kernel.org>