aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig28
-rw-r--r--drivers/leds/Makefile3
-rw-r--r--drivers/leds/led-class.c2
-rw-r--r--drivers/leds/leds-88pm860x.c11
-rw-r--r--drivers/leds/leds-bd2802.c6
-rw-r--r--drivers/leds/leds-gpio.c34
-rw-r--r--drivers/leds/leds-lp3944.c10
-rw-r--r--drivers/leds/leds-mc13783.c403
-rw-r--r--drivers/leds/leds-net5501.c94
-rw-r--r--drivers/leds/leds-ns2.c338
-rw-r--r--drivers/leds/leds-pca9532.c5
-rw-r--r--drivers/leds/leds-pca955x.c2
-rw-r--r--drivers/leds/leds-ss4200.c2
13 files changed, 909 insertions, 29 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 505eb64c329..e4112622e5a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -21,7 +21,7 @@ comment "LED drivers"
21 21
22config LEDS_88PM860X 22config LEDS_88PM860X
23 tristate "LED Support for Marvell 88PM860x PMIC" 23 tristate "LED Support for Marvell 88PM860x PMIC"
24 depends on LEDS_CLASS && MFD_88PM860X 24 depends on MFD_88PM860X
25 help 25 help
26 This option enables support for on-chip LED drivers found on Marvell 26 This option enables support for on-chip LED drivers found on Marvell
27 Semiconductor 88PM8606 PMIC. 27 Semiconductor 88PM8606 PMIC.
@@ -67,6 +67,16 @@ config LEDS_NET48XX
67 This option enables support for the Soekris net4801 and net4826 error 67 This option enables support for the Soekris net4801 and net4826 error
68 LED. 68 LED.
69 69
70config LEDS_NET5501
71 tristate "LED Support for Soekris net5501 series Error LED"
72 depends on LEDS_TRIGGERS
73 depends on X86 && LEDS_GPIO_PLATFORM && GPIO_CS5535
74 select LEDS_TRIGGER_DEFAULT_ON
75 default n
76 help
77 Add support for the Soekris net5501 board (detection, error led
78 and GPIO).
79
70config LEDS_FSG 80config LEDS_FSG
71 tristate "LED Support for the Freecom FSG-3" 81 tristate "LED Support for the Freecom FSG-3"
72 depends on MACH_FSG 82 depends on MACH_FSG
@@ -285,6 +295,22 @@ config LEDS_DELL_NETBOOKS
285 This adds support for the Latitude 2100 and similar 295 This adds support for the Latitude 2100 and similar
286 notebooks that have an external LED. 296 notebooks that have an external LED.
287 297
298config LEDS_MC13783
299 tristate "LED Support for MC13783 PMIC"
300 depends on MFD_MC13783
301 help
302 This option enable support for on-chip LED drivers found
303 on Freescale Semiconductor MC13783 PMIC.
304
305config LEDS_NS2
306 tristate "LED support for Network Space v2 GPIO LEDs"
307 depends on MACH_NETSPACE_V2 || MACH_INETSPACE_V2 || MACH_NETSPACE_MAX_V2
308 default y
309 help
310 This option enable support for the dual-GPIO LED found on the
311 Network Space v2 board (and parents). This include Internet Space v2,
312 Network Space (Max) v2 and d2 Network v2 boards.
313
288config LEDS_TRIGGERS 314config LEDS_TRIGGERS
289 bool "LED Trigger support" 315 bool "LED Trigger support"
290 help 316 help
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 0cd8b995738..7d6b95831f8 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o
13obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o 13obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
14obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o 14obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
15obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o 15obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
16obj-$(CONFIG_LEDS_NET5501) += leds-net5501.o
16obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o 17obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
17obj-$(CONFIG_LEDS_ALIX2) += leds-alix2.o 18obj-$(CONFIG_LEDS_ALIX2) += leds-alix2.o
18obj-$(CONFIG_LEDS_H1940) += leds-h1940.o 19obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
@@ -35,6 +36,8 @@ obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o
35obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o 36obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o
36obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o 37obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
37obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o 38obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o
39obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
40obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
38 41
39# LED SPI Drivers 42# LED SPI Drivers
40obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o 43obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 69e7d86a514..26066007650 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -74,7 +74,7 @@ static ssize_t led_max_brightness_show(struct device *dev,
74 74
75static struct device_attribute led_class_attrs[] = { 75static struct device_attribute led_class_attrs[] = {
76 __ATTR(brightness, 0644, led_brightness_show, led_brightness_store), 76 __ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
77 __ATTR(max_brightness, 0644, led_max_brightness_show, NULL), 77 __ATTR(max_brightness, 0444, led_max_brightness_show, NULL),
78#ifdef CONFIG_LEDS_TRIGGERS 78#ifdef CONFIG_LEDS_TRIGGERS
79 __ATTR(trigger, 0644, led_trigger_show, led_trigger_store), 79 __ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
80#endif 80#endif
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 16a60c06c96..b7677106cff 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -256,8 +256,10 @@ static int pm860x_led_probe(struct platform_device *pdev)
256 if (pdev->dev.parent->platform_data) { 256 if (pdev->dev.parent->platform_data) {
257 pm860x_pdata = pdev->dev.parent->platform_data; 257 pm860x_pdata = pdev->dev.parent->platform_data;
258 pdata = pm860x_pdata->led; 258 pdata = pm860x_pdata->led;
259 } else 259 } else {
260 pdata = NULL; 260 dev_err(&pdev->dev, "missing platform data\n");
261 return -EINVAL;
262 }
261 263
262 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); 264 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
263 if (data == NULL) 265 if (data == NULL)
@@ -268,8 +270,11 @@ static int pm860x_led_probe(struct platform_device *pdev)
268 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 270 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
269 data->iset = pdata->iset; 271 data->iset = pdata->iset;
270 data->port = __check_device(pdata, data->name); 272 data->port = __check_device(pdata, data->name);
271 if (data->port < 0) 273 if (data->port < 0) {
274 dev_err(&pdev->dev, "check device failed\n");
275 kfree(data);
272 return -EINVAL; 276 return -EINVAL;
277 }
273 278
274 data->current_brightness = 0; 279 data->current_brightness = 0;
275 data->cdev.name = data->name; 280 data->cdev.name = data->name;
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 286b501a357..19dc4b61a10 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -351,7 +351,7 @@ static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
351 return count; \ 351 return count; \
352} \ 352} \
353static struct device_attribute bd2802_reg##reg_addr##_attr = { \ 353static struct device_attribute bd2802_reg##reg_addr##_attr = { \
354 .attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE}, \ 354 .attr = {.name = reg_name, .mode = 0644}, \
355 .store = bd2802_store_reg##reg_addr, \ 355 .store = bd2802_store_reg##reg_addr, \
356}; 356};
357 357
@@ -482,7 +482,6 @@ static struct device_attribute bd2802_adv_conf_attr = {
482 .attr = { 482 .attr = {
483 .name = "advanced_configuration", 483 .name = "advanced_configuration",
484 .mode = 0644, 484 .mode = 0644,
485 .owner = THIS_MODULE
486 }, 485 },
487 .show = bd2802_show_adv_conf, 486 .show = bd2802_show_adv_conf,
488 .store = bd2802_store_adv_conf, 487 .store = bd2802_store_adv_conf,
@@ -519,7 +518,6 @@ static struct device_attribute bd2802_##attr_name##_attr = { \
519 .attr = { \ 518 .attr = { \
520 .name = name_str, \ 519 .name = name_str, \
521 .mode = 0644, \ 520 .mode = 0644, \
522 .owner = THIS_MODULE \
523 }, \ 521 }, \
524 .show = bd2802_show_##attr_name, \ 522 .show = bd2802_show_##attr_name, \
525 .store = bd2802_store_##attr_name, \ 523 .store = bd2802_store_##attr_name, \
@@ -742,7 +740,6 @@ failed_unregister_dev_file:
742 for (i--; i >= 0; i--) 740 for (i--; i >= 0; i--)
743 device_remove_file(&led->client->dev, bd2802_attributes[i]); 741 device_remove_file(&led->client->dev, bd2802_attributes[i]);
744failed_free: 742failed_free:
745 i2c_set_clientdata(client, NULL);
746 kfree(led); 743 kfree(led);
747 744
748 return ret; 745 return ret;
@@ -759,7 +756,6 @@ static int __exit bd2802_remove(struct i2c_client *client)
759 bd2802_disable_adv_conf(led); 756 bd2802_disable_adv_conf(led);
760 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) 757 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++)
761 device_remove_file(&led->client->dev, bd2802_attributes[i]); 758 device_remove_file(&led->client->dev, bd2802_attributes[i]);
762 i2c_set_clientdata(client, NULL);
763 kfree(led); 759 kfree(led);
764 760
765 return 0; 761 return 0;
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index c6e4b772b75..cc22eeefa10 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -26,7 +26,8 @@ struct gpio_led_data {
26 u8 new_level; 26 u8 new_level;
27 u8 can_sleep; 27 u8 can_sleep;
28 u8 active_low; 28 u8 active_low;
29 int (*platform_gpio_blink_set)(unsigned gpio, 29 u8 blinking;
30 int (*platform_gpio_blink_set)(unsigned gpio, int state,
30 unsigned long *delay_on, unsigned long *delay_off); 31 unsigned long *delay_on, unsigned long *delay_off);
31}; 32};
32 33
@@ -35,7 +36,13 @@ static void gpio_led_work(struct work_struct *work)
35 struct gpio_led_data *led_dat = 36 struct gpio_led_data *led_dat =
36 container_of(work, struct gpio_led_data, work); 37 container_of(work, struct gpio_led_data, work);
37 38
38 gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); 39 if (led_dat->blinking) {
40 led_dat->platform_gpio_blink_set(led_dat->gpio,
41 led_dat->new_level,
42 NULL, NULL);
43 led_dat->blinking = 0;
44 } else
45 gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
39} 46}
40 47
41static void gpio_led_set(struct led_classdev *led_cdev, 48static void gpio_led_set(struct led_classdev *led_cdev,
@@ -60,8 +67,14 @@ static void gpio_led_set(struct led_classdev *led_cdev,
60 if (led_dat->can_sleep) { 67 if (led_dat->can_sleep) {
61 led_dat->new_level = level; 68 led_dat->new_level = level;
62 schedule_work(&led_dat->work); 69 schedule_work(&led_dat->work);
63 } else 70 } else {
64 gpio_set_value(led_dat->gpio, level); 71 if (led_dat->blinking) {
72 led_dat->platform_gpio_blink_set(led_dat->gpio, level,
73 NULL, NULL);
74 led_dat->blinking = 0;
75 } else
76 gpio_set_value(led_dat->gpio, level);
77 }
65} 78}
66 79
67static int gpio_blink_set(struct led_classdev *led_cdev, 80static int gpio_blink_set(struct led_classdev *led_cdev,
@@ -70,12 +83,14 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
70 struct gpio_led_data *led_dat = 83 struct gpio_led_data *led_dat =
71 container_of(led_cdev, struct gpio_led_data, cdev); 84 container_of(led_cdev, struct gpio_led_data, cdev);
72 85
73 return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off); 86 led_dat->blinking = 1;
87 return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
88 delay_on, delay_off);
74} 89}
75 90
76static int __devinit create_gpio_led(const struct gpio_led *template, 91static int __devinit create_gpio_led(const struct gpio_led *template,
77 struct gpio_led_data *led_dat, struct device *parent, 92 struct gpio_led_data *led_dat, struct device *parent,
78 int (*blink_set)(unsigned, unsigned long *, unsigned long *)) 93 int (*blink_set)(unsigned, int, unsigned long *, unsigned long *))
79{ 94{
80 int ret, state; 95 int ret, state;
81 96
@@ -97,6 +112,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template,
97 led_dat->gpio = template->gpio; 112 led_dat->gpio = template->gpio;
98 led_dat->can_sleep = gpio_cansleep(template->gpio); 113 led_dat->can_sleep = gpio_cansleep(template->gpio);
99 led_dat->active_low = template->active_low; 114 led_dat->active_low = template->active_low;
115 led_dat->blinking = 0;
100 if (blink_set) { 116 if (blink_set) {
101 led_dat->platform_gpio_blink_set = blink_set; 117 led_dat->platform_gpio_blink_set = blink_set;
102 led_dat->cdev.blink_set = gpio_blink_set; 118 led_dat->cdev.blink_set = gpio_blink_set;
@@ -113,7 +129,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template,
113 ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); 129 ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
114 if (ret < 0) 130 if (ret < 0)
115 goto err; 131 goto err;
116 132
117 INIT_WORK(&led_dat->work, gpio_led_work); 133 INIT_WORK(&led_dat->work, gpio_led_work);
118 134
119 ret = led_classdev_register(parent, &led_dat->cdev); 135 ret = led_classdev_register(parent, &led_dat->cdev);
@@ -211,7 +227,7 @@ struct gpio_led_of_platform_data {
211static int __devinit of_gpio_leds_probe(struct of_device *ofdev, 227static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
212 const struct of_device_id *match) 228 const struct of_device_id *match)
213{ 229{
214 struct device_node *np = ofdev->node, *child; 230 struct device_node *np = ofdev->dev.of_node, *child;
215 struct gpio_led_of_platform_data *pdata; 231 struct gpio_led_of_platform_data *pdata;
216 int count = 0, ret; 232 int count = 0, ret;
217 233
@@ -291,8 +307,8 @@ static struct of_platform_driver of_gpio_leds_driver = {
291 .driver = { 307 .driver = {
292 .name = "of_gpio_leds", 308 .name = "of_gpio_leds",
293 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
310 .of_match_table = of_gpio_leds_match,
294 }, 311 },
295 .match_table = of_gpio_leds_match,
296 .probe = of_gpio_leds_probe, 312 .probe = of_gpio_leds_probe,
297 .remove = __devexit_p(of_gpio_leds_remove), 313 .remove = __devexit_p(of_gpio_leds_remove),
298}; 314};
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c
index 8d5ecceba18..9010c054615 100644
--- a/drivers/leds/leds-lp3944.c
+++ b/drivers/leds/leds-lp3944.c
@@ -379,6 +379,7 @@ static int __devinit lp3944_probe(struct i2c_client *client,
379{ 379{
380 struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; 380 struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data;
381 struct lp3944_data *data; 381 struct lp3944_data *data;
382 int err;
382 383
383 if (lp3944_pdata == NULL) { 384 if (lp3944_pdata == NULL) {
384 dev_err(&client->dev, "no platform data\n"); 385 dev_err(&client->dev, "no platform data\n");
@@ -401,9 +402,13 @@ static int __devinit lp3944_probe(struct i2c_client *client,
401 402
402 mutex_init(&data->lock); 403 mutex_init(&data->lock);
403 404
404 dev_info(&client->dev, "lp3944 enabled\n"); 405 err = lp3944_configure(client, data, lp3944_pdata);
406 if (err < 0) {
407 kfree(data);
408 return err;
409 }
405 410
406 lp3944_configure(client, data, lp3944_pdata); 411 dev_info(&client->dev, "lp3944 enabled\n");
407 return 0; 412 return 0;
408} 413}
409 414
@@ -427,7 +432,6 @@ static int __devexit lp3944_remove(struct i2c_client *client)
427 } 432 }
428 433
429 kfree(data); 434 kfree(data);
430 i2c_set_clientdata(client, NULL);
431 435
432 return 0; 436 return 0;
433} 437}
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
new file mode 100644
index 00000000000..f05bb08d0f0
--- /dev/null
+++ b/drivers/leds/leds-mc13783.c
@@ -0,0 +1,403 @@
1/*
2 * LEDs driver for Freescale MC13783
3 *
4 * Copyright (C) 2010 Philippe Rétornaz
5 *
6 * Based on leds-da903x:
7 * Copyright (C) 2008 Compulab, Ltd.
8 * Mike Rapoport <mike@compulab.co.il>
9 *
10 * Copyright (C) 2006-2008 Marvell International Ltd.
11 * Eric Miao <eric.miao@marvell.com>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/leds.h>
23#include <linux/workqueue.h>
24#include <linux/mfd/mc13783.h>
25#include <linux/slab.h>
26
27struct mc13783_led {
28 struct led_classdev cdev;
29 struct work_struct work;
30 struct mc13783 *master;
31 enum led_brightness new_brightness;
32 int id;
33};
34
35#define MC13783_REG_LED_CONTROL_0 51
36#define MC13783_LED_C0_ENABLE_BIT (1 << 0)
37#define MC13783_LED_C0_TRIODE_MD_BIT (1 << 7)
38#define MC13783_LED_C0_TRIODE_AD_BIT (1 << 8)
39#define MC13783_LED_C0_TRIODE_KP_BIT (1 << 9)
40#define MC13783_LED_C0_BOOST_BIT (1 << 10)
41#define MC13783_LED_C0_ABMODE_MASK 0x7
42#define MC13783_LED_C0_ABMODE 11
43#define MC13783_LED_C0_ABREF_MASK 0x3
44#define MC13783_LED_C0_ABREF 14
45
46#define MC13783_REG_LED_CONTROL_1 52
47#define MC13783_LED_C1_TC1HALF_BIT (1 << 18)
48
49#define MC13783_REG_LED_CONTROL_2 53
50#define MC13783_LED_C2_BL_P_MASK 0xf
51#define MC13783_LED_C2_MD_P 9
52#define MC13783_LED_C2_AD_P 13
53#define MC13783_LED_C2_KP_P 17
54#define MC13783_LED_C2_BL_C_MASK 0x7
55#define MC13783_LED_C2_MD_C 0
56#define MC13783_LED_C2_AD_C 3
57#define MC13783_LED_C2_KP_C 6
58
59#define MC13783_REG_LED_CONTROL_3 54
60#define MC13783_LED_C3_TC_P 6
61#define MC13783_LED_C3_TC_P_MASK 0x1f
62
63#define MC13783_REG_LED_CONTROL_4 55
64#define MC13783_REG_LED_CONTROL_5 56
65
66#define MC13783_LED_Cx_PERIOD 21
67#define MC13783_LED_Cx_PERIOD_MASK 0x3
68#define MC13783_LED_Cx_SLEWLIM_BIT (1 << 23)
69#define MC13783_LED_Cx_TRIODE_TC_BIT (1 << 23)
70#define MC13783_LED_Cx_TC_C_MASK 0x3
71
72static void mc13783_led_work(struct work_struct *work)
73{
74 struct mc13783_led *led = container_of(work, struct mc13783_led, work);
75 int reg = 0;
76 int mask = 0;
77 int value = 0;
78 int bank, off, shift;
79
80 switch (led->id) {
81 case MC13783_LED_MD:
82 reg = MC13783_REG_LED_CONTROL_2;
83 mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_MD_P;
84 value = (led->new_brightness >> 4) << MC13783_LED_C2_MD_P;
85 break;
86 case MC13783_LED_AD:
87 reg = MC13783_REG_LED_CONTROL_2;
88 mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_AD_P;
89 value = (led->new_brightness >> 4) << MC13783_LED_C2_AD_P;
90 break;
91 case MC13783_LED_KP:
92 reg = MC13783_REG_LED_CONTROL_2;
93 mask = MC13783_LED_C2_BL_P_MASK << MC13783_LED_C2_KP_P;
94 value = (led->new_brightness >> 4) << MC13783_LED_C2_KP_P;
95 break;
96 case MC13783_LED_R1:
97 case MC13783_LED_G1:
98 case MC13783_LED_B1:
99 case MC13783_LED_R2:
100 case MC13783_LED_G2:
101 case MC13783_LED_B2:
102 case MC13783_LED_R3:
103 case MC13783_LED_G3:
104 case MC13783_LED_B3:
105 off = led->id - MC13783_LED_R1;
106 bank = off/3;
107 reg = MC13783_REG_LED_CONTROL_3 + off/3;
108 shift = (off - bank * 3) * 5 + MC13783_LED_C3_TC_P;
109 value = (led->new_brightness >> 3) << shift;
110 mask = MC13783_LED_C3_TC_P_MASK << shift;
111 break;
112 }
113
114 mc13783_lock(led->master);
115
116 mc13783_reg_rmw(led->master, reg, mask, value);
117
118 mc13783_unlock(led->master);
119}
120
121static void mc13783_led_set(struct led_classdev *led_cdev,
122 enum led_brightness value)
123{
124 struct mc13783_led *led;
125
126 led = container_of(led_cdev, struct mc13783_led, cdev);
127 led->new_brightness = value;
128 schedule_work(&led->work);
129}
130
131static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
132{
133 int shift = 0;
134 int mask = 0;
135 int value = 0;
136 int reg = 0;
137 int ret, bank;
138
139 switch (led->id) {
140 case MC13783_LED_MD:
141 shift = MC13783_LED_C2_MD_C;
142 mask = MC13783_LED_C2_BL_C_MASK;
143 value = max_current & MC13783_LED_C2_BL_C_MASK;
144 reg = MC13783_REG_LED_CONTROL_2;
145 break;
146 case MC13783_LED_AD:
147 shift = MC13783_LED_C2_AD_C;
148 mask = MC13783_LED_C2_BL_C_MASK;
149 value = max_current & MC13783_LED_C2_BL_C_MASK;
150 reg = MC13783_REG_LED_CONTROL_2;
151 break;
152 case MC13783_LED_KP:
153 shift = MC13783_LED_C2_KP_C;
154 mask = MC13783_LED_C2_BL_C_MASK;
155 value = max_current & MC13783_LED_C2_BL_C_MASK;
156 reg = MC13783_REG_LED_CONTROL_2;
157 break;
158 case MC13783_LED_R1:
159 case MC13783_LED_G1:
160 case MC13783_LED_B1:
161 case MC13783_LED_R2:
162 case MC13783_LED_G2:
163 case MC13783_LED_B2:
164 case MC13783_LED_R3:
165 case MC13783_LED_G3:
166 case MC13783_LED_B3:
167 bank = (led->id - MC13783_LED_R1)/3;
168 reg = MC13783_REG_LED_CONTROL_3 + bank;
169 shift = ((led->id - MC13783_LED_R1) - bank * 3) * 2;
170 mask = MC13783_LED_Cx_TC_C_MASK;
171 value = max_current & MC13783_LED_Cx_TC_C_MASK;
172 break;
173 }
174
175 mc13783_lock(led->master);
176
177 ret = mc13783_reg_rmw(led->master, reg, mask << shift,
178 value << shift);
179
180 mc13783_unlock(led->master);
181 return ret;
182}
183
184static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
185{
186 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
187 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
188 int ret = 0;
189 int reg = 0;
190
191 mc13783_lock(dev);
192
193 if (pdata->flags & MC13783_LED_TC1HALF)
194 reg |= MC13783_LED_C1_TC1HALF_BIT;
195
196 if (pdata->flags & MC13783_LED_SLEWLIMTC)
197 reg |= MC13783_LED_Cx_SLEWLIM_BIT;
198
199 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, reg);
200 if (ret)
201 goto out;
202
203 reg = (pdata->bl_period & MC13783_LED_Cx_PERIOD_MASK) <<
204 MC13783_LED_Cx_PERIOD;
205
206 if (pdata->flags & MC13783_LED_SLEWLIMBL)
207 reg |= MC13783_LED_Cx_SLEWLIM_BIT;
208
209 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, reg);
210 if (ret)
211 goto out;
212
213 reg = (pdata->tc1_period & MC13783_LED_Cx_PERIOD_MASK) <<
214 MC13783_LED_Cx_PERIOD;
215
216 if (pdata->flags & MC13783_LED_TRIODE_TC1)
217 reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
218
219 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, reg);
220 if (ret)
221 goto out;
222
223 reg = (pdata->tc2_period & MC13783_LED_Cx_PERIOD_MASK) <<
224 MC13783_LED_Cx_PERIOD;
225
226 if (pdata->flags & MC13783_LED_TRIODE_TC2)
227 reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
228
229 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, reg);
230 if (ret)
231 goto out;
232
233 reg = (pdata->tc3_period & MC13783_LED_Cx_PERIOD_MASK) <<
234 MC13783_LED_Cx_PERIOD;
235
236 if (pdata->flags & MC13783_LED_TRIODE_TC3)
237 reg |= MC13783_LED_Cx_TRIODE_TC_BIT;;
238
239 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg);
240 if (ret)
241 goto out;
242
243 reg = MC13783_LED_C0_ENABLE_BIT;
244 if (pdata->flags & MC13783_LED_TRIODE_MD)
245 reg |= MC13783_LED_C0_TRIODE_MD_BIT;
246 if (pdata->flags & MC13783_LED_TRIODE_AD)
247 reg |= MC13783_LED_C0_TRIODE_AD_BIT;
248 if (pdata->flags & MC13783_LED_TRIODE_KP)
249 reg |= MC13783_LED_C0_TRIODE_KP_BIT;
250 if (pdata->flags & MC13783_LED_BOOST_EN)
251 reg |= MC13783_LED_C0_BOOST_BIT;
252
253 reg |= (pdata->abmode & MC13783_LED_C0_ABMODE_MASK) <<
254 MC13783_LED_C0_ABMODE;
255 reg |= (pdata->abref & MC13783_LED_C0_ABREF_MASK) <<
256 MC13783_LED_C0_ABREF;
257
258 ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, reg);
259
260out:
261 mc13783_unlock(dev);
262 return ret;
263}
264
265static int __devinit mc13783_led_probe(struct platform_device *pdev)
266{
267 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
268 struct mc13783_led_platform_data *led_cur;
269 struct mc13783_led *led, *led_dat;
270 int ret, i;
271 int init_led = 0;
272
273 if (pdata == NULL) {
274 dev_err(&pdev->dev, "missing platform data\n");
275 return -ENODEV;
276 }
277
278 if (pdata->num_leds < 1 || pdata->num_leds > MC13783_LED_MAX) {
279 dev_err(&pdev->dev, "Invalid led count %d\n", pdata->num_leds);
280 return -EINVAL;
281 }
282
283 led = kzalloc(sizeof(*led) * pdata->num_leds, GFP_KERNEL);
284 if (led == NULL) {
285 dev_err(&pdev->dev, "failed to alloc memory\n");
286 return -ENOMEM;
287 }
288
289 ret = mc13783_leds_prepare(pdev);
290 if (ret) {
291 dev_err(&pdev->dev, "unable to init led driver\n");
292 goto err_free;
293 }
294
295 for (i = 0; i < pdata->num_leds; i++) {
296 led_dat = &led[i];
297 led_cur = &pdata->led[i];
298
299 if (led_cur->id > MC13783_LED_MAX || led_cur->id < 0) {
300 dev_err(&pdev->dev, "invalid id %d\n", led_cur->id);
301 ret = -EINVAL;
302 goto err_register;
303 }
304
305 if (init_led & (1 << led_cur->id)) {
306 dev_err(&pdev->dev, "led %d already initialized\n",
307 led_cur->id);
308 ret = -EINVAL;
309 goto err_register;
310 }
311
312 init_led |= 1 << led_cur->id;
313 led_dat->cdev.name = led_cur->name;
314 led_dat->cdev.default_trigger = led_cur->default_trigger;
315 led_dat->cdev.brightness_set = mc13783_led_set;
316 led_dat->cdev.brightness = LED_OFF;
317 led_dat->id = led_cur->id;
318 led_dat->master = dev_get_drvdata(pdev->dev.parent);
319
320 INIT_WORK(&led_dat->work, mc13783_led_work);
321
322 ret = led_classdev_register(pdev->dev.parent, &led_dat->cdev);
323 if (ret) {
324 dev_err(&pdev->dev, "failed to register led %d\n",
325 led_dat->id);
326 goto err_register;
327 }
328
329 ret = mc13783_led_setup(led_dat, led_cur->max_current);
330 if (ret) {
331 dev_err(&pdev->dev, "unable to init led %d\n",
332 led_dat->id);
333 i++;
334 goto err_register;
335 }
336 }
337
338 platform_set_drvdata(pdev, led);
339 return 0;
340
341err_register:
342 for (i = i - 1; i >= 0; i--) {
343 led_classdev_unregister(&led[i].cdev);
344 cancel_work_sync(&led[i].work);
345 }
346
347err_free:
348 kfree(led);
349 return ret;
350}
351
352static int __devexit mc13783_led_remove(struct platform_device *pdev)
353{
354 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
355 struct mc13783_led *led = platform_get_drvdata(pdev);
356 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
357 int i;
358
359 for (i = 0; i < pdata->num_leds; i++) {
360 led_classdev_unregister(&led[i].cdev);
361 cancel_work_sync(&led[i].work);
362 }
363
364 mc13783_lock(dev);
365
366 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_0, 0);
367 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_1, 0);
368 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_2, 0);
369 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_3, 0);
370 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_4, 0);
371 mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, 0);
372
373 mc13783_unlock(dev);
374
375 kfree(led);
376 return 0;
377}
378
379static struct platform_driver mc13783_led_driver = {
380 .driver = {
381 .name = "mc13783-led",
382 .owner = THIS_MODULE,
383 },
384 .probe = mc13783_led_probe,
385 .remove = __devexit_p(mc13783_led_remove),
386};
387
388static int __init mc13783_led_init(void)
389{
390 return platform_driver_register(&mc13783_led_driver);
391}
392module_init(mc13783_led_init);
393
394static void __exit mc13783_led_exit(void)
395{
396 platform_driver_unregister(&mc13783_led_driver);
397}
398module_exit(mc13783_led_exit);
399
400MODULE_DESCRIPTION("LEDs driver for Freescale MC13783 PMIC");
401MODULE_AUTHOR("Philippe Retornaz <philippe.retornaz@epfl.ch>");
402MODULE_LICENSE("GPL");
403MODULE_ALIAS("platform:mc13783-led");
diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c
new file mode 100644
index 00000000000..3063f591f0d
--- /dev/null
+++ b/drivers/leds/leds-net5501.c
@@ -0,0 +1,94 @@
1/*
2 * Soekris board support code
3 *
4 * Copyright (C) 2008-2009 Tower Technologies
5 * Written by Alessandro Zummo <a.zummo@towertech.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/io.h>
15#include <linux/string.h>
16#include <linux/leds.h>
17#include <linux/platform_device.h>
18#include <linux/gpio.h>
19
20#include <asm/geode.h>
21
22static struct gpio_led net5501_leds[] = {
23 {
24 .name = "error",
25 .gpio = 6,
26 .default_trigger = "default-on",
27 },
28};
29
30static struct gpio_led_platform_data net5501_leds_data = {
31 .num_leds = ARRAY_SIZE(net5501_leds),
32 .leds = net5501_leds,
33};
34
35static struct platform_device net5501_leds_dev = {
36 .name = "leds-gpio",
37 .id = -1,
38 .dev.platform_data = &net5501_leds_data,
39};
40
41static void __init init_net5501(void)
42{
43 platform_device_register(&net5501_leds_dev);
44}
45
46struct soekris_board {
47 u16 offset;
48 char *sig;
49 u8 len;
50 void (*init)(void);
51};
52
53static struct soekris_board __initdata boards[] = {
54 { 0xb7b, "net5501", 7, init_net5501 }, /* net5501 v1.33/1.33c */
55 { 0xb1f, "net5501", 7, init_net5501 }, /* net5501 v1.32i */
56};
57
58static int __init soekris_init(void)
59{
60 int i;
61 unsigned char *rombase, *bios;
62
63 if (!is_geode())
64 return 0;
65
66 rombase = ioremap(0xffff0000, 0xffff);
67 if (!rombase) {
68 printk(KERN_INFO "Soekris net5501 LED driver failed to get rombase");
69 return 0;
70 }
71
72 bios = rombase + 0x20; /* null terminated */
73
74 if (strncmp(bios, "comBIOS", 7))
75 goto unmap;
76
77 for (i = 0; i < ARRAY_SIZE(boards); i++) {
78 unsigned char *model = rombase + boards[i].offset;
79
80 if (strncmp(model, boards[i].sig, boards[i].len) == 0) {
81 printk(KERN_INFO "Soekris %s: %s\n", model, bios);
82
83 if (boards[i].init)
84 boards[i].init();
85 break;
86 }
87 }
88
89unmap:
90 iounmap(rombase);
91 return 0;
92}
93
94arch_initcall(soekris_init);
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
new file mode 100644
index 00000000000..74dce4ba026
--- /dev/null
+++ b/drivers/leds/leds-ns2.c
@@ -0,0 +1,338 @@
1/*
2 * leds-ns2.c - Driver for the Network Space v2 (and parents) dual-GPIO LED
3 *
4 * Copyright (C) 2010 LaCie
5 *
6 * Author: Simon Guinot <sguinot@lacie.com>
7 *
8 * Based on leds-gpio.c by Raphael Assenat <raph@8d.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/platform_device.h>
28#include <linux/slab.h>
29#include <linux/gpio.h>
30#include <linux/leds.h>
31#include <mach/leds-ns2.h>
32
33/*
34 * The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in
35 * relation with the SATA activity. This capability is exposed through the
36 * "sata" sysfs attribute.
37 *
38 * The following array detail the different LED registers and the combination
39 * of their possible values:
40 *
41 * cmd_led | slow_led | /SATA active | LED state
42 * | | |
43 * 1 | 0 | x | off
44 * - | 1 | x | on
45 * 0 | 0 | 1 | on
46 * 0 | 0 | 0 | blink (rate 300ms)
47 */
48
49enum ns2_led_modes {
50 NS_V2_LED_OFF,
51 NS_V2_LED_ON,
52 NS_V2_LED_SATA,
53};
54
55struct ns2_led_mode_value {
56 enum ns2_led_modes mode;
57 int cmd_level;
58 int slow_level;
59};
60
61static struct ns2_led_mode_value ns2_led_modval[] = {
62 { NS_V2_LED_OFF , 1, 0 },
63 { NS_V2_LED_ON , 0, 1 },
64 { NS_V2_LED_ON , 1, 1 },
65 { NS_V2_LED_SATA, 0, 0 },
66};
67
68struct ns2_led_data {
69 struct led_classdev cdev;
70 unsigned cmd;
71 unsigned slow;
72 unsigned char sata; /* True when SATA mode active. */
73 rwlock_t rw_lock; /* Lock GPIOs. */
74};
75
76static int ns2_led_get_mode(struct ns2_led_data *led_dat,
77 enum ns2_led_modes *mode)
78{
79 int i;
80 int ret = -EINVAL;
81 int cmd_level;
82 int slow_level;
83
84 read_lock(&led_dat->rw_lock);
85
86 cmd_level = gpio_get_value(led_dat->cmd);
87 slow_level = gpio_get_value(led_dat->slow);
88
89 for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
90 if (cmd_level == ns2_led_modval[i].cmd_level &&
91 slow_level == ns2_led_modval[i].slow_level) {
92 *mode = ns2_led_modval[i].mode;
93 ret = 0;
94 break;
95 }
96 }
97
98 read_unlock(&led_dat->rw_lock);
99
100 return ret;
101}
102
103static void ns2_led_set_mode(struct ns2_led_data *led_dat,
104 enum ns2_led_modes mode)
105{
106 int i;
107
108 write_lock(&led_dat->rw_lock);
109
110 for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
111 if (mode == ns2_led_modval[i].mode) {
112 gpio_set_value(led_dat->cmd,
113 ns2_led_modval[i].cmd_level);
114 gpio_set_value(led_dat->slow,
115 ns2_led_modval[i].slow_level);
116 }
117 }
118
119 write_unlock(&led_dat->rw_lock);
120}
121
122static void ns2_led_set(struct led_classdev *led_cdev,
123 enum led_brightness value)
124{
125 struct ns2_led_data *led_dat =
126 container_of(led_cdev, struct ns2_led_data, cdev);
127 enum ns2_led_modes mode;
128
129 if (value == LED_OFF)
130 mode = NS_V2_LED_OFF;
131 else if (led_dat->sata)
132 mode = NS_V2_LED_SATA;
133 else
134 mode = NS_V2_LED_ON;
135
136 ns2_led_set_mode(led_dat, mode);
137}
138
139static ssize_t ns2_led_sata_store(struct device *dev,
140 struct device_attribute *attr,
141 const char *buff, size_t count)
142{
143 int ret;
144 unsigned long enable;
145 enum ns2_led_modes mode;
146 struct ns2_led_data *led_dat = dev_get_drvdata(dev);
147
148 ret = strict_strtoul(buff, 10, &enable);
149 if (ret < 0)
150 return ret;
151
152 enable = !!enable;
153
154 if (led_dat->sata == enable)
155 return count;
156
157 ret = ns2_led_get_mode(led_dat, &mode);
158 if (ret < 0)
159 return ret;
160
161 if (enable && mode == NS_V2_LED_ON)
162 ns2_led_set_mode(led_dat, NS_V2_LED_SATA);
163 if (!enable && mode == NS_V2_LED_SATA)
164 ns2_led_set_mode(led_dat, NS_V2_LED_ON);
165
166 led_dat->sata = enable;
167
168 return count;
169}
170
171static ssize_t ns2_led_sata_show(struct device *dev,
172 struct device_attribute *attr, char *buf)
173{
174 struct ns2_led_data *led_dat = dev_get_drvdata(dev);
175
176 return sprintf(buf, "%d\n", led_dat->sata);
177}
178
179static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store);
180
181static int __devinit
182create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
183 const struct ns2_led *template)
184{
185 int ret;
186 enum ns2_led_modes mode;
187
188 ret = gpio_request(template->cmd, template->name);
189 if (ret == 0) {
190 ret = gpio_direction_output(template->cmd,
191 gpio_get_value(template->cmd));
192 if (ret)
193 gpio_free(template->cmd);
194 }
195 if (ret) {
196 dev_err(&pdev->dev, "%s: failed to setup command GPIO\n",
197 template->name);
198 }
199
200 ret = gpio_request(template->slow, template->name);
201 if (ret == 0) {
202 ret = gpio_direction_output(template->slow,
203 gpio_get_value(template->slow));
204 if (ret)
205 gpio_free(template->slow);
206 }
207 if (ret) {
208 dev_err(&pdev->dev, "%s: failed to setup slow GPIO\n",
209 template->name);
210 goto err_free_cmd;
211 }
212
213 rwlock_init(&led_dat->rw_lock);
214
215 led_dat->cdev.name = template->name;
216 led_dat->cdev.default_trigger = template->default_trigger;
217 led_dat->cdev.blink_set = NULL;
218 led_dat->cdev.brightness_set = ns2_led_set;
219 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
220 led_dat->cmd = template->cmd;
221 led_dat->slow = template->slow;
222
223 ret = ns2_led_get_mode(led_dat, &mode);
224 if (ret < 0)
225 goto err_free_slow;
226
227 /* Set LED initial state. */
228 led_dat->sata = (mode == NS_V2_LED_SATA) ? 1 : 0;
229 led_dat->cdev.brightness =
230 (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL;
231
232 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
233 if (ret < 0)
234 goto err_free_slow;
235
236 dev_set_drvdata(led_dat->cdev.dev, led_dat);
237 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
238 if (ret < 0)
239 goto err_free_cdev;
240
241 return 0;
242
243err_free_cdev:
244 led_classdev_unregister(&led_dat->cdev);
245err_free_slow:
246 gpio_free(led_dat->slow);
247err_free_cmd:
248 gpio_free(led_dat->cmd);
249
250 return ret;
251}
252
253static void __devexit delete_ns2_led(struct ns2_led_data *led_dat)
254{
255 device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
256 led_classdev_unregister(&led_dat->cdev);
257 gpio_free(led_dat->cmd);
258 gpio_free(led_dat->slow);
259}
260
261static int __devinit ns2_led_probe(struct platform_device *pdev)
262{
263 struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
264 struct ns2_led_data *leds_data;
265 int i;
266 int ret;
267
268 if (!pdata)
269 return -EINVAL;
270
271 leds_data = kzalloc(sizeof(struct ns2_led_data) *
272 pdata->num_leds, GFP_KERNEL);
273 if (!leds_data)
274 return -ENOMEM;
275
276 for (i = 0; i < pdata->num_leds; i++) {
277 ret = create_ns2_led(pdev, &leds_data[i], &pdata->leds[i]);
278 if (ret < 0)
279 goto err;
280
281 }
282
283 platform_set_drvdata(pdev, leds_data);
284
285 return 0;
286
287err:
288 for (i = i - 1; i >= 0; i--)
289 delete_ns2_led(&leds_data[i]);
290
291 kfree(leds_data);
292
293 return ret;
294}
295
296static int __devexit ns2_led_remove(struct platform_device *pdev)
297{
298 int i;
299 struct ns2_led_platform_data *pdata = pdev->dev.platform_data;
300 struct ns2_led_data *leds_data;
301
302 leds_data = platform_get_drvdata(pdev);
303
304 for (i = 0; i < pdata->num_leds; i++)
305 delete_ns2_led(&leds_data[i]);
306
307 kfree(leds_data);
308 platform_set_drvdata(pdev, NULL);
309
310 return 0;
311}
312
313static struct platform_driver ns2_led_driver = {
314 .probe = ns2_led_probe,
315 .remove = __devexit_p(ns2_led_remove),
316 .driver = {
317 .name = "leds-ns2",
318 .owner = THIS_MODULE,
319 },
320};
321MODULE_ALIAS("platform:leds-ns2");
322
323static int __init ns2_led_init(void)
324{
325 return platform_driver_register(&ns2_led_driver);
326}
327
328static void __exit ns2_led_exit(void)
329{
330 platform_driver_unregister(&ns2_led_driver);
331}
332
333module_init(ns2_led_init);
334module_exit(ns2_led_exit);
335
336MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
337MODULE_DESCRIPTION("Network Space v2 LED driver");
338MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 6682175fa9f..43d08756d82 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -320,10 +320,8 @@ static int pca9532_probe(struct i2c_client *client,
320 mutex_init(&data->update_lock); 320 mutex_init(&data->update_lock);
321 321
322 err = pca9532_configure(client, data, pca9532_pdata); 322 err = pca9532_configure(client, data, pca9532_pdata);
323 if (err) { 323 if (err)
324 kfree(data); 324 kfree(data);
325 i2c_set_clientdata(client, NULL);
326 }
327 325
328 return err; 326 return err;
329} 327}
@@ -351,7 +349,6 @@ static int pca9532_remove(struct i2c_client *client)
351 } 349 }
352 350
353 kfree(data); 351 kfree(data);
354 i2c_set_clientdata(client, NULL);
355 return 0; 352 return 0;
356} 353}
357 354
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index 8ff50f23419..66aa3e8e786 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -342,7 +342,6 @@ exit:
342 } 342 }
343 343
344 kfree(pca955x); 344 kfree(pca955x);
345 i2c_set_clientdata(client, NULL);
346 345
347 return err; 346 return err;
348} 347}
@@ -358,7 +357,6 @@ static int __devexit pca955x_remove(struct i2c_client *client)
358 } 357 }
359 358
360 kfree(pca955x); 359 kfree(pca955x);
361 i2c_set_clientdata(client, NULL);
362 360
363 return 0; 361 return 0;
364} 362}
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index 51477ec7139..a688293abd0 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -534,7 +534,7 @@ static int __init nas_gpio_init(void)
534 set_power_light_amber_noblink(); 534 set_power_light_amber_noblink();
535 return 0; 535 return 0;
536out_err: 536out_err:
537 for (; i >= 0; i--) 537 for (i--; i >= 0; i--)
538 unregister_nasgpio_led(i); 538 unregister_nasgpio_led(i);
539 pci_unregister_driver(&nas_gpio_pci_driver); 539 pci_unregister_driver(&nas_gpio_pci_driver);
540 return ret; 540 return ret;