- Removed unused local header files from various drivers.

- Reverted platform driver removal to the original method for consistency.
 - Introduced ordered workqueues for LED events, replacing the less efficient system_wq.
 - Switched to a safer iteration macro in several drivers to prevent potential memory leaks.
 - Fixed a refcounting bug in the mt6360 flash LED driver.
 - Fixed an uninitialized variable in the mt6370_mc_pattern_clear() function.
 - Resolved Smatch warnings in the leds-bcm6328 driver.
 - Addressed a potential NULL pointer dereference in the brightness_show() function.
 - Fixed an incorrect format specifier in the ss4200 driver.
 - Prevented a resource leak in the max5970 driver's probe function.
 - Added support for specifying the number of serial shift bits in the device tree for the BCM63138 family.
 - Implemented multicolor brightness control in the lp5562 driver.
 - Added a device tree property to override the default LED pin polarity.
 - Added a property to specify the default brightness value when the LED is initially on.
 - Set missing timing properties for the ktd2692 driver.
 - Documented the "rc-feedback" trigger for controlling LEDs based on remote control activity.
 - Converted text bindings to YAML for the pca955x driver to enable device tree validation.
 - Removed redundant checks for invalid channel numbers in the lp55xx driver.
 - Updated the MAINTAINERS file with current contact information.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmc/KSgACgkQUa+KL4f8
 d2HvLRAAsTuxvq89Ooe5eVWTY39fADykEx8sLgKTJWBs+A4EkD6a6DZAU0QQKZeX
 o7ERtasl5E0WFXF2BaVYPWNDjcSFlqG3AB5PbQLpzUUEkllJWEaWz5ZthpTMct5n
 Q/ylbTA8dYS+bw3bztTKWRWX8RMXKSHdjymJoSuoFLY7T1MLqNHZbu+whNKfC++h
 UMMXyx2M9B+3/0cDghy1EvCWkBTVOL9GzhQhAc+guQTCA8VeK+7LilnCtDOwymdO
 lScTM87S5gD6n22tcDFHhHH+qXVG8LfNpRRKiZdv6BmFJwHpXD+nAMReJOmyReDp
 jepy1aX/W/1cw/GMzd/nOMx/8u8rbO5Up9euCS/jFvgSpn9bKYIlMy2CVsAznOGN
 elt/kCD3nIxY8pzMTnvxCEVYj+hfbCKQWq51cm6G5hhQbfVw72fwiVIGTy8fadO3
 kLOiWM3EKvtpjbdMl0BzWVOIPLO0gQOeYH7ZYb7TM0g3mtFo47DhoGHYQCiaGgko
 Bpb+4fcXpeFLTutM5HGvqqfOCnl/uk4Gf3KhdECSmjFb3L0JbWE/JN3CMq+AR7oK
 FcOhYhNVEGu7VILQYScmChz/DzJT267lyLKF7y1jkmz5ZKMD2r+8XZ2xEb5ks6PG
 +gU7lMY2OXWs/lB9rGTRfCkS50DFJfNG2F5oN7fZ5UJLMWL1EY8=
 =qZhx
 -----END PGP SIGNATURE-----

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

PULL LED updates from Lee Jones:

 - Remove unused local header files from various drivers

 - Revert platform driver removal to the original method for consistency

 - Introduce ordered workqueues for LED events, replacing the less
   efficient system_wq

 - Switch to a safer iteration macro in several drivers to prevent
   potential memory leaks

 - Fix a refcounting bug in the mt6360 flash LED driver

 - Fix an uninitialized variable in the mt6370_mc_pattern_clear()
   function

 - Resolve Smatch warnings in the leds-bcm6328 driver

 - Address a potential NULL pointer dereference in the brightness_show()
   function

 - Fix an incorrect format specifier in the ss4200 driver

 - Prevent a resource leak in the max5970 driver's probe function

 - Add support for specifying the number of serial shift bits in the
   device tree for the BCM63138 family

 - Implement multicolor brightness control in the lp5562 driver

 - Add a device tree property to override the default LED pin polarity

 - Add a property to specify the default brightness value when the LED
   is initially on

 - Set missing timing properties for the ktd2692 driver

 - Document the "rc-feedback" trigger for controlling LEDs based on
   remote control activity

 - Convert text bindings to YAML for the pca955x driver to enable device
   tree validation

 - Remove redundant checks for invalid channel numbers in the lp55xx
   driver

 - Update the MAINTAINERS file with current contact information

* tag 'leds-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/leds: (46 commits)
  leds: ss4200: Fix the wrong format specifier for 'blinking'
  leds: pwm: Add optional DT property default-brightness
  dt-bindings: leds: pwm: Add default-brightness property
  leds: class: Protect brightness_show() with led_cdev->led_access mutex
  leds: ktd2692: Set missing timing properties
  leds: max5970: Fix unreleased fwnode_handle in probe function
  leds: Introduce ordered workqueue for LEDs events instead of system_wq
  MAINTAINERS: Replace Siemens IPC related bouncing maintainers
  leds: bcm6328: Replace divide condition with comparison for shift value
  leds: lp55xx: Remove redundant test for invalid channel number
  dt-bindings: leds: pca955x: Convert text bindings to YAML
  leds: rgb: leds-mt6370-rgb: Fix uninitialized variable 'ret' in mt6370_mc_pattern_clear
  leds: lp5562: Add multicolor brightness control
  dt-bindings: leds: Add 'active-high' property
  leds: Switch back to struct platform_driver::remove()
  leds: bcm63138: Add some register defines
  leds: bcm63138: Handle shift register config
  leds: bcm63138: Use scopes and guards
  dt-bindings: leds: bcm63138: Add shift register bits
  leds: leds-gpio-register: Reorganize kerneldoc parameter names
  ...
This commit is contained in:
Linus Torvalds 2024-11-22 16:25:20 -08:00
commit 93251bdf7a
63 changed files with 397 additions and 330 deletions

View File

@ -118,6 +118,8 @@ properties:
# No trigger assigned to the LED. This is the default mode
# if trigger is absent
- none
# LED indicates remote control feedback
- rc-feedback
# LED indicates camera torch state
- torch
# LED indicates USB gadget activity
@ -202,6 +204,12 @@ properties:
#trigger-source-cells property in the source node.
$ref: /schemas/types.yaml#/definitions/phandle-array
active-high:
type: boolean
description:
Makes LED active high. To turn the LED ON, line needs to be
set to high voltage instead of low.
active-low:
type: boolean
description:
@ -225,6 +233,14 @@ properties:
Maximum timeout in microseconds after which the flash LED is turned off.
Required for flash LED nodes with configurable timeout.
allOf:
- if:
required:
- active-low
then:
properties:
active-high: false
additionalProperties: true
examples:

View File

