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

Merge tag 'leds-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds

Pull LED updates from Pavel Machek:
"Small cleanups/fixes mostly thanks to Marek, nothing major made it in
this time"

* tag 'leds-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds:
leds: turris-omnia: check for LED_COLOR_ID_RGB instead LED_COLOR_ID_MULTI
leds: turris-omnia: fix checkpatch warning
leds: turris-omnia: wrap to 80 columns
leds: turris-omnia: use constants instead of macros for color command
dt-bindings: leds: Convert pwm to yaml
leds: lp50xx: Fix an error handling path in 'lp50xx_probe_dt()'
leds: netxbig: add missing put_device() call in netxbig_leds_get_of_pdata()
Documentation: leds: remove invalidated information

+139 -117
-50
Documentation/devicetree/bindings/leds/leds-pwm.txt
··· 1 - LED connected to PWM 2 - 3 - Required properties: 4 - - compatible : should be "pwm-leds". 5 - 6 - Each LED is represented as a sub-node of the pwm-leds device. Each 7 - node's name represents the name of the corresponding LED. 8 - 9 - LED sub-node properties: 10 - - pwms : PWM property to point to the PWM device (phandle)/port (id) and to 11 - specify the period time to be used: <&phandle id period_ns>; 12 - - pwm-names : (optional) Name to be used by the PWM subsystem for the PWM device 13 - For the pwms and pwm-names property please refer to: 14 - Documentation/devicetree/bindings/pwm/pwm.txt 15 - - max-brightness : Maximum brightness possible for the LED 16 - - active-low : (optional) For PWMs where the LED is wired to supply 17 - rather than ground. 18 - - label : (optional) 19 - see Documentation/devicetree/bindings/leds/common.txt 20 - - linux,default-trigger : (optional) 21 - see Documentation/devicetree/bindings/leds/common.txt 22 - 23 - Example: 24 - 25 - twl_pwm: pwm { 26 - /* provides two PWMs (id 0, 1 for PWM1 and PWM2) */ 27 - compatible = "ti,twl6030-pwm"; 28 - #pwm-cells = <2>; 29 - }; 30 - 31 - twl_pwmled: pwmled { 32 - /* provides one PWM (id 0 for Charing indicator LED) */ 33 - compatible = "ti,twl6030-pwmled"; 34 - #pwm-cells = <2>; 35 - }; 36 - 37 - pwmleds { 38 - compatible = "pwm-leds"; 39 - kpad { 40 - label = "omap4::keypad"; 41 - pwms = <&twl_pwm 0 7812500>; 42 - max-brightness = <127>; 43 - }; 44 - 45 - charging { 46 - label = "omap4:green:chrg"; 47 - pwms = <&twl_pwmled 0 7812500>; 48 - max-brightness = <255>; 49 - }; 50 - };
+70
Documentation/devicetree/bindings/leds/leds-pwm.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/leds-pwm.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: LEDs connected to PWM 8 + 9 + maintainers: 10 + - Pavel Machek <pavel@ucw.cz> 11 + 12 + description: 13 + Each LED is represented as a sub-node of the pwm-leds device. Each 14 + node's name represents the name of the corresponding LED. 15 + 16 + properties: 17 + compatible: 18 + const: pwm-leds 19 + 20 + patternProperties: 21 + "^led(-[0-9a-f]+)?$": 22 + type: object 23 + 24 + $ref: common.yaml# 25 + 26 + properties: 27 + pwms: 28 + maxItems: 1 29 + 30 + pwm-names: true 31 + 32 + max-brightness: 33 + description: 34 + Maximum brightness possible for the LED 35 + $ref: /schemas/types.yaml#/definitions/uint32 36 + 37 + active-low: 38 + description: 39 + For PWMs where the LED is wired to supply rather than ground. 40 + type: boolean 41 + 42 + required: 43 + - pwms 44 + - max-brightness 45 + 46 + additionalProperties: false 47 + 48 + examples: 49 + - | 50 + 51 + #include <dt-bindings/leds/common.h> 52 + 53 + led-controller { 54 + compatible = "pwm-leds"; 55 + 56 + led-1 { 57 + label = "omap4::keypad"; 58 + pwms = <&twl_pwm 0 7812500>; 59 + max-brightness = <127>; 60 + }; 61 + 62 + led-2 { 63 + color = <LED_COLOR_ID_GREEN>; 64 + function = LED_FUNCTION_CHARGING; 65 + pwms = <&twl_pwmled 0 7812500>; 66 + max-brightness = <255>; 67 + }; 68 + }; 69 + 70 + ...
-10
Documentation/leds/leds-class.rst
··· 177 177 would cause nightmare dependency issues. I see this as a minor issue 178 178 compared to the benefits the simple trigger functionality brings. The 179 179 rest of the LED subsystem can be modular. 180 - 181 - 182 - Future Development 183 - ================== 184 - 185 - At the moment, a trigger can't be created specifically for a single LED. 186 - There are a number of cases where a trigger might only be mappable to a 187 - particular LED (ACPI?). The addition of triggers provided by the LED driver 188 - should cover this option and be possible to add without breaking the 189 - current interface.
+4 -2
drivers/leds/leds-lp50xx.c
··· 487 487 */ 488 488 mc_led_info = devm_kcalloc(priv->dev, LP50XX_LEDS_PER_MODULE, 489 489 sizeof(*mc_led_info), GFP_KERNEL); 490 - if (!mc_led_info) 491 - return -ENOMEM; 490 + if (!mc_led_info) { 491 + ret = -ENOMEM; 492 + goto child_out; 493 + } 492 494 493 495 fwnode_for_each_child_node(child, led_node) { 494 496 ret = fwnode_property_read_u32(led_node, "color",
+24 -11
drivers/leds/leds-netxbig.c
··· 448 448 gpio_ext = devm_kzalloc(dev, sizeof(*gpio_ext), GFP_KERNEL); 449 449 if (!gpio_ext) { 450 450 of_node_put(gpio_ext_np); 451 - return -ENOMEM; 451 + ret = -ENOMEM; 452 + goto put_device; 452 453 } 453 454 ret = netxbig_gpio_ext_get(dev, gpio_ext_dev, gpio_ext); 454 455 of_node_put(gpio_ext_np); 455 456 if (ret) 456 - return ret; 457 + goto put_device; 457 458 pdata->gpio_ext = gpio_ext; 458 459 459 460 /* Timers (optional) */ 460 461 ret = of_property_count_u32_elems(np, "timers"); 461 462 if (ret > 0) { 462 - if (ret % 3) 463 - return -EINVAL; 463 + if (ret % 3) { 464 + ret = -EINVAL; 465 + goto put_device; 466 + } 467 + 464 468 num_timers = ret / 3; 465 469 timers = devm_kcalloc(dev, num_timers, sizeof(*timers), 466 470 GFP_KERNEL); 467 - if (!timers) 468 - return -ENOMEM; 471 + if (!timers) { 472 + ret = -ENOMEM; 473 + goto put_device; 474 + } 469 475 for (i = 0; i < num_timers; i++) { 470 476 u32 tmp; 471 477 472 478 of_property_read_u32_index(np, "timers", 3 * i, 473 479 &timers[i].mode); 474 - if (timers[i].mode >= NETXBIG_LED_MODE_NUM) 475 - return -EINVAL; 480 + if (timers[i].mode >= NETXBIG_LED_MODE_NUM) { 481 + ret = -EINVAL; 482 + goto put_device; 483 + } 476 484 of_property_read_u32_index(np, "timers", 477 485 3 * i + 1, &tmp); 478 486 timers[i].delay_on = tmp; ··· 496 488 num_leds = of_get_available_child_count(np); 497 489 if (!num_leds) { 498 490 dev_err(dev, "No LED subnodes found in DT\n"); 499 - return -ENODEV; 491 + ret = -ENODEV; 492 + goto put_device; 500 493 } 501 494 502 495 leds = devm_kcalloc(dev, num_leds, sizeof(*leds), GFP_KERNEL); 503 - if (!leds) 504 - return -ENOMEM; 496 + if (!leds) { 497 + ret = -ENOMEM; 498 + goto put_device; 499 + } 505 500 506 501 led = leds; 507 502 for_each_available_child_of_node(np, child) { ··· 585 574 586 575 err_node_put: 587 576 of_node_put(child); 577 + put_device: 578 + put_device(gpio_ext_dev); 588 579 return ret; 589 580 } 590 581
+41 -44
drivers/leds/leds-turris-omnia.c
··· 12 12 #include <linux/of.h> 13 13 #include "leds.h" 14 14 15 - #define OMNIA_BOARD_LEDS 12 16 - #define OMNIA_LED_NUM_CHANNELS 3 15 + #define OMNIA_BOARD_LEDS 12 16 + #define OMNIA_LED_NUM_CHANNELS 3 17 17 18 - #define CMD_LED_MODE 3 19 - #define CMD_LED_MODE_LED(l) ((l) & 0x0f) 20 - #define CMD_LED_MODE_USER 0x10 18 + #define CMD_LED_MODE 3 19 + #define CMD_LED_MODE_LED(l) ((l) & 0x0f) 20 + #define CMD_LED_MODE_USER 0x10 21 21 22 - #define CMD_LED_STATE 4 23 - #define CMD_LED_STATE_LED(l) ((l) & 0x0f) 24 - #define CMD_LED_STATE_ON 0x10 22 + #define CMD_LED_STATE 4 23 + #define CMD_LED_STATE_LED(l) ((l) & 0x0f) 24 + #define CMD_LED_STATE_ON 0x10 25 25 26 - #define CMD_LED_COLOR 5 27 - #define CMD_LED_SET_BRIGHTNESS 7 28 - #define CMD_LED_GET_BRIGHTNESS 8 29 - 30 - #define OMNIA_CMD 0 31 - 32 - #define OMNIA_CMD_LED_COLOR_LED 1 33 - #define OMNIA_CMD_LED_COLOR_R 2 34 - #define OMNIA_CMD_LED_COLOR_G 3 35 - #define OMNIA_CMD_LED_COLOR_B 4 36 - #define OMNIA_CMD_LED_COLOR_LEN 5 26 + #define CMD_LED_COLOR 5 27 + #define CMD_LED_SET_BRIGHTNESS 7 28 + #define CMD_LED_GET_BRIGHTNESS 8 37 29 38 30 struct omnia_led { 39 31 struct led_classdev_mc mc_cdev; ··· 33 41 int reg; 34 42 }; 35 43 36 - #define to_omnia_led(l) container_of(l, struct omnia_led, mc_cdev) 44 + #define to_omnia_led(l) container_of(l, struct omnia_led, mc_cdev) 37 45 38 46 struct omnia_leds { 39 47 struct i2c_client *client; ··· 47 55 struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); 48 56 struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); 49 57 struct omnia_led *led = to_omnia_led(mc_cdev); 50 - u8 buf[OMNIA_CMD_LED_COLOR_LEN], state; 58 + u8 buf[5], state; 51 59 int ret; 52 60 53 61 mutex_lock(&leds->lock); 54 62 55 63 led_mc_calc_color_components(&led->mc_cdev, brightness); 56 64 57 - buf[OMNIA_CMD] = CMD_LED_COLOR; 58 - buf[OMNIA_CMD_LED_COLOR_LED] = led->reg; 59 - buf[OMNIA_CMD_LED_COLOR_R] = mc_cdev->subled_info[0].brightness; 60 - buf[OMNIA_CMD_LED_COLOR_G] = mc_cdev->subled_info[1].brightness; 61 - buf[OMNIA_CMD_LED_COLOR_B] = mc_cdev->subled_info[2].brightness; 65 + buf[0] = CMD_LED_COLOR; 66 + buf[1] = led->reg; 67 + buf[2] = mc_cdev->subled_info[0].brightness; 68 + buf[3] = mc_cdev->subled_info[1].brightness; 69 + buf[4] = mc_cdev->subled_info[2].brightness; 62 70 63 71 state = CMD_LED_STATE_LED(led->reg); 64 - if (buf[OMNIA_CMD_LED_COLOR_R] || buf[OMNIA_CMD_LED_COLOR_G] || buf[OMNIA_CMD_LED_COLOR_B]) 72 + if (buf[2] || buf[3] || buf[4]) 65 73 state |= CMD_LED_STATE_ON; 66 74 67 75 ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state); ··· 90 98 } 91 99 92 100 ret = of_property_read_u32(np, "color", &color); 93 - if (ret || color != LED_COLOR_ID_MULTI) { 101 + if (ret || color != LED_COLOR_ID_RGB) { 94 102 dev_warn(dev, 95 - "Node %pOF: must contain 'color' property with value LED_COLOR_ID_MULTI\n", 103 + "Node %pOF: must contain 'color' property with value LED_COLOR_ID_RGB\n", 96 104 np); 97 105 return 0; 98 106 } ··· 118 126 CMD_LED_MODE_LED(led->reg) | 119 127 CMD_LED_MODE_USER); 120 128 if (ret < 0) { 121 - dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, ret); 129 + dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np, 130 + ret); 122 131 return ret; 123 132 } 124 133 125 134 /* disable the LED */ 126 - ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE, CMD_LED_STATE_LED(led->reg)); 135 + ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE, 136 + CMD_LED_STATE_LED(led->reg)); 127 137 if (ret < 0) { 128 138 dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret); 129 139 return ret; 130 140 } 131 141 132 - ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev, &init_data); 142 + ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev, 143 + &init_data); 133 144 if (ret < 0) { 134 145 dev_err(dev, "Cannot register LED %pOF: %i\n", np, ret); 135 146 return ret; ··· 152 157 * file lives in the device directory of the LED controller, not an individual 153 158 * LED, so it should not confuse users. 154 159 */ 155 - static ssize_t brightness_show(struct device *dev, struct device_attribute *a, char *buf) 160 + static ssize_t brightness_show(struct device *dev, struct device_attribute *a, 161 + char *buf) 156 162 { 157 163 struct i2c_client *client = to_i2c_client(dev); 158 164 struct omnia_leds *leds = i2c_get_clientdata(client); ··· 169 173 return sprintf(buf, "%d\n", ret); 170 174 } 171 175 172 - static ssize_t brightness_store(struct device *dev, struct device_attribute *a, const char *buf, 173 - size_t count) 176 + static ssize_t brightness_store(struct device *dev, struct device_attribute *a, 177 + const char *buf, size_t count) 174 178 { 175 179 struct i2c_client *client = to_i2c_client(dev); 176 180 struct omnia_leds *leds = i2c_get_clientdata(client); 177 - unsigned int brightness; 181 + unsigned long brightness; 178 182 int ret; 179 183 180 - if (sscanf(buf, "%u", &brightness) != 1) 184 + if (kstrtoul(buf, 10, &brightness)) 181 185 return -EINVAL; 182 186 183 187 if (brightness > 100) 184 188 return -EINVAL; 185 189 186 190 mutex_lock(&leds->lock); 187 - ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS, (u8) brightness); 191 + ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS, 192 + (u8)brightness); 188 193 mutex_unlock(&leds->lock); 189 194 190 195 if (ret < 0) ··· 247 250 248 251 static int omnia_leds_remove(struct i2c_client *client) 249 252 { 250 - u8 buf[OMNIA_CMD_LED_COLOR_LEN]; 253 + u8 buf[5]; 251 254 252 255 /* put all LEDs into default (HW triggered) mode */ 253 256 i2c_smbus_write_byte_data(client, CMD_LED_MODE, 254 257 CMD_LED_MODE_LED(OMNIA_BOARD_LEDS)); 255 258 256 259 /* set all LEDs color to [255, 255, 255] */ 257 - buf[OMNIA_CMD] = CMD_LED_COLOR; 258 - buf[OMNIA_CMD_LED_COLOR_LED] = OMNIA_BOARD_LEDS; 259 - buf[OMNIA_CMD_LED_COLOR_R] = 255; 260 - buf[OMNIA_CMD_LED_COLOR_G] = 255; 261 - buf[OMNIA_CMD_LED_COLOR_B] = 255; 260 + buf[0] = CMD_LED_COLOR; 261 + buf[1] = OMNIA_BOARD_LEDS; 262 + buf[2] = 255; 263 + buf[3] = 255; 264 + buf[4] = 255; 262 265 263 266 i2c_master_send(client, buf, 5); 264 267