diff options
Diffstat (limited to 'drivers/leds')
29 files changed, 208 insertions, 126 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 93235f7378ba..9adc79406ff3 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -416,12 +416,12 @@ config LEDS_MC13783 depends on MFD_MC13XXX help This option enable support for on-chip LED drivers found - on Freescale Semiconductor MC13783/MC13892 PMIC. + on Freescale Semiconductor MC13783/MC13892/MC34708 PMIC. config LEDS_NS2 tristate "LED support for Network Space v2 GPIO LEDs" depends on LEDS_CLASS - depends on ARCH_KIRKWOOD + depends on ARCH_KIRKWOOD || MACH_KIRKWOOD default y help This option enable support for the dual-GPIO LED found on the @@ -431,7 +431,7 @@ config LEDS_NS2 config LEDS_NETXBIG tristate "LED support for Big Network series LEDs" depends on LEDS_CLASS - depends on ARCH_KIRKWOOD + depends on ARCH_KIRKWOOD || MACH_KIRKWOOD default y help This option enable support for LEDs found on the LaCie 2Big @@ -474,7 +474,7 @@ config LEDS_LM355x config LEDS_OT200 tristate "LED support for the Bachmann OT200" - depends on LEDS_CLASS && HAS_IOMEM + depends on LEDS_CLASS && HAS_IOMEM && (X86_32 || COMPILE_TEST) help This option enables support for the LEDs on the Bachmann OT200. Say Y to enable LEDs on the Bachmann OT200. diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index ce8921a753a3..71b40d3bf776 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -39,9 +39,11 @@ static void led_set_software_blink(struct led_classdev *led_cdev, led_cdev->blink_delay_on = delay_on; led_cdev->blink_delay_off = delay_off; - /* never on - don't blink */ - if (!delay_on) + /* never on - just set to off */ + if (!delay_on) { + __led_set_brightness(led_cdev, LED_OFF); return; + } /* never off - just set to brightness */ if (!delay_off) { diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index e387f41a9cb7..c3734f10fdd5 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -13,7 +13,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/list.h> #include <linux/spinlock.h> #include <linux/device.h> @@ -220,9 +219,12 @@ void led_trigger_unregister(struct led_trigger *trig) { struct led_classdev *led_cdev; + if (list_empty_careful(&trig->next_trig)) + return; + /* Remove from the list of led triggers */ down_write(&triggers_list_lock); - list_del(&trig->next_trig); + list_del_init(&trig->next_trig); up_write(&triggers_list_lock); /* Remove anyone actively using this trigger */ diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c index 5f588c0a376e..d1e1bca90d11 100644 --- a/drivers/leds/leds-88pm860x.c +++ b/drivers/leds/leds-88pm860x.c @@ -11,7 +11,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/i2c.h> diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c index 7e311a120b11..86b5bdb0c773 100644 --- a/drivers/leds/leds-adp5520.c +++ b/drivers/leds/leds-adp5520.c @@ -15,7 +15,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/workqueue.h> diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c index 6de216a89a0c..70c74a7f0dfe 100644 --- a/drivers/leds/leds-asic3.c +++ b/drivers/leds/leds-asic3.c @@ -7,7 +7,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/slab.h> diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c index 66d0a57db221..d0452b099aee 100644 --- a/drivers/leds/leds-blinkm.c +++ b/drivers/leds/leds-blinkm.c @@ -18,7 +18,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/jiffies.h> #include <linux/i2c.h> @@ -444,7 +443,7 @@ static void led_work(struct work_struct *work) { int ret; struct blinkm_led *led; - struct blinkm_data *data ; + struct blinkm_data *data; struct blinkm_work *blm_work = work_to_blmwork(work); led = blm_work->blinkm_led; diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c index d93e2455da5c..f58a354428e3 100644 --- a/drivers/leds/leds-clevo-mail.c +++ b/drivers/leds/leds-clevo-mail.c @@ -19,7 +19,7 @@ MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>"); MODULE_DESCRIPTION("Clevo mail LED driver"); MODULE_LICENSE("GPL"); -static bool __initdata nodetect; +static bool nodetect; module_param_named(nodetect, nodetect, bool, 0); MODULE_PARM_DESC(nodetect, "Skip DMI hardware detection"); @@ -153,7 +153,7 @@ static struct led_classdev clevo_mail_led = { .flags = LED_CORE_SUSPENDRESUME, }; -static int clevo_mail_led_probe(struct platform_device *pdev) +static int __init clevo_mail_led_probe(struct platform_device *pdev) { return led_classdev_register(&pdev->dev, &clevo_mail_led); } @@ -165,7 +165,6 @@ static int clevo_mail_led_remove(struct platform_device *pdev) } static struct platform_driver clevo_mail_led_driver = { - .probe = clevo_mail_led_probe, .remove = clevo_mail_led_remove, .driver = { .name = KBUILD_MODNAME, diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c index 8abcb66db01c..910339d86edf 100644 --- a/drivers/leds/leds-cobalt-qube.c +++ b/drivers/leds/leds-cobalt-qube.c @@ -3,7 +3,6 @@ * * Control the Cobalt Qube/RaQ front LED */ -#include <linux/init.h> #include <linux/io.h> #include <linux/ioport.h> #include <linux/leds.h> diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c index 2a4b87f8091a..35dffb100388 100644 --- a/drivers/leds/leds-da903x.c +++ b/drivers/leds/leds-da903x.c @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/workqueue.h> diff --git a/drivers/leds/leds-da9052.c b/drivers/leds/leds-da9052.c index 865d4faf874a..01486adc7f8b 100644 --- a/drivers/leds/leds-da9052.c +++ b/drivers/leds/leds-da9052.c @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/workqueue.h> diff --git a/drivers/leds/leds-fsg.c b/drivers/leds/leds-fsg.c index b4d5a44cc41b..2b4dc738dcd6 100644 --- a/drivers/leds/leds-fsg.c +++ b/drivers/leds/leds-fsg.c @@ -16,7 +16,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/module.h> diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 78b0e273a903..57ff20fecf57 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -11,7 +11,6 @@ * */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/gpio.h> #include <linux/leds.h> @@ -204,6 +203,9 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) led.default_state = LEDS_GPIO_DEFSTATE_OFF; } + if (of_get_property(child, "retain-state-suspended", NULL)) + led.retain_state_suspended = 1; + ret = create_gpio_led(&led, &priv->leds[priv->num_leds++], &pdev->dev, NULL); if (ret < 0) { @@ -224,6 +226,8 @@ static const struct of_device_id of_gpio_leds_match[] = { { .compatible = "gpio-leds", }, {}, }; + +MODULE_DEVICE_TABLE(of, of_gpio_leds_match); #else /* CONFIG_OF_GPIO */ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) { diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c index 366b6055e330..d61a98896c71 100644 --- a/drivers/leds/leds-hp6xx.c +++ b/drivers/leds/leds-hp6xx.c @@ -12,7 +12,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <asm/hd64461.h> diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c index 027ede73b80d..e2c642c1169b 100644 --- a/drivers/leds/leds-lm3533.c +++ b/drivers/leds/leds-lm3533.c @@ -12,7 +12,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/leds.h> #include <linux/mfd/core.h> #include <linux/mutex.h> diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 2ec34cfcedce..8ca197af2864 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c @@ -25,7 +25,6 @@ #include <linux/delay.h> #include <linux/firmware.h> #include <linux/i2c.h> -#include <linux/init.h> #include <linux/leds.h> #include <linux/module.h> #include <linux/mutex.h> diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index 4ade66a2d9d4..cb5ed82994ba 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c @@ -25,7 +25,6 @@ #include <linux/delay.h> #include <linux/firmware.h> #include <linux/i2c.h> -#include <linux/init.h> #include <linux/leds.h> #include <linux/module.h> #include <linux/mutex.h> diff --git a/drivers/leds/leds-lp5562.c b/drivers/leds/leds-lp5562.c index bf006f4e44a0..ca85724ab138 100644 --- a/drivers/leds/leds-lp5562.c +++ b/drivers/leds/leds-lp5562.c @@ -13,7 +13,6 @@ #include <linux/delay.h> #include <linux/firmware.h> #include <linux/i2c.h> -#include <linux/init.h> #include <linux/leds.h> #include <linux/module.h> #include <linux/mutex.h> @@ -347,9 +346,9 @@ static void lp5562_write_program_memory(struct lp55xx_chip *chip, /* check the size of program count */ static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn) { - return (ptn->size_r >= LP5562_PROGRAM_LENGTH || - ptn->size_g >= LP5562_PROGRAM_LENGTH || - ptn->size_b >= LP5562_PROGRAM_LENGTH); + return ptn->size_r >= LP5562_PROGRAM_LENGTH || + ptn->size_g >= LP5562_PROGRAM_LENGTH || + ptn->size_b >= LP5562_PROGRAM_LENGTH; } static int lp5562_run_predef_led_pattern(struct lp55xx_chip *chip, int mode) diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c index 3417e5be7b57..059f5b1f3553 100644 --- a/drivers/leds/leds-lt3593.c +++ b/drivers/leds/leds-lt3593.c @@ -17,7 +17,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/workqueue.h> diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c index ca87a1b4a0db..f1db88e25138 100644 --- a/drivers/leds/leds-mc13783.c +++ b/drivers/leds/leds-mc13783.c @@ -1,5 +1,5 @@ /* - * LEDs driver for Freescale MC13783/MC13892 + * LEDs driver for Freescale MC13783/MC13892/MC34708 * * Copyright (C) 2010 Philippe Rétornaz * @@ -17,57 +17,56 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> +#include <linux/of.h> #include <linux/workqueue.h> #include <linux/mfd/mc13xxx.h> -#define MC13XXX_REG_LED_CONTROL(x) (51 + (x)) - struct mc13xxx_led_devtype { int led_min; int led_max; int num_regs; + u32 ledctrl_base; }; struct mc13xxx_led { struct led_classdev cdev; struct work_struct work; - struct mc13xxx *master; enum led_brightness new_brightness; int id; + struct mc13xxx_leds *leds; }; struct mc13xxx_leds { + struct mc13xxx *master; struct mc13xxx_led_devtype *devtype; int num_leds; - struct mc13xxx_led led[0]; + struct mc13xxx_led *led; }; +static unsigned int mc13xxx_max_brightness(int id) +{ + if (id >= MC13783_LED_MD && id <= MC13783_LED_KP) + return 0x0f; + else if (id >= MC13783_LED_R1 && id <= MC13783_LED_B3) + return 0x1f; + + return 0x3f; +} + static void mc13xxx_led_work(struct work_struct *work) { struct mc13xxx_led *led = container_of(work, struct mc13xxx_led, work); - int reg, mask, value, bank, off, shift; + struct mc13xxx_leds *leds = led->leds; + unsigned int reg, bank, off, shift; switch (led->id) { case MC13783_LED_MD: - reg = MC13XXX_REG_LED_CONTROL(2); - shift = 9; - mask = 0x0f; - value = led->new_brightness >> 4; - break; case MC13783_LED_AD: - reg = MC13XXX_REG_LED_CONTROL(2); - shift = 13; - mask = 0x0f; - value = led->new_brightness >> 4; - break; case MC13783_LED_KP: - reg = MC13XXX_REG_LED_CONTROL(2); - shift = 17; - mask = 0x0f; - value = led->new_brightness >> 4; + reg = 2; + shift = 9 + (led->id - MC13783_LED_MD) * 4; break; case MC13783_LED_R1: case MC13783_LED_G1: @@ -80,44 +79,35 @@ static void mc13xxx_led_work(struct work_struct *work) case MC13783_LED_B3: off = led->id - MC13783_LED_R1; bank = off / 3; - reg = MC13XXX_REG_LED_CONTROL(3) + bank; + reg = 3 + bank; shift = (off - bank * 3) * 5 + 6; - value = led->new_brightness >> 3; - mask = 0x1f; break; case MC13892_LED_MD: - reg = MC13XXX_REG_LED_CONTROL(0); - shift = 3; - mask = 0x3f; - value = led->new_brightness >> 2; - break; case MC13892_LED_AD: - reg = MC13XXX_REG_LED_CONTROL(0); - shift = 15; - mask = 0x3f; - value = led->new_brightness >> 2; - break; case MC13892_LED_KP: - reg = MC13XXX_REG_LED_CONTROL(1); - shift = 3; - mask = 0x3f; - value = led->new_brightness >> 2; + reg = (led->id - MC13892_LED_MD) / 2; + shift = 3 + (led->id - MC13892_LED_MD) * 12; break; case MC13892_LED_R: case MC13892_LED_G: case MC13892_LED_B: off = led->id - MC13892_LED_R; bank = off / 2; - reg = MC13XXX_REG_LED_CONTROL(2) + bank; + reg = 2 + bank; shift = (off - bank * 2) * 12 + 3; - value = led->new_brightness >> 2; - mask = 0x3f; + break; + case MC34708_LED_R: + case MC34708_LED_G: + reg = 0; + shift = 3 + (led->id - MC34708_LED_R) * 12; break; default: BUG(); } - mc13xxx_reg_rmw(led->master, reg, mask << shift, value << shift); + mc13xxx_reg_rmw(leds->master, leds->devtype->ledctrl_base + reg, + mc13xxx_max_brightness(led->id) << shift, + led->new_brightness << shift); } static void mc13xxx_led_set(struct led_classdev *led_cdev, @@ -130,47 +120,121 @@ static void mc13xxx_led_set(struct led_classdev *led_cdev, schedule_work(&led->work); } -static int __init mc13xxx_led_probe(struct platform_device *pdev) +#ifdef CONFIG_OF +static struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt( + struct platform_device *pdev) { - struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct mc13xxx *mcdev = dev_get_drvdata(pdev->dev.parent); - struct mc13xxx_led_devtype *devtype = - (struct mc13xxx_led_devtype *)pdev->id_entry->driver_data; - struct mc13xxx_leds *leds; - int i, id, num_leds, ret = -ENODATA; - u32 reg, init_led = 0; + struct mc13xxx_leds *leds = platform_get_drvdata(pdev); + struct mc13xxx_leds_platform_data *pdata; + struct device_node *parent, *child; + struct device *dev = &pdev->dev; + int i = 0, ret = -ENODATA; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + + of_node_get(dev->parent->of_node); + + parent = of_find_node_by_name(dev->parent->of_node, "leds"); + if (!parent) + goto out_node_put; - if (!pdata) { - dev_err(&pdev->dev, "Missing platform data\n"); - return -ENODEV; + ret = of_property_read_u32_array(parent, "led-control", + pdata->led_control, + leds->devtype->num_regs); + if (ret) + goto out_node_put; + + pdata->num_leds = of_get_child_count(parent); + + pdata->led = devm_kzalloc(dev, pdata->num_leds * sizeof(*pdata->led), + GFP_KERNEL); + if (!pdata->led) { + ret = -ENOMEM; + goto out_node_put; } - num_leds = pdata->num_leds; + for_each_child_of_node(parent, child) { + const char *str; + u32 tmp; - if ((num_leds < 1) || - (num_leds > (devtype->led_max - devtype->led_min + 1))) { - dev_err(&pdev->dev, "Invalid LED count %d\n", num_leds); - return -EINVAL; + if (of_property_read_u32(child, "reg", &tmp)) + continue; + pdata->led[i].id = leds->devtype->led_min + tmp; + + if (!of_property_read_string(child, "label", &str)) + pdata->led[i].name = str; + if (!of_property_read_string(child, "linux,default-trigger", + &str)) + pdata->led[i].default_trigger = str; + + i++; } - leds = devm_kzalloc(&pdev->dev, num_leds * sizeof(struct mc13xxx_led) + - sizeof(struct mc13xxx_leds), GFP_KERNEL); + pdata->num_leds = i; + ret = i > 0 ? 0 : -ENODATA; + +out_node_put: + of_node_put(parent); + + return ret ? ERR_PTR(ret) : pdata; +} +#else +static inline struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt( + struct platform_device *pdev) +{ + return ERR_PTR(-ENOSYS); +} +#endif + +static int __init mc13xxx_led_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(dev); + struct mc13xxx *mcdev = dev_get_drvdata(dev->parent); + struct mc13xxx_led_devtype *devtype = + (struct mc13xxx_led_devtype *)pdev->id_entry->driver_data; + struct mc13xxx_leds *leds; + int i, id, ret = -ENODATA; + u32 init_led = 0; + + leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL); if (!leds) return -ENOMEM; leds->devtype = devtype; - leds->num_leds = num_leds; + leds->master = mcdev; platform_set_drvdata(pdev, leds); + if (dev->parent->of_node) { + pdata = mc13xxx_led_probe_dt(pdev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + } else if (!pdata) + return -ENODATA; + + leds->num_leds = pdata->num_leds; + + if ((leds->num_leds < 1) || + (leds->num_leds > (devtype->led_max - devtype->led_min + 1))) { + dev_err(dev, "Invalid LED count %d\n", leds->num_leds); + return -EINVAL; + } + + leds->led = devm_kzalloc(dev, leds->num_leds * sizeof(*leds->led), + GFP_KERNEL); + if (!leds->led) + return -ENOMEM; + for (i = 0; i < devtype->num_regs; i++) { - reg = pdata->led_control[i]; - WARN_ON(reg >= (1 << 24)); - ret = mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), reg); + ret = mc13xxx_reg_write(mcdev, leds->devtype->ledctrl_base + i, + pdata->led_control[i]); if (ret) return ret; } - for (i = 0; i < num_leds; i++) { + for (i = 0; i < leds->num_leds; i++) { const char *name, *trig; ret = -EINVAL; @@ -180,30 +244,29 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev) trig = pdata->led[i].default_trigger; if ((id > devtype->led_max) || (id < devtype->led_min)) { - dev_err(&pdev->dev, "Invalid ID %i\n", id); + dev_err(dev, "Invalid ID %i\n", id); break; } if (init_led & (1 << id)) { - dev_warn(&pdev->dev, - "LED %i already initialized\n", id); + dev_warn(dev, "LED %i already initialized\n", id); break; } init_led |= 1 << id; leds->led[i].id = id; - leds->led[i].master = mcdev; + leds->led[i].leds = leds; leds->led[i].cdev.name = name; leds->led[i].cdev.default_trigger = trig; + leds->led[i].cdev.flags = LED_CORE_SUSPENDRESUME; leds->led[i].cdev.brightness_set = mc13xxx_led_set; - leds->led[i].cdev.brightness = LED_OFF; + leds->led[i].cdev.max_brightness = mc13xxx_max_brightness(id); INIT_WORK(&leds->led[i].work, mc13xxx_led_work); - ret = led_classdev_register(pdev->dev.parent, - &leds->led[i].cdev); + ret = led_classdev_register(dev->parent, &leds->led[i].cdev); if (ret) { - dev_err(&pdev->dev, "Failed to register LED %i\n", id); + dev_err(dev, "Failed to register LED %i\n", id); break; } } @@ -219,7 +282,6 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev) static int mc13xxx_led_remove(struct platform_device *pdev) { - struct mc13xxx *mcdev = dev_get_drvdata(pdev->dev.parent); struct mc13xxx_leds *leds = platform_get_drvdata(pdev); int i; @@ -228,9 +290,6 @@ static int mc13xxx_led_remove(struct platform_device *pdev) cancel_work_sync(&leds->led[i].work); } - for (i = 0; i < leds->devtype->num_regs; i++) - mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), 0); - return 0; } @@ -238,17 +297,27 @@ static const struct mc13xxx_led_devtype mc13783_led_devtype = { .led_min = MC13783_LED_MD, .led_max = MC13783_LED_B3, .num_regs = 6, + .ledctrl_base = 51, }; static const struct mc13xxx_led_devtype mc13892_led_devtype = { .led_min = MC13892_LED_MD, .led_max = MC13892_LED_B, .num_regs = 4, + .ledctrl_base = 51, +}; + +static const struct mc13xxx_led_devtype mc34708_led_devtype = { + .led_min = MC34708_LED_R, + .led_max = MC34708_LED_G, + .num_regs = 1, + .ledctrl_base = 54, }; static const struct platform_device_id mc13xxx_led_id_table[] = { { "mc13783-led", (kernel_ulong_t)&mc13783_led_devtype, }, { "mc13892-led", (kernel_ulong_t)&mc13892_led_devtype, }, + { "mc34708-led", (kernel_ulong_t)&mc34708_led_devtype, }, { } }; MODULE_DEVICE_TABLE(platform, mc13xxx_led_id_table); diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index 2f9f141084ba..e97f443a6e07 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c @@ -21,7 +21,6 @@ */ #include <linux/module.h> -#include <linux/init.h> #include <linux/irq.h> #include <linux/slab.h> #include <linux/spinlock.h> diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index c7a4230233ea..efa625883c83 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c @@ -23,7 +23,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/gpio.h> diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c index 98cae529373f..c9d906098466 100644 --- a/drivers/leds/leds-ot200.c +++ b/drivers/leds/leds-ot200.c @@ -8,7 +8,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/leds.h> diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 605047428b5a..7d0aaed1e23a 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -14,7 +14,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of_platform.h> #include <linux/fb.h> @@ -84,6 +83,15 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds) (sizeof(struct led_pwm_data) * num_leds); } +static void led_pwm_cleanup(struct led_pwm_priv *priv) +{ + while (priv->num_leds--) { + led_classdev_unregister(&priv->leds[priv->num_leds].cdev); + if (priv->leds[priv->num_leds].can_sleep) + cancel_work_sync(&priv->leds[priv->num_leds].work); + } +} + static int led_pwm_create_of(struct platform_device *pdev, struct led_pwm_priv *priv) { @@ -131,8 +139,7 @@ static int led_pwm_create_of(struct platform_device *pdev, return 0; err: - while (priv->num_leds--) - led_classdev_unregister(&priv->leds[priv->num_leds].cdev); + led_pwm_cleanup(priv); return ret; } @@ -200,8 +207,8 @@ static int led_pwm_probe(struct platform_device *pdev) return 0; err: - while (i--) - led_classdev_unregister(&priv->leds[i].cdev); + priv->num_leds = i; + led_pwm_cleanup(priv); return ret; } @@ -209,13 +216,8 @@ err: static int led_pwm_remove(struct platform_device *pdev) { struct led_pwm_priv *priv = platform_get_drvdata(pdev); - int i; - for (i = 0; i < priv->num_leds; i++) { - led_classdev_unregister(&priv->leds[i].cdev); - if (priv->leds[i].can_sleep) - cancel_work_sync(&priv->leds[i].work); - } + led_pwm_cleanup(priv); return 0; } diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c index 98174e7240ee..28988b7b4fab 100644 --- a/drivers/leds/leds-s3c24xx.c +++ b/drivers/leds/leds-s3c24xx.c @@ -12,7 +12,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/gpio.h> diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c index 5b8f938a8d73..2eb3ef62962b 100644 --- a/drivers/leds/leds-ss4200.c +++ b/drivers/leds/leds-ss4200.c @@ -63,7 +63,7 @@ MODULE_LICENSE("GPL"); /* * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. */ -static DEFINE_PCI_DEVICE_TABLE(ich7_lpc_pci_id) = { +static const struct pci_device_id ich7_lpc_pci_id[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30) }, @@ -78,7 +78,7 @@ static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id) return 1; } -static bool __initdata nodetect; +static bool nodetect; module_param_named(nodetect, nodetect, bool, 0); MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c index 0a1a13f3a6a5..e72c974142d0 100644 --- a/drivers/leds/leds-wm831x-status.c +++ b/drivers/leds/leds-wm831x-status.c @@ -10,7 +10,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/leds.h> diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c index 3f75fd22fd49..4133ffe29015 100644 --- a/drivers/leds/leds-wm8350.c +++ b/drivers/leds/leds-wm8350.c @@ -10,7 +10,6 @@ */ #include <linux/kernel.h> -#include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/err.h> diff --git a/drivers/leds/trigger/ledtrig-cpu.c b/drivers/leds/trigger/ledtrig-cpu.c index 118335eccc56..1c3ee9fcaf34 100644 --- a/drivers/leds/trigger/ledtrig-cpu.c +++ b/drivers/leds/trigger/ledtrig-cpu.c @@ -26,6 +26,7 @@ #include <linux/percpu.h> #include <linux/syscore_ops.h> #include <linux/rwsem.h> +#include <linux/cpu.h> #include "../leds.h" #define MAX_NAME_LEN 8 @@ -92,6 +93,26 @@ static struct syscore_ops ledtrig_cpu_syscore_ops = { .resume = ledtrig_cpu_syscore_resume, }; +static int ledtrig_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_STARTING: + ledtrig_cpu(CPU_LED_START); + break; + case CPU_DYING: + ledtrig_cpu(CPU_LED_STOP); + break; + } + + return NOTIFY_OK; +} + + +static struct notifier_block ledtrig_cpu_nb = { + .notifier_call = ledtrig_cpu_notify, +}; + static int __init ledtrig_cpu_init(void) { int cpu; @@ -113,6 +134,7 @@ static int __init ledtrig_cpu_init(void) } register_syscore_ops(&ledtrig_cpu_syscore_ops); + register_cpu_notifier(&ledtrig_cpu_nb); pr_info("ledtrig-cpu: registered to indicate activity on CPUs\n"); @@ -124,6 +146,8 @@ static void __exit ledtrig_cpu_exit(void) { int cpu; + unregister_cpu_notifier(&ledtrig_cpu_nb); + for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |