aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-10 12:06:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-10 12:06:10 -0400
commit4162877d3ffa900b618c369c490c7faa6af60e47 (patch)
tree5e87df9b3cdf07dcdc072bfdddadef4eb04c18ca /drivers/leds
parent6c61403a446b5ee54c21cecabdc821acf06f96bf (diff)
parent14f5716bc23cebb627b40a2808e9f04eb77ab206 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds
Pull LED updates from Bryan Wu: "This cycle we got: - new driver for leds-mc13783 - bug fixes - code cleanup" * 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds: leds: make sure we unregister a trigger only once leds: leds-pwm: properly clean up after probe failure leds: clevo-mail: Make probe function __init leds-ot200: Fix dependencies leds-gpio: of: introduce MODULE_DEVICE_TABLE for module autoloading leds: clevo-mail: remove __initdata marker leds: leds-ss4200: remove __initdata marker leds: blinkm: remove unnecessary spaces leds: lp5562: remove unnecessary parentheses leds: leds-ss4200: remove DEFINE_PCI_DEVICE_TABLE macro leds: leds-s3c24xx: Trivial cleanup in header file drivers/leds: delete non-required instances of include <linux/init.h> leds: leds-gpio: add retain-state-suspended property leds: leds-mc13783: Add devicetree support leds: leds-mc13783: Remove unnecessary cleaning of registers on exit leds: leds-mc13783: Use proper "max_brightness" value fo LEDs leds: leds-mc13783: Use LED core PM functions leds: leds-mc13783: Add MC34708 LED support leds: Turn off led if blinking is disabled ledtrig-cpu: Handle CPU hot(un)plugging
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig4
-rw-r--r--drivers/leds/led-core.c6
-rw-r--r--drivers/leds/led-triggers.c6
-rw-r--r--drivers/leds/leds-88pm860x.c1
-rw-r--r--drivers/leds/leds-adp5520.c1
-rw-r--r--drivers/leds/leds-asic3.c1
-rw-r--r--drivers/leds/leds-blinkm.c3
-rw-r--r--drivers/leds/leds-clevo-mail.c5
-rw-r--r--drivers/leds/leds-cobalt-qube.c1
-rw-r--r--drivers/leds/leds-da903x.c1
-rw-r--r--drivers/leds/leds-da9052.c1
-rw-r--r--drivers/leds/leds-fsg.c1
-rw-r--r--drivers/leds/leds-gpio.c6
-rw-r--r--drivers/leds/leds-hp6xx.c1
-rw-r--r--drivers/leds/leds-lm3533.c1
-rw-r--r--drivers/leds/leds-lp5521.c1
-rw-r--r--drivers/leds/leds-lp5523.c1
-rw-r--r--drivers/leds/leds-lp5562.c7
-rw-r--r--drivers/leds/leds-lt3593.c1
-rw-r--r--drivers/leds/leds-mc13783.c223
-rw-r--r--drivers/leds/leds-netxbig.c1
-rw-r--r--drivers/leds/leds-ns2.c1
-rw-r--r--drivers/leds/leds-ot200.c1
-rw-r--r--drivers/leds/leds-pwm.c24
-rw-r--r--drivers/leds/leds-s3c24xx.c1
-rw-r--r--drivers/leds/leds-ss4200.c4
-rw-r--r--drivers/leds/leds-wm831x-status.c1
-rw-r--r--drivers/leds/leds-wm8350.c1
-rw-r--r--drivers/leds/trigger/ledtrig-cpu.c24
29 files changed, 206 insertions, 124 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 44c358ecf5a1..6de9dfbf61c1 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -416,7 +416,7 @@ config LEDS_MC13783
416 depends on MFD_MC13XXX 416 depends on MFD_MC13XXX
417 help 417 help
418 This option enable support for on-chip LED drivers found 418 This option enable support for on-chip LED drivers found
419 on Freescale Semiconductor MC13783/MC13892 PMIC. 419 on Freescale Semiconductor MC13783/MC13892/MC34708 PMIC.
420 420
421config LEDS_NS2 421config LEDS_NS2
422 tristate "LED support for Network Space v2 GPIO LEDs" 422 tristate "LED support for Network Space v2 GPIO LEDs"
@@ -474,7 +474,7 @@ config LEDS_LM355x
474 474
475config LEDS_OT200 475config LEDS_OT200
476 tristate "LED support for the Bachmann OT200" 476 tristate "LED support for the Bachmann OT200"
477 depends on LEDS_CLASS && HAS_IOMEM 477 depends on LEDS_CLASS && HAS_IOMEM && (X86_32 || COMPILE_TEST)
478 help 478 help
479 This option enables support for the LEDs on the Bachmann OT200. 479 This option enables support for the LEDs on the Bachmann OT200.
480 Say Y to enable LEDs on the Bachmann OT200. 480 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,
39 led_cdev->blink_delay_on = delay_on; 39 led_cdev->blink_delay_on = delay_on;
40 led_cdev->blink_delay_off = delay_off; 40 led_cdev->blink_delay_off = delay_off;
41 41
42 /* never on - don't blink */ 42 /* never on - just set to off */
43 if (!delay_on) 43 if (!delay_on) {
44 __led_set_brightness(led_cdev, LED_OFF);
44 return; 45 return;
46 }
45 47
46 /* never off - just set to brightness */ 48 /* never off - just set to brightness */
47 if (!delay_off) { 49 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 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/list.h> 16#include <linux/list.h>
18#include <linux/spinlock.h> 17#include <linux/spinlock.h>
19#include <linux/device.h> 18#include <linux/device.h>
@@ -220,9 +219,12 @@ void led_trigger_unregister(struct led_trigger *trig)
220{ 219{
221 struct led_classdev *led_cdev; 220 struct led_classdev *led_cdev;
222 221
222 if (list_empty_careful(&trig->next_trig))
223 return;
224
223 /* Remove from the list of led triggers */ 225 /* Remove from the list of led triggers */
224 down_write(&triggers_list_lock); 226 down_write(&triggers_list_lock);
225 list_del(&trig->next_trig); 227 list_del_init(&trig->next_trig);
226 up_write(&triggers_list_lock); 228 up_write(&triggers_list_lock);
227 229
228 /* Remove anyone actively using this trigger */ 230 /* 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 @@
11 */ 11 */
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/of.h> 14#include <linux/of.h>
16#include <linux/platform_device.h> 15#include <linux/platform_device.h>
17#include <linux/i2c.h> 16#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 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/platform_device.h> 18#include <linux/platform_device.h>
20#include <linux/leds.h> 19#include <linux/leds.h>
21#include <linux/workqueue.h> 20#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 @@
7 */ 7 */
8 8
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/platform_device.h> 10#include <linux/platform_device.h>
12#include <linux/leds.h> 11#include <linux/leds.h>
13#include <linux/slab.h> 12#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 @@
18 */ 18 */
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/slab.h> 21#include <linux/slab.h>
23#include <linux/jiffies.h> 22#include <linux/jiffies.h>
24#include <linux/i2c.h> 23#include <linux/i2c.h>
@@ -444,7 +443,7 @@ static void led_work(struct work_struct *work)
444{ 443{
445 int ret; 444 int ret;
446 struct blinkm_led *led; 445 struct blinkm_led *led;
447 struct blinkm_data *data ; 446 struct blinkm_data *data;
448 struct blinkm_work *blm_work = work_to_blmwork(work); 447 struct blinkm_work *blm_work = work_to_blmwork(work);
449 448
450 led = blm_work->blinkm_led; 449 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>");
19MODULE_DESCRIPTION("Clevo mail LED driver"); 19MODULE_DESCRIPTION("Clevo mail LED driver");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22static bool __initdata nodetect; 22static bool nodetect;
23module_param_named(nodetect, nodetect, bool, 0); 23module_param_named(nodetect, nodetect, bool, 0);
24MODULE_PARM_DESC(nodetect, "Skip DMI hardware detection"); 24MODULE_PARM_DESC(nodetect, "Skip DMI hardware detection");
25 25
@@ -153,7 +153,7 @@ static struct led_classdev clevo_mail_led = {
153 .flags = LED_CORE_SUSPENDRESUME, 153 .flags = LED_CORE_SUSPENDRESUME,
154}; 154};
155 155
156static int clevo_mail_led_probe(struct platform_device *pdev) 156static int __init clevo_mail_led_probe(struct platform_device *pdev)
157{ 157{
158 return led_classdev_register(&pdev->dev, &clevo_mail_led); 158 return led_classdev_register(&pdev->dev, &clevo_mail_led);
159} 159}
@@ -165,7 +165,6 @@ static int clevo_mail_led_remove(struct platform_device *pdev)
165} 165}
166 166
167static struct platform_driver clevo_mail_led_driver = { 167static struct platform_driver clevo_mail_led_driver = {
168 .probe = clevo_mail_led_probe,
169 .remove = clevo_mail_led_remove, 168 .remove = clevo_mail_led_remove,
170 .driver = { 169 .driver = {
171 .name = KBUILD_MODNAME, 170 .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 @@
3 * 3 *
4 * Control the Cobalt Qube/RaQ front LED 4 * Control the Cobalt Qube/RaQ front LED
5 */ 5 */
6#include <linux/init.h>
7#include <linux/io.h> 6#include <linux/io.h>
8#include <linux/ioport.h> 7#include <linux/ioport.h>
9#include <linux/leds.h> 8#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 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h> 17#include <linux/platform_device.h>
19#include <linux/leds.h> 18#include <linux/leds.h>
20#include <linux/workqueue.h> 19#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 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h> 17#include <linux/platform_device.h>
19#include <linux/leds.h> 18#include <linux/leds.h>
20#include <linux/workqueue.h> 19#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 @@
16 */ 16 */
17 17
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/platform_device.h> 19#include <linux/platform_device.h>
21#include <linux/leds.h> 20#include <linux/leds.h>
22#include <linux/module.h> 21#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 @@
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/platform_device.h> 14#include <linux/platform_device.h>
16#include <linux/gpio.h> 15#include <linux/gpio.h>
17#include <linux/leds.h> 16#include <linux/leds.h>
@@ -204,6 +203,9 @@ static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
204 led.default_state = LEDS_GPIO_DEFSTATE_OFF; 203 led.default_state = LEDS_GPIO_DEFSTATE_OFF;
205 } 204 }
206 205
206 if (of_get_property(child, "retain-state-suspended", NULL))
207 led.retain_state_suspended = 1;
208
207 ret = create_gpio_led(&led, &priv->leds[priv->num_leds++], 209 ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
208 &pdev->dev, NULL); 210 &pdev->dev, NULL);
209 if (ret < 0) { 211 if (ret < 0) {
@@ -224,6 +226,8 @@ static const struct of_device_id of_gpio_leds_match[] = {
224 { .compatible = "gpio-leds", }, 226 { .compatible = "gpio-leds", },
225 {}, 227 {},
226}; 228};
229
230MODULE_DEVICE_TABLE(of, of_gpio_leds_match);
227#else /* CONFIG_OF_GPIO */ 231#else /* CONFIG_OF_GPIO */
228static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) 232static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
229{ 233{
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 @@
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h> 15#include <linux/platform_device.h>
17#include <linux/leds.h> 16#include <linux/leds.h>
18#include <asm/hd64461.h> 17#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 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/leds.h> 15#include <linux/leds.h>
17#include <linux/mfd/core.h> 16#include <linux/mfd/core.h>
18#include <linux/mutex.h> 17#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 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/firmware.h> 26#include <linux/firmware.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/init.h>
29#include <linux/leds.h> 28#include <linux/leds.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/mutex.h> 30#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 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/firmware.h> 26#include <linux/firmware.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/init.h>
29#include <linux/leds.h> 28#include <linux/leds.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/mutex.h> 30#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 @@
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/firmware.h> 14#include <linux/firmware.h>
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/init.h>
17#include <linux/leds.h> 16#include <linux/leds.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/mutex.h> 18#include <linux/mutex.h>
@@ -347,9 +346,9 @@ static void lp5562_write_program_memory(struct lp55xx_chip *chip,
347/* check the size of program count */ 346/* check the size of program count */
348static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn) 347static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn)
349{ 348{
350 return (ptn->size_r >= LP5562_PROGRAM_LENGTH || 349 return ptn->size_r >= LP5562_PROGRAM_LENGTH ||
351 ptn->size_g >= LP5562_PROGRAM_LENGTH || 350 ptn->size_g >= LP5562_PROGRAM_LENGTH ||
352 ptn->size_b >= LP5562_PROGRAM_LENGTH); 351 ptn->size_b >= LP5562_PROGRAM_LENGTH;
353} 352}
354 353
355static int lp5562_run_predef_led_pattern(struct lp55xx_chip *chip, int mode) 354static 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 @@
17 */ 17 */
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h> 20#include <linux/platform_device.h>
22#include <linux/leds.h> 21#include <linux/leds.h>
23#include <linux/workqueue.h> 22#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 @@
1/* 1/*
2 * LEDs driver for Freescale MC13783/MC13892 2 * LEDs driver for Freescale MC13783/MC13892/MC34708
3 * 3 *
4 * Copyright (C) 2010 Philippe Rétornaz 4 * Copyright (C) 2010 Philippe Rétornaz
5 * 5 *
@@ -17,57 +17,56 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h> 20#include <linux/platform_device.h>
22#include <linux/leds.h> 21#include <linux/leds.h>
22#include <linux/of.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/mfd/mc13xxx.h> 24#include <linux/mfd/mc13xxx.h>
25 25
26#define MC13XXX_REG_LED_CONTROL(x) (51 + (x))
27
28struct mc13xxx_led_devtype { 26struct mc13xxx_led_devtype {
29 int led_min; 27 int led_min;
30 int led_max; 28 int led_max;
31 int num_regs; 29 int num_regs;
30 u32 ledctrl_base;
32}; 31};
33 32
34struct mc13xxx_led { 33struct mc13xxx_led {
35 struct led_classdev cdev; 34 struct led_classdev cdev;
36 struct work_struct work; 35 struct work_struct work;
37 struct mc13xxx *master;
38 enum led_brightness new_brightness; 36 enum led_brightness new_brightness;
39 int id; 37 int id;
38 struct mc13xxx_leds *leds;
40}; 39};
41 40
42struct mc13xxx_leds { 41struct mc13xxx_leds {
42 struct mc13xxx *master;
43 struct mc13xxx_led_devtype *devtype; 43 struct mc13xxx_led_devtype *devtype;
44 int num_leds; 44 int num_leds;
45 struct mc13xxx_led led[0]; 45 struct mc13xxx_led *led;
46}; 46};
47 47
48static unsigned int mc13xxx_max_brightness(int id)
49{
50 if (id >= MC13783_LED_MD && id <= MC13783_LED_KP)
51 return 0x0f;
52 else if (id >= MC13783_LED_R1 && id <= MC13783_LED_B3)
53 return 0x1f;
54
55 return 0x3f;
56}
57
48static void mc13xxx_led_work(struct work_struct *work) 58static void mc13xxx_led_work(struct work_struct *work)
49{ 59{
50 struct mc13xxx_led *led = container_of(work, struct mc13xxx_led, work); 60 struct mc13xxx_led *led = container_of(work, struct mc13xxx_led, work);
51 int reg, mask, value, bank, off, shift; 61 struct mc13xxx_leds *leds = led->leds;
62 unsigned int reg, bank, off, shift;
52 63
53 switch (led->id) { 64 switch (led->id) {
54 case MC13783_LED_MD: 65 case MC13783_LED_MD:
55 reg = MC13XXX_REG_LED_CONTROL(2);
56 shift = 9;
57 mask = 0x0f;
58 value = led->new_brightness >> 4;
59 break;
60 case MC13783_LED_AD: 66 case MC13783_LED_AD:
61 reg = MC13XXX_REG_LED_CONTROL(2);
62 shift = 13;
63 mask = 0x0f;
64 value = led->new_brightness >> 4;
65 break;
66 case MC13783_LED_KP: 67 case MC13783_LED_KP:
67 reg = MC13XXX_REG_LED_CONTROL(2); 68 reg = 2;
68 shift = 17; 69 shift = 9 + (led->id - MC13783_LED_MD) * 4;
69 mask = 0x0f;
70 value = led->new_brightness >> 4;
71 break; 70 break;
72 case MC13783_LED_R1: 71 case MC13783_LED_R1:
73 case MC13783_LED_G1: 72 case MC13783_LED_G1:
@@ -80,44 +79,35 @@ static void mc13xxx_led_work(struct work_struct *work)
80 case MC13783_LED_B3: 79 case MC13783_LED_B3:
81 off = led->id - MC13783_LED_R1; 80 off = led->id - MC13783_LED_R1;
82 bank = off / 3; 81 bank = off / 3;
83 reg = MC13XXX_REG_LED_CONTROL(3) + bank; 82 reg = 3 + bank;
84 shift = (off - bank * 3) * 5 + 6; 83 shift = (off - bank * 3) * 5 + 6;
85 value = led->new_brightness >> 3;
86 mask = 0x1f;
87 break; 84 break;
88 case MC13892_LED_MD: 85 case MC13892_LED_MD:
89 reg = MC13XXX_REG_LED_CONTROL(0);
90 shift = 3;
91 mask = 0x3f;
92 value = led->new_brightness >> 2;
93 break;
94 case MC13892_LED_AD: 86 case MC13892_LED_AD:
95 reg = MC13XXX_REG_LED_CONTROL(0);
96 shift = 15;
97 mask = 0x3f;
98 value = led->new_brightness >> 2;
99 break;
100 case MC13892_LED_KP: 87 case MC13892_LED_KP:
101 reg = MC13XXX_REG_LED_CONTROL(1); 88 reg = (led->id - MC13892_LED_MD) / 2;
102 shift = 3; 89 shift = 3 + (led->id - MC13892_LED_MD) * 12;
103 mask = 0x3f;
104 value = led->new_brightness >> 2;
105 break; 90 break;
106 case MC13892_LED_R: 91 case MC13892_LED_R:
107 case MC13892_LED_G: 92 case MC13892_LED_G:
108 case MC13892_LED_B: 93 case MC13892_LED_B:
109 off = led->id - MC13892_LED_R; 94 off = led->id - MC13892_LED_R;
110 bank = off / 2; 95 bank = off / 2;
111 reg = MC13XXX_REG_LED_CONTROL(2) + bank; 96 reg = 2 + bank;
112 shift = (off - bank * 2) * 12 + 3; 97 shift = (off - bank * 2) * 12 + 3;
113 value = led->new_brightness >> 2; 98 break;
114 mask = 0x3f; 99 case MC34708_LED_R:
100 case MC34708_LED_G:
101 reg = 0;
102 shift = 3 + (led->id - MC34708_LED_R) * 12;
115 break; 103 break;
116 default: 104 default:
117 BUG(); 105 BUG();
118 } 106 }
119 107
120 mc13xxx_reg_rmw(led->master, reg, mask << shift, value << shift); 108 mc13xxx_reg_rmw(leds->master, leds->devtype->ledctrl_base + reg,
109 mc13xxx_max_brightness(led->id) << shift,
110 led->new_brightness << shift);
121} 111}
122 112
123static void mc13xxx_led_set(struct led_classdev *led_cdev, 113static void mc13xxx_led_set(struct led_classdev *led_cdev,
@@ -130,47 +120,121 @@ static void mc13xxx_led_set(struct led_classdev *led_cdev,
130 schedule_work(&led->work); 120 schedule_work(&led->work);
131} 121}
132 122
133static int __init mc13xxx_led_probe(struct platform_device *pdev) 123#ifdef CONFIG_OF
124static struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt(
125 struct platform_device *pdev)
134{ 126{
135 struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 127 struct mc13xxx_leds *leds = platform_get_drvdata(pdev);
136 struct mc13xxx *mcdev = dev_get_drvdata(pdev->dev.parent); 128 struct mc13xxx_leds_platform_data *pdata;
137 struct mc13xxx_led_devtype *devtype = 129 struct device_node *parent, *child;
138 (struct mc13xxx_led_devtype *)pdev->id_entry->driver_data; 130 struct device *dev = &pdev->dev;
139 struct mc13xxx_leds *leds; 131 int i = 0, ret = -ENODATA;
140 int i, id, num_leds, ret = -ENODATA; 132
141 u32 reg, init_led = 0; 133 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
134 if (!pdata)
135 return ERR_PTR(-ENOMEM);
136
137 of_node_get(dev->parent->of_node);
138
139 parent = of_find_node_by_name(dev->parent->of_node, "leds");
140 if (!parent)
141 goto out_node_put;
142 142
143 if (!pdata) { 143 ret = of_property_read_u32_array(parent, "led-control",
144 dev_err(&pdev->dev, "Missing platform data\n"); 144 pdata->led_control,
145 return -ENODEV; 145 leds->devtype->num_regs);
146 if (ret)
147 goto out_node_put;
148
149 pdata->num_leds = of_get_child_count(parent);
150
151 pdata->led = devm_kzalloc(dev, pdata->num_leds * sizeof(*pdata->led),
152 GFP_KERNEL);
153 if (!pdata->led) {
154 ret = -ENOMEM;
155 goto out_node_put;
146 } 156 }
147 157
148 num_leds = pdata->num_leds; 158 for_each_child_of_node(parent, child) {
159 const char *str;
160 u32 tmp;
149 161
150 if ((num_leds < 1) || 162 if (of_property_read_u32(child, "reg", &tmp))
151 (num_leds > (devtype->led_max - devtype->led_min + 1))) { 163 continue;
152 dev_err(&pdev->dev, "Invalid LED count %d\n", num_leds); 164 pdata->led[i].id = leds->devtype->led_min + tmp;
153 return -EINVAL; 165
166 if (!of_property_read_string(child, "label", &str))
167 pdata->led[i].name = str;
168 if (!of_property_read_string(child, "linux,default-trigger",
169 &str))
170 pdata->led[i].default_trigger = str;
171
172 i++;
154 } 173 }
155 174
156 leds = devm_kzalloc(&pdev->dev, num_leds * sizeof(struct mc13xxx_led) + 175 pdata->num_leds = i;
157 sizeof(struct mc13xxx_leds), GFP_KERNEL); 176 ret = i > 0 ? 0 : -ENODATA;
177
178out_node_put:
179 of_node_put(parent);
180
181 return ret ? ERR_PTR(ret) : pdata;
182}
183#else
184static inline struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt(
185 struct platform_device *pdev)
186{
187 return ERR_PTR(-ENOSYS);
188}
189#endif
190
191static int __init mc13xxx_led_probe(struct platform_device *pdev)
192{
193 struct device *dev = &pdev->dev;
194 struct mc13xxx_leds_platform_data *pdata = dev_get_platdata(dev);
195 struct mc13xxx *mcdev = dev_get_drvdata(dev->parent);
196 struct mc13xxx_led_devtype *devtype =
197 (struct mc13xxx_led_devtype *)pdev->id_entry->driver_data;
198 struct mc13xxx_leds *leds;
199 int i, id, ret = -ENODATA;
200 u32 init_led = 0;
201
202 leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
158 if (!leds) 203 if (!leds)
159 return -ENOMEM; 204 return -ENOMEM;
160 205
161 leds->devtype = devtype; 206 leds->devtype = devtype;
162 leds->num_leds = num_leds; 207 leds->master = mcdev;
163 platform_set_drvdata(pdev, leds); 208 platform_set_drvdata(pdev, leds);
164 209
210 if (dev->parent->of_node) {
211 pdata = mc13xxx_led_probe_dt(pdev);
212 if (IS_ERR(pdata))
213 return PTR_ERR(pdata);
214 } else if (!pdata)
215 return -ENODATA;
216
217 leds->num_leds = pdata->num_leds;
218
219 if ((leds->num_leds < 1) ||
220 (leds->num_leds > (devtype->led_max - devtype->led_min + 1))) {
221 dev_err(dev, "Invalid LED count %d\n", leds->num_leds);
222 return -EINVAL;
223 }
224
225 leds->led = devm_kzalloc(dev, leds->num_leds * sizeof(*leds->led),
226 GFP_KERNEL);
227 if (!leds->led)
228 return -ENOMEM;
229
165 for (i = 0; i < devtype->num_regs; i++) { 230 for (i = 0; i < devtype->num_regs; i++) {
166 reg = pdata->led_control[i]; 231 ret = mc13xxx_reg_write(mcdev, leds->devtype->ledctrl_base + i,
167 WARN_ON(reg >= (1 << 24)); 232 pdata->led_control[i]);
168 ret = mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), reg);
169 if (ret) 233 if (ret)
170 return ret; 234 return ret;
171 } 235 }
172 236
173 for (i = 0; i < num_leds; i++) { 237 for (i = 0; i < leds->num_leds; i++) {
174 const char *name, *trig; 238 const char *name, *trig;
175 239
176 ret = -EINVAL; 240 ret = -EINVAL;
@@ -180,30 +244,29 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev)
180 trig = pdata->led[i].default_trigger; 244 trig = pdata->led[i].default_trigger;
181 245
182 if ((id > devtype->led_max) || (id < devtype->led_min)) { 246 if ((id > devtype->led_max) || (id < devtype->led_min)) {
183 dev_err(&pdev->dev, "Invalid ID %i\n", id); 247 dev_err(dev, "Invalid ID %i\n", id);
184 break; 248 break;
185 } 249 }
186 250
187 if (init_led & (1 << id)) { 251 if (init_led & (1 << id)) {
188 dev_warn(&pdev->dev, 252 dev_warn(dev, "LED %i already initialized\n", id);
189 "LED %i already initialized\n", id);
190 break; 253 break;
191 } 254 }
192 255
193 init_led |= 1 << id; 256 init_led |= 1 << id;
194 leds->led[i].id = id; 257 leds->led[i].id = id;
195 leds->led[i].master = mcdev; 258 leds->led[i].leds = leds;
196 leds->led[i].cdev.name = name; 259 leds->led[i].cdev.name = name;
197 leds->led[i].cdev.default_trigger = trig; 260 leds->led[i].cdev.default_trigger = trig;
261 leds->led[i].cdev.flags = LED_CORE_SUSPENDRESUME;
198 leds->led[i].cdev.brightness_set = mc13xxx_led_set; 262 leds->led[i].cdev.brightness_set = mc13xxx_led_set;
199 leds->led[i].cdev.brightness = LED_OFF; 263 leds->led[i].cdev.max_brightness = mc13xxx_max_brightness(id);
200 264
201 INIT_WORK(&leds->led[i].work, mc13xxx_led_work); 265 INIT_WORK(&leds->led[i].work, mc13xxx_led_work);
202 266
203 ret = led_classdev_register(pdev->dev.parent, 267 ret = led_classdev_register(dev->parent, &leds->led[i].cdev);
204 &leds->led[i].cdev);
205 if (ret) { 268 if (ret) {
206 dev_err(&pdev->dev, "Failed to register LED %i\n", id); 269 dev_err(dev, "Failed to register LED %i\n", id);
207 break; 270 break;
208 } 271 }
209 } 272 }
@@ -219,7 +282,6 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev)
219 282
220static int mc13xxx_led_remove(struct platform_device *pdev) 283static int mc13xxx_led_remove(struct platform_device *pdev)
221{ 284{
222 struct mc13xxx *mcdev = dev_get_drvdata(pdev->dev.parent);
223 struct mc13xxx_leds *leds = platform_get_drvdata(pdev); 285 struct mc13xxx_leds *leds = platform_get_drvdata(pdev);
224 int i; 286 int i;
225 287
@@ -228,9 +290,6 @@ static int mc13xxx_led_remove(struct platform_device *pdev)
228 cancel_work_sync(&leds->led[i].work); 290 cancel_work_sync(&leds->led[i].work);
229 } 291 }
230 292
231 for (i = 0; i < leds->devtype->num_regs; i++)
232 mc13xxx_reg_write(mcdev, MC13XXX_REG_LED_CONTROL(i), 0);
233
234 return 0; 293 return 0;
235} 294}
236 295
@@ -238,17 +297,27 @@ static const struct mc13xxx_led_devtype mc13783_led_devtype = {
238 .led_min = MC13783_LED_MD, 297 .led_min = MC13783_LED_MD,
239 .led_max = MC13783_LED_B3, 298 .led_max = MC13783_LED_B3,
240 .num_regs = 6, 299 .num_regs = 6,
300 .ledctrl_base = 51,
241}; 301};
242 302
243static const struct mc13xxx_led_devtype mc13892_led_devtype = { 303static const struct mc13xxx_led_devtype mc13892_led_devtype = {
244 .led_min = MC13892_LED_MD, 304 .led_min = MC13892_LED_MD,
245 .led_max = MC13892_LED_B, 305 .led_max = MC13892_LED_B,
246 .num_regs = 4, 306 .num_regs = 4,
307 .ledctrl_base = 51,
308};
309
310static const struct mc13xxx_led_devtype mc34708_led_devtype = {
311 .led_min = MC34708_LED_R,
312 .led_max = MC34708_LED_G,
313 .num_regs = 1,
314 .ledctrl_base = 54,
247}; 315};
248 316
249static const struct platform_device_id mc13xxx_led_id_table[] = { 317static const struct platform_device_id mc13xxx_led_id_table[] = {
250 { "mc13783-led", (kernel_ulong_t)&mc13783_led_devtype, }, 318 { "mc13783-led", (kernel_ulong_t)&mc13783_led_devtype, },
251 { "mc13892-led", (kernel_ulong_t)&mc13892_led_devtype, }, 319 { "mc13892-led", (kernel_ulong_t)&mc13892_led_devtype, },
320 { "mc34708-led", (kernel_ulong_t)&mc34708_led_devtype, },
252 { } 321 { }
253}; 322};
254MODULE_DEVICE_TABLE(platform, mc13xxx_led_id_table); 323MODULE_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 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/irq.h> 24#include <linux/irq.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/spinlock.h> 26#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 @@
23 */ 23 */
24 24
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/platform_device.h> 26#include <linux/platform_device.h>
28#include <linux/slab.h> 27#include <linux/slab.h>
29#include <linux/gpio.h> 28#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 @@
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/init.h>
12#include <linux/platform_device.h> 11#include <linux/platform_device.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
14#include <linux/leds.h> 13#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 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h> 17#include <linux/platform_device.h>
19#include <linux/of_platform.h> 18#include <linux/of_platform.h>
20#include <linux/fb.h> 19#include <linux/fb.h>
@@ -84,6 +83,15 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds)
84 (sizeof(struct led_pwm_data) * num_leds); 83 (sizeof(struct led_pwm_data) * num_leds);
85} 84}
86 85
86static void led_pwm_cleanup(struct led_pwm_priv *priv)
87{
88 while (priv->num_leds--) {
89 led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
90 if (priv->leds[priv->num_leds].can_sleep)
91 cancel_work_sync(&priv->leds[priv->num_leds].work);
92 }
93}
94
87static int led_pwm_create_of(struct platform_device *pdev, 95static int led_pwm_create_of(struct platform_device *pdev,
88 struct led_pwm_priv *priv) 96 struct led_pwm_priv *priv)
89{ 97{
@@ -131,8 +139,7 @@ static int led_pwm_create_of(struct platform_device *pdev,
131 139
132 return 0; 140 return 0;
133err: 141err:
134 while (priv->num_leds--) 142 led_pwm_cleanup(priv);
135 led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
136 143
137 return ret; 144 return ret;
138} 145}
@@ -200,8 +207,8 @@ static int led_pwm_probe(struct platform_device *pdev)
200 return 0; 207 return 0;
201 208
202err: 209err:
203 while (i--) 210 priv->num_leds = i;
204 led_classdev_unregister(&priv->leds[i].cdev); 211 led_pwm_cleanup(priv);
205 212
206 return ret; 213 return ret;
207} 214}
@@ -209,13 +216,8 @@ err:
209static int led_pwm_remove(struct platform_device *pdev) 216static int led_pwm_remove(struct platform_device *pdev)
210{ 217{
211 struct led_pwm_priv *priv = platform_get_drvdata(pdev); 218 struct led_pwm_priv *priv = platform_get_drvdata(pdev);
212 int i;
213 219
214 for (i = 0; i < priv->num_leds; i++) { 220 led_pwm_cleanup(priv);
215 led_classdev_unregister(&priv->leds[i].cdev);
216 if (priv->leds[i].can_sleep)
217 cancel_work_sync(&priv->leds[i].work);
218 }
219 221
220 return 0; 222 return 0;
221} 223}
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 @@
12*/ 12*/
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/platform_device.h> 15#include <linux/platform_device.h>
17#include <linux/leds.h> 16#include <linux/leds.h>
18#include <linux/gpio.h> 17#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");
63/* 63/*
64 * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. 64 * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
65 */ 65 */
66static DEFINE_PCI_DEVICE_TABLE(ich7_lpc_pci_id) = { 66static const struct pci_device_id ich7_lpc_pci_id[] = {
67 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, 67 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
68 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, 68 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
69 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30) }, 69 { 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)
78 return 1; 78 return 1;
79} 79}
80 80
81static bool __initdata nodetect; 81static bool nodetect;
82module_param_named(nodetect, nodetect, bool, 0); 82module_param_named(nodetect, nodetect, bool, 0);
83MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); 83MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection");
84 84
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 @@
10 */ 10 */
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h> 13#include <linux/platform_device.h>
15#include <linux/slab.h> 14#include <linux/slab.h>
16#include <linux/leds.h> 15#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 @@
10 */ 10 */
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h> 13#include <linux/platform_device.h>
15#include <linux/leds.h> 14#include <linux/leds.h>
16#include <linux/err.h> 15#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 @@
26#include <linux/percpu.h> 26#include <linux/percpu.h>
27#include <linux/syscore_ops.h> 27#include <linux/syscore_ops.h>
28#include <linux/rwsem.h> 28#include <linux/rwsem.h>
29#include <linux/cpu.h>
29#include "../leds.h" 30#include "../leds.h"
30 31
31#define MAX_NAME_LEN 8 32#define MAX_NAME_LEN 8
@@ -92,6 +93,26 @@ static struct syscore_ops ledtrig_cpu_syscore_ops = {
92 .resume = ledtrig_cpu_syscore_resume, 93 .resume = ledtrig_cpu_syscore_resume,
93}; 94};
94 95
96static int ledtrig_cpu_notify(struct notifier_block *self,
97 unsigned long action, void *hcpu)
98{
99 switch (action & ~CPU_TASKS_FROZEN) {
100 case CPU_STARTING:
101 ledtrig_cpu(CPU_LED_START);
102 break;
103 case CPU_DYING:
104 ledtrig_cpu(CPU_LED_STOP);
105 break;
106 }
107
108 return NOTIFY_OK;
109}
110
111
112static struct notifier_block ledtrig_cpu_nb = {
113 .notifier_call = ledtrig_cpu_notify,
114};
115
95static int __init ledtrig_cpu_init(void) 116static int __init ledtrig_cpu_init(void)
96{ 117{
97 int cpu; 118 int cpu;
@@ -113,6 +134,7 @@ static int __init ledtrig_cpu_init(void)
113 } 134 }
114 135
115 register_syscore_ops(&ledtrig_cpu_syscore_ops); 136 register_syscore_ops(&ledtrig_cpu_syscore_ops);
137 register_cpu_notifier(&ledtrig_cpu_nb);
116 138
117 pr_info("ledtrig-cpu: registered to indicate activity on CPUs\n"); 139 pr_info("ledtrig-cpu: registered to indicate activity on CPUs\n");
118 140
@@ -124,6 +146,8 @@ static void __exit ledtrig_cpu_exit(void)
124{ 146{
125 int cpu; 147 int cpu;
126 148
149 unregister_cpu_notifier(&ledtrig_cpu_nb);
150
127 for_each_possible_cpu(cpu) { 151 for_each_possible_cpu(cpu) {
128 struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); 152 struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu);
129 153