aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig7
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/led-class.c19
-rw-r--r--drivers/leds/led-core.c11
-rw-r--r--drivers/leds/leds-ipaq-micro.c141
-rw-r--r--drivers/leds/leds-lm3530.c20
-rw-r--r--drivers/leds/leds-lm3533.c20
-rw-r--r--drivers/leds/leds-lm355x.c21
-rw-r--r--drivers/leds/leds-lm3642.c30
-rw-r--r--drivers/leds/leds-lp55xx-common.c20
-rw-r--r--drivers/leds/leds-max8997.c16
-rw-r--r--drivers/leds/leds-netxbig.c31
-rw-r--r--drivers/leds/leds-ns2.c16
-rw-r--r--drivers/leds/leds-pca963x.c28
-rw-r--r--drivers/leds/leds-ss4200.c14
-rw-r--r--drivers/leds/leds-wm831x-status.c23
16 files changed, 271 insertions, 147 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index a1b044e7eaad..30e82860567a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -143,6 +143,13 @@ config LEDS_SUNFIRE
143 This option enables support for the Left, Middle, and Right 143 This option enables support for the Left, Middle, and Right
144 LEDs on the I/O and CPU boards of SunFire UltraSPARC servers. 144 LEDs on the I/O and CPU boards of SunFire UltraSPARC servers.
145 145
146config LEDS_IPAQ_MICRO
147 tristate "LED Support for the Compaq iPAQ h3xxx"
148 depends on MFD_IPAQ_MICRO
149 help
150 Choose this option if you want to use the notification LED on
151 Compaq/HP iPAQ h3100 and h3600.
152
146config LEDS_HP6XX 153config LEDS_HP6XX
147 tristate "LED Support for the HP Jornada 6xx" 154 tristate "LED Support for the HP Jornada 6xx"
148 depends on LEDS_CLASS 155 depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 79c5155199a7..b2a62959ff8f 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_LEDS_LP8501) += leds-lp8501.o
31obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o 31obj-$(CONFIG_LEDS_LP8788) += leds-lp8788.o
32obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o 32obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o
33obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o 33obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
34obj-$(CONFIG_LEDS_IPAQ_MICRO) += leds-ipaq-micro.o
34obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o 35obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
35obj-$(CONFIG_LEDS_OT200) += leds-ot200.o 36obj-$(CONFIG_LEDS_OT200) += leds-ot200.o
36obj-$(CONFIG_LEDS_FSG) += leds-fsg.o 37obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index f37d63cf726b..129729d35478 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -15,10 +15,10 @@
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/timer.h>
19#include <linux/err.h> 18#include <linux/err.h>
20#include <linux/ctype.h> 19#include <linux/ctype.h>
21#include <linux/leds.h> 20#include <linux/leds.h>
21#include <linux/workqueue.h>
22#include "leds.h" 22#include "leds.h"
23 23
24static struct class *leds_class; 24static struct class *leds_class;
@@ -97,9 +97,10 @@ static const struct attribute_group *led_groups[] = {
97 NULL, 97 NULL,
98}; 98};
99 99
100static void led_timer_function(unsigned long data) 100static void led_work_function(struct work_struct *ws)
101{ 101{
102 struct led_classdev *led_cdev = (void *)data; 102 struct led_classdev *led_cdev =
103 container_of(ws, struct led_classdev, blink_work.work);
103 unsigned long brightness; 104 unsigned long brightness;
104 unsigned long delay; 105 unsigned long delay;
105 106
@@ -143,7 +144,8 @@ static void led_timer_function(unsigned long data)
143 } 144 }
144 } 145 }
145 146
146 mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); 147 queue_delayed_work(system_wq, &led_cdev->blink_work,
148 msecs_to_jiffies(delay));
147} 149}
148 150
149static void set_brightness_delayed(struct work_struct *ws) 151static void set_brightness_delayed(struct work_struct *ws)
@@ -210,8 +212,9 @@ static const struct dev_pm_ops leds_class_dev_pm_ops = {
210 */ 212 */
211int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) 213int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
212{ 214{
213 led_cdev->dev = device_create(leds_class, parent, 0, led_cdev, 215 led_cdev->dev = device_create_with_groups(leds_class, parent, 0,
214 "%s", led_cdev->name); 216 led_cdev, led_cdev->groups,
217 "%s", led_cdev->name);
215 if (IS_ERR(led_cdev->dev)) 218 if (IS_ERR(led_cdev->dev))
216 return PTR_ERR(led_cdev->dev); 219 return PTR_ERR(led_cdev->dev);
217 220
@@ -230,9 +233,7 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
230 233
231 INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed); 234 INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
232 235
233 init_timer(&led_cdev->blink_timer); 236 INIT_DELAYED_WORK(&led_cdev->blink_work, led_work_function);
234 led_cdev->blink_timer.function = led_timer_function;
235 led_cdev->blink_timer.data = (unsigned long)led_cdev;
236 237
237#ifdef CONFIG_LEDS_TRIGGERS 238#ifdef CONFIG_LEDS_TRIGGERS
238 led_trigger_set_default(led_cdev); 239 led_trigger_set_default(led_cdev);
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 71b40d3bf776..4bb116867b88 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -16,6 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/rwsem.h> 17#include <linux/rwsem.h>
18#include <linux/leds.h> 18#include <linux/leds.h>
19#include <linux/workqueue.h>
19#include "leds.h" 20#include "leds.h"
20 21
21DECLARE_RWSEM(leds_list_lock); 22DECLARE_RWSEM(leds_list_lock);
@@ -51,7 +52,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev,
51 return; 52 return;
52 } 53 }
53 54
54 mod_timer(&led_cdev->blink_timer, jiffies + 1); 55 queue_delayed_work(system_wq, &led_cdev->blink_work, 1);
55} 56}
56 57
57 58
@@ -75,7 +76,7 @@ void led_blink_set(struct led_classdev *led_cdev,
75 unsigned long *delay_on, 76 unsigned long *delay_on,
76 unsigned long *delay_off) 77 unsigned long *delay_off)
77{ 78{
78 del_timer_sync(&led_cdev->blink_timer); 79 cancel_delayed_work_sync(&led_cdev->blink_work);
79 80
80 led_cdev->flags &= ~LED_BLINK_ONESHOT; 81 led_cdev->flags &= ~LED_BLINK_ONESHOT;
81 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; 82 led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;
@@ -90,7 +91,7 @@ void led_blink_set_oneshot(struct led_classdev *led_cdev,
90 int invert) 91 int invert)
91{ 92{
92 if ((led_cdev->flags & LED_BLINK_ONESHOT) && 93 if ((led_cdev->flags & LED_BLINK_ONESHOT) &&
93 timer_pending(&led_cdev->blink_timer)) 94 delayed_work_pending(&led_cdev->blink_work))
94 return; 95 return;
95 96
96 led_cdev->flags |= LED_BLINK_ONESHOT; 97 led_cdev->flags |= LED_BLINK_ONESHOT;
@@ -107,7 +108,7 @@ EXPORT_SYMBOL(led_blink_set_oneshot);
107 108
108void led_stop_software_blink(struct led_classdev *led_cdev) 109void led_stop_software_blink(struct led_classdev *led_cdev)
109{ 110{
110 del_timer_sync(&led_cdev->blink_timer); 111 cancel_delayed_work_sync(&led_cdev->blink_work);
111 led_cdev->blink_delay_on = 0; 112 led_cdev->blink_delay_on = 0;
112 led_cdev->blink_delay_off = 0; 113 led_cdev->blink_delay_off = 0;
113} 114}
@@ -116,7 +117,7 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink);
116void led_set_brightness(struct led_classdev *led_cdev, 117void led_set_brightness(struct led_classdev *led_cdev,
117 enum led_brightness brightness) 118 enum led_brightness brightness)
118{ 119{
119 /* delay brightness setting if need to stop soft-blink timer */ 120 /* delay brightness setting if need to stop soft-blink work */
120 if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) { 121 if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) {
121 led_cdev->delayed_set_value = brightness; 122 led_cdev->delayed_set_value = brightness;
122 schedule_work(&led_cdev->set_brightness_work); 123 schedule_work(&led_cdev->set_brightness_work);
diff --git a/drivers/leds/leds-ipaq-micro.c b/drivers/leds/leds-ipaq-micro.c
new file mode 100644
index 000000000000..3776f516cd88
--- /dev/null
+++ b/drivers/leds/leds-ipaq-micro.c
@@ -0,0 +1,141 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * h3xxx atmel micro companion support, notification LED subdevice
7 *
8 * Author : Linus Walleij <linus.walleij@linaro.org>
9 */
10
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/mfd/ipaq-micro.h>
14#include <linux/leds.h>
15
16#define LED_YELLOW 0x00
17#define LED_GREEN 0x01
18
19#define LED_EN (1 << 4) /* LED ON/OFF 0:off, 1:on */
20#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop set 0:disable, 1:enable */
21#define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
22
23static void micro_leds_brightness_set(struct led_classdev *led_cdev,
24 enum led_brightness value)
25{
26 struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent);
27 /*
28 * In this message:
29 * Byte 0 = LED color: 0 = yellow, 1 = green
30 * yellow LED is always ~30 blinks per minute
31 * Byte 1 = duration (flags?) appears to be ignored
32 * Byte 2 = green ontime in 1/10 sec (deciseconds)
33 * 1 = 1/10 second
34 * 0 = 256/10 second
35 * Byte 3 = green offtime in 1/10 sec (deciseconds)
36 * 1 = 1/10 second
37 * 0 = 256/10 seconds
38 */
39 struct ipaq_micro_msg msg = {
40 .id = MSG_NOTIFY_LED,
41 .tx_len = 4,
42 };
43
44 msg.tx_data[0] = LED_GREEN;
45 msg.tx_data[1] = 0;
46 if (value) {
47 msg.tx_data[2] = 0; /* Duty cycle 256 */
48 msg.tx_data[3] = 1;
49 } else {
50 msg.tx_data[2] = 1;
51 msg.tx_data[3] = 0; /* Duty cycle 256 */
52 }
53 ipaq_micro_tx_msg_sync(micro, &msg);
54}
55
56/* Maximum duty cycle in ms 256/10 sec = 25600 ms */
57#define IPAQ_LED_MAX_DUTY 25600
58
59static int micro_leds_blink_set(struct led_classdev *led_cdev,
60 unsigned long *delay_on,
61 unsigned long *delay_off)
62{
63 struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent);
64 /*
65 * In this message:
66 * Byte 0 = LED color: 0 = yellow, 1 = green
67 * yellow LED is always ~30 blinks per minute
68 * Byte 1 = duration (flags?) appears to be ignored
69 * Byte 2 = green ontime in 1/10 sec (deciseconds)
70 * 1 = 1/10 second
71 * 0 = 256/10 second
72 * Byte 3 = green offtime in 1/10 sec (deciseconds)
73 * 1 = 1/10 second
74 * 0 = 256/10 seconds
75 */
76 struct ipaq_micro_msg msg = {
77 .id = MSG_NOTIFY_LED,
78 .tx_len = 4,
79 };
80
81 msg.tx_data[0] = LED_GREEN;
82 if (*delay_on > IPAQ_LED_MAX_DUTY ||
83 *delay_off > IPAQ_LED_MAX_DUTY)
84 return -EINVAL;
85
86 if (*delay_on == 0 && *delay_off == 0) {
87 *delay_on = 100;
88 *delay_off = 100;
89 }
90
91 msg.tx_data[1] = 0;
92 if (*delay_on >= IPAQ_LED_MAX_DUTY)
93 msg.tx_data[2] = 0;
94 else
95 msg.tx_data[2] = (u8) DIV_ROUND_CLOSEST(*delay_on, 100);
96 if (*delay_off >= IPAQ_LED_MAX_DUTY)
97 msg.tx_data[3] = 0;
98 else
99 msg.tx_data[3] = (u8) DIV_ROUND_CLOSEST(*delay_off, 100);
100 return ipaq_micro_tx_msg_sync(micro, &msg);
101}
102
103static struct led_classdev micro_led = {
104 .name = "led-ipaq-micro",
105 .brightness_set = micro_leds_brightness_set,
106 .blink_set = micro_leds_blink_set,
107 .flags = LED_CORE_SUSPENDRESUME,
108};
109
110static int micro_leds_probe(struct platform_device *pdev)
111{
112 int ret;
113
114 ret = led_classdev_register(&pdev->dev, &micro_led);
115 if (ret) {
116 dev_err(&pdev->dev, "registering led failed: %d\n", ret);
117 return ret;
118 }
119 dev_info(&pdev->dev, "iPAQ micro notification LED driver\n");
120
121 return 0;
122}
123
124static int micro_leds_remove(struct platform_device *pdev)
125{
126 led_classdev_unregister(&micro_led);
127 return 0;
128}
129
130static struct platform_driver micro_leds_device_driver = {
131 .driver = {
132 .name = "ipaq-micro-leds",
133 },
134 .probe = micro_leds_probe,
135 .remove = micro_leds_remove,
136};
137module_platform_driver(micro_leds_device_driver);
138
139MODULE_LICENSE("GPL");
140MODULE_DESCRIPTION("driver for iPAQ Atmel micro leds");
141MODULE_ALIAS("platform:ipaq-micro-leds");
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 652368c2ea9a..91325de3cd33 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -400,6 +400,12 @@ static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
400} 400}
401static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set); 401static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
402 402
403static struct attribute *lm3530_attrs[] = {
404 &dev_attr_mode.attr,
405 NULL
406};
407ATTRIBUTE_GROUPS(lm3530);
408
403static int lm3530_probe(struct i2c_client *client, 409static int lm3530_probe(struct i2c_client *client,
404 const struct i2c_device_id *id) 410 const struct i2c_device_id *id)
405{ 411{
@@ -436,6 +442,7 @@ static int lm3530_probe(struct i2c_client *client,
436 drvdata->led_dev.name = LM3530_LED_DEV; 442 drvdata->led_dev.name = LM3530_LED_DEV;
437 drvdata->led_dev.brightness_set = lm3530_brightness_set; 443 drvdata->led_dev.brightness_set = lm3530_brightness_set;
438 drvdata->led_dev.max_brightness = MAX_BRIGHTNESS; 444 drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
445 drvdata->led_dev.groups = lm3530_groups;
439 446
440 i2c_set_clientdata(client, drvdata); 447 i2c_set_clientdata(client, drvdata);
441 448
@@ -461,26 +468,13 @@ static int lm3530_probe(struct i2c_client *client,
461 return err; 468 return err;
462 } 469 }
463 470
464 err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode);
465 if (err < 0) {
466 dev_err(&client->dev, "File device creation failed: %d\n", err);
467 err = -ENODEV;
468 goto err_create_file;
469 }
470
471 return 0; 471 return 0;
472
473err_create_file:
474 led_classdev_unregister(&drvdata->led_dev);
475 return err;
476} 472}
477 473
478static int lm3530_remove(struct i2c_client *client) 474static int lm3530_remove(struct i2c_client *client)
479{ 475{
480 struct lm3530_data *drvdata = i2c_get_clientdata(client); 476 struct lm3530_data *drvdata = i2c_get_clientdata(client);
481 477
482 device_remove_file(drvdata->led_dev.dev, &dev_attr_mode);
483
484 lm3530_led_disable(drvdata); 478 lm3530_led_disable(drvdata);
485 led_classdev_unregister(&drvdata->led_dev); 479 led_classdev_unregister(&drvdata->led_dev);
486 return 0; 480 return 0;
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index e2c642c1169b..cbf61a40137d 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -645,6 +645,11 @@ static struct attribute_group lm3533_led_attribute_group = {
645 .attrs = lm3533_led_attributes 645 .attrs = lm3533_led_attributes
646}; 646};
647 647
648static const struct attribute_group *lm3533_led_attribute_groups[] = {
649 &lm3533_led_attribute_group,
650 NULL
651};
652
648static int lm3533_led_setup(struct lm3533_led *led, 653static int lm3533_led_setup(struct lm3533_led *led,
649 struct lm3533_led_platform_data *pdata) 654 struct lm3533_led_platform_data *pdata)
650{ 655{
@@ -692,6 +697,7 @@ static int lm3533_led_probe(struct platform_device *pdev)
692 led->cdev.brightness_get = lm3533_led_get; 697 led->cdev.brightness_get = lm3533_led_get;
693 led->cdev.blink_set = lm3533_led_blink_set; 698 led->cdev.blink_set = lm3533_led_blink_set;
694 led->cdev.brightness = LED_OFF; 699 led->cdev.brightness = LED_OFF;
700 led->cdev.groups = lm3533_led_attribute_groups,
695 led->id = pdev->id; 701 led->id = pdev->id;
696 702
697 mutex_init(&led->mutex); 703 mutex_init(&led->mutex);
@@ -715,25 +721,16 @@ static int lm3533_led_probe(struct platform_device *pdev)
715 721
716 led->cb.dev = led->cdev.dev; 722 led->cb.dev = led->cdev.dev;
717 723
718 ret = sysfs_create_group(&led->cdev.dev->kobj,
719 &lm3533_led_attribute_group);
720 if (ret < 0) {
721 dev_err(&pdev->dev, "failed to create sysfs attributes\n");
722 goto err_unregister;
723 }
724
725 ret = lm3533_led_setup(led, pdata); 724 ret = lm3533_led_setup(led, pdata);
726 if (ret) 725 if (ret)
727 goto err_sysfs_remove; 726 goto err_unregister;
728 727
729 ret = lm3533_ctrlbank_enable(&led->cb); 728 ret = lm3533_ctrlbank_enable(&led->cb);
730 if (ret) 729 if (ret)
731 goto err_sysfs_remove; 730 goto err_unregister;
732 731
733 return 0; 732 return 0;
734 733
735err_sysfs_remove:
736 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
737err_unregister: 734err_unregister:
738 led_classdev_unregister(&led->cdev); 735 led_classdev_unregister(&led->cdev);
739 flush_work(&led->work); 736 flush_work(&led->work);
@@ -748,7 +745,6 @@ static int lm3533_led_remove(struct platform_device *pdev)
748 dev_dbg(&pdev->dev, "%s\n", __func__); 745 dev_dbg(&pdev->dev, "%s\n", __func__);
749 746
750 lm3533_ctrlbank_disable(&led->cb); 747 lm3533_ctrlbank_disable(&led->cb);
751 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
752 led_classdev_unregister(&led->cdev); 748 led_classdev_unregister(&led->cdev);
753 flush_work(&led->work); 749 flush_work(&led->work);
754 750
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c
index 591eb5e58ae3..f5112cb2d991 100644
--- a/drivers/leds/leds-lm355x.c
+++ b/drivers/leds/leds-lm355x.c
@@ -413,6 +413,12 @@ out:
413 413
414static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store); 414static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store);
415 415
416static struct attribute *lm355x_indicator_attrs[] = {
417 &dev_attr_pattern.attr,
418 NULL
419};
420ATTRIBUTE_GROUPS(lm355x_indicator);
421
416static const struct regmap_config lm355x_regmap = { 422static const struct regmap_config lm355x_regmap = {
417 .reg_bits = 8, 423 .reg_bits = 8,
418 .val_bits = 8, 424 .val_bits = 8,
@@ -501,25 +507,18 @@ static int lm355x_probe(struct i2c_client *client,
501 else 507 else
502 chip->cdev_indicator.max_brightness = 8; 508 chip->cdev_indicator.max_brightness = 8;
503 chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set; 509 chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set;
510 /* indicator pattern control only for LM3556 */
511 if (id->driver_data == CHIP_LM3556)
512 chip->cdev_indicator.groups = lm355x_indicator_groups;
504 err = led_classdev_register((struct device *) 513 err = led_classdev_register((struct device *)
505 &client->dev, &chip->cdev_indicator); 514 &client->dev, &chip->cdev_indicator);
506 if (err < 0) 515 if (err < 0)
507 goto err_create_indicator_file; 516 goto err_create_indicator_file;
508 /* indicator pattern control only for LM3554 */
509 if (id->driver_data == CHIP_LM3556) {
510 err =
511 device_create_file(chip->cdev_indicator.dev,
512 &dev_attr_pattern);
513 if (err < 0)
514 goto err_create_pattern_file;
515 }
516 517
517 dev_info(&client->dev, "%s is initialized\n", 518 dev_info(&client->dev, "%s is initialized\n",
518 lm355x_name[id->driver_data]); 519 lm355x_name[id->driver_data]);
519 return 0; 520 return 0;
520 521
521err_create_pattern_file:
522 led_classdev_unregister(&chip->cdev_indicator);
523err_create_indicator_file: 522err_create_indicator_file:
524 led_classdev_unregister(&chip->cdev_torch); 523 led_classdev_unregister(&chip->cdev_torch);
525err_create_torch_file: 524err_create_torch_file:
@@ -534,8 +533,6 @@ static int lm355x_remove(struct i2c_client *client)
534 struct lm355x_reg_data *preg = chip->regs; 533 struct lm355x_reg_data *preg = chip->regs;
535 534
536 regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0); 535 regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
537 if (chip->type == CHIP_LM3556)
538 device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
539 led_classdev_unregister(&chip->cdev_indicator); 536 led_classdev_unregister(&chip->cdev_indicator);
540 flush_work(&chip->work_indicator); 537 flush_work(&chip->work_indicator);
541 led_classdev_unregister(&chip->cdev_torch); 538 led_classdev_unregister(&chip->cdev_torch);
diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c
index ceb6b3cde6fe..d3dec0132769 100644
--- a/drivers/leds/leds-lm3642.c
+++ b/drivers/leds/leds-lm3642.c
@@ -313,6 +313,18 @@ static const struct regmap_config lm3642_regmap = {
313 .max_register = REG_MAX, 313 .max_register = REG_MAX,
314}; 314};
315 315
316static struct attribute *lm3642_flash_attrs[] = {
317 &dev_attr_strobe_pin.attr,
318 NULL
319};
320ATTRIBUTE_GROUPS(lm3642_flash);
321
322static struct attribute *lm3642_torch_attrs[] = {
323 &dev_attr_torch_pin.attr,
324 NULL
325};
326ATTRIBUTE_GROUPS(lm3642_torch);
327
316static int lm3642_probe(struct i2c_client *client, 328static int lm3642_probe(struct i2c_client *client,
317 const struct i2c_device_id *id) 329 const struct i2c_device_id *id)
318{ 330{
@@ -364,17 +376,13 @@ static int lm3642_probe(struct i2c_client *client,
364 chip->cdev_flash.max_brightness = 16; 376 chip->cdev_flash.max_brightness = 16;
365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set; 377 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
366 chip->cdev_flash.default_trigger = "flash"; 378 chip->cdev_flash.default_trigger = "flash";
379 chip->cdev_flash.groups = lm3642_flash_groups,
367 err = led_classdev_register((struct device *) 380 err = led_classdev_register((struct device *)
368 &client->dev, &chip->cdev_flash); 381 &client->dev, &chip->cdev_flash);
369 if (err < 0) { 382 if (err < 0) {
370 dev_err(chip->dev, "failed to register flash\n"); 383 dev_err(chip->dev, "failed to register flash\n");
371 goto err_out; 384 goto err_out;
372 } 385 }
373 err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
374 if (err < 0) {
375 dev_err(chip->dev, "failed to create strobe-pin file\n");
376 goto err_create_flash_pin_file;
377 }
378 386
379 /* torch */ 387 /* torch */
380 INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set); 388 INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set);
@@ -382,17 +390,13 @@ static int lm3642_probe(struct i2c_client *client,
382 chip->cdev_torch.max_brightness = 8; 390 chip->cdev_torch.max_brightness = 8;
383 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set; 391 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
384 chip->cdev_torch.default_trigger = "torch"; 392 chip->cdev_torch.default_trigger = "torch";
393 chip->cdev_torch.groups = lm3642_torch_groups,
385 err = led_classdev_register((struct device *) 394 err = led_classdev_register((struct device *)
386 &client->dev, &chip->cdev_torch); 395 &client->dev, &chip->cdev_torch);
387 if (err < 0) { 396 if (err < 0) {
388 dev_err(chip->dev, "failed to register torch\n"); 397 dev_err(chip->dev, "failed to register torch\n");
389 goto err_create_torch_file; 398 goto err_create_torch_file;
390 } 399 }
391 err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
392 if (err < 0) {
393 dev_err(chip->dev, "failed to create torch-pin file\n");
394 goto err_create_torch_pin_file;
395 }
396 400
397 /* indicator */ 401 /* indicator */
398 INIT_WORK(&chip->work_indicator, 402 INIT_WORK(&chip->work_indicator,
@@ -411,12 +415,8 @@ static int lm3642_probe(struct i2c_client *client,
411 return 0; 415 return 0;
412 416
413err_create_indicator_file: 417err_create_indicator_file:
414 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
415err_create_torch_pin_file:
416 led_classdev_unregister(&chip->cdev_torch); 418 led_classdev_unregister(&chip->cdev_torch);
417err_create_torch_file: 419err_create_torch_file:
418 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
419err_create_flash_pin_file:
420 led_classdev_unregister(&chip->cdev_flash); 420 led_classdev_unregister(&chip->cdev_flash);
421err_out: 421err_out:
422 return err; 422 return err;
@@ -428,10 +428,8 @@ static int lm3642_remove(struct i2c_client *client)
428 428
429 led_classdev_unregister(&chip->cdev_indicator); 429 led_classdev_unregister(&chip->cdev_indicator);
430 flush_work(&chip->work_indicator); 430 flush_work(&chip->work_indicator);
431 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
432 led_classdev_unregister(&chip->cdev_torch); 431 led_classdev_unregister(&chip->cdev_torch);
433 flush_work(&chip->work_torch); 432 flush_work(&chip->work_torch);
434 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
435 led_classdev_unregister(&chip->cdev_flash); 433 led_classdev_unregister(&chip->cdev_flash);
436 flush_work(&chip->work_flash); 434 flush_work(&chip->work_flash);
437 regmap_write(chip->regmap, REG_ENABLE, 0); 435 regmap_write(chip->regmap, REG_ENABLE, 0);
diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c
index 88317b4f7bf3..77c26bc32eed 100644
--- a/drivers/leds/leds-lp55xx-common.c
+++ b/drivers/leds/leds-lp55xx-common.c
@@ -127,15 +127,12 @@ static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, lp55xx_show_current,
127 lp55xx_store_current); 127 lp55xx_store_current);
128static DEVICE_ATTR(max_current, S_IRUGO , lp55xx_show_max_current, NULL); 128static DEVICE_ATTR(max_current, S_IRUGO , lp55xx_show_max_current, NULL);
129 129
130static struct attribute *lp55xx_led_attributes[] = { 130static struct attribute *lp55xx_led_attrs[] = {
131 &dev_attr_led_current.attr, 131 &dev_attr_led_current.attr,
132 &dev_attr_max_current.attr, 132 &dev_attr_max_current.attr,
133 NULL, 133 NULL,
134}; 134};
135 135ATTRIBUTE_GROUPS(lp55xx_led);
136static struct attribute_group lp55xx_led_attr_group = {
137 .attrs = lp55xx_led_attributes
138};
139 136
140static void lp55xx_set_brightness(struct led_classdev *cdev, 137static void lp55xx_set_brightness(struct led_classdev *cdev,
141 enum led_brightness brightness) 138 enum led_brightness brightness)
@@ -176,6 +173,7 @@ static int lp55xx_init_led(struct lp55xx_led *led,
176 } 173 }
177 174
178 led->cdev.brightness_set = lp55xx_set_brightness; 175 led->cdev.brightness_set = lp55xx_set_brightness;
176 led->cdev.groups = lp55xx_led_groups;
179 177
180 if (pdata->led_config[chan].name) { 178 if (pdata->led_config[chan].name) {
181 led->cdev.name = pdata->led_config[chan].name; 179 led->cdev.name = pdata->led_config[chan].name;
@@ -185,24 +183,12 @@ static int lp55xx_init_led(struct lp55xx_led *led,
185 led->cdev.name = name; 183 led->cdev.name = name;
186 } 184 }
187 185
188 /*
189 * register led class device for each channel and
190 * add device attributes
191 */
192
193 ret = led_classdev_register(dev, &led->cdev); 186 ret = led_classdev_register(dev, &led->cdev);
194 if (ret) { 187 if (ret) {
195 dev_err(dev, "led register err: %d\n", ret); 188 dev_err(dev, "led register err: %d\n", ret);
196 return ret; 189 return ret;
197 } 190 }
198 191
199 ret = sysfs_create_group(&led->cdev.dev->kobj, &lp55xx_led_attr_group);
200 if (ret) {
201 dev_err(dev, "led sysfs err: %d\n", ret);
202 led_classdev_unregister(&led->cdev);
203 return ret;
204 }
205
206 return 0; 192 return 0;
207} 193}
208 194
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c
index f449a8bdddc7..607bc2755aba 100644
--- a/drivers/leds/leds-max8997.c
+++ b/drivers/leds/leds-max8997.c
@@ -229,6 +229,12 @@ static ssize_t max8997_led_store_mode(struct device *dev,
229 229
230static DEVICE_ATTR(mode, 0644, max8997_led_show_mode, max8997_led_store_mode); 230static DEVICE_ATTR(mode, 0644, max8997_led_show_mode, max8997_led_store_mode);
231 231
232static struct attribute *max8997_attrs[] = {
233 &dev_attr_mode.attr,
234 NULL
235};
236ATTRIBUTE_GROUPS(max8997);
237
232static int max8997_led_probe(struct platform_device *pdev) 238static int max8997_led_probe(struct platform_device *pdev)
233{ 239{
234 struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); 240 struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
@@ -253,6 +259,7 @@ static int max8997_led_probe(struct platform_device *pdev)
253 led->cdev.brightness_set = max8997_led_brightness_set; 259 led->cdev.brightness_set = max8997_led_brightness_set;
254 led->cdev.flags |= LED_CORE_SUSPENDRESUME; 260 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
255 led->cdev.brightness = 0; 261 led->cdev.brightness = 0;
262 led->cdev.groups = max8997_groups;
256 led->iodev = iodev; 263 led->iodev = iodev;
257 264
258 /* initialize mode and brightness according to platform_data */ 265 /* initialize mode and brightness according to platform_data */
@@ -281,14 +288,6 @@ static int max8997_led_probe(struct platform_device *pdev)
281 if (ret < 0) 288 if (ret < 0)
282 return ret; 289 return ret;
283 290
284 ret = device_create_file(led->cdev.dev, &dev_attr_mode);
285 if (ret != 0) {
286 dev_err(&pdev->dev,
287 "failed to create file: %d\n", ret);
288 led_classdev_unregister(&led->cdev);
289 return ret;
290 }
291
292 return 0; 291 return 0;
293} 292}
294 293
@@ -296,7 +295,6 @@ static int max8997_led_remove(struct platform_device *pdev)
296{ 295{
297 struct max8997_led *led = platform_get_drvdata(pdev); 296 struct max8997_led *led = platform_get_drvdata(pdev);
298 297
299 device_remove_file(led->cdev.dev, &dev_attr_mode);
300 led_classdev_unregister(&led->cdev); 298 led_classdev_unregister(&led->cdev);
301 299
302 return 0; 300 return 0;
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index e97f443a6e07..64fde485dcaa 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -293,10 +293,14 @@ static ssize_t netxbig_led_sata_show(struct device *dev,
293 293
294static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); 294static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store);
295 295
296static struct attribute *netxbig_led_attrs[] = {
297 &dev_attr_sata.attr,
298 NULL
299};
300ATTRIBUTE_GROUPS(netxbig_led);
301
296static void delete_netxbig_led(struct netxbig_led_data *led_dat) 302static void delete_netxbig_led(struct netxbig_led_data *led_dat)
297{ 303{
298 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
299 device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
300 led_classdev_unregister(&led_dat->cdev); 304 led_classdev_unregister(&led_dat->cdev);
301} 305}
302 306
@@ -306,7 +310,6 @@ create_netxbig_led(struct platform_device *pdev,
306 const struct netxbig_led *template) 310 const struct netxbig_led *template)
307{ 311{
308 struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev); 312 struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
309 int ret;
310 313
311 spin_lock_init(&led_dat->lock); 314 spin_lock_init(&led_dat->lock);
312 led_dat->gpio_ext = pdata->gpio_ext; 315 led_dat->gpio_ext = pdata->gpio_ext;
@@ -327,6 +330,12 @@ create_netxbig_led(struct platform_device *pdev,
327 led_dat->sata = 0; 330 led_dat->sata = 0;
328 led_dat->cdev.brightness = LED_OFF; 331 led_dat->cdev.brightness = LED_OFF;
329 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 332 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
333 /*
334 * If available, expose the SATA activity blink capability through
335 * a "sata" sysfs attribute.
336 */
337 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
338 led_dat->cdev.groups = netxbig_led_groups;
330 led_dat->mode_addr = template->mode_addr; 339 led_dat->mode_addr = template->mode_addr;
331 led_dat->mode_val = template->mode_val; 340 led_dat->mode_val = template->mode_val;
332 led_dat->bright_addr = template->bright_addr; 341 led_dat->bright_addr = template->bright_addr;
@@ -334,21 +343,7 @@ create_netxbig_led(struct platform_device *pdev,
334 led_dat->timer = pdata->timer; 343 led_dat->timer = pdata->timer;
335 led_dat->num_timer = pdata->num_timer; 344 led_dat->num_timer = pdata->num_timer;
336 345
337 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 346 return led_classdev_register(&pdev->dev, &led_dat->cdev);
338 if (ret < 0)
339 return ret;
340
341 /*
342 * If available, expose the SATA activity blink capability through
343 * a "sata" sysfs attribute.
344 */
345 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) {
346 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
347 if (ret)
348 led_classdev_unregister(&led_dat->cdev);
349 }
350
351 return ret;
352} 347}
353 348
354static int netxbig_led_probe(struct platform_device *pdev) 349static int netxbig_led_probe(struct platform_device *pdev)
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index efa625883c83..231993d1fe21 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -185,6 +185,12 @@ static ssize_t ns2_led_sata_show(struct device *dev,
185 185
186static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store); 186static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store);
187 187
188static struct attribute *ns2_led_attrs[] = {
189 &dev_attr_sata.attr,
190 NULL
191};
192ATTRIBUTE_GROUPS(ns2_led);
193
188static int 194static int
189create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat, 195create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
190 const struct ns2_led *template) 196 const struct ns2_led *template)
@@ -219,6 +225,7 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
219 led_dat->cdev.blink_set = NULL; 225 led_dat->cdev.blink_set = NULL;
220 led_dat->cdev.brightness_set = ns2_led_set; 226 led_dat->cdev.brightness_set = ns2_led_set;
221 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 227 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
228 led_dat->cdev.groups = ns2_led_groups;
222 led_dat->cmd = template->cmd; 229 led_dat->cmd = template->cmd;
223 led_dat->slow = template->slow; 230 led_dat->slow = template->slow;
224 231
@@ -235,20 +242,11 @@ create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
235 if (ret < 0) 242 if (ret < 0)
236 return ret; 243 return ret;
237 244
238 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
239 if (ret < 0)
240 goto err_free_cdev;
241
242 return 0; 245 return 0;
243
244err_free_cdev:
245 led_classdev_unregister(&led_dat->cdev);
246 return ret;
247} 246}
248 247
249static void delete_ns2_led(struct ns2_led_data *led_dat) 248static void delete_ns2_led(struct ns2_led_data *led_dat)
250{ 249{
251 device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
252 led_classdev_unregister(&led_dat->cdev); 250 led_classdev_unregister(&led_dat->cdev);
253} 251}
254 252
diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index 82589c0a5689..f110b4c456ba 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -12,7 +12,7 @@
12 * directory of this archive for more details. 12 * directory of this archive for more details.
13 * 13 *
14 * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62) 14 * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
15 * LED driver for the PCA9634 I2C LED driver (7-bit slave address set by hw.) 15 * LED driver for the PCA9634/5 I2C LED driver (7-bit slave address set by hw.)
16 * 16 *
17 * Note that hardware blinking violates the leds infrastructure driver 17 * Note that hardware blinking violates the leds infrastructure driver
18 * interface since the hardware only supports blinking all LEDs with the 18 * interface since the hardware only supports blinking all LEDs with the
@@ -52,6 +52,7 @@
52enum pca963x_type { 52enum pca963x_type {
53 pca9633, 53 pca9633,
54 pca9634, 54 pca9634,
55 pca9635,
55}; 56};
56 57
57struct pca963x_chipdef { 58struct pca963x_chipdef {
@@ -74,6 +75,12 @@ static struct pca963x_chipdef pca963x_chipdefs[] = {
74 .ledout_base = 0xc, 75 .ledout_base = 0xc,
75 .n_leds = 8, 76 .n_leds = 8,
76 }, 77 },
78 [pca9635] = {
79 .grppwm = 0x12,
80 .grpfreq = 0x13,
81 .ledout_base = 0x14,
82 .n_leds = 16,
83 },
77}; 84};
78 85
79/* Total blink period in milliseconds */ 86/* Total blink period in milliseconds */
@@ -84,6 +91,7 @@ static const struct i2c_device_id pca963x_id[] = {
84 { "pca9632", pca9633 }, 91 { "pca9632", pca9633 },
85 { "pca9633", pca9633 }, 92 { "pca9633", pca9633 },
86 { "pca9634", pca9634 }, 93 { "pca9634", pca9634 },
94 { "pca9635", pca9635 },
87 { } 95 { }
88}; 96};
89MODULE_DEVICE_TABLE(i2c, pca963x_id); 97MODULE_DEVICE_TABLE(i2c, pca963x_id);
@@ -107,7 +115,7 @@ struct pca963x_led {
107 struct work_struct work; 115 struct work_struct work;
108 enum led_brightness brightness; 116 enum led_brightness brightness;
109 struct led_classdev led_cdev; 117 struct led_classdev led_cdev;
110 int led_num; /* 0 .. 7 potentially */ 118 int led_num; /* 0 .. 15 potentially */
111 enum pca963x_cmd cmd; 119 enum pca963x_cmd cmd;
112 char name[32]; 120 char name[32];
113 u8 gdc; 121 u8 gdc;
@@ -321,6 +329,7 @@ static const struct of_device_id of_pca963x_match[] = {
321 { .compatible = "nxp,pca9632", }, 329 { .compatible = "nxp,pca9632", },
322 { .compatible = "nxp,pca9633", }, 330 { .compatible = "nxp,pca9633", },
323 { .compatible = "nxp,pca9634", }, 331 { .compatible = "nxp,pca9634", },
332 { .compatible = "nxp,pca9635", },
324 {}, 333 {},
325}; 334};
326#else 335#else
@@ -375,9 +384,8 @@ static int pca963x_probe(struct i2c_client *client,
375 pca963x_chip->leds = pca963x; 384 pca963x_chip->leds = pca963x;
376 385
377 /* Turn off LEDs by default*/ 386 /* Turn off LEDs by default*/
378 i2c_smbus_write_byte_data(client, chip->ledout_base, 0x00); 387 for (i = 0; i < chip->n_leds / 4; i++)
379 if (chip->n_leds > 4) 388 i2c_smbus_write_byte_data(client, chip->ledout_base + i, 0x00);
380 i2c_smbus_write_byte_data(client, chip->ledout_base + 1, 0x00);
381 389
382 for (i = 0; i < chip->n_leds; i++) { 390 for (i = 0; i < chip->n_leds; i++) {
383 pca963x[i].led_num = i; 391 pca963x[i].led_num = i;
@@ -415,9 +423,13 @@ static int pca963x_probe(struct i2c_client *client,
415 /* Disable LED all-call address and set normal mode */ 423 /* Disable LED all-call address and set normal mode */
416 i2c_smbus_write_byte_data(client, PCA963X_MODE1, 0x00); 424 i2c_smbus_write_byte_data(client, PCA963X_MODE1, 0x00);
417 425
418 /* Configure output: open-drain or totem pole (push-pull) */ 426 if (pdata) {
419 if (pdata && pdata->outdrv == PCA963X_OPEN_DRAIN) 427 /* Configure output: open-drain or totem pole (push-pull) */
420 i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x01); 428 if (pdata->outdrv == PCA963X_OPEN_DRAIN)
429 i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x01);
430 else
431 i2c_smbus_write_byte_data(client, PCA963X_MODE2, 0x05);
432 }
421 433
422 return 0; 434 return 0;
423 435
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index 2eb3ef62962b..046cb7008745 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -469,6 +469,12 @@ static ssize_t nas_led_blink_store(struct device *dev,
469 469
470static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store); 470static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store);
471 471
472static struct attribute *nasgpio_led_attrs[] = {
473 &dev_attr_blink.attr,
474 NULL
475};
476ATTRIBUTE_GROUPS(nasgpio_led);
477
472static int register_nasgpio_led(int led_nr) 478static int register_nasgpio_led(int led_nr)
473{ 479{
474 int ret; 480 int ret;
@@ -481,20 +487,18 @@ static int register_nasgpio_led(int led_nr)
481 led->brightness = LED_FULL; 487 led->brightness = LED_FULL;
482 led->brightness_set = nasgpio_led_set_brightness; 488 led->brightness_set = nasgpio_led_set_brightness;
483 led->blink_set = nasgpio_led_set_blink; 489 led->blink_set = nasgpio_led_set_blink;
490 led->groups = nasgpio_led_groups;
484 ret = led_classdev_register(&nas_gpio_pci_dev->dev, led); 491 ret = led_classdev_register(&nas_gpio_pci_dev->dev, led);
485 if (ret) 492 if (ret)
486 return ret; 493 return ret;
487 ret = device_create_file(led->dev, &dev_attr_blink); 494
488 if (ret) 495 return 0;
489 led_classdev_unregister(led);
490 return ret;
491} 496}
492 497
493static void unregister_nasgpio_led(int led_nr) 498static void unregister_nasgpio_led(int led_nr)
494{ 499{
495 struct led_classdev *led = get_classdev_for_led_nr(led_nr); 500 struct led_classdev *led = get_classdev_for_led_nr(led_nr);
496 led_classdev_unregister(led); 501 led_classdev_unregister(led);
497 device_remove_file(led->dev, &dev_attr_blink);
498} 502}
499/* 503/*
500 * module load/initialization 504 * module load/initialization
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c
index e72c974142d0..1b71e0701002 100644
--- a/drivers/leds/leds-wm831x-status.c
+++ b/drivers/leds/leds-wm831x-status.c
@@ -219,6 +219,12 @@ static ssize_t wm831x_status_src_store(struct device *dev,
219 219
220static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store); 220static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store);
221 221
222static struct attribute *wm831x_status_attrs[] = {
223 &dev_attr_src.attr,
224 NULL
225};
226ATTRIBUTE_GROUPS(wm831x_status);
227
222static int wm831x_status_probe(struct platform_device *pdev) 228static int wm831x_status_probe(struct platform_device *pdev)
223{ 229{
224 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 230 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
@@ -232,8 +238,7 @@ static int wm831x_status_probe(struct platform_device *pdev)
232 res = platform_get_resource(pdev, IORESOURCE_REG, 0); 238 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
233 if (res == NULL) { 239 if (res == NULL) {
234 dev_err(&pdev->dev, "No register resource\n"); 240 dev_err(&pdev->dev, "No register resource\n");
235 ret = -EINVAL; 241 return -EINVAL;
236 goto err;
237 } 242 }
238 243
239 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status), 244 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status),
@@ -284,31 +289,21 @@ static int wm831x_status_probe(struct platform_device *pdev)
284 drvdata->cdev.default_trigger = pdata.default_trigger; 289 drvdata->cdev.default_trigger = pdata.default_trigger;
285 drvdata->cdev.brightness_set = wm831x_status_set; 290 drvdata->cdev.brightness_set = wm831x_status_set;
286 drvdata->cdev.blink_set = wm831x_status_blink_set; 291 drvdata->cdev.blink_set = wm831x_status_blink_set;
292 drvdata->cdev.groups = wm831x_status_groups;
287 293
288 ret = led_classdev_register(wm831x->dev, &drvdata->cdev); 294 ret = led_classdev_register(wm831x->dev, &drvdata->cdev);
289 if (ret < 0) { 295 if (ret < 0) {
290 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 296 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
291 goto err_led; 297 return ret;
292 } 298 }
293 299
294 ret = device_create_file(drvdata->cdev.dev, &dev_attr_src);
295 if (ret != 0)
296 dev_err(&pdev->dev,
297 "No source control for LED: %d\n", ret);
298
299 return 0; 300 return 0;
300
301err_led:
302 led_classdev_unregister(&drvdata->cdev);
303err:
304 return ret;
305} 301}
306 302
307static int wm831x_status_remove(struct platform_device *pdev) 303static int wm831x_status_remove(struct platform_device *pdev)
308{ 304{
309 struct wm831x_status *drvdata = platform_get_drvdata(pdev); 305 struct wm831x_status *drvdata = platform_get_drvdata(pdev);
310 306
311 device_remove_file(drvdata->cdev.dev, &dev_attr_src);
312 led_classdev_unregister(&drvdata->cdev); 307 led_classdev_unregister(&drvdata->cdev);
313 308
314 return 0; 309 return 0;