@ -41,6 +41,16 @@ properties:
"#size-cells":
const: 0
brcm,serial-shift-bits:
minimum: 1
maximum: 32
description:
This describes the number of 8-bit serial shifters connected to the LED
controller block. The hardware is typically using 8-bit shift registers
with 8 LEDs per shift register, so 4 shifters results in 32 LEDs or 2
shifters give 16 LEDs etc, but the hardware supports any odd number of
registers. If left unspecified, the hardware boot-time default is used.
patternProperties:
"^led@[a-f0-9]+$":
type: object
@ -71,6 +81,7 @@ examples:
leds@ff800800 {
compatible = "brcm,bcm4908-leds", "brcm,bcm63138-leds";
reg = <0xff800800 0xdc>;
brcm,serial-shift-bits = <16>;
#address-cells = <1>;
#size-cells = <0>;

View File

@ -1,89 +0,0 @@
* NXP - pca955x LED driver
The PCA955x family of chips are I2C LED blinkers whose pins not used
to control LEDs can be used as general purpose I/Os. The GPIO pins can
be input or output, and output pins can also be pulse-width controlled.
Required properties:
- compatible : should be one of :
"nxp,pca9550"
"nxp,pca9551"
"nxp,pca9552"
"ibm,pca9552"
"nxp,pca9553"
- #address-cells: must be 1
- #size-cells: must be 0
- reg: I2C slave address. depends on the model.
Optional properties:
- gpio-controller: allows pins to be used as GPIOs.
- #gpio-cells: must be 2.
- gpio-line-names: define the names of the GPIO lines
LED sub-node properties:
- reg : number of LED line.
from 0 to 1 for the pca9550
from 0 to 7 for the pca9551
from 0 to 15 for the pca9552
from 0 to 3 for the pca9553
- type: (optional) either
PCA955X_TYPE_NONE
PCA955X_TYPE_LED
PCA955X_TYPE_GPIO
see dt-bindings/leds/leds-pca955x.h (default to LED)
- label : (optional)
see Documentation/devicetree/bindings/leds/common.txt
- linux,default-trigger : (optional)
see Documentation/devicetree/bindings/leds/common.txt
Examples:
pca9552: pca9552@60 {
compatible = "nxp,pca9552";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x60>;
gpio-controller;
#gpio-cells = <2>;
gpio-line-names = "GPIO12", "GPIO13", "GPIO14", "GPIO15";
gpio@12 {
reg = <12>;
type = <PCA955X_TYPE_GPIO>;
};
gpio@13 {
reg = <13>;
type = <PCA955X_TYPE_GPIO>;
};
gpio@14 {
reg = <14>;
type = <PCA955X_TYPE_GPIO>;
};
gpio@15 {
reg = <15>;
type = <PCA955X_TYPE_GPIO>;
};
led@0 {
label = "red:power";
linux,default-trigger = "default-on";
reg = <0>;
type = <PCA955X_TYPE_LED>;
};
led@1 {
label = "green:power";
reg = <1>;
type = <PCA955X_TYPE_LED>;
};
led@2 {
label = "pca9552:yellow";
reg = <2>;
type = <PCA955X_TYPE_LED>;
};
led@3 {
label = "pca9552:white";
reg = <3>;
type = <PCA955X_TYPE_LED>;
};
};

View File

@ -34,6 +34,12 @@ patternProperties:
Maximum brightness possible for the LED
$ref: /schemas/types.yaml#/definitions/uint32
default-brightness:
description:
Brightness to be set if LED's default state is on. Used only during
initialization. If the option is not set then max brightness is used.
$ref: /schemas/types.yaml#/definitions/uint32
required:
- pwms
- max-brightness

View File

@ -0,0 +1,158 @@
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/leds/nxp,pca955x.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP PCA955X LED controllers
maintainers:
- Nate Case <ncase@xes-inc.com>
description: |
The PCA955x family of chips are I2C LED blinkers whose pins not used
to control LEDs can be used as general purpose I/Os. The GPIO pins can
be input or output, and output pins can also be pulse-width controlled.
For more product information please see the link below:
- https://www.nxp.com/docs/en/data-sheet/PCA9552.pdf
properties:
compatible:
enum:
- nxp,pca9550
- nxp,pca9551
- nxp,pca9552
- ibm,pca9552
- nxp,pca9553
reg:
maxItems: 1
"#address-cells":
const: 1
"#size-cells":
const: 0
gpio-controller: true
gpio-line-names:
minItems: 1
maxItems: 16
"#gpio-cells":
const: 2
patternProperties:
"^led@[0-9a-f]$":
type: object
$ref: common.yaml#
unevaluatedProperties: false
properties:
reg:
maxItems: 1
type:
description: |
Output configuration, see include/dt-bindings/leds/leds-pca955x.h
$ref: /schemas/types.yaml#/definitions/uint32
default: 0
minimum: 0
maximum: 2
required:
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- nxp,pca9550
then:
patternProperties:
"^led@[0-9a-f]$":
properties:
reg:
maximum: 1
- if:
properties:
compatible:
contains:
enum:
- nxp,pca9551
then:
patternProperties:
"^led@[0-9a-f]$":
properties:
reg:
maximum: 7
- if:
properties:
compatible:
contains:
enum:
- nxp,pca9552
- ibm,pca9552
then:
patternProperties:
"^led@[0-9a-f]$":
properties:
reg:
maximum: 15
- if:
properties:
compatible:
contains:
enum:
- nxp,pca9553
then:
patternProperties:
"^led@[0-9a-f]$":
properties:
reg:
maximum: 3
additionalProperties: false
examples:
- |
#include <dt-bindings/leds/leds-pca955x.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
led-controller@60 {
compatible = "nxp,pca9552";
reg = <0x60>;
#address-cells = <1>;
#size-cells = <0>;
led@0 {
reg = <0>;
label = "red:power";
linux,default-trigger = "default-on";
type = <PCA955X_TYPE_LED>;
};
led@1 {
reg = <1>;
label = "green:power";
type = <PCA955X_TYPE_LED>;
};
led@2 {
reg = <2>;
label = "pca9552:yellow";
type = <PCA955X_TYPE_LED>;
};
led@3 {
reg = <3>;
label = "pca9552:white";
type = <PCA955X_TYPE_LED>;
};
};
};
...

View File

@ -21231,16 +21231,16 @@ F: drivers/media/usb/siano/
F: drivers/media/usb/siano/
SIEMENS IPC LED DRIVERS
M: Gerd Haeussler <gerd.haeussler.ext@siemens.com>
M: Xing Tong Wu <xingtong.wu@siemens.com>
M: Bao Cheng Su <baocheng.su@siemens.com>
M: Benedikt Niedermayr <benedikt.niedermayr@siemens.com>
M: Tobias Schaffner <tobias.schaffner@siemens.com>
L: linux-leds@vger.kernel.org
S: Maintained
F: drivers/leds/simple/
SIEMENS IPC PLATFORM DRIVERS
M: Gerd Haeussler <gerd.haeussler.ext@siemens.com>
M: Xing Tong Wu <xingtong.wu@siemens.com>
M: Bao Cheng Su <baocheng.su@siemens.com>
M: Benedikt Niedermayr <benedikt.niedermayr@siemens.com>
M: Tobias Schaffner <tobias.schaffner@siemens.com>
L: platform-driver-x86@vger.kernel.org
S: Maintained
@ -21249,8 +21249,8 @@ F: include/linux/platform_data/x86/simatic-ipc-base.h
F: include/linux/platform_data/x86/simatic-ipc.h
SIEMENS IPC WATCHDOG DRIVERS
M: Gerd Haeussler <gerd.haeussler.ext@siemens.com>
M: Xing Tong Wu <xingtong.wu@siemens.com>
M: Bao Cheng Su <baocheng.su@siemens.com>
M: Benedikt Niedermayr <benedikt.niedermayr@siemens.com>
M: Tobias Schaffner <tobias.schaffner@siemens.com>
L: linux-watchdog@vger.kernel.org
S: Maintained

View File

