summaryrefslogtreecommitdiff
path: root/drivers/leds
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-17 18:40:42 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-17 18:40:42 -0700
commit4feaab05dc1eda3dbb57b097377766002e7a7cb9 (patch)
treefc7a877094032fd1e8d161c8782fecc73f70a8b6 /drivers/leds
parente7345f92c27af003f219ad026d0e629a50b41e5c (diff)
parent6d4faf3b6b6eb3c8a750b2e6659a5b1ff3dd9e75 (diff)
Merge tag 'leds-for-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds
Pull LED updates from Jacek Anaszewski: "In this cycle we've finally managed to contribute the patch set sorting out LED naming issues. Besides that there are many changes scattered among various LED class drivers and triggers. LED naming related improvements: - add new 'function' and 'color' fwnode properties and deprecate 'label' property which has been frequently abused for conveying vendor specific names that have been available in sysfs anyway - introduce a set of standard LED_FUNCTION* definitions - introduce a set of standard LED_COLOR_ID* definitions - add a new {devm_}led_classdev_register_ext() API with the capability of automatic LED name composition basing on the properties available in the passed fwnode; the function is backwards compatible in a sense that it uses 'label' data, if present in the fwnode, for creating LED name - add tools/leds/get_led_device_info.sh script for retrieving LED vendor, product and bus names, if applicable; it also performs basic validation of an LED name - update following drivers and their DT bindings to use the new LED registration API: - leds-an30259a, leds-gpio, leds-as3645a, leds-aat1290, leds-cr0014114, leds-lm3601x, leds-lm3692x, leds-lp8860, leds-lt3593, leds-sc27xx-blt Other LED class improvements: - replace {devm_}led_classdev_register() macros with inlines - allow to call led_classdev_unregister() unconditionally - switch to use fwnode instead of be stuck with OF one LED triggers improvements: - led-triggers: - fix dereferencing of null pointer - fix a memory leak bug - ledtrig-gpio: - GPIO 0 is valid Drop superseeded apu2/3 support from leds-apu since for apu2+ a newer, more complete driver exists, based on a generic driver for the AMD SOCs gpio-controller, supporting LEDs as well other devices: - drop profile field from priv data - drop iosize field from priv data - drop enum_apu_led_platform_types - drop superseeded apu2/3 led support - add pr_fmt prefix for better log output - fix error message on probing failure Other misc fixes and improvements to existing LED class drivers: - leds-ns2, leds-max77650: - add of_node_put() before return - leds-pwm, leds-is31fl32xx: - use struct_size() helper - leds-lm3697, leds-lm36274, leds-lm3532: - switch to use fwnode_property_count_uXX() - leds-lm3532: - fix brightness control for i2c mode - change the define for the fs current register - fixes for the driver for stability - add full scale current configuration - dt: Add property for full scale current. - avoid potentially unpaired regulator calls - move static keyword to the front of declarations - fix optional led-max-microamp prop error handling - leds-max77650: - add of_node_put() before return - add MODULE_ALIAS() - Switch to fwnode property API - leds-as3645a: - fix misuse of strlcpy - leds-netxbig: - add of_node_put() in netxbig_leds_get_of_pdata() - remove legacy board-file support - leds-is31fl319x: - simplify getting the adapter of a client - leds-ti-lmu-common: - fix coccinelle issue - move static keyword to the front of declaration - leds-syscon: - use resource managed variant of device register - leds-ktd2692: - fix a typo in the name of a constant - leds-lp5562: - allow firmware files up to the maximum length - leds-an30259a: - fix typo - leds-pca953x: - include the right header" * tag 'leds-for-5.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds: (72 commits) leds: lm3532: Fix optional led-max-microamp prop error handling led: triggers: Fix dereferencing of null pointer leds: ti-lmu-common: Move static keyword to the front of declaration leds: lm3532: Move static keyword to the front of declarations leds: trigger: gpio: GPIO 0 is valid leds: pwm: Use struct_size() helper leds: is31fl32xx: Use struct_size() helper leds: ti-lmu-common: Fix coccinelle issue in TI LMU leds: lm3532: Avoid potentially unpaired regulator calls leds: syscon: Use resource managed variant of device register leds: Replace {devm_}led_classdev_register() macros with inlines leds: Allow to call led_classdev_unregister() unconditionally leds: lm3532: Add full scale current configuration dt: lm3532: Add property for full scale current. leds: lm3532: Fixes for the driver for stability leds: lm3532: Change the define for the fs current register leds: lm3532: Fix brightness control for i2c mode leds: Switch to use fwnode instead of be stuck with OF one leds: max77650: Switch to fwnode property API led: triggers: Fix a memory leak bug ...
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig6
-rw-r--r--drivers/leds/led-class-flash.c9
-rw-r--r--drivers/leds/led-class.c62
-rw-r--r--drivers/leds/led-core.c136
-rw-r--r--drivers/leds/led-triggers.c5
-rw-r--r--drivers/leds/leds-aat1290.c16
-rw-r--r--drivers/leds/leds-an30259a.c29
-rw-r--r--drivers/leds/leds-apu.c157
-rw-r--r--drivers/leds/leds-as3645a.c74
-rw-r--r--drivers/leds/leds-cr0014114.c33
-rw-r--r--drivers/leds/leds-gpio.c26
-rw-r--r--drivers/leds/leds-is31fl319x.c3
-rw-r--r--drivers/leds/leds-is31fl32xx.c8
-rw-r--r--drivers/leds/leds-ktd2692.c4
-rw-r--r--drivers/leds/leds-lm3532.c138
-rw-r--r--drivers/leds/leds-lm3601x.c38
-rw-r--r--drivers/leds/leds-lm36274.c4
-rw-r--r--drivers/leds/leds-lm3692x.c22
-rw-r--r--drivers/leds/leds-lm3697.c5
-rw-r--r--drivers/leds/leds-lp5562.c6
-rw-r--r--drivers/leds/leds-lp8860.c35
-rw-r--r--drivers/leds/leds-lt3593.c20
-rw-r--r--drivers/leds/leds-max77650.c44
-rw-r--r--drivers/leds/leds-netxbig.c76
-rw-r--r--drivers/leds/leds-ns2.c21
-rw-r--r--drivers/leds/leds-pca9532.c2
-rw-r--r--drivers/leds/leds-pwm.c11
-rw-r--r--drivers/leds/leds-sc27xx-bltc.c22
-rw-r--r--drivers/leds/leds-syscon.c2
-rw-r--r--drivers/leds/leds-ti-lmu-common.c15
-rw-r--r--drivers/leds/leds.h1
-rw-r--r--drivers/leds/trigger/ledtrig-gpio.c12
32 files changed, 554 insertions, 488 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index b0fdeef10bd9..1988de1d64c0 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -74,9 +74,12 @@ config LEDS_APU
depends on LEDS_CLASS
depends on X86 && DMI
help
- This driver makes the PC Engines APU/APU2/APU3 front panel LEDs
+ This driver makes the PC Engines APU1 front panel LEDs
accessible from userspace programs through the LED subsystem.
+ If you're looking for APU2/3, use the pcengines-apu2 driver.
+ (symbol CONFIG_PCENGINES_APU2)
+
To compile this driver as a module, choose M here: the
module will be called leds-apu.
@@ -587,6 +590,7 @@ config LEDS_NETXBIG
tristate "LED support for Big Network series LEDs"
depends on LEDS_CLASS
depends on MACH_KIRKWOOD
+ depends on OF_GPIO
default y
help
This option enables support for LEDs found on the LaCie 2Big
diff --git a/drivers/leds/led-class-flash.c b/drivers/leds/led-class-flash.c
index 94980c654d89..60c3de5c6b9f 100644
--- a/drivers/leds/led-class-flash.c
+++ b/drivers/leds/led-class-flash.c
@@ -282,8 +282,9 @@ static void led_flash_init_sysfs_groups(struct led_classdev_flash *fled_cdev)
led_cdev->groups = flash_groups;
}
-int led_classdev_flash_register(struct device *parent,
- struct led_classdev_flash *fled_cdev)
+int led_classdev_flash_register_ext(struct device *parent,
+ struct led_classdev_flash *fled_cdev,
+ struct led_init_data *init_data)
{
struct led_classdev *led_cdev;
const struct led_flash_ops *ops;
@@ -309,13 +310,13 @@ int led_classdev_flash_register(struct device *parent,
}
/* Register led class device */
- ret = led_classdev_register(parent, led_cdev);
+ ret = led_classdev_register_ext(parent, led_cdev, init_data);
if (ret < 0)
return ret;
return 0;
}
-EXPORT_SYMBOL_GPL(led_classdev_flash_register);
+EXPORT_SYMBOL_GPL(led_classdev_flash_register_ext);
void led_classdev_flash_unregister(struct led_classdev_flash *fled_cdev)
{
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 4793e77808e2..647b1263c579 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -14,6 +14,7 @@
#include <linux/leds.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
@@ -213,13 +214,6 @@ static int led_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
-static int match_name(struct device *dev, const void *data)
-{
- if (!dev_name(dev))
- return 0;
- return !strcmp(dev_name(dev), (char *)data);
-}
-
static int led_classdev_next_name(const char *init_name, char *name,
size_t len)
{
@@ -230,7 +224,7 @@ static int led_classdev_next_name(const char *init_name, char *name,
strlcpy(name, init_name, len);
while ((ret < len) &&
- (dev = class_find_device(leds_class, NULL, name, match_name))) {
+ (dev = class_find_device_by_name(leds_class, name))) {
put_device(dev);
ret = snprintf(name, len, "%s_%u", init_name, ++i);
}
@@ -242,31 +236,48 @@ static int led_classdev_next_name(const char *init_name, char *name,
}
/**
- * of_led_classdev_register - register a new object of led_classdev class.
+ * led_classdev_register_ext - register a new object of led_classdev class
+ * with init data.
*
* @parent: parent of LED device
* @led_cdev: the led_classdev structure for this device.
- * @np: DT node describing this LED
+ * @init_data: LED class device initialization data
*/
-int of_led_classdev_register(struct device *parent, struct device_node *np,
- struct led_classdev *led_cdev)
+int led_classdev_register_ext(struct device *parent,
+ struct led_classdev *led_cdev,
+ struct led_init_data *init_data)
{
- char name[LED_MAX_NAME_SIZE];
+ char composed_name[LED_MAX_NAME_SIZE];
+ char final_name[LED_MAX_NAME_SIZE];
+ const char *proposed_name = composed_name;
int ret;
- ret = led_classdev_next_name(led_cdev->name, name, sizeof(name));
+ if (init_data) {
+ if (init_data->devname_mandatory && !init_data->devicename) {
+ dev_err(parent, "Mandatory device name is missing");
+ return -EINVAL;
+ }
+ ret = led_compose_name(parent, init_data, composed_name);
+ if (ret < 0)
+ return ret;
+ } else {
+ proposed_name = led_cdev->name;
+ }
+
+ ret = led_classdev_next_name(proposed_name, final_name, sizeof(final_name));
if (ret < 0)
return ret;
mutex_init(&led_cdev->led_access);
mutex_lock(&led_cdev->led_access);
led_cdev->dev = device_create_with_groups(leds_class, parent, 0,
- led_cdev, led_cdev->groups, "%s", name);
+ led_cdev, led_cdev->groups, "%s", final_name);
if (IS_ERR(led_cdev->dev)) {
mutex_unlock(&led_cdev->led_access);
return PTR_ERR(led_cdev->dev);
}
- led_cdev->dev->of_node = np;
+ if (init_data && init_data->fwnode)
+ led_cdev->dev->fwnode = init_data->fwnode;
if (ret)
dev_warn(parent, "Led %s renamed to %s due to name collision",
@@ -276,6 +287,7 @@ int of_led_classdev_register(struct device *parent, struct device_node *np,
ret = led_add_brightness_hw_changed(led_cdev);
if (ret) {
device_unregister(led_cdev->dev);
+ led_cdev->dev = NULL;
mutex_unlock(&led_cdev->led_access);
return ret;
}
@@ -311,7 +323,7 @@ int of_led_classdev_register(struct device *parent, struct device_node *np,
return 0;
}
-EXPORT_SYMBOL_GPL(of_led_classdev_register);
+EXPORT_SYMBOL_GPL(led_classdev_register_ext);
/**
* led_classdev_unregister - unregisters a object of led_properties class.
@@ -321,6 +333,9 @@ EXPORT_SYMBOL_GPL(of_led_classdev_register);
*/
void led_classdev_unregister(struct led_classdev *led_cdev)
{
+ if (IS_ERR_OR_NULL(led_cdev->dev))
+ return;
+
#ifdef CONFIG_LEDS_TRIGGERS
down_write(&led_cdev->trigger_lock);
if (led_cdev->trigger)
@@ -356,14 +371,15 @@ static void devm_led_classdev_release(struct device *dev, void *res)
}
/**
- * devm_of_led_classdev_register - resource managed led_classdev_register()
+ * devm_led_classdev_register_ext - resource managed led_classdev_register_ext()
*
* @parent: parent of LED device
* @led_cdev: the led_classdev structure for this device.
+ * @init_data: LED class device initialization data
*/
-int devm_of_led_classdev_register(struct device *parent,
- struct device_node *np,
- struct led_classdev *led_cdev)
+int devm_led_classdev_register_ext(struct device *parent,
+ struct led_classdev *led_cdev,
+ struct led_init_data *init_data)
{
struct led_classdev **dr;
int rc;
@@ -372,7 +388,7 @@ int devm_of_led_classdev_register(struct device *parent,
if (!dr)
return -ENOMEM;
- rc = of_led_classdev_register(parent, np, led_cdev);
+ rc = led_classdev_register_ext(parent, led_cdev, init_data);
if (rc) {
devres_free(dr);
return rc;
@@ -383,7 +399,7 @@ int devm_of_led_classdev_register(struct device *parent,
return 0;
}
-EXPORT_SYMBOL_GPL(devm_of_led_classdev_register);
+EXPORT_SYMBOL_GPL(devm_led_classdev_register_ext);
static int devm_led_classdev_match(struct device *dev, void *res, void *data)
{
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 7107cd7e87cf..f1f718dbe0f8 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -13,8 +13,10 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/rwsem.h>
#include <linux/slab.h>
+#include <uapi/linux/uleds.h>
#include "leds.h"
DECLARE_RWSEM(leds_list_lock);
@@ -23,6 +25,18 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
LIST_HEAD(leds_list);
EXPORT_SYMBOL_GPL(leds_list);
+const char * const led_colors[LED_COLOR_ID_MAX] = {
+ [LED_COLOR_ID_WHITE] = "white",
+ [LED_COLOR_ID_RED] = "red",
+ [LED_COLOR_ID_GREEN] = "green",
+ [LED_COLOR_ID_BLUE] = "blue",
+ [LED_COLOR_ID_AMBER] = "amber",
+ [LED_COLOR_ID_VIOLET] = "violet",
+ [LED_COLOR_ID_YELLOW] = "yellow",
+ [LED_COLOR_ID_IR] = "ir",
+};
+EXPORT_SYMBOL_GPL(led_colors);
+
static int __led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
@@ -310,14 +324,11 @@ EXPORT_SYMBOL_GPL(led_update_brightness);
u32 *led_get_default_pattern(struct led_classdev *led_cdev, unsigned int *size)
{
- struct device_node *np = dev_of_node(led_cdev->dev);
+ struct fwnode_handle *fwnode = led_cdev->dev->fwnode;
u32 *pattern;
int count;
- if (!np)
- return NULL;
-
- count = of_property_count_u32_elems(np, "led-pattern");
+ count = fwnode_property_count_u32(fwnode, "led-pattern");
if (count < 0)
return NULL;
@@ -325,7 +336,7 @@ u32 *led_get_default_pattern(struct led_classdev *led_cdev, unsigned int *size)
if (!pattern)
return NULL;
- if (of_property_read_u32_array(np, "led-pattern", pattern, count)) {
+ if (fwnode_property_read_u32_array(fwnode, "led-pattern", pattern, count)) {
kfree(pattern);
return NULL;
}
@@ -353,3 +364,116 @@ void led_sysfs_enable(struct led_classdev *led_cdev)
led_cdev->flags &= ~LED_SYSFS_DISABLE;
}
EXPORT_SYMBOL_GPL(led_sysfs_enable);
+
+static void led_parse_fwnode_props(struct device *dev,
+ struct fwnode_handle *fwnode,
+ struct led_properties *props)
+{
+ int ret;
+
+ if (!fwnode)
+ return;
+
+ if (fwnode_property_present(fwnode, "label")) {
+ ret = fwnode_property_read_string(fwnode, "label", &props->label);
+ if (ret)
+ dev_err(dev, "Error parsing 'label' property (%d)\n", ret);
+ return;
+ }
+
+ if (fwnode_property_present(fwnode, "color")) {
+ ret = fwnode_property_read_u32(fwnode, "color", &props->color);
+ if (ret)
+ dev_err(dev, "Error parsing 'color' property (%d)\n", ret);
+ else if (props->color >= LED_COLOR_ID_MAX)
+ dev_err(dev, "LED color identifier out of range\n");
+ else
+ props->color_present = true;
+ }
+
+
+ if (!fwnode_property_present(fwnode, "function"))
+ return;
+
+ ret = fwnode_property_read_string(fwnode, "function", &props->function);
+ if (ret) {
+ dev_err(dev,
+ "Error parsing 'function' property (%d)\n",
+ ret);
+ }
+
+ if (!fwnode_property_present(fwnode, "function-enumerator"))
+ return;
+
+ ret = fwnode_property_read_u32(fwnode, "function-enumerator",
+ &props->func_enum);
+ if (ret) {
+ dev_err(dev,
+ "Error parsing 'function-enumerator' property (%d)\n",
+ ret);
+ } else {
+ props->func_enum_present = true;
+ }
+}
+
+int led_compose_name(struct device *dev, struct led_init_data *init_data,
+ char *led_classdev_name)
+{
+ struct led_properties props = {};
+ struct fwnode_handle *fwnode = init_data->fwnode;
+ const char *devicename = init_data->devicename;
+
+ if (!led_classdev_name)
+ return -EINVAL;
+
+ led_parse_fwnode_props(dev, fwnode, &props);
+
+ if (props.label) {
+ /*
+ * If init_data.devicename is NULL, then it indicates that
+ * DT label should be used as-is for LED class device name.
+ * Otherwise the label is prepended with devicename to compose
+ * the final LED class device name.
+ */
+ if (!devicename) {
+ strscpy(led_classdev_name, props.label,
+ LED_MAX_NAME_SIZE);
+ } else {
+ snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
+ devicename, props.label);
+ }
+ } else if (props.function || props.color_present) {
+ char tmp_buf[LED_MAX_NAME_SIZE];
+
+ if (props.func_enum_present) {
+ snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s-%d",
+ props.color_present ? led_colors[props.color] : "",
+ props.function ?: "", props.func_enum);
+ } else {
+ snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s",
+ props.color_present ? led_colors[props.color] : "",
+ props.function ?: "");
+ }
+ if (init_data->devname_mandatory) {
+ snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
+ devicename, tmp_buf);
+ } else {
+ strscpy(led_classdev_name, tmp_buf, LED_MAX_NAME_SIZE);
+
+ }
+ } else if (init_data->default_label) {
+ if (!devicename) {
+ dev_err(dev, "Legacy LED naming requires devicename segment");
+ return -EINVAL;
+ }
+ snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
+ devicename, init_data->default_label);
+ } else if (is_of_node(fwnode)) {
+ strscpy(led_classdev_name, to_of_node(fwnode)->name,
+ LED_MAX_NAME_SIZE);
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(led_compose_name);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 8d11a5e23227..23963e5cb5d6 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -167,12 +167,13 @@ err_add_groups:
trig->deactivate(led_cdev);
err_activate:
- led_cdev->trigger = NULL;
- led_cdev->trigger_data = NULL;
write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
list_del(&led_cdev->trig_list);
write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags);
+ led_cdev->trigger = NULL;
+ led_cdev->trigger_data = NULL;
led_set_brightness(led_cdev, LED_OFF);
+ kfree(event);
return ret;
}
diff --git a/drivers/leds/leds-aat1290.c b/drivers/leds/leds-aat1290.c
index bf26f5bed1f0..5a0fe7b7b8bc 100644
--- a/drivers/leds/leds-aat1290.c
+++ b/drivers/leds/leds-aat1290.c
@@ -42,6 +42,8 @@
#define AAT1290_FLASH_TM_NUM_LEVELS 16
#define AAT1290_MM_CURRENT_SCALE_SIZE 15
+#define AAT1290_NAME "aat1290"
+
struct aat1290_led_config_data {
/* maximum LED current in movie mode */
@@ -75,7 +77,6 @@ struct aat1290_led {
int *mm_current_scale;
/* device mode */
bool movie_mode;
-
/* brightness cache */
unsigned int torch_brightness;
};
@@ -215,7 +216,6 @@ static int aat1290_led_parse_dt(struct aat1290_led *led,
struct aat1290_led_config_data *cfg,
struct device_node **sub_node)
{
- struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
struct device *dev = &led->pdev->dev;
struct device_node *child_node;
#if IS_ENABLED(CONFIG_V4L2_FLASH_LED_CLASS)
@@ -254,9 +254,6 @@ static int aat1290_led_parse_dt(struct aat1290_led *led,
return -EINVAL;
}
- led_cdev->name = of_get_property(child_node, "label", NULL) ? :
- child_node->name;
-
ret = of_property_read_u32(child_node, "led-max-microamp",
&cfg->max_mm_current);
/*
@@ -428,7 +425,7 @@ static void aat1290_init_v4l2_flash_config(struct aat1290_led *led,
struct led_classdev *led_cdev = &led->fled_cdev.led_cdev;
struct led_flash_setting *s;
- strlcpy(v4l2_sd_cfg->dev_name, led_cdev->name,
+ strlcpy(v4l2_sd_cfg->dev_name, led_cdev->dev->kobj.name,
sizeof(v4l2_sd_cfg->dev_name));
s = &v4l2_sd_cfg->intensity;
@@ -466,6 +463,7 @@ static int aat1290_led_probe(struct platform_device *pdev)
struct aat1290_led *led;
struct led_classdev *led_cdev;
struct led_classdev_flash *fled_cdev;
+ struct led_init_data init_data = {};
struct aat1290_led_config_data led_cfg = {};
struct v4l2_flash_config v4l2_sd_cfg = {};
int ret;
@@ -494,8 +492,12 @@ static int aat1290_led_probe(struct platform_device *pdev)
aat1290_init_flash_timeout(led, &led_cfg);
+ init_data.fwnode = of_fwnode_handle(sub_node);
+ init_data.devicename = AAT1290_NAME;
+
/* Register LED Flash class device */
- ret = led_classdev_flash_register(&pdev->dev, fled_cdev);
+ ret = led_classdev_flash_register_ext(&pdev->dev, fled_cdev,
+ &init_data);
if (ret < 0)
goto err_flash_register;
diff --git a/drivers/leds/leds-an30259a.c b/drivers/leds/leds-an30259a.c
index 1c1f0c8c56f4..250dc9d6f635 100644
--- a/drivers/leds/leds-an30259a.c
+++ b/drivers/leds/leds-an30259a.c
@@ -13,7 +13,6 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/regmap.h>
-#include <uapi/linux/uleds.h>
#define AN30259A_MAX_LEDS 3
@@ -54,6 +53,8 @@
#define AN30259A_BLINK_MAX_TIME 7500 /* ms */
#define AN30259A_SLOPE_RESOLUTION 500 /* ms */
+#define AN30259A_NAME "an30259a"
+
#define STATE_OFF 0
#define STATE_KEEP 1
#define STATE_ON 2
@@ -62,11 +63,11 @@ struct an30259a;
struct an30259a_led {
struct an30259a *chip;
+ struct fwnode_handle *fwnode;
struct led_classdev cdev;
u32 num;
u32 default_state;
bool sloping;
- char label[LED_MAX_NAME_SIZE];
};
struct an30259a {
@@ -226,14 +227,7 @@ static int an30259a_dt_init(struct i2c_client *client,
led->num = source;
led->chip = chip;
-
- if (of_property_read_string(child, "label", &str))
- snprintf(led->label, sizeof(led->label), "an30259a::");
- else
- snprintf(led->label, sizeof(led->label), "an30259a:%s",
- str);
-
- led->cdev.name = led->label;
+ led->fwnode = of_fwnode_handle(child);
if (!of_property_read_string(child, "default-state", &str)) {
if (!strcmp(str, "on"))
@@ -312,13 +306,20 @@ static int an30259a_probe(struct i2c_client *client)
chip->regmap = devm_regmap_init_i2c(client, &an30259a_regmap_config);
for (i = 0; i < chip->num_leds; i++) {
+ struct led_init_data init_data = {};
+
an30259a_init_default_state(&chip->leds[i]);
chip->leds[i].cdev.brightness_set_blocking =
an30259a_brightness_set;
chip->leds[i].cdev.blink_set = an30259a_blink_set;
- err = devm_led_classdev_register(&client->dev,
- &chip->leds[i].cdev);
+ init_data.fwnode = chip->leds[i].fwnode;
+ init_data.devicename = AN30259A_NAME;
+ init_data.default_label = ":";
+
+ err = devm_led_classdev_register_ext(&client->dev,
+ &chip->leds[i].cdev,
+ &init_data);
if (err < 0)
goto exit;
}
@@ -353,7 +354,7 @@ MODULE_DEVICE_TABLE(i2c, an30259a_id);
static struct i2c_driver an30259a_driver = {
.driver = {
- .name = "leds-an32059a",
+ .name = "leds-an30259a",
.of_match_table = of_match_ptr(an30259a_match_table),
},
.probe_new = an30259a_probe,
@@ -364,5 +365,5 @@ static struct i2c_driver an30259a_driver = {
module_i2c_driver(an30259a_driver);
MODULE_AUTHOR("Simon Shields <simon@lineageos.org>");
-MODULE_DESCRIPTION("AN32059A LED driver");
+MODULE_DESCRIPTION("AN30259A LED driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-apu.c b/drivers/leds/leds-apu.c
index 8d42e46e2de3..7fd557aceff6 100644
--- a/drivers/leds/leds-apu.c
+++ b/drivers/leds/leds-apu.c
@@ -31,6 +31,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/dmi.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -47,12 +49,6 @@
#define APU1_NUM_GPIO 3
#define APU1_IOSIZE sizeof(u8)
-#define APU2_FCH_ACPI_MMIO_BASE 0xFED80000
-#define APU2_FCH_GPIO_BASE (APU2_FCH_ACPI_MMIO_BASE + 0x1500)
-#define APU2_GPIO_BIT_WRITE 22
-#define APU2_APU2_NUM_GPIO 4
-#define APU2_IOSIZE sizeof(u32)
-
/* LED access parameters */
struct apu_param {
void __iomem *addr; /* for ioread/iowrite */
@@ -72,19 +68,9 @@ struct apu_led_profile {
unsigned long offset; /* for devm_ioremap */
};
-/* Supported platform types */
-enum apu_led_platform_types {
- APU1_LED_PLATFORM,
- APU2_LED_PLATFORM,
-};
-
struct apu_led_pdata {
struct platform_device *pdev;
struct apu_led_priv *pled;
- const struct apu_led_profile *profile;
- enum apu_led_platform_types platform;
- int num_led_instances;
- int iosize; /* for devm_ioremap() */
spinlock_t lock;
};
@@ -96,19 +82,6 @@ static const struct apu_led_profile apu1_led_profile[] = {
{ "apu:green:3", LED_OFF, APU1_FCH_GPIO_BASE + 2 * APU1_IOSIZE },
};
-static const struct apu_led_profile apu2_led_profile[] = {
- { "apu2:green:1", LED_ON, APU2_FCH_GPIO_BASE + 68 * APU2_IOSIZE },
- { "apu2:green:2", LED_OFF, APU2_FCH_GPIO_BASE + 69 * APU2_IOSIZE },
- { "apu2:green:3", LED_OFF, APU2_FCH_GPIO_BASE + 70 * APU2_IOSIZE },
-};
-
-/* Same as apu2_led_profile, but with "3" in the LED names. */
-static const struct apu_led_profile apu3_led_profile[] = {
- { "apu3:green:1", LED_ON, APU2_FCH_GPIO_BASE + 68 * APU2_IOSIZE },
- { "apu3:green:2", LED_OFF, APU2_FCH_GPIO_BASE + 69 * APU2_IOSIZE },
- { "apu3:green:3", LED_OFF, APU2_FCH_GPIO_BASE + 70 * APU2_IOSIZE },
-};
-
static const struct dmi_system_id apu_led_dmi_table[] __initconst = {
{
.ident = "apu",
@@ -117,54 +90,6 @@ static const struct dmi_system_id apu_led_dmi_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_NAME, "APU")
}
},
- /* PC Engines APU2 with "Legacy" bios < 4.0.8 */
- {
- .ident = "apu2",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
- DMI_MATCH(DMI_BOARD_NAME, "APU2")
- }
- },
- /* PC Engines APU2 with "Legacy" bios >= 4.0.8 */
- {
- .ident = "apu2",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
- DMI_MATCH(DMI_BOARD_NAME, "apu2")
- }
- },
- /* PC Engines APU2 with "Mainline" bios */
- {
- .ident = "apu2",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
- DMI_MATCH(DMI_BOARD_NAME, "PC Engines apu2")
- }
- },
- /* PC Engines APU3 with "Legacy" bios < 4.0.8 */
- {
- .ident = "apu3",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
- DMI_MATCH(DMI_BOARD_NAME, "APU3")
- }
- },
- /* PC Engines APU3 with "Legacy" bios >= 4.0.8 */
- {
- .ident = "apu3",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
- DMI_MATCH(DMI_BOARD_NAME, "apu3")
- }
- },
- /* PC Engines APU2 with "Mainline" bios */
- {
- .ident = "apu3",
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "PC Engines"),
- DMI_MATCH(DMI_BOARD_NAME, "PC Engines apu3")
- }
- },
{}
};
MODULE_DEVICE_TABLE(dmi, apu_led_dmi_table);
@@ -178,52 +103,30 @@ static void apu1_led_brightness_set(struct led_classdev *led, enum led_brightnes
spin_unlock(&apu_led->lock);
}
-static void apu2_led_brightness_set(struct led_classdev *led, enum led_brightness value)
-{
- struct apu_led_priv *pled = cdev_to_priv(led);
- u32 value_new;
-
- spin_lock(&apu_led->lock);
-
- value_new = ioread32(pled->param.addr);
-
- if (value)
- value_new &= ~BIT(APU2_GPIO_BIT_WRITE);
- else
- value_new |= BIT(APU2_GPIO_BIT_WRITE);
-
- iowrite32(value_new, pled->param.addr);
-
- spin_unlock(&apu_led->lock);
-}
-
static int apu_led_config(struct device *dev, struct apu_led_pdata *apuld)
{
int i;
int err;
apu_led->pled = devm_kcalloc(dev,
- apu_led->num_led_instances, sizeof(struct apu_led_priv),
+ ARRAY_SIZE(apu1_led_profile), sizeof(struct apu_led_priv),
GFP_KERNEL);
if (!apu_led->pled)
return -ENOMEM;
- for (i = 0; i < apu_led->num_led_instances; i++) {
+ for (i = 0; i < ARRAY_SIZE(apu1_led_profile); i++) {
struct apu_led_priv *pled = &apu_led->pled[i];
struct led_classdev *led_cdev = &pled->cdev;
- led_cdev->name = apu_led->profile[i].name;
- led_cdev->brightness = apu_led->profile[i].brightness;
+ led_cdev->name = apu1_led_profile[i].name;
+ led_cdev->brightness = apu1_led_profile[i].brightness;
led_cdev->max_brightness = 1;
led_cdev->flags = LED_CORE_SUSPENDRESUME;
- if (apu_led->platform == APU1_LED_PLATFORM)
- led_cdev->brightness_set = apu1_led_brightness_set;
- else if (apu_led->platform == APU2_LED_PLATFORM)
- led_cdev->brightness_set = apu2_led_brightness_set;
+ led_cdev->brightness_set = apu1_led_brightness_set;
pled->param.addr = devm_ioremap(dev,
- apu_led->profile[i].offset, apu_led->iosize);
+ apu1_led_profile[i].offset, APU1_IOSIZE);
if (!pled->param.addr) {
err = -ENOMEM;
goto error;
@@ -233,7 +136,7 @@ static int apu_led_config(struct device *dev, struct apu_led_pdata *apuld)
if (err)
goto error;
- led_cdev->brightness_set(led_cdev, apu_led->profile[i].brightness);
+ apu1_led_brightness_set(led_cdev, apu1_led_profile[i].brightness);
}
return 0;
@@ -254,28 +157,6 @@ static int __init apu_led_probe(struct platform_device *pdev)
apu_led->pdev = pdev;
- if (dmi_match(DMI_PRODUCT_NAME, "APU")) {
- apu_led->profile = apu1_led_profile;
- apu_led->platform = APU1_LED_PLATFORM;
- apu_led->num_led_instances = ARRAY_SIZE(apu1_led_profile);
- apu_led->iosize = APU1_IOSIZE;
- } else if (dmi_match(DMI_BOARD_NAME, "APU2") ||
- dmi_match(DMI_BOARD_NAME, "apu2") ||
- dmi_match(DMI_BOARD_NAME, "PC Engines apu2")) {
- apu_led->profile = apu2_led_profile;
- apu_led->platform = APU2_LED_PLATFORM;
- apu_led->num_led_instances = ARRAY_SIZE(apu2_led_profile);
- apu_led->iosize = APU2_IOSIZE;
- } else if (dmi_match(DMI_BOARD_NAME, "APU3") ||
- dmi_match(DMI_BOARD_NAME, "apu3") ||
- dmi_match(DMI_BOARD_NAME, "PC Engines apu3")) {
- apu_led->profile = apu3_led_profile;
- /* Otherwise identical to APU2. */
- apu_led->platform = APU2_LED_PLATFORM;
- apu_led->num_led_instances = ARRAY_SIZE(apu3_led_profile);
- apu_led->iosize = APU2_IOSIZE;
- }
-
spin_lock_init(&apu_led->lock);
return apu_led_config(&pdev->dev, apu_led);
}
@@ -291,19 +172,9 @@ static int __init apu_led_init(void)
struct platform_device *pdev;
int err;
- if (!dmi_match(DMI_SYS_VENDOR, "PC Engines")) {
- pr_err("No PC Engines board detected\n");
- return -ENODEV;
- }
- if (!(dmi_match(DMI_PRODUCT_NAME, "APU") ||
- dmi_match(DMI_PRODUCT_NAME, "APU2") ||
- dmi_match(DMI_PRODUCT_NAME, "apu2") ||
- dmi_match(DMI_PRODUCT_NAME, "PC Engines apu2") ||
- dmi_match(DMI_PRODUCT_NAME, "APU3") ||
- dmi_match(DMI_PRODUCT_NAME, "apu3") ||
- dmi_match(DMI_PRODUCT_NAME, "PC Engines apu3"))) {
- pr_err("Unknown PC Engines board: %s\n",
- dmi_get_system_info(DMI_PRODUCT_NAME));
+ if (!(dmi_match(DMI_SYS_VENDOR, "PC Engines") &&
+ dmi_match(DMI_PRODUCT_NAME, "APU"))) {
+ pr_err("No PC Engines APUv1 board detected. For APUv2,3 support, enable CONFIG_PCENGINES_APU2\n");
return -ENODEV;
}
@@ -326,7 +197,7 @@ static void __exit apu_led_exit(void)
{
int i;
- for (i = 0; i < apu_led->num_led_instances; i++)
+ for (i = 0; i < ARRAY_SIZE(apu1_led_profile); i++)
led_classdev_unregister(&apu_led->pled[i].cdev);
platform_device_unregister(apu_led->pdev);
@@ -337,6 +208,6 @@ module_init(apu_led_init);
module_exit(apu_led_exit);
MODULE_AUTHOR("Alan Mizrahi");
-MODULE_DESCRIPTION("PC Engines APU family LED driver");
+MODULE_DESCRIPTION("PC Engines APU1 front LED driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:leds_apu");
diff --git a/drivers/leds/leds-as3645a.c b/drivers/leds/leds-as3645a.c
index 14ab6b0e4de9..b7e0ae1af8fa 100644
--- a/drivers/leds/leds-as3645a.c
+++ b/drivers/leds/leds-as3645a.c
@@ -124,11 +124,6 @@ struct as3645a_config {
u32 peak;
};
-struct as3645a_names {
- char flash[32];
- char indicator[32];
-};
-
struct as3645a {
struct i2c_client *client;
@@ -484,12 +479,10 @@ static int as3645a_detect(struct as3645a *flash)
}
static int as3645a_parse_node(struct as3645a *flash,
- struct as3645a_names *names,
struct fwnode_handle *fwnode)
{
struct as3645a_config *cfg = &flash->cfg;
struct fwnode_handle *child;
- const char *name;
int rval;
fwnode_for_each_child_node(fwnode, child) {
@@ -517,17 +510,6 @@ static int as3645a_parse_node(struct as3645a *flash,
return -ENODEV;
}
- rval = fwnode_property_read_string(flash->flash_node, "label", &name);
- if (!rval) {
- strlcpy(names->flash, name, sizeof(names->flash));
- } else if (is_of_node(fwnode)) {
- snprintf(names->flash, sizeof(names->flash),
- "%pOFn:flash", to_of_node(fwnode));
- } else {
- dev_err(&flash->client->dev, "flash node has no label!\n");
- return -EINVAL;
- }
-
rval = fwnode_property_read_u32(flash->flash_node, "flash-timeout-us",
&cfg->flash_timeout_us);
if (rval < 0) {
@@ -565,17 +547,6 @@ static int as3645a_parse_node(struct as3645a *flash,
goto out_err;
}
- rval = fwnode_property_read_string(flash->indicator_node, "label",
- &name);
- if (!rval) {
- strlcpy(names->indicator, name, sizeof(names->indicator));
- } else if (is_of_node(fwnode)) {
- snprintf(names->indicator, sizeof(names->indicator),
- "%pOFn:indicator", to_of_node(fwnode));
- } else {
- dev_err(&flash->client->dev, "indicator node has no label!\n");
- return -EINVAL;
- }
rval = fwnode_property_read_u32(flash->indicator_node,
"led-max-microamp",
@@ -595,21 +566,25 @@ out_err:
return rval;
}
-static int as3645a_led_class_setup(struct as3645a *flash,
- struct as3645a_names *names)
+static int as3645a_led_class_setup(struct as3645a *flash)
{
struct led_classdev *fled_cdev = &flash->fled.led_cdev;
struct led_classdev *iled_cdev = &flash->iled_cdev;
+ struct led_init_data init_data = {};
struct led_flash_setting *cfg;
int rval;
- iled_cdev->name = names->indicator;
iled_cdev->brightness_set_blocking = as3645a_set_indicator_brightness;
iled_cdev->max_brightness =
flash->cfg.indicator_max_ua / AS_INDICATOR_INTENSITY_STEP;
iled_cdev->flags = LED_CORE_SUSPENDRESUME;
- rval = led_classdev_register(&flash->client->dev, iled_cdev);
+ init_data.fwnode = flash->indicator_node;
+ init_data.devicename = AS_NAME;
+ init_data.default_label = "indicator";
+
+ rval = led_classdev_register_ext(&flash->client->dev, iled_cdev,
+ &init_data);
if (rval < 0)
return rval;
@@ -627,7 +602,6 @@ static int as3645a_led_class_setup(struct as3645a *flash,
flash->fled.ops = &as3645a_led_flash_ops;
- fled_cdev->name = names->flash;
fled_cdev->brightness_set_blocking = as3645a_set_assist_brightness;
/* Value 0 is off in LED class. */
fled_cdev->max_brightness =
@@ -635,15 +609,23 @@ static int as3645a_led_class_setup(struct as3645a *flash,
flash->cfg.assist_max_ua) + 1;
fled_cdev->flags = LED_DEV_CAP_FLASH | LED_CORE_SUSPENDRESUME;
- rval = led_classdev_flash_register(&flash->client->dev, &flash->fled);
- if (rval) {
- led_classdev_unregister(iled_cdev);
- dev_err(&flash->client->dev,
- "led_classdev_flash_register() failed, error %d\n",
- rval);
- }
+ init_data.fwnode = flash->flash_node;
+ init_data.devicename = AS_NAME;
+ init_data.default_label = "flash";
+
+ rval = led_classdev_flash_register_ext(&flash->client->dev,
+ &flash->fled, &init_data);
+ if (rval)
+ goto out_err;
return rval;
+
+out_err:
+ led_classdev_unregister(iled_cdev);
+ dev_err(&flash->client->dev,
+ "led_classdev_flash_register() failed, error %d\n",
+ rval);
+ return rval;
}
static int as3645a_v4l2_setup(struct as3645a *flash)
@@ -667,8 +649,9 @@ static int as3645a_v4l2_setup(struct as3645a *flash)
},
};
- strlcpy(cfg.dev_name, led->name, sizeof(cfg.dev_name));
- strlcpy(cfgind.dev_name, flash->iled_cdev.name, sizeof(cfg.dev_name));
+ strlcpy(cfg.dev_name, led->dev->kobj.name, sizeof(cfg.dev_name));
+ strlcpy(cfgind.dev_name, flash->iled_cdev.dev->kobj.name,
+ sizeof(cfgind.dev_name));
flash->vf = v4l2_flash_init(
&flash->client->dev, flash->flash_node, &flash->fled, NULL,
@@ -689,7 +672,6 @@ static int as3645a_v4l2_setup(struct as3645a *flash)
static int as3645a_probe(struct i2c_client *client)
{
- struct as3645a_names names;
struct as3645a *flash;
int rval;
@@ -702,7 +684,7 @@ static int as3645a_probe(struct i2c_client *client)
flash->client = client;
- rval = as3645a_parse_node(flash, &names, dev_fwnode(&client->dev));
+ rval = as3645a_parse_node(flash, dev_fwnode(&client->dev));
if (rval < 0)
return rval;
@@ -717,7 +699,7 @@ static int as3645a_probe(struct i2c_client *client)
if (rval)
goto out_mutex_destroy;
- rval = as3645a_led_class_setup(flash, &names);
+ rval = as3645a_led_class_setup(flash);
if (rval)
goto out_mutex_destroy;
diff --git a/drivers/leds/leds-cr0014114.c b/drivers/leds/leds-cr0014114.c
index 0e4262462cb9..2da448ae718e 100644
--- a/drivers/leds/leds-cr0014114.c
+++ b/drivers/leds/leds-cr0014114.c
@@ -8,7 +8,6 @@
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <linux/workqueue.h>
-#include <uapi/linux/uleds.h>
/*
* CR0014114 SPI protocol descrtiption:
@@ -40,8 +39,9 @@
#define CR_FW_DELAY_MSEC 10
#define CR_RECOUNT_DELAY (HZ * 3600)
+#define CR_DEV_NAME "cr0014114"
+
struct cr0014114_led {
- char name[LED_MAX_NAME_SIZE];
struct cr0014114 *priv;
struct led_classdev ldev;
u8 brightness;
@@ -167,8 +167,7 @@ static int cr0014114_set_sync(struct led_classdev *ldev,
struct cr0014114_led,
ldev);
- dev_dbg(led->priv->dev, "Set brightness of %s to %d\n",
- led->name, brightness);
+ dev_dbg(led->priv->dev, "Set brightness to %d\n", brightness);
mutex_lock(&led->priv->lock);
led->brightness = (u8)brightness;
@@ -183,42 +182,32 @@ static int cr0014114_probe_dt(struct cr0014114 *priv)
size_t i = 0;
struct cr0014114_led *led;
struct fwnode_handle *child;
- struct device_node *np;
+ struct led_init_data init_data = {};
int ret;
- const char *str;
device_for_each_child_node(priv->dev, child) {
- np = to_of_node(child);
led = &priv->leds[i];
- ret = fwnode_property_read_string(child, "label", &str);
- if (ret)
- snprintf(led->name, sizeof(led->name),
- "cr0014114::");
- else
- snprintf(led->name, sizeof(led->name),
- "cr0014114:%s", str);
-
fwnode_property_read_string(child, "linux,default-trigger",
&led->ldev.default_trigger);
led->priv = priv;
- led->ldev.name = led->name;
led->ldev.max_brightness = CR_MAX_BRIGHTNESS;
led->ldev.brightness_set_blocking = cr0014114_set_sync;
- ret = devm_of_led_classdev_register(priv->dev, np,
- &led->ldev);
+ init_data.fwnode = child;
+ init_data.devicename = CR_DEV_NAME;
+ init_data.default_label = ":";
+
+ ret = devm_led_classdev_register_ext(priv->dev, &led->ldev,
+ &init_data);
if (ret) {
dev_err(priv->dev,
- "failed to register LED device %s, err %d",
- led->name, ret);
+ "failed to register LED device, err %d", ret);
fwnode_handle_put(child);
return ret;
}
- led->ldev.dev->of_node = np;
-
i++;
}
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index bdc98ddca1dc..a5c73f3d5f79 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -73,11 +73,11 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
static int create_gpio_led(const struct gpio_led *template,
struct gpio_led_data *led_dat, struct device *parent,
- struct device_node *np, gpio_blink_set_t blink_set)
+ struct fwnode_handle *fwnode, gpio_blink_set_t blink_set)
{
+ struct led_init_data init_data = {};
int ret, state;
- led_dat->cdev.name = template->name;
led_dat->cdev.default_trigger = template->default_trigger;
led_dat->can_sleep = gpiod_cansleep(led_dat->gpiod);
if (!led_dat->can_sleep)
@@ -108,7 +108,16 @@ static int create_gpio_led(const struct gpio_led *template,
if (ret < 0)
return ret;
- return devm_of_led_classdev_register(parent, np, &led_dat->cdev);
+ if (template->name) {
+ led_dat->cdev.name = template->name;
+ ret = devm_led_classdev_register(parent, &led_dat->cdev);
+ } else {
+ init_data.fwnode = fwnode;
+ ret = devm_led_classdev_register_ext(parent, &led_dat->cdev,
+ &init_data);
+ }
+
+ return ret;
}
struct gpio_leds_priv {
@@ -141,15 +150,6 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
struct gpio_led_data *led_dat = &priv->leds[priv->num_leds];
struct gpio_led led = {};
const char *state = NULL;
- struct device_node *np = to_of_node(child);
-
- ret = fwnode_property_read_string(child, "label", &led.name);
- if (ret && IS_ENABLED(CONFIG_OF) && np)
- led.name = np->name;
- if (!led.name) {
- fwnode_handle_put(child);
- return ERR_PTR(-EINVAL);
- }
led.gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, child,
GPIOD_ASIS,
@@ -181,7 +181,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
if (fwnode_property_present(child, "panic-indicator"))
led.panic_indicator = 1;
- ret = create_gpio_led(&led, led_dat, dev, np, NULL);
+ ret = create_gpio_led(&led, led_dat, dev, child, NULL);
if (ret < 0) {
fwnode_handle_put(child);
return ERR_PTR(ret);
diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
index 2d077b8edd0e..ca6634b8683c 100644
--- a/drivers/leds/leds-is31fl319x.c
+++ b/drivers/leds/leds-is31fl319x.c
@@ -333,12 +333,11 @@ static int is31fl319x_probe(struct i2c_client *client,
{
struct is31fl319x_chip *is31;
struct device *dev = &client->dev;
- struct i2c_adapter *adapter = to_i2c_adapter(dev->parent);
int err;
int i = 0;
u32 aggregated_led_microamp = IS31FL319X_CURRENT_MAX;
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -EIO;
is31 = devm_kzalloc(&client->dev, sizeof(*is31), GFP_KERNEL);
diff --git a/drivers/leds/leds-is31fl32xx.c b/drivers/leds/leds-is31fl32xx.c
index 6fbab70dfb04..6f29b8943913 100644
--- a/drivers/leds/leds-is31fl32xx.c
+++ b/drivers/leds/leds-is31fl32xx.c
@@ -324,12 +324,6 @@ static int is31fl32xx_init_regs(struct is31fl32xx_priv *priv)
return 0;
}
-static inline size_t sizeof_is31fl32xx_priv(int num_leds)
-{
- return sizeof(struct is31fl32xx_priv) +
- (sizeof(struct is31fl32xx_led_data) * num_leds);
-}
-
static int is31fl32xx_parse_child_dt(const struct device *dev,
const struct device_node *child,
struct is31fl32xx_led_data *led_data)
@@ -450,7 +444,7 @@ static int is31fl32xx_probe(struct i2c_client *client,
if (!count)
return -EINVAL;
- priv = devm_kzalloc(dev, sizeof_is31fl32xx_priv(count),
+ priv = devm_kzalloc(dev, struct_size(priv, leds, count),
GFP_KERNEL);
if (!priv)
return -ENOMEM;
diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c
index f63918206bfb..670efee9b131 100644
--- a/drivers/leds/leds-ktd2692.c
+++ b/drivers/leds/leds-ktd2692.c
@@ -19,7 +19,7 @@
/* Value related the movie mode */
#define KTD2692_MOVIE_MODE_CURRENT_LEVELS 16
#define KTD2692_MM_TO_FL_RATIO(x) ((x) / 3)
-#define KTD2962_MM_MIN_CURR_THRESHOLD_SCALE 8
+#define KTD2692_MM_MIN_CURR_THRESHOLD_SCALE 8
/* Value related the flash mode */
#define KTD2692_FLASH_MODE_TIMEOUT_LEVELS 8
@@ -250,7 +250,7 @@ static void ktd2692_setup(struct ktd2692_context *led)
ktd2692_expresswire_reset(led);
gpiod_direction_output(led->aux_gpio, KTD2692_LOW);
- ktd2692_expresswire_write(led, (KTD2962_MM_MIN_CURR_THRESHOLD_SCALE - 1)
+ ktd2692_expresswire_write(led, (KTD2692_MM_MIN_CURR_THRESHOLD_SCALE - 1)
| KTD2692_REG_MM_MIN_CURR_THRESHOLD_BASE);
ktd2692_expresswire_write(led, KTD2692_FLASH_MODE_CURR_PERCENT(45)
| KTD2692_REG_FLASH_CURRENT_BASE);
diff --git a/drivers/leds/leds-lm3532.c b/drivers/leds/leds-lm3532.c
index 180895b83b88..0507c6575c08 100644
--- a/drivers/leds/leds-lm3532.c
+++ b/drivers/leds/leds-lm3532.c
@@ -23,11 +23,11 @@
#define LM3532_REG_PWM_B_CFG 0x14
#define LM3532_REG_PWM_C_CFG 0x15
#define LM3532_REG_ZONE_CFG_A 0x16
-#define LM3532_REG_CTRL_A_BRT 0x17
+#define LM3532_REG_CTRL_A_FS_CURR 0x17
#define LM3532_REG_ZONE_CFG_B 0x18
-#define LM3532_REG_CTRL_B_BRT 0x19
+#define LM3532_REG_CTRL_B_FS_CURR 0x19
#define LM3532_REG_ZONE_CFG_C 0x1a
-#define LM3532_REG_CTRL_C_BRT 0x1b
+#define LM3532_REG_CTRL_C_FS_CURR 0x1b
#define LM3532_REG_ENABLE 0x1d
#define LM3532_ALS_CONFIG 0x23
#define LM3532_REG_ZN_0_HI 0x60
@@ -38,9 +38,12 @@
#define LM3532_REG_ZN_2_LO 0x65
#define LM3532_REG_ZN_3_HI 0x66
#define LM3532_REG_ZN_3_LO 0x67
+#define LM3532_REG_ZONE_TRGT_A 0x70
+#define LM3532_REG_ZONE_TRGT_B 0x75
+#define LM3532_REG_ZONE_TRGT_C 0x7a
#define LM3532_REG_MAX 0x7e
-/* Contorl Enable */
+/* Control Enable */
#define LM3532_CTRL_A_ENABLE BIT(0)
#define LM3532_CTRL_B_ENABLE BIT(1)
#define LM3532_CTRL_C_ENABLE BIT(2)
@@ -86,6 +89,10 @@
#define LM3532_NUM_AVG_VALS 8
#define LM3532_NUM_IMP_VALS 32
+#define LM3532_FS_CURR_MIN 5000
+#define LM3532_FS_CURR_MAX 29800
+#define LM3532_FS_CURR_STEP 800
+
/*
* struct lm3532_als_data
* @config - value of ALS configuration register
@@ -116,8 +123,11 @@ struct lm3532_als_data {
* @priv - Pointer the device data structure
* @control_bank - Control bank the LED is associated to
* @mode - Mode of the LED string
+ * @ctrl_brt_pointer - Zone target register that controls the sink
* @num_leds - Number of LED strings are supported in this array
+ * @full_scale_current - The full-scale current setting for the current sink.
* @led_strings - The LED strings supported in this array
+ * @enabled - Enabled status
* @label - LED label
*/
struct lm3532_led {
@@ -126,7 +136,10 @@ struct lm3532_led {
int control_bank;
int mode;
+ int ctrl_brt_pointer;
int num_leds;
+ int full_scale_current;
+ int enabled:1;
u32 led_strings[LM3532_MAX_CONTROL_BANKS];
char label[LED_MAX_NAME_SIZE];
};
@@ -168,11 +181,11 @@ static const struct reg_default lm3532_reg_defs[] = {
{LM3532_REG_PWM_B_CFG, 0x82},
{LM3532_REG_PWM_C_CFG, 0x82},
{LM3532_REG_ZONE_CFG_A, 0xf1},
- {LM3532_REG_CTRL_A_BRT, 0xf3},
+ {LM3532_REG_CTRL_A_FS_CURR, 0xf3},
{LM3532_REG_ZONE_CFG_B, 0xf1},
- {LM3532_REG_CTRL_B_BRT, 0xf3},
+ {LM3532_REG_CTRL_B_FS_CURR, 0xf3},
{LM3532_REG_ZONE_CFG_C, 0xf1},
- {LM3532_REG_CTRL_C_BRT, 0xf3},
+ {LM3532_REG_CTRL_C_FS_CURR, 0xf3},
{LM3532_REG_ENABLE, 0xf8},
{LM3532_ALS_CONFIG, 0x44},
{LM3532_REG_ZN_0_HI, 0x35},
@@ -195,7 +208,7 @@ static const struct regmap_config lm3532_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
-const static int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
+static const int als_imp_table[LM3532_NUM_IMP_VALS] = {37000, 18500, 12330,
92500, 7400, 6170, 5290,
4630, 4110, 3700, 3360,
3080, 2850, 2640, 2440,
@@ -252,7 +265,7 @@ static int lm3532_get_index(const int table[], int size, int value)
return -EINVAL;
}
-const static int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
+static const int als_avrg_table[LM3532_NUM_AVG_VALS] = {17920, 35840, 71680,
1433360, 286720, 573440,
1146880, 2293760};
static int lm3532_get_als_avg_index(int avg_time)
@@ -267,7 +280,7 @@ static int lm3532_get_als_avg_index(int avg_time)
avg_time);
}
-const static int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
+static const int ramp_table[LM3532_NUM_RAMP_VALS] = { 8, 1024, 2048, 4096, 8192,
16384, 32768, 65536};
static int lm3532_get_ramp_index(int ramp_time)
{
@@ -281,11 +294,15 @@ static int lm3532_get_ramp_index(int ramp_time)
ramp_time);
}
+/* Caller must take care of locking */
static int lm3532_led_enable(struct lm3532_led *led_data)
{
int ctrl_en_val = BIT(led_data->control_bank);
int ret;
+ if (led_data->enabled)
+ return 0;
+
ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
ctrl_en_val, ctrl_en_val);
if (ret) {
@@ -293,22 +310,38 @@ static int lm3532_led_enable(struct lm3532_led *led_data)
return ret;
}
- return regulator_enable(led_data->priv->regulator);
+ ret = regulator_enable(led_data->priv->regulator);
+ if (ret < 0)
+ return ret;
+
+ led_data->enabled = 1;
+
+ return 0;
}
+/* Caller must take care of locking */
static int lm3532_led_disable(struct lm3532_led *led_data)
{
int ctrl_en_val = BIT(led_data->control_bank);
int ret;
+ if (!led_data->enabled)
+ return 0;
+
ret = regmap_update_bits(led_data->priv->regmap, LM3532_REG_ENABLE,
- ctrl_en_val, ~ctrl_en_val);
+ ctrl_en_val, 0);
if (ret) {
dev_err(led_data->priv->dev, "Failed to set ctrl:%d\n", ret);
return ret;
}
- return regulator_disable(led_data->priv->regulator);
+ ret = regulator_disable(led_data->priv->regulator);
+ if (ret < 0)
+ return ret;
+
+ led_data->enabled = 0;
+
+ return 0;
}
static int lm3532_brightness_set(struct led_classdev *led_cdev,
@@ -321,7 +354,7 @@ static int lm3532_brightness_set(struct led_classdev *led_cdev,
mutex_lock(&led->priv->lock);
- if (led->mode == LM3532_BL_MODE_ALS) {
+ if (led->mode == LM3532_ALS_CTRL) {
if (brt_val > LED_OFF)
ret = lm3532_led_enable(led);
else
@@ -339,8 +372,8 @@ static int lm3532_brightness_set(struct led_classdev *led_cdev,
if (ret)
goto unlock;
- brightness_reg = LM3532_REG_CTRL_A_BRT + led->control_bank * 2;
- brt_val = brt_val / LM3532_BRT_VAL_ADJUST;
+ brightness_reg = LM3532_REG_ZONE_TRGT_A + led->control_bank * 5 +
+ (led->ctrl_brt_pointer >> 2);
ret = regmap_write(led->priv->regmap, brightness_reg, brt_val);
@@ -356,8 +389,43 @@ static int lm3532_init_registers(struct lm3532_led *led)
unsigned int output_cfg_val = 0;
unsigned int output_cfg_shift = 0;
unsigned int output_cfg_mask = 0;
+ unsigned int brightness_config_reg;
+ unsigned int brightness_config_val;
+ int fs_current_reg;
+ int fs_current_val;
int ret, i;
+ if (drvdata->enable_gpio)
+ gpiod_direction_output(drvdata->enable_gpio, 1);
+
+ brightness_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
+ /*
+ * This could be hard coded to the default value but the control
+ * brightness register may have changed during boot.
+ */
+ ret = regmap_read(drvdata->regmap, brightness_config_reg,
+ &led->ctrl_brt_pointer);
+ if (ret)
+ return ret;
+
+ led->ctrl_brt_pointer &= LM3532_ZONE_MASK;
+ brightness_config_val = led->ctrl_brt_pointer | led->mode;
+ ret = regmap_write(drvdata->regmap, brightness_config_reg,
+ brightness_config_val);
+ if (ret)
+ return ret;
+
+ if (led->full_scale_current) {
+ fs_current_reg = LM3532_REG_CTRL_A_FS_CURR + led->control_bank * 2;
+ fs_current_val = (led->full_scale_current - LM3532_FS_CURR_MIN) /
+ LM3532_FS_CURR_STEP;
+
+ ret = regmap_write(drvdata->regmap, fs_current_reg,
+ fs_current_val);
+ if (ret)
+ return ret;
+ }
+
for (i = 0; i < led->num_leds; i++) {
output_cfg_shift = led->led_strings[i] * 2;
output_cfg_val |= (led->control_bank << output_cfg_shift);
@@ -382,7 +450,6 @@ static int lm3532_als_configure(struct lm3532_data *priv,
struct lm3532_als_data *als = priv->als_data;
u32 als_vmin, als_vmax, als_vstep;
int zone_reg = LM3532_REG_ZN_0_HI;
- int brightnes_config_reg;
int ret;
int i;
@@ -411,14 +478,7 @@ static int lm3532_als_configure(struct lm3532_data *priv,
als->config = (als->als_avrg_time | (LM3532_ENABLE_ALS) |
(als->als_input_mode << LM3532_ALS_SEL_SHIFT));
- ret = regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
- if (ret)
- return ret;
-
- brightnes_config_reg = LM3532_REG_ZONE_CFG_A + led->control_bank * 2;
-
- return regmap_update_bits(priv->regmap, brightnes_config_reg,
- LM3532_I2C_CTRL, LM3532_ALS_CTRL);
+ return regmap_write(priv->regmap, LM3532_ALS_CONFIG, als->config);
}
static int lm3532_parse_als(struct lm3532_data *priv)
@@ -541,18 +601,27 @@ static int lm3532_parse_node(struct lm3532_data *priv)
goto child_out;
}
+ if (fwnode_property_present(child, "led-max-microamp") &&
+ fwnode_property_read_u32(child, "led-max-microamp",
+ &led->full_scale_current))
+ dev_err(&priv->client->dev,
+ "Failed getting led-max-microamp\n");
+ else
+ led->full_scale_current = min(led->full_scale_current,
+ LM3532_FS_CURR_MAX);
+
if (led->mode == LM3532_BL_MODE_ALS) {
+ led->mode = LM3532_ALS_CTRL;
ret = lm3532_parse_als(priv);
if (ret)
dev_err(&priv->client->dev, "Failed to parse als\n");
else
lm3532_als_configure(priv, led);
+ } else {
+ led->mode = LM3532_I2C_CTRL;
}
- led->num_leds = fwnode_property_read_u32_array(child,
- "led-sources",
- NULL, 0);
-
+ led->num_leds = fwnode_property_count_u32(child, "led-sources");
if (led->num_leds > LM3532_MAX_LED_STRINGS) {
dev_err(&priv->client->dev, "To many LED string defined\n");
continue;
@@ -590,7 +659,13 @@ static int lm3532_parse_node(struct lm3532_data *priv)
goto child_out;
}
- lm3532_init_registers(led);
+ ret = lm3532_init_registers(led);
+ if (ret) {
+ dev_err(&priv->client->dev, "register init err: %d\n",
+ ret);
+ fwnode_handle_put(child);
+ goto child_out;
+ }
i++;
}
@@ -637,9 +712,6 @@ static int lm3532_probe(struct i2c_client *client,
return ret;
}
- if (drvdata->enable_gpio)
- gpiod_direction_output(drvdata->enable_gpio, 1);
-
return ret;
}
diff --git a/drivers/leds/leds-lm3601x.c b/drivers/leds/leds-lm3601x.c
index 081aa71e43a3..b02972f1a341 100644
--- a/drivers/leds/leds-lm3601x.c
+++ b/drivers/leds/leds-lm3601x.c
@@ -10,7 +10,6 @@
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>
-#include <uapi/linux/uleds.h>
#define LM3601X_LED_IR 0x0
#define LM3601X_LED_TORCH 0x1
@@ -90,8 +89,6 @@ struct lm3601x_led {
struct regmap *regmap;
struct mutex lock;
- char led_name[LED_MAX_NAME_SIZE];
-
unsigned int flash_timeout;
unsigned int last_flag;
@@ -322,10 +319,12 @@ static const struct led_flash_ops flash_ops = {
.fault_get = lm3601x_flash_fault_get,
};
-static int lm3601x_register_leds(struct lm3601x_led *led)
+static int lm3601x_register_leds(struct lm3601x_led *led,
+ struct fwnode_handle *fwnode)
{
struct led_classdev *led_cdev;
struct led_flash_setting *setting;
+ struct led_init_data init_data = {};
led->fled_cdev.ops = &flash_ops;
@@ -342,20 +341,25 @@ static int lm3601x_register_leds(struct lm3601x_led *led)
setting->val = led->flash_current_max;
led_cdev = &led->fled_cdev.led_cdev;
- led_cdev->name = led->led_name;
led_cdev->brightness_set_blocking = lm3601x_brightness_set;
led_cdev->max_brightness = DIV_ROUND_UP(led->torch_current_max,
LM3601X_TORCH_REG_DIV);
led_cdev->flags |= LED_DEV_CAP_FLASH;
- return led_classdev_flash_register(&led->client->dev, &led->fled_cdev);
+ init_data.fwnode = fwnode;
+ init_data.devicename = led->client->name;
+ init_data.default_label = (led->led_mode == LM3601X_LED_TORCH) ?
+ "torch" : "infrared";
+
+ return led_classdev_flash_register_ext(&led->client->dev,
+ &led->fled_cdev, &init_data);
}
-static int lm3601x_parse_node(struct lm3601x_led *led)
+static int lm3601x_parse_node(struct lm3601x_led *led,
+ struct fwnode_handle **fwnode)
{
struct fwnode_handle *child = NULL;
int ret = -ENODEV;
- const char *name;
child = device_get_next_child_node(&led->client->dev, child);
if (!child) {
@@ -376,17 +380,6 @@ static int lm3601x_parse_node(struct lm3601x_led *led)
goto out_err;
}
- ret = fwnode_property_read_string(child, "label", &name);
- if (ret) {
- if (led->led_mode == LM3601X_LED_TORCH)
- name = "torch";
- else
- name = "infrared";
- }
-
- snprintf(led->led_name, sizeof(led->led_name),
- "%s:%s", led->client->name, name);
-
ret = fwnode_property_read_u32(child, "led-max-microamp",
&led->torch_current_max);
if (ret) {
@@ -411,6 +404,8 @@ static int lm3601x_parse_node(struct lm3601x_led *led)
goto out_err;
}
+ *fwnode = child;
+
out_err:
fwnode_handle_put(child);
return ret;
@@ -419,6 +414,7 @@ out_err:
static int lm3601x_probe(struct i2c_client *client)
{
struct lm3601x_led *led;
+ struct fwnode_handle *fwnode;
int ret;
led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL);
@@ -428,7 +424,7 @@ static int lm3601x_probe(struct i2c_client *client)
led->client = client;
i2c_set_clientdata(client, led);
- ret = lm3601x_parse_node(led);
+ ret = lm3601x_parse_node(led, &fwnode);
if (ret)
return -ENODEV;
@@ -442,7 +438,7 @@ static int lm3601x_probe(struct i2c_client *client)
mutex_init(&led->lock);
- return lm3601x_register_leds(led);
+ return lm3601x_register_leds(led, fwnode);
}
static int lm3601x_remove(struct i2c_client *client)
diff --git a/drivers/leds/leds-lm36274.c b/drivers/leds/leds-lm36274.c
index ed9dc857ec8f..836b60c9a2b8 100644
--- a/drivers/leds/leds-lm36274.c
+++ b/drivers/leds/leds-lm36274.c
@@ -90,9 +90,7 @@ static int lm36274_parse_dt(struct lm36274 *lm36274_data)
snprintf(label, sizeof(label),
"%s:%s", lm36274_data->pdev->name, name);
- lm36274_data->num_leds = fwnode_property_read_u32_array(child,
- "led-sources",
- NULL, 0);
+ lm36274_data->num_leds = fwnode_property_count_u32(child, "led-sources");
if (lm36274_data->num_leds <= 0)
return -ENODEV;
diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c
index 4f413a7c5f05..3d381f2f73d0 100644
--- a/drivers/leds/leds-lm3692x.c
+++ b/drivers/leds/leds-lm3692x.c
@@ -13,7 +13,6 @@
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
-#include <uapi/linux/uleds.h>
#define LM36922_MODEL 0
#define LM36923_MODEL 1
@@ -103,7 +102,6 @@
* @regmap - Devices register map
* @enable_gpio - VDDIO/EN gpio to enable communication interface
* @regulator - LED supply regulator pointer
- * @label - LED label
* @led_enable - LED sync to be enabled
* @model_id - Current device model ID enumerated
*/
@@ -114,7 +112,6 @@ struct lm3692x_led {
struct regmap *regmap;
struct gpio_desc *enable_gpio;
struct regulator *regulator;
- char label[LED_MAX_NAME_SIZE];
int led_enable;
int model_id;
};
@@ -325,7 +322,7 @@ out:
static int lm3692x_probe_dt(struct lm3692x_led *led)
{
struct fwnode_handle *child = NULL;
- const char *name;
+ struct led_init_data init_data = {};
int ret;
led->enable_gpio = devm_gpiod_get_optional(&led->client->dev,
@@ -350,30 +347,23 @@ static int lm3692x_probe_dt(struct lm3692x_led *led)
fwnode_property_read_string(child, "linux,default-trigger",
&led->led_dev.default_trigger);
- ret = fwnode_property_read_string(child, "label", &name);
- if (ret)
- snprintf(led->label, sizeof(led->label),
- "%s::", led->client->name);
- else
- snprintf(led->label, sizeof(led->label),
- "%s:%s", led->client->name, name);
-
ret = fwnode_property_read_u32(child, "reg", &led->led_enable);
if (ret) {
dev_err(&led->client->dev, "reg DT property missing\n");
return ret;
}
- led->led_dev.name = led->label;
+ init_data.fwnode = child;
+ init_data.devicename = led->client->name;
+ init_data.default_label = ":";
- ret = devm_led_classdev_register(&led->client->dev, &led->led_dev);
+ ret = devm_led_classdev_register_ext(&led->client->dev, &led->led_dev,
+ &init_data);
if (ret) {
dev_err(&led->client->dev, "led register err: %d\n", ret);
return ret;
}
- led->led_dev.dev->of_node = to_of_node(child);
-
return 0;
}
diff --git a/drivers/leds/leds-lm3697.c b/drivers/leds/leds-lm3697.c
index 54e0e35df824..b71711aff8a3 100644
--- a/drivers/leds/leds-lm3697.c
+++ b/drivers/leds/leds-lm3697.c
@@ -244,10 +244,7 @@ static int lm3697_probe_dt(struct lm3697 *priv)
led->lmu_data.lsb_brightness_reg = LM3697_CTRL_A_BRT_LSB +
led->control_bank * 2;
- led->num_leds = fwnode_property_read_u32_array(child,
- "led-sources",
- NULL, 0);
-
+ led->num_leds = fwnode_property_count_u32(child, "led-sources");
if (led->num_leds > LM3697_MAX_LED_STRINGS) {
dev_err(&priv->client->dev, "To many LED strings defined\n");
continue;
diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c
index 37632fc63741..edb57c42e8b1 100644
--- a/drivers/leds/leds-lp5562.c
+++ b/drivers/leds/leds-lp5562.c
@@ -260,7 +260,11 @@ static void lp5562_firmware_loaded(struct lp55xx_chip *chip)
{
const struct firmware *fw = chip->fw;
- if (fw->size > LP5562_PROGRAM_LENGTH) {
+ /*
+ * the firmware is encoded in ascii hex character, with 2 chars
+ * per byte
+ */
+ if (fw->size > (LP5562_PROGRAM_LENGTH * 2)) {
dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
fw->size);
return;
diff --git a/drivers/leds/leds-lp8860.c b/drivers/leds/leds-lp8860.c
index ed680d0c15b0..ac2f5d6272dc 100644
--- a/drivers/leds/leds-lp8860.c
+++ b/drivers/leds/leds-lp8860.c
@@ -18,7 +18,6 @@
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/slab.h>
-#include <uapi/linux/uleds.h>
#define LP8860_DISP_CL1_BRT_MSB 0x00
#define LP8860_DISP_CL1_BRT_LSB 0x01
@@ -83,6 +82,8 @@
#define LP8860_CLEAR_FAULTS 0x01
+#define LP8860_NAME "lp8860"
+
/**
* struct lp8860_led -
* @lock - Lock for reading/writing the device
@@ -92,7 +93,6 @@
* @eeprom_regmap - EEPROM register map
* @enable_gpio - VDDIO/EN gpio to enable communication interface
* @regulator - LED supply regulator pointer
- * @label - LED label
*/
struct lp8860_led {
struct mutex lock;
@@ -102,7 +102,6 @@ struct lp8860_led {
struct regmap *eeprom_regmap;
struct gpio_desc *enable_gpio;
struct regulator *regulator;
- char label[LED_MAX_NAME_SIZE];
};
struct lp8860_eeprom_reg {
@@ -383,25 +382,19 @@ static int lp8860_probe(struct i2c_client *client,
struct lp8860_led *led;
struct device_node *np = client->dev.of_node;
struct device_node *child_node;
- const char *name;
+ struct led_init_data init_data = {};
led = devm_kzalloc(&client->dev, sizeof(*led), GFP_KERNEL);
if (!led)
return -ENOMEM;
- for_each_available_child_of_node(np, child_node) {
- led->led_dev.default_trigger = of_get_property(child_node,
- "linux,default-trigger",
- NULL);
-
- ret = of_property_read_string(child_node, "label", &name);
- if (!ret)
- snprintf(led->label, sizeof(led->label), "%s:%s",
- id->name, name);
- else
- snprintf(led->label, sizeof(led->label),
- "%s::display_cluster", id->name);
- }
+ child_node = of_get_next_available_child(np, NULL);
+ if (!child_node)
+ return -EINVAL;
+
+ led->led_dev.default_trigger = of_get_property(child_node,
+ "linux,default-trigger",
+ NULL);
led->enable_gpio = devm_gpiod_get_optional(&client->dev,
"enable", GPIOD_OUT_LOW);
@@ -416,7 +409,6 @@ static int lp8860_probe(struct i2c_client *client,
led->regulator = NULL;
led->client = client;
- led->led_dev.name = led->label;
led->led_dev.brightness_set_blocking = lp8860_brightness_set;
mutex_init(&led->lock);
@@ -443,7 +435,12 @@ static int lp8860_probe(struct i2c_client *client,
if (ret)
return ret;
- ret = devm_led_classdev_register(&client->dev, &led->led_dev);
+ init_data.fwnode = of_fwnode_handle(child_node);
+ init_data.devicename = LP8860_NAME;
+ init_data.default_label = ":display_cluster";
+
+ ret = devm_led_classdev_register_ext(&client->dev, &led->led_dev,
+ &init_data);
if (ret) {
dev_err(&client->dev, "led register err: %d\n", ret);
return ret;
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index 83e8e58d81cb..c94995f0daa2 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -10,10 +10,10 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <uapi/linux/uleds.h>
+
+#define LED_LT3593_NAME "lt3593"
struct lt3593_led_data {
- char name[LED_MAX_NAME_SIZE];
struct led_classdev cdev;
struct gpio_desc *gpiod;
};
@@ -66,6 +66,7 @@ static int lt3593_led_probe(struct platform_device *pdev)
struct lt3593_led_data *led_data;
struct fwnode_handle *child;
int ret, state = LEDS_GPIO_DEFSTATE_OFF;
+ struct led_init_data init_data = {};
const char *tmp;
if (!dev->of_node)
@@ -86,14 +87,6 @@ static int lt3593_led_probe(struct platform_device *pdev)
child = device_get_next_child_node(dev, NULL);
- ret = fwnode_property_read_string(child, "label", &tmp);
- if (ret < 0)
- snprintf(led_data->name, sizeof(led_data->name),
- "lt3593::");
- else
- snprintf(led_data->name, sizeof(led_data->name),
- "lt3593:%s", tmp);
-
fwnode_property_read_string(child, "linux,default-trigger",
&led_data->cdev.default_trigger);
@@ -102,11 +95,14 @@ static int lt3593_led_probe(struct platform_device *pdev)
state = LEDS_GPIO_DEFSTATE_ON;
}
- led_data->cdev.name = led_data->name;
led_data->cdev.brightness_set_blocking = lt3593_led_set;
led_data->cdev.brightness = state ? LED_FULL : LED_OFF;
- ret = devm_led_classdev_register(dev, &led_data->cdev);
+ init_data.fwnode = child;
+ init_data.devicename = LED_LT3593_NAME;
+ init_data.default_label = ":";
+
+ ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data);
if (ret < 0) {
fwnode_handle_put(child);
return ret;
diff --git a/drivers/leds/leds-max77650.c b/drivers/leds/leds-max77650.c
index 8a8e5c65b157..4c2d0b3c6dad 100644
--- a/drivers/leds/leds-max77650.c
+++ b/drivers/leds/leds-max77650.c
@@ -62,7 +62,7 @@ static int max77650_led_brightness_set(struct led_classdev *cdev,
static int max77650_led_probe(struct platform_device *pdev)
{
- struct device_node *of_node, *child;
+ struct fwnode_handle *child;
struct max77650_led *leds, *led;
struct device *dev;
struct regmap *map;
@@ -71,10 +71,6 @@ static int max77650_led_probe(struct platform_device *pdev)
u32 reg;
dev = &pdev->dev;
- of_node = dev->of_node;
-
- if (!of_node)
- return -ENODEV;
leds = devm_kcalloc(dev, sizeof(*leds),
MAX77650_LED_NUM_LEDS, GFP_KERNEL);
@@ -85,14 +81,16 @@ static int max77650_led_probe(struct platform_device *pdev)
if (!map)
return -ENODEV;
- num_leds = of_get_child_count(of_node);
+ num_leds = device_get_child_node_count(dev);
if (!num_leds || num_leds > MAX77650_LED_NUM_LEDS)
return -ENODEV;
- for_each_child_of_node(of_node, child) {
- rv = of_property_read_u32(child, "reg", &reg);
- if (rv || reg >= MAX77650_LED_NUM_LEDS)
- return -EINVAL;
+ device_for_each_child_node(dev, child) {
+ rv = fwnode_property_read_u32(child, "reg", &reg);
+ if (rv || reg >= MAX77650_LED_NUM_LEDS) {
+ rv = -EINVAL;
+ goto err_node_put;
+ }
led = &leds[reg];
led->map = map;
@@ -101,35 +99,40 @@ static int max77650_led_probe(struct platform_device *pdev)
led->cdev.brightness_set_blocking = max77650_led_brightness_set;
led->cdev.max_brightness = MAX77650_LED_MAX_BRIGHTNESS;
- label = of_get_property(child, "label", NULL);
- if (!label) {
+ rv = fwnode_property_read_string(child, "label", &label);
+ if (rv) {
led->cdev.name = "max77650::";
} else {
led->cdev.name = devm_kasprintf(dev, GFP_KERNEL,
"max77650:%s", label);
- if (!led->cdev.name)
- return -ENOMEM;
+ if (!led->cdev.name) {
+ rv = -ENOMEM;
+ goto err_node_put;
+ }
}
- of_property_read_string(child, "linux,default-trigger",
- &led->cdev.default_trigger);
+ fwnode_property_read_string(child, "linux,default-trigger",
+ &led->cdev.default_trigger);
- rv = devm_of_led_classdev_register(dev, child, &led->cdev);
+ rv = devm_led_classdev_register(dev, &led->cdev);
if (rv)
- return rv;
+ goto err_node_put;
rv = regmap_write(map, led->regA, MAX77650_LED_A_DEFAULT);
if (rv)
- return rv;
+ goto err_node_put;
rv = regmap_write(map, led->regB, MAX77650_LED_B_DEFAULT);
if (rv)
- return rv;
+ goto err_node_put;
}
return regmap_write(map,
MAX77650_REG_CNFG_LED_TOP,
MAX77650_LED_TOP_DEFAULT);
+err_node_put:
+ fwnode_handle_put(child);
+ return rv;
}
static struct platform_driver max77650_led_driver = {
@@ -143,3 +146,4 @@ module_platform_driver(max77650_led_driver);
MODULE_DESCRIPTION("MAXIM 77650/77651 LED driver");
MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:max77650-led");
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index 10497a466775..14ef4ccdda3a 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -15,7 +15,48 @@
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/leds.h>
-#include <linux/platform_data/leds-kirkwood-netxbig.h>
+
+struct netxbig_gpio_ext {
+ unsigned int *addr;
+ int num_addr;
+ unsigned int *data;
+ int num_data;
+ unsigned int enable;
+};
+
+enum netxbig_led_mode {
+ NETXBIG_LED_OFF,
+ NETXBIG_LED_ON,
+ NETXBIG_LED_SATA,
+ NETXBIG_LED_TIMER1,
+ NETXBIG_LED_TIMER2,
+ NETXBIG_LED_MODE_NUM,
+};
+
+#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM
+
+struct netxbig_led_timer {
+ unsigned long delay_on;
+ unsigned long delay_off;
+ enum netxbig_led_mode mode;
+};
+
+struct netxbig_led {
+ const char *name;
+ const char *default_trigger;
+ int mode_addr;
+ int *mode_val;
+ int bright_addr;
+ int bright_max;
+};
+
+struct netxbig_led_platform_data {
+ struct netxbig_gpio_ext *gpio_ext;
+ struct netxbig_led_timer *timer;
+ int num_timer;
+ struct netxbig_led *leds;
+ int num_leds;
+};
/*
* GPIO extension bus.
@@ -306,7 +347,6 @@ static int create_netxbig_led(struct platform_device *pdev,
return devm_led_classdev_register(&pdev->dev, &led_dat->cdev);
}
-#ifdef CONFIG_OF_GPIO
static int gpio_ext_get_of_pdata(struct device *dev, struct device_node *np,
struct netxbig_gpio_ext *gpio_ext)
{
@@ -388,12 +428,14 @@ static int netxbig_leds_get_of_pdata(struct device *dev,
}
gpio_ext = devm_kzalloc(dev, sizeof(*gpio_ext), GFP_KERNEL);
- if (!gpio_ext)
+ if (!gpio_ext) {
+ of_node_put(gpio_ext_np);
return -ENOMEM;
+ }
ret = gpio_ext_get_of_pdata(dev, gpio_ext_np, gpio_ext);
+ of_node_put(gpio_ext_np);
if (ret)
return ret;
- of_node_put(gpio_ext_np);
pdata->gpio_ext = gpio_ext;
/* Timers (optional) */
@@ -522,30 +564,20 @@ static const struct of_device_id of_netxbig_leds_match[] = {
{},
};
MODULE_DEVICE_TABLE(of, of_netxbig_leds_match);
-#else
-static inline int
-netxbig_leds_get_of_pdata(struct device *dev,
- struct netxbig_led_platform_data *pdata)
-{
- return -ENODEV;
-}
-#endif /* CONFIG_OF_GPIO */
static int netxbig_led_probe(struct platform_device *pdev)
{
- struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct netxbig_led_platform_data *pdata;
struct netxbig_led_data *leds_data;
int i;
int ret;
- if (!pdata) {
- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
- ret = netxbig_leds_get_of_pdata(&pdev->dev, pdata);
- if (ret)
- return ret;
- }
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ ret = netxbig_leds_get_of_pdata(&pdev->dev, pdata);
+ if (ret)
+ return ret;
leds_data = devm_kcalloc(&pdev->dev,
pdata->num_leds, sizeof(*leds_data),
@@ -571,7 +603,7 @@ static struct platform_driver netxbig_led_driver = {
.probe = netxbig_led_probe,
.driver = {
.name = "leds-netxbig",
- .of_match_table = of_match_ptr(of_netxbig_leds_match),
+ .of_match_table = of_netxbig_leds_match,
},
};
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index f92e2c07c1c6..7c500dfdcfa3 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -245,7 +245,7 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
struct device_node *np = dev->of_node;
struct device_node *child;
struct ns2_led *led, *leds;
- int num_leds = 0;
+ int ret, num_leds = 0;
num_leds = of_get_child_count(np);
if (!num_leds)
@@ -259,16 +259,16 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
led = leds;
for_each_child_of_node(np, child) {
const char *string;
- int ret, i, num_modes;
+ int i, num_modes;
struct ns2_led_modval *modval;
ret = of_get_named_gpio(child, "cmd-gpio", 0);
if (ret < 0)
- return ret;
+ goto err_node_put;
led->cmd = ret;
ret = of_get_named_gpio(child, "slow-gpio", 0);
if (ret < 0)
- return ret;
+ goto err_node_put;
led->slow = ret;
ret = of_property_read_string(child, "label", &string);
led->name = (ret == 0) ? string : child->name;
@@ -281,7 +281,8 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
if (ret < 0 || ret % 3) {
dev_err(dev,
"Missing or malformed modes-map property\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_node_put;
}
num_modes = ret / 3;
@@ -289,8 +290,10 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
num_modes,
sizeof(struct ns2_led_modval),
GFP_KERNEL);
- if (!modval)
- return -ENOMEM;
+ if (!modval) {
+ ret = -ENOMEM;
+ goto err_node_put;
+ }
for (i = 0; i < num_modes; i++) {
of_property_read_u32_index(child,
@@ -314,6 +317,10 @@ ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
pdata->num_leds = num_leds;
return 0;
+
+err_node_put:
+ of_node_put(child);
+ return ret;
}
static const struct of_device_id of_ns2_leds_match[] = {
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 290871072d65..c7c7199e8ebd 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -16,7 +16,7 @@
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/leds-pca9532.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/of.h>
#include <linux/of_device.h>
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 48d068f80f11..8b6965a563e9 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -65,12 +65,6 @@ static int led_pwm_set(struct led_classdev *led_cdev,
return 0;
}
-static inline size_t sizeof_pwm_leds_priv(int num_leds)
-{
- return sizeof(struct led_pwm_priv) +
- (sizeof(struct led_pwm_data) * num_leds);
-}
-
static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
struct led_pwm *led, struct fwnode_handle *fwnode)
{
@@ -111,8 +105,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
if (!led_data->period && (led->pwm_period_ns > 0))
led_data->period = led->pwm_period_ns;
- ret = devm_of_led_classdev_register(dev, to_of_node(fwnode),
- &led_data->cdev);
+ ret = devm_led_classdev_register(dev, &led_data->cdev);
if (ret == 0) {
priv->num_leds++;
led_pwm_set(&led_data->cdev, led_data->cdev.brightness);
@@ -175,7 +168,7 @@ static int led_pwm_probe(struct platform_device *pdev)
if (!count)
return -EINVAL;
- priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count),
+ priv = devm_kzalloc(&pdev->dev, struct_size(priv, leds, count),
GFP_KERNEL);
if (!priv)
return -ENOMEM;
diff --git a/drivers/leds/leds-sc27xx-bltc.c b/drivers/leds/leds-sc27xx-bltc.c
index fecf27fb1cdc..0ede87420bfc 100644
--- a/drivers/leds/leds-sc27xx-bltc.c
+++ b/drivers/leds/leds-sc27xx-bltc.c
@@ -6,7 +6,6 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
-#include <uapi/linux/uleds.h>
/* PMIC global control register definition */
#define SC27XX_MODULE_EN0 0xc08
@@ -46,7 +45,7 @@
#define SC27XX_DELTA_T_MAX (SC27XX_LEDS_STEP * 255)
struct sc27xx_led {
- char name[LED_MAX_NAME_SIZE];
+ struct fwnode_handle *fwnode;
struct led_classdev ldev;
struct sc27xx_led_priv *priv;
u8 line;
@@ -249,19 +248,24 @@ static int sc27xx_led_register(struct device *dev, struct sc27xx_led_priv *priv)
for (i = 0; i < SC27XX_LEDS_MAX; i++) {
struct sc27xx_led *led = &priv->leds[i];
+ struct led_init_data init_data = {};
if (!led->active)
continue;
led->line = i;
led->priv = priv;
- led->ldev.name = led->name;
led->ldev.brightness_set_blocking = sc27xx_led_set;
led->ldev.pattern_set = sc27xx_led_pattern_set;
led->ldev.pattern_clear = sc27xx_led_pattern_clear;
led->ldev.default_trigger = "pattern";
- err = devm_led_classdev_register(dev, &led->ldev);
+ init_data.fwnode = led->fwnode;
+ init_data.devicename = "sc27xx";
+ init_data.default_label = ":";
+
+ err = devm_led_classdev_register_ext(dev, &led->ldev,
+ &init_data);
if (err)
return err;
}
@@ -274,7 +278,6 @@ static int sc27xx_led_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node, *child;
struct sc27xx_led_priv *priv;
- const char *str;
u32 base, count, reg;
int err;
@@ -316,15 +319,8 @@ static int sc27xx_led_probe(struct platform_device *pdev)
return -EINVAL;
}
+ priv->leds[reg].fwnode = of_fwnode_handle(child);
priv->leds[reg].active = true;
-
- err = of_property_read_string(child, "label", &str);
- if (err)
- snprintf(priv->leds[reg].name, LED_MAX_NAME_SIZE,
- "sc27xx::");
- else
- snprintf(priv->leds[reg].name, LED_MAX_NAME_SIZE,
- "sc27xx:%s", str);
}
err = sc27xx_led_register(dev, priv);
diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c
index e35dff0050f0..b58f3cafe16f 100644
--- a/drivers/leds/leds-syscon.c
+++ b/drivers/leds/leds-syscon.c
@@ -115,7 +115,7 @@ static int syscon_led_probe(struct platform_device *pdev)
}
sled->cdev.brightness_set = syscon_led_set;
- ret = led_classdev_register(dev, &sled->cdev);
+ ret = devm_led_classdev_register(dev, &sled->cdev);
if (ret < 0)
return ret;
diff --git a/drivers/leds/leds-ti-lmu-common.c b/drivers/leds/leds-ti-lmu-common.c
index adc7293004f1..d7f10ad721ba 100644
--- a/drivers/leds/leds-ti-lmu-common.c
+++ b/drivers/leds/leds-ti-lmu-common.c
@@ -11,10 +11,10 @@
#include <linux/leds-ti-lmu-common.h>
-const static int ramp_table[16] = {2048, 262000, 524000, 1049000, 2090000,
- 4194000, 8389000, 16780000, 33550000, 41940000,
- 50330000, 58720000, 67110000, 83880000,
- 100660000, 117440000};
+static const unsigned int ramp_table[16] = {2048, 262000, 524000, 1049000,
+ 2090000, 4194000, 8389000, 16780000, 33550000,
+ 41940000, 50330000, 58720000, 67110000,
+ 83880000, 100660000, 117440000};
static int ti_lmu_common_update_brightness(struct ti_lmu_bank *lmu_bank,
int brightness)
@@ -54,7 +54,7 @@ int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness)
}
EXPORT_SYMBOL(ti_lmu_common_set_brightness);
-static int ti_lmu_common_convert_ramp_to_index(unsigned int usec)
+static unsigned int ti_lmu_common_convert_ramp_to_index(unsigned int usec)
{
int size = ARRAY_SIZE(ramp_table);
int i;
@@ -78,7 +78,7 @@ static int ti_lmu_common_convert_ramp_to_index(unsigned int usec)
}
}
- return -EINVAL;
+ return 0;
}
int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank)
@@ -94,9 +94,6 @@ int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank)
ramp_down = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_down_usec);
}
- if (ramp_up < 0 || ramp_down < 0)
- return -EINVAL;
-
ramp = (ramp_up << 4) | ramp_down;
return regmap_write(regmap, lmu_bank->runtime_ramp_reg, ramp);
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 47b229469069..0b577cece8f7 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -27,5 +27,6 @@ void led_set_brightness_nosleep(struct led_classdev *led_cdev,
extern struct rw_semaphore leds_list_lock;
extern struct list_head leds_list;
extern struct list_head trigger_list;
+extern const char * const led_colors[LED_COLOR_ID_MAX];
#endif /* __LEDS_H_INCLUDED */
diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c
index 33cc99a1a16a..dc64679b1a92 100644
--- a/drivers/leds/trigger/ledtrig-gpio.c
+++ b/drivers/leds/trigger/ledtrig-gpio.c
@@ -131,10 +131,10 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
if (gpio_data->gpio == gpio)
return n;
- if (!gpio) {
- if (gpio_data->gpio != 0)
+ if (!gpio_is_valid(gpio)) {
+ if (gpio_is_valid(gpio_data->gpio))
free_irq(gpio_to_irq(gpio_data->gpio), led);
- gpio_data->gpio = 0;
+ gpio_data->gpio = gpio;
return n;
}
@@ -144,7 +144,7 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
if (ret) {
dev_err(dev, "request_irq failed with error %d\n", ret);
} else {
- if (gpio_data->gpio != 0)
+ if (gpio_is_valid(gpio_data->gpio))
free_irq(gpio_to_irq(gpio_data->gpio), led);
gpio_data->gpio = gpio;
/* After changing the GPIO, we need to update the LED. */
@@ -172,6 +172,8 @@ static int gpio_trig_activate(struct led_classdev *led)
return -ENOMEM;
gpio_data->led = led;
+ gpio_data->gpio = -ENOENT;
+
led_set_trigger_data(led, gpio_data);
return 0;
@@ -181,7 +183,7 @@ static void gpio_trig_deactivate(struct led_classdev *led)
{
struct gpio_trig_data *gpio_data = led_get_trigger_data(led);
- if (gpio_data->gpio != 0)
+ if (gpio_is_valid(gpio_data->gpio))
free_irq(gpio_to_irq(gpio_data->gpio), led);
kfree(gpio_data);
}