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.12' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds

Pull LED updates from Lee Jones:

- Limited LED current based on thermal conditions in the QCOM flash LED
driver

- Fixed device child node usage in the BD2606MVV and PCA995x drivers

- Used device_for_each_child_node_scoped() to access child nodes in the
IS31FL319X driver

- Reset the LED controller during the probe in the LM3601X driver

- Used device_for_each_child_node() to access device child nodes in the
PCA995X driver

- Fixed CONFIG_LEDS_CLASS_MULTICOLOR dependency in the BlinkM driver

- Replaced msleep() with usleep_range() in the SUN50I-A100 driver

- Used scoped device node handling to simplify error paths in the
AAT1290, KTD2692, and MC13783 drivers

- Added missing of_node_get for probe duration in the MAX77693 driver

- Simplified using for_each_available_child_of_node_scoped() loops when
iterating over device nodes

- Used devm_clk_get_enabled() helpers in the LP55XX driver

- Converted DT bindings from TXT to YAML format for various drivers,
including LM3692x and SC2731-BLTC

- Set num_leds after allocation in the GPIO driver

- Removed irrelevant blink configuration error message in the PCA9532
driver

- Fixed module autoloading with MODULE_DEVICE_TABLE() in the Turris
Omnia driver

* tag 'leds-next-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (38 commits)
leds: turris-omnia: Fix module autoloading with MODULE_DEVICE_TABLE()
leds: pca9532: Remove irrelevant blink configuration error message
leds: gpio: Set num_leds after allocation
dt-bindings: leds: Convert leds-lm3692x to YAML format
leds: lp55xx: Use devm_clk_get_enabled() helpers
leds: as3645a: Use device_* to iterate over device child nodes
leds: qcom-lpg: Simplify with scoped for each OF child loop
leds: turris-omnia: Simplify with scoped for each OF child loop
leds: sc27xx: Simplify with scoped for each OF child loop
leds: pca9532: Simplify with scoped for each OF child loop
leds: netxbig: Simplify with scoped for each OF child loop
leds: mt6323: Simplify with scoped for each OF child loop
leds: mc13783: Use scoped device node handling to simplify error paths
leds: lp55xx: Simplify with scoped for each OF child loop
leds: is31fl32xx: Simplify with scoped for each OF child loop
leds: bcm6358: Simplify with scoped for each OF child loop
leds: bcm6328: Simplify with scoped for each OF child loop
leds: aw2013: Simplify with scoped for each OF child loop
leds: 88pm860x: Simplify with scoped for each OF child loop
leds: max77693: Simplify with scoped for each OF child loop
...

