LEDs for for v6.17

- Improvements & Fixes
   * A fix has been implemented in QCOM Flash to prevent incorrect register
     access when the driver is re-bound. This is solved by duplicating a static
     register array during the probe function, which prevents register addresses
     from being miscalculated after multiple binds.
   * The LP50xx driver now correctly handles the 'reg' property in device tree
     child nodes to ensure the multi_index is set correctly. This prevents
     issues where LEDs could be controlled incorrectly if the device tree nodes
     were processed in a different order. An error is returned if the reg
     property is missing or out of range.
   * A Kconfig dependency on between TPS6131x and V4L2_FLASH_LED_CLASS has been
     added to prevent a build failure when the driver is built-in and the V4L2
     flash infrastructure is a loadable module.
   * A potential buffer overflow warning in PCA955x was reported by older GCC
     versions has been fixed by using a more precise format specifier when
     creating the default LED label.
 
 - Cleanups & Refactoring
   * The MAINTAINERS file entry for the TPS6131X flash LED driver has been
     corrected to point to the correct device tree binding file name.
   * A comment in the Flash Class for the flash_timeout setter has been
     corrected to "flash timeout" from "flash duration" for accuracy.
   * The of_led_get() function is no longer exported as it has no users
     outside of its own module.
 
 - Removals
   * The commit to configure LED blink intervals for hardware offload in the
     Netdev Trigger has been reverted. This change was found to break existing
     PHY drivers by putting their LEDs into a permanent, unconditional blinking
     state.
 
 - Device Tree Bindings Updates
   * The binding for LP50xx has been updated to document that the child reg
     property is the index within the LED bank. The example was also updated to
     use correct values.
   * The JNCP5623 binding has been updated to add 0x39 as a valid I2C address,
     as it is used by the NCP5623C variant.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmiKNSgACgkQUa+KL4f8
 d2GwyA//QyWJVRmx3iK64MWnMVHZxuFdXcilYXtYFGPdQNj/aqB51X8XeUDlpfDR
 9YU9m+MZZJv4ku+BJNWMmilsOZmCSd2L0SjNcvg4EBagE7uCRGlc/zhSYQT99f4H
 VvVTNRLaiY2JS4cLt5hQFccWSFFuVpHaDDr8lU6MnogPoUWm31PLP9oyjQZdw/3s
 cEsSge6xhjQ48HLudp8t4o+OYt7SsiwGwua5dgLm65Cihiv2jI3c6xpTXsvk23Go
 oIXpYRsUnPOh2FBhiBQYtwY4mtbfPL2EjfRBXoH8wPelVF+rqufwClp4GxolcbwR
 VH9Xy1MtzW4Qe9SCV8t1UtsjzmGz1J+rO3NMCnGfYpCCwlrW0664P1tU90UDz7Uf
 W8b5brD7tbJkW+29qfbxeCZE6hSYHqDh+0p+BLvQiN3Onv7xqozW1ODdVpAEjhLe
 0okvY3WCkf0+dn08FVkQYuAmXQwYmKM2ylqr8LOlL/ESOK9vipEf48wRwPwm42VA
 kDqdgy0J9N00sSD/iHXBHj6DjXVjjtrfJiOVLicfmRgTCPpm3UasPA9K7sVj5hZ3
 TjDPPSY0MrTazMFf5AX7Q0nLEe/K7ZXK44xIn0pWw+loycmhrHNbFrcxS6D/BYV+
 zkauHl/SKprLiVXWLYvyWjxLweHDO3LhKFjUQ6cOn+YZRdz5rSY=
 =+8ND
 -----END PGP SIGNATURE-----

Merge tag 'leds-next-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds

Pull LED updates from Lee Jones:
 "Improvements & Fixes:

   - A fix for QCOM Flash to prevent incorrect register access when the
     driver is re-bound. This is solved by duplicating a static register
     array during the probe function, which prevents register addresses
     from being miscalculated after multiple binds

   - The LP50xx driver now correctly handles the 'reg' property in
     device tree child nodes to ensure the multi_index is set correctly.
     This prevents issues where LEDs could be controlled incorrectly if
     the device tree nodes were processed in a different order. An error
     is returned if the reg property is missing or out of range

   - Add a Kconfig dependency on between TPS6131x and
     V4L2_FLASH_LED_CLASS to prevent a build failure when the driver is
     built-in and the V4L2 flash infrastructure is a loadable module

   - Fix a potential buffer overflow warning in PCA955x reported by
     older GCC versions by using a more precise format specifier when
     creating the default LED label.

  Cleanups & Refactoring:

   - Correct the MAINTAINERS file entry for the TPS6131X flash LED
     driver to point to the correct device tree binding file name

   - Fix a comment in the Flash Class for the flash_timeout setter to
     "flash timeout" from "flash duration" for accuracy

   - The of_led_get() function is no longer exported as it has no users
     outside of its own module.

  Removals:

   - Revert the commit to configure LED blink intervals for hardware
     offload in the Netdev Trigger. This change was found to break
     existing PHY drivers by putting their LEDs into a permanent,
     unconditional blinking state.

  Device Tree Bindings Updates:

   - Update the binding for LP50xx to document that the child reg
     property is the index within the LED bank. The example was also
     updated to use correct values

   - Update the JNCP5623 binding to add 0x39 as a valid I2C address, as
     it is used by the NCP5623C variant"

