Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+45 -33
+12 -7
Documentation/devicetree/bindings/leds/leds-lp50xx.yaml
··· 81 81 82 82 properties: 83 83 reg: 84 - maxItems: 1 84 + items: 85 + - minimum: 0 86 + maximum: 2 87 + 88 + description: 89 + This property denotes the index within the LED bank. 85 90 86 91 required: 87 92 - reg ··· 143 138 color = <LED_COLOR_ID_RGB>; 144 139 function = LED_FUNCTION_STANDBY; 145 140 146 - led@3 { 147 - reg = <0x3>; 141 + led@0 { 142 + reg = <0x0>; 148 143 color = <LED_COLOR_ID_RED>; 149 144 }; 150 145 151 - led@4 { 152 - reg = <0x4>; 146 + led@1 { 147 + reg = <0x1>; 153 148 color = <LED_COLOR_ID_GREEN>; 154 149 }; 155 150 156 - led@5 { 157 - reg = <0x5>; 151 + led@2 { 152 + reg = <0x2>; 158 153 color = <LED_COLOR_ID_BLUE>; 159 154 }; 160 155 };
+3 -1
Documentation/devicetree/bindings/leds/onnn,ncp5623.yaml
··· 19 19 - onnn,ncp5623 20 20 21 21 reg: 22 - const: 0x38 22 + enum: 23 + - 0x38 24 + - 0x39 23 25 24 26 multi-led: 25 27 type: object
+1 -1
MAINTAINERS
··· 24813 24813 M: Matthias Fend <matthias.fend@emfend.at> 24814 24814 L: linux-leds@vger.kernel.org 24815 24815 S: Maintained 24816 - F: Documentation/devicetree/bindings/leds/ti,tps6131x.yaml 24816 + F: Documentation/devicetree/bindings/leds/ti,tps61310.yaml 24817 24817 F: drivers/leds/flash/leds-tps6131x.c 24818 24818 24819 24819 TEXAS INSTRUMENTS' DAC7612 DAC DRIVER
+1
drivers/leds/flash/Kconfig
··· 136 136 tristate "LED support for TI TPS6131x flash LED driver" 137 137 depends on I2C && OF 138 138 depends on GPIOLIB 139 + depends on V4L2_FLASH_LED_CLASS || !V4L2_FLASH_LED_CLASS 139 140 select REGMAP_I2C 140 141 help 141 142 This option enables support for Texas Instruments TPS61310/TPS61311
+11 -4
drivers/leds/flash/leds-qcom-flash.c
··· 117 117 REG_MAX_COUNT, 118 118 }; 119 119 120 - static struct reg_field mvflash_3ch_regs[REG_MAX_COUNT] = { 120 + static const struct reg_field mvflash_3ch_regs[REG_MAX_COUNT] = { 121 121 REG_FIELD(0x08, 0, 7), /* status1 */ 122 122 REG_FIELD(0x09, 0, 7), /* status2 */ 123 123 REG_FIELD(0x0a, 0, 7), /* status3 */ ··· 132 132 REG_FIELD(0x58, 0, 2), /* therm_thrsh3 */ 133 133 }; 134 134 135 - static struct reg_field mvflash_4ch_regs[REG_MAX_COUNT] = { 135 + static const struct reg_field mvflash_4ch_regs[REG_MAX_COUNT] = { 136 136 REG_FIELD(0x06, 0, 7), /* status1 */ 137 137 REG_FIELD(0x07, 0, 6), /* status2 */ 138 138 REG_FIELD(0x09, 0, 7), /* status3 */ ··· 854 854 if (val == FLASH_SUBTYPE_3CH_PM8150_VAL || val == FLASH_SUBTYPE_3CH_PMI8998_VAL) { 855 855 flash_data->hw_type = QCOM_MVFLASH_3CH; 856 856 flash_data->max_channels = 3; 857 - regs = mvflash_3ch_regs; 857 + regs = devm_kmemdup(dev, mvflash_3ch_regs, sizeof(mvflash_3ch_regs), 858 + GFP_KERNEL); 859 + if (!regs) 860 + return -ENOMEM; 858 861 } else if (val == FLASH_SUBTYPE_4CH_VAL) { 859 862 flash_data->hw_type = QCOM_MVFLASH_4CH; 860 863 flash_data->max_channels = 4; 861 - regs = mvflash_4ch_regs; 864 + regs = devm_kmemdup(dev, mvflash_4ch_regs, sizeof(mvflash_4ch_regs), 865 + GFP_KERNEL); 866 + if (!regs) 867 + return -ENOMEM; 862 868 863 869 rc = regmap_read(regmap, reg_base + FLASH_REVISION_REG, &val); 864 870 if (rc < 0) { ··· 886 880 dev_err(dev, "Failed to allocate regmap field, rc=%d\n", rc); 887 881 return rc; 888 882 } 883 + devm_kfree(dev, regs); /* devm_regmap_field_bulk_alloc() makes copies */ 889 884 890 885 platform_set_drvdata(pdev, flash_data); 891 886 mutex_init(&flash_data->lock);
+1 -2
drivers/leds/led-class.c
··· 256 256 * Returns the LED device parsed from the phandle specified in the "leds" 257 257 * property of a device tree node or a negative error-code on failure. 258 258 */ 259 - struct led_classdev *of_led_get(struct device_node *np, int index) 259 + static struct led_classdev *of_led_get(struct device_node *np, int index) 260 260 { 261 261 struct device *led_dev; 262 262 struct device_node *led_node; ··· 270 270 271 271 return led_module_get(led_dev); 272 272 } 273 - EXPORT_SYMBOL_GPL(of_led_get); 274 273 275 274 /** 276 275 * led_put() - release a LED device
+10 -1
drivers/leds/leds-lp50xx.c
··· 476 476 return -ENOMEM; 477 477 478 478 fwnode_for_each_child_node(child, led_node) { 479 + int multi_index; 479 480 ret = fwnode_property_read_u32(led_node, "color", 480 481 &color_id); 481 482 if (ret) { ··· 484 483 dev_err(priv->dev, "Cannot read color\n"); 485 484 return ret; 486 485 } 486 + ret = fwnode_property_read_u32(led_node, "reg", &multi_index); 487 + if (ret != 0) { 488 + dev_err(priv->dev, "reg must be set\n"); 489 + return -EINVAL; 490 + } else if (multi_index >= LP50XX_LEDS_PER_MODULE) { 491 + dev_err(priv->dev, "reg %i out of range\n", multi_index); 492 + return -EINVAL; 493 + } 487 494 488 - mc_led_info[num_colors].color_index = color_id; 495 + mc_led_info[multi_index].color_index = color_id; 489 496 num_colors++; 490 497 } 491 498
+2 -2
drivers/leds/leds-pca955x.c
··· 587 587 struct pca955x_platform_data *pdata; 588 588 bool keep_psc0 = false; 589 589 bool set_default_label = false; 590 - char default_label[8]; 590 + char default_label[4]; 591 591 int bit, err, reg; 592 592 593 593 chip = i2c_get_match_data(client); ··· 693 693 } 694 694 695 695 if (set_default_label) { 696 - snprintf(default_label, sizeof(default_label), "%u", i); 696 + snprintf(default_label, sizeof(default_label), "%hhu", i); 697 697 init_data.default_label = default_label; 698 698 } else { 699 699 init_data.default_label = NULL;
+3 -13
drivers/leds/trigger/ledtrig-netdev.c
··· 68 68 unsigned int last_activity; 69 69 70 70 unsigned long mode; 71 - unsigned long blink_delay; 72 71 int link_speed; 73 72 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported_link_modes); 74 73 u8 duplex; ··· 86 87 /* Already validated, hw control is possible with the requested mode */ 87 88 if (trigger_data->hw_control) { 88 89 led_cdev->hw_control_set(led_cdev, trigger_data->mode); 89 - if (led_cdev->blink_set) { 90 - led_cdev->blink_set(led_cdev, &trigger_data->blink_delay, 91 - &trigger_data->blink_delay); 92 - } 93 90 94 91 return; 95 92 } ··· 454 459 size_t size) 455 460 { 456 461 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); 457 - struct led_classdev *led_cdev = trigger_data->led_cdev; 458 462 unsigned long value; 459 463 int ret; 460 464 461 - if (trigger_data->hw_control && !led_cdev->blink_set) 465 + if (trigger_data->hw_control) 462 466 return -EINVAL; 463 467 464 468 ret = kstrtoul(buf, 0, &value); ··· 466 472 467 473 /* impose some basic bounds on the timer interval */ 468 474 if (value >= 5 && value <= 10000) { 469 - if (trigger_data->hw_control) { 470 - trigger_data->blink_delay = value; 471 - } else { 472 - cancel_delayed_work_sync(&trigger_data->work); 475 + cancel_delayed_work_sync(&trigger_data->work); 473 476 474 - atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); 475 - } 477 + atomic_set(&trigger_data->interval, msecs_to_jiffies(value)); 476 478 set_baseline_state(trigger_data); /* resets timer */ 477 479 } 478 480
+1 -1
include/linux/led-class-flash.h
··· 197 197 * @fled_cdev: the flash LED to set 198 198 * @timeout: the flash timeout to set it to 199 199 * 200 - * Set the flash strobe duration. 200 + * Set the flash strobe timeout. 201 201 * 202 202 * Returns: 0 on success or negative error value on failure 203 203 */
-1
include/linux/leds.h
··· 294 294 struct led_classdev *__must_check led_get(struct device *dev, char *con_id); 295 295 struct led_classdev *__must_check devm_led_get(struct device *dev, char *con_id); 296 296 297 - extern struct led_classdev *of_led_get(struct device_node *np, int index); 298 297 extern void led_put(struct led_classdev *led_cdev); 299 298 struct led_classdev *__must_check devm_of_led_get(struct device *dev, 300 299 int index);