diff options
author | Micha? K?pie? <kernel@kempniu.pl> | 2016-12-23 04:00:08 -0500 |
---|---|---|
committer | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2016-12-28 05:38:10 -0500 |
commit | a608a9d52fa4168efd478d684039ed545a69dbcd (patch) | |
tree | 778dbb5f6f0e0851d9ae837e43d0da4b0ec0e45a | |
parent | f6c5c1f96d976e1fb9d71fb824629c450ee0a122 (diff) |
platform/x86: fujitsu-laptop: use brightness_set_blocking for LED-setting callbacks
All LED-setting functions in fujitsu-laptop are currently assigned to
the brightness_set callback, which is incorrect because they can sleep
(due to their use of call_fext_func(), which in turn issues ACPI calls)
and the documentation (in include/linux/leds.h) clearly states they must
not. Assign them to brightness_set_blocking instead and change them to
match the expected function prototype.
This change makes it possible to use Fujitsu-specific LEDs with "heavy"
triggers, like disk-activity or phy0rx.
Fixes: 3a407086090b ("fujitsu-laptop: Add BL power, LED control and radio state information")
Fixes: 4f62568c1fcf ("fujitsu-laptop: Support radio LED")
Fixes: d6b88f64b0d4 ("fujitsu-laptop: Add support for eco LED")
Signed-off-by: Michał Kępień <kernel@kempniu.pl>
Acked-by: Jonathan Woithe <jwoithe@just42.net>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-rw-r--r-- | drivers/platform/x86/fujitsu-laptop.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 61f39abf5dc8..82d67715ce76 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -177,43 +177,43 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event); | |||
177 | 177 | ||
178 | #if IS_ENABLED(CONFIG_LEDS_CLASS) | 178 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
179 | static enum led_brightness logolamp_get(struct led_classdev *cdev); | 179 | static enum led_brightness logolamp_get(struct led_classdev *cdev); |
180 | static void logolamp_set(struct led_classdev *cdev, | 180 | static int logolamp_set(struct led_classdev *cdev, |
181 | enum led_brightness brightness); | 181 | enum led_brightness brightness); |
182 | 182 | ||
183 | static struct led_classdev logolamp_led = { | 183 | static struct led_classdev logolamp_led = { |
184 | .name = "fujitsu::logolamp", | 184 | .name = "fujitsu::logolamp", |
185 | .brightness_get = logolamp_get, | 185 | .brightness_get = logolamp_get, |
186 | .brightness_set = logolamp_set | 186 | .brightness_set_blocking = logolamp_set |
187 | }; | 187 | }; |
188 | 188 | ||
189 | static enum led_brightness kblamps_get(struct led_classdev *cdev); | 189 | static enum led_brightness kblamps_get(struct led_classdev *cdev); |
190 | static void kblamps_set(struct led_classdev *cdev, | 190 | static int kblamps_set(struct led_classdev *cdev, |
191 | enum led_brightness brightness); | 191 | enum led_brightness brightness); |
192 | 192 | ||
193 | static struct led_classdev kblamps_led = { | 193 | static struct led_classdev kblamps_led = { |
194 | .name = "fujitsu::kblamps", | 194 | .name = "fujitsu::kblamps", |
195 | .brightness_get = kblamps_get, | 195 | .brightness_get = kblamps_get, |
196 | .brightness_set = kblamps_set | 196 | .brightness_set_blocking = kblamps_set |
197 | }; | 197 | }; |
198 | 198 | ||
199 | static enum led_brightness radio_led_get(struct led_classdev *cdev); | 199 | static enum led_brightness radio_led_get(struct led_classdev *cdev); |
200 | static void radio_led_set(struct led_classdev *cdev, | 200 | static int radio_led_set(struct led_classdev *cdev, |
201 | enum led_brightness brightness); | 201 | enum led_brightness brightness); |
202 | 202 | ||
203 | static struct led_classdev radio_led = { | 203 | static struct led_classdev radio_led = { |
204 | .name = "fujitsu::radio_led", | 204 | .name = "fujitsu::radio_led", |
205 | .brightness_get = radio_led_get, | 205 | .brightness_get = radio_led_get, |
206 | .brightness_set = radio_led_set | 206 | .brightness_set_blocking = radio_led_set |
207 | }; | 207 | }; |
208 | 208 | ||
209 | static enum led_brightness eco_led_get(struct led_classdev *cdev); | 209 | static enum led_brightness eco_led_get(struct led_classdev *cdev); |
210 | static void eco_led_set(struct led_classdev *cdev, | 210 | static int eco_led_set(struct led_classdev *cdev, |
211 | enum led_brightness brightness); | 211 | enum led_brightness brightness); |
212 | 212 | ||
213 | static struct led_classdev eco_led = { | 213 | static struct led_classdev eco_led = { |
214 | .name = "fujitsu::eco_led", | 214 | .name = "fujitsu::eco_led", |
215 | .brightness_get = eco_led_get, | 215 | .brightness_get = eco_led_get, |
216 | .brightness_set = eco_led_set | 216 | .brightness_set_blocking = eco_led_set |
217 | }; | 217 | }; |
218 | #endif | 218 | #endif |
219 | 219 | ||
@@ -267,48 +267,48 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) | |||
267 | #if IS_ENABLED(CONFIG_LEDS_CLASS) | 267 | #if IS_ENABLED(CONFIG_LEDS_CLASS) |
268 | /* LED class callbacks */ | 268 | /* LED class callbacks */ |
269 | 269 | ||
270 | static void logolamp_set(struct led_classdev *cdev, | 270 | static int logolamp_set(struct led_classdev *cdev, |
271 | enum led_brightness brightness) | 271 | enum led_brightness brightness) |
272 | { | 272 | { |
273 | if (brightness >= LED_FULL) { | 273 | if (brightness >= LED_FULL) { |
274 | call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); | 274 | call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); |
275 | call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_ON); | 275 | return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_ON); |
276 | } else if (brightness >= LED_HALF) { | 276 | } else if (brightness >= LED_HALF) { |
277 | call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); | 277 | call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON); |
278 | call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_OFF); | 278 | return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_OFF); |
279 | } else { | 279 | } else { |
280 | call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_OFF); | 280 | return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_OFF); |
281 | } | 281 | } |
282 | } | 282 | } |
283 | 283 | ||
284 | static void kblamps_set(struct led_classdev *cdev, | 284 | static int kblamps_set(struct led_classdev *cdev, |
285 | enum led_brightness brightness) | 285 | enum led_brightness brightness) |
286 | { | 286 | { |
287 | if (brightness >= LED_FULL) | 287 | if (brightness >= LED_FULL) |
288 | call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON); | 288 | return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON); |
289 | else | 289 | else |
290 | call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF); | 290 | return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF); |
291 | } | 291 | } |
292 | 292 | ||
293 | static void radio_led_set(struct led_classdev *cdev, | 293 | static int radio_led_set(struct led_classdev *cdev, |
294 | enum led_brightness brightness) | 294 | enum led_brightness brightness) |
295 | { | 295 | { |
296 | if (brightness >= LED_FULL) | 296 | if (brightness >= LED_FULL) |
297 | call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, RADIO_LED_ON); | 297 | return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, RADIO_LED_ON); |
298 | else | 298 | else |
299 | call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, 0x0); | 299 | return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, 0x0); |
300 | } | 300 | } |
301 | 301 | ||
302 | static void eco_led_set(struct led_classdev *cdev, | 302 | static int eco_led_set(struct led_classdev *cdev, |
303 | enum led_brightness brightness) | 303 | enum led_brightness brightness) |
304 | { | 304 | { |
305 | int curr; | 305 | int curr; |
306 | 306 | ||
307 | curr = call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0); | 307 | curr = call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0); |
308 | if (brightness >= LED_FULL) | 308 | if (brightness >= LED_FULL) |
309 | call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr | ECO_LED_ON); | 309 | return call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr | ECO_LED_ON); |
310 | else | 310 | else |
311 | call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr & ~ECO_LED_ON); | 311 | return call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr & ~ECO_LED_ON); |
312 | } | 312 | } |
313 | 313 | ||
314 | static enum led_brightness logolamp_get(struct led_classdev *cdev) | 314 | static enum led_brightness logolamp_get(struct led_classdev *cdev) |