| Age | Commit message (Collapse) | Author |
|
# Conflicts:
# drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
# net/ceph/osd_client.c
|
|
https://git.kernel.org/pub/scm/linux/kernel/git/lee/leds.git
|
|
Some hardware can autonomously activate/deactivate hardware control.
After that, the LED hardware notifies the LED driver. Currently, there
is no mechanism for LED drivers to notify the LED core about such events
and initiate a trigger transition to reflect the hardware state.
Add a new interface called led_trigger_notify_hw_control_changed(), so
that LED drivers can call it to notify the LED core about the
transition.
The interface only allows two transitions:
1. "none" => private trigger
2. private trigger => "none"
If the current trigger is neither the private trigger nor "none", no
transition will be made. This protects the currently selected software
trigger.
Note that LED_OFF won't be emitted during the #2 transition, as some
hardware may have selected a new brightness level during its hardware
state transition (e.g., laptop keyboards with a shortcut cycling through
different backlight brightnesses and auto mode).
The interface is designed as a void function as any failure should be
non-fatal and the result of transition should not have any impact on the
LED drivers' event handling procedures.
To use the interface, the config LEDS_TRIGGERS_HW_CHANGED must be
enabled, and the LED driver must set the LED_TRIG_HW_CHANGED flag for
the classdev.
By default, the config is enabled when LEDS_BRIGHTNESS_HW_CHANGED is
enabled.
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-10-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
With all existing triggers adopting the new interface, strict checks
could be enforced to make the semantics of hardware control triggers
clearer.
In detail, a hardware control trigger should:
- Implement hw_offloaded() callback to indicate hardware control
- Associate with the LED classdev's hw_control_trigger string
The fallback path is kept, but a warning message is emitted when it
reaches there.
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-9-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
"netdev" can run in hardware control according to hardware capabilities
and trigger options.
Implement hw_offloaded() callback to provide its hardware control state
to the LED core, and document the relation between the custom
"offloaded" attribute and the generic "trigger_may_offload_to_hw"
attribute.
The callback mimics how the existing "offloaded" attribute does, i.e.,
locklessly reads hw_control, as it's just a hint and don't need to be
accurate.
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-8-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
hw_control_trigger
"omnia-mcu" is a private hardware control trigger which always stays in
hardware control mode. Implement hw_offloaded() callback with its return
value to be always true to reflect this.
Meanwhile, declare it as a hardware control trigger as it's forgotten
before.
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-7-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
"chromeos-auto" is a private hardware control trigger which always stays
in hardware control. Implement hw_offloaded() callback with its return
value to be always true to reflect this.
Reviewed-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-6-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
trigger_may_offload_to_hw attribute
There are multiple triggers implementing hardware control. However, the
LED trigger core doesn't really know the hardware control (offloaded)
state since the coordination is done directly between the trigger and
the LED driver. It can only assume private triggers as offloaded and
generic ones as not offloaded.
Add an hw_offloaded() callback so that triggers can report their
offloaded states to the LED trigger core. When unimplemented, it
defaults to true for private triggers and false for generic ones to keep
the current behavior unchanged.
With that, provide a new attribute "trigger_may_offload_to_hw", so that
userspace can determine:
- if the LED device supports hardware control (supported => visible)
- which trigger is the hardware control trigger selected by the LED
device and offloaded to hardware ("[foo_trigger]")
Note: the documentation describes the attribute as "returning a list"
despite the LED core currently only supports one hardware control
trigger per LED device. This is intentional to make the attribute
extensible in the future without breaking userspace. IOW, userspace
should parse the new attribute in the same way as
/sys/class/leds/<led>/trigger.
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-5-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Currently led_trigger_group and its members are placed at led-class.c,
but they falls into the triggers namespace and does triggers stuff.
Placing them at led-class.c also requires the read and write callback to
be exported and results in an extra #ifdef block.
Move it into led-triggers.c, so that it becomes the only symbol to be
exported for sysfs attributes.
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-4-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Since commit b819dc7d8fb2 ("leds: core: Report ENODATA for brightness of
hardware controlled LED"), the brightness attribute becomes write-only
when the LED is controlled fully by the hardware. A write-only attribute
is very confusing.
Moreover, most LED drivers set hardware brightness innocently with the
side effect of disabling hardware control, but the hardware control
trigger remains active, resulting in the software and hardware being out
of sync.
Fix it by removing the hardware control trigger when writing the
brightness attribute.
This should also match the semantics of hardware control:
When the LED is in hw control, no software blink is possible and
doing so will effectively disable hw control.
Fixes: b819dc7d8fb2 ("leds: core: Report ENODATA for brightness of hardware controlled LED")
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-3-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Currently led_trigger_is_hw_controlled() is placed at led-class.c, which
is not an right place as it falls into the triggers namespace and does
triggers stuff.
Move it into led-triggers.c, and split it into locked and unlocked
variant for convenience.
Fixes: b819dc7d8fb2 ("leds: core: Report ENODATA for brightness of hardware controlled LED")
Acked-by: Ike Panhc <ikepanhc@gmail.com>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-2-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
The led_classdev_register_ext() protects transient states when
registering with the led_access mutex and relies on all sensitive sysfs
attribute callbacks holding the mutex to prevent exposing transient
states.
The Fixes: commit broke this as it accessed trigger_lock without holding
led_access. Fix it by protecting brightness_show() with led_access in
all code paths.
Fixes: b819dc7d8fb2 ("leds: core: Report ENODATA for brightness of hardware controlled LED")
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20260921-leds-trigger-hw-changed-v7-1-fe3cdb6dec51@rong.moe
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Convert LED and channel parsing in lpg_add_led() and
lpg_parse_channel() from DT-specific helpers to the fwnode API.
The probe loop now uses device_for_each_child_node_scoped(),
dropping explicit node lifetime handling.
Behaviour is unchanged for device tree: fwnode_get_child_node_count()
and both child iteration helpers skip unavailable children on OF,
and the fwnode handle is passed straight to LED registration.
cdev->default_trigger is only assigned when
fwnode_property_read_string() succeeds, so an absent
linux,default-trigger property no longer yields an uninitialized
pointer.
Assisted-by: LLM
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://patch.msgid.link/20260919001331.720072-1-rosenp@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Convert open-coded if/else with set_bit/clear_bit and their
non-atomic __set_bit/__clear_bit variants to the assign_bit/__assign_bit
API.
Done with Coccinelle semantic patch and manual fixups.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Link: https://patch.msgid.link/20260918141728.3022983-1-peng.fan@oss.nxp.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
In preparation for making the devm_kmalloc family of allocators type
aware, we need to make sure that the returned type from the allocation
matches the type of the variable being assigned. (Before, the allocator
would always return "void *", which can be implicitly cast to any
pointer type.)
This allocates one int per entry of max_mm_current_percent, but the size
was taken from the whole array, which would make the allocation type a
pointer to the array rather than the "int *" being assigned. Allocate
ARRAY_SIZE-many entries instead. The resulting allocation size is the
same: AAT1290_MM_CURRENT_SCALE_SIZE and
ARRAY_SIZE(max_mm_current_percent) are both 15.
Build tested ARCH=x86_64 allmodconfig with GCC 16.2.0:
drivers/leds/flash/leds-aat1290.o
Assisted-by: LLM coccinelle
Signed-off-by: Kees Cook <kees+treewide@kernel.org>
Link: https://patch.msgid.link/20260917211357.i.412-kees@kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Kernel driver implementation for LTC3208 Multidisplay LED Driver.
The LTC3208 is a Multi-display LED driver, designed to control up to
7 distinct LED channels (MAIN, SUB, AUX, CAMHI, CAMLO, RED, GREEN, BLUE),
each configurable with its own current level that is equally set to its
respective output current source pins for external LEDs.
It is programmed via the I2C serial interface.
MAIN and SUB support 8-bit current level resolution,
while AUX, CAMHI/LO, RED, GREEN, and BLUE support 4-bit levels.
The AUX LED channel can be configured to mirror the CAM, SUB, and MAIN
channel current levels, or as its own independent AUX channel.
The CAM LED channel is configured as 2 separate CAMHI and CAMLO register
sub-channels, which current is selected via the CAMHL pin, or set to
CAMHI register only via setting the S_CAMHILO bit high in register G (0x7).
Signed-off-by: Jan Carlo Roleda <jancarlo.roleda@analog.com>
Link: https://patch.msgid.link/20260923003325.61722-3-jancarlo.roleda@analog.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Do not emit extra trailing space and use sysfs_emit_at()
over sprintf()/strcat()/strlen() in flash_fault_show().
Suggested-by: Lee Jones <lee@kernel.org>
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Link: https://patch.msgid.link/20260916161607.90106-2-dmantipov@yandex.ru
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
In flash_fault_show(), address of uninitialized 'fault' variable is
passed to device-specific .fault_get callbacks. This is not a problem
if such a callback directly assigns the value like rt4505_fault_get(),
but results in an undefined behavior if callback just performs bitwise
ORs like as3645a_get_fault(). So just initialize 'fault' with zero.
Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260904054437.461706-1-dmantipov@yandex.ru?part=1
Fixes: 7aea8389a77ab ("leds: Add LED Flash class extension to the LED subsystem")
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Link: https://patch.msgid.link/20260916161607.90106-1-dmantipov@yandex.ru
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
The channel current register is 8 bits wide, while max_brightness comes
from the device tree and can be larger. The brightness, pattern and
blink paths each apply that limit on their own, open-coding the same
min_t() against U8_MAX, and the blink path previously drifted from the
others by ignoring max_brightness altogether.
Move the limit into st1202_iled_max() and use it in all three places.
Each path programs the same value as before: the LED core already limits
brightness to max_brightness, so capping it against st1202_iled_max() in
st1202_led_set() gives the same result as capping it against U8_MAX.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497935DA426302FB808A81EC5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
st1202_led_set() writes the requested brightness straight into the 8-bit
channel current register. The LED core limits brightness to
max_brightness, which comes from the device tree max-brightness property
and has no upper bound, so on a board declaring more than 255 a
brightness of 256 reaches the register as 0 and turns the LED off, and
larger values wrap around.
Cap the value at U8_MAX, the width of the register, so anything above it
drives the channel at full current. The pattern and blink paths already
cap the current they program the same way.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497C60D1D2921DD0384926FC5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
st1202_blink_set() drives the channel current register to U8_MAX, the
full scale of the part, regardless of the ceiling the board declared.
led_classdev_register_ext() takes max_brightness from the device tree
max-brightness property. The driver does not implement led-max-microamp,
so that is the only way a board can ask for less than 20 mA.
The brightness and pattern paths both respect it. Blinking is the one
that does not, so a board that declares a lower ceiling holds it until
something enables the timer trigger.
Program the same value the other paths use, capped at the width of the
current register so an out of range property cannot wrap it to zero.
Fixes: 35cbd34a6a05 ("leds: st1202: Add hardware-accelerated blink support")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB84979A5D536C71D319A06808C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
st1202_blink_set() programs slots 0 and 1 of its own channel and leaves
slots 2 to 7 at ST1202_PATTERN_PWM_FULL, the value both st1202_led_set()
and st1202_led_pattern_clear() leave behind. Nothing keeps those slots
out of the output except the duration registers being zero, and those
are shared by all twelve channels.
Another channel programming a hardware pattern longer than two steps
writes those durations again and re-arms the sequencer, so the blinking
channel drives full scale for the extra steps. With two LEDs on one
device, blinking one and giving the other a four step pattern, the
blinking channel lights during the two steps it never programmed.
Zero the channel's own unused slots, the same invariant
st1202_led_pattern_set() applies to the slots beyond its pattern length.
blink_set() already zeroes durations 2 to 7 when it runs; the slots are
exposed only when another channel sets those shared durations again.
A channel whose blink is shorter than the active timeline still loses
its own timing, because the sequencer has one set of duration registers.
This only stops it emitting output it never asked for.
Fixes: 35cbd34a6a05 ("leds: st1202: Add hardware-accelerated blink support")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB849770CF6D41F3DFF56B1AC3C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
st1202_brightness_set() takes the chip mutex and performs I2C transfers,
both of which can sleep, but it is installed as the brightness_set
callback. led_set_brightness_nopm() calls that op directly on the
assumption that it never sleeps, including from softirq context, so the
driver can sleep in atomic context.
The driver also installs brightness_set_blocking, but the core only
falls back to it when brightness_set is absent, so st1202_led_set() was
never reached. It merely turned the channel on or off and ignored the
requested brightness, so dropping brightness_set on its own would have
lost brightness control entirely.
Move the register programming into st1202_led_set() so the blocking
callback honours the brightness value, and drop brightness_set. The core
now defers the update to a work queue, where sleeping is allowed. Errors
from the register writes are propagated rather than discarded.
st1202_led_set() was the last user of the locking st1202_channel_set()
wrapper, which is removed.
Programming every PWM slot to full scale is kept: it is what makes the
brightness visible while the global sequencer is running, without having
to stop the sequencer and disturb the other channels.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497CF8FB57A272EB671F0C6C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
st1202_dt_init() stores each LED's firmware node while walking the
device tree with for_each_available_child_of_node_scoped(), which drops
its reference to the node at the end of every iteration. The LED class
stores the pointer with device_set_node() and does not take a reference
of its own, so nothing keeps the node alive for as long as the LED
device uses it. That has been the case since the driver was added, when
the LED class devices were registered inside that same loop.
Commit c72e455b89f2 ("leds: leds-st1202: Fix NULL pointer access on race
condition") moved the registration into a separate loop in
st1202_probe(), which also leaves the stored pointer unreferenced
between the two loops.
With CONFIG_OF_DYNAMIC the node can be freed while it is still in use,
leaving led->fwnode and the LED device's firmware node dangling.
Take a reference when the node is stored and release it through a devm
action. The action is registered before the LED class devices are, so it
runs after they have been unregistered.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB849710C564F23C21BDA3EA41C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
A channel's output is ILED x Pattern_PWM / 4095, so a pattern is only
visible while the analog current register holds a non-zero value.
st1202_led_pattern_set() programs the PWM slots and starts the sequencer
but never writes ILED, so a channel whose current is zero stays dark
while pattern_set() reports success.
Zero is reached by ordinary use. Writing 0 to brightness sets it, and so
does switching away from the pattern trigger, because
pattern_trig_deactivate() ends with led_set_brightness(LED_OFF). A
sequence as simple as
echo none > trigger
echo pattern > trigger
echo "255 500 0 500" > hw_pattern
therefore programs a pattern that never lights up.
Program the current in pattern_set() and release it in pattern_clear(),
so the pattern path owns ILED for as long as a pattern is loaded.
Releasing it matters because the trigger calls pattern_clear() before it
parses a new pattern: without that, a rejected or empty hw_pattern write
would leave the channel at full current with every PWM slot at full
scale, latching the LED on. Clearing before the slots are raised also
avoids a brief full-brightness flash on every reprogram.
A current of zero is not enough to release the channel, though: the
datasheet notes that it does not switch the channel off but leaves a
small uncontrolled current, which shows as a faint glow. pattern_clear()
therefore also disables the channel, and pattern_set() enables it again.
Both are done before the sequencer is stopped, so an I2C error partway
through a clear cannot leave the channel lit.
Probe clears every channel, so the LEDs now reach user space switched
off. Until now they came up lit at the chip's power-on current, because
pattern_clear() fills every slot at full scale. Probe no longer enables
the channels itself either: st1202_setup() has already disabled them
all, and each path that lights a channel enables it when needed.
The current is programmed to the same max_brightness the PWM values are
scaled against, so a pattern step of N produces the same output as
writing N to brightness, and a board declaring a lower ceiling through
the max-brightness property keeps it on both paths.
Note that this makes a hardware pattern take the channel to its maximum
current, so brightness reads back as max_brightness once a pattern is
loaded and as zero once it is cleared. The pattern's own values, not the
last brightness written, decide what the channel shows while a pattern
is running.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB84978D7C1CC0367D1818093DC5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
The LED1202 PWM registers are 12 bits wide, but st1202_led_pattern_set()
writes the 8-bit brightness value carried by struct led_pattern into
them unscaled. A pattern step asking for full brightness therefore
drives the channel at 255 out of 4095, about 6% duty cycle, so a pattern
is dimmer than the same brightness set directly.
Scale the value to the full PWM range before programming it.
Scale against max_brightness rather than the register maximum. The LED
core takes max_brightness from the DT max-brightness property, so a
board can declare a ceiling below full scale, and the pattern trigger
already rejects steps above it. Scaling against a hardcoded 255 would
leave such a board unable to reach its own declared maximum from the
pattern path while the brightness path reaches it.
Scaling divides by max_brightness. The LED core replaces a zero
max-brightness from the device tree with LED_FULL, so the divisor should
never be zero, but the helper returns zero rather than rely on that.
max_brightness is capped at U8_MAX, the driver's own maximum, so a
device tree declaring more than the part supports is treated as full
scale. struct led_pattern brightness is signed, so clamp both ends and
floor a negative value to LED_OFF rather than let it wrap.
Document that a step is relative to max_brightness, since the range
given in the documentation no longer holds when the device tree sets
max-brightness.
Fixes: 259230378c65 ("leds: Add LED1202 I2C driver")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497B938D3592582E17CB757C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
The pattern duration registers are chip-wide while the PWM registers are
per-channel, so a channel can end up driven by a sequencer timeline it
never programmed.
st1202_led_pattern_set() programs only the first len slots. The pattern
trigger calls pattern_clear() before pattern_set() only once a channel is
already in PATTERN_TYPE_HW mode, and activating the trigger resets that
mode, so the first hardware pattern written after every activation skips
it. If another channel has already programmed a longer pattern,
durations [len, 8) are still set, and this channel's PWM for those slots
holds whatever was last written there.
That used to be LED_OFF, so a channel stayed dark for the slots it had
not programmed itself. Since commit d2ca0e2b6d64 ("leds: st1202: Set all
pattern PWM slots to full after clearing pattern") pattern_clear() leaves
ST1202_PATTERN_PWM_FULL there, and so does the brightness path since
commit 7cbe470366bd ("leds: st1202: Fix brightness having no effect while
pattern mode is active"). The channel now plays its own steps and then
sits at full brightness for the rest of the sequence.
Zero this channel's PWM for the unused slots so it stays dark for the
remainder of the timeline, as st1202_blink_set() already does for the
channels it is not driving.
The duration registers are deliberately left alone. All twelve channels
share them, so clearing them would truncate a longer pattern still
running elsewhere on the same device. A channel whose pattern is shorter
than the active timeline therefore keeps the longer period; that follows
from having a single hardware sequencer and is not something this can
correct.
Fixes: d2ca0e2b6d64 ("leds: st1202: Set all pattern PWM slots to full after clearing pattern")
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497E9939E3C0D68401659D0C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
The driver spells 8-bit unsigned values both as uint8_t and as u8, a
mix present since the driver was added. The register helpers and the
prescaler conversion use uint8_t, while the rest of the driver uses u8,
which is also the preferred type in kernel code.
Convert the remaining uint8_t uses to u8.
No functional change.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497783FB573CD48491F9648C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
The driver already names pattern indices "pattern" in the signatures of
st1202_pwm_pattern_write() and st1202_duration_pattern_write(), and
st1202_blink_set() follows the same convention. The remaining loops
abbreviate it to "patt", which matches nothing else in the file.
Rename those loop variables to "pattern". In st1202_led_pattern_set()
that name is taken by the array of pattern steps, so rename the
parameter to "patterns", which also reflects better that it is an array.
Two st1202_pwm_pattern_write() calls exceed 100 columns with the longer
name and are wrapped accordingly.
No functional change.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497AD614B8686BBDA654674C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
ST1202_CONFIG_REG_SHFT is abbreviated to the point of being unreadable
and, unlike the neighbouring PATS and PATSR bits, carries no comment
explaining what it controls.
Rename it to ST1202_CONFIG_REG_PHASE_SHIFT and document it in the same
style as the other configuration bits, retaining the datasheet name in
the comment so it remains searchable.
The longer name no longer fits the existing layout in
st1202_led_pattern_set(), where the continuation line was already 106
columns wide. Re-wrap that register write to match the layout
st1202_blink_set() uses for the same operation and drop the redundant
parentheses around the bit mask.
No functional change.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB849716E21E082D3B93B5B683C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
st1202_prescalar_to_miliseconds() converts a duration in milliseconds
into the prescaler value written to the pattern duration registers, so
its name states the conversion the wrong way round. It also misspells
both "prescaler" and "milliseconds".
Rename it to st1202_milliseconds_to_prescaler(). No functional change.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: LLM
Link: https://patch.msgid.link/GV1PR08MB8497AA602374777F1BA08E07C5BA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
failure
Every write in lm3692x_leds_enable() checks its return and jumps to
out: on failure -- except the last one, which falls through and sets
led->enabled = true regardless of whether it actually succeeded. Leaks
the regulator on a failing probe, and short-circuits later
brightness_set() calls without retrying.
Route it through out: like every other write here, and only set
enabled = true once it succeeds.
Fixes: 260718b3a35d ("leds: lm3692x: Disable chip on brightness 0")
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Link: https://patch.msgid.link/20260915034515.4147981-1-congnt264@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Coverity report INTEGER_OVERFLOW (tainted_data_return ->
cast_underflow -> overflow) in pca9532_getled().
pca9532_getled() stored the return value of i2c_smbus_read_byte_data()
into a char and used it directly to compute the LED state without
checking for an error. i2c_smbus_read_byte_data() returns a negative
error code on failure. On an I2C read error the negative value was
assigned to an unsigned type, triggering an integer underflow/overflow,
and a meaningless LED state was returned to the caller.
Read the value into an int, check for the error, and fall back to
PCA9532_OFF while emitting a warning when the read fails.
Fixes: 28c5fe99016d ("leds: pca9532: Extend pca9532 device tree support")
Assisted-by: VeroCoder:vero-1 [cli]
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260727-led-fix-v1-1-d635c5037109@nxp.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
regulator_disable_action() retrieves the driver context from device
driver data. However, ktd2692_parse_dt() registers the action before
ktd2692_probe() stores the context with platform_set_drvdata().
If devm_add_action_or_reset() cannot allocate the action, it invokes the
callback immediately. A later probe failure also invokes it during
managed-resource unwinding. Both paths dereference a NULL context.
Pass the already allocated context directly to the action and retain the
device pointer in it for error reporting. The context is allocated before
the action is registered, so reverse-order devres unwinding keeps it alive
through the callback.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: ee78b9360e14 ("leds: ktd2692: Fix an error handling path")
Cc: stable@vger.kernel.org
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260910194525.99654-1-mhun512@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
lp8860_probe() looks up the driver's single LED child node with
of_get_next_available_child() and hands it to the LED core as
init_data.fwnode, but never drops the reference that lookup returned:
child_node = of_get_next_available_child(np, NULL);
if (!child_node)
return -EINVAL;
...
init_data.fwnode = of_fwnode_handle(child_node);
of_get_next_available_child() returns the node with its refcount
incremented, and the LED core does not take a reference of its own:
led_classdev_register_ext() only reads properties out of
init_data.fwnode and then stores the bare pointer with
device_set_node(). The reference therefore stays owned by the driver
for as long as it holds the node.
Nothing in lp8860_probe() ever releases it, so it is leaked on every
error return taken after the lookup - the enable GPIO, the vled
regulator, devm_mutex_init(), the regmap allocation, the optional
EEPROM programming and the LED class registration - and on a fully
successful probe alike. A device that binds and unbinds repeatedly
leaks one device_node reference per bind.
Sibling drivers already get this right: leds-lm3692x.c, from the same
TI LED family, calls fwnode_handle_put(init_data.fwnode) once after
devm_led_classdev_register_ext() to cover both outcomes, while
leds-ktd2692.c and leds-aat1290.c take the node with __free(device_node).
Use __free(device_node) here too. Unlike a single of_node_put() at the
end of probe it also covers the intermediate error returns, and it keeps
the node alive for the whole function, which the LED core still needs
when it reads the child's properties during registration.
Fixes: 99ca0ea57309 ("leds: lp8860: Use generic support for composing LED names")
Signed-off-by: Miles Krause <mileskrause5200@gmail.com>
Link: https://patch.msgid.link/20260910-leds-lp8860-of-node-leak-v1-1-d333cff4345b@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Convert the DT-specific helpers in is31fl32xx_parse_dt() and
is31fl32xx_parse_child_dt() to their fwnode/device equivalents.
Behaviour is unchanged for device tree: device_property_read_bool(),
device_for_each_child_node_scoped() and device_get_child_node_count()
operate on the same nodes and keep the skip of unavailable children.
Use the %pfwP format specifier in error messages, as child is now a
struct fwnode_handle and %pOF would misread it as a device_node.
Assisted-by: opencode:deepseek-v4-flash-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://patch.msgid.link/20260907201940.40524-1-rosenp@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Replace the DT-specific of_property_read_u32() calls and the
dev_of_node()/of_fwnode_handle() roundtrip with their
device/fwnode equivalents. Behaviour is unchanged for device
tree: device_property_read_u32() and dev_fwnode() operate on the
same node, and the fallback from "reg" to "offset" is preserved.
Use dev_fwnode() for init_data.fwnode; unlike a child node from
a scoped iterator, the platform device's own node is held by the
driver core for the device lifetime.
Assisted-by: opencode:deepseek-v4-flash-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Link: https://patch.msgid.link/20260907202436.42304-1-rosenp@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Correct "retrive" to "retrieve", reported by scripts/checkpatch.pl using
the misspelling list in scripts/spelling.txt. Only touches a comment, no
code changes.
Since v1 the subject carries the driver name and a capitalised
description, to match the LED subsystem convention.
Assisted-by: Cursor:claude-opus-5
Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
Link: https://patch.msgid.link/20260907045436.18039-1-hemanth.selam@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Since there are no users of this driver via platform data, remove the
platform data support and switch to using Device Tree bindings.
Previously, all cell devices were linked to the parent device. This could
cause problems further down the line because the LM3533 has multiple cells
of the same type. Using a single phandle to the parent could cause
confusion when attempting to reference or call the correct child node.
Since this commit adds a dedicated node for every cell, remove linking of
the cell to the parent node.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Daniel Thompson (RISCstar) <danielt@kernel.org> #for backlight
Acked-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> #for-iio
Link: https://patch.msgid.link/20260731113632.158440-9-clamor95@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Instead of passing the entire lm3533 core data structure, only pass the
regmap and the light sensor presence flag to child devices.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Acked-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> #for-iio
Link: https://patch.msgid.link/20260731113632.158440-5-clamor95@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Remove driver-specific regmap wrappers in favor of using regmap helpers
directly.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Link: https://patch.msgid.link/20260731113632.158440-3-clamor95@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Rework the subled loop in max77705_add_led() around
fwnode_for_each_child_node_scoped() instead of adding a manual
fwnode_handle_put(child) before the early return on a
max77705_parse_subled() failure, so the reference on the current
child fwnode is released automatically on every exit path from the
loop. child is never used outside the loop, so the now-unused outer
child declaration is dropped along with it.
Suggested-by: Krzysztof Kozlowski <krzk@kernel.org>
Fixes: 3b6eaa3db567 ("leds: Use fwnode_for_each_child_node() instead")
Signed-off-by: Manush Prajwal <manushprajwal555@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Link: https://patch.msgid.link/6a914e1e.7d702ed2.1273e8.2a52@mx.google.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Implement blink_set() to enable hardware-accelerated blinking via the
timer trigger. The LED1202 pattern engine is used to produce a two-step
sequence: full brightness for delay_on, off for delay_off, repeating
indefinitely.
Requested delays are clamped to the hardware range [22ms, 5610ms] then
rounded up to the nearest 22ms step. Clamping before rounding prevents
integer overflow in roundup() for extreme input values; since
ST1202_MILLIS_PATTERN_DUR_MAX is an exact multiple of
ST1202_MILLIS_PATTERN_DUR_MIN, rounding a clamped value cannot exceed
the maximum. A zero delay is replaced with the default of 500ms
independently for each of delay_on and delay_off.
The LED1202 pattern sequencer is global and its timing registers are
shared across all channels, so only one blink configuration can be
active at a time. Other active channels have their PWM slots zeroed for
both pattern steps so they remain dark rather than outputting unintended
values when the sequencer runs. The target channel's ILED register is
set to full brightness and the channel is enabled, since the timer
trigger deactivates the current trigger before calling blink_set which
would otherwise leave the channel disabled.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Link: https://patch.msgid.link/GV1PR08MB84973F79E871176EB387C377C5DA2@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds
Pull LED updates from Lee Jones:
"New Support & Features:
- Core: Extend netdev trigger speeds up to 100G
- PWM Multicolor: Introduce default-intensity property
- Analog Devices LTC3220: Add support for 18 channel LED driver
- NXP PCA963x: Add multicolor LED class support
Improvements & Fixes:
- GPIO: Clear error pointers for skipped LEDs
- Broadcom BCM63138: Use %pe to print pinctrl error instead of %ld
- ISSI IS31FL319x: Modernize device registration by using fwnode APIs
- NXP PCA9532: Fix inverted GPIO output polarity
- NXP PCA9532: Fix phantom device registration on missing hardware
- STMicroelectronics ST1202: Correct and extend hw_pattern
documentation
- STMicroelectronics ST1202: Fix channel disable logic on zero
brightness and ensure brightness changes are applied in active mode
- STMicroelectronics ST1202: Fix hardware pattern sequence
programming, validate inputs, and correct pattern duration
calculations
- STMicroelectronics ST1202: Validate LED reg property against
channel count
- TI LP5860: Fix a potential double-unlock during device
initialization and fix error handling path by using
devm_mutex_init()
Cleanups & Refactoring:
- GPIO: Make legacy gpiolib interface optional
Device Tree Binding Updates:
- Core: Add default-intensity property
- Core: Document "gpio" trigger
- Analog Devices LTC3220: Add DT binding for LTC3220 18 channel LED
driver
- Broadcom BCM6358: Convert to DT schema
- LaCie NS2: Convert to DT schema
- NXP PCA963x: Add multicolor LED support
- NXP PCA963x: Fix reg maximum for pca9635
- TI TPS65217: Convert backlight bindings to DT schema"
* tag 'leds-next-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (29 commits)
leds: is31fl319x: Modernize registration
dt-bindings: leds: lacie,ns2-leds: Convert to DT schema
leds: pca963x: Add multicolor LED class support
dt-bindings: leds: nxp,pca963x: Add multicolor LED support
dt-bindings: leds: nxp,pca963x: Fix reg maximum for pca9635
leds: gpio: Clear error pointers for skipped LEDs
dt-bindings: leds: backlight: Convert TPS65217 to DT schema
leds: pca9532: Fix phantom device registration on missing hardware
leds: gpio: Make legacy gpiolib interface optional
leds: bcm63138: Use %pe to print pinctrl error instead of %ld
dt-bindings: leds: Add default-intensity property
leds: ltc3220: Add Support for LTC3220 18 channel LED Driver
dt-bindings: leds: Add LTC3220 18 channel LED Driver
dt-bindings: leds: bcm6358: Convert to DT schema
dt-bindings: leds: Document "gpio" trigger
leds: st1202: Correct and extend hw_pattern documentation
leds: st1202: Validate LED reg property against channel count
leds: st1202: Disable channel when brightness is set to zero
leds: st1202: Fix brightness having no effect while pattern mode is active
leds: st1202: Fix spurious pattern sequence start in setup
...
|
|
Nothing in suspend.h needs swap.h. However, many files indirectly
depend on some of swap.h's dependencies, so this is a large
cross-subsystem patch. Stats:
42 are missing includes of interrupt.h (the question of why swap.h
brings in interrupt.h remains unanswered).
10 missing includes of seq_file.h
5 missing includes of swap.h (obviously all files could have just added
swap.h, but I preferred to bring in a more minimal inclusion set)
3 missing includes of highmem.h
2 missing includes of device.h
2 missing includes of string_choices.h
1 missing include of cacheflush.h
1 missing include of dma-direction.h
1 missing include of kthread.h
1 missing include of pagemap.h
1 missing include of string_helpers.h
1 missing include of writeback.h
I tried to follow whatever conventions appeared to be in use for the
various subsystems I touched; for example I added string_choices.h to
drm_print.h instead of individually to each driver which used the
functions declared there.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
|
|
Use _ext version to have properties parsed to avoid needing to parse
them in the driver itself. More modern properties are recognized and
the LEDs can be referenced via phandle.
Due to the maximum current mechanics, LEDs are not registered right
in the first iteration over the nodes.
Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Link: https://patch.msgid.link/20260806-led-modern-v4-1-eed715baab2e@kemnade.info
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
Allow grouping of individual PCA963x PWM channels into a single
multicolor LED device by adding support for the LED multicolor class.
A child node with sub-children is treated as a multicolor group,
others are treated as single leds, keeping full backwards compatibility.
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Link: https://patch.msgid.link/20260727-monza-leds-v8-3-6e7e93d44dba@oss.qualcomm.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
gpio_led_get_gpiod() returns an error pointer when a platform-data
LED's GPIO is unavailable. gpio_led_probe() skips registration in that
case, but leaves the error pointer in led_dat->gpiod.
The skipped entry remains included in priv->num_leds. During shutdown,
gpio_led_shutdown() walks those entries and passes the error pointer to
gpio_led_set(), producing:
gpiod_set_value: invalid GPIO (errorpointer: -ENOENT)
Clear led_dat->gpiod before skipping the LED so skipped entries do not
retain error-valued descriptors.
Fixes: 45d4c6de4e49 ("leds: gpio: Try to lookup gpiod from device")
Suggested-by: Lee Jones <lee@kernel.org>
Assisted-by: ChatGPT:GPT-5.5-Thinking
Signed-off-by: Steve Dunnagan <sdunnaga@redhat.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260724180412.43150-1-sdunnaga@redhat.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
The initial PWM and PSC register writes in pca9532_configure() do not
check the return values of i2c_smbus_write_byte_data(). If the I2C
device is physically absent from the bus, the write fails with -ENXIO.
However, the driver ignores this error and allows probe() to complete
successfully.
This results in the registration of phantom LED class devices and
gpiochips backed by non-existent hardware. Subsequent GPIO reads from
these phantom chips return bogus values (due to -ENXIO being truncated
to an unsigned char in pca9532_gpio_get_value()), silently corrupting
hardware state tracking in userspace.
Propagate the I2C write failures back to probe() so the driver core
can gracefully abort binding and release devres-managed resources.
Fixes: e14fa82439d3 ("leds: Add pca9532 led driver")
Signed-off-by: Cosmo Chou <chou.cosmo@gmail.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Link: https://patch.msgid.link/20260715080747.1638097-1-chou.cosmo@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
|
|
There are still a handful of ancient mips/armv5/sh boards that use the
gpio_led:gpio member to pass an old-style gpio number, but all modern
users have been converted to gpio descriptors.
While the CONFIG_GPIOLIB_LEGACY option that guards devm_gpio_request_one()
and related helpers is currently turned on in all kernel builds,
the plan is to only enable it on the few platforms that actually
pass gpio numbers in any platform_data.
Split out the legacy portion of the platform_data handling into a custom
helper function that is guarded with in #ifdef block, to allow the
the leds-gpio driver to compile cleanly when CONFIG_GPIOLIB_LEGACY
gets turned off. Once the last user is converted, this function can
be removed.
Link: https://lore.kernel.org/all/e9252384-a55c-4a91-9c61-06e05a0b2ce4@app.fastmail.com/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> # for input
Link: https://patch.msgid.link/20260710211854.1371746-4-arnd@kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
|