diff options
Diffstat (limited to 'drivers')
26 files changed, 414 insertions, 401 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 d54c8e4d8954..d231240c2047 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/of.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/timer.h> @@ -235,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->of_node = to_of_node(init_data->fwnode); if (ret) dev_warn(parent, "Led %s renamed to %s due to name collision", @@ -304,7 +322,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. @@ -349,14 +367,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; @@ -365,7 +384,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; @@ -376,7 +395,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..f0c1c403f678 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) { @@ -353,3 +367,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/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-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..646100724971 100644 --- a/drivers/leds/leds-lm3532.c +++ b/drivers/leds/leds-lm3532.c @@ -549,10 +549,7 @@ static int lm3532_parse_node(struct lm3532_data *priv) lm3532_als_configure(priv, led); } - 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; 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..5a14f9775b0e 100644 --- a/drivers/leds/leds-max77650.c +++ b/drivers/leds/leds-max77650.c @@ -91,8 +91,10 @@ static int max77650_led_probe(struct platform_device *pdev) for_each_child_of_node(of_node, child) { rv = of_property_read_u32(child, "reg", ®); - if (rv || reg >= MAX77650_LED_NUM_LEDS) - return -EINVAL; + if (rv || reg >= MAX77650_LED_NUM_LEDS) { + rv = -EINVAL; + goto err_node_put; + } led = &leds[reg]; led->map = map; @@ -107,29 +109,34 @@ static int max77650_led_probe(struct platform_device *pdev) } 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); - 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: + of_node_put(child); + return rv; } static struct platform_driver max77650_led_driver = { @@ -143,3 +150,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-pwm.c b/drivers/leds/leds-pwm.c index 48d068f80f11..d0e1f2710351 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -111,8 +111,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); 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.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 */ |