diff options
-rw-r--r-- | Documentation/leds-class.txt | 21 | ||||
-rw-r--r-- | drivers/leds/Kconfig | 2 | ||||
-rw-r--r-- | drivers/leds/led-class.c | 105 | ||||
-rw-r--r-- | drivers/leds/led-triggers.c | 2 | ||||
-rw-r--r-- | drivers/leds/ledtrig-timer.c | 124 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/Kconfig | 3 | ||||
-rw-r--r-- | include/linux/leds.h | 47 |
7 files changed, 171 insertions, 133 deletions
diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt index 8fd5ca2ae32..58b266bd184 100644 --- a/Documentation/leds-class.txt +++ b/Documentation/leds-class.txt | |||
@@ -60,15 +60,18 @@ Hardware accelerated blink of LEDs | |||
60 | 60 | ||
61 | Some LEDs can be programmed to blink without any CPU interaction. To | 61 | Some LEDs can be programmed to blink without any CPU interaction. To |
62 | support this feature, a LED driver can optionally implement the | 62 | support this feature, a LED driver can optionally implement the |
63 | blink_set() function (see <linux/leds.h>). If implemented, triggers can | 63 | blink_set() function (see <linux/leds.h>). To set an LED to blinking, |
64 | attempt to use it before falling back to software timers. The blink_set() | 64 | however, it is better to use use the API function led_blink_set(), |
65 | function should return 0 if the blink setting is supported, or -EINVAL | 65 | as it will check and implement software fallback if necessary. |
66 | otherwise, which means that LED blinking will be handled by software. | 66 | |
67 | 67 | To turn off blinking again, use the API function led_brightness_set() | |
68 | The blink_set() function should choose a user friendly blinking | 68 | as that will not just set the LED brightness but also stop any software |
69 | value if it is called with *delay_on==0 && *delay_off==0 parameters. In | 69 | timers that may have been required for blinking. |
70 | this case the driver should give back the chosen value through delay_on | 70 | |
71 | and delay_off parameters to the leds subsystem. | 71 | The blink_set() function should choose a user friendly blinking value |
72 | if it is called with *delay_on==0 && *delay_off==0 parameters. In this | ||
73 | case the driver should give back the chosen value through delay_on and | ||
74 | delay_off parameters to the leds subsystem. | ||
72 | 75 | ||
73 | Setting the brightness to zero with brightness_set() callback function | 76 | Setting the brightness to zero with brightness_set() callback function |
74 | should completely turn off the LED and cancel the previously programmed | 77 | should completely turn off the LED and cancel the previously programmed |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index cc2a88d5192..56b4b7a5ff3 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -10,7 +10,7 @@ menuconfig NEW_LEDS | |||
10 | if NEW_LEDS | 10 | if NEW_LEDS |
11 | 11 | ||
12 | config LEDS_CLASS | 12 | config LEDS_CLASS |
13 | tristate "LED Class Support" | 13 | bool "LED Class Support" |
14 | help | 14 | help |
15 | This option enables the led sysfs class in /sys/class/leds. You'll | 15 | This option enables the led sysfs class in /sys/class/leds. You'll |
16 | need this to do anything useful with LEDs. If unsure, say N. | 16 | need this to do anything useful with LEDs. If unsure, say N. |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 26066007650..211e21f34bd 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -81,6 +81,79 @@ static struct device_attribute led_class_attrs[] = { | |||
81 | __ATTR_NULL, | 81 | __ATTR_NULL, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static void led_timer_function(unsigned long data) | ||
85 | { | ||
86 | struct led_classdev *led_cdev = (void *)data; | ||
87 | unsigned long brightness; | ||
88 | unsigned long delay; | ||
89 | |||
90 | if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { | ||
91 | led_set_brightness(led_cdev, LED_OFF); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | brightness = led_get_brightness(led_cdev); | ||
96 | if (!brightness) { | ||
97 | /* Time to switch the LED on. */ | ||
98 | brightness = led_cdev->blink_brightness; | ||
99 | delay = led_cdev->blink_delay_on; | ||
100 | } else { | ||
101 | /* Store the current brightness value to be able | ||
102 | * to restore it when the delay_off period is over. | ||
103 | */ | ||
104 | led_cdev->blink_brightness = brightness; | ||
105 | brightness = LED_OFF; | ||
106 | delay = led_cdev->blink_delay_off; | ||
107 | } | ||
108 | |||
109 | led_set_brightness(led_cdev, brightness); | ||
110 | |||
111 | mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); | ||
112 | } | ||
113 | |||
114 | static void led_stop_software_blink(struct led_classdev *led_cdev) | ||
115 | { | ||
116 | /* deactivate previous settings */ | ||
117 | del_timer_sync(&led_cdev->blink_timer); | ||
118 | led_cdev->blink_delay_on = 0; | ||
119 | led_cdev->blink_delay_off = 0; | ||
120 | } | ||
121 | |||
122 | static void led_set_software_blink(struct led_classdev *led_cdev, | ||
123 | unsigned long delay_on, | ||
124 | unsigned long delay_off) | ||
125 | { | ||
126 | int current_brightness; | ||
127 | |||
128 | current_brightness = led_get_brightness(led_cdev); | ||
129 | if (current_brightness) | ||
130 | led_cdev->blink_brightness = current_brightness; | ||
131 | if (!led_cdev->blink_brightness) | ||
132 | led_cdev->blink_brightness = led_cdev->max_brightness; | ||
133 | |||
134 | if (delay_on == led_cdev->blink_delay_on && | ||
135 | delay_off == led_cdev->blink_delay_off) | ||
136 | return; | ||
137 | |||
138 | led_stop_software_blink(led_cdev); | ||
139 | |||
140 | led_cdev->blink_delay_on = delay_on; | ||
141 | led_cdev->blink_delay_off = delay_off; | ||
142 | |||
143 | /* never on - don't blink */ | ||
144 | if (!delay_on) | ||
145 | return; | ||
146 | |||
147 | /* never off - just set to brightness */ | ||
148 | if (!delay_off) { | ||
149 | led_set_brightness(led_cdev, led_cdev->blink_brightness); | ||
150 | return; | ||
151 | } | ||
152 | |||
153 | mod_timer(&led_cdev->blink_timer, jiffies + 1); | ||
154 | } | ||
155 | |||
156 | |||
84 | /** | 157 | /** |
85 | * led_classdev_suspend - suspend an led_classdev. | 158 | * led_classdev_suspend - suspend an led_classdev. |
86 | * @led_cdev: the led_classdev to suspend. | 159 | * @led_cdev: the led_classdev to suspend. |
@@ -148,6 +221,10 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
148 | 221 | ||
149 | led_update_brightness(led_cdev); | 222 | led_update_brightness(led_cdev); |
150 | 223 | ||
224 | init_timer(&led_cdev->blink_timer); | ||
225 | led_cdev->blink_timer.function = led_timer_function; | ||
226 | led_cdev->blink_timer.data = (unsigned long)led_cdev; | ||
227 | |||
151 | #ifdef CONFIG_LEDS_TRIGGERS | 228 | #ifdef CONFIG_LEDS_TRIGGERS |
152 | led_trigger_set_default(led_cdev); | 229 | led_trigger_set_default(led_cdev); |
153 | #endif | 230 | #endif |
@@ -157,7 +234,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) | |||
157 | 234 | ||
158 | return 0; | 235 | return 0; |
159 | } | 236 | } |
160 | |||
161 | EXPORT_SYMBOL_GPL(led_classdev_register); | 237 | EXPORT_SYMBOL_GPL(led_classdev_register); |
162 | 238 | ||
163 | /** | 239 | /** |
@@ -175,6 +251,9 @@ void led_classdev_unregister(struct led_classdev *led_cdev) | |||
175 | up_write(&led_cdev->trigger_lock); | 251 | up_write(&led_cdev->trigger_lock); |
176 | #endif | 252 | #endif |
177 | 253 | ||
254 | /* Stop blinking */ | ||
255 | led_brightness_set(led_cdev, LED_OFF); | ||
256 | |||
178 | device_unregister(led_cdev->dev); | 257 | device_unregister(led_cdev->dev); |
179 | 258 | ||
180 | down_write(&leds_list_lock); | 259 | down_write(&leds_list_lock); |
@@ -183,6 +262,30 @@ void led_classdev_unregister(struct led_classdev *led_cdev) | |||
183 | } | 262 | } |
184 | EXPORT_SYMBOL_GPL(led_classdev_unregister); | 263 | EXPORT_SYMBOL_GPL(led_classdev_unregister); |
185 | 264 | ||
265 | void led_blink_set(struct led_classdev *led_cdev, | ||
266 | unsigned long *delay_on, | ||
267 | unsigned long *delay_off) | ||
268 | { | ||
269 | if (led_cdev->blink_set && | ||
270 | led_cdev->blink_set(led_cdev, delay_on, delay_off)) | ||
271 | return; | ||
272 | |||
273 | /* blink with 1 Hz as default if nothing specified */ | ||
274 | if (!*delay_on && !*delay_off) | ||
275 | *delay_on = *delay_off = 500; | ||
276 | |||
277 | led_set_software_blink(led_cdev, *delay_on, *delay_off); | ||
278 | } | ||
279 | EXPORT_SYMBOL(led_blink_set); | ||
280 | |||
281 | void led_brightness_set(struct led_classdev *led_cdev, | ||
282 | enum led_brightness brightness) | ||
283 | { | ||
284 | led_stop_software_blink(led_cdev); | ||
285 | led_cdev->brightness_set(led_cdev, brightness); | ||
286 | } | ||
287 | EXPORT_SYMBOL(led_brightness_set); | ||
288 | |||
186 | static int __init leds_init(void) | 289 | static int __init leds_init(void) |
187 | { | 290 | { |
188 | leds_class = class_create(THIS_MODULE, "leds"); | 291 | leds_class = class_create(THIS_MODULE, "leds"); |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index f1c00db88b5..c41eb6180c9 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -113,7 +113,7 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) | |||
113 | if (led_cdev->trigger->deactivate) | 113 | if (led_cdev->trigger->deactivate) |
114 | led_cdev->trigger->deactivate(led_cdev); | 114 | led_cdev->trigger->deactivate(led_cdev); |
115 | led_cdev->trigger = NULL; | 115 | led_cdev->trigger = NULL; |
116 | led_set_brightness(led_cdev, LED_OFF); | 116 | led_brightness_set(led_cdev, LED_OFF); |
117 | } | 117 | } |
118 | if (trigger) { | 118 | if (trigger) { |
119 | write_lock_irqsave(&trigger->leddev_list_lock, flags); | 119 | write_lock_irqsave(&trigger->leddev_list_lock, flags); |
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 82b77bd482f..b09bcbeade9 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c | |||
@@ -12,73 +12,25 @@ | |||
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/list.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/device.h> | 17 | #include <linux/device.h> |
21 | #include <linux/sysdev.h> | ||
22 | #include <linux/timer.h> | ||
23 | #include <linux/ctype.h> | 18 | #include <linux/ctype.h> |
24 | #include <linux/leds.h> | 19 | #include <linux/leds.h> |
25 | #include <linux/slab.h> | ||
26 | #include "leds.h" | 20 | #include "leds.h" |
27 | 21 | ||
28 | struct timer_trig_data { | ||
29 | int brightness_on; /* LED brightness during "on" period. | ||
30 | * (LED_OFF < brightness_on <= LED_FULL) | ||
31 | */ | ||
32 | unsigned long delay_on; /* milliseconds on */ | ||
33 | unsigned long delay_off; /* milliseconds off */ | ||
34 | struct timer_list timer; | ||
35 | }; | ||
36 | |||
37 | static void led_timer_function(unsigned long data) | ||
38 | { | ||
39 | struct led_classdev *led_cdev = (struct led_classdev *) data; | ||
40 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
41 | unsigned long brightness; | ||
42 | unsigned long delay; | ||
43 | |||
44 | if (!timer_data->delay_on || !timer_data->delay_off) { | ||
45 | led_set_brightness(led_cdev, LED_OFF); | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | brightness = led_get_brightness(led_cdev); | ||
50 | if (!brightness) { | ||
51 | /* Time to switch the LED on. */ | ||
52 | brightness = timer_data->brightness_on; | ||
53 | delay = timer_data->delay_on; | ||
54 | } else { | ||
55 | /* Store the current brightness value to be able | ||
56 | * to restore it when the delay_off period is over. | ||
57 | */ | ||
58 | timer_data->brightness_on = brightness; | ||
59 | brightness = LED_OFF; | ||
60 | delay = timer_data->delay_off; | ||
61 | } | ||
62 | |||
63 | led_set_brightness(led_cdev, brightness); | ||
64 | |||
65 | mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); | ||
66 | } | ||
67 | |||
68 | static ssize_t led_delay_on_show(struct device *dev, | 22 | static ssize_t led_delay_on_show(struct device *dev, |
69 | struct device_attribute *attr, char *buf) | 23 | struct device_attribute *attr, char *buf) |
70 | { | 24 | { |
71 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 25 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
72 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
73 | 26 | ||
74 | return sprintf(buf, "%lu\n", timer_data->delay_on); | 27 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_on); |
75 | } | 28 | } |
76 | 29 | ||
77 | static ssize_t led_delay_on_store(struct device *dev, | 30 | static ssize_t led_delay_on_store(struct device *dev, |
78 | struct device_attribute *attr, const char *buf, size_t size) | 31 | struct device_attribute *attr, const char *buf, size_t size) |
79 | { | 32 | { |
80 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 33 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
81 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
82 | int ret = -EINVAL; | 34 | int ret = -EINVAL; |
83 | char *after; | 35 | char *after; |
84 | unsigned long state = simple_strtoul(buf, &after, 10); | 36 | unsigned long state = simple_strtoul(buf, &after, 10); |
@@ -88,21 +40,7 @@ static ssize_t led_delay_on_store(struct device *dev, | |||
88 | count++; | 40 | count++; |
89 | 41 | ||
90 | if (count == size) { | 42 | if (count == size) { |
91 | if (timer_data->delay_on != state) { | 43 | led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); |
92 | /* the new value differs from the previous */ | ||
93 | timer_data->delay_on = state; | ||
94 | |||
95 | /* deactivate previous settings */ | ||
96 | del_timer_sync(&timer_data->timer); | ||
97 | |||
98 | /* try to activate hardware acceleration, if any */ | ||
99 | if (!led_cdev->blink_set || | ||
100 | led_cdev->blink_set(led_cdev, | ||
101 | &timer_data->delay_on, &timer_data->delay_off)) { | ||
102 | /* no hardware acceleration, blink via timer */ | ||
103 | mod_timer(&timer_data->timer, jiffies + 1); | ||
104 | } | ||
105 | } | ||
106 | ret = count; | 44 | ret = count; |
107 | } | 45 | } |
108 | 46 | ||
@@ -113,16 +51,14 @@ static ssize_t led_delay_off_show(struct device *dev, | |||
113 | struct device_attribute *attr, char *buf) | 51 | struct device_attribute *attr, char *buf) |
114 | { | 52 | { |
115 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 53 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
116 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
117 | 54 | ||
118 | return sprintf(buf, "%lu\n", timer_data->delay_off); | 55 | return sprintf(buf, "%lu\n", led_cdev->blink_delay_off); |
119 | } | 56 | } |
120 | 57 | ||
121 | static ssize_t led_delay_off_store(struct device *dev, | 58 | static ssize_t led_delay_off_store(struct device *dev, |
122 | struct device_attribute *attr, const char *buf, size_t size) | 59 | struct device_attribute *attr, const char *buf, size_t size) |
123 | { | 60 | { |
124 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 61 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
125 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | ||
126 | int ret = -EINVAL; | 62 | int ret = -EINVAL; |
127 | char *after; | 63 | char *after; |
128 | unsigned long state = simple_strtoul(buf, &after, 10); | 64 | unsigned long state = simple_strtoul(buf, &after, 10); |
@@ -132,21 +68,7 @@ static ssize_t led_delay_off_store(struct device *dev, | |||
132 | count++; | 68 | count++; |
133 | 69 | ||
134 | if (count == size) { | 70 | if (count == size) { |
135 | if (timer_data->delay_off != state) { | 71 | led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); |
136 | /* the new value differs from the previous */ | ||
137 | timer_data->delay_off = state; | ||
138 | |||
139 | /* deactivate previous settings */ | ||
140 | del_timer_sync(&timer_data->timer); | ||
141 | |||
142 | /* try to activate hardware acceleration, if any */ | ||
143 | if (!led_cdev->blink_set || | ||
144 | led_cdev->blink_set(led_cdev, | ||
145 | &timer_data->delay_on, &timer_data->delay_off)) { | ||
146 | /* no hardware acceleration, blink via timer */ | ||
147 | mod_timer(&timer_data->timer, jiffies + 1); | ||
148 | } | ||
149 | } | ||
150 | ret = count; | 72 | ret = count; |
151 | } | 73 | } |
152 | 74 | ||
@@ -158,60 +80,34 @@ static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store); | |||
158 | 80 | ||
159 | static void timer_trig_activate(struct led_classdev *led_cdev) | 81 | static void timer_trig_activate(struct led_classdev *led_cdev) |
160 | { | 82 | { |
161 | struct timer_trig_data *timer_data; | ||
162 | int rc; | 83 | int rc; |
163 | 84 | ||
164 | timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); | 85 | led_cdev->trigger_data = NULL; |
165 | if (!timer_data) | ||
166 | return; | ||
167 | |||
168 | timer_data->brightness_on = led_get_brightness(led_cdev); | ||
169 | if (timer_data->brightness_on == LED_OFF) | ||
170 | timer_data->brightness_on = led_cdev->max_brightness; | ||
171 | led_cdev->trigger_data = timer_data; | ||
172 | |||
173 | init_timer(&timer_data->timer); | ||
174 | timer_data->timer.function = led_timer_function; | ||
175 | timer_data->timer.data = (unsigned long) led_cdev; | ||
176 | 86 | ||
177 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); | 87 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); |
178 | if (rc) | 88 | if (rc) |
179 | goto err_out; | 89 | return; |
180 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); | 90 | rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); |
181 | if (rc) | 91 | if (rc) |
182 | goto err_out_delayon; | 92 | goto err_out_delayon; |
183 | 93 | ||
184 | /* If there is hardware support for blinking, start one | 94 | led_cdev->trigger_data = (void *)1; |
185 | * user friendly blink rate chosen by the driver. | ||
186 | */ | ||
187 | if (led_cdev->blink_set) | ||
188 | led_cdev->blink_set(led_cdev, | ||
189 | &timer_data->delay_on, &timer_data->delay_off); | ||
190 | 95 | ||
191 | return; | 96 | return; |
192 | 97 | ||
193 | err_out_delayon: | 98 | err_out_delayon: |
194 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | 99 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); |
195 | err_out: | ||
196 | led_cdev->trigger_data = NULL; | ||
197 | kfree(timer_data); | ||
198 | } | 100 | } |
199 | 101 | ||
200 | static void timer_trig_deactivate(struct led_classdev *led_cdev) | 102 | static void timer_trig_deactivate(struct led_classdev *led_cdev) |
201 | { | 103 | { |
202 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 104 | if (led_cdev->trigger_data) { |
203 | unsigned long on = 0, off = 0; | ||
204 | |||
205 | if (timer_data) { | ||
206 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); | 105 | device_remove_file(led_cdev->dev, &dev_attr_delay_on); |
207 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); | 106 | device_remove_file(led_cdev->dev, &dev_attr_delay_off); |
208 | del_timer_sync(&timer_data->timer); | ||
209 | kfree(timer_data); | ||
210 | } | 107 | } |
211 | 108 | ||
212 | /* If there is hardware support for blinking, stop it */ | 109 | /* Stop blinking */ |
213 | if (led_cdev->blink_set) | 110 | led_brightness_set(led_cdev, LED_OFF); |
214 | led_cdev->blink_set(led_cdev, &on, &off); | ||
215 | } | 111 | } |
216 | 112 | ||
217 | static struct led_trigger timer_led_trigger = { | 113 | static struct led_trigger timer_led_trigger = { |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index eea1ef2f502..4396d4b9bfb 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -221,9 +221,6 @@ config RT2X00_LIB_LEDS | |||
221 | boolean | 221 | boolean |
222 | default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) | 222 | default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) |
223 | 223 | ||
224 | comment "rt2x00 leds support disabled due to modularized LEDS_CLASS and built-in rt2x00" | ||
225 | depends on RT2X00_LIB=y && LEDS_CLASS=m | ||
226 | |||
227 | config RT2X00_LIB_DEBUGFS | 224 | config RT2X00_LIB_DEBUGFS |
228 | bool "Ralink debugfs support" | 225 | bool "Ralink debugfs support" |
229 | depends on RT2X00_LIB && MAC80211_DEBUGFS | 226 | depends on RT2X00_LIB && MAC80211_DEBUGFS |
diff --git a/include/linux/leds.h b/include/linux/leds.h index ba6986a1166..0f19df9e37b 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/rwsem.h> | 17 | #include <linux/rwsem.h> |
18 | #include <linux/timer.h> | ||
18 | 19 | ||
19 | struct device; | 20 | struct device; |
20 | /* | 21 | /* |
@@ -45,10 +46,14 @@ struct led_classdev { | |||
45 | /* Get LED brightness level */ | 46 | /* Get LED brightness level */ |
46 | enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); | 47 | enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); |
47 | 48 | ||
48 | /* Activate hardware accelerated blink, delays are in | 49 | /* |
49 | * miliseconds and if none is provided then a sensible default | 50 | * Activate hardware accelerated blink, delays are in milliseconds |
50 | * should be chosen. The call can adjust the timings if it can't | 51 | * and if both are zero then a sensible default should be chosen. |
51 | * match the values specified exactly. */ | 52 | * The call should adjust the timings in that case and if it can't |
53 | * match the values specified exactly. | ||
54 | * Deactivate blinking again when the brightness is set to a fixed | ||
55 | * value via the brightness_set() callback. | ||
56 | */ | ||
52 | int (*blink_set)(struct led_classdev *led_cdev, | 57 | int (*blink_set)(struct led_classdev *led_cdev, |
53 | unsigned long *delay_on, | 58 | unsigned long *delay_on, |
54 | unsigned long *delay_off); | 59 | unsigned long *delay_off); |
@@ -57,6 +62,10 @@ struct led_classdev { | |||
57 | struct list_head node; /* LED Device list */ | 62 | struct list_head node; /* LED Device list */ |
58 | const char *default_trigger; /* Trigger to use */ | 63 | const char *default_trigger; /* Trigger to use */ |
59 | 64 | ||
65 | unsigned long blink_delay_on, blink_delay_off; | ||
66 | struct timer_list blink_timer; | ||
67 | int blink_brightness; | ||
68 | |||
60 | #ifdef CONFIG_LEDS_TRIGGERS | 69 | #ifdef CONFIG_LEDS_TRIGGERS |
61 | /* Protects the trigger data below */ | 70 | /* Protects the trigger data below */ |
62 | struct rw_semaphore trigger_lock; | 71 | struct rw_semaphore trigger_lock; |
@@ -73,6 +82,36 @@ extern void led_classdev_unregister(struct led_classdev *led_cdev); | |||
73 | extern void led_classdev_suspend(struct led_classdev *led_cdev); | 82 | extern void led_classdev_suspend(struct led_classdev *led_cdev); |
74 | extern void led_classdev_resume(struct led_classdev *led_cdev); | 83 | extern void led_classdev_resume(struct led_classdev *led_cdev); |
75 | 84 | ||
85 | /** | ||
86 | * led_blink_set - set blinking with software fallback | ||
87 | * @led_cdev: the LED to start blinking | ||
88 | * @delay_on: the time it should be on (in ms) | ||
89 | * @delay_off: the time it should ble off (in ms) | ||
90 | * | ||
91 | * This function makes the LED blink, attempting to use the | ||
92 | * hardware acceleration if possible, but falling back to | ||
93 | * software blinking if there is no hardware blinking or if | ||
94 | * the LED refuses the passed values. | ||
95 | * | ||
96 | * Note that if software blinking is active, simply calling | ||
97 | * led_cdev->brightness_set() will not stop the blinking, | ||
98 | * use led_classdev_brightness_set() instead. | ||
99 | */ | ||
100 | extern void led_blink_set(struct led_classdev *led_cdev, | ||
101 | unsigned long *delay_on, | ||
102 | unsigned long *delay_off); | ||
103 | /** | ||
104 | * led_brightness_set - set LED brightness | ||
105 | * @led_cdev: the LED to set | ||
106 | * @brightness: the brightness to set it to | ||
107 | * | ||
108 | * Set an LED's brightness, and, if necessary, cancel the | ||
109 | * software blink timer that implements blinking when the | ||
110 | * hardware doesn't. | ||
111 | */ | ||
112 | extern void led_brightness_set(struct led_classdev *led_cdev, | ||
113 | enum led_brightness brightness); | ||
114 | |||
76 | /* | 115 | /* |
77 | * LED Triggers | 116 | * LED Triggers |
78 | */ | 117 | */ |