summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-10-26 08:55:14 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2026-10-26 08:55:14 -1000
commit5b93dc1c0c61fd0fe575cb473e9e25f929fda509 (patch)
treee9405ab03dda86826201dca3a7731924825bb982 /include/linux
parentd857e1f3faf998f2614dcdb52a90a27bc83bd71d (diff)
parent59cf91cf87abb67a49b1bb7b9d3b06486abde8cf (diff)
Merge tag 'leds-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds
Pull LED updates from Lee Jones: "New Support & Features: - Core: Add `led_trigger_notify_hw_control_changed()` to allow drivers to notify the core of autonomous hardware control transitions - Core: Add the `hw_offloaded()` trigger callback and `trigger_may_offload_to_hw` sysfs attribute to expose hardware-offloaded triggers - Netdev Trigger: Implement the `hw_offloaded()` callback to report hardware control state to the LED core - Analog Devices LTC3208: Add support for the LTC3208 7-channel multi-display I2C LED driver - ChromeOS EC: Implement the `hw_offloaded()` callback for the `chromeos-auto` trigger - CZ.NIC Turris Omnia: Implement the `hw_offloaded()` callback and declare `omnia-mcu` as a hardware control trigger - STMicroelectronics ST1202: Add hardware-accelerated blink support via `blink_set()` Improvements & Fixes: - Class: Always hold the `led_access` mutex in `brightness_show()` to avoid exposing transient registration states - Class: Deactivate active hardware control triggers when writing to the `brightness` sysfs attribute - Core: Enforce strict validation in `led_trigger_is_hw_controlled()` and warn on legacy fallback paths - Flash Class: Initialize the fault variable in `flash_fault_show()` to prevent undefined behavior when callbacks perform bitwise ORs - Kinetic KTD2692: Pass the driver context directly to `regulator_disable_action()` to prevent a NULL pointer dereference during error unwinding - Maxim MAX77705: Use `fwnode_for_each_child_node_scoped()` in `max77705_add_led()` to prevent child node reference leaks on error paths - NXP PCA9532: Check the return value of `i2c_smbus_read_byte_data()` in `pca9532_getled()` to avoid integer underflow on read errors - Qualcomm WLED: Fix a NULL pointer dereference in `wled_remove()` by setting platform driver data in `wled_probe()` - Qualcomm WLED: Fix the WLED3 brightness register stride to prevent consecutive string writes from overlapping - Qualcomm WLED: Read back the hardware-programmed brightness at probe, expose it via `get_brightness()`, and prevent unbalanced OVP IRQ enabling - STMicroelectronics ST1202: Clear unused PWM pattern slots in `pattern_set()` and `blink_set()` to prevent unintended output when sharing the global sequencer - STMicroelectronics ST1202: Program and cap the channel current according to `max_brightness` across brightness, blink, and hardware pattern modes, and scale pattern brightness to the 12-bit PWM range - STMicroelectronics ST1202: Retain a reference to each child LED firmware node for the lifetime of the device - STMicroelectronics ST1202: Use only the blocking `brightness_set_blocking()` callback to avoid sleeping in atomic context during I2C transfers - TI LM3692x: Check the final register write in `lm3692x_leds_enable()` to prevent regulator/GPIO leaks and an inconsistent enabled state - TI LP8860: Fix a `device_node` reference leak in `lp8860_probe()` using `__free(device_node)` Cleanups & Refactoring: - Core: Move `led_trigger_is_hw_controlled()` and `led_trigger_group` from `led-class.c` into `led-triggers.c` - Core: Replace conditional `set_bit()`/`clear_bit()` patterns with `assign_bit()` and `__assign_bit()` - Flash Class: Simplify `flash_fault_show()` using `sysfs_emit_at()` and omit the trailing space - Maintainers: Add Griffin Kroah-Hartman as an LED subsystem reviewer - Intel SS4200: Fix a spelling typo in a comment - ISSI IS31FL32xx: Convert DT-specific parsing helpers to generic device and fwnode property APIs - NXP PCA955x: Drop redundant intermediate platform data and allocate the LED array using a flexible array member - Qualcomm LPG: Convert LED and channel parsing to fwnode APIs and avoid leaving `default_trigger` uninitialized - Skyworks AAT1290: Use `ARRAY_SIZE()` when allocating `mm_current_scale` to match the target pointer type for type-aware allocators - STMicroelectronics ST1202: Introduce a `st1202_iled_max()` helper to unify channel current ceiling calculations - STMicroelectronics ST1202: Standardize variable and macro naming, fix helper spelling, and use `u8` consistently instead of `uint8_t` - Syscon: Convert from OF-specific property helpers to the generic device property and fwnode APIs Device Tree Binding Updates: - Core: Allow PHY RX triggers (`phy[0-9]+rx`) in `linux,default-trigger` - Core: Standardize example indentation across multiple LED and backlight binding schemas - Analog Devices LTC3208: Document the LTC3208 multi-display LED driver - LaCie netxbig: Convert LED bindings to DT schema - Motorola CPCAP: Convert LED bindings to DT schemaLEDs for v7.4" * tag 'leds-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (49 commits) dt-bindings: leds: lacie,netxbig-leds: Convert to DT schema leds: pca955x: Drop platform data and allocate LEDs with the device dt-bindings: leds: Use consistent indentation in the example backlight: qcom-wled: Read back the programmed brightness at probe backlight: qcom-wled: Fix unbalanced OVP IRQ enable at probe backlight: qcom-wled: Fix WLED3 brightness register stride backlight: qcom-wled: Fix NULL pointer dereference in wled_remove() dt-bindings: leds: Allow PHY RX triggers MAINTAINERS: Add myself as a LED SUBSYSTEM reviewer leds: trigger: Add led_trigger_notify_hw_control_changed() interface leds: trigger: Enforce strict checks in led_trigger_is_hw_controlled() leds: trigger: netdev: Implement hw_offloaded() callback leds: turris-omnia: Implement hw_offloaded() trigger callback and declare hw_control_trigger leds: cros_ec: Implement hw_offloaded() trigger callback leds: trigger: Add hw_offloaded() callback and provide trigger_may_offload_to_hw attribute leds: trigger: Move led_trigger_group to the right place leds: class: Remove hardware control trigger when writing brightness leds: trigger: Move led_trigger_is_hw_controlled() to the right place leds: class: Always protect brightness_show() with led_access dt-bindings: leds: leds-cpcap: Convert to DT schema ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/leds.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/include/linux/leds.h b/include/linux/leds.h
index a515f075c29a..beaf23993063 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -109,6 +109,7 @@ struct led_classdev {
#define LED_INIT_DEFAULT_TRIGGER BIT(23)
#define LED_REJECT_NAME_CONFLICT BIT(24)
#define LED_MULTI_COLOR BIT(25)
+#define LED_TRIG_HW_CHANGED BIT(26)
/* set_brightness_work / blink_timer flags, atomic, private. */
unsigned long work_flags;
@@ -239,6 +240,11 @@ struct led_classdev {
struct kernfs_node *brightness_hw_changed_kn;
#endif
+#ifdef CONFIG_LEDS_TRIGGERS_HW_CHANGED
+ bool trigger_hw_changed;
+ struct work_struct trigger_hw_changed_work;
+#endif
+
/* Ensures consistent access to the LED class device */
struct mutex led_access;
};
@@ -485,6 +491,7 @@ struct led_trigger {
const char *name;
int (*activate)(struct led_classdev *led_cdev);
void (*deactivate)(struct led_classdev *led_cdev);
+ bool (*hw_offloaded)(struct led_classdev *led_cdev);
/* Brightness set by led_trigger_event */
enum led_brightness brightness;
@@ -533,6 +540,9 @@ void led_trigger_blink_oneshot(struct led_trigger *trigger,
void led_trigger_set_default(struct led_classdev *led_cdev);
int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger);
void led_trigger_remove(struct led_classdev *led_cdev);
+void led_trigger_remove_hw_control(struct led_classdev *led_cdev);
+
+bool led_trigger_is_hw_controlled(struct led_classdev *led_cdev);
static inline void led_set_trigger_data(struct led_classdev *led_cdev,
void *trigger_data)
@@ -584,6 +594,13 @@ static inline int led_trigger_set(struct led_classdev *led_cdev,
}
static inline void led_trigger_remove(struct led_classdev *led_cdev) {}
+static inline void led_trigger_remove_hw_control(struct led_classdev *led_cdev) {}
+
+static inline bool led_trigger_is_hw_controlled(struct led_classdev *led_cdev)
+{
+ return false;
+}
+
static inline void led_set_trigger_data(struct led_classdev *led_cdev) {}
static inline void *led_get_trigger_data(struct led_classdev *led_cdev)
{
@@ -598,6 +615,13 @@ led_trigger_get_brightness(const struct led_trigger *trigger)
#endif /* CONFIG_LEDS_TRIGGERS */
+#ifdef CONFIG_LEDS_TRIGGERS_HW_CHANGED
+void led_trigger_notify_hw_control_changed(struct led_classdev *led_cdev, bool activate);
+#else
+static inline void led_trigger_notify_hw_control_changed(struct led_classdev *led_cdev,
+ bool activate) {}
+#endif
+
/* Trigger specific enum */
enum led_trigger_netdev_modes {
TRIGGER_NETDEV_LINK = 0,