+778 -428
+2
Documentation/devicetree/bindings/leds/common.yaml
··· 113 113 # LED indicates NAND memory activity (deprecated), 114 114 # in new implementations use "mtd" 115 115 - nand-disk 116 + # LED indicates network activity 117 + - netdev 116 118 # No trigger assigned to the LED. This is the default mode 117 119 # if trigger is absent 118 120 - none
-65
Documentation/devicetree/bindings/leds/leds-lm3692x.txt
··· 1 - * Texas Instruments - LM3692x Highly Efficient White LED Driver 2 - 3 - The LM3692x is an ultra-compact, highly efficient, 4 - white-LED driver designed for LCD display backlighting. 5 - 6 - The main difference between the LM36922 and LM36923 is the number of 7 - LED strings it supports. The LM36922 supports two strings while the LM36923 8 - supports three strings. 9 - 10 - Required properties: 11 - - compatible: 12 - "ti,lm36922" 13 - "ti,lm36923" 14 - - reg : I2C slave address 15 - - #address-cells : 1 16 - - #size-cells : 0 17 - 18 - Optional properties: 19 - - enable-gpios : gpio pin to enable/disable the device. 20 - - vled-supply : LED supply 21 - - ti,ovp-microvolt: Overvoltage protection in 22 - micro-volt, can be 17000000, 21000000, 25000000 or 23 - 29000000. If ti,ovp-microvolt is not specified it 24 - defaults to 29000000. 25 - 26 - Required child properties: 27 - - reg : 0 - Will enable all LED sync paths 28 - 1 - Will enable the LED1 sync 29 - 2 - Will enable the LED2 sync 30 - 3 - Will enable the LED3 sync (LM36923 only) 31 - 32 - Optional child properties: 33 - - function : see Documentation/devicetree/bindings/leds/common.txt 34 - - color : see Documentation/devicetree/bindings/leds/common.txt 35 - - label : see Documentation/devicetree/bindings/leds/common.txt (deprecated) 36 - - linux,default-trigger : 37 - see Documentation/devicetree/bindings/leds/common.txt 38 - - led-max-microamp : 39 - see Documentation/devicetree/bindings/leds/common.txt 40 - 41 - Example: 42 - 43 - #include <dt-bindings/leds/common.h> 44 - 45 - led-controller@36 { 46 - compatible = "ti,lm3692x"; 47 - reg = <0x36>; 48 - #address-cells = <1>; 49 - #size-cells = <0>; 50 - 51 - enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; 52 - vled-supply = <&vbatt>; 53 - ti,ovp-microvolt = <29000000>; 54 - 55 - led@0 { 56 - reg = <0>; 57 - function = LED_FUNCTION_BACKLIGHT; 58 - color = <LED_COLOR_ID_WHITE>; 59 - linux,default-trigger = "backlight"; 60 - led-max-microamp = <20000>; 61 - }; 62 - } 63 - 64 - For more product information please see the link below: 65 - https://www.ti.com/lit/ds/snvsa29/snvsa29.pdf
-43
Documentation/devicetree/bindings/leds/leds-sc27xx-bltc.txt
··· 1 - LEDs connected to Spreadtrum SC27XX PMIC breathing light controller 2 - 3 - The SC27xx breathing light controller supports to 3 outputs: 4 - red LED, green LED and blue LED. Each LED can work at normal 5 - PWM mode or breath light mode. 6 - 7 - Required properties: 8 - - compatible: Should be "sprd,sc2731-bltc". 9 - - #address-cells: Must be 1. 10 - - #size-cells: Must be 0. 11 - - reg: Specify the controller address. 12 - 13 - Required child properties: 14 - - reg: Port this LED is connected to. 15 - 16 - Optional child properties: 17 - - function: See Documentation/devicetree/bindings/leds/common.txt. 18 - - color: See Documentation/devicetree/bindings/leds/common.txt. 19 - - label: See Documentation/devicetree/bindings/leds/common.txt (deprecated). 20 - 21 - Examples: 22 - 23 - led-controller@200 { 24 - compatible = "sprd,sc2731-bltc"; 25 - #address-cells = <1>; 26 - #size-cells = <0>; 27 - reg = <0x200>; 28 - 29 - led@0 { 30 - color = <LED_COLOR_ID_RED>; 31 - reg = <0x0>; 32 - }; 33 - 34 - led@1 { 35 - color = <LED_COLOR_ID_GREEN>; 36 - reg = <0x1>; 37 - }; 38 - 39 - led@2 { 40 - color = <LED_COLOR_ID_BLUE>; 41 - reg = <0x2>; 42 - }; 43 - };
+4 -2
Documentation/devicetree/bindings/leds/nxp,pca995x.yaml
··· 11 11 - Marek Vasut <marex@denx.de> 12 12 13 13 description: 14 - The NXP PCA9952/PCA9955B are programmable LED controllers connected via I2C 15 - that can drive 16 separate lines. Each of them can be individually switched 14 + The NXP PCA995x family are programmable LED controllers connected via I2C 15 + that can drive separate lines. Each of them can be individually switched 16 16 on and off, and brightness can be controlled via individual PWM. 17 17 18 18 Datasheets are available at 19 19 https://www.nxp.com/docs/en/data-sheet/PCA9952_PCA9955.pdf 20 20 https://www.nxp.com/docs/en/data-sheet/PCA9955B.pdf 21 + https://www.nxp.com/docs/en/data-sheet/PCA9956B.pdf 21 22 22 23 properties: 23 24 compatible: 24 25 enum: 25 26 - nxp,pca9952 26 27 - nxp,pca9955b 28 + - nxp,pca9956b 27 29 28 30 reg: 29 31 maxItems: 1
+84
Documentation/devicetree/bindings/leds/sprd,sc2731-bltc.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/leds/sprd,sc2731-bltc.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Spreadtrum SC2731 PMIC breathing light controller 8 + 9 + maintainers: 10 + - Orson Zhai <orsonzhai@gmail.com> 11 + - Baolin Wang <baolin.wang7@gmail.com> 12 + - Chunyan Zhang <zhang.lyra@gmail.com> 13 + 14 + description: | 15 + The SC2731 breathing light controller supports up to 3 outputs: 16 + red LED, green LED and blue LED. Each LED can work at normal PWM mode 17 + or breath light mode. 18 + 19 + properties: 20 + compatible: 21 + const: sprd,sc2731-bltc 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + '#address-cells': 27 + const: 1 28 + 29 + '#size-cells': 30 + const: 0 31 + 32 + patternProperties: 33 + "^led@[0-2]$": 34 + type: object 35 + $ref: common.yaml# 36 + unevaluatedProperties: false 37 + 38 + properties: 39 + reg: 40 + minimum: 0 41 + maximum: 2 42 + 43 + required: 44 + - reg 45 + 46 + required: 47 + - compatible 48 + - reg 49 + - '#address-cells' 50 + - '#size-cells' 51 + 52 + additionalProperties: false 53 + 54 + examples: 55 + - | 56 + #include <dt-bindings/leds/common.h> 57 + 58 + pmic { 59 + #address-cells = <1>; 60 + #size-cells = <0>; 61 + 62 + led-controller@200 { 63 + compatible = "sprd,sc2731-bltc"; 64 + reg = <0x200>; 65 + #address-cells = <1>; 66 + #size-cells = <0>; 67 + 68 + led@0 { 69 + reg = <0x0>; 70 + color = <LED_COLOR_ID_RED>; 71 + }; 72 + 73 + led@1 { 74 + reg = <0x1>; 75 + color = <LED_COLOR_ID_GREEN>; 76 + }; 77 + 78 + led@2 { 79 + reg = <0x2>; 80 + color = <LED_COLOR_ID_BLUE>; 81 + }; 82 + }; 83 + }; 84 + ...
+110
Documentation/devicetree/bindings/leds/ti.lm36922.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/leds/ti.lm36922.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Texas Instruments - LM3692x Highly Efficient White LED Driver 8 + 9 + maintainers: 10 + - Dan Murphy <dmurphy@ti.com> 11 + 12 + description: | 13 + The LM3692x is an ultra-compact, highly efficient, 14 + white-LED driver designed for LCD display backlighting. 15 + 16 + The main difference between the LM36922 and LM36923 is the number of 17 + LED strings it supports. The LM36922 supports two strings while the LM36923 18 + supports three strings. 19 + 20 + For more product information please see the link below: 21 + https://www.ti.com/lit/ds/snvsa29/snvsa29.pdf 22 + 23 + properties: 24 + compatible: 25 + enum: 26 + - ti,lm36922 27 + - ti,lm36923 28 + 29 + reg: 30 + maxItems: 1 31 + 32 + "#address-cells": 33 + const: 1 34 + 35 + "#size-cells": 36 + const: 0 37 + 38 + enable-gpios: 39 + description: gpio pin to enable/disable the device. 40 + 41 + vled-supply: 42 + description: LED supply 43 + 44 + ti,ovp-microvolt: 45 + description: Overvoltage protection. 46 + default: 29000000 47 + enum: [17000000, 21000000, 25000000, 29000000] 48 + 49 + patternProperties: 50 + '^led@[0-3]$': 51 + type: object 52 + $ref: common.yaml 53 + properties: 54 + reg: 55 + enum: [0, 1, 2, 3] 56 + description: | 57 + 0 - Will enable all LED sync paths 58 + 1 - Will enable the LED1 sync 59 + 2 - Will enable the LED2 sync 60 + 3 - Will enable the LED3 sync (LM36923 only) 61 + 62 + unevaluatedProperties: false 63 + 64 + required: 65 + - compatible 66 + - reg 67 + - "#address-cells" 68 + - "#size-cells" 69 + 70 + allOf: 71 + - if: 72 + properties: 73 + compatible: 74 + contains: 75 + const: ti,lm36922 76 + then: 77 + properties: 78 + led@3: false 79 + 80 + additionalProperties: false 81 + 82 + examples: 83 + - | 84 + #include <dt-bindings/gpio/gpio.h> 85 + #include <dt-bindings/leds/common.h> 86 + 87 + i2c { 88 + #address-cells = <1>; 89 + #size-cells = <0>; 90 + 91 + led-controller@36 { 92 + compatible = "ti,lm36922"; 93 + reg = <0x36>; 94 + #address-cells = <1>; 95 + #size-cells = <0>; 96 + 97 + enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; 98 + vled-supply = <&vbatt>; 99 + ti,ovp-microvolt = <29000000>; 100 + 101 + led@0 { 102 + reg = <0>; 103 + function = LED_FUNCTION_BACKLIGHT; 104 + color = <LED_COLOR_ID_WHITE>; 105 + linux,default-trigger = "backlight"; 106 + led-max-microamp = <20000>; 107 + }; 108 + }; 109 + }; 110 +
+26 -3
Documentation/leds/leds-blinkm.rst
··· 13 13 Also you can store blinking sequences as "scripts" in 14 14 the controller and run them. Also fading is an option. 15 15 16 - The interface this driver provides is 2-fold: 16 + The interface this driver provides is 3-fold: 17 17 18 - a) LED class interface for use with triggers 18 + a) LED multicolor class interface for use with triggers 19 + ####################################################### 20 + 21 + The registration follows the scheme:: 22 + 23 + blinkm-<i2c-bus-nr>-<i2c-device-nr>:rgb:indicator 24 + 25 + $ ls -h /sys/class/leds/blinkm-1-9:rgb:indicator 26 + brightness device max_brightness multi_index multi_intensity power subsystem trigger uevent 27 + 28 + Hue is controlled by the multi_intensity file and lightness is controlled by 29 + the brightness file. 30 + 31 + The order in which to write the intensity values can be found in multi_index. 32 + Exactly three values between 0 and 255 must be written to multi_intensity to 33 + change the color:: 34 + 35 + $ echo 255 100 50 > multi_intensity 36 + 37 + The overall lightness be changed by writing a value between 0 and 255 to the 38 + brightness file. 39 + 40 + b) LED class interface for use with triggers 19 41 ############################################ 20 42 21 43 The registration follows the scheme:: ··· 101 79 102 80 103 81 104 - as of 6/2012 82 + as of 07/2024 105 83 106 84 dl9pf <at> gmx <dot> de 85 + jstrauss <at> mailbox <dot> org
+8
Documentation/leds/well-known-leds.txt
··· 72 72 73 73 Good: ":backlight" (Motorola Droid 4) 74 74 75 + * Indicators 76 + 77 + Good: ":indicator" (Blinkm) 78 + 79 + * RGB 80 + 81 + Good: ":rgb" (Blinkm) 82 + 75 83 * Ethernet LEDs 76 84 77 85 Currently two types of Network LEDs are support, those controlled by
+8
drivers/leds/Kconfig
··· 825 825 This option enables support for the BlinkM RGB LED connected 826 826 through I2C. Say Y to enable support for the BlinkM LED. 827 827 828 + config LEDS_BLINKM_MULTICOLOR 829 + bool "Enable multicolor support for BlinkM I2C RGB LED" 830 + depends on LEDS_BLINKM 831 + depends on LEDS_CLASS_MULTICOLOR=y || LEDS_CLASS_MULTICOLOR=LEDS_BLINKM 832 + help 833 + This option enables multicolor sysfs class support for BlinkM LED and 834 + disables the older, separated sysfs interface 835 + 828 836 config LEDS_POWERNV 829 837 tristate "LED support for PowerNV Platform" 830 838 depends on LEDS_CLASS
+6 -8
drivers/leds/flash/leds-aat1290.c
··· 7 7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com> 8 8 */ 9 9 10 + #include <linux/cleanup.h> 10 11 #include <linux/delay.h> 11 12 #include <linux/gpio/consumer.h> 12 13 #include <linux/led-class-flash.h> ··· 216 215 struct device_node **sub_node) 217 216 { 218 217 struct device *dev = &led->pdev->dev; 219 - struct device_node *child_node; 220 218 #if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS) 221 219 struct pinctrl *pinctrl; 222 220 #endif ··· 246 246 } 247 247 #endif 248 248 249 - child_node = of_get_next_available_child(dev_of_node(dev), NULL); 249 + struct device_node *child_node __free(device_node) = 250 + of_get_next_available_child(dev_of_node(dev), NULL); 250 251 if (!child_node) { 251 252 dev_err(dev, "No DT child node found for connected LED.\n"); 252 253 return -EINVAL; ··· 268 267 if (ret < 0) { 269 268 dev_err(dev, 270 269 "flash-max-microamp DT property missing\n"); 271 - goto err_parse_dt; 270 + return ret; 272 271 } 273 272 274 273 ret = of_property_read_u32(child_node, "flash-max-timeout-us", ··· 276 275 if (ret < 0) { 277 276 dev_err(dev, 278 277 "flash-max-timeout-us DT property missing\n"); 279 - goto err_parse_dt; 278 + return ret; 280 279 } 281 280 282 281 *sub_node = child_node; 283 282 284 - err_parse_dt: 285 - of_node_put(child_node); 286 - 287 - return ret; 283 + return 0; 288 284 } 289 285 290 286 static void aat1290_led_validate_mm_current(struct aat1290_led *led,
+3 -5
drivers/leds/flash/leds-as3645a.c
··· 478 478 return as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE); 479 479 } 480 480 481 - static int as3645a_parse_node(struct as3645a *flash, 482 - struct fwnode_handle *fwnode) 481 + static int as3645a_parse_node(struct device *dev, struct as3645a *flash) 483 482 { 484 483 struct as3645a_config *cfg = &flash->cfg; 485 - struct fwnode_handle *child; 486 484 int rval; 487 485 488 - fwnode_for_each_child_node(fwnode, child) { 486 + device_for_each_child_node_scoped(dev, child) { 489 487 u32 id = 0; 490 488 491 489 fwnode_property_read_u32(child, "reg", &id); ··· 684 686 685 687 flash->client = client; 686 688 687 - rval = as3645a_parse_node(flash, dev_fwnode(&client->dev)); 689 + rval = as3645a_parse_node(&client->dev, flash); 688 690 if (rval < 0) 689 691 return rval; 690 692
+7 -8
drivers/leds/flash/leds-ktd2692.c
··· 6 6 * Ingi Kim <ingi2.kim@samsung.com> 7 7 */ 8 8 9 + #include <linux/cleanup.h> 9 10 #include <linux/err.h> 10 11 #include <linux/gpio/consumer.h> 11 12 #include <linux/leds-expresswire.h> ··· 209 208 struct ktd2692_led_config_data *cfg) 210 209 { 211 210 struct device_node *np = dev_of_node(dev); 212 - struct device_node *child_node; 213 211 int ret; 214 212 215 213 if (!np) ··· 239 239 } 240 240 } 241 241 242 - child_node = of_get_next_available_child(np, NULL); 242 + struct device_node *child_node __free(device_node) = 243 + of_get_next_available_child(np, NULL); 243 244 if (!child_node) { 244 245 dev_err(dev, "No DT child node found for connected LED.\n"); 245 246 return -EINVAL; ··· 253 252 &cfg->movie_max_microamp); 254 253 if (ret) { 255 254 dev_err(dev, "failed to parse led-max-microamp\n"); 256 - goto err_parse_dt; 255 + return ret; 257 256 } 258 257 259 258 ret = of_property_read_u32(child_node, "flash-max-microamp", 260 259 &cfg->flash_max_microamp); 261 260 if (ret) { 262 261 dev_err(dev, "failed to parse flash-max-microamp\n"); 263 - goto err_parse_dt; 262 + return ret; 264 263 } 265 264 266 265 ret = of_property_read_u32(child_node, "flash-max-timeout-us", 267 266 &cfg->flash_max_timeout); 268 267 if (ret) { 269 268 dev_err(dev, "failed to parse flash-max-timeout-us\n"); 270 - goto err_parse_dt; 269 + return ret; 271 270 } 272 271 273 - err_parse_dt: 274 - of_node_put(child_node); 275 - return ret; 272 + return 0; 276 273 } 277 274 278 275 static const struct led_flash_ops flash_ops = {
+16 -3
drivers/leds/flash/leds-lm3601x.c
··· 190 190 goto out; 191 191 } 192 192 193 - ret = regmap_write(led->regmap, LM3601X_LED_TORCH_REG, brightness); 193 + ret = regmap_write(led->regmap, LM3601X_LED_TORCH_REG, brightness - 1); 194 194 if (ret < 0) 195 195 goto out; 196 196 ··· 341 341 342 342 led_cdev = &led->fled_cdev.led_cdev; 343 343 led_cdev->brightness_set_blocking = lm3601x_brightness_set; 344 - led_cdev->max_brightness = DIV_ROUND_UP(led->torch_current_max, 345 - LM3601X_TORCH_REG_DIV); 344 + led_cdev->max_brightness = 345 + DIV_ROUND_UP(led->torch_current_max - LM3601X_MIN_TORCH_I_UA + 1, 346 + LM3601X_TORCH_REG_DIV); 346 347 led_cdev->flags |= LED_DEV_CAP_FLASH; 347 348 348 349 init_data.fwnode = fwnode; ··· 385 384 dev_warn(&led->client->dev, 386 385 "led-max-microamp DT property missing\n"); 387 386 goto out_err; 387 + } 388 + 389 + if (led->torch_current_max > LM3601X_MAX_TORCH_I_UA) { 390 + dev_warn(&led->client->dev, 391 + "Max torch current set too high (%d vs %d)\n", 392 + led->torch_current_max, 393 + LM3601X_MAX_TORCH_I_UA); 394 + led->torch_current_max = LM3601X_MAX_TORCH_I_UA; 388 395 } 389 396 390 397 ret = fwnode_property_read_u32(child, "flash-max-microamp", ··· 442 433 "Failed to allocate register map: %d\n", ret); 443 434 return ret; 444 435 } 436 + 437 + ret = regmap_write(led->regmap, LM3601X_DEV_ID_REG, LM3601X_SW_RESET); 438 + if (ret) 439 + dev_warn(&client->dev, "Failed to reset the LED controller\n"); 445 440 446 441 mutex_init(&led->lock); 447 442
+10 -10
drivers/leds/flash/leds-max77693.c
··· 599 599 { 600 600 struct device *dev = &led->pdev->dev; 601 601 struct max77693_sub_led *sub_leds = led->sub_leds; 602 - struct device_node *node = dev_of_node(dev), *child_node; 602 + struct device_node *node = dev_of_node(dev); 603 603 struct property *prop; 604 604 u32 led_sources[2]; 605 605 int i, ret, fled_id; ··· 608 608 of_property_read_u32(node, "maxim,boost-mvout", &cfg->boost_vout); 609 609 of_property_read_u32(node, "maxim,mvsys-min", &cfg->low_vsys); 610 610 611 - for_each_available_child_of_node(node, child_node) { 611 + for_each_available_child_of_node_scoped(node, child_node) { 612 612 prop = of_find_property(child_node, "led-sources", NULL); 613 613 if (prop) { 614 614 const __be32 *srcs = NULL; ··· 622 622 } else { 623 623 dev_err(dev, 624 624 "led-sources DT property missing\n"); 625 - of_node_put(child_node); 626 625 return -EINVAL; 627 626 } 628 627 ··· 637 638 } else { 638 639 dev_err(dev, 639 640 "Wrong led-sources DT property value.\n"); 640 - of_node_put(child_node); 641 641 return -EINVAL; 642 642 } 643 643 644 644 if (sub_nodes[fled_id]) { 645 645 dev_err(dev, 646 646 "Conflicting \"led-sources\" DT properties\n"); 647 - of_node_put(child_node); 648 647 return -EINVAL; 649 648 } 650 649 651 - sub_nodes[fled_id] = child_node; 650 + sub_nodes[fled_id] = of_node_get(child_node); 652 651 sub_leds[fled_id].fled_id = fled_id; 653 652 654 653 cfg->label[fled_id] = ··· 678 681 679 682 if (++cfg->num_leds == 2 || 680 683 (max77693_fled_used(led, FLED1) && 681 - max77693_fled_used(led, FLED2))) { 682 - of_node_put(child_node); 684 + max77693_fled_used(led, FLED2))) 683 685 break; 684 - } 685 686 } 686 687 687 688 if (cfg->num_leds == 0) { ··· 963 968 964 969 ret = max77693_setup(led, &led_cfg); 965 970 if (ret < 0) 966 - return ret; 971 + goto err_setup; 967 972 968 973 mutex_init(&led->lock); 969 974 ··· 995 1000 else 996 1001 goto err_register_led1; 997 1002 } 1003 + of_node_put(sub_nodes[i]); 1004 + sub_nodes[i] = NULL; 998 1005 } 999 1006 1000 1007 return 0; ··· 1010 1013 err_register_led1: 1011 1014 mutex_destroy(&led->lock); 1012 1015 1016 + err_setup: 1017 + for (i = FLED1; i <= FLED2; i++) 1018 + of_node_put(sub_nodes[i]); 1013 1019 return ret; 1014 1020 } 1015 1021
+162 -1
drivers/leds/flash/leds-qcom-flash.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 3 + * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 4 */ 5 5 6 6 #include <linux/bitfield.h> ··· 14 14 #include <media/v4l2-flash-led-class.h> 15 15 16 16 /* registers definitions */ 17 + #define FLASH_REVISION_REG 0x00 18 + #define FLASH_4CH_REVISION_V0P1 0x01 19 + 17 20 #define FLASH_TYPE_REG 0x04 18 21 #define FLASH_TYPE_VAL 0x18 19 22 ··· 76 73 77 74 #define UA_PER_MA 1000 78 75 76 + /* thermal threshold constants */ 77 + #define OTST_3CH_MIN_VAL 3 78 + #define OTST1_4CH_MIN_VAL 0 79 + #define OTST1_4CH_V0P1_MIN_VAL 3 80 + #define OTST2_4CH_MIN_VAL 0 81 + 82 + #define OTST1_MAX_CURRENT_MA 1000 83 + #define OTST2_MAX_CURRENT_MA 500 84 + #define OTST3_MAX_CURRENT_MA 200 85 + 79 86 enum hw_type { 80 87 QCOM_MVFLASH_3CH, 81 88 QCOM_MVFLASH_4CH, ··· 111 98 REG_IRESOLUTION, 112 99 REG_CHAN_STROBE, 113 100 REG_CHAN_EN, 101 + REG_THERM_THRSH1, 102 + REG_THERM_THRSH2, 103 + REG_THERM_THRSH3, 114 104 REG_MAX_COUNT, 115 105 }; 116 106 ··· 127 111 REG_FIELD(0x47, 0, 5), /* iresolution */ 128 112 REG_FIELD_ID(0x49, 0, 2, 3, 1), /* chan_strobe */ 129 113 REG_FIELD(0x4c, 0, 2), /* chan_en */ 114 + REG_FIELD(0x56, 0, 2), /* therm_thrsh1 */ 115 + REG_FIELD(0x57, 0, 2), /* therm_thrsh2 */ 116 + REG_FIELD(0x58, 0, 2), /* therm_thrsh3 */ 130 117 }; 131 118 132 119 static struct reg_field mvflash_4ch_regs[REG_MAX_COUNT] = { ··· 142 123 REG_FIELD(0x49, 0, 3), /* iresolution */ 143 124 REG_FIELD_ID(0x4a, 0, 6, 4, 1), /* chan_strobe */ 144 125 REG_FIELD(0x4e, 0, 3), /* chan_en */ 126 + REG_FIELD(0x7a, 0, 2), /* therm_thrsh1 */ 127 + REG_FIELD(0x78, 0, 2), /* therm_thrsh2 */ 145 128 }; 146 129 147 130 struct qcom_flash_data { ··· 151 130 struct regmap_field *r_fields[REG_MAX_COUNT]; 152 131 struct mutex lock; 153 132 enum hw_type hw_type; 133 + u32 total_ma; 154 134 u8 leds_count; 155 135 u8 max_channels; 156 136 u8 chan_en_bits; 137 + u8 revision; 157 138 }; 158 139 159 140 struct qcom_flash_led { ··· 166 143 u32 max_timeout_ms; 167 144 u32 flash_current_ma; 168 145 u32 flash_timeout_ms; 146 + u32 current_in_use_ma; 169 147 u8 *chan_id; 170 148 u8 chan_count; 171 149 bool enabled; ··· 193 169 dev_err(led->flash.led_cdev.dev, "write module_en failed, rc=%d\n", rc); 194 170 mutex_unlock(&flash_data->lock); 195 171 172 + return rc; 173 + } 174 + 175 + static int update_allowed_flash_current(struct qcom_flash_led *led, u32 *current_ma, bool strobe) 176 + { 177 + struct qcom_flash_data *flash_data = led->flash_data; 178 + u32 therm_ma, avail_ma, thrsh[3], min_thrsh, sts; 179 + int rc = 0; 180 + 181 + mutex_lock(&flash_data->lock); 182 + /* 183 + * Put previously allocated current into allowed budget in either of these two cases: 184 + * 1) LED is disabled; 185 + * 2) LED is enabled repeatedly 186 + */ 187 + if (!strobe || led->current_in_use_ma != 0) { 188 + if (flash_data->total_ma >= led->current_in_use_ma) 189 + flash_data->total_ma -= led->current_in_use_ma; 190 + else 191 + flash_data->total_ma = 0; 192 + 193 + led->current_in_use_ma = 0; 194 + if (!strobe) 195 + goto unlock; 196 + } 197 + 198 + /* 199 + * Cache the default thermal threshold settings, and set them to the lowest levels before 200 + * reading over-temp real time status. If over-temp has been triggered at the lowest 201 + * threshold, it's very likely that it would be triggered at a higher (default) threshold 202 + * when more flash current is requested. Prevent device from triggering over-temp condition 203 + * by limiting the flash current for the new request. 204 + */ 205 + rc = regmap_field_read(flash_data->r_fields[REG_THERM_THRSH1], &thrsh[0]); 206 + if (rc < 0) 207 + goto unlock; 208 + 209 + rc = regmap_field_read(flash_data->r_fields[REG_THERM_THRSH2], &thrsh[1]); 210 + if (rc < 0) 211 + goto unlock; 212 + 213 + if (flash_data->hw_type == QCOM_MVFLASH_3CH) { 214 + rc = regmap_field_read(flash_data->r_fields[REG_THERM_THRSH3], &thrsh[2]); 215 + if (rc < 0) 216 + goto unlock; 217 + } 218 + 219 + min_thrsh = OTST_3CH_MIN_VAL; 220 + if (flash_data->hw_type == QCOM_MVFLASH_4CH) 221 + min_thrsh = (flash_data->revision == FLASH_4CH_REVISION_V0P1) ? 222 + OTST1_4CH_V0P1_MIN_VAL : OTST1_4CH_MIN_VAL; 223 + 224 + rc = regmap_field_write(flash_data->r_fields[REG_THERM_THRSH1], min_thrsh); 225 + if (rc < 0) 226 + goto unlock; 227 + 228 + if (flash_data->hw_type == QCOM_MVFLASH_4CH) 229 + min_thrsh = OTST2_4CH_MIN_VAL; 230 + 231 + /* 232 + * The default thermal threshold settings have been updated hence 233 + * restore them if any fault happens starting from here. 234 + */ 235 + rc = regmap_field_write(flash_data->r_fields[REG_THERM_THRSH2], min_thrsh); 236 + if (rc < 0) 237 + goto restore; 238 + 239 + if (flash_data->hw_type == QCOM_MVFLASH_3CH) { 240 + rc = regmap_field_write(flash_data->r_fields[REG_THERM_THRSH3], min_thrsh); 241 + if (rc < 0) 242 + goto restore; 243 + } 244 + 245 + /* Read thermal level status to get corresponding derating flash current */ 246 + rc = regmap_field_read(flash_data->r_fields[REG_STATUS2], &sts); 247 + if (rc) 248 + goto restore; 249 + 250 + therm_ma = FLASH_TOTAL_CURRENT_MAX_UA / 1000; 251 + if (flash_data->hw_type == QCOM_MVFLASH_3CH) { 252 + if (sts & FLASH_STS_3CH_OTST3) 253 + therm_ma = OTST3_MAX_CURRENT_MA; 254 + else if (sts & FLASH_STS_3CH_OTST2) 255 + therm_ma = OTST2_MAX_CURRENT_MA; 256 + else if (sts & FLASH_STS_3CH_OTST1) 257 + therm_ma = OTST1_MAX_CURRENT_MA; 258 + } else { 259 + if (sts & FLASH_STS_4CH_OTST2) 260 + therm_ma = OTST2_MAX_CURRENT_MA; 261 + else if (sts & FLASH_STS_4CH_OTST1) 262 + therm_ma = OTST1_MAX_CURRENT_MA; 263 + } 264 + 265 + /* Calculate the allowed flash current for the request */ 266 + if (therm_ma <= flash_data->total_ma) 267 + avail_ma = 0; 268 + else 269 + avail_ma = therm_ma - flash_data->total_ma; 270 + 271 + *current_ma = min_t(u32, *current_ma, avail_ma); 272 + led->current_in_use_ma = *current_ma; 273 + flash_data->total_ma += led->current_in_use_ma; 274 + 275 + dev_dbg(led->flash.led_cdev.dev, "allowed flash current: %dmA, total current: %dmA\n", 276 + led->current_in_use_ma, flash_data->total_ma); 277 + 278 + restore: 279 + /* Restore to default thermal threshold settings */ 280 + rc = regmap_field_write(flash_data->r_fields[REG_THERM_THRSH1], thrsh[0]); 281 + if (rc < 0) 282 + goto unlock; 283 + 284 + rc = regmap_field_write(flash_data->r_fields[REG_THERM_THRSH2], thrsh[1]); 285 + if (rc < 0) 286 + goto unlock; 287 + 288 + if (flash_data->hw_type == QCOM_MVFLASH_3CH) 289 + rc = regmap_field_write(flash_data->r_fields[REG_THERM_THRSH3], thrsh[2]); 290 + 291 + unlock: 292 + mutex_unlock(&flash_data->lock); 196 293 return rc; 197 294 } 198 295 ··· 458 313 if (rc) 459 314 return rc; 460 315 316 + rc = update_allowed_flash_current(led, &led->flash_current_ma, state); 317 + if (rc < 0) 318 + return rc; 319 + 461 320 rc = set_flash_current(led, led->flash_current_ma, FLASH_MODE); 462 321 if (rc) 463 322 return rc; ··· 576 427 577 428 rc = set_flash_module_en(led, false); 578 429 if (rc) 430 + return rc; 431 + 432 + rc = update_allowed_flash_current(led, &current_ma, enable); 433 + if (rc < 0) 579 434 return rc; 580 435 581 436 rc = set_flash_current(led, current_ma, TORCH_MODE); ··· 860 707 flash_data->hw_type = QCOM_MVFLASH_4CH; 861 708 flash_data->max_channels = 4; 862 709 regs = mvflash_4ch_regs; 710 + 711 + rc = regmap_read(regmap, reg_base + FLASH_REVISION_REG, &val); 712 + if (rc < 0) { 713 + dev_err(dev, "Failed to read flash LED module revision, rc=%d\n", rc); 714 + return rc; 715 + } 716 + 717 + flash_data->revision = val; 863 718 } else { 864 719 dev_err(dev, "flash LED subtype %#x is not yet supported\n", val); 865 720 return -ENODEV;
+2 -3
drivers/leds/leds-88pm860x.c
··· 115 115 static int pm860x_led_dt_init(struct platform_device *pdev, 116 116 struct pm860x_led *data) 117 117 { 118 - struct device_node *nproot, *np; 118 + struct device_node *nproot; 119 119 int iset = 0; 120 120 121 121 if (!dev_of_node(pdev->dev.parent)) ··· 125 125 dev_err(&pdev->dev, "failed to find leds node\n"); 126 126 return -ENODEV; 127 127 } 128 - for_each_available_child_of_node(nproot, np) { 128 + for_each_available_child_of_node_scoped(nproot, np) { 129 129 if (of_node_name_eq(np, data->name)) { 130 130 of_property_read_u32(np, "marvell,88pm860x-iset", 131 131 &iset); 132 132 data->iset = PM8606_LED_CURRENT(iset); 133 - of_node_put(np); 134 133 break; 135 134 } 136 135 }
+3 -5
drivers/leds/leds-aw2013.c
··· 263 263 264 264 static int aw2013_probe_dt(struct aw2013 *chip) 265 265 { 266 - struct device_node *np = dev_of_node(&chip->client->dev), *child; 266 + struct device_node *np = dev_of_node(&chip->client->dev); 267 267 int count, ret = 0, i = 0; 268 268 struct aw2013_led *led; 269 269 ··· 273 273 274 274 regmap_write(chip->regmap, AW2013_RSTR, AW2013_RSTR_RESET); 275 275 276 - for_each_available_child_of_node(np, child) { 276 + for_each_available_child_of_node_scoped(np, child) { 277 277 struct led_init_data init_data = {}; 278 278 u32 source; 279 279 u32 imax; ··· 304 304 305 305 ret = devm_led_classdev_register_ext(&chip->client->dev, 306 306 &led->cdev, &init_data); 307 - if (ret < 0) { 308 - of_node_put(child); 307 + if (ret < 0) 309 308 return ret; 310 - } 311 309 312 310 i++; 313 311 }
+2 -5
drivers/leds/leds-bcm6328.c
··· 392 392 { 393 393 struct device *dev = &pdev->dev; 394 394 struct device_node *np = dev_of_node(&pdev->dev); 395 - struct device_node *child; 396 395 void __iomem *mem; 397 396 spinlock_t *lock; /* memory lock */ 398 397 unsigned long val, *blink_leds, *blink_delay; ··· 434 435 val |= BCM6328_SERIAL_LED_SHIFT_DIR; 435 436 bcm6328_led_write(mem + BCM6328_REG_INIT, val); 436 437 437 - for_each_available_child_of_node(np, child) { 438 + for_each_available_child_of_node_scoped(np, child) { 438 439 int rc; 439 440 u32 reg; 440 441 ··· 453 454 rc = bcm6328_led(dev, child, reg, mem, lock, 454 455 blink_leds, blink_delay); 455 456 456 - if (rc < 0) { 457 - of_node_put(child); 457 + if (rc < 0) 458 458 return rc; 459 - } 460 459 } 461 460 462 461 return 0;
+2 -5
drivers/leds/leds-bcm6358.c
··· 147 147 { 148 148 struct device *dev = &pdev->dev; 149 149 struct device_node *np = dev_of_node(&pdev->dev); 150 - struct device_node *child; 151 150 void __iomem *mem; 152 151 spinlock_t *lock; /* memory lock */ 153 152 unsigned long val; ··· 183 184 } 184 185 bcm6358_led_write(mem + BCM6358_REG_CTRL, val); 185 186 186 - for_each_available_child_of_node(np, child) { 187 + for_each_available_child_of_node_scoped(np, child) { 187 188 int rc; 188 189 u32 reg; 189 190 ··· 197 198 } 198 199 199 200 rc = bcm6358_led(dev, child, reg, mem, lock); 200 - if (rc < 0) { 201 - of_node_put(child); 201 + if (rc < 0) 202 202 return rc; 203 - } 204 203 } 205 204 206 205 return 0;
+10 -13
drivers/leds/leds-bd2606mvv.c
··· 69 69 70 70 static int bd2606mvv_probe(struct i2c_client *client) 71 71 { 72 - struct fwnode_handle *np, *child; 73 72 struct device *dev = &client->dev; 74 73 struct bd2606mvv_priv *priv; 75 74 struct fwnode_handle *led_fwnodes[BD2606_MAX_LEDS] = { 0 }; 76 75 int active_pairs[BD2606_MAX_LEDS / 2] = { 0 }; 77 76 int err, reg; 78 - int i; 77 + int i, j; 79 78 80 - np = dev_fwnode(dev); 81 - if (!np) 79 + if (!dev_fwnode(dev)) 82 80 return -ENODEV; 83 81 84 82 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); ··· 92 94 93 95 i2c_set_clientdata(client, priv); 94 96 95 - fwnode_for_each_available_child_node(np, child) { 97 + device_for_each_child_node_scoped(dev, child) { 96 98 struct bd2606mvv_led *led; 97 99 98 100 err = fwnode_property_read_u32(child, "reg", &reg); 99 - if (err) { 100 - fwnode_handle_put(child); 101 + if (err) 101 102 return err; 102 - } 103 - if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg]) { 104 - fwnode_handle_put(child); 103 + 104 + if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg]) 105 105 return -EINVAL; 106 - } 106 + 107 107 led = &priv->leds[reg]; 108 - led_fwnodes[reg] = child; 108 + led_fwnodes[reg] = fwnode_handle_get(child); 109 109 active_pairs[reg / 2]++; 110 110 led->priv = priv; 111 111 led->led_no = reg; ··· 126 130 &priv->leds[i].ldev, 127 131 &init_data); 128 132 if (err < 0) { 129 - fwnode_handle_put(child); 133 + for (j = i; j < BD2606_MAX_LEDS; j++) 134 + fwnode_handle_put(led_fwnodes[j]); 130 135 return dev_err_probe(dev, err, 131 136 "couldn't register LED %s\n", 132 137 priv->leds[i].ldev.name);
+176 -88
drivers/leds/leds-blinkm.c
··· 2 2 /* 3 3 * leds-blinkm.c 4 4 * (c) Jan-Simon Möller (dl9pf@gmx.de) 5 + * (c) Joseph Strauss (jstrauss@mailbox.org) 5 6 */ 6 7 7 8 #include <linux/module.h> ··· 16 15 #include <linux/pm_runtime.h> 17 16 #include <linux/leds.h> 18 17 #include <linux/delay.h> 18 + #include <linux/led-class-multicolor.h> 19 + #include <linux/kconfig.h> 20 + 21 + #define NUM_LEDS 3 19 22 20 23 /* Addresses to scan - BlinkM is on 0x09 by default*/ 21 24 static const unsigned short normal_i2c[] = { 0x09, I2C_CLIENT_END }; ··· 27 22 static int blinkm_transfer_hw(struct i2c_client *client, int cmd); 28 23 static int blinkm_test_run(struct i2c_client *client); 29 24 25 + /* Contains structs for both the color-separated sysfs classes, and the new multicolor class */ 30 26 struct blinkm_led { 31 27 struct i2c_client *i2c_client; 32 - struct led_classdev led_cdev; 28 + union { 29 + /* used when multicolor support is disabled */ 30 + struct led_classdev led_cdev; 31 + struct led_classdev_mc mcled_cdev; 32 + } cdev; 33 33 int id; 34 34 }; 35 35 36 - #define cdev_to_blmled(c) container_of(c, struct blinkm_led, led_cdev) 36 + #define led_cdev_to_blmled(c) container_of(c, struct blinkm_led, cdev.led_cdev) 37 + #define mcled_cdev_to_led(c) container_of(c, struct blinkm_led, cdev.mcled_cdev) 37 38 38 39 struct blinkm_data { 39 40 struct i2c_client *i2c_client; 40 41 struct mutex update_lock; 41 42 /* used for led class interface */ 42 - struct blinkm_led blinkm_leds[3]; 43 + struct blinkm_led blinkm_leds[NUM_LEDS]; 43 44 /* used for "blinkm" sysfs interface */ 44 45 u8 red; /* color red */ 45 46 u8 green; /* color green */ ··· 430 419 return 0; 431 420 } 432 421 422 + static int blinkm_set_mc_brightness(struct led_classdev *led_cdev, 423 + enum led_brightness value) 424 + { 425 + struct led_classdev_mc *mcled_cdev = lcdev_to_mccdev(led_cdev); 426 + struct blinkm_led *led = mcled_cdev_to_led(mcled_cdev); 427 + struct blinkm_data *data = i2c_get_clientdata(led->i2c_client); 428 + 429 + led_mc_calc_color_components(mcled_cdev, value); 430 + 431 + data->next_red = (u8) mcled_cdev->subled_info[RED].brightness; 432 + data->next_green = (u8) mcled_cdev->subled_info[GREEN].brightness; 433 + data->next_blue = (u8) mcled_cdev->subled_info[BLUE].brightness; 434 + 435 + blinkm_transfer_hw(led->i2c_client, BLM_GO_RGB); 436 + 437 + return 0; 438 + } 439 + 433 440 static int blinkm_led_common_set(struct led_classdev *led_cdev, 434 441 enum led_brightness value, int color) 435 442 { 436 443 /* led_brightness is 0, 127 or 255 - we just use it here as-is */ 437 - struct blinkm_led *led = cdev_to_blmled(led_cdev); 444 + struct blinkm_led *led = led_cdev_to_blmled(led_cdev); 438 445 struct blinkm_data *data = i2c_get_clientdata(led->i2c_client); 439 446 440 447 switch (color) { ··· 594 565 return 0; 595 566 } 596 567 568 + static int register_separate_colors(struct i2c_client *client, struct blinkm_data *data) 569 + { 570 + /* 3 separate classes for red, green, and blue respectively */ 571 + struct blinkm_led *leds[NUM_LEDS]; 572 + int err; 573 + char blinkm_led_name[28]; 574 + /* Register red, green, and blue sysfs classes */ 575 + for (int i = 0; i < NUM_LEDS; i++) { 576 + /* RED = 0, GREEN = 1, BLUE = 2 */ 577 + leds[i] = &data->blinkm_leds[i]; 578 + leds[i]->i2c_client = client; 579 + leds[i]->id = i; 580 + leds[i]->cdev.led_cdev.max_brightness = 255; 581 + leds[i]->cdev.led_cdev.flags = LED_CORE_SUSPENDRESUME; 582 + switch (i) { 583 + case RED: 584 + scnprintf(blinkm_led_name, sizeof(blinkm_led_name), 585 + "blinkm-%d-%d-red", 586 + client->adapter->nr, 587 + client->addr); 588 + leds[i]->cdev.led_cdev.name = blinkm_led_name; 589 + leds[i]->cdev.led_cdev.brightness_set_blocking = 590 + blinkm_led_red_set; 591 + err = led_classdev_register(&client->dev, 592 + &leds[i]->cdev.led_cdev); 593 + if (err < 0) { 594 + dev_err(&client->dev, 595 + "couldn't register LED %s\n", 596 + leds[i]->cdev.led_cdev.name); 597 + goto failred; 598 + } 599 + break; 600 + case GREEN: 601 + scnprintf(blinkm_led_name, sizeof(blinkm_led_name), 602 + "blinkm-%d-%d-green", 603 + client->adapter->nr, 604 + client->addr); 605 + leds[i]->cdev.led_cdev.name = blinkm_led_name; 606 + leds[i]->cdev.led_cdev.brightness_set_blocking = 607 + blinkm_led_green_set; 608 + err = led_classdev_register(&client->dev, 609 + &leds[i]->cdev.led_cdev); 610 + if (err < 0) { 611 + dev_err(&client->dev, 612 + "couldn't register LED %s\n", 613 + leds[i]->cdev.led_cdev.name); 614 + goto failgreen; 615 + } 616 + break; 617 + case BLUE: 618 + scnprintf(blinkm_led_name, sizeof(blinkm_led_name), 619 + "blinkm-%d-%d-blue", 620 + client->adapter->nr, 621 + client->addr); 622 + leds[i]->cdev.led_cdev.name = blinkm_led_name; 623 + leds[i]->cdev.led_cdev.brightness_set_blocking = 624 + blinkm_led_blue_set; 625 + err = led_classdev_register(&client->dev, 626 + &leds[i]->cdev.led_cdev); 627 + if (err < 0) { 628 + dev_err(&client->dev, 629 + "couldn't register LED %s\n", 630 + leds[i]->cdev.led_cdev.name); 631 + goto failblue; 632 + } 633 + break; 634 + default: 635 + break; 636 + } /* end switch */ 637 + } /* end for */ 638 + return 0; 639 + 640 + failblue: 641 + led_classdev_unregister(&leds[GREEN]->cdev.led_cdev); 642 + failgreen: 643 + led_classdev_unregister(&leds[RED]->cdev.led_cdev); 644 + failred: 645 + sysfs_remove_group(&client->dev.kobj, &blinkm_group); 646 + 647 + return err; 648 + } 649 + 650 + static int register_multicolor(struct i2c_client *client, struct blinkm_data *data) 651 + { 652 + struct blinkm_led *mc_led; 653 + struct mc_subled *mc_led_info; 654 + char blinkm_led_name[28]; 655 + int err; 656 + 657 + /* Register multicolor sysfs class */ 658 + /* The first element of leds is used for multicolor facilities */ 659 + mc_led = &data->blinkm_leds[RED]; 660 + mc_led->i2c_client = client; 661 + 662 + mc_led_info = devm_kcalloc(&client->dev, NUM_LEDS, sizeof(*mc_led_info), 663 + GFP_KERNEL); 664 + if (!mc_led_info) 665 + return -ENOMEM; 666 + 667 + mc_led_info[RED].color_index = LED_COLOR_ID_RED; 668 + mc_led_info[GREEN].color_index = LED_COLOR_ID_GREEN; 669 + mc_led_info[BLUE].color_index = LED_COLOR_ID_BLUE; 670 + 671 + mc_led->cdev.mcled_cdev.subled_info = mc_led_info; 672 + mc_led->cdev.mcled_cdev.num_colors = NUM_LEDS; 673 + mc_led->cdev.mcled_cdev.led_cdev.brightness = 255; 674 + mc_led->cdev.mcled_cdev.led_cdev.max_brightness = 255; 675 + mc_led->cdev.mcled_cdev.led_cdev.flags = LED_CORE_SUSPENDRESUME; 676 + 677 + scnprintf(blinkm_led_name, sizeof(blinkm_led_name), 678 + "blinkm-%d-%d:rgb:indicator", 679 + client->adapter->nr, 680 + client->addr); 681 + mc_led->cdev.mcled_cdev.led_cdev.name = blinkm_led_name; 682 + mc_led->cdev.mcled_cdev.led_cdev.brightness_set_blocking = blinkm_set_mc_brightness; 683 + 684 + err = led_classdev_multicolor_register(&client->dev, &mc_led->cdev.mcled_cdev); 685 + if (err < 0) { 686 + dev_err(&client->dev, "couldn't register LED %s\n", 687 + mc_led->cdev.led_cdev.name); 688 + sysfs_remove_group(&client->dev.kobj, &blinkm_group); 689 + } 690 + return 0; 691 + } 692 + 597 693 static int blinkm_probe(struct i2c_client *client) 598 694 { 599 695 struct blinkm_data *data; 600 - struct blinkm_led *led[3]; 601 - int err, i; 602 - char blinkm_led_name[28]; 696 + int err; 603 697 604 698 data = devm_kzalloc(&client->dev, 605 699 sizeof(struct blinkm_data), GFP_KERNEL); 606 - if (!data) { 607 - err = -ENOMEM; 608 - goto exit; 609 - } 700 + if (!data) 701 + return -ENOMEM; 610 702 611 703 data->i2c_addr = 0x08; 612 704 /* i2c addr - use fake addr of 0x08 initially (real is 0x09) */ 613 705 data->fw_ver = 0xfe; 614 706 /* firmware version - use fake until we read real value 615 - * (currently broken - BlinkM confused!) */ 707 + * (currently broken - BlinkM confused!) 708 + */ 616 709 data->script_id = 0x01; 617 710 data->i2c_client = client; 618 711 ··· 745 594 err = sysfs_create_group(&client->dev.kobj, &blinkm_group); 746 595 if (err < 0) { 747 596 dev_err(&client->dev, "couldn't register sysfs group\n"); 748 - goto exit; 597 + return err; 749 598 } 750 599 751 - for (i = 0; i < 3; i++) { 752 - /* RED = 0, GREEN = 1, BLUE = 2 */ 753 - led[i] = &data->blinkm_leds[i]; 754 - led[i]->i2c_client = client; 755 - led[i]->id = i; 756 - led[i]->led_cdev.max_brightness = 255; 757 - led[i]->led_cdev.flags = LED_CORE_SUSPENDRESUME; 758 - switch (i) { 759 - case RED: 760 - snprintf(blinkm_led_name, sizeof(blinkm_led_name), 761 - "blinkm-%d-%d-red", 762 - client->adapter->nr, 763 - client->addr); 764 - led[i]->led_cdev.name = blinkm_led_name; 765 - led[i]->led_cdev.brightness_set_blocking = 766 - blinkm_led_red_set; 767 - err = led_classdev_register(&client->dev, 768 - &led[i]->led_cdev); 769 - if (err < 0) { 770 - dev_err(&client->dev, 771 - "couldn't register LED %s\n", 772 - led[i]->led_cdev.name); 773 - goto failred; 774 - } 775 - break; 776 - case GREEN: 777 - snprintf(blinkm_led_name, sizeof(blinkm_led_name), 778 - "blinkm-%d-%d-green", 779 - client->adapter->nr, 780 - client->addr); 781 - led[i]->led_cdev.name = blinkm_led_name; 782 - led[i]->led_cdev.brightness_set_blocking = 783 - blinkm_led_green_set; 784 - err = led_classdev_register(&client->dev, 785 - &led[i]->led_cdev); 786 - if (err < 0) { 787 - dev_err(&client->dev, 788 - "couldn't register LED %s\n", 789 - led[i]->led_cdev.name); 790 - goto failgreen; 791 - } 792 - break; 793 - case BLUE: 794 - snprintf(blinkm_led_name, sizeof(blinkm_led_name), 795 - "blinkm-%d-%d-blue", 796 - client->adapter->nr, 797 - client->addr); 798 - led[i]->led_cdev.name = blinkm_led_name; 799 - led[i]->led_cdev.brightness_set_blocking = 800 - blinkm_led_blue_set; 801 - err = led_classdev_register(&client->dev, 802 - &led[i]->led_cdev); 803 - if (err < 0) { 804 - dev_err(&client->dev, 805 - "couldn't register LED %s\n", 806 - led[i]->led_cdev.name); 807 - goto failblue; 808 - } 809 - break; 810 - } /* end switch */ 811 - } /* end for */ 600 + if (!IS_ENABLED(CONFIG_LEDS_BLINKM_MULTICOLOR)) { 601 + err = register_separate_colors(client, data); 602 + if (err < 0) 603 + return err; 604 + } else { 605 + err = register_multicolor(client, data); 606 + if (err < 0) 607 + return err; 608 + } 812 609 813 - /* Initialize the blinkm */ 814 610 blinkm_init_hw(client); 815 611 816 612 return 0; 817 - 818 - failblue: 819 - led_classdev_unregister(&led[GREEN]->led_cdev); 820 - 821 - failgreen: 822 - led_classdev_unregister(&led[RED]->led_cdev); 823 - 824 - failred: 825 - sysfs_remove_group(&client->dev.kobj, &blinkm_group); 826 - exit: 827 - return err; 828 613 } 829 614 830 615 static void blinkm_remove(struct i2c_client *client) ··· 770 683 int i; 771 684 772 685 /* make sure no workqueue entries are pending */ 773 - for (i = 0; i < 3; i++) 774 - led_classdev_unregister(&data->blinkm_leds[i].led_cdev); 686 + for (i = 0; i < NUM_LEDS; i++) 687 + led_classdev_unregister(&data->blinkm_leds[i].cdev.led_cdev); 775 688 776 689 /* reset rgb */ 777 690 data->next_red = 0x00; ··· 827 740 module_i2c_driver(blinkm_driver); 828 741 829 742 MODULE_AUTHOR("Jan-Simon Moeller <dl9pf@gmx.de>"); 743 + MODULE_AUTHOR("Joseph Strauss <jstrauss@mailbox.org>"); 830 744 MODULE_DESCRIPTION("BlinkM RGB LED driver"); 831 745 MODULE_LICENSE("GPL"); 832 746
+6 -3
drivers/leds/leds-gpio.c
··· 150 150 { 151 151 struct fwnode_handle *child; 152 152 struct gpio_leds_priv *priv; 153 - int count, ret; 153 + int count, used, ret; 154 154 155 155 count = device_get_child_node_count(dev); 156 156 if (!count) ··· 159 159 priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL); 160 160 if (!priv) 161 161 return ERR_PTR(-ENOMEM); 162 + priv->num_leds = count; 163 + used = 0; 162 164 163 165 device_for_each_child_node(dev, child) { 164 - struct gpio_led_data *led_dat = &priv->leds[priv->num_leds]; 166 + struct gpio_led_data *led_dat = &priv->leds[used]; 165 167 struct gpio_led led = {}; 166 168 167 169 /* ··· 199 197 /* Set gpiod label to match the corresponding LED name. */ 200 198 gpiod_set_consumer_name(led_dat->gpiod, 201 199 led_dat->cdev.dev->kobj.name); 202 - priv->num_leds++; 200 + used++; 203 201 } 202 + priv->num_leds = used; 204 203 205 204 return priv; 206 205 }
+11 -23
drivers/leds/leds-is31fl319x.c
··· 392 392 393 393 static int is31fl319x_parse_fw(struct device *dev, struct is31fl319x_chip *is31) 394 394 { 395 - struct fwnode_handle *fwnode = dev_fwnode(dev), *child; 395 + struct fwnode_handle *fwnode = dev_fwnode(dev); 396 396 int count; 397 397 int ret; 398 398 ··· 404 404 is31->cdef = device_get_match_data(dev); 405 405 406 406 count = 0; 407 - fwnode_for_each_available_child_node(fwnode, child) 407 + device_for_each_child_node_scoped(dev, child) 408 408 count++; 409 409 410 410 dev_dbg(dev, "probing with %d leds defined in DT\n", count); ··· 414 414 "Number of leds defined must be between 1 and %u\n", 415 415 is31->cdef->num_leds); 416 416 417 - fwnode_for_each_available_child_node(fwnode, child) { 417 + device_for_each_child_node_scoped(dev, child) { 418 418 struct is31fl319x_led *led; 419 419 u32 reg; 420 420 421 421 ret = fwnode_property_read_u32(child, "reg", &reg); 422 - if (ret) { 423 - ret = dev_err_probe(dev, ret, "Failed to read led 'reg' property\n"); 424 - goto put_child_node; 425 - } 422 + if (ret) 423 + return dev_err_probe(dev, ret, "Failed to read led 'reg' property\n"); 426 424 427 - if (reg < 1 || reg > is31->cdef->num_leds) { 428 - ret = dev_err_probe(dev, -EINVAL, "invalid led reg %u\n", reg); 429 - goto put_child_node; 430 - } 425 + if (reg < 1 || reg > is31->cdef->num_leds) 426 + return dev_err_probe(dev, -EINVAL, "invalid led reg %u\n", reg); 431 427 432 428 led = &is31->leds[reg - 1]; 433 429 434 - if (led->configured) { 435 - ret = dev_err_probe(dev, -EINVAL, "led %u is already configured\n", reg); 436 - goto put_child_node; 437 - } 430 + if (led->configured) 431 + return dev_err_probe(dev, -EINVAL, "led %u is already configured\n", reg); 438 432 439 433 ret = is31fl319x_parse_child_fw(dev, child, led, is31); 440 - if (ret) { 441 - ret = dev_err_probe(dev, ret, "led %u DT parsing failed\n", reg); 442 - goto put_child_node; 443 - } 434 + if (ret) 435 + return dev_err_probe(dev, ret, "led %u DT parsing failed\n", reg); 444 436 445 437 led->configured = true; 446 438 } ··· 446 454 } 447 455 448 456 return 0; 449 - 450 - put_child_node: 451 - fwnode_handle_put(child); 452 - return ret; 453 457 } 454 458 455 459 static inline int is31fl3190_microamp_to_cs(struct device *dev, u32 microamp)
+4 -10
drivers/leds/leds-is31fl32xx.c
··· 363 363 static int is31fl32xx_parse_dt(struct device *dev, 364 364 struct is31fl32xx_priv *priv) 365 365 { 366 - struct device_node *child; 367 366 int ret = 0; 368 367 369 - for_each_available_child_of_node(dev_of_node(dev), child) { 368 + for_each_available_child_of_node_scoped(dev_of_node(dev), child) { 370 369 struct led_init_data init_data = {}; 371 370 struct is31fl32xx_led_data *led_data = 372 371 &priv->leds[priv->num_leds]; ··· 375 376 376 377 ret = is31fl32xx_parse_child_dt(dev, child, led_data); 377 378 if (ret) 378 - goto err; 379 + return ret; 379 380 380 381 /* Detect if channel is already in use by another child */ 381 382 other_led_data = is31fl32xx_find_led_data(priv, ··· 384 385 dev_err(dev, 385 386 "Node %pOF 'reg' conflicts with another LED\n", 386 387 child); 387 - ret = -EINVAL; 388 - goto err; 388 + return -EINVAL; 389 389 } 390 390 391 391 init_data.fwnode = of_fwnode_handle(child); ··· 394 396 if (ret) { 395 397 dev_err(dev, "Failed to register LED for %pOF: %d\n", 396 398 child, ret); 397 - goto err; 399 + return ret; 398 400 } 399 401 400 402 priv->num_leds++; 401 403 } 402 404 403 405 return 0; 404 - 405 - err: 406 - of_node_put(child); 407 - return ret; 408 406 } 409 407 410 408 static const struct of_device_id of_is31fl32xx_match[] = {
+4 -18
drivers/leds/leds-lp55xx-common.c
··· 965 965 bool lp55xx_is_extclk_used(struct lp55xx_chip *chip) 966 966 { 967 967 struct clk *clk; 968 - int err; 969 968 970 - clk = devm_clk_get(&chip->cl->dev, "32k_clk"); 969 + clk = devm_clk_get_enabled(&chip->cl->dev, "32k_clk"); 971 970 if (IS_ERR(clk)) 972 971 goto use_internal_clk; 973 972 974 - err = clk_prepare_enable(clk); 975 - if (err) 973 + if (clk_get_rate(clk) != LP55XX_CLK_32K) 976 974 goto use_internal_clk; 977 - 978 - if (clk_get_rate(clk) != LP55XX_CLK_32K) { 979 - clk_disable_unprepare(clk); 980 - goto use_internal_clk; 981 - } 982 975 983 976 dev_info(&chip->cl->dev, "%dHz external clock used\n", LP55XX_CLK_32K); 984 977 985 - chip->clk = clk; 986 978 return true; 987 979 988 980 use_internal_clk: ··· 986 994 static void lp55xx_deinit_device(struct lp55xx_chip *chip) 987 995 { 988 996 struct lp55xx_platform_data *pdata = chip->pdata; 989 - 990 - if (chip->clk) 991 - clk_disable_unprepare(chip->clk); 992 997 993 998 if (pdata->enable_gpiod) 994 999 gpiod_set_value(pdata->enable_gpiod, 0); ··· 1162 1173 struct lp55xx_led_config *cfg, 1163 1174 int child_number) 1164 1175 { 1165 - struct device_node *child; 1166 1176 int num_colors = 0, ret; 1167 1177 1168 - for_each_available_child_of_node(np, child) { 1178 + for_each_available_child_of_node_scoped(np, child) { 1169 1179 ret = lp55xx_parse_multi_led_child(child, cfg, child_number, 1170 1180 num_colors); 1171 - if (ret) { 1172 - of_node_put(child); 1181 + if (ret) 1173 1182 return ret; 1174 - } 1175 1183 num_colors++; 1176 1184 } 1177 1185
-1
drivers/leds/leds-lp55xx-common.h
··· 193 193 */ 194 194 struct lp55xx_chip { 195 195 struct i2c_client *cl; 196 - struct clk *clk; 197 196 struct lp55xx_platform_data *pdata; 198 197 struct mutex lock; /* lock for user-space interface */ 199 198 int num_leds;
+11 -13
drivers/leds/leds-mc13783.c
··· 12 12 * Eric Miao <eric.miao@marvell.com> 13 13 */ 14 14 15 + #include <linux/cleanup.h> 15 16 #include <linux/module.h> 16 17 #include <linux/kernel.h> 17 18 #include <linux/platform_device.h> ··· 114 113 { 115 114 struct mc13xxx_leds *leds = platform_get_drvdata(pdev); 116 115 struct mc13xxx_leds_platform_data *pdata; 117 - struct device_node *parent, *child; 116 + struct device_node *child; 118 117 struct device *dev = &pdev->dev; 119 118 int i = 0, ret = -ENODATA; 120 119 ··· 122 121 if (!pdata) 123 122 return ERR_PTR(-ENOMEM); 124 123 125 - parent = of_get_child_by_name(dev_of_node(dev->parent), "leds"); 124 + struct device_node *parent __free(device_node) = 125 + of_get_child_by_name(dev_of_node(dev->parent), "leds"); 126 126 if (!parent) 127 - goto out_node_put; 127 + return ERR_PTR(-ENODATA); 128 128 129 129 ret = of_property_read_u32_array(parent, "led-control", 130 130 pdata->led_control, 131 131 leds->devtype->num_regs); 132 132 if (ret) 133 - goto out_node_put; 133 + return ERR_PTR(ret); 134 134 135 135 pdata->num_leds = of_get_available_child_count(parent); 136 136 137 137 pdata->led = devm_kcalloc(dev, pdata->num_leds, sizeof(*pdata->led), 138 138 GFP_KERNEL); 139 - if (!pdata->led) { 140 - ret = -ENOMEM; 141 - goto out_node_put; 142 - } 139 + if (!pdata->led) 140 + return ERR_PTR(-ENOMEM); 143 141 144 142 for_each_available_child_of_node(parent, child) { 145 143 const char *str; ··· 158 158 } 159 159 160 160 pdata->num_leds = i; 161 - ret = i > 0 ? 0 : -ENODATA; 161 + if (i <= 0) 162 + return ERR_PTR(-ENODATA); 162 163 163 - out_node_put: 164 - of_node_put(parent); 165 - 166 - return ret ? ERR_PTR(ret) : pdata; 164 + return pdata; 167 165 } 168 166 #else 169 167 static inline struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt(
+7 -15
drivers/leds/leds-mt6323.c
··· 527 527 { 528 528 struct device *dev = &pdev->dev; 529 529 struct device_node *np = dev_of_node(dev); 530 - struct device_node *child; 531 530 struct mt6397_chip *hw = dev_get_drvdata(dev->parent); 532 531 struct mt6323_leds *leds; 533 532 struct mt6323_led *led; ··· 564 565 return ret; 565 566 } 566 567 567 - for_each_available_child_of_node(np, child) { 568 + for_each_available_child_of_node_scoped(np, child) { 568 569 struct led_init_data init_data = {}; 569 570 bool is_wled; 570 571 571 572 ret = of_property_read_u32(child, "reg", &reg); 572 573 if (ret) { 573 574 dev_err(dev, "Failed to read led 'reg' property\n"); 574 - goto put_child_node; 575 + return ret; 575 576 } 576 577 577 578 if (reg >= max_leds || reg >= MAX_SUPPORTED_LEDS || 578 579 leds->led[reg]) { 579 580 dev_err(dev, "Invalid led reg %u\n", reg); 580 - ret = -EINVAL; 581 - goto put_child_node; 581 + return -EINVAL; 582 582 } 583 583 584 584 led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL); 585 - if (!led) { 586 - ret = -ENOMEM; 587 - goto put_child_node; 588 - } 585 + if (!led) 586 + return -ENOMEM; 589 587 590 588 is_wled = of_property_read_bool(child, "mediatek,is-wled"); 591 589 ··· 608 612 if (ret < 0) { 609 613 dev_err(leds->dev, 610 614 "Failed to LED set default from devicetree\n"); 611 - goto put_child_node; 615 + return ret; 612 616 } 613 617 614 618 init_data.fwnode = of_fwnode_handle(child); ··· 617 621 &init_data); 618 622 if (ret) { 619 623 dev_err(dev, "Failed to register LED: %d\n", ret); 620 - goto put_child_node; 624 + return ret; 621 625 } 622 626 } 623 627 624 628 return 0; 625 - 626 - put_child_node: 627 - of_node_put(child); 628 - return ret; 629 629 } 630 630 631 631 static void mt6323_led_remove(struct platform_device *pdev)
+8 -11
drivers/leds/leds-netxbig.c
··· 423 423 struct device_node *gpio_ext_np; 424 424 struct platform_device *gpio_ext_pdev; 425 425 struct device *gpio_ext_dev; 426 - struct device_node *child; 427 426 struct netxbig_gpio_ext *gpio_ext; 428 427 struct netxbig_led_timer *timers; 429 428 struct netxbig_led *leds, *led; ··· 506 507 } 507 508 508 509 led = leds; 509 - for_each_available_child_of_node(np, child) { 510 + for_each_available_child_of_node_scoped(np, child) { 510 511 const char *string; 511 512 int *mode_val; 512 513 int num_modes; ··· 514 515 ret = of_property_read_u32(child, "mode-addr", 515 516 &led->mode_addr); 516 517 if (ret) 517 - goto err_node_put; 518 + goto put_device; 518 519 519 520 ret = of_property_read_u32(child, "bright-addr", 520 521 &led->bright_addr); 521 522 if (ret) 522 - goto err_node_put; 523 + goto put_device; 523 524 524 525 ret = of_property_read_u32(child, "max-brightness", 525 526 &led->bright_max); 526 527 if (ret) 527 - goto err_node_put; 528 + goto put_device; 528 529 529 530 mode_val = 530 531 devm_kcalloc(dev, ··· 532 533 GFP_KERNEL); 533 534 if (!mode_val) { 534 535 ret = -ENOMEM; 535 - goto err_node_put; 536 + goto put_device; 536 537 } 537 538 538 539 for (i = 0; i < NETXBIG_LED_MODE_NUM; i++) ··· 541 542 ret = of_property_count_u32_elems(child, "mode-val"); 542 543 if (ret < 0 || ret % 2) { 543 544 ret = -EINVAL; 544 - goto err_node_put; 545 + goto put_device; 545 546 } 546 547 num_modes = ret / 2; 547 548 if (num_modes > NETXBIG_LED_MODE_NUM) { 548 549 ret = -EINVAL; 549 - goto err_node_put; 550 + goto put_device; 550 551 } 551 552 552 553 for (i = 0; i < num_modes; i++) { ··· 559 560 "mode-val", 2 * i + 1, &val); 560 561 if (mode >= NETXBIG_LED_MODE_NUM) { 561 562 ret = -EINVAL; 562 - goto err_node_put; 563 + goto put_device; 563 564 } 564 565 mode_val[mode] = val; 565 566 } ··· 582 583 583 584 return 0; 584 585 585 - err_node_put: 586 - of_node_put(child); 587 586 put_device: 588 587 put_device(gpio_ext_dev); 589 588 return ret;
+4 -8
drivers/leds/leds-pca9532.c
··· 215 215 if (other->state == PCA9532_PWM1) { 216 216 if (other->ldev.blink_delay_on != delay_on || 217 217 other->ldev.blink_delay_off != delay_off) { 218 - dev_err(&led->client->dev, 219 - "HW can handle only one blink configuration at a time\n"); 218 + /* HW can handle only one blink configuration at a time */ 220 219 return -EINVAL; 221 220 } 222 221 } ··· 223 224 224 225 psc = ((delay_on + delay_off) * PCA9532_PWM_PERIOD_DIV - 1) / 1000; 225 226 if (psc > U8_MAX) { 226 - dev_err(&led->client->dev, "Blink period too long to be handled by hardware\n"); 227 + /* Blink period too long to be handled by hardware */ 227 228 return -EINVAL; 228 229 } 229 230 ··· 505 506 pca9532_of_populate_pdata(struct device *dev, struct device_node *np) 506 507 { 507 508 struct pca9532_platform_data *pdata; 508 - struct device_node *child; 509 509 int devid, maxleds; 510 510 int i = 0; 511 511 const char *state; ··· 523 525 of_property_read_u8_array(np, "nxp,psc", &pdata->psc[PCA9532_PWM_ID_0], 524 526 ARRAY_SIZE(pdata->psc)); 525 527 526 - for_each_available_child_of_node(np, child) { 528 + for_each_available_child_of_node_scoped(np, child) { 527 529 if (of_property_read_string(child, "label", 528 530 &pdata->leds[i].name)) 529 531 pdata->leds[i].name = child->name; ··· 536 538 else if (!strcmp(state, "keep")) 537 539 pdata->leds[i].state = PCA9532_KEEP; 538 540 } 539 - if (++i >= maxleds) { 540 - of_node_put(child); 541 + if (++i >= maxleds) 541 542 break; 542 - } 543 543 } 544 544 545 545 return pdata;
+46 -32
drivers/leds/leds-pca995x.c
··· 19 19 #define PCA995X_MODE1 0x00 20 20 #define PCA995X_MODE2 0x01 21 21 #define PCA995X_LEDOUT0 0x02 22 - #define PCA9955B_PWM0 0x08 23 - #define PCA9952_PWM0 0x0A 24 - #define PCA9952_IREFALL 0x43 25 - #define PCA9955B_IREFALL 0x45 26 22 27 23 /* Auto-increment disabled. Normal mode */ 28 24 #define PCA995X_MODE1_CFG 0x00 ··· 30 34 #define PCA995X_LDRX_MASK 0x3 31 35 #define PCA995X_LDRX_BITS 2 32 36 33 - #define PCA995X_MAX_OUTPUTS 16 37 + #define PCA995X_MAX_OUTPUTS 24 34 38 #define PCA995X_OUTPUTS_PER_REG 4 35 39 36 40 #define PCA995X_IREFALL_FULL_CFG 0xFF 37 41 #define PCA995X_IREFALL_HALF_CFG (PCA995X_IREFALL_FULL_CFG / 2) 38 42 39 - #define PCA995X_TYPE_NON_B 0 40 - #define PCA995X_TYPE_B 1 41 - 42 43 #define ldev_to_led(c) container_of(c, struct pca995x_led, ldev) 44 + 45 + struct pca995x_chipdef { 46 + unsigned int num_leds; 47 + u8 pwm_base; 48 + u8 irefall; 49 + }; 50 + 51 + static const struct pca995x_chipdef pca9952_chipdef = { 52 + .num_leds = 16, 53 + .pwm_base = 0x0a, 54 + .irefall = 0x43, 55 + }; 56 + 57 + static const struct pca995x_chipdef pca9955b_chipdef = { 58 + .num_leds = 16, 59 + .pwm_base = 0x08, 60 + .irefall = 0x45, 61 + }; 62 + 63 + static const struct pca995x_chipdef pca9956b_chipdef = { 64 + .num_leds = 24, 65 + .pwm_base = 0x0a, 66 + .irefall = 0x40, 67 + }; 43 68 44 69 struct pca995x_led { 45 70 unsigned int led_no; ··· 71 54 struct pca995x_chip { 72 55 struct regmap *regmap; 73 56 struct pca995x_led leds[PCA995X_MAX_OUTPUTS]; 74 - int btype; 57 + const struct pca995x_chipdef *chipdef; 75 58 }; 76 59 77 60 static int pca995x_brightness_set(struct led_classdev *led_cdev, ··· 79 62 { 80 63 struct pca995x_led *led = ldev_to_led(led_cdev); 81 64 struct pca995x_chip *chip = led->chip; 65 + const struct pca995x_chipdef *chipdef = chip->chipdef; 82 66 u8 ledout_addr, pwmout_addr; 83 67 int shift, ret; 84 68 85 - pwmout_addr = (chip->btype ? PCA9955B_PWM0 : PCA9952_PWM0) + led->led_no; 69 + pwmout_addr = chipdef->pwm_base + led->led_no; 86 70 ledout_addr = PCA995X_LEDOUT0 + (led->led_no / PCA995X_OUTPUTS_PER_REG); 87 71 shift = PCA995X_LDRX_BITS * (led->led_no % PCA995X_OUTPUTS_PER_REG); 88 72 ··· 120 102 static int pca995x_probe(struct i2c_client *client) 121 103 { 122 104 struct fwnode_handle *led_fwnodes[PCA995X_MAX_OUTPUTS] = { 0 }; 123 - struct fwnode_handle *np, *child; 124 105 struct device *dev = &client->dev; 106 + const struct pca995x_chipdef *chipdef; 125 107 struct pca995x_chip *chip; 126 108 struct pca995x_led *led; 127 - int i, btype, reg, ret; 109 + int i, j, reg, ret; 128 110 129 - btype = (unsigned long)device_get_match_data(&client->dev); 111 + chipdef = device_get_match_data(&client->dev); 130 112 131 - np = dev_fwnode(dev); 132 - if (!np) 113 + if (!dev_fwnode(dev)) 133 114 return -ENODEV; 134 115 135 116 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 136 117 if (!chip) 137 118 return -ENOMEM; 138 119 139 - chip->btype = btype; 120 + chip->chipdef = chipdef; 140 121 chip->regmap = devm_regmap_init_i2c(client, &pca995x_regmap); 141 122 if (IS_ERR(chip->regmap)) 142 123 return PTR_ERR(chip->regmap); 143 124 144 125 i2c_set_clientdata(client, chip); 145 126 146 - fwnode_for_each_available_child_node(np, child) { 127 + device_for_each_child_node_scoped(dev, child) { 147 128 ret = fwnode_property_read_u32(child, "reg", &reg); 148 - if (ret) { 149 - fwnode_handle_put(child); 129 + if (ret) 150 130 return ret; 151 - } 152 131 153 - if (reg < 0 || reg >= PCA995X_MAX_OUTPUTS || led_fwnodes[reg]) { 154 - fwnode_handle_put(child); 132 + if (reg < 0 || reg >= PCA995X_MAX_OUTPUTS || led_fwnodes[reg]) 155 133 return -EINVAL; 156 - } 157 134 158 135 led = &chip->leds[reg]; 159 - led_fwnodes[reg] = child; 136 + led_fwnodes[reg] = fwnode_handle_get(child); 160 137 led->chip = chip; 161 138 led->led_no = reg; 162 139 led->ldev.brightness_set_blocking = pca995x_brightness_set; ··· 170 157 &chip->leds[i].ldev, 171 158 &init_data); 172 159 if (ret < 0) { 173 - fwnode_handle_put(child); 160 + for (j = i; j < PCA995X_MAX_OUTPUTS; j++) 161 + fwnode_handle_put(led_fwnodes[j]); 174 162 return dev_err_probe(dev, ret, 175 163 "Could not register LED %s\n", 176 164 chip->leds[i].ldev.name); ··· 184 170 return ret; 185 171 186 172 /* IREF Output current value for all LEDn outputs */ 187 - return regmap_write(chip->regmap, 188 - btype ? PCA9955B_IREFALL : PCA9952_IREFALL, 189 - PCA995X_IREFALL_HALF_CFG); 173 + return regmap_write(chip->regmap, chipdef->irefall, PCA995X_IREFALL_HALF_CFG); 190 174 } 191 175 192 176 static const struct i2c_device_id pca995x_id[] = { 193 - { "pca9952", .driver_data = (kernel_ulong_t)PCA995X_TYPE_NON_B }, 194 - { "pca9955b", .driver_data = (kernel_ulong_t)PCA995X_TYPE_B }, 177 + { "pca9952", .driver_data = (kernel_ulong_t)&pca9952_chipdef }, 178 + { "pca9955b", .driver_data = (kernel_ulong_t)&pca9955b_chipdef }, 179 + { "pca9956b", .driver_data = (kernel_ulong_t)&pca9956b_chipdef }, 195 180 {} 196 181 }; 197 182 MODULE_DEVICE_TABLE(i2c, pca995x_id); 198 183 199 184 static const struct of_device_id pca995x_of_match[] = { 200 - { .compatible = "nxp,pca9952", .data = (void *)PCA995X_TYPE_NON_B }, 201 - { .compatible = "nxp,pca9955b", .data = (void *)PCA995X_TYPE_B }, 185 + { .compatible = "nxp,pca9952", .data = &pca9952_chipdef }, 186 + { .compatible = "nxp,pca9955b", . data = &pca9955b_chipdef }, 187 + { .compatible = "nxp,pca9956b", .data = &pca9956b_chipdef }, 202 188 {}, 203 189 }; 204 190 MODULE_DEVICE_TABLE(of, pca995x_of_match);
+4 -8
drivers/leds/leds-sc27xx-bltc.c
··· 276 276 static int sc27xx_led_probe(struct platform_device *pdev) 277 277 { 278 278 struct device *dev = &pdev->dev; 279 - struct device_node *np = dev_of_node(dev), *child; 279 + struct device_node *np = dev_of_node(dev); 280 280 struct sc27xx_led_priv *priv; 281 281 u32 base, count, reg; 282 282 int err; ··· 304 304 return err; 305 305 } 306 306 307 - for_each_available_child_of_node(np, child) { 307 + for_each_available_child_of_node_scoped(np, child) { 308 308 err = of_property_read_u32(child, "reg", &reg); 309 - if (err) { 310 - of_node_put(child); 309 + if (err) 311 310 return err; 312 - } 313 311 314 - if (reg >= SC27XX_LEDS_MAX || priv->leds[reg].active) { 315 - of_node_put(child); 312 + if (reg >= SC27XX_LEDS_MAX || priv->leds[reg].active) 316 313 return -EINVAL; 317 - } 318 314 319 315 priv->leds[reg].fwnode = of_fwnode_handle(child); 320 316 priv->leds[reg].active = true;
+1 -1
drivers/leds/leds-sun50i-a100.c
··· 368 368 if (!xfer_active) 369 369 break; 370 370 371 - msleep(1); 371 + usleep_range(1000, 1100); 372 372 } 373 373 374 374 clk_disable_unprepare(priv->mod_clk);
+4 -5
drivers/leds/leds-turris-omnia.c
··· 452 452 static int omnia_leds_probe(struct i2c_client *client) 453 453 { 454 454 struct device *dev = &client->dev; 455 - struct device_node *np = dev_of_node(dev), *child; 455 + struct device_node *np = dev_of_node(dev); 456 456 struct omnia_leds *leds; 457 457 struct omnia_led *led; 458 458 int ret, count; ··· 497 497 } 498 498 499 499 led = &leds->leds[0]; 500 - for_each_available_child_of_node(np, child) { 500 + for_each_available_child_of_node_scoped(np, child) { 501 501 ret = omnia_led_register(client, led, child); 502 - if (ret < 0) { 503 - of_node_put(child); 502 + if (ret < 0) 504 503 return ret; 505 - } 506 504 507 505 led += ret; 508 506 } ··· 530 532 { .compatible = "cznic,turris-omnia-leds", }, 531 533 {}, 532 534 }; 535 + MODULE_DEVICE_TABLE(of, of_omnia_leds_match); 533 536 534 537 static const struct i2c_device_id omnia_id[] = { 535 538 { "omnia" },
+4 -10
drivers/leds/rgb/leds-qcom-lpg.c
··· 1368 1368 { 1369 1369 struct led_init_data init_data = {}; 1370 1370 struct led_classdev *cdev; 1371 - struct device_node *child; 1372 1371 struct mc_subled *info; 1373 1372 struct lpg_led *led; 1374 1373 const char *state; ··· 1398 1399 if (!info) 1399 1400 return -ENOMEM; 1400 1401 i = 0; 1401 - for_each_available_child_of_node(np, child) { 1402 + for_each_available_child_of_node_scoped(np, child) { 1402 1403 ret = lpg_parse_channel(lpg, child, &led->channels[i]); 1403 - if (ret < 0) { 1404 - of_node_put(child); 1404 + if (ret < 0) 1405 1405 return ret; 1406 - } 1407 1406 1408 1407 info[i].color_index = led->channels[i]->color; 1409 1408 info[i].intensity = 0; ··· 1597 1600 1598 1601 static int lpg_probe(struct platform_device *pdev) 1599 1602 { 1600 - struct device_node *np; 1601 1603 struct lpg *lpg; 1602 1604 int ret; 1603 1605 int i; ··· 1636 1640 if (ret < 0) 1637 1641 return ret; 1638 1642 1639 - for_each_available_child_of_node(pdev->dev.of_node, np) { 1643 + for_each_available_child_of_node_scoped(pdev->dev.of_node, np) { 1640 1644 ret = lpg_add_led(lpg, np); 1641 - if (ret) { 1642 - of_node_put(np); 1645 + if (ret) 1643 1646 return ret; 1644 - } 1645 1647 } 1646 1648 1647 1649 for (i = 0; i < lpg->num_channels; i++)
+21 -3
drivers/leds/trigger/ledtrig-netdev.c
··· 39 39 * (has carrier) or not 40 40 * tx - LED blinks on transmitted data 41 41 * rx - LED blinks on receive data 42 + * tx_err - LED blinks on transmit error 43 + * rx_err - LED blinks on receive error 42 44 * 43 45 * Note: If the user selects a mode that is not supported by hw, default 44 46 * behavior is to fall back to software control of the LED. However not every ··· 146 144 * checking stats 147 145 */ 148 146 if (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) || 149 - test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) 147 + test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) || 148 + test_bit(TRIGGER_NETDEV_TX_ERR, &trigger_data->mode) || 149 + test_bit(TRIGGER_NETDEV_RX_ERR, &trigger_data->mode)) 150 150 schedule_delayed_work(&trigger_data->work, 0); 151 151 } 152 152 } ··· 341 337 case TRIGGER_NETDEV_FULL_DUPLEX: 342 338 case TRIGGER_NETDEV_TX: 343 339 case TRIGGER_NETDEV_RX: 340 + case TRIGGER_NETDEV_TX_ERR: 341 + case TRIGGER_NETDEV_RX_ERR: 344 342 bit = attr; 345 343 break; 346 344 default: ··· 377 371 case TRIGGER_NETDEV_FULL_DUPLEX: 378 372 case TRIGGER_NETDEV_TX: 379 373 case TRIGGER_NETDEV_RX: 374 + case TRIGGER_NETDEV_TX_ERR: 375 + case TRIGGER_NETDEV_RX_ERR: 380 376 bit = attr; 381 377 break; 382 378 default: ··· 437 429 DEFINE_NETDEV_TRIGGER(full_duplex, TRIGGER_NETDEV_FULL_DUPLEX); 438 430 DEFINE_NETDEV_TRIGGER(tx, TRIGGER_NETDEV_TX); 439 431 DEFINE_NETDEV_TRIGGER(rx, TRIGGER_NETDEV_RX); 432 + DEFINE_NETDEV_TRIGGER(tx_err, TRIGGER_NETDEV_TX_ERR); 433 + DEFINE_NETDEV_TRIGGER(rx_err, TRIGGER_NETDEV_RX_ERR); 440 434 441 435 static ssize_t interval_show(struct device *dev, 442 436 struct device_attribute *attr, char *buf) ··· 548 538 &dev_attr_half_duplex.attr, 549 539 &dev_attr_rx.attr, 550 540 &dev_attr_tx.attr, 541 + &dev_attr_rx_err.attr, 542 + &dev_attr_tx_err.attr, 551 543 &dev_attr_interval.attr, 552 544 &dev_attr_offloaded.attr, 553 545 NULL ··· 640 628 641 629 /* If we are not looking for RX/TX then return */ 642 630 if (!test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) && 643 - !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode)) 631 + !test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) && 632 + !test_bit(TRIGGER_NETDEV_TX_ERR, &trigger_data->mode) && 633 + !test_bit(TRIGGER_NETDEV_RX_ERR, &trigger_data->mode)) 644 634 return; 645 635 646 636 dev_stats = dev_get_stats(trigger_data->net_dev, &temp); ··· 650 636 (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ? 651 637 dev_stats->tx_packets : 0) + 652 638 (test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ? 653 - dev_stats->rx_packets : 0); 639 + dev_stats->rx_packets : 0) + 640 + (test_bit(TRIGGER_NETDEV_TX_ERR, &trigger_data->mode) ? 641 + dev_stats->tx_errors : 0) + 642 + (test_bit(TRIGGER_NETDEV_RX_ERR, &trigger_data->mode) ? 643 + dev_stats->rx_errors : 0); 654 644 655 645 if (trigger_data->last_activity != new_activity) { 656 646 led_stop_software_blink(trigger_data->led_cdev);
+2
include/linux/leds.h
··· 611 611 TRIGGER_NETDEV_FULL_DUPLEX, 612 612 TRIGGER_NETDEV_TX, 613 613 TRIGGER_NETDEV_RX, 614 + TRIGGER_NETDEV_TX_ERR, 615 + TRIGGER_NETDEV_RX_ERR, 614 616 615 617 /* Keep last */ 616 618 __TRIGGER_NETDEV_MAX,