* tag 'leds-next-6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds:
  dt-bindings: leds: ncp5623: Add 0x39 as a valid I2C address
  Revert "leds: trigger: netdev: Configure LED blink interval for HW offload"
  leds: pca955x: Avoid potential overflow when filling default_label (take 2)
  leds: Unexport of_led_get()
  leds: tps6131x: Add V4L2_FLASH_LED_CLASS dependency
  dt-bindings: leds: lp50xx: Document child reg, fix example
  leds: leds-lp50xx: Handle reg to get correct multi_index
  leds: led-class-flash:: Fix flash_timeout comment
  MAINTAINERS: Adjust file entry in TPS6131X FLASH LED DRIVER
  leds: flash: leds-qcom-flash: Fix registry access after re-bind
This commit is contained in:
Linus Torvalds 2025-07-31 11:54:01 -07:00
commit 831462ff3e
11 changed files with 45 additions and 33 deletions

View File

@ -81,7 +81,12 @@ patternProperties:
properties:
reg:
maxItems: 1
items:
- minimum: 0
maximum: 2
description:
This property denotes the index within the LED bank.
required:
- reg
@ -138,18 +143,18 @@ examples:
color = <LED_COLOR_ID_RGB>;
function = LED_FUNCTION_STANDBY;
led@3 {
reg = <0x3>;
led@0 {
reg = <0x0>;
color = <LED_COLOR_ID_RED>;
};
led@4 {
reg = <0x4>;
led@1 {
reg = <0x1>;
color = <LED_COLOR_ID_GREEN>;
};
led@5 {
reg = <0x5>;
led@2 {
reg = <0x2>;
color = <LED_COLOR_ID_BLUE>;
};
};

View File

@ -19,7 +19,9 @@ properties:
- onnn,ncp5623
reg:
const: 0x38
enum:
- 0x38
- 0x39
multi-led:
type: object

View File

@ -24813,7 +24813,7 @@ TEXAS INSTRUMENTS TPS6131X FLASH LED DRIVER
M: Matthias Fend <matthias.fend@emfend.at>
L: linux-leds@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/leds/ti,tps6131x.yaml
F: Documentation/devicetree/bindings/leds/ti,tps61310.yaml
F: drivers/leds/flash/leds-tps6131x.c
TEXAS INSTRUMENTS' DAC7612 DAC DRIVER

View File

@ -136,6 +136,7 @@ config LEDS_TPS6131X
tristate "LED support for TI TPS6131x flash LED driver"
depends on I2C && OF
depends on GPIOLIB
depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS
select REGMAP_I2C
help
This option enables support for Texas Instruments TPS61310/TPS61311

View File

@ -117,7 +117,7 @@ enum {
REG_MAX_COUNT,
};
static struct reg_field mvflash_3ch_regs[REG_MAX_COUNT] = {
static const struct reg_field mvflash_3ch_regs[REG_MAX_COUNT] = {
REG_FIELD(0x08, 0, 7), /* status1 */
REG_FIELD(0x09, 0, 7), /* status2 */
REG_FIELD(0x0a, 0, 7), /* status3 */
@ -132,7 +132,7 @@ static struct reg_field mvflash_3ch_regs[REG_MAX_COUNT] = {
REG_FIELD(0x58, 0, 2), /* therm_thrsh3 */
};
static struct reg_field mvflash_4ch_regs[REG_MAX_COUNT] = {
static const struct reg_field mvflash_4ch_regs[REG_MAX_COUNT] = {
REG_FIELD(0x06, 0, 7), /* status1 */
REG_FIELD(0x07, 0, 6), /* status2 */
REG_FIELD(0x09, 0, 7), /* status3 */
@ -854,11 +854,17 @@ static int qcom_flash_led_probe(struct platform_device *pdev)
if (val == FLASH_SUBTYPE_3CH_PM8150_VAL || val == FLASH_SUBTYPE_3CH_PMI8998_VAL) {
flash_data->hw_type = QCOM_MVFLASH_3CH;
flash_data->max_channels = 3;
regs = mvflash_3ch_regs;
regs = devm_kmemdup(dev, mvflash_3ch_regs, sizeof(mvflash_3ch_regs),
GFP_KERNEL);
if (!regs)
return -ENOMEM;
} else if (val == FLASH_SUBTYPE_4CH_VAL) {
flash_data->hw_type = QCOM_MVFLASH_4CH;
flash_data->max_channels = 4;
regs = mvflash_4ch_regs;
regs = devm_kmemdup(dev, mvflash_4ch_regs, sizeof(mvflash_4ch_regs),
GFP_KERNEL);
if (!regs)
return -ENOMEM;
rc = regmap_read(regmap, reg_base + FLASH_REVISION_REG, &val);
if (rc < 0) {
@ -880,6 +886,7 @@ static int qcom_flash_led_probe(struct platform_device *pdev)
dev_err(dev, "Failed to allocate regmap field, rc=%d\n", rc);
return rc;
}
devm_kfree(dev, regs); /* devm_regmap_field_bulk_alloc() makes copies */
platform_set_drvdata(pdev, flash_data);
mutex_init(&flash_data->lock);

View File

@ -256,7 +256,7 @@ static const struct class leds_class = {
* Returns the LED device parsed from the phandle specified in the "leds"
* property of a device tree node or a negative error-code on failure.
*/
struct led_classdev *of_led_get(struct device_node *np, int index)
static struct led_classdev *of_led_get(struct device_node *np, int index)
{
struct device *led_dev;
struct device_node *led_node;
@ -270,7 +270,6 @@ struct led_classdev *of_led_get(struct device_node *np, int index)
return led_module_get(led_dev);
}
EXPORT_SYMBOL_GPL(of_led_get);
/**
* led_put() - release a LED device

View File

@ -476,6 +476,7 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
return -ENOMEM;
fwnode_for_each_child_node(child, led_node) {
int multi_index;
ret = fwnode_property_read_u32(led_node, "color",
&color_id);
if (ret) {
@ -483,8 +484,16 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
dev_err(priv->dev, "Cannot read color\n");
return ret;
}
ret = fwnode_property_read_u32(led_node, "reg", &multi_index);
if (ret != 0) {
dev_err(priv->dev, "reg must be set\n");
return -EINVAL;
} else if (multi_index >= LP50XX_LEDS_PER_MODULE) {
dev_err(priv->dev, "reg %i out of range\n", multi_index);
return -EINVAL;
}
mc_led_info[num_colors].color_index = color_id;
mc_led_info[multi_index].color_index = color_id;
num_colors++;
}

View File

@ -587,7 +587,7 @@ static int pca955x_probe(struct i2c_client *client)
struct pca955x_platform_data *pdata;
bool keep_psc0 = false;
bool set_default_label = false;
char default_label[8];
char default_label[4];
int bit, err, reg;
chip = i2c_get_match_data(client);
@ -693,7 +693,7 @@ static int pca955x_probe(struct i2c_client *client)
}
if (set_default_label) {
snprintf(default_label, sizeof(default_label), "%u", i);
snprintf(default_label, sizeof(default_label), "%hhu", i);
init_data.default_label = default_label;
} else {
init_data.default_label = NULL;

View File

@ -68,7 +68,6 @@ struct led_netdev_data {
unsigned int last_activity;
unsigned long mode;
unsigned long blink_delay;
int link_speed;
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported_link_modes);
u8 duplex;
@ -87,10 +86,6 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
/* Already validated, hw control is possible with the requested mode */
if (trigger_data->hw_control) {
led_cdev->hw_control_set(led_cdev, trigger_data->mode);
if (led_cdev->blink_set) {
led_cdev->blink_set(led_cdev, &trigger_data->blink_delay,
&trigger_data->blink_delay);
}
return;
}
@ -459,11 +454,10 @@ static ssize_t interval_store(struct device *dev,
size_t size)
{
struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
struct led_classdev *led_cdev = trigger_data->led_cdev;
unsigned long value;
int ret;
if (trigger_data->hw_control && !led_cdev->blink_set)
if (trigger_data->hw_control)
return -EINVAL;
ret = kstrtoul(buf, 0, &value);
@ -472,13 +466,9 @@ static ssize_t interval_store(struct device *dev,
/* impose some basic bounds on the timer interval */
if (value >= 5 && value <= 10000) {
if (trigger_data->hw_control) {
trigger_data->blink_delay = value;
} else {
cancel_delayed_work_sync(&trigger_data->work);
atomic_set(&trigger_data->interval, msecs_to_jiffies(value));
}
set_baseline_state(trigger_data); /* resets timer */
}

View File

@ -197,7 +197,7 @@ int led_update_flash_brightness(struct led_classdev_flash *fled_cdev);
* @fled_cdev: the flash LED to set
* @timeout: the flash timeout to set it to
*
* Set the flash strobe duration.
* Set the flash strobe timeout.
*
* Returns: 0 on success or negative error value on failure
*/

View File

@ -294,7 +294,6 @@ void led_remove_lookup(struct led_lookup_data *led_lookup);
struct led_classdev *__must_check led_get(struct device *dev, char *con_id);
struct led_classdev *__must_check devm_led_get(struct device *dev, char *con_id);
extern struct led_classdev *of_led_get(struct device_node *np, int index);
extern void led_put(struct led_classdev *led_cdev);
struct led_classdev *__must_check devm_of_led_get(struct device *dev,
int index);