aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/leds/00-INDEX2
-rw-r--r--Documentation/leds/leds-blinkm.txt80
-rw-r--r--Documentation/leds/leds-lm3556.txt85
-rw-r--r--Documentation/leds/ledtrig-oneshot.txt59
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/leds/Kconfig39
-rw-r--r--drivers/leds/Makefile4
-rw-r--r--drivers/leds/led-class.c27
-rw-r--r--drivers/leds/led-core.c66
-rw-r--r--drivers/leds/led-triggers.c114
-rw-r--r--drivers/leds/leds-88pm860x.c9
-rw-r--r--drivers/leds/leds-adp5520.c8
-rw-r--r--drivers/leds/leds-asic3.c16
-rw-r--r--drivers/leds/leds-atmel-pwm.c5
-rw-r--r--drivers/leds/leds-bd2802.c8
-rw-r--r--drivers/leds/leds-blinkm.c815
-rw-r--r--drivers/leds/leds-da903x.c9
-rw-r--r--drivers/leds/leds-dac124s085.c4
-rw-r--r--drivers/leds/leds-gpio.c11
-rw-r--r--drivers/leds/leds-lm3530.c24
-rw-r--r--drivers/leds/leds-lm3556.c512
-rw-r--r--drivers/leds/leds-lp3944.c9
-rw-r--r--drivers/leds/leds-lp5521.c20
-rw-r--r--drivers/leds/leds-lp5523.c30
-rw-r--r--drivers/leds/leds-lp8788.c193
-rw-r--r--drivers/leds/leds-lt3593.c9
-rw-r--r--drivers/leds/leds-max8997.c93
-rw-r--r--drivers/leds/leds-mc13783.c9
-rw-r--r--drivers/leds/leds-netxbig.c10
-rw-r--r--drivers/leds/leds-ns2.c19
-rw-r--r--drivers/leds/leds-pca9532.c10
-rw-r--r--drivers/leds/leds-pca955x.c18
-rw-r--r--drivers/leds/leds-pca9633.c6
-rw-r--r--drivers/leds/leds-pwm.c7
-rw-r--r--drivers/leds/leds-regulator.c9
-rw-r--r--drivers/leds/leds-renesas-tpu.c23
-rw-r--r--drivers/leds/leds-s3c24xx.c44
-rw-r--r--drivers/leds/leds-sunfire.c21
-rw-r--r--drivers/leds/leds-tca6507.c17
-rw-r--r--drivers/leds/leds.h2
-rw-r--r--drivers/leds/ledtrig-backlight.c8
-rw-r--r--drivers/leds/ledtrig-default-on.c2
-rw-r--r--drivers/leds/ledtrig-gpio.c6
-rw-r--r--drivers/leds/ledtrig-heartbeat.c2
-rw-r--r--drivers/leds/ledtrig-ide-disk.c25
-rw-r--r--drivers/leds/ledtrig-oneshot.c204
-rw-r--r--drivers/leds/ledtrig-timer.c2
-rw-r--r--drivers/leds/ledtrig-transient.c8
-rw-r--r--include/linux/leds.h29
-rw-r--r--include/linux/platform_data/leds-lm3556.h50
-rw-r--r--net/mac80211/led.c2
51 files changed, 2376 insertions, 413 deletions
diff --git a/Documentation/leds/00-INDEX b/Documentation/leds/00-INDEX
index 29f481df32c7..5fefe374892f 100644
--- a/Documentation/leds/00-INDEX
+++ b/Documentation/leds/00-INDEX
@@ -6,3 +6,5 @@ leds-lp5521.txt
6 - notes on how to use the leds-lp5521 driver. 6 - notes on how to use the leds-lp5521 driver.
7leds-lp5523.txt 7leds-lp5523.txt
8 - notes on how to use the leds-lp5523 driver. 8 - notes on how to use the leds-lp5523 driver.
9leds-lm3556.txt
10 - notes on how to use the leds-lm3556 driver.
diff --git a/Documentation/leds/leds-blinkm.txt b/Documentation/leds/leds-blinkm.txt
new file mode 100644
index 000000000000..9dd92f4cf4e1
--- /dev/null
+++ b/Documentation/leds/leds-blinkm.txt
@@ -0,0 +1,80 @@
1The leds-blinkm driver supports the devices of the BlinkM family.
2
3They are RGB-LED modules driven by a (AT)tiny microcontroller and
4communicate through I2C. The default address of these modules is
50x09 but this can be changed through a command. By this you could
6dasy-chain up to 127 BlinkMs on an I2C bus.
7
8The device accepts RGB and HSB color values through separate commands.
9Also you can store blinking sequences as "scripts" in
10the controller and run them. Also fading is an option.
11
12The interface this driver provides is 2-fold:
13
14a) LED class interface for use with triggers
15############################################
16
17The registration follows the scheme:
18blinkm-<i2c-bus-nr>-<i2c-device-nr>-<color>
19
20$ ls -h /sys/class/leds/blinkm-6-*
21/sys/class/leds/blinkm-6-9-blue:
22brightness device max_brightness power subsystem trigger uevent
23
24/sys/class/leds/blinkm-6-9-green:
25brightness device max_brightness power subsystem trigger uevent
26
27/sys/class/leds/blinkm-6-9-red:
28brightness device max_brightness power subsystem trigger uevent
29
30(same is /sys/bus/i2c/devices/6-0009/leds)
31
32We can control the colors separated into red, green and blue and
33assign triggers on each color.
34
35E.g.:
36
37$ cat blinkm-6-9-blue/brightness
3805
39
40$ echo 200 > blinkm-6-9-blue/brightness
41$
42
43$ modprobe ledtrig-heartbeat
44$ echo heartbeat > blinkm-6-9-green/trigger
45$
46
47
48b) Sysfs group to control rgb, fade, hsb, scripts ...
49#####################################################
50
51This extended interface is available as folder blinkm
52in the sysfs folder of the I2C device.
53E.g. below /sys/bus/i2c/devices/6-0009/blinkm
54
55$ ls -h /sys/bus/i2c/devices/6-0009/blinkm/
56blue green red test
57
58Currently supported is just setting red, green, blue
59and a test sequence.
60
61E.g.:
62
63$ cat *
6400
6500
6600
67#Write into test to start test sequence!#
68
69$ echo 1 > test
70$
71
72$ echo 255 > red
73$
74
75
76
77as of 6/2012
78
79dl9pf <at> gmx <dot> de
80
diff --git a/Documentation/leds/leds-lm3556.txt b/Documentation/leds/leds-lm3556.txt
new file mode 100644
index 000000000000..d9eb91b51913
--- /dev/null
+++ b/Documentation/leds/leds-lm3556.txt
@@ -0,0 +1,85 @@
1Kernel driver for lm3556
2========================
3
4*Texas Instrument:
5 1.5 A Synchronous Boost LED Flash Driver w/ High-Side Current Source
6* Datasheet: http://www.national.com/ds/LM/LM3556.pdf
7
8Authors:
9 Daniel Jeong
10 Contact:Daniel Jeong(daniel.jeong-at-ti.com, gshark.jeong-at-gmail.com)
11
12Description
13-----------
14There are 3 functions in LM3556, Flash, Torch and Indicator.
15
16FLASH MODE
17In Flash Mode, the LED current source(LED) provides 16 target current levels
18from 93.75 mA to 1500 mA.The Flash currents are adjusted via the CURRENT
19CONTROL REGISTER(0x09).Flash mode is activated by the ENABLE REGISTER(0x0A),
20or by pulling the STROBE pin HIGH.
21LM3556 Flash can be controlled through sys/class/leds/flash/brightness file
22* if STROBE pin is enabled, below example control brightness only, and
23ON / OFF will be controlled by STROBE pin.
24
25Flash Example:
26OFF : #echo 0 > sys/class/leds/flash/brightness
2793.75 mA: #echo 1 > sys/class/leds/flash/brightness
28... .....
291500 mA: #echo 16 > sys/class/leds/flash/brightness
30
31TORCH MODE
32In Torch Mode, the current source(LED) is programmed via the CURRENT CONTROL
33REGISTER(0x09).Torch Mode is activated by the ENABLE REGISTER(0x0A) or by the
34hardware TORCH input.
35LM3556 torch can be controlled through sys/class/leds/torch/brightness file.
36* if TORCH pin is enabled, below example control brightness only,
37and ON / OFF will be controlled by TORCH pin.
38
39Torch Example:
40OFF : #echo 0 > sys/class/leds/torch/brightness
4146.88 mA: #echo 1 > sys/class/leds/torch/brightness
42... .....
43375 mA : #echo 8 > sys/class/leds/torch/brightness
44
45INDICATOR MODE
46Indicator pattern can be set through sys/class/leds/indicator/pattern file,
47and 4 patterns are pre-defined in indicator_pattern array.
48According to N-lank, Pulse time and N Period values, different pattern wiill
49be generated.If you want new patterns for your own device, change
50indicator_pattern array with your own values and INDIC_PATTERN_SIZE.
51Please refer datasheet for more detail about N-Blank, Pulse time and N Period.
52
53Indicator pattern example:
54pattern 0: #echo 0 > sys/class/leds/indicator/pattern
55....
56pattern 3: #echo 3 > sys/class/leds/indicator/pattern
57
58Indicator brightness can be controlled through
59sys/class/leds/indicator/brightness file.
60
61Example:
62OFF : #echo 0 > sys/class/leds/indicator/brightness
635.86 mA : #echo 1 > sys/class/leds/indicator/brightness
64........
6546.875mA : #echo 8 > sys/class/leds/indicator/brightness
66
67Notes
68-----
69Driver expects it is registered using the i2c_board_info mechanism.
70To register the chip at address 0x63 on specific adapter, set the platform data
71according to include/linux/platform_data/leds-lm3556.h, set the i2c board info
72
73Example:
74 static struct i2c_board_info __initdata board_i2c_ch4[] = {
75 {
76 I2C_BOARD_INFO(LM3556_NAME, 0x63),
77 .platform_data = &lm3556_pdata,
78 },
79 };
80
81and register it in the platform init function
82
83Example:
84 board_register_i2c_bus(4, 400,
85 board_i2c_ch4, ARRAY_SIZE(board_i2c_ch4));
diff --git a/Documentation/leds/ledtrig-oneshot.txt b/Documentation/leds/ledtrig-oneshot.txt
new file mode 100644
index 000000000000..07cd1fa41a3a
--- /dev/null
+++ b/Documentation/leds/ledtrig-oneshot.txt
@@ -0,0 +1,59 @@
1One-shot LED Trigger
2====================
3
4This is a LED trigger useful for signaling the user of an event where there are
5no clear trap points to put standard led-on and led-off settings. Using this
6trigger, the application needs only to signal the trigger when an event has
7happened, than the trigger turns the LED on and than keeps it off for a
8specified amount of time.
9
10This trigger is meant to be usable both for sporadic and dense events. In the
11first case, the trigger produces a clear single controlled blink for each
12event, while in the latter it keeps blinking at constant rate, as to signal
13that the events are arriving continuously.
14
15A one-shot LED only stays in a constant state when there are no events. An
16additional "invert" property specifies if the LED has to stay off (normal) or
17on (inverted) when not rearmed.
18
19The trigger can be activated from user space on led class devices as shown
20below:
21
22 echo oneshot > trigger
23
24This adds the following sysfs attributes to the LED:
25
26 delay_on - specifies for how many milliseconds the LED has to stay at
27 LED_FULL brightness after it has been armed.
28 Default to 100 ms.
29
30 delay_off - specifies for how many milliseconds the LED has to stay at
31 LED_OFF brightness after it has been armed.
32 Default to 100 ms.
33
34 invert - reverse the blink logic. If set to 0 (default) blink on for delay_on
35 ms, then blink off for delay_off ms, leaving the LED normally off. If
36 set to 1, blink off for delay_off ms, then blink on for delay_on ms,
37 leaving the LED normally on.
38 Setting this value also immediately change the LED state.
39
40 shot - write any non-empty string to signal an events, this starts a blink
41 sequence if not already running.
42
43Example use-case: network devices, initialization:
44
45 echo oneshot > trigger # set trigger for this led
46 echo 33 > delay_on # blink at 1 / (33 + 33) Hz on continuous traffic
47 echo 33 > delay_off
48
49interface goes up:
50
51 echo 1 > invert # set led as normally-on, turn the led on
52
53packet received/transmitted:
54
55 echo 1 > shot # led starts blinking, ignored if already blinking
56
57interface goes down
58
59 echo 0 > invert # set led as normally-off, turn the led off
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f363b005226..3bc49687b653 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1529,6 +1529,11 @@ W: http://blackfin.uclinux.org/
1529S: Supported 1529S: Supported
1530F: drivers/i2c/busses/i2c-bfin-twi.c 1530F: drivers/i2c/busses/i2c-bfin-twi.c
1531 1531
1532BLINKM RGB LED DRIVER
1533M: Jan-Simon Moeller <jansimon.moeller@gmx.de>
1534S: Maintained
1535F: drivers/leds/leds-blinkm.c
1536
1532BLOCK LAYER 1537BLOCK LAYER
1533M: Jens Axboe <axboe@kernel.dk> 1538M: Jens Axboe <axboe@kernel.dk>
1534T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git 1539T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 12b2b55c519e..c96bbaadeebd 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -200,6 +200,13 @@ config LEDS_LP5523
200 Driver provides direct control via LED class and interface for 200 Driver provides direct control via LED class and interface for
201 programming the engines. 201 programming the engines.
202 202
203config LEDS_LP8788
204 tristate "LED support for the TI LP8788 PMIC"
205 depends on LEDS_CLASS
206 depends on MFD_LP8788
207 help
208 This option enables support for the Keyboard LEDs on the LP8788 PMIC.
209
203config LEDS_CLEVO_MAIL 210config LEDS_CLEVO_MAIL
204 tristate "Mail LED on Clevo notebook" 211 tristate "Mail LED on Clevo notebook"
205 depends on LEDS_CLASS 212 depends on LEDS_CLASS
@@ -415,6 +422,14 @@ config LEDS_MAX8997
415 This option enables support for on-chip LED drivers on 422 This option enables support for on-chip LED drivers on
416 MAXIM MAX8997 PMIC. 423 MAXIM MAX8997 PMIC.
417 424
425config LEDS_LM3556
426 tristate "LED support for LM3556 Chip"
427 depends on LEDS_CLASS && I2C
428 select REGMAP_I2C
429 help
430 This option enables support for LEDs connected to LM3556.
431 LM3556 includes Torch, Flash and Indicator functions.
432
418config LEDS_OT200 433config LEDS_OT200
419 tristate "LED support for the Bachmann OT200" 434 tristate "LED support for the Bachmann OT200"
420 depends on LEDS_CLASS && HAS_IOMEM 435 depends on LEDS_CLASS && HAS_IOMEM
@@ -422,6 +437,14 @@ config LEDS_OT200
422 This option enables support for the LEDs on the Bachmann OT200. 437 This option enables support for the LEDs on the Bachmann OT200.
423 Say Y to enable LEDs on the Bachmann OT200. 438 Say Y to enable LEDs on the Bachmann OT200.
424 439
440config LEDS_BLINKM
441 tristate "LED support for the BlinkM I2C RGB LED"
442 depends on LEDS_CLASS
443 depends on I2C
444 help
445 This option enables support for the BlinkM RGB LED connected
446 through I2C. Say Y to enable support for the BlinkM LED.
447
425config LEDS_TRIGGERS 448config LEDS_TRIGGERS
426 bool "LED Trigger support" 449 bool "LED Trigger support"
427 depends on LEDS_CLASS 450 depends on LEDS_CLASS
@@ -443,6 +466,20 @@ config LEDS_TRIGGER_TIMER
443 466
444 If unsure, say Y. 467 If unsure, say Y.
445 468
469config LEDS_TRIGGER_ONESHOT
470 tristate "LED One-shot Trigger"
471 depends on LEDS_TRIGGERS
472 help
473 This allows LEDs to blink in one-shot pulses with parameters
474 controlled via sysfs. It's useful to notify the user on
475 sporadic events, when there are no clear begin and end trap points,
476 or on dense events, where this blinks the LED at constant rate if
477 rearmed continuously.
478
479 It also shows how to use the led_blink_set_oneshot() function.
480
481 If unsure, say Y.
482
446config LEDS_TRIGGER_IDE_DISK 483config LEDS_TRIGGER_IDE_DISK
447 bool "LED IDE Disk Trigger" 484 bool "LED IDE Disk Trigger"
448 depends on IDE_GD_ATA 485 depends on IDE_GD_ATA
@@ -497,7 +534,7 @@ config LEDS_TRIGGER_TRANSIENT
497 depends on LEDS_TRIGGERS 534 depends on LEDS_TRIGGERS
498 help 535 help
499 This allows one time activation of a transient state on 536 This allows one time activation of a transient state on
500 GPIO/PWM based hadrware. 537 GPIO/PWM based hardware.
501 If unsure, say Y. 538 If unsure, say Y.
502 539
503endif # NEW_LEDS 540endif # NEW_LEDS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index f8958cd6cf6e..a4429a9217bc 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
24obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o 24obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o
25obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o 25obj-$(CONFIG_LEDS_LP5521) += leds-lp5521.o
26obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o 26obj-$(CONFIG_LEDS_LP5523) += leds-lp5523.o
27obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
27obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o 28obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
28obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o 29obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
29obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o 30obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
@@ -47,12 +48,15 @@ obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
47obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o 48obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
48obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o 49obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o
49obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o 50obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
51obj-$(CONFIG_LEDS_LM3556) += leds-lm3556.o
52obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o
50 53
51# LED SPI Drivers 54# LED SPI Drivers
52obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o 55obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
53 56
54# LED Triggers 57# LED Triggers
55obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o 58obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
59obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
56obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o 60obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
57obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o 61obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
58obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o 62obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index e663e6f413e9..c599095bc005 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -53,7 +53,7 @@ static ssize_t led_brightness_store(struct device *dev,
53 53
54 if (state == LED_OFF) 54 if (state == LED_OFF)
55 led_trigger_remove(led_cdev); 55 led_trigger_remove(led_cdev);
56 led_set_brightness(led_cdev, state); 56 __led_set_brightness(led_cdev, state);
57 57
58 return size; 58 return size;
59} 59}
@@ -82,7 +82,12 @@ static void led_timer_function(unsigned long data)
82 unsigned long delay; 82 unsigned long delay;
83 83
84 if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { 84 if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
85 led_set_brightness(led_cdev, LED_OFF); 85 __led_set_brightness(led_cdev, LED_OFF);
86 return;
87 }
88
89 if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) {
90 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
86 return; 91 return;
87 } 92 }
88 93
@@ -100,7 +105,21 @@ static void led_timer_function(unsigned long data)
100 delay = led_cdev->blink_delay_off; 105 delay = led_cdev->blink_delay_off;
101 } 106 }
102 107
103 led_set_brightness(led_cdev, brightness); 108 __led_set_brightness(led_cdev, brightness);
109
110 /* Return in next iteration if led is in one-shot mode and we are in
111 * the final blink state so that the led is toggled each delay_on +
112 * delay_off milliseconds in worst case.
113 */
114 if (led_cdev->flags & LED_BLINK_ONESHOT) {
115 if (led_cdev->flags & LED_BLINK_INVERT) {
116 if (brightness)
117 led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
118 } else {
119 if (!brightness)
120 led_cdev->flags |= LED_BLINK_ONESHOT_STOP;
121 }
122 }
104 123
105 mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); 124 mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
106} 125}
@@ -203,7 +222,7 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
203#endif 222#endif
204 223
205 /* Stop blinking */ 224 /* Stop blinking */
206 led_brightness_set(led_cdev, LED_OFF); 225 led_set_brightness(led_cdev, LED_OFF);
207 226
208 device_unregister(led_cdev->dev); 227 device_unregister(led_cdev->dev);
209 228
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index d65353d8d3fc..2ab05af3de31 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -24,14 +24,6 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
24LIST_HEAD(leds_list); 24LIST_HEAD(leds_list);
25EXPORT_SYMBOL_GPL(leds_list); 25EXPORT_SYMBOL_GPL(leds_list);
26 26
27static void led_stop_software_blink(struct led_classdev *led_cdev)
28{
29 /* deactivate previous settings */
30 del_timer_sync(&led_cdev->blink_timer);
31 led_cdev->blink_delay_on = 0;
32 led_cdev->blink_delay_off = 0;
33}
34
35static void led_set_software_blink(struct led_classdev *led_cdev, 27static void led_set_software_blink(struct led_classdev *led_cdev,
36 unsigned long delay_on, 28 unsigned long delay_on,
37 unsigned long delay_off) 29 unsigned long delay_off)
@@ -53,7 +45,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev,
53 45
54 /* never off - just set to brightness */ 46 /* never off - just set to brightness */
55 if (!delay_off) { 47 if (!delay_off) {
56 led_set_brightness(led_cdev, led_cdev->blink_brightness); 48 __led_set_brightness(led_cdev, led_cdev->blink_brightness);
57 return; 49 return;
58 } 50 }
59 51
@@ -61,13 +53,12 @@ static void led_set_software_blink(struct led_classdev *led_cdev,
61} 53}
62 54
63 55
64void led_blink_set(struct led_classdev *led_cdev, 56static void led_blink_setup(struct led_classdev *led_cdev,
65 unsigned long *delay_on, 57 unsigned long *delay_on,
66 unsigned long *delay_off) 58 unsigned long *delay_off)
67{ 59{
68 del_timer_sync(&led_cdev->blink_timer); 60 if (!(led_cdev->flags & LED_BLINK_ONESHOT) &&
69 61 led_cdev->blink_set &&
70 if (led_cdev->blink_set &&
71 !led_cdev->blink_set(led_cdev, delay_on, delay_off)) 62 !led_cdev->blink_set(led_cdev, delay_on, delay_off))
72 return; 63 return;
73 64
@@ -77,12 +68,49 @@ void led_blink_set(struct led_classdev *led_cdev,
77 68
78 led_set_software_blink(led_cdev, *delay_on, *delay_off); 69 led_set_software_blink(led_cdev, *delay_on, *delay_off);
79} 70}
71
72void led_blink_set(struct led_classdev *led_cdev,
73 unsigned long *delay_on,
74 unsigned long *delay_off)
75{
76 del_timer_sync(&led_cdev->blink_timer);
77
78 led_cdev->flags &= ~LED_BLINK_ONESHOT;
79 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
80
81 led_blink_setup(led_cdev, delay_on, delay_off);
82}
80EXPORT_SYMBOL(led_blink_set); 83EXPORT_SYMBOL(led_blink_set);
81 84
82void led_brightness_set(struct led_classdev *led_cdev, 85void led_blink_set_oneshot(struct led_classdev *led_cdev,
86 unsigned long *delay_on,
87 unsigned long *delay_off,
88 int invert)
89{
90 if ((led_cdev->flags & LED_BLINK_ONESHOT) &&
91 timer_pending(&led_cdev->blink_timer))
92 return;
93
94 led_cdev->flags |= LED_BLINK_ONESHOT;
95 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
96
97 if (invert)
98 led_cdev->flags |= LED_BLINK_INVERT;
99 else
100 led_cdev->flags &= ~LED_BLINK_INVERT;
101
102 led_blink_setup(led_cdev, delay_on, delay_off);
103}
104EXPORT_SYMBOL(led_blink_set_oneshot);
105
106void led_set_brightness(struct led_classdev *led_cdev,
83 enum led_brightness brightness) 107 enum led_brightness brightness)
84{ 108{
85 led_stop_software_blink(led_cdev); 109 /* stop and clear soft-blink timer */
86 led_cdev->brightness_set(led_cdev, brightness); 110 del_timer_sync(&led_cdev->blink_timer);
111 led_cdev->blink_delay_on = 0;
112 led_cdev->blink_delay_off = 0;
113
114 __led_set_brightness(led_cdev, brightness);
87} 115}
88EXPORT_SYMBOL(led_brightness_set); 116EXPORT_SYMBOL(led_set_brightness);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 46b4c766335d..6157cbbf4113 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -99,7 +99,7 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
99EXPORT_SYMBOL_GPL(led_trigger_show); 99EXPORT_SYMBOL_GPL(led_trigger_show);
100 100
101/* Caller must ensure led_cdev->trigger_lock held */ 101/* Caller must ensure led_cdev->trigger_lock held */
102void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) 102void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
103{ 103{
104 unsigned long flags; 104 unsigned long flags;
105 105
@@ -112,15 +112,15 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
112 if (led_cdev->trigger->deactivate) 112 if (led_cdev->trigger->deactivate)
113 led_cdev->trigger->deactivate(led_cdev); 113 led_cdev->trigger->deactivate(led_cdev);
114 led_cdev->trigger = NULL; 114 led_cdev->trigger = NULL;
115 led_brightness_set(led_cdev, LED_OFF); 115 led_set_brightness(led_cdev, LED_OFF);
116 } 116 }
117 if (trigger) { 117 if (trig) {
118 write_lock_irqsave(&trigger->leddev_list_lock, flags); 118 write_lock_irqsave(&trig->leddev_list_lock, flags);
119 list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); 119 list_add_tail(&led_cdev->trig_list, &trig->led_cdevs);
120 write_unlock_irqrestore(&trigger->leddev_list_lock, flags); 120 write_unlock_irqrestore(&trig->leddev_list_lock, flags);
121 led_cdev->trigger = trigger; 121 led_cdev->trigger = trig;
122 if (trigger->activate) 122 if (trig->activate)
123 trigger->activate(led_cdev); 123 trig->activate(led_cdev);
124 } 124 }
125} 125}
126EXPORT_SYMBOL_GPL(led_trigger_set); 126EXPORT_SYMBOL_GPL(led_trigger_set);
@@ -153,24 +153,24 @@ EXPORT_SYMBOL_GPL(led_trigger_set_default);
153 153
154/* LED Trigger Interface */ 154/* LED Trigger Interface */
155 155
156int led_trigger_register(struct led_trigger *trigger) 156int led_trigger_register(struct led_trigger *trig)
157{ 157{
158 struct led_classdev *led_cdev; 158 struct led_classdev *led_cdev;
159 struct led_trigger *trig; 159 struct led_trigger *_trig;
160 160
161 rwlock_init(&trigger->leddev_list_lock); 161 rwlock_init(&trig->leddev_list_lock);
162 INIT_LIST_HEAD(&trigger->led_cdevs); 162 INIT_LIST_HEAD(&trig->led_cdevs);
163 163
164 down_write(&triggers_list_lock); 164 down_write(&triggers_list_lock);
165 /* Make sure the trigger's name isn't already in use */ 165 /* Make sure the trigger's name isn't already in use */
166 list_for_each_entry(trig, &trigger_list, next_trig) { 166 list_for_each_entry(_trig, &trigger_list, next_trig) {
167 if (!strcmp(trig->name, trigger->name)) { 167 if (!strcmp(_trig->name, trig->name)) {
168 up_write(&triggers_list_lock); 168 up_write(&triggers_list_lock);
169 return -EEXIST; 169 return -EEXIST;
170 } 170 }
171 } 171 }
172 /* Add to the list of led triggers */ 172 /* Add to the list of led triggers */
173 list_add_tail(&trigger->next_trig, &trigger_list); 173 list_add_tail(&trig->next_trig, &trigger_list);
174 up_write(&triggers_list_lock); 174 up_write(&triggers_list_lock);
175 175
176 /* Register with any LEDs that have this as a default trigger */ 176 /* Register with any LEDs that have this as a default trigger */
@@ -178,8 +178,8 @@ int led_trigger_register(struct led_trigger *trigger)
178 list_for_each_entry(led_cdev, &leds_list, node) { 178 list_for_each_entry(led_cdev, &leds_list, node) {
179 down_write(&led_cdev->trigger_lock); 179 down_write(&led_cdev->trigger_lock);
180 if (!led_cdev->trigger && led_cdev->default_trigger && 180 if (!led_cdev->trigger && led_cdev->default_trigger &&
181 !strcmp(led_cdev->default_trigger, trigger->name)) 181 !strcmp(led_cdev->default_trigger, trig->name))
182 led_trigger_set(led_cdev, trigger); 182 led_trigger_set(led_cdev, trig);
183 up_write(&led_cdev->trigger_lock); 183 up_write(&led_cdev->trigger_lock);
184 } 184 }
185 up_read(&leds_list_lock); 185 up_read(&leds_list_lock);
@@ -188,20 +188,20 @@ int led_trigger_register(struct led_trigger *trigger)
188} 188}
189EXPORT_SYMBOL_GPL(led_trigger_register); 189EXPORT_SYMBOL_GPL(led_trigger_register);
190 190
191void led_trigger_unregister(struct led_trigger *trigger) 191void led_trigger_unregister(struct led_trigger *trig)
192{ 192{
193 struct led_classdev *led_cdev; 193 struct led_classdev *led_cdev;
194 194
195 /* Remove from the list of led triggers */ 195 /* Remove from the list of led triggers */
196 down_write(&triggers_list_lock); 196 down_write(&triggers_list_lock);
197 list_del(&trigger->next_trig); 197 list_del(&trig->next_trig);
198 up_write(&triggers_list_lock); 198 up_write(&triggers_list_lock);
199 199
200 /* Remove anyone actively using this trigger */ 200 /* Remove anyone actively using this trigger */
201 down_read(&leds_list_lock); 201 down_read(&leds_list_lock);
202 list_for_each_entry(led_cdev, &leds_list, node) { 202 list_for_each_entry(led_cdev, &leds_list, node) {
203 down_write(&led_cdev->trigger_lock); 203 down_write(&led_cdev->trigger_lock);
204 if (led_cdev->trigger == trigger) 204 if (led_cdev->trigger == trig)
205 led_trigger_set(led_cdev, NULL); 205 led_trigger_set(led_cdev, NULL);
206 up_write(&led_cdev->trigger_lock); 206 up_write(&led_cdev->trigger_lock);
207 } 207 }
@@ -211,58 +211,80 @@ EXPORT_SYMBOL_GPL(led_trigger_unregister);
211 211
212/* Simple LED Tigger Interface */ 212/* Simple LED Tigger Interface */
213 213
214void led_trigger_event(struct led_trigger *trigger, 214void led_trigger_event(struct led_trigger *trig,
215 enum led_brightness brightness) 215 enum led_brightness brightness)
216{ 216{
217 struct list_head *entry; 217 struct list_head *entry;
218 218
219 if (!trigger) 219 if (!trig)
220 return; 220 return;
221 221
222 read_lock(&trigger->leddev_list_lock); 222 read_lock(&trig->leddev_list_lock);
223 list_for_each(entry, &trigger->led_cdevs) { 223 list_for_each(entry, &trig->led_cdevs) {
224 struct led_classdev *led_cdev; 224 struct led_classdev *led_cdev;
225 225
226 led_cdev = list_entry(entry, struct led_classdev, trig_list); 226 led_cdev = list_entry(entry, struct led_classdev, trig_list);
227 led_set_brightness(led_cdev, brightness); 227 led_set_brightness(led_cdev, brightness);
228 } 228 }
229 read_unlock(&trigger->leddev_list_lock); 229 read_unlock(&trig->leddev_list_lock);
230} 230}
231EXPORT_SYMBOL_GPL(led_trigger_event); 231EXPORT_SYMBOL_GPL(led_trigger_event);
232 232
233void led_trigger_blink(struct led_trigger *trigger, 233static void led_trigger_blink_setup(struct led_trigger *trig,
234 unsigned long *delay_on, 234 unsigned long *delay_on,
235 unsigned long *delay_off) 235 unsigned long *delay_off,
236 int oneshot,
237 int invert)
236{ 238{
237 struct list_head *entry; 239 struct list_head *entry;
238 240
239 if (!trigger) 241 if (!trig)
240 return; 242 return;
241 243
242 read_lock(&trigger->leddev_list_lock); 244 read_lock(&trig->leddev_list_lock);
243 list_for_each(entry, &trigger->led_cdevs) { 245 list_for_each(entry, &trig->led_cdevs) {
244 struct led_classdev *led_cdev; 246 struct led_classdev *led_cdev;
245 247
246 led_cdev = list_entry(entry, struct led_classdev, trig_list); 248 led_cdev = list_entry(entry, struct led_classdev, trig_list);
247 led_blink_set(led_cdev, delay_on, delay_off); 249 if (oneshot)
250 led_blink_set_oneshot(led_cdev, delay_on, delay_off,
251 invert);
252 else
253 led_blink_set(led_cdev, delay_on, delay_off);
248 } 254 }
249 read_unlock(&trigger->leddev_list_lock); 255 read_unlock(&trig->leddev_list_lock);
256}
257
258void led_trigger_blink(struct led_trigger *trig,
259 unsigned long *delay_on,
260 unsigned long *delay_off)
261{
262 led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0);
250} 263}
251EXPORT_SYMBOL_GPL(led_trigger_blink); 264EXPORT_SYMBOL_GPL(led_trigger_blink);
252 265
266void led_trigger_blink_oneshot(struct led_trigger *trig,
267 unsigned long *delay_on,
268 unsigned long *delay_off,
269 int invert)
270{
271 led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert);
272}
273EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot);
274
253void led_trigger_register_simple(const char *name, struct led_trigger **tp) 275void led_trigger_register_simple(const char *name, struct led_trigger **tp)
254{ 276{
255 struct led_trigger *trigger; 277 struct led_trigger *trig;
256 int err; 278 int err;
257 279
258 trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 280 trig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
259 281
260 if (trigger) { 282 if (trig) {
261 trigger->name = name; 283 trig->name = name;
262 err = led_trigger_register(trigger); 284 err = led_trigger_register(trig);
263 if (err < 0) { 285 if (err < 0) {
264 kfree(trigger); 286 kfree(trig);
265 trigger = NULL; 287 trig = NULL;
266 printk(KERN_WARNING "LED trigger %s failed to register" 288 printk(KERN_WARNING "LED trigger %s failed to register"
267 " (%d)\n", name, err); 289 " (%d)\n", name, err);
268 } 290 }
@@ -270,15 +292,15 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp)
270 printk(KERN_WARNING "LED trigger %s failed to register" 292 printk(KERN_WARNING "LED trigger %s failed to register"
271 " (no memory)\n", name); 293 " (no memory)\n", name);
272 294
273 *tp = trigger; 295 *tp = trig;
274} 296}
275EXPORT_SYMBOL_GPL(led_trigger_register_simple); 297EXPORT_SYMBOL_GPL(led_trigger_register_simple);
276 298
277void led_trigger_unregister_simple(struct led_trigger *trigger) 299void led_trigger_unregister_simple(struct led_trigger *trig)
278{ 300{
279 if (trigger) 301 if (trig)
280 led_trigger_unregister(trigger); 302 led_trigger_unregister(trig);
281 kfree(trigger); 303 kfree(trig);
282} 304}
283EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); 305EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
284 306
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 5b61aaf7ac0f..61897cfeeda6 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -209,7 +209,7 @@ static int pm860x_led_probe(struct platform_device *pdev)
209 return -EINVAL; 209 return -EINVAL;
210 } 210 }
211 211
212 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); 212 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL);
213 if (data == NULL) 213 if (data == NULL)
214 return -ENOMEM; 214 return -ENOMEM;
215 strncpy(data->name, res->name, MFD_NAME_SIZE - 1); 215 strncpy(data->name, res->name, MFD_NAME_SIZE - 1);
@@ -220,7 +220,6 @@ static int pm860x_led_probe(struct platform_device *pdev)
220 data->port = pdata->flags; 220 data->port = pdata->flags;
221 if (data->port < 0) { 221 if (data->port < 0) {
222 dev_err(&pdev->dev, "check device failed\n"); 222 dev_err(&pdev->dev, "check device failed\n");
223 kfree(data);
224 return -EINVAL; 223 return -EINVAL;
225 } 224 }
226 225
@@ -233,13 +232,10 @@ static int pm860x_led_probe(struct platform_device *pdev)
233 ret = led_classdev_register(chip->dev, &data->cdev); 232 ret = led_classdev_register(chip->dev, &data->cdev);
234 if (ret < 0) { 233 if (ret < 0) {
235 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 234 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
236 goto out; 235 return ret;
237 } 236 }
238 pm860x_led_set(&data->cdev, 0); 237 pm860x_led_set(&data->cdev, 0);
239 return 0; 238 return 0;
240out:
241 kfree(data);
242 return ret;
243} 239}
244 240
245static int pm860x_led_remove(struct platform_device *pdev) 241static int pm860x_led_remove(struct platform_device *pdev)
@@ -247,7 +243,6 @@ static int pm860x_led_remove(struct platform_device *pdev)
247 struct pm860x_led *data = platform_get_drvdata(pdev); 243 struct pm860x_led *data = platform_get_drvdata(pdev);
248 244
249 led_classdev_unregister(&data->cdev); 245 led_classdev_unregister(&data->cdev);
250 kfree(data);
251 246
252 return 0; 247 return 0;
253} 248}
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
index b1400db3f839..aa56a867693a 100644
--- a/drivers/leds/leds-adp5520.c
+++ b/drivers/leds/leds-adp5520.c
@@ -119,7 +119,8 @@ static int __devinit adp5520_led_probe(struct platform_device *pdev)
119 return -EFAULT; 119 return -EFAULT;
120 } 120 }
121 121
122 led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL); 122 led = devm_kzalloc(&pdev->dev, sizeof(*led) * pdata->num_leds,
123 GFP_KERNEL);
123 if (led == NULL) { 124 if (led == NULL) {
124 dev_err(&pdev->dev, "failed to alloc memory\n"); 125 dev_err(&pdev->dev, "failed to alloc memory\n");
125 return -ENOMEM; 126 return -ENOMEM;
@@ -129,7 +130,7 @@ static int __devinit adp5520_led_probe(struct platform_device *pdev)
129 130
130 if (ret) { 131 if (ret) {
131 dev_err(&pdev->dev, "failed to write\n"); 132 dev_err(&pdev->dev, "failed to write\n");
132 goto err_free; 133 return ret;
133 } 134 }
134 135
135 for (i = 0; i < pdata->num_leds; ++i) { 136 for (i = 0; i < pdata->num_leds; ++i) {
@@ -179,8 +180,6 @@ err:
179 } 180 }
180 } 181 }
181 182
182err_free:
183 kfree(led);
184 return ret; 183 return ret;
185} 184}
186 185
@@ -200,7 +199,6 @@ static int __devexit adp5520_led_remove(struct platform_device *pdev)
200 cancel_work_sync(&led[i].work); 199 cancel_work_sync(&led[i].work);
201 } 200 }
202 201
203 kfree(led);
204 return 0; 202 return 0;
205} 203}
206 204
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c
index 525a92492837..5de74ff90dcf 100644
--- a/drivers/leds/leds-asic3.c
+++ b/drivers/leds/leds-asic3.c
@@ -99,12 +99,13 @@ static int __devinit asic3_led_probe(struct platform_device *pdev)
99 99
100 ret = mfd_cell_enable(pdev); 100 ret = mfd_cell_enable(pdev);
101 if (ret < 0) 101 if (ret < 0)
102 goto ret0; 102 return ret;
103 103
104 led->cdev = kzalloc(sizeof(struct led_classdev), GFP_KERNEL); 104 led->cdev = devm_kzalloc(&pdev->dev, sizeof(struct led_classdev),
105 GFP_KERNEL);
105 if (!led->cdev) { 106 if (!led->cdev) {
106 ret = -ENOMEM; 107 ret = -ENOMEM;
107 goto ret1; 108 goto out;
108 } 109 }
109 110
110 led->cdev->name = led->name; 111 led->cdev->name = led->name;
@@ -115,15 +116,12 @@ static int __devinit asic3_led_probe(struct platform_device *pdev)
115 116
116 ret = led_classdev_register(&pdev->dev, led->cdev); 117 ret = led_classdev_register(&pdev->dev, led->cdev);
117 if (ret < 0) 118 if (ret < 0)
118 goto ret2; 119 goto out;
119 120
120 return 0; 121 return 0;
121 122
122ret2: 123out:
123 kfree(led->cdev);
124ret1:
125 (void) mfd_cell_disable(pdev); 124 (void) mfd_cell_disable(pdev);
126ret0:
127 return ret; 125 return ret;
128} 126}
129 127
@@ -133,8 +131,6 @@ static int __devexit asic3_led_remove(struct platform_device *pdev)
133 131
134 led_classdev_unregister(led->cdev); 132 led_classdev_unregister(led->cdev);
135 133
136 kfree(led->cdev);
137
138 return mfd_cell_disable(pdev); 134 return mfd_cell_disable(pdev);
139} 135}
140 136
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 64ad702a2ecc..45430632faab 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -46,7 +46,8 @@ static int __devinit pwmled_probe(struct platform_device *pdev)
46 if (!pdata || pdata->num_leds < 1) 46 if (!pdata || pdata->num_leds < 1)
47 return -ENODEV; 47 return -ENODEV;
48 48
49 leds = kcalloc(pdata->num_leds, sizeof(*leds), GFP_KERNEL); 49 leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds),
50 GFP_KERNEL);
50 if (!leds) 51 if (!leds)
51 return -ENOMEM; 52 return -ENOMEM;
52 53
@@ -108,7 +109,6 @@ err:
108 pwm_channel_free(&leds[i].pwmc); 109 pwm_channel_free(&leds[i].pwmc);
109 } 110 }
110 } 111 }
111 kfree(leds);
112 112
113 return status; 113 return status;
114} 114}
@@ -129,7 +129,6 @@ static int __exit pwmled_remove(struct platform_device *pdev)
129 pwm_channel_free(&led->pwmc); 129 pwm_channel_free(&led->pwmc);
130 } 130 }
131 131
132 kfree(leds);
133 platform_set_drvdata(pdev, NULL); 132 platform_set_drvdata(pdev, NULL);
134 return 0; 133 return 0;
135} 134}
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 591cbdf5a046..89ca6a2a19d1 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -677,7 +677,7 @@ static int __devinit bd2802_probe(struct i2c_client *client,
677 struct bd2802_led_platform_data *pdata; 677 struct bd2802_led_platform_data *pdata;
678 int ret, i; 678 int ret, i;
679 679
680 led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL); 680 led = devm_kzalloc(&client->dev, sizeof(struct bd2802_led), GFP_KERNEL);
681 if (!led) { 681 if (!led) {
682 dev_err(&client->dev, "failed to allocate driver data\n"); 682 dev_err(&client->dev, "failed to allocate driver data\n");
683 return -ENOMEM; 683 return -ENOMEM;
@@ -697,7 +697,7 @@ static int __devinit bd2802_probe(struct i2c_client *client,
697 ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00); 697 ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
698 if (ret < 0) { 698 if (ret < 0) {
699 dev_err(&client->dev, "failed to detect device\n"); 699 dev_err(&client->dev, "failed to detect device\n");
700 goto failed_free; 700 return ret;
701 } else 701 } else
702 dev_info(&client->dev, "return 0x%02x\n", ret); 702 dev_info(&client->dev, "return 0x%02x\n", ret);
703 703
@@ -729,9 +729,6 @@ static int __devinit bd2802_probe(struct i2c_client *client,
729failed_unregister_dev_file: 729failed_unregister_dev_file:
730 for (i--; i >= 0; i--) 730 for (i--; i >= 0; i--)
731 device_remove_file(&led->client->dev, bd2802_attributes[i]); 731 device_remove_file(&led->client->dev, bd2802_attributes[i]);
732failed_free:
733 kfree(led);
734
735 return ret; 732 return ret;
736} 733}
737 734
@@ -746,7 +743,6 @@ static int __exit bd2802_remove(struct i2c_client *client)
746 bd2802_disable_adv_conf(led); 743 bd2802_disable_adv_conf(led);
747 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) 744 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++)
748 device_remove_file(&led->client->dev, bd2802_attributes[i]); 745 device_remove_file(&led->client->dev, bd2802_attributes[i]);
749 kfree(led);
750 746
751 return 0; 747 return 0;
752} 748}
diff --git a/drivers/leds/leds-blinkm.c b/drivers/leds/leds-blinkm.c
new file mode 100644
index 000000000000..f7c3d7f1ec52
--- /dev/null
+++ b/drivers/leds/leds-blinkm.c
@@ -0,0 +1,815 @@
1/*
2 * leds-blinkm.c
3 * (c) Jan-Simon Möller (dl9pf@gmx.de)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/jiffies.h>
24#include <linux/i2c.h>
25#include <linux/err.h>
26#include <linux/mutex.h>
27#include <linux/sysfs.h>
28#include <linux/printk.h>
29#include <linux/pm_runtime.h>
30#include <linux/leds.h>
31#include <linux/delay.h>
32
33/* Addresses to scan - BlinkM is on 0x09 by default*/
34static const unsigned short normal_i2c[] = { 0x09, I2C_CLIENT_END };
35
36static int blinkm_transfer_hw(struct i2c_client *client, int cmd);
37static int blinkm_test_run(struct i2c_client *client);
38
39struct blinkm_led {
40 struct i2c_client *i2c_client;
41 struct led_classdev led_cdev;
42 int id;
43 atomic_t active;
44};
45
46struct blinkm_work {
47 struct blinkm_led *blinkm_led;
48 struct work_struct work;
49};
50
51#define cdev_to_blmled(c) container_of(c, struct blinkm_led, led_cdev)
52#define work_to_blmwork(c) container_of(c, struct blinkm_work, work)
53
54struct blinkm_data {
55 struct i2c_client *i2c_client;
56 struct mutex update_lock;
57 /* used for led class interface */
58 struct blinkm_led blinkm_leds[3];
59 /* used for "blinkm" sysfs interface */
60 u8 red; /* color red */
61 u8 green; /* color green */
62 u8 blue; /* color blue */
63 /* next values to use for transfer */
64 u8 next_red; /* color red */
65 u8 next_green; /* color green */
66 u8 next_blue; /* color blue */
67 /* internal use */
68 u8 args[7]; /* set of args for transmission */
69 u8 i2c_addr; /* i2c addr */
70 u8 fw_ver; /* firmware version */
71 /* used, but not from userspace */
72 u8 hue; /* HSB hue */
73 u8 saturation; /* HSB saturation */
74 u8 brightness; /* HSB brightness */
75 u8 next_hue; /* HSB hue */
76 u8 next_saturation; /* HSB saturation */
77 u8 next_brightness; /* HSB brightness */
78 /* currently unused / todo */
79 u8 fade_speed; /* fade speed 1 - 255 */
80 s8 time_adjust; /* time adjust -128 - 127 */
81 u8 fade:1; /* fade on = 1, off = 0 */
82 u8 rand:1; /* rand fade mode on = 1 */
83 u8 script_id; /* script ID */
84 u8 script_repeats; /* repeats of script */
85 u8 script_startline; /* line to start */
86};
87
88/* Colors */
89#define RED 0
90#define GREEN 1
91#define BLUE 2
92
93/* mapping command names to cmd chars - see datasheet */
94#define BLM_GO_RGB 0
95#define BLM_FADE_RGB 1
96#define BLM_FADE_HSB 2
97#define BLM_FADE_RAND_RGB 3
98#define BLM_FADE_RAND_HSB 4
99#define BLM_PLAY_SCRIPT 5
100#define BLM_STOP_SCRIPT 6
101#define BLM_SET_FADE_SPEED 7
102#define BLM_SET_TIME_ADJ 8
103#define BLM_GET_CUR_RGB 9
104#define BLM_WRITE_SCRIPT_LINE 10
105#define BLM_READ_SCRIPT_LINE 11
106#define BLM_SET_SCRIPT_LR 12 /* Length & Repeats */
107#define BLM_SET_ADDR 13
108#define BLM_GET_ADDR 14
109#define BLM_GET_FW_VER 15
110#define BLM_SET_STARTUP_PARAM 16
111
112/* BlinkM Commands
113 * as extracted out of the datasheet:
114 *
115 * cmdchar = command (ascii)
116 * cmdbyte = command in hex
117 * nr_args = number of arguments (to send)
118 * nr_ret = number of return values (to read)
119 * dir = direction (0 = read, 1 = write, 2 = both)
120 *
121 */
122static const struct {
123 char cmdchar;
124 u8 cmdbyte;
125 u8 nr_args;
126 u8 nr_ret;
127 u8 dir:2;
128} blinkm_cmds[17] = {
129 /* cmdchar, cmdbyte, nr_args, nr_ret, dir */
130 { 'n', 0x6e, 3, 0, 1},
131 { 'c', 0x63, 3, 0, 1},
132 { 'h', 0x68, 3, 0, 1},
133 { 'C', 0x43, 3, 0, 1},
134 { 'H', 0x48, 3, 0, 1},
135 { 'p', 0x70, 3, 0, 1},
136 { 'o', 0x6f, 0, 0, 1},
137 { 'f', 0x66, 1, 0, 1},
138 { 't', 0x74, 1, 0, 1},
139 { 'g', 0x67, 0, 3, 0},
140 { 'W', 0x57, 7, 0, 1},
141 { 'R', 0x52, 2, 5, 2},
142 { 'L', 0x4c, 3, 0, 1},
143 { 'A', 0x41, 4, 0, 1},
144 { 'a', 0x61, 0, 1, 0},
145 { 'Z', 0x5a, 0, 1, 0},
146 { 'B', 0x42, 5, 0, 1},
147};
148
149static ssize_t show_color_common(struct device *dev, char *buf, int color)
150{
151 struct i2c_client *client;
152 struct blinkm_data *data;
153 int ret;
154
155 client = to_i2c_client(dev);
156 data = i2c_get_clientdata(client);
157
158 ret = blinkm_transfer_hw(client, BLM_GET_CUR_RGB);
159 if (ret < 0)
160 return ret;
161 switch (color) {
162 case RED:
163 return scnprintf(buf, PAGE_SIZE, "%02X\n", data->red);
164 break;
165 case GREEN:
166 return scnprintf(buf, PAGE_SIZE, "%02X\n", data->green);
167 break;
168 case BLUE:
169 return scnprintf(buf, PAGE_SIZE, "%02X\n", data->blue);
170 break;
171 default:
172 return -EINVAL;
173 }
174 return -EINVAL;
175}
176
177static int store_color_common(struct device *dev, const char *buf, int color)
178{
179 struct i2c_client *client;
180 struct blinkm_data *data;
181 int ret;
182 u8 value;
183
184 client = to_i2c_client(dev);
185 data = i2c_get_clientdata(client);
186
187 ret = kstrtou8(buf, 10, &value);
188 if (ret < 0) {
189 dev_err(dev, "BlinkM: value too large!\n");
190 return ret;
191 }
192
193 switch (color) {
194 case RED:
195 data->next_red = value;
196 break;
197 case GREEN:
198 data->next_green = value;
199 break;
200 case BLUE:
201 data->next_blue = value;
202 break;
203 default:
204 return -EINVAL;
205 }
206
207 dev_dbg(dev, "next_red = %d, next_green = %d, next_blue = %d\n",
208 data->next_red, data->next_green, data->next_blue);
209
210 /* if mode ... */
211 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
212 if (ret < 0) {
213 dev_err(dev, "BlinkM: can't set RGB\n");
214 return ret;
215 }
216 return 0;
217}
218
219static ssize_t show_red(struct device *dev, struct device_attribute *attr,
220 char *buf)
221{
222 return show_color_common(dev, buf, RED);
223}
224
225static ssize_t store_red(struct device *dev, struct device_attribute *attr,
226 const char *buf, size_t count)
227{
228 int ret;
229
230 ret = store_color_common(dev, buf, RED);
231 if (ret < 0)
232 return ret;
233 return count;
234}
235
236static DEVICE_ATTR(red, S_IRUGO | S_IWUSR, show_red, store_red);
237
238static ssize_t show_green(struct device *dev, struct device_attribute *attr,
239 char *buf)
240{
241 return show_color_common(dev, buf, GREEN);
242}
243
244static ssize_t store_green(struct device *dev, struct device_attribute *attr,
245 const char *buf, size_t count)
246{
247
248 int ret;
249
250 ret = store_color_common(dev, buf, GREEN);
251 if (ret < 0)
252 return ret;
253 return count;
254}
255
256static DEVICE_ATTR(green, S_IRUGO | S_IWUSR, show_green, store_green);
257
258static ssize_t show_blue(struct device *dev, struct device_attribute *attr,
259 char *buf)
260{
261 return show_color_common(dev, buf, BLUE);
262}
263
264static ssize_t store_blue(struct device *dev, struct device_attribute *attr,
265 const char *buf, size_t count)
266{
267 int ret;
268
269 ret = store_color_common(dev, buf, BLUE);
270 if (ret < 0)
271 return ret;
272 return count;
273}
274
275static DEVICE_ATTR(blue, S_IRUGO | S_IWUSR, show_blue, store_blue);
276
277static ssize_t show_test(struct device *dev, struct device_attribute *attr,
278 char *buf)
279{
280 return scnprintf(buf, PAGE_SIZE,
281 "#Write into test to start test sequence!#\n");
282}
283
284static ssize_t store_test(struct device *dev, struct device_attribute *attr,
285 const char *buf, size_t count)
286{
287
288 struct i2c_client *client;
289 int ret;
290 client = to_i2c_client(dev);
291
292 /*test */
293 ret = blinkm_test_run(client);
294 if (ret < 0)
295 return ret;
296
297 return count;
298}
299
300static DEVICE_ATTR(test, S_IRUGO | S_IWUSR, show_test, store_test);
301
302/* TODO: HSB, fade, timeadj, script ... */
303
304static struct attribute *blinkm_attrs[] = {
305 &dev_attr_red.attr,
306 &dev_attr_green.attr,
307 &dev_attr_blue.attr,
308 &dev_attr_test.attr,
309 NULL,
310};
311
312static struct attribute_group blinkm_group = {
313 .name = "blinkm",
314 .attrs = blinkm_attrs,
315};
316
317static int blinkm_write(struct i2c_client *client, int cmd, u8 *arg)
318{
319 int result;
320 int i;
321 int arglen = blinkm_cmds[cmd].nr_args;
322 /* write out cmd to blinkm - always / default step */
323 result = i2c_smbus_write_byte(client, blinkm_cmds[cmd].cmdbyte);
324 if (result < 0)
325 return result;
326 /* no args to write out */
327 if (arglen == 0)
328 return 0;
329
330 for (i = 0; i < arglen; i++) {
331 /* repeat for arglen */
332 result = i2c_smbus_write_byte(client, arg[i]);
333 if (result < 0)
334 return result;
335 }
336 return 0;
337}
338
339static int blinkm_read(struct i2c_client *client, int cmd, u8 *arg)
340{
341 int result;
342 int i;
343 int retlen = blinkm_cmds[cmd].nr_ret;
344 for (i = 0; i < retlen; i++) {
345 /* repeat for retlen */
346 result = i2c_smbus_read_byte(client);
347 if (result < 0)
348 return result;
349 arg[i] = result;
350 }
351
352 return 0;
353}
354
355static int blinkm_transfer_hw(struct i2c_client *client, int cmd)
356{
357 /* the protocol is simple but non-standard:
358 * e.g. cmd 'g' (= 0x67) for "get device address"
359 * - which defaults to 0x09 - would be the sequence:
360 * a) write 0x67 to the device (byte write)
361 * b) read the value (0x09) back right after (byte read)
362 *
363 * Watch out for "unfinished" sequences (i.e. not enough reads
364 * or writes after a command. It will make the blinkM misbehave.
365 * Sequence is key here.
366 */
367
368 /* args / return are in private data struct */
369 struct blinkm_data *data = i2c_get_clientdata(client);
370
371 /* We start hardware transfers which are not to be
372 * mixed with other commands. Aquire a lock now. */
373 if (mutex_lock_interruptible(&data->update_lock) < 0)
374 return -EAGAIN;
375
376 /* switch cmd - usually write before reads */
377 switch (cmd) {
378 case BLM_FADE_RAND_RGB:
379 case BLM_GO_RGB:
380 case BLM_FADE_RGB:
381 data->args[0] = data->next_red;
382 data->args[1] = data->next_green;
383 data->args[2] = data->next_blue;
384 blinkm_write(client, cmd, data->args);
385 data->red = data->args[0];
386 data->green = data->args[1];
387 data->blue = data->args[2];
388 break;
389 case BLM_FADE_HSB:
390 case BLM_FADE_RAND_HSB:
391 data->args[0] = data->next_hue;
392 data->args[1] = data->next_saturation;
393 data->args[2] = data->next_brightness;
394 blinkm_write(client, cmd, data->args);
395 data->hue = data->next_hue;
396 data->saturation = data->next_saturation;
397 data->brightness = data->next_brightness;
398 break;
399 case BLM_PLAY_SCRIPT:
400 data->args[0] = data->script_id;
401 data->args[1] = data->script_repeats;
402 data->args[2] = data->script_startline;
403 blinkm_write(client, cmd, data->args);
404 break;
405 case BLM_STOP_SCRIPT:
406 blinkm_write(client, cmd, NULL);
407 break;
408 case BLM_GET_CUR_RGB:
409 data->args[0] = data->red;
410 data->args[1] = data->green;
411 data->args[2] = data->blue;
412 blinkm_write(client, cmd, NULL);
413 blinkm_read(client, cmd, data->args);
414 data->red = data->args[0];
415 data->green = data->args[1];
416 data->blue = data->args[2];
417 break;
418 case BLM_GET_ADDR:
419 data->args[0] = data->i2c_addr;
420 blinkm_write(client, cmd, NULL);
421 blinkm_read(client, cmd, data->args);
422 data->i2c_addr = data->args[0];
423 break;
424 case BLM_SET_TIME_ADJ:
425 case BLM_SET_FADE_SPEED:
426 case BLM_READ_SCRIPT_LINE:
427 case BLM_WRITE_SCRIPT_LINE:
428 case BLM_SET_SCRIPT_LR:
429 case BLM_SET_ADDR:
430 case BLM_GET_FW_VER:
431 case BLM_SET_STARTUP_PARAM:
432 dev_err(&client->dev,
433 "BlinkM: cmd %d not implemented yet.\n", cmd);
434 break;
435 default:
436 dev_err(&client->dev, "BlinkM: unknown command %d\n", cmd);
437 mutex_unlock(&data->update_lock);
438 return -EINVAL;
439 } /* end switch(cmd) */
440
441 /* transfers done, unlock */
442 mutex_unlock(&data->update_lock);
443 return 0;
444}
445
446static void led_work(struct work_struct *work)
447{
448 int ret;
449 struct blinkm_led *led;
450 struct blinkm_data *data ;
451 struct blinkm_work *blm_work = work_to_blmwork(work);
452
453 led = blm_work->blinkm_led;
454 data = i2c_get_clientdata(led->i2c_client);
455 ret = blinkm_transfer_hw(led->i2c_client, BLM_GO_RGB);
456 atomic_dec(&led->active);
457 dev_dbg(&led->i2c_client->dev,
458 "# DONE # next_red = %d, next_green = %d,"
459 " next_blue = %d, active = %d\n",
460 data->next_red, data->next_green,
461 data->next_blue, atomic_read(&led->active));
462 kfree(blm_work);
463}
464
465static int blinkm_led_common_set(struct led_classdev *led_cdev,
466 enum led_brightness value, int color)
467{
468 /* led_brightness is 0, 127 or 255 - we just use it here as-is */
469 struct blinkm_led *led = cdev_to_blmled(led_cdev);
470 struct blinkm_data *data = i2c_get_clientdata(led->i2c_client);
471 struct blinkm_work *bl_work;
472
473 switch (color) {
474 case RED:
475 /* bail out if there's no change */
476 if (data->next_red == (u8) value)
477 return 0;
478 /* we assume a quite fast sequence here ([off]->on->off)
479 * think of network led trigger - we cannot blink that fast, so
480 * in case we already have a off->on->off transition queued up,
481 * we refuse to queue up more.
482 * Revisit: fast-changing brightness. */
483 if (atomic_read(&led->active) > 1)
484 return 0;
485 data->next_red = (u8) value;
486 break;
487 case GREEN:
488 /* bail out if there's no change */
489 if (data->next_green == (u8) value)
490 return 0;
491 /* we assume a quite fast sequence here ([off]->on->off)
492 * Revisit: fast-changing brightness. */
493 if (atomic_read(&led->active) > 1)
494 return 0;
495 data->next_green = (u8) value;
496 break;
497 case BLUE:
498 /* bail out if there's no change */
499 if (data->next_blue == (u8) value)
500 return 0;
501 /* we assume a quite fast sequence here ([off]->on->off)
502 * Revisit: fast-changing brightness. */
503 if (atomic_read(&led->active) > 1)
504 return 0;
505 data->next_blue = (u8) value;
506 break;
507
508 default:
509 dev_err(&led->i2c_client->dev, "BlinkM: unknown color.\n");
510 return -EINVAL;
511 }
512
513 bl_work = kzalloc(sizeof(*bl_work), GFP_ATOMIC);
514 if (!bl_work)
515 return -ENOMEM;
516
517 atomic_inc(&led->active);
518 dev_dbg(&led->i2c_client->dev,
519 "#TO_SCHED# next_red = %d, next_green = %d,"
520 " next_blue = %d, active = %d\n",
521 data->next_red, data->next_green,
522 data->next_blue, atomic_read(&led->active));
523
524 /* a fresh work _item_ for each change */
525 bl_work->blinkm_led = led;
526 INIT_WORK(&bl_work->work, led_work);
527 /* queue work in own queue for easy sync on exit*/
528 schedule_work(&bl_work->work);
529
530 return 0;
531}
532
533static void blinkm_led_red_set(struct led_classdev *led_cdev,
534 enum led_brightness value)
535{
536 blinkm_led_common_set(led_cdev, value, RED);
537}
538
539static void blinkm_led_green_set(struct led_classdev *led_cdev,
540 enum led_brightness value)
541{
542 blinkm_led_common_set(led_cdev, value, GREEN);
543}
544
545static void blinkm_led_blue_set(struct led_classdev *led_cdev,
546 enum led_brightness value)
547{
548 blinkm_led_common_set(led_cdev, value, BLUE);
549}
550
551static void blinkm_init_hw(struct i2c_client *client)
552{
553 int ret;
554 ret = blinkm_transfer_hw(client, BLM_STOP_SCRIPT);
555 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
556}
557
558static int blinkm_test_run(struct i2c_client *client)
559{
560 int ret;
561 struct blinkm_data *data = i2c_get_clientdata(client);
562
563 data->next_red = 0x01;
564 data->next_green = 0x05;
565 data->next_blue = 0x10;
566 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
567 if (ret < 0)
568 return ret;
569 msleep(2000);
570
571 data->next_red = 0x25;
572 data->next_green = 0x10;
573 data->next_blue = 0x31;
574 ret = blinkm_transfer_hw(client, BLM_FADE_RGB);
575 if (ret < 0)
576 return ret;
577 msleep(2000);
578
579 data->next_hue = 0x50;
580 data->next_saturation = 0x10;
581 data->next_brightness = 0x20;
582 ret = blinkm_transfer_hw(client, BLM_FADE_HSB);
583 if (ret < 0)
584 return ret;
585 msleep(2000);
586
587 return 0;
588}
589
590/* Return 0 if detection is successful, -ENODEV otherwise */
591static int blinkm_detect(struct i2c_client *client, struct i2c_board_info *info)
592{
593 struct i2c_adapter *adapter = client->adapter;
594 int ret;
595 int count = 99;
596 u8 tmpargs[7];
597
598 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
599 | I2C_FUNC_SMBUS_WORD_DATA
600 | I2C_FUNC_SMBUS_WRITE_BYTE))
601 return -ENODEV;
602
603 /* Now, we do the remaining detection. Simple for now. */
604 /* We might need more guards to protect other i2c slaves */
605
606 /* make sure the blinkM is balanced (read/writes) */
607 while (count > 0) {
608 ret = blinkm_write(client, BLM_GET_ADDR, NULL);
609 usleep_range(5000, 10000);
610 ret = blinkm_read(client, BLM_GET_ADDR, tmpargs);
611 usleep_range(5000, 10000);
612 if (tmpargs[0] == 0x09)
613 count = 0;
614 count--;
615 }
616
617 /* Step 1: Read BlinkM address back - cmd_char 'a' */
618 ret = blinkm_write(client, BLM_GET_ADDR, NULL);
619 if (ret < 0)
620 return ret;
621 usleep_range(20000, 30000); /* allow a small delay */
622 ret = blinkm_read(client, BLM_GET_ADDR, tmpargs);
623 if (ret < 0)
624 return ret;
625
626 if (tmpargs[0] != 0x09) {
627 dev_err(&client->dev, "enodev DEV ADDR = 0x%02X\n", tmpargs[0]);
628 return -ENODEV;
629 }
630
631 strlcpy(info->type, "blinkm", I2C_NAME_SIZE);
632 return 0;
633}
634
635static int __devinit blinkm_probe(struct i2c_client *client,
636 const struct i2c_device_id *id)
637{
638 struct blinkm_data *data;
639 struct blinkm_led *led[3];
640 int err, i;
641 char blinkm_led_name[28];
642
643 data = devm_kzalloc(&client->dev,
644 sizeof(struct blinkm_data), GFP_KERNEL);
645 if (!data) {
646 err = -ENOMEM;
647 goto exit;
648 }
649
650 data->i2c_addr = 0x09;
651 data->i2c_addr = 0x08;
652 /* i2c addr - use fake addr of 0x08 initially (real is 0x09) */
653 data->fw_ver = 0xfe;
654 /* firmware version - use fake until we read real value
655 * (currently broken - BlinkM confused!) */
656 data->script_id = 0x01;
657 data->i2c_client = client;
658
659 i2c_set_clientdata(client, data);
660 mutex_init(&data->update_lock);
661
662 /* Register sysfs hooks */
663 err = sysfs_create_group(&client->dev.kobj, &blinkm_group);
664 if (err < 0) {
665 dev_err(&client->dev, "couldn't register sysfs group\n");
666 goto exit;
667 }
668
669 for (i = 0; i < 3; i++) {
670 /* RED = 0, GREEN = 1, BLUE = 2 */
671 led[i] = &data->blinkm_leds[i];
672 led[i]->i2c_client = client;
673 led[i]->id = i;
674 led[i]->led_cdev.max_brightness = 255;
675 led[i]->led_cdev.flags = LED_CORE_SUSPENDRESUME;
676 atomic_set(&led[i]->active, 0);
677 switch (i) {
678 case RED:
679 snprintf(blinkm_led_name, sizeof(blinkm_led_name),
680 "blinkm-%d-%d-red",
681 client->adapter->nr,
682 client->addr);
683 led[i]->led_cdev.name = blinkm_led_name;
684 led[i]->led_cdev.brightness_set = blinkm_led_red_set;
685 err = led_classdev_register(&client->dev,
686 &led[i]->led_cdev);
687 if (err < 0) {
688 dev_err(&client->dev,
689 "couldn't register LED %s\n",
690 led[i]->led_cdev.name);
691 goto failred;
692 }
693 break;
694 case GREEN:
695 snprintf(blinkm_led_name, sizeof(blinkm_led_name),
696 "blinkm-%d-%d-green",
697 client->adapter->nr,
698 client->addr);
699 led[i]->led_cdev.name = blinkm_led_name;
700 led[i]->led_cdev.brightness_set = blinkm_led_green_set;
701 err = led_classdev_register(&client->dev,
702 &led[i]->led_cdev);
703 if (err < 0) {
704 dev_err(&client->dev,
705 "couldn't register LED %s\n",
706 led[i]->led_cdev.name);
707 goto failgreen;
708 }
709 break;
710 case BLUE:
711 snprintf(blinkm_led_name, sizeof(blinkm_led_name),
712 "blinkm-%d-%d-blue",
713 client->adapter->nr,
714 client->addr);
715 led[i]->led_cdev.name = blinkm_led_name;
716 led[i]->led_cdev.brightness_set = blinkm_led_blue_set;
717 err = led_classdev_register(&client->dev,
718 &led[i]->led_cdev);
719 if (err < 0) {
720 dev_err(&client->dev,
721 "couldn't register LED %s\n",
722 led[i]->led_cdev.name);
723 goto failblue;
724 }
725 break;
726 } /* end switch */
727 } /* end for */
728
729 /* Initialize the blinkm */
730 blinkm_init_hw(client);
731
732 return 0;
733
734failblue:
735 led_classdev_unregister(&led[GREEN]->led_cdev);
736
737failgreen:
738 led_classdev_unregister(&led[RED]->led_cdev);
739
740failred:
741 sysfs_remove_group(&client->dev.kobj, &blinkm_group);
742exit:
743 return err;
744}
745
746static int __devexit blinkm_remove(struct i2c_client *client)
747{
748 struct blinkm_data *data = i2c_get_clientdata(client);
749 int ret = 0;
750 int i;
751
752 /* make sure no workqueue entries are pending */
753 for (i = 0; i < 3; i++) {
754 flush_scheduled_work();
755 led_classdev_unregister(&data->blinkm_leds[i].led_cdev);
756 }
757
758 /* reset rgb */
759 data->next_red = 0x00;
760 data->next_green = 0x00;
761 data->next_blue = 0x00;
762 ret = blinkm_transfer_hw(client, BLM_FADE_RGB);
763 if (ret < 0)
764 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
765
766 /* reset hsb */
767 data->next_hue = 0x00;
768 data->next_saturation = 0x00;
769 data->next_brightness = 0x00;
770 ret = blinkm_transfer_hw(client, BLM_FADE_HSB);
771 if (ret < 0)
772 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
773
774 /* red fade to off */
775 data->next_red = 0xff;
776 ret = blinkm_transfer_hw(client, BLM_GO_RGB);
777 if (ret < 0)
778 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
779
780 /* off */
781 data->next_red = 0x00;
782 ret = blinkm_transfer_hw(client, BLM_FADE_RGB);
783 if (ret < 0)
784 dev_err(&client->dev, "Failure in blinkm_remove ignored. Continuing.\n");
785
786 sysfs_remove_group(&client->dev.kobj, &blinkm_group);
787 return 0;
788}
789
790static const struct i2c_device_id blinkm_id[] = {
791 {"blinkm", 0},
792 {}
793};
794
795MODULE_DEVICE_TABLE(i2c, blinkm_id);
796
797 /* This is the driver that will be inserted */
798static struct i2c_driver blinkm_driver = {
799 .class = I2C_CLASS_HWMON,
800 .driver = {
801 .name = "blinkm",
802 },
803 .probe = blinkm_probe,
804 .remove = __devexit_p(blinkm_remove),
805 .id_table = blinkm_id,
806 .detect = blinkm_detect,
807 .address_list = normal_i2c,
808};
809
810module_i2c_driver(blinkm_driver);
811
812MODULE_AUTHOR("Jan-Simon Moeller <dl9pf@gmx.de>");
813MODULE_DESCRIPTION("BlinkM RGB LED driver");
814MODULE_LICENSE("GPL");
815
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
index d9cd73ebd6c4..cc77c9d92615 100644
--- a/drivers/leds/leds-da903x.c
+++ b/drivers/leds/leds-da903x.c
@@ -108,7 +108,7 @@ static int __devinit da903x_led_probe(struct platform_device *pdev)
108 return -EINVAL; 108 return -EINVAL;
109 } 109 }
110 110
111 led = kzalloc(sizeof(struct da903x_led), GFP_KERNEL); 111 led = devm_kzalloc(&pdev->dev, sizeof(struct da903x_led), GFP_KERNEL);
112 if (led == NULL) { 112 if (led == NULL) {
113 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id); 113 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id);
114 return -ENOMEM; 114 return -ENOMEM;
@@ -129,15 +129,11 @@ static int __devinit da903x_led_probe(struct platform_device *pdev)
129 ret = led_classdev_register(led->master, &led->cdev); 129 ret = led_classdev_register(led->master, &led->cdev);
130 if (ret) { 130 if (ret) {
131 dev_err(&pdev->dev, "failed to register LED %d\n", id); 131 dev_err(&pdev->dev, "failed to register LED %d\n", id);
132 goto err; 132 return ret;
133 } 133 }
134 134
135 platform_set_drvdata(pdev, led); 135 platform_set_drvdata(pdev, led);
136 return 0; 136 return 0;
137
138err:
139 kfree(led);
140 return ret;
141} 137}
142 138
143static int __devexit da903x_led_remove(struct platform_device *pdev) 139static int __devexit da903x_led_remove(struct platform_device *pdev)
@@ -145,7 +141,6 @@ static int __devexit da903x_led_remove(struct platform_device *pdev)
145 struct da903x_led *led = platform_get_drvdata(pdev); 141 struct da903x_led *led = platform_get_drvdata(pdev);
146 142
147 led_classdev_unregister(&led->cdev); 143 led_classdev_unregister(&led->cdev);
148 kfree(led);
149 return 0; 144 return 0;
150} 145}
151 146
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
index d56c14269ff0..1f9d8e62d37e 100644
--- a/drivers/leds/leds-dac124s085.c
+++ b/drivers/leds/leds-dac124s085.c
@@ -69,7 +69,7 @@ static int dac124s085_probe(struct spi_device *spi)
69 struct dac124s085_led *led; 69 struct dac124s085_led *led;
70 int i, ret; 70 int i, ret;
71 71
72 dac = kzalloc(sizeof(*dac), GFP_KERNEL); 72 dac = devm_kzalloc(&spi->dev, sizeof(*dac), GFP_KERNEL);
73 if (!dac) 73 if (!dac)
74 return -ENOMEM; 74 return -ENOMEM;
75 75
@@ -102,7 +102,6 @@ eledcr:
102 led_classdev_unregister(&dac->leds[i].ldev); 102 led_classdev_unregister(&dac->leds[i].ldev);
103 103
104 spi_set_drvdata(spi, NULL); 104 spi_set_drvdata(spi, NULL);
105 kfree(dac);
106 return ret; 105 return ret;
107} 106}
108 107
@@ -117,7 +116,6 @@ static int dac124s085_remove(struct spi_device *spi)
117 } 116 }
118 117
119 spi_set_drvdata(spi, NULL); 118 spi_set_drvdata(spi, NULL);
120 kfree(dac);
121 119
122 return 0; 120 return 0;
123} 121}
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index f4c470a3bc8d..c032b2180340 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -178,7 +178,8 @@ static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_dev
178 if (!count) 178 if (!count)
179 return NULL; 179 return NULL;
180 180
181 priv = kzalloc(sizeof_gpio_leds_priv(count), GFP_KERNEL); 181 priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
182 GFP_KERNEL);
182 if (!priv) 183 if (!priv)
183 return NULL; 184 return NULL;
184 185
@@ -215,7 +216,6 @@ static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_dev
215err: 216err:
216 for (count = priv->num_leds - 2; count >= 0; count--) 217 for (count = priv->num_leds - 2; count >= 0; count--)
217 delete_gpio_led(&priv->leds[count]); 218 delete_gpio_led(&priv->leds[count]);
218 kfree(priv);
219 return NULL; 219 return NULL;
220} 220}
221 221
@@ -239,8 +239,9 @@ static int __devinit gpio_led_probe(struct platform_device *pdev)
239 int i, ret = 0; 239 int i, ret = 0;
240 240
241 if (pdata && pdata->num_leds) { 241 if (pdata && pdata->num_leds) {
242 priv = kzalloc(sizeof_gpio_leds_priv(pdata->num_leds), 242 priv = devm_kzalloc(&pdev->dev,
243 GFP_KERNEL); 243 sizeof_gpio_leds_priv(pdata->num_leds),
244 GFP_KERNEL);
244 if (!priv) 245 if (!priv)
245 return -ENOMEM; 246 return -ENOMEM;
246 247
@@ -253,7 +254,6 @@ static int __devinit gpio_led_probe(struct platform_device *pdev)
253 /* On failure: unwind the led creations */ 254 /* On failure: unwind the led creations */
254 for (i = i - 1; i >= 0; i--) 255 for (i = i - 1; i >= 0; i--)
255 delete_gpio_led(&priv->leds[i]); 256 delete_gpio_led(&priv->leds[i]);
256 kfree(priv);
257 return ret; 257 return ret;
258 } 258 }
259 } 259 }
@@ -277,7 +277,6 @@ static int __devexit gpio_led_remove(struct platform_device *pdev)
277 delete_gpio_led(&priv->leds[i]); 277 delete_gpio_led(&priv->leds[i]);
278 278
279 dev_set_drvdata(&pdev->dev, NULL); 279 dev_set_drvdata(&pdev->dev, NULL);
280 kfree(priv);
281 280
282 return 0; 281 return 0;
283} 282}
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 84ba6de8039c..23637bdb275d 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -386,28 +386,24 @@ static int __devinit lm3530_probe(struct i2c_client *client,
386 386
387 if (pdata == NULL) { 387 if (pdata == NULL) {
388 dev_err(&client->dev, "platform data required\n"); 388 dev_err(&client->dev, "platform data required\n");
389 err = -ENODEV; 389 return -ENODEV;
390 goto err_out;
391 } 390 }
392 391
393 /* BL mode */ 392 /* BL mode */
394 if (pdata->mode > LM3530_BL_MODE_PWM) { 393 if (pdata->mode > LM3530_BL_MODE_PWM) {
395 dev_err(&client->dev, "Illegal Mode request\n"); 394 dev_err(&client->dev, "Illegal Mode request\n");
396 err = -EINVAL; 395 return -EINVAL;
397 goto err_out;
398 } 396 }
399 397
400 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 398 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
401 dev_err(&client->dev, "I2C_FUNC_I2C not supported\n"); 399 dev_err(&client->dev, "I2C_FUNC_I2C not supported\n");
402 err = -EIO; 400 return -EIO;
403 goto err_out;
404 } 401 }
405 402
406 drvdata = kzalloc(sizeof(struct lm3530_data), GFP_KERNEL); 403 drvdata = devm_kzalloc(&client->dev, sizeof(struct lm3530_data),
407 if (drvdata == NULL) { 404 GFP_KERNEL);
408 err = -ENOMEM; 405 if (drvdata == NULL)
409 goto err_out; 406 return -ENOMEM;
410 }
411 407
412 drvdata->mode = pdata->mode; 408 drvdata->mode = pdata->mode;
413 drvdata->client = client; 409 drvdata->client = client;
@@ -425,7 +421,7 @@ static int __devinit lm3530_probe(struct i2c_client *client,
425 dev_err(&client->dev, "regulator get failed\n"); 421 dev_err(&client->dev, "regulator get failed\n");
426 err = PTR_ERR(drvdata->regulator); 422 err = PTR_ERR(drvdata->regulator);
427 drvdata->regulator = NULL; 423 drvdata->regulator = NULL;
428 goto err_regulator_get; 424 return err;
429 } 425 }
430 426
431 if (drvdata->pdata->brt_val) { 427 if (drvdata->pdata->brt_val) {
@@ -458,9 +454,6 @@ err_create_file:
458err_class_register: 454err_class_register:
459err_reg_init: 455err_reg_init:
460 regulator_put(drvdata->regulator); 456 regulator_put(drvdata->regulator);
461err_regulator_get:
462 kfree(drvdata);
463err_out:
464 return err; 457 return err;
465} 458}
466 459
@@ -474,7 +467,6 @@ static int __devexit lm3530_remove(struct i2c_client *client)
474 regulator_disable(drvdata->regulator); 467 regulator_disable(drvdata->regulator);
475 regulator_put(drvdata->regulator); 468 regulator_put(drvdata->regulator);
476 led_classdev_unregister(&drvdata->led_dev); 469 led_classdev_unregister(&drvdata->led_dev);
477 kfree(drvdata);
478 return 0; 470 return 0;
479} 471}
480 472
diff --git a/drivers/leds/leds-lm3556.c b/drivers/leds/leds-lm3556.c
new file mode 100644
index 000000000000..3062abd9a532
--- /dev/null
+++ b/drivers/leds/leds-lm3556.c
@@ -0,0 +1,512 @@
1/*
2 * Simple driver for Texas Instruments LM3556 LED Flash driver chip (Rev0x03)
3 * Copyright (C) 2012 Texas Instruments
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Please refer Documentation/leds/leds-lm3556.txt file.
10 */
11#include <linux/module.h>
12#include <linux/delay.h>
13#include <linux/i2c.h>
14#include <linux/leds.h>
15#include <linux/slab.h>
16#include <linux/platform_device.h>
17#include <linux/fs.h>
18#include <linux/regmap.h>
19#include <linux/platform_data/leds-lm3556.h>
20
21#define REG_FILT_TIME (0x0)
22#define REG_IVFM_MODE (0x1)
23#define REG_NTC (0x2)
24#define REG_INDIC_TIME (0x3)
25#define REG_INDIC_BLINK (0x4)
26#define REG_INDIC_PERIOD (0x5)
27#define REG_TORCH_TIME (0x6)
28#define REG_CONF (0x7)
29#define REG_FLASH (0x8)
30#define REG_I_CTRL (0x9)
31#define REG_ENABLE (0xA)
32#define REG_FLAG (0xB)
33#define REG_MAX (0xB)
34
35#define IVFM_FILTER_TIME_SHIFT (3)
36#define UVLO_EN_SHIFT (7)
37#define HYSTERSIS_SHIFT (5)
38#define IVM_D_TH_SHIFT (2)
39#define IVFM_ADJ_MODE_SHIFT (0)
40#define NTC_EVENT_LVL_SHIFT (5)
41#define NTC_TRIP_TH_SHIFT (2)
42#define NTC_BIAS_I_LVL_SHIFT (0)
43#define INDIC_RAMP_UP_TIME_SHIFT (3)
44#define INDIC_RAMP_DN_TIME_SHIFT (0)
45#define INDIC_N_BLANK_SHIFT (4)
46#define INDIC_PULSE_TIME_SHIFT (0)
47#define INDIC_N_PERIOD_SHIFT (0)
48#define TORCH_RAMP_UP_TIME_SHIFT (3)
49#define TORCH_RAMP_DN_TIME_SHIFT (0)
50#define STROBE_USUAGE_SHIFT (7)
51#define STROBE_PIN_POLARITY_SHIFT (6)
52#define TORCH_PIN_POLARITY_SHIFT (5)
53#define TX_PIN_POLARITY_SHIFT (4)
54#define TX_EVENT_LVL_SHIFT (3)
55#define IVFM_EN_SHIFT (2)
56#define NTC_MODE_SHIFT (1)
57#define INDIC_MODE_SHIFT (0)
58#define INDUCTOR_I_LIMIT_SHIFT (6)
59#define FLASH_RAMP_TIME_SHIFT (3)
60#define FLASH_TOUT_TIME_SHIFT (0)
61#define TORCH_I_SHIFT (4)
62#define FLASH_I_SHIFT (0)
63#define NTC_EN_SHIFT (7)
64#define TX_PIN_EN_SHIFT (6)
65#define STROBE_PIN_EN_SHIFT (5)
66#define TORCH_PIN_EN_SHIFT (4)
67#define PRECHG_MODE_EN_SHIFT (3)
68#define PASS_MODE_ONLY_EN_SHIFT (2)
69#define MODE_BITS_SHIFT (0)
70
71#define IVFM_FILTER_TIME_MASK (0x3)
72#define UVLO_EN_MASK (0x1)
73#define HYSTERSIS_MASK (0x3)
74#define IVM_D_TH_MASK (0x7)
75#define IVFM_ADJ_MODE_MASK (0x3)
76#define NTC_EVENT_LVL_MASK (0x1)
77#define NTC_TRIP_TH_MASK (0x7)
78#define NTC_BIAS_I_LVL_MASK (0x3)
79#define INDIC_RAMP_UP_TIME_MASK (0x7)
80#define INDIC_RAMP_DN_TIME_MASK (0x7)
81#define INDIC_N_BLANK_MASK (0x7)
82#define INDIC_PULSE_TIME_MASK (0x7)
83#define INDIC_N_PERIOD_MASK (0x7)
84#define TORCH_RAMP_UP_TIME_MASK (0x7)
85#define TORCH_RAMP_DN_TIME_MASK (0x7)
86#define STROBE_USUAGE_MASK (0x1)
87#define STROBE_PIN_POLARITY_MASK (0x1)
88#define TORCH_PIN_POLARITY_MASK (0x1)
89#define TX_PIN_POLARITY_MASK (0x1)
90#define TX_EVENT_LVL_MASK (0x1)
91#define IVFM_EN_MASK (0x1)
92#define NTC_MODE_MASK (0x1)
93#define INDIC_MODE_MASK (0x1)
94#define INDUCTOR_I_LIMIT_MASK (0x3)
95#define FLASH_RAMP_TIME_MASK (0x7)
96#define FLASH_TOUT_TIME_MASK (0x7)
97#define TORCH_I_MASK (0x7)
98#define FLASH_I_MASK (0xF)
99#define NTC_EN_MASK (0x1)
100#define TX_PIN_EN_MASK (0x1)
101#define STROBE_PIN_EN_MASK (0x1)
102#define TORCH_PIN_EN_MASK (0x1)
103#define PRECHG_MODE_EN_MASK (0x1)
104#define PASS_MODE_ONLY_EN_MASK (0x1)
105#define MODE_BITS_MASK (0x13)
106#define EX_PIN_CONTROL_MASK (0xF1)
107#define EX_PIN_ENABLE_MASK (0x70)
108
109enum lm3556_indic_pulse_time {
110 PULSE_TIME_0_MS = 0,
111 PULSE_TIME_32_MS,
112 PULSE_TIME_64_MS,
113 PULSE_TIME_92_MS,
114 PULSE_TIME_128_MS,
115 PULSE_TIME_160_MS,
116 PULSE_TIME_196_MS,
117 PULSE_TIME_224_MS,
118 PULSE_TIME_256_MS,
119 PULSE_TIME_288_MS,
120 PULSE_TIME_320_MS,
121 PULSE_TIME_352_MS,
122 PULSE_TIME_384_MS,
123 PULSE_TIME_416_MS,
124 PULSE_TIME_448_MS,
125 PULSE_TIME_480_MS,
126};
127
128enum lm3556_indic_n_blank {
129 INDIC_N_BLANK_0 = 0,
130 INDIC_N_BLANK_1,
131 INDIC_N_BLANK_2,
132 INDIC_N_BLANK_3,
133 INDIC_N_BLANK_4,
134 INDIC_N_BLANK_5,
135 INDIC_N_BLANK_6,
136 INDIC_N_BLANK_7,
137 INDIC_N_BLANK_8,
138 INDIC_N_BLANK_9,
139 INDIC_N_BLANK_10,
140 INDIC_N_BLANK_11,
141 INDIC_N_BLANK_12,
142 INDIC_N_BLANK_13,
143 INDIC_N_BLANK_14,
144 INDIC_N_BLANK_15,
145};
146
147enum lm3556_indic_period {
148 INDIC_PERIOD_0 = 0,
149 INDIC_PERIOD_1,
150 INDIC_PERIOD_2,
151 INDIC_PERIOD_3,
152 INDIC_PERIOD_4,
153 INDIC_PERIOD_5,
154 INDIC_PERIOD_6,
155 INDIC_PERIOD_7,
156};
157
158enum lm3556_mode {
159 MODES_STASNDBY = 0,
160 MODES_INDIC,
161 MODES_TORCH,
162 MODES_FLASH
163};
164
165#define INDIC_PATTERN_SIZE 4
166
167struct indicator {
168 u8 blinking;
169 u8 period_cnt;
170};
171
172struct lm3556_chip_data {
173 struct device *dev;
174
175 struct led_classdev cdev_flash;
176 struct led_classdev cdev_torch;
177 struct led_classdev cdev_indicator;
178
179 struct lm3556_platform_data *pdata;
180 struct regmap *regmap;
181 struct mutex lock;
182
183 unsigned int last_flag;
184};
185
186/* indicator pattern */
187static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
188 [0] = {(INDIC_N_BLANK_1 << INDIC_N_BLANK_SHIFT)
189 | PULSE_TIME_32_MS, INDIC_PERIOD_1},
190 [1] = {(INDIC_N_BLANK_15 << INDIC_N_BLANK_SHIFT)
191 | PULSE_TIME_32_MS, INDIC_PERIOD_2},
192 [2] = {(INDIC_N_BLANK_10 << INDIC_N_BLANK_SHIFT)
193 | PULSE_TIME_32_MS, INDIC_PERIOD_4},
194 [3] = {(INDIC_N_BLANK_5 << INDIC_N_BLANK_SHIFT)
195 | PULSE_TIME_32_MS, INDIC_PERIOD_7},
196};
197
198/* chip initialize */
199static int __devinit lm3556_chip_init(struct lm3556_chip_data *chip)
200{
201 unsigned int reg_val;
202 int ret;
203 struct lm3556_platform_data *pdata = chip->pdata;
204
205 /* set config register */
206 ret = regmap_read(chip->regmap, REG_CONF, &reg_val);
207 if (ret < 0) {
208 dev_err(chip->dev, "Failed to read REG_CONF Register\n");
209 goto out;
210 }
211
212 reg_val &= (~EX_PIN_CONTROL_MASK);
213 reg_val |= ((pdata->torch_pin_polarity & 0x01)
214 << TORCH_PIN_POLARITY_SHIFT);
215 reg_val |= ((pdata->strobe_usuage & 0x01) << STROBE_USUAGE_SHIFT);
216 reg_val |= ((pdata->strobe_pin_polarity & 0x01)
217 << STROBE_PIN_POLARITY_SHIFT);
218 reg_val |= ((pdata->tx_pin_polarity & 0x01) << TX_PIN_POLARITY_SHIFT);
219 reg_val |= ((pdata->indicator_mode & 0x01) << INDIC_MODE_SHIFT);
220
221 ret = regmap_write(chip->regmap, REG_CONF, reg_val);
222 if (ret < 0) {
223 dev_err(chip->dev, "Failed to write REG_CONF Regisgter\n");
224 goto out;
225 }
226
227 /* set enable register */
228 ret = regmap_read(chip->regmap, REG_ENABLE, &reg_val);
229 if (ret < 0) {
230 dev_err(chip->dev, "Failed to read REG_ENABLE Register\n");
231 goto out;
232 }
233
234 reg_val &= (~EX_PIN_ENABLE_MASK);
235 reg_val |= ((pdata->torch_pin_en & 0x01) << TORCH_PIN_EN_SHIFT);
236 reg_val |= ((pdata->strobe_pin_en & 0x01) << STROBE_PIN_EN_SHIFT);
237 reg_val |= ((pdata->tx_pin_en & 0x01) << TX_PIN_EN_SHIFT);
238
239 ret = regmap_write(chip->regmap, REG_ENABLE, reg_val);
240 if (ret < 0) {
241 dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
242 goto out;
243 }
244
245out:
246 return ret;
247}
248
249/* chip control */
250static int lm3556_control(struct lm3556_chip_data *chip,
251 u8 brightness, enum lm3556_mode opmode)
252{
253 int ret;
254 struct lm3556_platform_data *pdata = chip->pdata;
255
256 ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
257 if (ret < 0) {
258 dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
259 goto out;
260 }
261
262 if (chip->last_flag)
263 dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
264
265 /* brightness 0 means off-state */
266 if (!brightness)
267 opmode = MODES_STASNDBY;
268
269 switch (opmode) {
270 case MODES_TORCH:
271 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
272 TORCH_I_MASK << TORCH_I_SHIFT,
273 (brightness - 1) << TORCH_I_SHIFT);
274
275 if (pdata->torch_pin_en)
276 opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
277 break;
278
279 case MODES_FLASH:
280 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
281 FLASH_I_MASK << FLASH_I_SHIFT,
282 (brightness - 1) << FLASH_I_SHIFT);
283 break;
284
285 case MODES_INDIC:
286 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
287 TORCH_I_MASK << TORCH_I_SHIFT,
288 (brightness - 1) << TORCH_I_SHIFT);
289 break;
290
291 case MODES_STASNDBY:
292 if (pdata->torch_pin_en)
293 opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
294 break;
295
296 default:
297 return ret;
298 }
299 if (ret < 0) {
300 dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
301 goto out;
302 }
303 ret = regmap_update_bits(chip->regmap, REG_ENABLE,
304 MODE_BITS_MASK << MODE_BITS_SHIFT,
305 opmode << MODE_BITS_SHIFT);
306
307out:
308 return ret;
309}
310
311/* torch */
312static void lm3556_torch_brightness_set(struct led_classdev *cdev,
313 enum led_brightness brightness)
314{
315 struct lm3556_chip_data *chip =
316 container_of(cdev, struct lm3556_chip_data, cdev_torch);
317
318 mutex_lock(&chip->lock);
319 lm3556_control(chip, brightness, MODES_TORCH);
320 mutex_unlock(&chip->lock);
321}
322
323/* flash */
324static void lm3556_strobe_brightness_set(struct led_classdev *cdev,
325 enum led_brightness brightness)
326{
327 struct lm3556_chip_data *chip =
328 container_of(cdev, struct lm3556_chip_data, cdev_flash);
329
330 mutex_lock(&chip->lock);
331 lm3556_control(chip, brightness, MODES_FLASH);
332 mutex_unlock(&chip->lock);
333}
334
335/* indicator */
336static void lm3556_indicator_brightness_set(struct led_classdev *cdev,
337 enum led_brightness brightness)
338{
339 struct lm3556_chip_data *chip =
340 container_of(cdev, struct lm3556_chip_data, cdev_indicator);
341
342 mutex_lock(&chip->lock);
343 lm3556_control(chip, brightness, MODES_INDIC);
344 mutex_unlock(&chip->lock);
345}
346
347/* indicator pattern */
348static ssize_t lm3556_indicator_pattern_store(struct device *dev,
349 struct device_attribute *devAttr,
350 const char *buf, size_t size)
351{
352 ssize_t ret;
353 struct led_classdev *led_cdev = dev_get_drvdata(dev);
354 struct lm3556_chip_data *chip =
355 container_of(led_cdev, struct lm3556_chip_data, cdev_indicator);
356 unsigned int state;
357
358 ret = kstrtouint(buf, 10, &state);
359 if (ret)
360 goto out;
361 if (state > INDIC_PATTERN_SIZE - 1)
362 state = INDIC_PATTERN_SIZE - 1;
363
364 ret = regmap_write(chip->regmap, REG_INDIC_BLINK,
365 indicator_pattern[state].blinking);
366 if (ret < 0) {
367 dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
368 goto out;
369 }
370
371 ret = regmap_write(chip->regmap, REG_INDIC_PERIOD,
372 indicator_pattern[state].period_cnt);
373 if (ret < 0) {
374 dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
375 goto out;
376 }
377
378 return size;
379out:
380 dev_err(chip->dev, "Indicator pattern doesn't saved\n");
381 return size;
382}
383
384static DEVICE_ATTR(pattern, 0666, NULL, lm3556_indicator_pattern_store);
385
386static const struct regmap_config lm3556_regmap = {
387 .reg_bits = 8,
388 .val_bits = 8,
389 .max_register = REG_MAX,
390};
391
392/* module initialize */
393static int __devinit lm3556_probe(struct i2c_client *client,
394 const struct i2c_device_id *id)
395{
396 struct lm3556_platform_data *pdata = client->dev.platform_data;
397 struct lm3556_chip_data *chip;
398
399 int err;
400
401 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
402 dev_err(&client->dev, "i2c functionality check fail.\n");
403 return -EOPNOTSUPP;
404 }
405
406 if (pdata == NULL) {
407 dev_err(&client->dev, "Needs Platform Data.\n");
408 return -ENODATA;
409 }
410
411 chip =
412 devm_kzalloc(&client->dev, sizeof(struct lm3556_chip_data),
413 GFP_KERNEL);
414 if (!chip)
415 return -ENOMEM;
416
417 chip->dev = &client->dev;
418 chip->pdata = pdata;
419
420 chip->regmap = devm_regmap_init_i2c(client, &lm3556_regmap);
421 if (IS_ERR(chip->regmap)) {
422 err = PTR_ERR(chip->regmap);
423 dev_err(&client->dev, "Failed to allocate register map: %d\n",
424 err);
425 return err;
426 }
427
428 mutex_init(&chip->lock);
429 i2c_set_clientdata(client, chip);
430
431 err = lm3556_chip_init(chip);
432 if (err < 0)
433 goto err_out;
434
435 /* flash */
436 chip->cdev_flash.name = "flash";
437 chip->cdev_flash.max_brightness = 16;
438 chip->cdev_flash.brightness_set = lm3556_strobe_brightness_set;
439 err = led_classdev_register((struct device *)
440 &client->dev, &chip->cdev_flash);
441 if (err < 0)
442 goto err_out;
443 /* torch */
444 chip->cdev_torch.name = "torch";
445 chip->cdev_torch.max_brightness = 8;
446 chip->cdev_torch.brightness_set = lm3556_torch_brightness_set;
447 err = led_classdev_register((struct device *)
448 &client->dev, &chip->cdev_torch);
449 if (err < 0)
450 goto err_create_torch_file;
451 /* indicator */
452 chip->cdev_indicator.name = "indicator";
453 chip->cdev_indicator.max_brightness = 8;
454 chip->cdev_indicator.brightness_set = lm3556_indicator_brightness_set;
455 err = led_classdev_register((struct device *)
456 &client->dev, &chip->cdev_indicator);
457 if (err < 0)
458 goto err_create_indicator_file;
459
460 err = device_create_file(chip->cdev_indicator.dev, &dev_attr_pattern);
461 if (err < 0)
462 goto err_create_pattern_file;
463
464 dev_info(&client->dev, "LM3556 is initialized\n");
465 return 0;
466
467err_create_pattern_file:
468 led_classdev_unregister(&chip->cdev_indicator);
469err_create_indicator_file:
470 led_classdev_unregister(&chip->cdev_torch);
471err_create_torch_file:
472 led_classdev_unregister(&chip->cdev_flash);
473err_out:
474 return err;
475}
476
477static int __devexit lm3556_remove(struct i2c_client *client)
478{
479 struct lm3556_chip_data *chip = i2c_get_clientdata(client);
480
481 device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
482 led_classdev_unregister(&chip->cdev_indicator);
483 led_classdev_unregister(&chip->cdev_torch);
484 led_classdev_unregister(&chip->cdev_flash);
485 regmap_write(chip->regmap, REG_ENABLE, 0);
486 return 0;
487}
488
489static const struct i2c_device_id lm3556_id[] = {
490 {LM3556_NAME, 0},
491 {}
492};
493
494MODULE_DEVICE_TABLE(i2c, lm3556_id);
495
496static struct i2c_driver lm3556_i2c_driver = {
497 .driver = {
498 .name = LM3556_NAME,
499 .owner = THIS_MODULE,
500 .pm = NULL,
501 },
502 .probe = lm3556_probe,
503 .remove = __devexit_p(lm3556_remove),
504 .id_table = lm3556_id,
505};
506
507module_i2c_driver(lm3556_i2c_driver);
508
509MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3556");
510MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
511MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
512MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c
index b8f9f0a5d431..c298f7d9f535 100644
--- a/drivers/leds/leds-lp3944.c
+++ b/drivers/leds/leds-lp3944.c
@@ -393,7 +393,8 @@ static int __devinit lp3944_probe(struct i2c_client *client,
393 return -ENODEV; 393 return -ENODEV;
394 } 394 }
395 395
396 data = kzalloc(sizeof(struct lp3944_data), GFP_KERNEL); 396 data = devm_kzalloc(&client->dev, sizeof(struct lp3944_data),
397 GFP_KERNEL);
397 if (!data) 398 if (!data)
398 return -ENOMEM; 399 return -ENOMEM;
399 400
@@ -403,10 +404,8 @@ static int __devinit lp3944_probe(struct i2c_client *client,
403 mutex_init(&data->lock); 404 mutex_init(&data->lock);
404 405
405 err = lp3944_configure(client, data, lp3944_pdata); 406 err = lp3944_configure(client, data, lp3944_pdata);
406 if (err < 0) { 407 if (err < 0)
407 kfree(data);
408 return err; 408 return err;
409 }
410 409
411 dev_info(&client->dev, "lp3944 enabled\n"); 410 dev_info(&client->dev, "lp3944 enabled\n");
412 return 0; 411 return 0;
@@ -431,8 +430,6 @@ static int __devexit lp3944_remove(struct i2c_client *client)
431 break; 430 break;
432 } 431 }
433 432
434 kfree(data);
435
436 return 0; 433 return 0;
437} 434}
438 435
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index 23815624f35e..2064aefedc07 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -744,7 +744,7 @@ static int __devinit lp5521_probe(struct i2c_client *client,
744 int ret, i, led; 744 int ret, i, led;
745 u8 buf; 745 u8 buf;
746 746
747 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 747 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
748 if (!chip) 748 if (!chip)
749 return -ENOMEM; 749 return -ENOMEM;
750 750
@@ -755,8 +755,7 @@ static int __devinit lp5521_probe(struct i2c_client *client,
755 755
756 if (!pdata) { 756 if (!pdata) {
757 dev_err(&client->dev, "no platform data\n"); 757 dev_err(&client->dev, "no platform data\n");
758 ret = -EINVAL; 758 return -EINVAL;
759 goto fail1;
760 } 759 }
761 760
762 mutex_init(&chip->lock); 761 mutex_init(&chip->lock);
@@ -766,7 +765,7 @@ static int __devinit lp5521_probe(struct i2c_client *client,
766 if (pdata->setup_resources) { 765 if (pdata->setup_resources) {
767 ret = pdata->setup_resources(); 766 ret = pdata->setup_resources();
768 if (ret < 0) 767 if (ret < 0)
769 goto fail1; 768 return ret;
770 } 769 }
771 770
772 if (pdata->enable) { 771 if (pdata->enable) {
@@ -807,7 +806,7 @@ static int __devinit lp5521_probe(struct i2c_client *client,
807 ret = lp5521_configure(client); 806 ret = lp5521_configure(client);
808 if (ret < 0) { 807 if (ret < 0) {
809 dev_err(&client->dev, "error configuring chip\n"); 808 dev_err(&client->dev, "error configuring chip\n");
810 goto fail2; 809 goto fail1;
811 } 810 }
812 811
813 /* Initialize leds */ 812 /* Initialize leds */
@@ -822,7 +821,7 @@ static int __devinit lp5521_probe(struct i2c_client *client,
822 ret = lp5521_init_led(&chip->leds[led], client, i, pdata); 821 ret = lp5521_init_led(&chip->leds[led], client, i, pdata);
823 if (ret) { 822 if (ret) {
824 dev_err(&client->dev, "error initializing leds\n"); 823 dev_err(&client->dev, "error initializing leds\n");
825 goto fail3; 824 goto fail2;
826 } 825 }
827 chip->num_leds++; 826 chip->num_leds++;
828 827
@@ -840,21 +839,19 @@ static int __devinit lp5521_probe(struct i2c_client *client,
840 ret = lp5521_register_sysfs(client); 839 ret = lp5521_register_sysfs(client);
841 if (ret) { 840 if (ret) {
842 dev_err(&client->dev, "registering sysfs failed\n"); 841 dev_err(&client->dev, "registering sysfs failed\n");
843 goto fail3; 842 goto fail2;
844 } 843 }
845 return ret; 844 return ret;
846fail3: 845fail2:
847 for (i = 0; i < chip->num_leds; i++) { 846 for (i = 0; i < chip->num_leds; i++) {
848 led_classdev_unregister(&chip->leds[i].cdev); 847 led_classdev_unregister(&chip->leds[i].cdev);
849 cancel_work_sync(&chip->leds[i].brightness_work); 848 cancel_work_sync(&chip->leds[i].brightness_work);
850 } 849 }
851fail2: 850fail1:
852 if (pdata->enable) 851 if (pdata->enable)
853 pdata->enable(0); 852 pdata->enable(0);
854 if (pdata->release_resources) 853 if (pdata->release_resources)
855 pdata->release_resources(); 854 pdata->release_resources();
856fail1:
857 kfree(chip);
858 return ret; 855 return ret;
859} 856}
860 857
@@ -875,7 +872,6 @@ static int __devexit lp5521_remove(struct i2c_client *client)
875 chip->pdata->enable(0); 872 chip->pdata->enable(0);
876 if (chip->pdata->release_resources) 873 if (chip->pdata->release_resources)
877 chip->pdata->release_resources(); 874 chip->pdata->release_resources();
878 kfree(chip);
879 return 0; 875 return 0;
880} 876}
881 877
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index 857a3e15f2dd..fbc12acada95 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -877,7 +877,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
877 struct lp5523_platform_data *pdata; 877 struct lp5523_platform_data *pdata;
878 int ret, i, led; 878 int ret, i, led;
879 879
880 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 880 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
881 if (!chip) 881 if (!chip)
882 return -ENOMEM; 882 return -ENOMEM;
883 883
@@ -888,8 +888,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
888 888
889 if (!pdata) { 889 if (!pdata) {
890 dev_err(&client->dev, "no platform data\n"); 890 dev_err(&client->dev, "no platform data\n");
891 ret = -EINVAL; 891 return -EINVAL;
892 goto fail1;
893 } 892 }
894 893
895 mutex_init(&chip->lock); 894 mutex_init(&chip->lock);
@@ -899,7 +898,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
899 if (pdata->setup_resources) { 898 if (pdata->setup_resources) {
900 ret = pdata->setup_resources(); 899 ret = pdata->setup_resources();
901 if (ret < 0) 900 if (ret < 0)
902 goto fail1; 901 return ret;
903 } 902 }
904 903
905 if (pdata->enable) { 904 if (pdata->enable) {
@@ -916,7 +915,7 @@ static int __devinit lp5523_probe(struct i2c_client *client,
916 */ 915 */
917 ret = lp5523_detect(client); 916 ret = lp5523_detect(client);
918 if (ret) 917 if (ret)
919 goto fail2; 918 goto fail1;
920 919
921 dev_info(&client->dev, "LP5523 Programmable led chip found\n"); 920 dev_info(&client->dev, "LP5523 Programmable led chip found\n");
922 921
@@ -925,13 +924,13 @@ static int __devinit lp5523_probe(struct i2c_client *client,
925 ret = lp5523_init_engine(&chip->engines[i], i + 1); 924 ret = lp5523_init_engine(&chip->engines[i], i + 1);
926 if (ret) { 925 if (ret) {
927 dev_err(&client->dev, "error initializing engine\n"); 926 dev_err(&client->dev, "error initializing engine\n");
928 goto fail2; 927 goto fail1;
929 } 928 }
930 } 929 }
931 ret = lp5523_configure(client); 930 ret = lp5523_configure(client);
932 if (ret < 0) { 931 if (ret < 0) {
933 dev_err(&client->dev, "error configuring chip\n"); 932 dev_err(&client->dev, "error configuring chip\n");
934 goto fail2; 933 goto fail1;
935 } 934 }
936 935
937 /* Initialize leds */ 936 /* Initialize leds */
@@ -943,10 +942,13 @@ static int __devinit lp5523_probe(struct i2c_client *client,
943 if (pdata->led_config[i].led_current == 0) 942 if (pdata->led_config[i].led_current == 0)
944 continue; 943 continue;
945 944
945 INIT_WORK(&chip->leds[led].brightness_work,
946 lp5523_led_brightness_work);
947
946 ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata); 948 ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata);
947 if (ret) { 949 if (ret) {
948 dev_err(&client->dev, "error initializing leds\n"); 950 dev_err(&client->dev, "error initializing leds\n");
949 goto fail3; 951 goto fail2;
950 } 952 }
951 chip->num_leds++; 953 chip->num_leds++;
952 954
@@ -956,30 +958,25 @@ static int __devinit lp5523_probe(struct i2c_client *client,
956 LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr, 958 LP5523_REG_LED_CURRENT_BASE + chip->leds[led].chan_nr,
957 chip->leds[led].led_current); 959 chip->leds[led].led_current);
958 960
959 INIT_WORK(&(chip->leds[led].brightness_work),
960 lp5523_led_brightness_work);
961
962 led++; 961 led++;
963 } 962 }
964 963
965 ret = lp5523_register_sysfs(client); 964 ret = lp5523_register_sysfs(client);
966 if (ret) { 965 if (ret) {
967 dev_err(&client->dev, "registering sysfs failed\n"); 966 dev_err(&client->dev, "registering sysfs failed\n");
968 goto fail3; 967 goto fail2;
969 } 968 }
970 return ret; 969 return ret;
971fail3: 970fail2:
972 for (i = 0; i < chip->num_leds; i++) { 971 for (i = 0; i < chip->num_leds; i++) {
973 led_classdev_unregister(&chip->leds[i].cdev); 972 led_classdev_unregister(&chip->leds[i].cdev);
974 cancel_work_sync(&chip->leds[i].brightness_work); 973 cancel_work_sync(&chip->leds[i].brightness_work);
975 } 974 }
976fail2: 975fail1:
977 if (pdata->enable) 976 if (pdata->enable)
978 pdata->enable(0); 977 pdata->enable(0);
979 if (pdata->release_resources) 978 if (pdata->release_resources)
980 pdata->release_resources(); 979 pdata->release_resources();
981fail1:
982 kfree(chip);
983 return ret; 980 return ret;
984} 981}
985 982
@@ -999,7 +996,6 @@ static int lp5523_remove(struct i2c_client *client)
999 chip->pdata->enable(0); 996 chip->pdata->enable(0);
1000 if (chip->pdata->release_resources) 997 if (chip->pdata->release_resources)
1001 chip->pdata->release_resources(); 998 chip->pdata->release_resources();
1002 kfree(chip);
1003 return 0; 999 return 0;
1004} 1000}
1005 1001
diff --git a/drivers/leds/leds-lp8788.c b/drivers/leds/leds-lp8788.c
new file mode 100644
index 000000000000..53bd136f1ef0
--- /dev/null
+++ b/drivers/leds/leds-lp8788.c
@@ -0,0 +1,193 @@
1/*
2 * TI LP8788 MFD - keyled driver
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <linux/mutex.h>
20#include <linux/mfd/lp8788.h>
21#include <linux/mfd/lp8788-isink.h>
22
23#define MAX_BRIGHTNESS LP8788_ISINK_MAX_PWM
24#define DEFAULT_LED_NAME "keyboard-backlight"
25
26struct lp8788_led {
27 struct lp8788 *lp;
28 struct mutex lock;
29 struct work_struct work;
30 struct led_classdev led_dev;
31 enum lp8788_isink_number isink_num;
32 enum led_brightness brightness;
33 int on;
34};
35
36struct lp8788_led_config {
37 enum lp8788_isink_scale scale;
38 enum lp8788_isink_number num;
39 int iout;
40};
41
42static struct lp8788_led_config default_led_config = {
43 .scale = LP8788_ISINK_SCALE_100mA,
44 .num = LP8788_ISINK_3,
45 .iout = 0,
46};
47
48static int lp8788_led_init_device(struct lp8788_led *led,
49 struct lp8788_led_platform_data *pdata)
50{
51 struct lp8788_led_config *cfg = &default_led_config;
52 u8 addr, mask, val;
53 int ret;
54
55 if (pdata) {
56 cfg->scale = pdata->scale;
57 cfg->num = pdata->num;
58 cfg->iout = pdata->iout_code;
59 }
60
61 led->isink_num = cfg->num;
62
63 /* scale configuration */
64 addr = LP8788_ISINK_CTRL;
65 mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET);
66 val = cfg->scale << cfg->num;
67 ret = lp8788_update_bits(led->lp, addr, mask, val);
68 if (ret)
69 return ret;
70
71 /* current configuration */
72 addr = lp8788_iout_addr[cfg->num];
73 mask = lp8788_iout_mask[cfg->num];
74 val = cfg->iout;
75
76 return lp8788_update_bits(led->lp, addr, mask, val);
77}
78
79static void lp8788_led_enable(struct lp8788_led *led,
80 enum lp8788_isink_number num, int on)
81{
82 u8 mask = 1 << num;
83 u8 val = on << num;
84
85 if (lp8788_update_bits(led->lp, LP8788_ISINK_CTRL, mask, val))
86 return;
87
88 led->on = on;
89}
90
91static void lp8788_led_work(struct work_struct *work)
92{
93 struct lp8788_led *led = container_of(work, struct lp8788_led, work);
94 enum lp8788_isink_number num = led->isink_num;
95 int enable;
96 u8 val = led->brightness;
97
98 mutex_lock(&led->lock);
99
100 switch (num) {
101 case LP8788_ISINK_1:
102 case LP8788_ISINK_2:
103 case LP8788_ISINK_3:
104 lp8788_write_byte(led->lp, lp8788_pwm_addr[num], val);
105 break;
106 default:
107 mutex_unlock(&led->lock);
108 return;
109 }
110
111 enable = (val > 0) ? 1 : 0;
112 if (enable != led->on)
113 lp8788_led_enable(led, num, enable);
114
115 mutex_unlock(&led->lock);
116}
117
118static void lp8788_brightness_set(struct led_classdev *led_cdev,
119 enum led_brightness brt_val)
120{
121 struct lp8788_led *led =
122 container_of(led_cdev, struct lp8788_led, led_dev);
123
124 led->brightness = brt_val;
125 schedule_work(&led->work);
126}
127
128static __devinit int lp8788_led_probe(struct platform_device *pdev)
129{
130 struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
131 struct lp8788_led_platform_data *led_pdata;
132 struct lp8788_led *led;
133 int ret;
134
135 led = devm_kzalloc(lp->dev, sizeof(struct lp8788_led), GFP_KERNEL);
136 if (!led)
137 return -ENOMEM;
138
139 led->lp = lp;
140 led->led_dev.max_brightness = MAX_BRIGHTNESS;
141 led->led_dev.brightness_set = lp8788_brightness_set;
142
143 led_pdata = lp->pdata ? lp->pdata->led_pdata : NULL;
144
145 if (!led_pdata || !led_pdata->name)
146 led->led_dev.name = DEFAULT_LED_NAME;
147 else
148 led->led_dev.name = led_pdata->name;
149
150 mutex_init(&led->lock);
151 INIT_WORK(&led->work, lp8788_led_work);
152
153 platform_set_drvdata(pdev, led);
154
155 ret = lp8788_led_init_device(led, led_pdata);
156 if (ret) {
157 dev_err(lp->dev, "led init device err: %d\n", ret);
158 return ret;
159 }
160
161 ret = led_classdev_register(lp->dev, &led->led_dev);
162 if (ret) {
163 dev_err(lp->dev, "led register err: %d\n", ret);
164 return ret;
165 }
166
167 return 0;
168}
169
170static int __devexit lp8788_led_remove(struct platform_device *pdev)
171{
172 struct lp8788_led *led = platform_get_drvdata(pdev);
173
174 led_classdev_unregister(&led->led_dev);
175 flush_work_sync(&led->work);
176
177 return 0;
178}
179
180static struct platform_driver lp8788_led_driver = {
181 .probe = lp8788_led_probe,
182 .remove = __devexit_p(lp8788_led_remove),
183 .driver = {
184 .name = LP8788_DEV_KEYLED,
185 .owner = THIS_MODULE,
186 },
187};
188module_platform_driver(lp8788_led_driver);
189
190MODULE_DESCRIPTION("Texas Instruments LP8788 Keyboard LED Driver");
191MODULE_AUTHOR("Milo Kim");
192MODULE_LICENSE("GPL");
193MODULE_ALIAS("platform:lp8788-keyled");
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index e311a96c4469..09a732217f6d 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -149,8 +149,9 @@ static int __devinit lt3593_led_probe(struct platform_device *pdev)
149 if (!pdata) 149 if (!pdata)
150 return -EBUSY; 150 return -EBUSY;
151 151
152 leds_data = kzalloc(sizeof(struct lt3593_led_data) * pdata->num_leds, 152 leds_data = devm_kzalloc(&pdev->dev,
153 GFP_KERNEL); 153 sizeof(struct lt3593_led_data) * pdata->num_leds,
154 GFP_KERNEL);
154 if (!leds_data) 155 if (!leds_data)
155 return -ENOMEM; 156 return -ENOMEM;
156 157
@@ -169,8 +170,6 @@ err:
169 for (i = i - 1; i >= 0; i--) 170 for (i = i - 1; i >= 0; i--)
170 delete_lt3593_led(&leds_data[i]); 171 delete_lt3593_led(&leds_data[i]);
171 172
172 kfree(leds_data);
173
174 return ret; 173 return ret;
175} 174}
176 175
@@ -185,8 +184,6 @@ static int __devexit lt3593_led_remove(struct platform_device *pdev)
185 for (i = 0; i < pdata->num_leds; i++) 184 for (i = 0; i < pdata->num_leds; i++)
186 delete_lt3593_led(&leds_data[i]); 185 delete_lt3593_led(&leds_data[i]);
187 186
188 kfree(leds_data);
189
190 return 0; 187 return 0;
191} 188}
192 189
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c
index f4c0e37fad1e..569e36de37df 100644
--- a/drivers/leds/leds-max8997.c
+++ b/drivers/leds/leds-max8997.c
@@ -49,71 +49,37 @@ struct max8997_led {
49 struct mutex mutex; 49 struct mutex mutex;
50}; 50};
51 51
52static void max8997_led_clear_mode(struct max8997_led *led,
53 enum max8997_led_mode mode)
54{
55 struct i2c_client *client = led->iodev->i2c;
56 u8 val = 0, mask = 0;
57 int ret;
58
59 switch (mode) {
60 case MAX8997_FLASH_MODE:
61 mask = led->id ?
62 MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK;
63 break;
64 case MAX8997_MOVIE_MODE:
65 mask = led->id ?
66 MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK;
67 break;
68 case MAX8997_FLASH_PIN_CONTROL_MODE:
69 mask = led->id ?
70 MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK;
71 break;
72 case MAX8997_MOVIE_PIN_CONTROL_MODE:
73 mask = led->id ?
74 MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK;
75 break;
76 default:
77 break;
78 }
79
80 if (mask) {
81 ret = max8997_update_reg(client,
82 MAX8997_REG_LEN_CNTL, val, mask);
83 if (ret)
84 dev_err(led->iodev->dev,
85 "failed to update register(%d)\n", ret);
86 }
87}
88
89static void max8997_led_set_mode(struct max8997_led *led, 52static void max8997_led_set_mode(struct max8997_led *led,
90 enum max8997_led_mode mode) 53 enum max8997_led_mode mode)
91{ 54{
92 int ret; 55 int ret;
93 struct i2c_client *client = led->iodev->i2c; 56 struct i2c_client *client = led->iodev->i2c;
94 u8 mask = 0; 57 u8 mask = 0, val;
95
96 /* First, clear the previous mode */
97 max8997_led_clear_mode(led, led->led_mode);
98 58
99 switch (mode) { 59 switch (mode) {
100 case MAX8997_FLASH_MODE: 60 case MAX8997_FLASH_MODE:
101 mask = led->id ? 61 mask = MAX8997_LED1_FLASH_MASK | MAX8997_LED0_FLASH_MASK;
62 val = led->id ?
102 MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK; 63 MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK;
103 led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS; 64 led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
104 break; 65 break;
105 case MAX8997_MOVIE_MODE: 66 case MAX8997_MOVIE_MODE:
106 mask = led->id ? 67 mask = MAX8997_LED1_MOVIE_MASK | MAX8997_LED0_MOVIE_MASK;
68 val = led->id ?
107 MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK; 69 MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK;
108 led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS; 70 led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
109 break; 71 break;
110 case MAX8997_FLASH_PIN_CONTROL_MODE: 72 case MAX8997_FLASH_PIN_CONTROL_MODE:
111 mask = led->id ? 73 mask = MAX8997_LED1_FLASH_PIN_MASK |
74 MAX8997_LED0_FLASH_PIN_MASK;
75 val = led->id ?
112 MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK; 76 MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK;
113 led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS; 77 led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
114 break; 78 break;
115 case MAX8997_MOVIE_PIN_CONTROL_MODE: 79 case MAX8997_MOVIE_PIN_CONTROL_MODE:
116 mask = led->id ? 80 mask = MAX8997_LED1_MOVIE_PIN_MASK |
81 MAX8997_LED0_MOVIE_PIN_MASK;
82 val = led->id ?
117 MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK; 83 MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK;
118 led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS; 84 led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
119 break; 85 break;
@@ -123,8 +89,8 @@ static void max8997_led_set_mode(struct max8997_led *led,
123 } 89 }
124 90
125 if (mask) { 91 if (mask) {
126 ret = max8997_update_reg(client, 92 ret = max8997_update_reg(client, MAX8997_REG_LEN_CNTL, val,
127 MAX8997_REG_LEN_CNTL, mask, mask); 93 mask);
128 if (ret) 94 if (ret)
129 dev_err(led->iodev->dev, 95 dev_err(led->iodev->dev,
130 "failed to update register(%d)\n", ret); 96 "failed to update register(%d)\n", ret);
@@ -276,11 +242,9 @@ static int __devinit max8997_led_probe(struct platform_device *pdev)
276 return -ENODEV; 242 return -ENODEV;
277 } 243 }
278 244
279 led = kzalloc(sizeof(*led), GFP_KERNEL); 245 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
280 if (led == NULL) { 246 if (led == NULL)
281 ret = -ENOMEM; 247 return -ENOMEM;
282 goto err_mem;
283 }
284 248
285 led->id = pdev->id; 249 led->id = pdev->id;
286 snprintf(name, sizeof(name), "max8997-led%d", pdev->id); 250 snprintf(name, sizeof(name), "max8997-led%d", pdev->id);
@@ -315,23 +279,17 @@ static int __devinit max8997_led_probe(struct platform_device *pdev)
315 279
316 ret = led_classdev_register(&pdev->dev, &led->cdev); 280 ret = led_classdev_register(&pdev->dev, &led->cdev);
317 if (ret < 0) 281 if (ret < 0)
318 goto err_led; 282 return ret;
319 283
320 ret = device_create_file(led->cdev.dev, &dev_attr_mode); 284 ret = device_create_file(led->cdev.dev, &dev_attr_mode);
321 if (ret != 0) { 285 if (ret != 0) {
322 dev_err(&pdev->dev, 286 dev_err(&pdev->dev,
323 "failed to create file: %d\n", ret); 287 "failed to create file: %d\n", ret);
324 goto err_file; 288 led_classdev_unregister(&led->cdev);
289 return ret;
325 } 290 }
326 291
327 return 0; 292 return 0;
328
329err_file:
330 led_classdev_unregister(&led->cdev);
331err_led:
332 kfree(led);
333err_mem:
334 return ret;
335} 293}
336 294
337static int __devexit max8997_led_remove(struct platform_device *pdev) 295static int __devexit max8997_led_remove(struct platform_device *pdev)
@@ -340,7 +298,6 @@ static int __devexit max8997_led_remove(struct platform_device *pdev)
340 298
341 device_remove_file(led->cdev.dev, &dev_attr_mode); 299 device_remove_file(led->cdev.dev, &dev_attr_mode);
342 led_classdev_unregister(&led->cdev); 300 led_classdev_unregister(&led->cdev);
343 kfree(led);
344 301
345 return 0; 302 return 0;
346} 303}
@@ -354,17 +311,7 @@ static struct platform_driver max8997_led_driver = {
354 .remove = __devexit_p(max8997_led_remove), 311 .remove = __devexit_p(max8997_led_remove),
355}; 312};
356 313
357static int __init max8997_led_init(void) 314module_platform_driver(max8997_led_driver);
358{
359 return platform_driver_register(&max8997_led_driver);
360}
361module_init(max8997_led_init);
362
363static void __exit max8997_led_exit(void)
364{
365 platform_driver_unregister(&max8997_led_driver);
366}
367module_exit(max8997_led_exit);
368 315
369MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); 316MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
370MODULE_DESCRIPTION("MAX8997 LED driver"); 317MODULE_DESCRIPTION("MAX8997 LED driver");
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index 4cc6a2e3df34..2a5d43400677 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -280,7 +280,8 @@ static int __devinit mc13783_led_probe(struct platform_device *pdev)
280 return -EINVAL; 280 return -EINVAL;
281 } 281 }
282 282
283 led = kcalloc(pdata->num_leds, sizeof(*led), GFP_KERNEL); 283 led = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*led),
284 GFP_KERNEL);
284 if (led == NULL) { 285 if (led == NULL) {
285 dev_err(&pdev->dev, "failed to alloc memory\n"); 286 dev_err(&pdev->dev, "failed to alloc memory\n");
286 return -ENOMEM; 287 return -ENOMEM;
@@ -289,7 +290,7 @@ static int __devinit mc13783_led_probe(struct platform_device *pdev)
289 ret = mc13783_leds_prepare(pdev); 290 ret = mc13783_leds_prepare(pdev);
290 if (ret) { 291 if (ret) {
291 dev_err(&pdev->dev, "unable to init led driver\n"); 292 dev_err(&pdev->dev, "unable to init led driver\n");
292 goto err_free; 293 return ret;
293 } 294 }
294 295
295 for (i = 0; i < pdata->num_leds; i++) { 296 for (i = 0; i < pdata->num_leds; i++) {
@@ -344,8 +345,6 @@ err_register:
344 cancel_work_sync(&led[i].work); 345 cancel_work_sync(&led[i].work);
345 } 346 }
346 347
347err_free:
348 kfree(led);
349 return ret; 348 return ret;
350} 349}
351 350
@@ -372,7 +371,7 @@ static int __devexit mc13783_led_remove(struct platform_device *pdev)
372 371
373 mc13xxx_unlock(dev); 372 mc13xxx_unlock(dev);
374 373
375 kfree(led); 374 platform_set_drvdata(pdev, NULL);
376 return 0; 375 return 0;
377} 376}
378 377
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index 73973fdbd8be..e37618e363cf 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -362,14 +362,14 @@ static int __devinit netxbig_led_probe(struct platform_device *pdev)
362 if (!pdata) 362 if (!pdata)
363 return -EINVAL; 363 return -EINVAL;
364 364
365 leds_data = kzalloc(sizeof(struct netxbig_led_data) * pdata->num_leds, 365 leds_data = devm_kzalloc(&pdev->dev,
366 GFP_KERNEL); 366 sizeof(struct netxbig_led_data) * pdata->num_leds, GFP_KERNEL);
367 if (!leds_data) 367 if (!leds_data)
368 return -ENOMEM; 368 return -ENOMEM;
369 369
370 ret = gpio_ext_init(pdata->gpio_ext); 370 ret = gpio_ext_init(pdata->gpio_ext);
371 if (ret < 0) 371 if (ret < 0)
372 goto err_free_data; 372 return ret;
373 373
374 for (i = 0; i < pdata->num_leds; i++) { 374 for (i = 0; i < pdata->num_leds; i++) {
375 ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]); 375 ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]);
@@ -386,9 +386,6 @@ err_free_leds:
386 delete_netxbig_led(&leds_data[i]); 386 delete_netxbig_led(&leds_data[i]);
387 387
388 gpio_ext_free(pdata->gpio_ext); 388 gpio_ext_free(pdata->gpio_ext);
389err_free_data:
390 kfree(leds_data);
391
392 return ret; 389 return ret;
393} 390}
394 391
@@ -404,7 +401,6 @@ static int __devexit netxbig_led_remove(struct platform_device *pdev)
404 delete_netxbig_led(&leds_data[i]); 401 delete_netxbig_led(&leds_data[i]);
405 402
406 gpio_ext_free(pdata->gpio_ext); 403 gpio_ext_free(pdata->gpio_ext);
407 kfree(leds_data);
408 404
409 return 0; 405 return 0;
410} 406}
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index 01cf89ec6944..10528dafb043 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -273,29 +273,23 @@ static int __devinit ns2_led_probe(struct platform_device *pdev)
273 if (!pdata) 273 if (!pdata)
274 return -EINVAL; 274 return -EINVAL;
275 275
276 leds_data = kzalloc(sizeof(struct ns2_led_data) * 276 leds_data = devm_kzalloc(&pdev->dev, sizeof(struct ns2_led_data) *
277 pdata->num_leds, GFP_KERNEL); 277 pdata->num_leds, GFP_KERNEL);
278 if (!leds_data) 278 if (!leds_data)
279 return -ENOMEM; 279 return -ENOMEM;
280 280
281 for (i = 0; i < pdata->num_leds; i++) { 281 for (i = 0; i < pdata->num_leds; i++) {
282 ret = create_ns2_led(pdev, &leds_data[i], &pdata->leds[i]); 282 ret = create_ns2_led(pdev, &leds_data[i], &pdata->leds[i]);
283 if (ret < 0) 283 if (ret < 0) {
284 goto err; 284 for (i = i - 1; i >= 0; i--)
285 285 delete_ns2_led(&leds_data[i]);
286 return ret;
287 }
286 } 288 }
287 289
288 platform_set_drvdata(pdev, leds_data); 290 platform_set_drvdata(pdev, leds_data);
289 291
290 return 0; 292 return 0;
291
292err:
293 for (i = i - 1; i >= 0; i--)
294 delete_ns2_led(&leds_data[i]);
295
296 kfree(leds_data);
297
298 return ret;
299} 293}
300 294
301static int __devexit ns2_led_remove(struct platform_device *pdev) 295static int __devexit ns2_led_remove(struct platform_device *pdev)
@@ -309,7 +303,6 @@ static int __devexit ns2_led_remove(struct platform_device *pdev)
309 for (i = 0; i < pdata->num_leds; i++) 303 for (i = 0; i < pdata->num_leds; i++)
310 delete_ns2_led(&leds_data[i]); 304 delete_ns2_led(&leds_data[i]);
311 305
312 kfree(leds_data);
313 platform_set_drvdata(pdev, NULL); 306 platform_set_drvdata(pdev, NULL);
314 307
315 return 0; 308 return 0;
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index ceccab44b5b8..cee8a5b483ac 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -449,7 +449,6 @@ static int pca9532_probe(struct i2c_client *client,
449{ 449{
450 struct pca9532_data *data = i2c_get_clientdata(client); 450 struct pca9532_data *data = i2c_get_clientdata(client);
451 struct pca9532_platform_data *pca9532_pdata = client->dev.platform_data; 451 struct pca9532_platform_data *pca9532_pdata = client->dev.platform_data;
452 int err;
453 452
454 if (!pca9532_pdata) 453 if (!pca9532_pdata)
455 return -EIO; 454 return -EIO;
@@ -458,7 +457,7 @@ static int pca9532_probe(struct i2c_client *client,
458 I2C_FUNC_SMBUS_BYTE_DATA)) 457 I2C_FUNC_SMBUS_BYTE_DATA))
459 return -EIO; 458 return -EIO;
460 459
461 data = kzalloc(sizeof(*data), GFP_KERNEL); 460 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
462 if (!data) 461 if (!data)
463 return -ENOMEM; 462 return -ENOMEM;
464 463
@@ -469,11 +468,7 @@ static int pca9532_probe(struct i2c_client *client,
469 data->client = client; 468 data->client = client;
470 mutex_init(&data->update_lock); 469 mutex_init(&data->update_lock);
471 470
472 err = pca9532_configure(client, data, pca9532_pdata); 471 return pca9532_configure(client, data, pca9532_pdata);
473 if (err)
474 kfree(data);
475
476 return err;
477} 472}
478 473
479static int pca9532_remove(struct i2c_client *client) 474static int pca9532_remove(struct i2c_client *client)
@@ -485,7 +480,6 @@ static int pca9532_remove(struct i2c_client *client)
485 if (err) 480 if (err)
486 return err; 481 return err;
487 482
488 kfree(data);
489 return 0; 483 return 0;
490} 484}
491 485
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index 5f462dbf0dbb..aef3cf0432fe 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -293,15 +293,14 @@ static int __devinit pca955x_probe(struct i2c_client *client,
293 } 293 }
294 } 294 }
295 295
296 pca955x = kzalloc(sizeof(*pca955x), GFP_KERNEL); 296 pca955x = devm_kzalloc(&client->dev, sizeof(*pca955x), GFP_KERNEL);
297 if (!pca955x) 297 if (!pca955x)
298 return -ENOMEM; 298 return -ENOMEM;
299 299
300 pca955x->leds = kzalloc(sizeof(*pca955x_led) * chip->bits, GFP_KERNEL); 300 pca955x->leds = devm_kzalloc(&client->dev,
301 if (!pca955x->leds) { 301 sizeof(*pca955x_led) * chip->bits, GFP_KERNEL);
302 err = -ENOMEM; 302 if (!pca955x->leds)
303 goto exit_nomem; 303 return -ENOMEM;
304 }
305 304
306 i2c_set_clientdata(client, pca955x); 305 i2c_set_clientdata(client, pca955x);
307 306
@@ -361,10 +360,6 @@ exit:
361 cancel_work_sync(&pca955x->leds[i].work); 360 cancel_work_sync(&pca955x->leds[i].work);
362 } 361 }
363 362
364 kfree(pca955x->leds);
365exit_nomem:
366 kfree(pca955x);
367
368 return err; 363 return err;
369} 364}
370 365
@@ -378,9 +373,6 @@ static int __devexit pca955x_remove(struct i2c_client *client)
378 cancel_work_sync(&pca955x->leds[i].work); 373 cancel_work_sync(&pca955x->leds[i].work);
379 } 374 }
380 375
381 kfree(pca955x->leds);
382 kfree(pca955x);
383
384 return 0; 376 return 0;
385} 377}
386 378
diff --git a/drivers/leds/leds-pca9633.c b/drivers/leds/leds-pca9633.c
index d8926fd031aa..edcd706c5631 100644
--- a/drivers/leds/leds-pca9633.c
+++ b/drivers/leds/leds-pca9633.c
@@ -108,7 +108,7 @@ static int __devinit pca9633_probe(struct i2c_client *client,
108 } 108 }
109 } 109 }
110 110
111 pca9633 = kcalloc(4, sizeof(*pca9633), GFP_KERNEL); 111 pca9633 = devm_kzalloc(&client->dev, 4 * sizeof(*pca9633), GFP_KERNEL);
112 if (!pca9633) 112 if (!pca9633)
113 return -ENOMEM; 113 return -ENOMEM;
114 114
@@ -156,8 +156,6 @@ exit:
156 cancel_work_sync(&pca9633[i].work); 156 cancel_work_sync(&pca9633[i].work);
157 } 157 }
158 158
159 kfree(pca9633);
160
161 return err; 159 return err;
162} 160}
163 161
@@ -171,8 +169,6 @@ static int __devexit pca9633_remove(struct i2c_client *client)
171 cancel_work_sync(&pca9633[i].work); 169 cancel_work_sync(&pca9633[i].work);
172 } 170 }
173 171
174 kfree(pca9633);
175
176 return 0; 172 return 0;
177} 173}
178 174
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 3ed92f34bd44..f2e44c719437 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -57,7 +57,8 @@ static int led_pwm_probe(struct platform_device *pdev)
57 if (!pdata) 57 if (!pdata)
58 return -EBUSY; 58 return -EBUSY;
59 59
60 leds_data = kzalloc(sizeof(struct led_pwm_data) * pdata->num_leds, 60 leds_data = devm_kzalloc(&pdev->dev,
61 sizeof(struct led_pwm_data) * pdata->num_leds,
61 GFP_KERNEL); 62 GFP_KERNEL);
62 if (!leds_data) 63 if (!leds_data)
63 return -ENOMEM; 64 return -ENOMEM;
@@ -103,8 +104,6 @@ err:
103 } 104 }
104 } 105 }
105 106
106 kfree(leds_data);
107
108 return ret; 107 return ret;
109} 108}
110 109
@@ -121,8 +120,6 @@ static int __devexit led_pwm_remove(struct platform_device *pdev)
121 pwm_free(leds_data[i].pwm); 120 pwm_free(leds_data[i].pwm);
122 } 121 }
123 122
124 kfree(leds_data);
125
126 return 0; 123 return 0;
127} 124}
128 125
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
index df7e963bddd3..25d382d60fa9 100644
--- a/drivers/leds/leds-regulator.c
+++ b/drivers/leds/leds-regulator.c
@@ -158,7 +158,7 @@ static int __devinit regulator_led_probe(struct platform_device *pdev)
158 return PTR_ERR(vcc); 158 return PTR_ERR(vcc);
159 } 159 }
160 160
161 led = kzalloc(sizeof(*led), GFP_KERNEL); 161 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
162 if (led == NULL) { 162 if (led == NULL) {
163 ret = -ENOMEM; 163 ret = -ENOMEM;
164 goto err_vcc; 164 goto err_vcc;
@@ -169,7 +169,7 @@ static int __devinit regulator_led_probe(struct platform_device *pdev)
169 dev_err(&pdev->dev, "Invalid default brightness %d\n", 169 dev_err(&pdev->dev, "Invalid default brightness %d\n",
170 pdata->brightness); 170 pdata->brightness);
171 ret = -EINVAL; 171 ret = -EINVAL;
172 goto err_led; 172 goto err_vcc;
173 } 173 }
174 led->value = pdata->brightness; 174 led->value = pdata->brightness;
175 175
@@ -190,7 +190,7 @@ static int __devinit regulator_led_probe(struct platform_device *pdev)
190 ret = led_classdev_register(&pdev->dev, &led->cdev); 190 ret = led_classdev_register(&pdev->dev, &led->cdev);
191 if (ret < 0) { 191 if (ret < 0) {
192 cancel_work_sync(&led->work); 192 cancel_work_sync(&led->work);
193 goto err_led; 193 goto err_vcc;
194 } 194 }
195 195
196 /* to expose the default value to userspace */ 196 /* to expose the default value to userspace */
@@ -201,8 +201,6 @@ static int __devinit regulator_led_probe(struct platform_device *pdev)
201 201
202 return 0; 202 return 0;
203 203
204err_led:
205 kfree(led);
206err_vcc: 204err_vcc:
207 regulator_put(vcc); 205 regulator_put(vcc);
208 return ret; 206 return ret;
@@ -216,7 +214,6 @@ static int __devexit regulator_led_remove(struct platform_device *pdev)
216 cancel_work_sync(&led->work); 214 cancel_work_sync(&led->work);
217 regulator_led_disable(led); 215 regulator_led_disable(led);
218 regulator_put(led->vcc); 216 regulator_put(led->vcc);
219 kfree(led);
220 return 0; 217 return 0;
221} 218}
222 219
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c
index 32fe337d5c68..9ee12c28059a 100644
--- a/drivers/leds/leds-renesas-tpu.c
+++ b/drivers/leds/leds-renesas-tpu.c
@@ -243,31 +243,30 @@ static int __devinit r_tpu_probe(struct platform_device *pdev)
243 struct led_renesas_tpu_config *cfg = pdev->dev.platform_data; 243 struct led_renesas_tpu_config *cfg = pdev->dev.platform_data;
244 struct r_tpu_priv *p; 244 struct r_tpu_priv *p;
245 struct resource *res; 245 struct resource *res;
246 int ret = -ENXIO; 246 int ret;
247 247
248 if (!cfg) { 248 if (!cfg) {
249 dev_err(&pdev->dev, "missing platform data\n"); 249 dev_err(&pdev->dev, "missing platform data\n");
250 goto err0; 250 goto err0;
251 } 251 }
252 252
253 p = kzalloc(sizeof(*p), GFP_KERNEL); 253 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
254 if (p == NULL) { 254 if (p == NULL) {
255 dev_err(&pdev->dev, "failed to allocate driver data\n"); 255 dev_err(&pdev->dev, "failed to allocate driver data\n");
256 ret = -ENOMEM; 256 return -ENOMEM;
257 goto err0;
258 } 257 }
259 258
260 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 259 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
261 if (!res) { 260 if (!res) {
262 dev_err(&pdev->dev, "failed to get I/O memory\n"); 261 dev_err(&pdev->dev, "failed to get I/O memory\n");
263 goto err1; 262 return -ENXIO;
264 } 263 }
265 264
266 /* map memory, let mapbase point to our channel */ 265 /* map memory, let mapbase point to our channel */
267 p->mapbase = ioremap_nocache(res->start, resource_size(res)); 266 p->mapbase = ioremap_nocache(res->start, resource_size(res));
268 if (p->mapbase == NULL) { 267 if (p->mapbase == NULL) {
269 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 268 dev_err(&pdev->dev, "failed to remap I/O memory\n");
270 goto err1; 269 return -ENXIO;
271 } 270 }
272 271
273 /* get hold of clock */ 272 /* get hold of clock */
@@ -275,7 +274,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev)
275 if (IS_ERR(p->clk)) { 274 if (IS_ERR(p->clk)) {
276 dev_err(&pdev->dev, "cannot get clock\n"); 275 dev_err(&pdev->dev, "cannot get clock\n");
277 ret = PTR_ERR(p->clk); 276 ret = PTR_ERR(p->clk);
278 goto err2; 277 goto err0;
279 } 278 }
280 279
281 p->pdev = pdev; 280 p->pdev = pdev;
@@ -294,7 +293,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev)
294 p->ldev.flags |= LED_CORE_SUSPENDRESUME; 293 p->ldev.flags |= LED_CORE_SUSPENDRESUME;
295 ret = led_classdev_register(&pdev->dev, &p->ldev); 294 ret = led_classdev_register(&pdev->dev, &p->ldev);
296 if (ret < 0) 295 if (ret < 0)
297 goto err3; 296 goto err1;
298 297
299 /* max_brightness may be updated by the LED core code */ 298 /* max_brightness may be updated by the LED core code */
300 p->min_rate = p->ldev.max_brightness * p->refresh_rate; 299 p->min_rate = p->ldev.max_brightness * p->refresh_rate;
@@ -302,14 +301,11 @@ static int __devinit r_tpu_probe(struct platform_device *pdev)
302 pm_runtime_enable(&pdev->dev); 301 pm_runtime_enable(&pdev->dev);
303 return 0; 302 return 0;
304 303
305 err3: 304 err1:
306 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); 305 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF);
307 clk_put(p->clk); 306 clk_put(p->clk);
308 err2:
309 iounmap(p->mapbase);
310 err1:
311 kfree(p);
312 err0: 307 err0:
308 iounmap(p->mapbase);
313 return ret; 309 return ret;
314} 310}
315 311
@@ -327,7 +323,6 @@ static int __devexit r_tpu_remove(struct platform_device *pdev)
327 clk_put(p->clk); 323 clk_put(p->clk);
328 324
329 iounmap(p->mapbase); 325 iounmap(p->mapbase);
330 kfree(p);
331 return 0; 326 return 0;
332} 327}
333 328
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index bd0a5ed49c42..942f0ea18178 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -45,17 +45,19 @@ static void s3c24xx_led_set(struct led_classdev *led_cdev,
45{ 45{
46 struct s3c24xx_gpio_led *led = to_gpio(led_cdev); 46 struct s3c24xx_gpio_led *led = to_gpio(led_cdev);
47 struct s3c24xx_led_platdata *pd = led->pdata; 47 struct s3c24xx_led_platdata *pd = led->pdata;
48 int state = (value ? 1 : 0) ^ (pd->flags & S3C24XX_LEDF_ACTLOW);
48 49
49 /* there will be a short delay between setting the output and 50 /* there will be a short delay between setting the output and
50 * going from output to input when using tristate. */ 51 * going from output to input when using tristate. */
51 52
52 s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^ 53 gpio_set_value(pd->gpio, state);
53 (pd->flags & S3C24XX_LEDF_ACTLOW));
54
55 if (pd->flags & S3C24XX_LEDF_TRISTATE)
56 s3c2410_gpio_cfgpin(pd->gpio,
57 value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT);
58 54
55 if (pd->flags & S3C24XX_LEDF_TRISTATE) {
56 if (value)
57 gpio_direction_output(pd->gpio, state);
58 else
59 gpio_direction_input(pd->gpio);
60 }
59} 61}
60 62
61static int s3c24xx_led_remove(struct platform_device *dev) 63static int s3c24xx_led_remove(struct platform_device *dev)
@@ -63,7 +65,6 @@ static int s3c24xx_led_remove(struct platform_device *dev)
63 struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); 65 struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);
64 66
65 led_classdev_unregister(&led->cdev); 67 led_classdev_unregister(&led->cdev);
66 kfree(led);
67 68
68 return 0; 69 return 0;
69} 70}
@@ -74,7 +75,8 @@ static int s3c24xx_led_probe(struct platform_device *dev)
74 struct s3c24xx_gpio_led *led; 75 struct s3c24xx_gpio_led *led;
75 int ret; 76 int ret;
76 77
77 led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL); 78 led = devm_kzalloc(&dev->dev, sizeof(struct s3c24xx_gpio_led),
79 GFP_KERNEL);
78 if (led == NULL) { 80 if (led == NULL) {
79 dev_err(&dev->dev, "No memory for device\n"); 81 dev_err(&dev->dev, "No memory for device\n");
80 return -ENOMEM; 82 return -ENOMEM;
@@ -89,27 +91,27 @@ static int s3c24xx_led_probe(struct platform_device *dev)
89 91
90 led->pdata = pdata; 92 led->pdata = pdata;
91 93
94 ret = devm_gpio_request(&dev->dev, pdata->gpio, "S3C24XX_LED");
95 if (ret < 0)
96 return ret;
97
92 /* no point in having a pull-up if we are always driving */ 98 /* no point in having a pull-up if we are always driving */
93 99
94 if (pdata->flags & S3C24XX_LEDF_TRISTATE) { 100 s3c_gpio_setpull(pdata->gpio, S3C_GPIO_PULL_NONE);
95 s3c2410_gpio_setpin(pdata->gpio, 0); 101
96 s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT); 102 if (pdata->flags & S3C24XX_LEDF_TRISTATE)
97 } else { 103 gpio_direction_input(pdata->gpio);
98 s3c2410_gpio_pullup(pdata->gpio, 0); 104 else
99 s3c2410_gpio_setpin(pdata->gpio, 0); 105 gpio_direction_output(pdata->gpio,
100 s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT); 106 pdata->flags & S3C24XX_LEDF_ACTLOW ? 1 : 0);
101 }
102 107
103 /* register our new led device */ 108 /* register our new led device */
104 109
105 ret = led_classdev_register(&dev->dev, &led->cdev); 110 ret = led_classdev_register(&dev->dev, &led->cdev);
106 if (ret < 0) { 111 if (ret < 0)
107 dev_err(&dev->dev, "led_classdev_register failed\n"); 112 dev_err(&dev->dev, "led_classdev_register failed\n");
108 kfree(led);
109 return ret;
110 }
111 113
112 return 0; 114 return ret;
113} 115}
114 116
115static struct platform_driver s3c24xx_led_driver = { 117static struct platform_driver s3c24xx_led_driver = {
diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c
index 1757396b20b3..134d9a4b34f1 100644
--- a/drivers/leds/leds-sunfire.c
+++ b/drivers/leds/leds-sunfire.c
@@ -132,15 +132,13 @@ static int __devinit sunfire_led_generic_probe(struct platform_device *pdev,
132 if (pdev->num_resources != 1) { 132 if (pdev->num_resources != 1) {
133 printk(KERN_ERR PFX "Wrong number of resources %d, should be 1\n", 133 printk(KERN_ERR PFX "Wrong number of resources %d, should be 1\n",
134 pdev->num_resources); 134 pdev->num_resources);
135 err = -EINVAL; 135 return -EINVAL;
136 goto out;
137 } 136 }
138 137
139 p = kzalloc(sizeof(*p), GFP_KERNEL); 138 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
140 if (!p) { 139 if (!p) {
141 printk(KERN_ERR PFX "Could not allocate struct sunfire_drvdata\n"); 140 printk(KERN_ERR PFX "Could not allocate struct sunfire_drvdata\n");
142 err = -ENOMEM; 141 return -ENOMEM;
143 goto out;
144 } 142 }
145 143
146 for (i = 0; i < NUM_LEDS_PER_BOARD; i++) { 144 for (i = 0; i < NUM_LEDS_PER_BOARD; i++) {
@@ -156,20 +154,15 @@ static int __devinit sunfire_led_generic_probe(struct platform_device *pdev,
156 if (err) { 154 if (err) {
157 printk(KERN_ERR PFX "Could not register %s LED\n", 155 printk(KERN_ERR PFX "Could not register %s LED\n",
158 lp->name); 156 lp->name);
159 goto out_unregister_led_cdevs; 157 for (i--; i >= 0; i--)
158 led_classdev_unregister(&p->leds[i].led_cdev);
159 return err;
160 } 160 }
161 } 161 }
162 162
163 dev_set_drvdata(&pdev->dev, p); 163 dev_set_drvdata(&pdev->dev, p);
164 164
165 return 0; 165 return 0;
166
167out_unregister_led_cdevs:
168 for (i--; i >= 0; i--)
169 led_classdev_unregister(&p->leds[i].led_cdev);
170 kfree(p);
171out:
172 return err;
173} 166}
174 167
175static int __devexit sunfire_led_generic_remove(struct platform_device *pdev) 168static int __devexit sunfire_led_generic_remove(struct platform_device *pdev)
@@ -180,8 +173,6 @@ static int __devexit sunfire_led_generic_remove(struct platform_device *pdev)
180 for (i = 0; i < NUM_LEDS_PER_BOARD; i++) 173 for (i = 0; i < NUM_LEDS_PER_BOARD; i++)
181 led_classdev_unregister(&p->leds[i].led_cdev); 174 led_classdev_unregister(&p->leds[i].led_cdev);
182 175
183 kfree(p);
184
185 return 0; 176 return 0;
186} 177}
187 178
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
index 6c1c14f31635..dabcf7ae8d0f 100644
--- a/drivers/leds/leds-tca6507.c
+++ b/drivers/leds/leds-tca6507.c
@@ -687,7 +687,7 @@ static int __devinit tca6507_probe(struct i2c_client *client,
687 NUM_LEDS); 687 NUM_LEDS);
688 return -ENODEV; 688 return -ENODEV;
689 } 689 }
690 tca = kzalloc(sizeof(*tca), GFP_KERNEL); 690 tca = devm_kzalloc(&client->dev, sizeof(*tca), GFP_KERNEL);
691 if (!tca) 691 if (!tca)
692 return -ENOMEM; 692 return -ENOMEM;
693 693
@@ -727,7 +727,6 @@ exit:
727 if (tca->leds[i].led_cdev.name) 727 if (tca->leds[i].led_cdev.name)
728 led_classdev_unregister(&tca->leds[i].led_cdev); 728 led_classdev_unregister(&tca->leds[i].led_cdev);
729 } 729 }
730 kfree(tca);
731 return err; 730 return err;
732} 731}
733 732
@@ -743,7 +742,6 @@ static int __devexit tca6507_remove(struct i2c_client *client)
743 } 742 }
744 tca6507_remove_gpio(tca); 743 tca6507_remove_gpio(tca);
745 cancel_work_sync(&tca->work); 744 cancel_work_sync(&tca->work);
746 kfree(tca);
747 745
748 return 0; 746 return 0;
749} 747}
@@ -758,18 +756,7 @@ static struct i2c_driver tca6507_driver = {
758 .id_table = tca6507_id, 756 .id_table = tca6507_id,
759}; 757};
760 758
761static int __init tca6507_leds_init(void) 759module_i2c_driver(tca6507_driver);
762{
763 return i2c_add_driver(&tca6507_driver);
764}
765
766static void __exit tca6507_leds_exit(void)
767{
768 i2c_del_driver(&tca6507_driver);
769}
770
771module_init(tca6507_leds_init);
772module_exit(tca6507_leds_exit);
773 760
774MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); 761MODULE_AUTHOR("NeilBrown <neilb@suse.de>");
775MODULE_DESCRIPTION("TCA6507 LED/GPO driver"); 762MODULE_DESCRIPTION("TCA6507 LED/GPO driver");
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index e77c7f8dcdd4..d02acd496126 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -17,7 +17,7 @@
17#include <linux/rwsem.h> 17#include <linux/rwsem.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19 19
20static inline void led_set_brightness(struct led_classdev *led_cdev, 20static inline void __led_set_brightness(struct led_classdev *led_cdev,
21 enum led_brightness value) 21 enum led_brightness value)
22{ 22{
23 if (value > led_cdev->max_brightness) 23 if (value > led_cdev->max_brightness)
diff --git a/drivers/leds/ledtrig-backlight.c b/drivers/leds/ledtrig-backlight.c
index e2726867c5d4..b941685f2227 100644
--- a/drivers/leds/ledtrig-backlight.c
+++ b/drivers/leds/ledtrig-backlight.c
@@ -46,9 +46,9 @@ static int fb_notifier_callback(struct notifier_block *p,
46 46
47 if ((n->old_status == UNBLANK) ^ n->invert) { 47 if ((n->old_status == UNBLANK) ^ n->invert) {
48 n->brightness = led->brightness; 48 n->brightness = led->brightness;
49 led_set_brightness(led, LED_OFF); 49 __led_set_brightness(led, LED_OFF);
50 } else { 50 } else {
51 led_set_brightness(led, n->brightness); 51 __led_set_brightness(led, n->brightness);
52 } 52 }
53 53
54 n->old_status = new_status; 54 n->old_status = new_status;
@@ -87,9 +87,9 @@ static ssize_t bl_trig_invert_store(struct device *dev,
87 87
88 /* After inverting, we need to update the LED. */ 88 /* After inverting, we need to update the LED. */
89 if ((n->old_status == BLANK) ^ n->invert) 89 if ((n->old_status == BLANK) ^ n->invert)
90 led_set_brightness(led, LED_OFF); 90 __led_set_brightness(led, LED_OFF);
91 else 91 else
92 led_set_brightness(led, n->brightness); 92 __led_set_brightness(led, n->brightness);
93 93
94 return num; 94 return num;
95} 95}
diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/ledtrig-default-on.c
index a4ef54b9d508..eac1f1b1adac 100644
--- a/drivers/leds/ledtrig-default-on.c
+++ b/drivers/leds/ledtrig-default-on.c
@@ -19,7 +19,7 @@
19 19
20static void defon_trig_activate(struct led_classdev *led_cdev) 20static void defon_trig_activate(struct led_classdev *led_cdev)
21{ 21{
22 led_set_brightness(led_cdev, led_cdev->max_brightness); 22 __led_set_brightness(led_cdev, led_cdev->max_brightness);
23} 23}
24 24
25static struct led_trigger defon_led_trigger = { 25static struct led_trigger defon_led_trigger = {
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c
index f057c101b896..ba215dc42f98 100644
--- a/drivers/leds/ledtrig-gpio.c
+++ b/drivers/leds/ledtrig-gpio.c
@@ -54,12 +54,12 @@ static void gpio_trig_work(struct work_struct *work)
54 54
55 if (tmp) { 55 if (tmp) {
56 if (gpio_data->desired_brightness) 56 if (gpio_data->desired_brightness)
57 led_set_brightness(gpio_data->led, 57 __led_set_brightness(gpio_data->led,
58 gpio_data->desired_brightness); 58 gpio_data->desired_brightness);
59 else 59 else
60 led_set_brightness(gpio_data->led, LED_FULL); 60 __led_set_brightness(gpio_data->led, LED_FULL);
61 } else { 61 } else {
62 led_set_brightness(gpio_data->led, LED_OFF); 62 __led_set_brightness(gpio_data->led, LED_OFF);
63 } 63 }
64} 64}
65 65
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
index a019fbb70880..1edc7463ce83 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -74,7 +74,7 @@ static void led_heartbeat_function(unsigned long data)
74 break; 74 break;
75 } 75 }
76 76
77 led_set_brightness(led_cdev, brightness); 77 __led_set_brightness(led_cdev, brightness);
78 mod_timer(&heartbeat_data->timer, jiffies + delay); 78 mod_timer(&heartbeat_data->timer, jiffies + delay);
79} 79}
80 80
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index ec099fcbcb00..2cd7c0cf5924 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -12,39 +12,22 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/jiffies.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/init.h> 16#include <linux/init.h>
18#include <linux/timer.h>
19#include <linux/leds.h> 17#include <linux/leds.h>
20 18
21static void ledtrig_ide_timerfunc(unsigned long data); 19#define BLINK_DELAY 30
22 20
23DEFINE_LED_TRIGGER(ledtrig_ide); 21DEFINE_LED_TRIGGER(ledtrig_ide);
24static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0); 22static unsigned long ide_blink_delay = BLINK_DELAY;
25static int ide_activity;
26static int ide_lastactivity;
27 23
28void ledtrig_ide_activity(void) 24void ledtrig_ide_activity(void)
29{ 25{
30 ide_activity++; 26 led_trigger_blink_oneshot(ledtrig_ide,
31 if (!timer_pending(&ledtrig_ide_timer)) 27 &ide_blink_delay, &ide_blink_delay, 0);
32 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
33} 28}
34EXPORT_SYMBOL(ledtrig_ide_activity); 29EXPORT_SYMBOL(ledtrig_ide_activity);
35 30
36static void ledtrig_ide_timerfunc(unsigned long data)
37{
38 if (ide_lastactivity != ide_activity) {
39 ide_lastactivity = ide_activity;
40 /* INT_MAX will set each LED to its maximum brightness */
41 led_trigger_event(ledtrig_ide, INT_MAX);
42 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
43 } else {
44 led_trigger_event(ledtrig_ide, LED_OFF);
45 }
46}
47
48static int __init ledtrig_ide_init(void) 31static int __init ledtrig_ide_init(void)
49{ 32{
50 led_trigger_register_simple("ide-disk", &ledtrig_ide); 33 led_trigger_register_simple("ide-disk", &ledtrig_ide);
diff --git a/drivers/leds/ledtrig-oneshot.c b/drivers/leds/ledtrig-oneshot.c
new file mode 100644
index 000000000000..2c029aa5c4f1
--- /dev/null
+++ b/drivers/leds/ledtrig-oneshot.c
@@ -0,0 +1,204 @@
1/*
2 * One-shot LED Trigger
3 *
4 * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com>
5 *
6 * Based on ledtrig-timer.c by Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/ctype.h>
19#include <linux/slab.h>
20#include <linux/leds.h>
21#include "leds.h"
22
23#define DEFAULT_DELAY 100
24
25struct oneshot_trig_data {
26 unsigned int invert;
27};
28
29static ssize_t led_shot(struct device *dev,
30 struct device_attribute *attr, const char *buf, size_t size)
31{
32 struct led_classdev *led_cdev = dev_get_drvdata(dev);
33 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
34
35 led_blink_set_oneshot(led_cdev,
36 &led_cdev->blink_delay_on, &led_cdev->blink_delay_off,
37 oneshot_data->invert);
38
39 /* content is ignored */
40 return size;
41}
42static ssize_t led_invert_show(struct device *dev,
43 struct device_attribute *attr, char *buf)
44{
45 struct led_classdev *led_cdev = dev_get_drvdata(dev);
46 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
47
48 return sprintf(buf, "%u\n", oneshot_data->invert);
49}
50
51static ssize_t led_invert_store(struct device *dev,
52 struct device_attribute *attr, const char *buf, size_t size)
53{
54 struct led_classdev *led_cdev = dev_get_drvdata(dev);
55 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
56 unsigned long state;
57 int ret;
58
59 ret = kstrtoul(buf, 0, &state);
60 if (ret)
61 return ret;
62
63 oneshot_data->invert = !!state;
64
65 if (oneshot_data->invert)
66 __led_set_brightness(led_cdev, LED_FULL);
67 else
68 __led_set_brightness(led_cdev, LED_OFF);
69
70 return size;
71}
72
73static ssize_t led_delay_on_show(struct device *dev,
74 struct device_attribute *attr, char *buf)
75{
76 struct led_classdev *led_cdev = dev_get_drvdata(dev);
77
78 return sprintf(buf, "%lu\n", led_cdev->blink_delay_on);
79}
80
81static ssize_t led_delay_on_store(struct device *dev,
82 struct device_attribute *attr, const char *buf, size_t size)
83{
84 struct led_classdev *led_cdev = dev_get_drvdata(dev);
85 unsigned long state;
86 int ret;
87
88 ret = kstrtoul(buf, 0, &state);
89 if (ret)
90 return ret;
91
92 led_cdev->blink_delay_on = state;
93
94 return size;
95}
96static ssize_t led_delay_off_show(struct device *dev,
97 struct device_attribute *attr, char *buf)
98{
99 struct led_classdev *led_cdev = dev_get_drvdata(dev);
100
101 return sprintf(buf, "%lu\n", led_cdev->blink_delay_off);
102}
103
104static ssize_t led_delay_off_store(struct device *dev,
105 struct device_attribute *attr, const char *buf, size_t size)
106{
107 struct led_classdev *led_cdev = dev_get_drvdata(dev);
108 unsigned long state;
109 int ret;
110
111 ret = kstrtoul(buf, 0, &state);
112 if (ret)
113 return ret;
114
115 led_cdev->blink_delay_off = state;
116
117 return size;
118}
119
120static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
121static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
122static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store);
123static DEVICE_ATTR(shot, 0200, NULL, led_shot);
124
125static void oneshot_trig_activate(struct led_classdev *led_cdev)
126{
127 struct oneshot_trig_data *oneshot_data;
128 int rc;
129
130 oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL);
131 if (!oneshot_data)
132 return;
133
134 led_cdev->trigger_data = oneshot_data;
135
136 rc = device_create_file(led_cdev->dev, &dev_attr_delay_on);
137 if (rc)
138 goto err_out_trig_data;
139 rc = device_create_file(led_cdev->dev, &dev_attr_delay_off);
140 if (rc)
141 goto err_out_delayon;
142 rc = device_create_file(led_cdev->dev, &dev_attr_invert);
143 if (rc)
144 goto err_out_delayoff;
145 rc = device_create_file(led_cdev->dev, &dev_attr_shot);
146 if (rc)
147 goto err_out_invert;
148
149 led_cdev->blink_delay_on = DEFAULT_DELAY;
150 led_cdev->blink_delay_off = DEFAULT_DELAY;
151
152 led_cdev->activated = true;
153
154 return;
155
156err_out_invert:
157 device_remove_file(led_cdev->dev, &dev_attr_invert);
158err_out_delayoff:
159 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
160err_out_delayon:
161 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
162err_out_trig_data:
163 kfree(led_cdev->trigger_data);
164}
165
166static void oneshot_trig_deactivate(struct led_classdev *led_cdev)
167{
168 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
169
170 if (led_cdev->activated) {
171 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
172 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
173 device_remove_file(led_cdev->dev, &dev_attr_invert);
174 device_remove_file(led_cdev->dev, &dev_attr_shot);
175 kfree(oneshot_data);
176 led_cdev->activated = false;
177 }
178
179 /* Stop blinking */
180 led_set_brightness(led_cdev, LED_OFF);
181}
182
183static struct led_trigger oneshot_led_trigger = {
184 .name = "oneshot",
185 .activate = oneshot_trig_activate,
186 .deactivate = oneshot_trig_deactivate,
187};
188
189static int __init oneshot_trig_init(void)
190{
191 return led_trigger_register(&oneshot_led_trigger);
192}
193
194static void __exit oneshot_trig_exit(void)
195{
196 led_trigger_unregister(&oneshot_led_trigger);
197}
198
199module_init(oneshot_trig_init);
200module_exit(oneshot_trig_exit);
201
202MODULE_AUTHOR("Fabio Baltieri <fabio.baltieri@gmail.com>");
203MODULE_DESCRIPTION("One-shot LED trigger");
204MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 9010f7abaf2c..f774d0592204 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -104,7 +104,7 @@ static void timer_trig_deactivate(struct led_classdev *led_cdev)
104 } 104 }
105 105
106 /* Stop blinking */ 106 /* Stop blinking */
107 led_brightness_set(led_cdev, LED_OFF); 107 led_set_brightness(led_cdev, LED_OFF);
108} 108}
109 109
110static struct led_trigger timer_led_trigger = { 110static struct led_trigger timer_led_trigger = {
diff --git a/drivers/leds/ledtrig-transient.c b/drivers/leds/ledtrig-transient.c
index 83179f435e1e..398f1042c43e 100644
--- a/drivers/leds/ledtrig-transient.c
+++ b/drivers/leds/ledtrig-transient.c
@@ -41,7 +41,7 @@ static void transient_timer_function(unsigned long data)
41 struct transient_trig_data *transient_data = led_cdev->trigger_data; 41 struct transient_trig_data *transient_data = led_cdev->trigger_data;
42 42
43 transient_data->activate = 0; 43 transient_data->activate = 0;
44 led_set_brightness(led_cdev, transient_data->restore_state); 44 __led_set_brightness(led_cdev, transient_data->restore_state);
45} 45}
46 46
47static ssize_t transient_activate_show(struct device *dev, 47static ssize_t transient_activate_show(struct device *dev,
@@ -72,7 +72,7 @@ static ssize_t transient_activate_store(struct device *dev,
72 if (state == 0 && transient_data->activate == 1) { 72 if (state == 0 && transient_data->activate == 1) {
73 del_timer(&transient_data->timer); 73 del_timer(&transient_data->timer);
74 transient_data->activate = state; 74 transient_data->activate = state;
75 led_set_brightness(led_cdev, transient_data->restore_state); 75 __led_set_brightness(led_cdev, transient_data->restore_state);
76 return size; 76 return size;
77 } 77 }
78 78
@@ -80,7 +80,7 @@ static ssize_t transient_activate_store(struct device *dev,
80 if (state == 1 && transient_data->activate == 0 && 80 if (state == 1 && transient_data->activate == 0 &&
81 transient_data->duration != 0) { 81 transient_data->duration != 0) {
82 transient_data->activate = state; 82 transient_data->activate = state;
83 led_set_brightness(led_cdev, transient_data->state); 83 __led_set_brightness(led_cdev, transient_data->state);
84 transient_data->restore_state = 84 transient_data->restore_state =
85 (transient_data->state == LED_FULL) ? LED_OFF : LED_FULL; 85 (transient_data->state == LED_FULL) ? LED_OFF : LED_FULL;
86 mod_timer(&transient_data->timer, 86 mod_timer(&transient_data->timer,
@@ -203,7 +203,7 @@ static void transient_trig_deactivate(struct led_classdev *led_cdev)
203 203
204 if (led_cdev->activated) { 204 if (led_cdev->activated) {
205 del_timer_sync(&transient_data->timer); 205 del_timer_sync(&transient_data->timer);
206 led_set_brightness(led_cdev, transient_data->restore_state); 206 __led_set_brightness(led_cdev, transient_data->restore_state);
207 device_remove_file(led_cdev->dev, &dev_attr_activate); 207 device_remove_file(led_cdev->dev, &dev_attr_activate);
208 device_remove_file(led_cdev->dev, &dev_attr_duration); 208 device_remove_file(led_cdev->dev, &dev_attr_duration);
209 device_remove_file(led_cdev->dev, &dev_attr_state); 209 device_remove_file(led_cdev->dev, &dev_attr_state);
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 39eee41d8c6f..3aade1d8f410 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -38,6 +38,9 @@ struct led_classdev {
38#define LED_SUSPENDED (1 << 0) 38#define LED_SUSPENDED (1 << 0)
39 /* Upper 16 bits reflect control information */ 39 /* Upper 16 bits reflect control information */
40#define LED_CORE_SUSPENDRESUME (1 << 16) 40#define LED_CORE_SUSPENDRESUME (1 << 16)
41#define LED_BLINK_ONESHOT (1 << 17)
42#define LED_BLINK_ONESHOT_STOP (1 << 18)
43#define LED_BLINK_INVERT (1 << 19)
41 44
42 /* Set LED brightness level */ 45 /* Set LED brightness level */
43 /* Must not sleep, use a workqueue if needed */ 46 /* Must not sleep, use a workqueue if needed */
@@ -103,7 +106,25 @@ extern void led_blink_set(struct led_classdev *led_cdev,
103 unsigned long *delay_on, 106 unsigned long *delay_on,
104 unsigned long *delay_off); 107 unsigned long *delay_off);
105/** 108/**
106 * led_brightness_set - set LED brightness 109 * led_blink_set_oneshot - do a oneshot software blink
110 * @led_cdev: the LED to start blinking
111 * @delay_on: the time it should be on (in ms)
112 * @delay_off: the time it should ble off (in ms)
113 * @invert: blink off, then on, leaving the led on
114 *
115 * This function makes the LED blink one time for delay_on +
116 * delay_off time, ignoring the request if another one-shot
117 * blink is already in progress.
118 *
119 * If invert is set, led blinks for delay_off first, then for
120 * delay_on and leave the led on after the on-off cycle.
121 */
122extern void led_blink_set_oneshot(struct led_classdev *led_cdev,
123 unsigned long *delay_on,
124 unsigned long *delay_off,
125 int invert);
126/**
127 * led_set_brightness - set LED brightness
107 * @led_cdev: the LED to set 128 * @led_cdev: the LED to set
108 * @brightness: the brightness to set it to 129 * @brightness: the brightness to set it to
109 * 130 *
@@ -111,7 +132,7 @@ extern void led_blink_set(struct led_classdev *led_cdev,
111 * software blink timer that implements blinking when the 132 * software blink timer that implements blinking when the
112 * hardware doesn't. 133 * hardware doesn't.
113 */ 134 */
114extern void led_brightness_set(struct led_classdev *led_cdev, 135extern void led_set_brightness(struct led_classdev *led_cdev,
115 enum led_brightness brightness); 136 enum led_brightness brightness);
116 137
117/* 138/*
@@ -150,6 +171,10 @@ extern void led_trigger_event(struct led_trigger *trigger,
150extern void led_trigger_blink(struct led_trigger *trigger, 171extern void led_trigger_blink(struct led_trigger *trigger,
151 unsigned long *delay_on, 172 unsigned long *delay_on,
152 unsigned long *delay_off); 173 unsigned long *delay_off);
174extern void led_trigger_blink_oneshot(struct led_trigger *trigger,
175 unsigned long *delay_on,
176 unsigned long *delay_off,
177 int invert);
153 178
154#else 179#else
155 180
diff --git a/include/linux/platform_data/leds-lm3556.h b/include/linux/platform_data/leds-lm3556.h
new file mode 100644
index 000000000000..4b4e7d6b0527
--- /dev/null
+++ b/include/linux/platform_data/leds-lm3556.h
@@ -0,0 +1,50 @@
1/*
2 * Simple driver for Texas Instruments LM3556 LED Flash driver chip (Rev0x03)
3 * Copyright (C) 2012 Texas Instruments
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 */
10
11#ifndef __LINUX_LM3556_H
12#define __LINUX_LM3556_H
13
14#define LM3556_NAME "leds-lm3556"
15
16enum lm3556_pin_polarity {
17 PIN_LOW_ACTIVE = 0,
18 PIN_HIGH_ACTIVE,
19};
20
21enum lm3556_pin_enable {
22 PIN_DISABLED = 0,
23 PIN_ENABLED,
24};
25
26enum lm3556_strobe_usuage {
27 STROBE_EDGE_DETECT = 0,
28 STROBE_LEVEL_DETECT,
29};
30
31enum lm3556_indic_mode {
32 INDIC_MODE_INTERNAL = 0,
33 INDIC_MODE_EXTERNAL,
34};
35
36struct lm3556_platform_data {
37 enum lm3556_pin_enable torch_pin_en;
38 enum lm3556_pin_polarity torch_pin_polarity;
39
40 enum lm3556_strobe_usuage strobe_usuage;
41 enum lm3556_pin_enable strobe_pin_en;
42 enum lm3556_pin_polarity strobe_pin_polarity;
43
44 enum lm3556_pin_enable tx_pin_en;
45 enum lm3556_pin_polarity tx_pin_polarity;
46
47 enum lm3556_indic_mode indicator_mode;
48};
49
50#endif /* __LINUX_LM3556_H */
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 1bf7903496f8..bcffa6903129 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -276,7 +276,7 @@ static void ieee80211_stop_tpt_led_trig(struct ieee80211_local *local)
276 276
277 read_lock(&tpt_trig->trig.leddev_list_lock); 277 read_lock(&tpt_trig->trig.leddev_list_lock);
278 list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list) 278 list_for_each_entry(led_cdev, &tpt_trig->trig.led_cdevs, trig_list)
279 led_brightness_set(led_cdev, LED_OFF); 279 led_set_brightness(led_cdev, LED_OFF);
280 read_unlock(&tpt_trig->trig.leddev_list_lock); 280 read_unlock(&tpt_trig->trig.leddev_list_lock);
281} 281}
282 282