@ -2,6 +2,8 @@
/*
* Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
*/
#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/leds.h>
@ -19,8 +21,10 @@
#define BCM63138_LEDS_PER_REG (32 / BCM63138_LED_BITS) /* 8 */
#define BCM63138_GLB_CTRL 0x00
#define BCM63138_GLB_CTRL_SERIAL_LED_DATA_PPOL 0x00000002
#define BCM63138_GLB_CTRL_SERIAL_LED_EN_POL 0x00000008
#define BCM63138_GLB_CTRL_SERIAL_LED_DATA_PPOL BIT(1)
#define BCM63138_GLB_CTRL_SERIAL_LED_CLK_POL BIT(2)
#define BCM63138_GLB_CTRL_SERIAL_LED_EN_POL BIT(3)
#define BCM63138_GLB_CTRL_SERIAL_LED_MSB_FIRST BIT(4)
#define BCM63138_MASK 0x04
#define BCM63138_HW_LED_EN 0x08
#define BCM63138_SERIAL_LED_SHIFT_SEL 0x0c
@ -33,6 +37,7 @@
#define BCM63138_BRIGHT_CTRL3 0x28
#define BCM63138_BRIGHT_CTRL4 0x2c
#define BCM63138_POWER_LED_CFG 0x30
#define BCM63138_POWER_LUT_BASE0 0x34 /* -> b0 */
#define BCM63138_HW_POLARITY 0xb4
#define BCM63138_SW_DATA 0xb8
#define BCM63138_SW_POLARITY 0xbc
@ -125,17 +130,14 @@ static void bcm63138_leds_brightness_set(struct led_classdev *led_cdev,
{
struct bcm63138_led *led = container_of(led_cdev, struct bcm63138_led, cdev);
struct bcm63138_leds *leds = led->leds;
unsigned long flags;
spin_lock_irqsave(&leds->lock, flags);
guard(spinlock_irqsave)(&leds->lock);
bcm63138_leds_enable_led(leds, led, value);
if (!value)
bcm63138_leds_set_flash_rate(leds, led, 0);
else
bcm63138_leds_set_bright(leds, led, value);
spin_unlock_irqrestore(&leds->lock, flags);
}
static int bcm63138_leds_blink_set(struct led_classdev *led_cdev,
@ -144,7 +146,6 @@ static int bcm63138_leds_blink_set(struct led_classdev *led_cdev,
{
struct bcm63138_led *led = container_of(led_cdev, struct bcm63138_led, cdev);
struct bcm63138_leds *leds = led->leds;
unsigned long flags;
u8 value;
if (!*delay_on && !*delay_off) {
@ -179,13 +180,11 @@ static int bcm63138_leds_blink_set(struct led_classdev *led_cdev,
return -EINVAL;
}
spin_lock_irqsave(&leds->lock, flags);
guard(spinlock_irqsave)(&leds->lock);
bcm63138_leds_enable_led(leds, led, BCM63138_MAX_BRIGHTNESS);
bcm63138_leds_set_flash_rate(leds, led, value);
spin_unlock_irqrestore(&leds->lock, flags);
return 0;
}
@ -259,7 +258,7 @@ static int bcm63138_leds_probe(struct platform_device *pdev)
struct device_node *np = dev_of_node(&pdev->dev);
struct device *dev = &pdev->dev;
struct bcm63138_leds *leds;
struct device_node *child;
u32 shift_bits;
leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
if (!leds)
@ -273,6 +272,12 @@ static int bcm63138_leds_probe(struct platform_device *pdev)
spin_lock_init(&leds->lock);
/* If this property is not present, we use boot defaults */
if (!of_property_read_u32(np, "brcm,serial-shift-bits", &shift_bits)) {
bcm63138_leds_write(leds, BCM63138_SERIAL_LED_SHIFT_SEL,
GENMASK(shift_bits - 1, 0));
}
bcm63138_leds_write(leds, BCM63138_GLB_CTRL,
BCM63138_GLB_CTRL_SERIAL_LED_DATA_PPOL |
BCM63138_GLB_CTRL_SERIAL_LED_EN_POL);
@ -280,7 +285,7 @@ static int bcm63138_leds_probe(struct platform_device *pdev)
bcm63138_leds_write(leds, BCM63138_SERIAL_LED_POLARITY, 0);
bcm63138_leds_write(leds, BCM63138_PARALLEL_LED_POLARITY, 0);
for_each_available_child_of_node(np, child) {
for_each_available_child_of_node_scoped(np, child) {
bcm63138_leds_create_led(leds, child);
}

View File

@ -861,7 +861,7 @@ MODULE_DEVICE_TABLE(of, of_sso_led_match);
static struct platform_driver intel_sso_led_driver = {
.probe = intel_sso_led_probe,
.remove_new = intel_sso_led_remove,
.remove = intel_sso_led_remove,
.driver = {
.name = "lgm-ssoled",
.of_match_table = of_sso_led_match,

View File

@ -536,7 +536,7 @@ MODULE_DEVICE_TABLE(of, aat1290_led_dt_match);
static struct platform_driver aat1290_led_driver = {
.probe = aat1290_led_probe,
.remove_new = aat1290_led_remove,
.remove = aat1290_led_remove,
.driver = {
.name = "aat1290",
.of_match_table = aat1290_led_dt_match,

View File

@ -292,6 +292,7 @@ static int ktd2692_probe(struct platform_device *pdev)
fled_cdev = &led->fled_cdev;
led_cdev = &fled_cdev->led_cdev;
led->props.timing = ktd2692_timing;
ret = ktd2692_parse_dt(led, &pdev->dev, &led_cfg);
if (ret)
@ -343,7 +344,7 @@ static struct platform_driver ktd2692_driver = {
.of_match_table = ktd2692_match,
},
.probe = ktd2692_probe,
.remove_new = ktd2692_remove,
.remove = ktd2692_remove,
};
module_platform_driver(ktd2692_driver);

View File

@ -1042,7 +1042,7 @@ MODULE_DEVICE_TABLE(of, max77693_led_dt_match);
static struct platform_driver max77693_led_driver = {
.probe = max77693_led_probe,
.remove_new = max77693_led_remove,
.remove = max77693_led_remove,
.driver = {
.name = "max77693-led",
.of_match_table = max77693_led_dt_match,

View File

@ -784,7 +784,6 @@ static void mt6360_v4l2_flash_release(struct mt6360_priv *priv)
static int mt6360_led_probe(struct platform_device *pdev)
{
struct mt6360_priv *priv;
struct fwnode_handle *child;
size_t count;
int i = 0, ret;
@ -811,7 +810,7 @@ static int mt6360_led_probe(struct platform_device *pdev)
return -ENODEV;
}
device_for_each_child_node(&pdev->dev, child) {
device_for_each_child_node_scoped(&pdev->dev, child) {
struct mt6360_led *led = priv->leds + i;
struct led_init_data init_data = { .fwnode = child, };
u32 reg, led_color;
@ -887,7 +886,7 @@ static struct platform_driver mt6360_led_driver = {
.of_match_table = mt6360_led_of_id,
},
.probe = mt6360_led_probe,
.remove_new = mt6360_led_remove,
.remove = mt6360_led_remove,
};
module_platform_driver(mt6360_led_driver);

View File

@ -509,7 +509,6 @@ static int mt6370_led_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mt6370_priv *priv;
struct fwnode_handle *child;
size_t count;
int i = 0, ret;
@ -529,22 +528,18 @@ static int mt6370_led_probe(struct platform_device *pdev)
if (!priv->regmap)
return dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n");
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct mt6370_led *led = priv->leds + i;
led->priv = priv;
ret = mt6370_init_flash_properties(dev, led, child);
if (ret) {
fwnode_handle_put(child);
if (ret)
return ret;
}
ret = mt6370_led_register(dev, led, child);
if (ret) {
fwnode_handle_put(child);
if (ret)
return ret;
}
i++;
}

View File

@ -812,7 +812,6 @@ static int qcom_flash_led_probe(struct platform_device *pdev)
{
struct qcom_flash_data *flash_data;
struct qcom_flash_led *led;
struct fwnode_handle *child;
struct device *dev = &pdev->dev;
struct regmap *regmap;
struct reg_field *regs;
@ -896,7 +895,7 @@ static int qcom_flash_led_probe(struct platform_device *pdev)
if (!flash_data->v4l2_flash)
return -ENOMEM;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
if (!led) {
rc = -ENOMEM;
@ -914,7 +913,6 @@ static int qcom_flash_led_probe(struct platform_device *pdev)
return 0;
release:
fwnode_handle_put(child);
while (flash_data->v4l2_flash[flash_data->leds_count] && flash_data->leds_count)
v4l2_flash_release(flash_data->v4l2_flash[flash_data->leds_count--]);
return rc;
@ -942,7 +940,7 @@ static struct platform_driver qcom_flash_led_driver = {
.of_match_table = qcom_flash_led_match_table,
},
.probe = qcom_flash_led_probe,
.remove_new = qcom_flash_led_remove,
.remove = qcom_flash_led_remove,
};
module_platform_driver(qcom_flash_led_driver);

View File

@ -388,7 +388,7 @@ static struct platform_driver rt8515_driver = {
.of_match_table = rt8515_match,
},
.probe = rt8515_probe,
.remove_new = rt8515_remove,
.remove = rt8515_remove,
};
module_platform_driver(rt8515_driver);

View File

@ -300,7 +300,7 @@ MODULE_DEVICE_TABLE(of, sgm3140_dt_match);
static struct platform_driver sgm3140_driver = {
.probe = sgm3140_probe,
.remove_new = sgm3140_remove,
.remove = sgm3140_remove,
.driver = {
.name = "sgm3140",
.of_match_table = sgm3140_dt_match,

View File

@ -12,7 +12,6 @@
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/slab.h>
#include "leds.h"
#define has_flash_op(fled_cdev, op) \
(fled_cdev && fled_cdev->ops->op)

View File

@ -11,8 +11,6 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include "leds.h"
int led_mc_calc_color_components(struct led_classdev_mc *mcled_cdev,
enum led_brightness brightness)
{

View File

@ -25,15 +25,20 @@
static DEFINE_MUTEX(leds_lookup_lock);
static LIST_HEAD(leds_lookup_list);
static struct workqueue_struct *leds_wq;
static ssize_t brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
unsigned int brightness;
/* no lock needed for this */
mutex_lock(&led_cdev->led_access);
led_update_brightness(led_cdev);
brightness = led_cdev->brightness;
mutex_unlock(&led_cdev->led_access);
return sprintf(buf, "%u\n", led_cdev->brightness);
return sprintf(buf, "%u\n", brightness);
}
static ssize_t brightness_store(struct device *dev,
@ -57,7 +62,6 @@ static ssize_t brightness_store(struct device *dev,
if (state == LED_OFF)
led_trigger_remove(led_cdev);
led_set_brightness(led_cdev, state);
flush_work(&led_cdev->set_brightness_work);
ret = size;
unlock:
@ -70,8 +74,13 @@ static ssize_t max_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
unsigned int max_brightness;
return sprintf(buf, "%u\n", led_cdev->max_brightness);
mutex_lock(&led_cdev->led_access);
max_brightness = led_cdev->max_brightness;
mutex_unlock(&led_cdev->led_access);
return sprintf(buf, "%u\n", max_brightness);
}
static DEVICE_ATTR_RO(max_brightness);
@ -549,6 +558,8 @@ int led_classdev_register_ext(struct device *parent,
led_update_brightness(led_cdev);
led_cdev->wq = leds_wq;
led_init_core(led_cdev);
#ifdef CONFIG_LEDS_TRIGGERS
@ -667,12 +678,19 @@ EXPORT_SYMBOL_GPL(devm_led_classdev_unregister);
static int __init leds_init(void)
{
leds_wq = alloc_ordered_workqueue("leds", 0);
if (!leds_wq) {
pr_err("Failed to create LEDs ordered workqueue\n");
return -ENOMEM;
}
return class_register(&leds_class);
}
static void __exit leds_exit(void)
{
class_unregister(&leds_class);
destroy_workqueue(leds_wq);
}
subsys_initcall(leds_init);

View File

@ -273,7 +273,7 @@ void led_blink_set_nosleep(struct led_classdev *led_cdev, unsigned long delay_on
led_cdev->delayed_delay_on = delay_on;
led_cdev->delayed_delay_off = delay_off;
set_bit(LED_SET_BLINK, &led_cdev->work_flags);
schedule_work(&led_cdev->set_brightness_work);
queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
return;
}
@ -304,7 +304,7 @@ void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness)
*/
if (!brightness) {
set_bit(LED_BLINK_DISABLE, &led_cdev->work_flags);
schedule_work(&led_cdev->set_brightness_work);
queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
} else {
set_bit(LED_BLINK_BRIGHTNESS_CHANGE,
&led_cdev->work_flags);
@ -340,7 +340,7 @@ void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value)
set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
}
schedule_work(&led_cdev->set_brightness_work);
queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
}
EXPORT_SYMBOL_GPL(led_set_brightness_nopm);

View File

@ -226,7 +226,7 @@ static struct platform_driver pm860x_led_driver = {
.name = "88pm860x-led",
},
.probe = pm860x_led_probe,
.remove_new = pm860x_led_remove,
.remove = pm860x_led_remove,
};
module_platform_driver(pm860x_led_driver);

View File

@ -184,7 +184,7 @@ static struct platform_driver adp5520_led_driver = {
.name = "adp5520-led",
},
.probe = adp5520_led_probe,
.remove_new = adp5520_led_remove,
.remove = adp5520_led_remove,
};
module_platform_driver(adp5520_led_driver);

View File

@ -409,7 +409,6 @@ static int aw200xx_probe_get_display_rows(struct device *dev,
static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip)
{
struct fwnode_handle *child;
u32 current_min, current_max, min_uA;
int ret;
int i;
@ -424,7 +423,7 @@ static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip)
min_uA = UINT_MAX;
i = 0;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct led_init_data init_data = {};
struct aw200xx_led *led;
u32 source, imax;
@ -468,10 +467,8 @@ static int aw200xx_probe_fw(struct device *dev, struct aw200xx *chip)
ret = devm_led_classdev_register_ext(dev, &led->cdev,
&init_data);
if (ret) {
fwnode_handle_put(child);
if (ret)
break;
}
i++;
}

View File

@ -113,7 +113,7 @@ static void bcm6328_led_mode(struct bcm6328_led *led, unsigned long value)
unsigned long val, shift;
shift = bcm6328_pin2shift(led->pin);
if (shift / 16)
if (shift >= 16)
mode = led->mem + BCM6328_REG_MODE_HI;
else
mode = led->mem + BCM6328_REG_MODE_LO;
@ -357,7 +357,7 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
break;
case LEDS_DEFSTATE_KEEP:
shift = bcm6328_pin2shift(led->pin);
if (shift / 16)
if (shift >= 16)
mode = mem + BCM6328_REG_MODE_HI;
else
mode = mem + BCM6328_REG_MODE_LO;

View File

@ -461,7 +461,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(cht_wc_leds_pm, cht_wc_leds_suspend, cht_wc_leds
static struct platform_driver cht_wc_leds_driver = {
.probe = cht_wc_leds_probe,
.remove_new = cht_wc_leds_remove,
.remove = cht_wc_leds_remove,
.shutdown = cht_wc_leds_disable,
.driver = {
.name = "cht_wcove_leds",

View File

@ -165,7 +165,7 @@ static void clevo_mail_led_remove(struct platform_device *pdev)
}
static struct platform_driver clevo_mail_led_driver = {
.remove_new = clevo_mail_led_remove,
.remove = clevo_mail_led_remove,
.driver = {
.name = KBUILD_MODNAME,
},

View File

@ -181,11 +181,10 @@ static int cr0014114_probe_dt(struct cr0014114 *priv)
{
size_t i = 0;
struct cr0014114_led *led;
struct fwnode_handle *child;
struct led_init_data init_data = {};
int ret;
device_for_each_child_node(priv->dev, child) {
device_for_each_child_node_scoped(priv->dev, child) {
led = &priv->leds[i];
led->priv = priv;
@ -201,7 +200,6 @@ static int cr0014114_probe_dt(struct cr0014114 *priv)
if (ret) {
dev_err(priv->dev,
"failed to register LED device, err %d", ret);
fwnode_handle_put(child);
return ret;
}

View File

@ -133,7 +133,7 @@ static struct platform_driver da903x_led_driver = {
.name = "da903x-led",
},
.probe = da903x_led_probe,
.remove_new = da903x_led_remove,
.remove = da903x_led_remove,
};
module_platform_driver(da903x_led_driver);

View File

@ -179,7 +179,7 @@ static struct platform_driver da9052_led_driver = {
.name = "da9052-leds",
},
.probe = da9052_led_probe,
.remove_new = da9052_led_remove,
.remove = da9052_led_remove,
};
module_platform_driver(da9052_led_driver);

View File

@ -237,22 +237,20 @@ static int el15203000_pattern_clear(struct led_classdev *ldev)
static int el15203000_probe_dt(struct el15203000 *priv)
{
struct el15203000_led *led = priv->leds;
struct fwnode_handle *child;
int ret;
device_for_each_child_node(priv->dev, child) {
device_for_each_child_node_scoped(priv->dev, child) {
struct led_init_data init_data = {};
ret = fwnode_property_read_u32(child, "reg", &led->reg);
if (ret) {
dev_err(priv->dev, "LED without ID number");
goto err_child_out;
return ret;
}
if (led->reg > U8_MAX) {
dev_err(priv->dev, "LED value %d is invalid", led->reg);
ret = -EINVAL;
goto err_child_out;
return -EINVAL;
}
led->priv = priv;
@ -274,17 +272,13 @@ static int el15203000_probe_dt(struct el15203000 *priv)
dev_err(priv->dev,
"failed to register LED device %s, err %d",
led->ldev.name, ret);
goto err_child_out;
return ret;
}
led++;
}
return 0;
err_child_out:
fwnode_handle_put(child);
return ret;
}
static int el15203000_probe(struct spi_device *spi)

View File

@ -10,8 +10,8 @@
/**
* gpio_led_register_device - register a gpio-led device
* @pdata: the platform data used for the new device
* @id: platform ID
* @pdata: the platform data used for the new device
*
* Makes a copy of pdata and pdata->leds and registers a new leds-gpio device
* with the result. This allows to have pdata and pdata-leds in .init.rodata

View File

@ -21,8 +21,6 @@
#include <linux/slab.h>
#include <linux/types.h>
#include "leds.h"
struct gpio_led_data {
struct led_classdev cdev;
struct gpio_desc *gpiod;
@ -148,7 +146,6 @@ struct gpio_leds_priv {
static struct gpio_leds_priv *gpio_leds_create(struct device *dev)
{
struct fwnode_handle *child;
struct gpio_leds_priv *priv;
int count, used, ret;
@ -162,7 +159,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev)
priv->num_leds = count;
used = 0;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct gpio_led_data *led_dat = &priv->leds[used];
struct gpio_led led = {};
@ -176,7 +173,6 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev)
if (IS_ERR(led.gpiod)) {
dev_err_probe(dev, PTR_ERR(led.gpiod), "Failed to get GPIO '%pfw'\n",
child);
fwnode_handle_put(child);
return ERR_CAST(led.gpiod);
}
@ -192,10 +188,9 @@ static struct gpio_leds_priv *gpio_leds_create(struct device *dev)
led.panic_indicator = 1;
ret = create_gpio_led(&led, led_dat, dev, child, NULL);
if (ret < 0) {
fwnode_handle_put(child);
if (ret < 0)
return ERR_PTR(ret);
}
/* Set gpiod label to match the corresponding LED name. */
gpiod_set_consumer_name(led_dat->gpiod,
led_dat->cdev.dev->kobj.name);

View File

@ -551,7 +551,6 @@ static void gpio_set_low_action(void *data)
static int lm3532_parse_node(struct lm3532_data *priv)
{
struct fwnode_handle *child = NULL;
struct lm3532_led *led;
int control_bank;
u32 ramp_time;
@ -587,7 +586,7 @@ static int lm3532_parse_node(struct lm3532_data *priv)
else
priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
device_for_each_child_node(priv->dev, child) {
device_for_each_child_node_scoped(priv->dev, child) {
struct led_init_data idata = {
.fwnode = child,
.default_label = ":",
@ -599,7 +598,7 @@ static int lm3532_parse_node(struct lm3532_data *priv)
ret = fwnode_property_read_u32(child, "reg", &control_bank);
if (ret) {
dev_err(&priv->client->dev, "reg property missing\n");
goto child_out;
return ret;
}
if (control_bank > LM3532_CONTROL_C) {
@ -613,7 +612,7 @@ static int lm3532_parse_node(struct lm3532_data *priv)
&led->mode);
if (ret) {
dev_err(&priv->client->dev, "ti,led-mode property missing\n");
goto child_out;
return ret;
}
if (fwnode_property_present(child, "led-max-microamp") &&
@ -647,7 +646,7 @@ static int lm3532_parse_node(struct lm3532_data *priv)
led->num_leds);
if (ret) {
dev_err(&priv->client->dev, "led-sources property missing\n");
goto child_out;
return ret;
}
led->priv = priv;
@ -657,23 +656,20 @@ static int lm3532_parse_node(struct lm3532_data *priv)
if (ret) {
dev_err(&priv->client->dev, "led register err: %d\n",
ret);
goto child_out;
return ret;
}
ret = lm3532_init_registers(led);
if (ret) {
dev_err(&priv->client->dev, "register init err: %d\n",
ret);
goto child_out;
return ret;
}
i++;
}
return 0;
child_out:
fwnode_handle_put(child);
return ret;
return 0;
}
static int lm3532_probe(struct i2c_client *client)

View File

@ -744,7 +744,7 @@ static struct platform_driver lm3533_led_driver = {
.name = "lm3533-leds",
},
.probe = lm3533_led_probe,
.remove_new = lm3533_led_remove,
.remove = lm3533_led_remove,
.shutdown = lm3533_led_shutdown,
};
module_platform_driver(lm3533_led_driver);

View File

@ -202,7 +202,6 @@ static int lm3697_init(struct lm3697 *priv)
static int lm3697_probe_dt(struct lm3697 *priv)
{
struct fwnode_handle *child = NULL;
struct device *dev = priv->dev;
struct lm3697_led *led;
int ret = -EINVAL;
@ -220,19 +219,18 @@ static int lm3697_probe_dt(struct lm3697 *priv)
if (IS_ERR(priv->regulator))
priv->regulator = NULL;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct led_init_data init_data = {};
ret = fwnode_property_read_u32(child, "reg", &control_bank);
if (ret) {
dev_err(dev, "reg property missing\n");
goto child_out;
return ret;
}
if (control_bank > LM3697_CONTROL_B) {
dev_err(dev, "reg property is invalid\n");
ret = -EINVAL;
goto child_out;
return -EINVAL;
}
led = &priv->leds[i];
@ -262,7 +260,7 @@ static int lm3697_probe_dt(struct lm3697 *priv)
led->num_leds);
if (ret) {
dev_err(dev, "led-sources property missing\n");
goto child_out;
return ret;
}
for (j = 0; j < led->num_leds; j++)
@ -286,17 +284,13 @@ static int lm3697_probe_dt(struct lm3697 *priv)
&init_data);
if (ret) {
dev_err(dev, "led register err: %d\n", ret);
goto child_out;
return ret;
}
i++;
}
return ret;
child_out:
fwnode_handle_put(child);
return ret;
return 0;
}
static int lm3697_probe(struct i2c_client *client)

View File

@ -16,8 +16,6 @@
#include <linux/led-class-multicolor.h>
#include "leds.h"
#define LP50XX_DEV_CFG0 0x00
#define LP50XX_DEV_CFG1 0x01
#define LP50XX_LED_CFG0 0x02
@ -434,7 +432,6 @@ static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv,
static int lp50xx_probe_dt(struct lp50xx *priv)
{
struct fwnode_handle *child = NULL;
struct fwnode_handle *led_node = NULL;
struct led_init_data init_data = {};
struct led_classdev *led_cdev;
@ -454,17 +451,17 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
if (IS_ERR(priv->regulator))
priv->regulator = NULL;
device_for_each_child_node(priv->dev, child) {
device_for_each_child_node_scoped(priv->dev, child) {
led = &priv->leds[i];
ret = fwnode_property_count_u32(child, "reg");
if (ret < 0) {
dev_err(priv->dev, "reg property is invalid\n");
goto child_out;
return ret;
}
ret = lp50xx_probe_leds(child, priv, led, ret);
if (ret)
goto child_out;
return ret;
init_data.fwnode = child;
num_colors = 0;
@ -475,10 +472,8 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
*/
mc_led_info = devm_kcalloc(priv->dev, LP50XX_LEDS_PER_MODULE,
sizeof(*mc_led_info), GFP_KERNEL);
if (!mc_led_info) {
ret = -ENOMEM;
goto child_out;
}
if (!mc_led_info)
return -ENOMEM;
fwnode_for_each_child_node(child, led_node) {
ret = fwnode_property_read_u32(led_node, "color",
@ -486,7 +481,7 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
if (ret) {
fwnode_handle_put(led_node);
dev_err(priv->dev, "Cannot read color\n");
goto child_out;
return ret;
}
mc_led_info[num_colors].color_index = color_id;
@ -504,16 +499,12 @@ static int lp50xx_probe_dt(struct lp50xx *priv)
&init_data);
if (ret) {
dev_err(priv->dev, "led register err: %d\n", ret);
goto child_out;
return ret;
}
i++;
}
return 0;
child_out:
fwnode_handle_put(child);
return ret;
}
static int lp50xx_probe(struct i2c_client *client)

View File

@ -161,6 +161,30 @@ static int lp5562_post_init_device(struct lp55xx_chip *chip)
return 0;
}
static int lp5562_multicolor_brightness(struct lp55xx_led *led)
{
struct lp55xx_chip *chip = led->chip;
static const u8 addr[] = {
LP5562_REG_R_PWM,
LP5562_REG_G_PWM,
LP5562_REG_B_PWM,
LP5562_REG_W_PWM,
};
int ret;
int i;
guard(mutex)(&chip->lock);
for (i = 0; i < led->mc_cdev.num_colors; i++) {
ret = lp55xx_write(chip,
addr[led->mc_cdev.subled_info[i].channel],
led->mc_cdev.subled_info[i].brightness);
if (ret)
break;
}
return ret;
}
static int lp5562_led_brightness(struct lp55xx_led *led)
{
struct lp55xx_chip *chip = led->chip;
@ -364,6 +388,7 @@ static struct lp55xx_device_config lp5562_cfg = {
.post_init_device = lp5562_post_init_device,
.set_led_current = lp5562_set_led_current,
.brightness_fn = lp5562_led_brightness,
.multicolor_brightness_fn = lp5562_multicolor_brightness,
.run_engine = lp5562_run_engine,
.firmware_cb = lp55xx_firmware_loaded_cb,
.dev_attr_group = &lp5562_group,

View File

@ -1132,9 +1132,6 @@ static int lp55xx_parse_common_child(struct device_node *np,
if (ret)
return ret;
if (*chan_nr < 0 || *chan_nr > cfg->max_channel)
return -EINVAL;
return 0;
}

View File

@ -45,7 +45,7 @@ static int max5970_led_set_brightness(struct led_classdev *cdev,
static int max5970_led_probe(struct platform_device *pdev)
{
struct fwnode_handle *led_node, *child;
struct fwnode_handle *child;
struct device *dev = &pdev->dev;
struct regmap *regmap;
struct max5970_led *ddata;
@ -55,7 +55,8 @@ static int max5970_led_probe(struct platform_device *pdev)
if (!regmap)
return -ENODEV;
led_node = device_get_named_child_node(dev->parent, "leds");
struct fwnode_handle *led_node __free(fwnode_handle) =
device_get_named_child_node(dev->parent, "leds");
if (!led_node)
return -ENODEV;

View File

@ -62,7 +62,6 @@ static int max77650_led_brightness_set(struct led_classdev *cdev,
static int max77650_led_probe(struct platform_device *pdev)
{
struct fwnode_handle *child;
struct max77650_led *leds, *led;
struct device *dev;
struct regmap *map;
@ -84,14 +83,12 @@ static int max77650_led_probe(struct platform_device *pdev)
if (!num_leds || num_leds > MAX77650_LED_NUM_LEDS)
return -ENODEV;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct led_init_data init_data = {};
rv = fwnode_property_read_u32(child, "reg", &reg);
if (rv || reg >= MAX77650_LED_NUM_LEDS) {
rv = -EINVAL;
goto err_node_put;
}
if (rv || reg >= MAX77650_LED_NUM_LEDS)
return -EINVAL;
led = &leds[reg];
led->map = map;
@ -108,23 +105,20 @@ static int max77650_led_probe(struct platform_device *pdev)
rv = devm_led_classdev_register_ext(dev, &led->cdev,
&init_data);
if (rv)
goto err_node_put;
return rv;
rv = regmap_write(map, led->regA, MAX77650_LED_A_DEFAULT);
if (rv)
goto err_node_put;
return rv;
rv = regmap_write(map, led->regB, MAX77650_LED_B_DEFAULT);
if (rv)
goto err_node_put;
return rv;
}
return regmap_write(map,
MAX77650_REG_CNFG_LED_TOP,
MAX77650_LED_TOP_DEFAULT);
err_node_put:
fwnode_handle_put(child);
return rv;
}
static const struct of_device_id max77650_led_of_match[] = {

View File

@ -301,7 +301,7 @@ static struct platform_driver mc13xxx_led_driver = {
.driver = {
.name = "mc13xxx-led",
},
.remove_new = mc13xxx_led_remove,
.remove = mc13xxx_led_remove,
.id_table = mc13xxx_led_id_table,
};
module_platform_driver_probe(mc13xxx_led_driver, mc13xxx_led_probe);

View File

@ -713,7 +713,7 @@ MODULE_DEVICE_TABLE(of, mt6323_led_dt_match);
static struct platform_driver mt6323_led_driver = {
.probe = mt6323_led_probe,
.remove_new = mt6323_led_remove,
.remove = mt6323_led_remove,
.driver = {
.name = "mt6323-led",
.of_match_table = mt6323_led_dt_match,

View File

@ -238,7 +238,6 @@ static int ns2_led_register(struct device *dev, struct fwnode_handle *node,
static int ns2_led_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct fwnode_handle *child;
struct ns2_led *leds;
int count;
int ret;
@ -251,12 +250,10 @@ static int ns2_led_probe(struct platform_device *pdev)
if (!leds)
return -ENOMEM;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
ret = ns2_led_register(dev, child, leds++);
if (ret) {
fwnode_handle_put(child);
if (ret)
return ret;
}
}
return 0;

View File

@ -306,7 +306,6 @@ static int pca963x_register_leds(struct i2c_client *client,
struct pca963x_chipdef *chipdef = chip->chipdef;
struct pca963x_led *led = chip->leds;
struct device *dev = &client->dev;
struct fwnode_handle *child;
bool hw_blink;
s32 mode2;
u32 reg;
@ -338,7 +337,7 @@ static int pca963x_register_leds(struct i2c_client *client,
if (ret < 0)
return ret;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct led_init_data init_data = {};
char default_label[32];
@ -346,8 +345,7 @@ static int pca963x_register_leds(struct i2c_client *client,
if (ret || reg >= chipdef->n_leds) {
dev_err(dev, "Invalid 'reg' property for node %pfw\n",
child);
ret = -EINVAL;
goto err;
return -EINVAL;
}
led->led_num = reg;
@ -369,16 +367,13 @@ static int pca963x_register_leds(struct i2c_client *client,
if (ret) {
dev_err(dev, "Failed to register LED for node %pfw\n",
child);
goto err;
return ret;
}
++led;
}
return 0;
err:
fwnode_handle_put(child);
return ret;
}
static int pca963x_suspend(struct device *dev)

View File

@ -323,8 +323,8 @@ static const struct of_device_id powernv_led_match[] = {
MODULE_DEVICE_TABLE(of, powernv_led_match);
static struct platform_driver powernv_led_driver = {
.probe = powernv_led_probe,
.remove_new = powernv_led_remove,
.probe = powernv_led_probe,
.remove = powernv_led_remove,
.driver = {
.name = "powernv-led-driver",
.of_match_table = powernv_led_match,

View File

@ -17,7 +17,6 @@
#include <linux/err.h>
#include <linux/pwm.h>
#include <linux/slab.h>
#include "leds.h"
struct led_pwm {
const char *name;
@ -63,6 +62,20 @@ static int led_pwm_set(struct led_classdev *led_cdev,
return pwm_apply_might_sleep(led_dat->pwm, &led_dat->pwmstate);
}
static int led_pwm_default_brightness_get(struct fwnode_handle *fwnode,
int max_brightness)
{
unsigned int default_brightness;
int ret;
ret = fwnode_property_read_u32(fwnode, "default-brightness",
&default_brightness);
if (ret < 0 || default_brightness > max_brightness)
default_brightness = max_brightness;
return default_brightness;
}
__attribute__((nonnull))
static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
struct led_pwm *led, struct fwnode_handle *fwnode)
@ -104,7 +117,8 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
/* set brightness */
switch (led->default_state) {
case LEDS_DEFSTATE_ON:
led_data->cdev.brightness = led->max_brightness;
led_data->cdev.brightness =
led_pwm_default_brightness_get(fwnode, led->max_brightness);
break;
case LEDS_DEFSTATE_KEEP:
{
@ -140,21 +154,18 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
static int led_pwm_create_fwnode(struct device *dev, struct led_pwm_priv *priv)
{
struct fwnode_handle *fwnode;
struct led_pwm led;
int ret;
device_for_each_child_node(dev, fwnode) {
device_for_each_child_node_scoped(dev, fwnode) {
memset(&led, 0, sizeof(led));
ret = fwnode_property_read_string(fwnode, "label", &led.name);
if (ret && is_of_node(fwnode))
led.name = to_of_node(fwnode)->name;
if (!led.name) {
ret = -EINVAL;
goto err_child_out;
}
if (!led.name)
return -EINVAL;
led.active_low = fwnode_property_read_bool(fwnode,
"active-low");
@ -165,14 +176,10 @@ static int led_pwm_create_fwnode(struct device *dev, struct led_pwm_priv *priv)
ret = led_pwm_add(dev, priv, &led, fwnode);
if (ret)
goto err_child_out;
return ret;
}
return 0;
err_child_out:
fwnode_handle_put(fwnode);
return ret;
}
static int led_pwm_probe(struct platform_device *pdev)

View File

@ -49,7 +49,7 @@ static void rb532_led_remove(struct platform_device *pdev)
static struct platform_driver rb532_led_driver = {
.probe = rb532_led_probe,
.remove_new = rb532_led_remove,
.remove = rb532_led_remove,
.driver = {
.name = "rb532-led",
},

View File

@ -193,7 +193,7 @@ static struct platform_driver regulator_led_driver = {
.of_match_table = regulator_led_of_match,
},
.probe = regulator_led_probe,
.remove_new = regulator_led_remove,
.remove = regulator_led_remove,
};
module_platform_driver(regulator_led_driver);

View File

@ -344,7 +344,7 @@ static struct platform_driver sc27xx_led_driver = {
.of_match_table = sc27xx_led_of_match,
},
.probe = sc27xx_led_probe,
.remove_new = sc27xx_led_remove,
.remove = sc27xx_led_remove,
};
module_platform_driver(sc27xx_led_driver);

View File

@ -451,7 +451,7 @@ static ssize_t blink_show(struct device *dev,
int blinking = 0;
if (nasgpio_led_get_attr(led, GPO_BLINK))
blinking = 1;
return sprintf(buf, "%u\n", blinking);
return sprintf(buf, "%d\n", blinking);
}
static ssize_t blink_store(struct device *dev,

View File

@ -392,7 +392,6 @@ static int sun50i_a100_ledc_probe(struct platform_device *pdev)
struct sun50i_a100_ledc_led *led;
struct device *dev = &pdev->dev;
struct sun50i_a100_ledc *priv;
struct fwnode_handle *child;
struct resource *mem;
u32 max_addr = 0;
u32 num_leds = 0;
@ -402,21 +401,17 @@ static int sun50i_a100_ledc_probe(struct platform_device *pdev)
* The maximum LED address must be known in sun50i_a100_ledc_resume() before
* class device registration, so parse and validate the subnodes up front.
*/
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
u32 addr, color;
ret = fwnode_property_read_u32(child, "reg", &addr);
if (ret || addr >= LEDC_MAX_LEDS) {
fwnode_handle_put(child);
if (ret || addr >= LEDC_MAX_LEDS)
return dev_err_probe(dev, -EINVAL, "'reg' must be between 0 and %d\n",
LEDC_MAX_LEDS - 1);
}
ret = fwnode_property_read_u32(child, "color", &color);
if (ret || color != LED_COLOR_ID_RGB) {
fwnode_handle_put(child);
if (ret || color != LED_COLOR_ID_RGB)
return dev_err_probe(dev, -EINVAL, "'color' must be LED_COLOR_ID_RGB\n");
}
max_addr = max(max_addr, addr);
num_leds++;
@ -502,7 +497,7 @@ static int sun50i_a100_ledc_probe(struct platform_device *pdev)
return ret;
led = priv->leds;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct led_classdev *cdev;
/* The node was already validated above. */
@ -527,7 +522,11 @@ static int sun50i_a100_ledc_probe(struct platform_device *pdev)
ret = led_classdev_multicolor_register_ext(dev, &led->mc_cdev, &init_data);
if (ret) {
dev_err_probe(dev, ret, "Failed to register multicolor LED %u", led->addr);
goto err_put_child;
while (led-- > priv->leds)
led_classdev_multicolor_unregister(&led->mc_cdev);
sun50i_a100_ledc_suspend(&pdev->dev);
return ret;
}
led++;
@ -536,14 +535,6 @@ static int sun50i_a100_ledc_probe(struct platform_device *pdev)
dev_info(dev, "Registered %u LEDs\n", num_leds);
return 0;
err_put_child:
fwnode_handle_put(child);
while (led-- > priv->leds)
led_classdev_multicolor_unregister(&led->mc_cdev);
sun50i_a100_ledc_suspend(&pdev->dev);
return ret;
}
static void sun50i_a100_ledc_remove(struct platform_device *pdev)
@ -567,7 +558,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(sun50i_a100_ledc_pm,
static struct platform_driver sun50i_a100_ledc_driver = {
.probe = sun50i_a100_ledc_probe,
.remove_new = sun50i_a100_ledc_remove,
.remove = sun50i_a100_ledc_remove,
.shutdown = sun50i_a100_ledc_remove,
.driver = {
.name = "sun50i-a100-ledc",

View File

@ -219,7 +219,7 @@ MODULE_ALIAS("platform:sunfire-fhc-leds");
static struct platform_driver sunfire_clockboard_led_driver = {
.probe = sunfire_clockboard_led_probe,
.remove_new = sunfire_led_generic_remove,
.remove = sunfire_led_generic_remove,
.driver = {
.name = "sunfire-clockboard-leds",
},
@ -227,7 +227,7 @@ static struct platform_driver sunfire_clockboard_led_driver = {
static struct platform_driver sunfire_fhc_led_driver = {
.probe = sunfire_fhc_led_probe,
.remove_new = sunfire_led_generic_remove,
.remove = sunfire_led_generic_remove,
.driver = {
.name = "sunfire-fhc-leds",
},

View File

@ -658,7 +658,6 @@ static struct tca6507_platform_data *
tca6507_led_dt_init(struct device *dev)
{
struct tca6507_platform_data *pdata;
struct fwnode_handle *child;
struct led_info *tca_leds;
int count;
@ -671,7 +670,7 @@ tca6507_led_dt_init(struct device *dev)
if (!tca_leds)
return ERR_PTR(-ENOMEM);
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct led_info led;
u32 reg;
int ret;
@ -688,10 +687,8 @@ tca6507_led_dt_init(struct device *dev)
led.flags |= TCA6507_MAKE_GPIO;
ret = fwnode_property_read_u32(child, "reg", &reg);
if (ret || reg >= NUM_LEDS) {
fwnode_handle_put(child);
if (ret || reg >= NUM_LEDS)
return ERR_PTR(ret ? : -EINVAL);
}
tca_leds[reg] = led;
}

View File

@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include "leds.h"
#define OMNIA_BOARD_LEDS 12
#define OMNIA_LED_NUM_CHANNELS 3

View File

@ -292,7 +292,7 @@ static struct platform_driver wm831x_status_driver = {
.name = "wm831x-status",
},
.probe = wm831x_status_probe,
.remove_new = wm831x_status_remove,
.remove = wm831x_status_remove,
};
module_platform_driver(wm831x_status_driver);

View File

@ -255,7 +255,7 @@ static struct platform_driver wm8350_led_driver = {
.name = "wm8350-led",
},
.probe = wm8350_led_probe,
.remove_new = wm8350_led_remove,
.remove = wm8350_led_remove,
.shutdown = wm8350_led_shutdown,
};

View File

@ -55,7 +55,7 @@ static void restore_sysfs_write_access(void *data)
{
struct led_classdev *led_cdev = data;
/* Restore the write acccess to the LED */
/* Restore the write access to the LED */
mutex_lock(&led_cdev->led_access);
led_sysfs_enable(led_cdev);
mutex_unlock(&led_cdev->led_access);

View File

@ -495,7 +495,6 @@ static int ktd202x_add_led(struct ktd202x *chip, struct fwnode_handle *fwnode, u
static int ktd202x_probe_fw(struct ktd202x *chip)
{
struct fwnode_handle *child;
struct device *dev = chip->dev;
int count;
int i = 0;
@ -509,13 +508,12 @@ static int ktd202x_probe_fw(struct ktd202x *chip)
/* Allow the device to execute the complete reset */
usleep_range(200, 300);
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
int ret = ktd202x_add_led(chip, child, i);
if (ret) {
fwnode_handle_put(child);
if (ret)
return ret;
}
i++;
}

View File

@ -587,7 +587,7 @@ static inline int mt6370_mc_pattern_clear(struct led_classdev *lcdev)
struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc);
struct mt6370_priv *priv = led->priv;
struct mc_subled *subled;
int i, ret;
int i, ret = 0;
mutex_lock(&led->priv->lock);
@ -905,7 +905,6 @@ static int mt6370_leds_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mt6370_priv *priv;
struct fwnode_handle *child;
size_t count;
unsigned int i = 0;
int ret;
@ -936,37 +935,27 @@ static int mt6370_leds_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "Failed to allocate regmap field\n");
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct mt6370_led *led = priv->leds + i++;
struct led_init_data init_data = { .fwnode = child };
u32 reg, color;
ret = fwnode_property_read_u32(child, "reg", &reg);
if (ret) {
dev_err(dev, "Failed to parse reg property\n");
goto fwnode_release;
}
if (ret)
dev_err_probe(dev, ret, "Failed to parse reg property\n");
if (reg >= MT6370_MAX_LEDS) {
ret = -EINVAL;
dev_err(dev, "Error reg property number\n");
goto fwnode_release;
}
if (reg >= MT6370_MAX_LEDS)
return dev_err_probe(dev, -EINVAL, "Error reg property number\n");
ret = fwnode_property_read_u32(child, "color", &color);
if (ret) {
dev_err(dev, "Failed to parse color property\n");
goto fwnode_release;
}
if (ret)
return dev_err_probe(dev, ret, "Failed to parse color property\n");
if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI)
reg = MT6370_VIRTUAL_MULTICOLOR;
if (priv->leds_active & BIT(reg)) {
ret = -EINVAL;
dev_err(dev, "Duplicate reg property\n");
goto fwnode_release;
}
if (priv->leds_active & BIT(reg))
return dev_err_probe(dev, -EINVAL, "Duplicate reg property\n");
priv->leds_active |= BIT(reg);
@ -975,18 +964,14 @@ static int mt6370_leds_probe(struct platform_device *pdev)
ret = mt6370_init_led_properties(dev, led, &init_data);
if (ret)
goto fwnode_release;
return ret;
ret = mt6370_led_register(dev, led, &init_data);
if (ret)
goto fwnode_release;
return ret;
}
return 0;
fwnode_release:
fwnode_handle_put(child);
return ret;
}
static const struct of_device_id mt6370_rgbled_device_table[] = {

View File

@ -53,7 +53,7 @@ static void simatic_ipc_leds_gpio_apollolake_remove(struct platform_device *pdev
static struct platform_driver simatic_ipc_led_gpio_apollolake_driver = {
.probe = simatic_ipc_leds_gpio_apollolake_probe,
.remove_new = simatic_ipc_leds_gpio_apollolake_remove,
.remove = simatic_ipc_leds_gpio_apollolake_remove,
.driver = {
.name = KBUILD_MODNAME,
},

View File

@ -43,7 +43,7 @@ static void simatic_ipc_leds_gpio_elkhartlake_remove(struct platform_device *pde
static struct platform_driver simatic_ipc_led_gpio_elkhartlake_driver = {
.probe = simatic_ipc_leds_gpio_elkhartlake_probe,
.remove_new = simatic_ipc_leds_gpio_elkhartlake_remove,
.remove = simatic_ipc_leds_gpio_elkhartlake_remove,
.driver = {
.name = KBUILD_MODNAME,
},

View File

@ -93,7 +93,7 @@ static void simatic_ipc_leds_gpio_f7188x_remove(struct platform_device *pdev)
static struct platform_driver simatic_ipc_led_gpio_driver = {
.probe = simatic_ipc_leds_gpio_f7188x_probe,
.remove_new = simatic_ipc_leds_gpio_f7188x_remove,
.remove = simatic_ipc_leds_gpio_f7188x_remove,
.driver = {
.name = KBUILD_MODNAME,
},

View File

@ -171,6 +171,7 @@ struct led_classdev {
int new_blink_brightness;
void (*flash_resume)(struct led_classdev *led_cdev);
struct workqueue_struct *wq; /* LED workqueue */
struct work_struct set_brightness_work;
int delayed_set_value;
unsigned long delayed_delay_on;
@ -238,7 +239,7 @@ struct led_classdev {
struct kernfs_node *brightness_hw_changed_kn;
#endif
/* Ensures consistent access to the LED Flash Class device */
/* Ensures consistent access to the LED class device */
struct mutex led_access;
};