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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull LED updates from Lee Jones:
"Updates:
- Add optional GPIO enable pin support to PWM LED driver

Fixes:
- Allow LED module 0 to be added to module bank in lp50xx driver
- Fix upboard LED driver module alias to ensure proper auto-loading
- Update LP5009 to support 3 modules for a total of 9 LEDs
- Skip LEDs without color components in cros_ec driver instead of
failing probe
- Fix GPIO descriptor leaks in netxbig error paths by releasing
acquired GPIOs
- Allow LED_COLOR_ID_MULTI in qcom-lpg driver for greater flexibility
- Enable LP55XX common LED use without FW_LOADER_USER_HELPER
- Ensure lp50xx chip is enabled before any I2C communication

Cleanups:
- Use fwnode_for_each_child_node() instead of
fwnode_for_each_available_child_node() in LED drivers
- Use device_get_next_child_node() instead of
fwnode_get_next_available_child_node() in LED flash drivers
- Replace sprintf() with sysfs_emit() in sysfs show functions for
improved bounds checking
- Replace system_wq() with system_percpu_wq() in the input event
trigger
- Reorder include files to alphabetic order in the PWM LED driver
- Do not enable TRILED in qcom-lpg when configuring PWM
- Drop duplicate LEDS_EXPRESSWIRE config from Kconfig

Removals:
- Remove arcxcnn_bl.txt Device Tree binding documentation

Devicetree bindings:
- Convert ArcticSand arc2c0608 LED driver binding to DT Schema
- Add default-brightness property to common LED binding
- Add enable-gpios property to PWM LED binding
- Add PM7550 to qcom,spmi-flash-led compatible
- Explain standalone PWM usage in qcom-lpg binding"

* tag 'leds-next-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (21 commits)
leds: rgb: leds-qcom-lpg: Don't enable TRILED when configuring PWM
dt-bindings: leds: qcom-lpg: Explain standalone PWM usage
leds: rgb: leds-qcom-lpg: Allow LED_COLOR_ID_MULTI
leds: pwm: Reorder include files to alphabetic order
leds: pwm: Add optional GPIO enable pin support
dt-bindings: leds: pwm: Add enable-gpios property
leds: trigger: Replace use of system_wq() with system_percpu_wq()
leds: led-class: Replace sprintf() with sysfs_emit() in sysfs show functions
dt-bindings: leds: qcom,spmi-flash-led: Add PM7550
leds: netxbig: Fix GPIO descriptor leak in error paths
leds: leds-lp50xx: Enable chip before any communication
leds: Drop duplicate LEDS_EXPRESSWIRE config
leds: leds-cros_ec: Skip LEDs without color components
leds: leds-lp50xx: LP5009 supports 3 modules for a total of 9 LEDs
leds: upboard: Fix module alias
leds: leds-lp50xx: Allow LED 0 to be added to module bank
leds: lp55xx_common: Enable use without FW_LOADER_USER_HELPER
dt-bindings: leds: Add default-brightness property to common.yaml
leds: flash: Use fwnode_get_next_child_node() instead
leds: Use fwnode_for_each_child_node() instead
...

+246 -102
+108
Documentation/devicetree/bindings/leds/backlight/arc,arc2c0608.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/leds/backlight/arc,arc2c0608.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: ArcticSand arc2c0608 LED driver 8 + 9 + description: | 10 + The ArcticSand arc2c0608 LED driver provides ultra 11 + efficient notebook backlighting. Optional properties not 12 + specified will default to values in IC EPROM. 13 + 14 + Datasheet: 15 + https://www.murata.com/-/media/webrenewal/products/power/power-semiconductor/overview/lineup/led-boost/arc2/arc2c0608.ashx. 16 + 17 + maintainers: 18 + - Brian Dodge <bdodge@arcticsand.com> 19 + 20 + allOf: 21 + - $ref: /schemas/leds/common.yaml 22 + 23 + properties: 24 + compatible: 25 + const: arc,arc2c0608 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + default-brightness: 31 + $ref: /schemas/types.yaml#/definitions/uint32 32 + minimum: 0 33 + maximum: 4095 34 + 35 + led-sources: 36 + $ref: /schemas/types.yaml#/definitions/uint32-array 37 + description: List of enabled channels 38 + items: 39 + enum: [0, 1, 2, 3, 4, 5] 40 + minItems: 1 41 + uniqueItems: true 42 + 43 + arc,led-config-0: 44 + $ref: /schemas/types.yaml#/definitions/uint32 45 + description: Fading speed (period between intensity 46 + steps) 47 + 48 + arc,led-config-1: 49 + $ref: /schemas/types.yaml#/definitions/uint32 50 + description: If set, sets ILED_CONFIG register. Used for 51 + fine tuning the maximum LED current. 52 + 53 + arc,dim-freq: 54 + $ref: /schemas/types.yaml#/definitions/uint32 55 + description: PWM mode frequency setting (bits [3:0] used) 56 + 57 + arc,comp-config: 58 + $ref: /schemas/types.yaml#/definitions/uint32 59 + description: Setting for register CONFIG_COMP which 60 + controls internal resitances, feed forward freqs, 61 + and initial VOUT at startup. Consult the datasheet. 62 + 63 + arc,filter-config: 64 + $ref: /schemas/types.yaml#/definitions/uint32 65 + description: RC and PWM Filter settings. 66 + Bit Assignment 67 + 7654 3 2 1 0 68 + xxxx RCF1 RCF0 PWM1 PWM0 69 + RCF statuses PWM Filter Statues 70 + 00 = OFF (default) 00 = OFF (default) 71 + 01 = LOW 01 = 2 STEPS 72 + 10 - MEDIUM 10 = 4 STEPS 73 + 11 = HIGH 11 = 8 STEPS 74 + 75 + arc,trim-config: 76 + $ref: /schemas/types.yaml#/definitions/uint32 77 + description: Sets percentage increase of Maximum LED 78 + Current. 79 + 0x00 = 0% increase. 80 + 0x20 = 20.2%. 81 + 0x3F = 41.5% 82 + 83 + label: true 84 + 85 + linux,default-trigger: true 86 + 87 + additionalProperties: false 88 + 89 + required: 90 + - compatible 91 + - reg 92 + 93 + examples: 94 + - | 95 + i2c { 96 + #address-cells = <1>; 97 + #size-cells = <0>; 98 + 99 + led-controller@30 { 100 + compatible = "arc,arc2c0608"; 101 + reg = <0x30>; 102 + default-brightness = <500>; 103 + label = "lcd-backlight"; 104 + linux,default-trigger = "backlight"; 105 + led-sources = <0 1 2 5>; 106 + }; 107 + }; 108 + ...
-33
Documentation/devicetree/bindings/leds/backlight/arcxcnn_bl.txt
··· 1 - Binding for ArcticSand arc2c0608 LED driver 2 - 3 - Required properties: 4 - - compatible: should be "arc,arc2c0608" 5 - - reg: slave address 6 - 7 - Optional properties: 8 - - default-brightness: brightness value on boot, value from: 0-4095 9 - - label: The name of the backlight device 10 - See Documentation/devicetree/bindings/leds/common.txt 11 - - led-sources: List of enabled channels from 0 to 5. 12 - See Documentation/devicetree/bindings/leds/common.txt 13 - 14 - - arc,led-config-0: setting for register ILED_CONFIG_0 15 - - arc,led-config-1: setting for register ILED_CONFIG_1 16 - - arc,dim-freq: PWM mode frequence setting (bits [3:0] used) 17 - - arc,comp-config: setting for register CONFIG_COMP 18 - - arc,filter-config: setting for register FILTER_CONFIG 19 - - arc,trim-config: setting for register IMAXTUNE 20 - 21 - Note: Optional properties not specified will default to values in IC EPROM 22 - 23 - Example: 24 - 25 - arc2c0608@30 { 26 - compatible = "arc,arc2c0608"; 27 - reg = <0x30>; 28 - default-brightness = <500>; 29 - label = "lcd-backlight"; 30 - linux,default-trigger = "backlight"; 31 - led-sources = <0 1 2 5>; 32 - }; 33 -
+6
Documentation/devicetree/bindings/leds/common.yaml
··· 173 173 led-max-microamp. 174 174 $ref: /schemas/types.yaml#/definitions/uint32 175 175 176 + default-brightness: 177 + description: 178 + Brightness to be set if LED's default state is on. Used only during 179 + initialization. If the option is not set then max brightness is used. 180 + $ref: /schemas/types.yaml#/definitions/uint32 181 + 176 182 panic-indicator: 177 183 description: 178 184 This property specifies that the LED should be used, if at all possible,
+7
Documentation/devicetree/bindings/leds/leds-pwm.yaml
··· 40 40 initialization. If the option is not set then max brightness is used. 41 41 $ref: /schemas/types.yaml#/definitions/uint32 42 42 43 + enable-gpios: 44 + description: 45 + GPIO for LED hardware enable control. Set active when brightness is 46 + non-zero and inactive when brightness is zero. 47 + The GPIO default state follows the "default-state" property. 48 + maxItems: 1 49 + 43 50 required: 44 51 - pwms 45 52 - max-brightness
+5
Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml
··· 13 13 The Qualcomm Light Pulse Generator consists of three different hardware blocks; 14 14 a ramp generator with lookup table (LUT), the light pulse generator and a three 15 15 channel current sink. These blocks are found in a wide range of Qualcomm PMICs. 16 + The light pulse generator (LPG) can also be used independently to output PWM 17 + signal for standard PWM applications. In this scenario, the LPG output should 18 + be routed to a specific PMIC GPIO by setting the GPIO pin mux to the special 19 + functions indicated in the datasheet, the TRILED driver for the channel will 20 + not be enabled in this configuration. 16 21 17 22 properties: 18 23 compatible:
+1
Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml
··· 24 24 - enum: 25 25 - qcom,pm6150l-flash-led 26 26 - qcom,pm660l-flash-led 27 + - qcom,pm7550-flash-led 27 28 - qcom,pm8150c-flash-led 28 29 - qcom,pm8150l-flash-led 29 30 - qcom,pm8350c-flash-led
+1 -1
Documentation/leds/leds-lp5521.rst
··· 22 22 LP5521 has the internal program memory for running various LED patterns. 23 23 There are two ways to run LED patterns. 24 24 25 - 1) Legacy interface - enginex_mode and enginex_load 25 + 1) sysfs interface - enginex_mode and enginex_load 26 26 Control interface for the engines: 27 27 28 28 x is 1 .. 3
+1 -1
Documentation/leds/leds-lp5523.rst
··· 35 35 LP5523 has the internal program memory for running various LED patterns. 36 36 There are two ways to run LED patterns. 37 37 38 - 1) Legacy interface - enginex_mode, enginex_load and enginex_leds 38 + 1) sysfs interface - enginex_mode, enginex_load and enginex_leds 39 39 40 40 Control interface for the engines: 41 41
+2 -6
drivers/leds/Kconfig
··· 214 214 To compile this driver as a module, choose M here: the module 215 215 will be called leds-el15203000. 216 216 217 - config LEDS_EXPRESSWIRE 218 - bool 219 - depends on GPIOLIB 220 - 221 217 config LEDS_TURRIS_OMNIA 222 218 tristate "LED support for CZ.NIC's Turris Omnia" 223 219 depends on LEDS_CLASS_MULTICOLOR ··· 439 443 depends on LEDS_CLASS_MULTICOLOR 440 444 depends on OF 441 445 depends on I2C 442 - select FW_LOADER 443 - select FW_LOADER_USER_HELPER 446 + imply FW_LOADER 447 + imply FW_LOADER_USER_HELPER 444 448 help 445 449 This option supports common operations for LP5521/5523/55231/5562/5569/ 446 450 8501 devices.
+1 -1
drivers/leds/flash/leds-rt4505.c
··· 365 365 return ret; 366 366 } 367 367 368 - child = fwnode_get_next_available_child_node(client->dev.fwnode, NULL); 368 + child = device_get_next_child_node(&client->dev, NULL); 369 369 if (!child) { 370 370 dev_err(priv->dev, "Failed to get child node\n"); 371 371 return -EINVAL;
+1 -1
drivers/leds/flash/leds-rt8515.c
··· 304 304 return dev_err_probe(dev, PTR_ERR(rt->enable_torch), 305 305 "cannot get ENT (enable torch) GPIO\n"); 306 306 307 - child = fwnode_get_next_available_child_node(dev->fwnode, NULL); 307 + child = device_get_next_child_node(dev, NULL); 308 308 if (!child) { 309 309 dev_err(dev, 310 310 "No fwnode child node found for connected LED.\n");
+1 -2
drivers/leds/flash/leds-sgm3140.c
··· 214 214 return dev_err_probe(&pdev->dev, ret, 215 215 "Failed to request regulator\n"); 216 216 217 - child_node = fwnode_get_next_available_child_node(pdev->dev.fwnode, 218 - NULL); 217 + child_node = device_get_next_child_node(&pdev->dev, NULL); 219 218 if (!child_node) { 220 219 dev_err(&pdev->dev, 221 220 "No fwnode child node found for connected LED.\n");
+1 -1
drivers/leds/flash/leds-tps6131x.c
··· 544 544 545 545 tps6131x->valley_current_limit = device_property_read_bool(dev, "ti,valley-current-limit"); 546 546 547 - tps6131x->led_node = fwnode_get_next_available_child_node(dev->fwnode, NULL); 547 + tps6131x->led_node = device_get_next_child_node(dev, NULL); 548 548 if (!tps6131x->led_node) { 549 549 dev_err(dev, "Missing LED node\n"); 550 550 return -EINVAL;
+3 -3
drivers/leds/led-class.c
··· 38 38 brightness = led_cdev->brightness; 39 39 mutex_unlock(&led_cdev->led_access); 40 40 41 - return sprintf(buf, "%u\n", brightness); 41 + return sysfs_emit(buf, "%u\n", brightness); 42 42 } 43 43 44 44 static ssize_t brightness_store(struct device *dev, ··· 80 80 max_brightness = led_cdev->max_brightness; 81 81 mutex_unlock(&led_cdev->led_access); 82 82 83 - return sprintf(buf, "%u\n", max_brightness); 83 + return sysfs_emit(buf, "%u\n", max_brightness); 84 84 } 85 85 static DEVICE_ATTR_RO(max_brightness); 86 86 ··· 122 122 if (led_cdev->brightness_hw_changed == -1) 123 123 return -ENODATA; 124 124 125 - return sprintf(buf, "%u\n", led_cdev->brightness_hw_changed); 125 + return sysfs_emit(buf, "%u\n", led_cdev->brightness_hw_changed); 126 126 } 127 127 128 128 static DEVICE_ATTR_RO(brightness_hw_changed);
+2 -3
drivers/leds/leds-cros_ec.c
··· 142 142 } 143 143 } 144 144 145 - if (!num_subleds) 146 - return -EINVAL; 147 - 148 145 *max_brightness = common_range; 149 146 return num_subleds; 150 147 } ··· 186 189 &priv->led_mc_cdev.led_cdev.max_brightness); 187 190 if (num_subleds < 0) 188 191 return num_subleds; 192 + if (num_subleds == 0) 193 + return 0; /* LED without any colors, skip */ 189 194 190 195 priv->cros_ec = cros_ec; 191 196 priv->led_id = id;
+45 -22
drivers/leds/leds-lp50xx.c
··· 50 50 51 51 #define LP50XX_SW_RESET 0xff 52 52 #define LP50XX_CHIP_EN BIT(6) 53 + #define LP50XX_CHIP_DISABLE 0x00 54 + #define LP50XX_START_TIME_US 500 55 + #define LP50XX_RESET_TIME_US 3 56 + 57 + #define LP50XX_EN_GPIO_LOW 0 58 + #define LP50XX_EN_GPIO_HIGH 1 53 59 54 60 /* There are 3 LED outputs per bank */ 55 61 #define LP50XX_LEDS_PER_MODULE 3 56 62 57 - #define LP5009_MAX_LED_MODULES 2 63 + #define LP5009_MAX_LED_MODULES 3 58 64 #define LP5012_MAX_LED_MODULES 4 59 65 #define LP5018_MAX_LED_MODULES 6 60 66 #define LP5024_MAX_LED_MODULES 8 ··· 347 341 return ret; 348 342 } 349 343 350 - static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[]) 344 + static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[], int num_leds) 351 345 { 352 346 u8 led_config_lo, led_config_hi; 353 347 u32 bank_enable_mask = 0; 354 348 int ret; 355 349 int i; 356 350 357 - for (i = 0; i < priv->chip_info->max_modules; i++) { 358 - if (led_banks[i]) 359 - bank_enable_mask |= (1 << led_banks[i]); 360 - } 351 + for (i = 0; i < num_leds; i++) 352 + bank_enable_mask |= (1 << led_banks[i]); 361 353 362 354 led_config_lo = bank_enable_mask; 363 355 led_config_hi = bank_enable_mask >> 8; ··· 375 371 return regmap_write(priv->regmap, priv->chip_info->reset_reg, LP50XX_SW_RESET); 376 372 } 377 373 378 - static int lp50xx_enable_disable(struct lp50xx *priv, int enable_disable) 374 + static int lp50xx_enable(struct lp50xx *priv) 379 375 { 380 376 int ret; 381 377 382 - ret = gpiod_direction_output(priv->enable_gpio, enable_disable); 378 + if (priv->enable_gpio) { 379 + ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_HIGH); 380 + if (ret) 381 + return ret; 382 + 383 + udelay(LP50XX_START_TIME_US); 384 + } 385 + 386 + ret = lp50xx_reset(priv); 383 387 if (ret) 384 388 return ret; 385 389 386 - if (enable_disable) 387 - return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); 388 - else 389 - return regmap_write(priv->regmap, LP50XX_DEV_CFG0, 0); 390 + return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); 391 + } 390 392 393 + static int lp50xx_disable(struct lp50xx *priv) 394 + { 395 + int ret; 396 + 397 + ret = regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_DISABLE); 398 + if (ret) 399 + return ret; 400 + 401 + if (priv->enable_gpio) { 402 + ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_LOW); 403 + if (ret) 404 + return ret; 405 + 406 + udelay(LP50XX_RESET_TIME_US); 407 + } 408 + 409 + return 0; 391 410 } 392 411 393 412 static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv, ··· 432 405 return ret; 433 406 } 434 407 435 - ret = lp50xx_set_banks(priv, led_banks); 408 + ret = lp50xx_set_banks(priv, led_banks, num_leds); 436 409 if (ret) { 437 410 dev_err(priv->dev, "Cannot setup banked LEDs\n"); 438 411 return ret; ··· 473 446 if (IS_ERR(priv->enable_gpio)) 474 447 return dev_err_probe(priv->dev, PTR_ERR(priv->enable_gpio), 475 448 "Failed to get enable GPIO\n"); 449 + 450 + ret = lp50xx_enable(priv); 451 + if (ret) 452 + return ret; 476 453 477 454 priv->regulator = devm_regulator_get(priv->dev, "vled"); 478 455 if (IS_ERR(priv->regulator)) ··· 578 547 return ret; 579 548 } 580 549 581 - ret = lp50xx_reset(led); 582 - if (ret) 583 - return ret; 584 - 585 - ret = lp50xx_enable_disable(led, 1); 586 - if (ret) 587 - return ret; 588 - 589 550 return lp50xx_probe_dt(led); 590 551 } 591 552 ··· 586 563 struct lp50xx *led = i2c_get_clientdata(client); 587 564 int ret; 588 565 589 - ret = lp50xx_enable_disable(led, 0); 566 + ret = lp50xx_disable(led); 590 567 if (ret) 591 568 dev_err(led->dev, "Failed to disable chip\n"); 592 569
+1 -1
drivers/leds/leds-max5970.c
··· 60 60 if (!led_node) 61 61 return -ENODEV; 62 62 63 - fwnode_for_each_available_child_node(led_node, child) { 63 + fwnode_for_each_child_node(led_node, child) { 64 64 u32 reg; 65 65 66 66 if (fwnode_property_read_u32(child, "reg", &reg))
+1 -1
drivers/leds/leds-max77705.c
··· 191 191 cdev->brightness_set_blocking = max77705_led_brightness_set_multi; 192 192 cdev->blink_set = max77705_rgb_blink; 193 193 194 - fwnode_for_each_available_child_node(np, child) { 194 + fwnode_for_each_child_node(np, child) { 195 195 ret = max77705_parse_subled(dev, child, &info[i]); 196 196 if (ret < 0) 197 197 return ret;
+26 -10
drivers/leds/leds-netxbig.c
··· 364 364 if (!addr) 365 365 return -ENOMEM; 366 366 367 + gpio_ext->addr = addr; 368 + gpio_ext->num_addr = 0; 369 + 367 370 /* 368 371 * We cannot use devm_ managed resources with these GPIO descriptors 369 372 * since they are associated with the "GPIO extension device" which ··· 378 375 gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, 379 376 GPIOD_OUT_LOW); 380 377 if (IS_ERR(gpiod)) 381 - return PTR_ERR(gpiod); 378 + goto err_set_code; 382 379 gpiod_set_consumer_name(gpiod, "GPIO extension addr"); 383 380 addr[i] = gpiod; 381 + gpio_ext->num_addr++; 384 382 } 385 - gpio_ext->addr = addr; 386 - gpio_ext->num_addr = num_addr; 387 383 388 384 ret = gpiod_count(gpio_ext_dev, "data"); 389 385 if (ret < 0) { 390 386 dev_err(dev, 391 387 "Failed to count GPIOs in DT property data-gpios\n"); 392 - return ret; 388 + goto err_free_addr; 393 389 } 394 390 num_data = ret; 395 391 data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); 396 - if (!data) 397 - return -ENOMEM; 392 + if (!data) { 393 + ret = -ENOMEM; 394 + goto err_free_addr; 395 + } 396 + 397 + gpio_ext->data = data; 398 + gpio_ext->num_data = 0; 398 399 399 400 for (i = 0; i < num_data; i++) { 400 401 gpiod = gpiod_get_index(gpio_ext_dev, "data", i, 401 402 GPIOD_OUT_LOW); 402 403 if (IS_ERR(gpiod)) 403 - return PTR_ERR(gpiod); 404 + goto err_free_data; 404 405 gpiod_set_consumer_name(gpiod, "GPIO extension data"); 405 406 data[i] = gpiod; 407 + gpio_ext->num_data++; 406 408 } 407 - gpio_ext->data = data; 408 - gpio_ext->num_data = num_data; 409 409 410 410 gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); 411 411 if (IS_ERR(gpiod)) { 412 412 dev_err(dev, 413 413 "Failed to get GPIO from DT property enable-gpio\n"); 414 - return PTR_ERR(gpiod); 414 + goto err_free_data; 415 415 } 416 416 gpiod_set_consumer_name(gpiod, "GPIO extension enable"); 417 417 gpio_ext->enable = gpiod; 418 418 419 419 return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); 420 + 421 + err_free_data: 422 + for (i = 0; i < gpio_ext->num_data; i++) 423 + gpiod_put(gpio_ext->data[i]); 424 + err_set_code: 425 + ret = PTR_ERR(gpiod); 426 + err_free_addr: 427 + for (i = 0; i < gpio_ext->num_addr; i++) 428 + gpiod_put(gpio_ext->addr[i]); 429 + return ret; 420 430 } 421 431 422 432 static int netxbig_leds_get_of_pdata(struct device *dev,
+24 -5
drivers/leds/leds-pwm.c
··· 9 9 * based on leds-gpio.c by Raphael Assenat <raph@8d.com> 10 10 */ 11 11 12 - #include <linux/module.h> 13 - #include <linux/kernel.h> 14 - #include <linux/platform_device.h> 15 - #include <linux/of.h> 16 - #include <linux/leds.h> 17 12 #include <linux/err.h> 13 + #include <linux/gpio/consumer.h> 14 + #include <linux/kernel.h> 15 + #include <linux/leds.h> 16 + #include <linux/module.h> 17 + #include <linux/of.h> 18 + #include <linux/platform_device.h> 18 19 #include <linux/pwm.h> 19 20 #include <linux/slab.h> 20 21 ··· 27 26 }; 28 27 29 28 struct led_pwm_data { 29 + struct gpio_desc *enable_gpio; 30 30 struct led_classdev cdev; 31 31 struct pwm_device *pwm; 32 32 struct pwm_state pwmstate; ··· 52 50 53 51 if (led_dat->active_low) 54 52 duty = led_dat->pwmstate.period - duty; 53 + 54 + gpiod_set_value_cansleep(led_dat->enable_gpio, !!brightness); 55 55 56 56 led_dat->pwmstate.duty_cycle = duty; 57 57 /* ··· 135 131 } 136 132 break; 137 133 } 134 + 135 + /* 136 + * Claim the GPIO as GPIOD_ASIS and set the value 137 + * later on to honor the different default states 138 + */ 139 + led_data->enable_gpio = devm_fwnode_gpiod_get(dev, fwnode, "enable", GPIOD_ASIS, NULL); 140 + if (IS_ERR(led_data->enable_gpio)) { 141 + if (PTR_ERR(led_data->enable_gpio) == -ENOENT) 142 + /* Enable GPIO is optional */ 143 + led_data->enable_gpio = NULL; 144 + else 145 + return PTR_ERR(led_data->enable_gpio); 146 + } 147 + 148 + gpiod_direction_output(led_data->enable_gpio, !!led_data->cdev.brightness); 138 149 139 150 ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data); 140 151 if (ret) {
+1 -1
drivers/leds/leds-upboard.c
··· 123 123 MODULE_AUTHOR("Thomas Richard <thomas.richard@bootlin.com>"); 124 124 MODULE_DESCRIPTION("UP Board LED driver"); 125 125 MODULE_LICENSE("GPL"); 126 - MODULE_ALIAS("platform:upboard-led"); 126 + MODULE_ALIAS("platform:upboard-leds");
+2 -2
drivers/leds/rgb/leds-ktd202x.c
··· 391 391 int i = 0; 392 392 393 393 num_channels = 0; 394 - fwnode_for_each_available_child_node(fwnode, child) 394 + fwnode_for_each_child_node(fwnode, child) 395 395 num_channels++; 396 396 397 397 if (!num_channels || num_channels > chip->num_leds) ··· 401 401 if (!info) 402 402 return -ENOMEM; 403 403 404 - fwnode_for_each_available_child_node(fwnode, child) { 404 + fwnode_for_each_child_node(fwnode, child) { 405 405 u32 mono_color; 406 406 u32 reg; 407 407 int ret;
+1 -1
drivers/leds/rgb/leds-ncp5623.c
··· 180 180 goto release_mc_node; 181 181 } 182 182 183 - fwnode_for_each_available_child_node(mc_node, led_node) { 183 + fwnode_for_each_child_node(mc_node, led_node) { 184 184 ret = fwnode_property_read_u32(led_node, "color", &color_index); 185 185 if (ret) 186 186 goto release_led_node;
+4 -6
drivers/leds/rgb/leds-qcom-lpg.c
··· 2 2 /* 3 3 * Copyright (c) 2017-2022 Linaro Ltd 4 4 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. 5 - * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. 5 + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 6 6 */ 7 7 #include <linux/bits.h> 8 8 #include <linux/bitfield.h> ··· 1247 1247 1248 1248 lpg_apply(chan); 1249 1249 1250 - triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0); 1251 - 1252 1250 out_unlock: 1253 1251 mutex_unlock(&lpg->lock); 1254 1252 ··· 1380 1382 return dev_err_probe(lpg->dev, ret, 1381 1383 "failed to parse \"color\" of %pOF\n", np); 1382 1384 1383 - if (color == LED_COLOR_ID_RGB) 1385 + if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) 1384 1386 num_channels = of_get_available_child_count(np); 1385 1387 else 1386 1388 num_channels = 1; ··· 1392 1394 led->lpg = lpg; 1393 1395 led->num_channels = num_channels; 1394 1396 1395 - if (color == LED_COLOR_ID_RGB) { 1397 + if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) { 1396 1398 info = devm_kcalloc(lpg->dev, num_channels, sizeof(*info), GFP_KERNEL); 1397 1399 if (!info) 1398 1400 return -ENOMEM; ··· 1452 1454 1453 1455 init_data.fwnode = of_fwnode_handle(np); 1454 1456 1455 - if (color == LED_COLOR_ID_RGB) 1457 + if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) 1456 1458 ret = devm_led_classdev_multicolor_register_ext(lpg->dev, &led->mcdev, &init_data); 1457 1459 else 1458 1460 ret = devm_led_classdev_register_ext(lpg->dev, &led->cdev, &init_data);
+1 -1
drivers/leds/trigger/ledtrig-input-events.c
··· 66 66 67 67 spin_unlock_irqrestore(&data->lock, flags); 68 68 69 - mod_delayed_work(system_wq, &data->work, led_off_delay); 69 + mod_delayed_work(system_percpu_wq, &data->work, led_off_delay); 70 70 } 71 71 72 72 static int input_events_connect(struct input_handler *handler, struct input_dev *dev,