aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2013-05-28 05:22:09 -0400
committerJiri Kosina <jkosina@suse.cz>2013-05-28 05:22:09 -0400
commit40e32ee6e475852f532c847ed1804b87f6531a67 (patch)
treec82f929072fbd08bac483df64b3207882d61536f
parentf04d51404f51947d3feabf2518495ba5aa3bb2c4 (diff)
HID: sony: fix leds dependency
The newly added support for Buzz controller - introduced Kconfig selection of LEDS_CLASS - introduced conditional preprocessor checking for CONFIG_LEDS_CLASS This has multiple problems -- namely select doesn't work transitively, so it shouldn't be used. On the other hand the code assumed that LEDS_CLASS is enabled in some places, but not everywhere. Put LEDS_CLASS as a Kconfig dependency for hid-sony and remove all the CONFIG_LEDS_CLASS conditionals from hid-sony. Reported-by: fengguang.wu@intel.com Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/Kconfig4
-rw-r--r--drivers/hid/hid-sony.c105
2 files changed, 44 insertions, 65 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 53caf0b115cb..5bad26ef227a 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -596,8 +596,8 @@ config HID_SAMSUNG
596config HID_SONY 596config HID_SONY
597 tristate "Sony PS2/3 accessories" 597 tristate "Sony PS2/3 accessories"
598 depends on USB_HID 598 depends on USB_HID
599 select NEW_LEDS 599 depends on NEW_LEDS
600 select LEDS_CLASS 600 depends on LEDS_CLASS
601 ---help--- 601 ---help---
602 Support for 602 Support for
603 603
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 41e829c8bc48..f1c906176615 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -21,6 +21,7 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/usb.h> 23#include <linux/usb.h>
24#include <linux/leds.h>
24 25
25#include "hid-ids.h" 26#include "hid-ids.h"
26 27
@@ -103,10 +104,8 @@ struct sony_sc {
103}; 104};
104 105
105struct buzz_extra { 106struct buzz_extra {
106#ifdef CONFIG_LEDS_CLASS
107 int led_state; 107 int led_state;
108 struct led_classdev *leds[4]; 108 struct led_classdev *leds[4];
109#endif
110}; 109};
111 110
112/* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 111/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
@@ -274,7 +273,6 @@ static int sixaxis_set_operational_bt(struct hid_device *hdev)
274 return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); 273 return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
275} 274}
276 275
277#ifdef CONFIG_LEDS_CLASS
278static void buzz_set_leds(struct hid_device *hdev, int leds) 276static void buzz_set_leds(struct hid_device *hdev, int leds)
279{ 277{
280 struct list_head *report_list = 278 struct list_head *report_list =
@@ -351,13 +349,15 @@ static enum led_brightness buzz_led_get_brightness(struct led_classdev *led)
351 349
352 return on ? LED_FULL : LED_OFF; 350 return on ? LED_FULL : LED_OFF;
353} 351}
354#endif
355 352
356static int buzz_init(struct hid_device *hdev) 353static int buzz_init(struct hid_device *hdev)
357{ 354{
358 struct sony_sc *drv_data; 355 struct sony_sc *drv_data;
359 struct buzz_extra *buzz; 356 struct buzz_extra *buzz;
360 int ret = 0; 357 int n, ret = 0;
358 struct led_classdev *led;
359 size_t name_sz;
360 char *name;
361 361
362 drv_data = hid_get_drvdata(hdev); 362 drv_data = hid_get_drvdata(hdev);
363 BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); 363 BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
@@ -374,90 +374,69 @@ static int buzz_init(struct hid_device *hdev)
374 * LEDs to on */ 374 * LEDs to on */
375 buzz_set_leds(hdev, 0x00); 375 buzz_set_leds(hdev, 0x00);
376 376
377#ifdef CONFIG_LEDS_CLASS 377 name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1;
378 {
379 int n;
380 struct led_classdev *led;
381 size_t name_sz;
382 char *name;
383 378
384 name_sz = strlen(dev_name(&hdev->dev)) + strlen("::buzz#") + 1; 379 for (n = 0; n < 4; n++) {
385 380 led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL);
386 for (n = 0; n < 4; n++) { 381 if (!led) {
387 led = kzalloc(sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 382 hid_err(hdev, "Couldn't allocate memory for LED %d\n", n);
388 if (!led) { 383 goto error_leds;
389 hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 384 }
390 goto error_leds;
391 }
392 385
393 name = (void *)(&led[1]); 386 name = (void *)(&led[1]);
394 snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1); 387 snprintf(name, name_sz, "%s::buzz%d", dev_name(&hdev->dev), n + 1);
395 led->name = name; 388 led->name = name;
396 led->brightness = 0; 389 led->brightness = 0;
397 led->max_brightness = 1; 390 led->max_brightness = 1;
398 led->brightness_get = buzz_led_get_brightness; 391 led->brightness_get = buzz_led_get_brightness;
399 led->brightness_set = buzz_led_set_brightness; 392 led->brightness_set = buzz_led_set_brightness;
400
401 if (led_classdev_register(&hdev->dev, led)) {
402 hid_err(hdev, "Failed to register LED %d\n", n);
403 kfree(led);
404 goto error_leds;
405 }
406 393
407 buzz->leds[n] = led; 394 if (led_classdev_register(&hdev->dev, led)) {
395 hid_err(hdev, "Failed to register LED %d\n", n);
396 kfree(led);
397 goto error_leds;
408 } 398 }
399
400 buzz->leds[n] = led;
409 } 401 }
410#endif
411 402
412 return ret; 403 return ret;
413 404
414#ifdef CONFIG_LEDS_CLASS
415error_leds: 405error_leds:
416 { 406 for (n = 0; n < 4; n++) {
417 int n; 407 led = buzz->leds[n];
418 struct led_classdev *led; 408 buzz->leds[n] = NULL;
419 409 if (!led)
420 for (n = 0; n < 4; n++) { 410 continue;
421 led = buzz->leds[n]; 411 led_classdev_unregister(led);
422 buzz->leds[n] = NULL; 412 kfree(led);
423 if (!led)
424 continue;
425 led_classdev_unregister(led);
426 kfree(led);
427 }
428 } 413 }
429 414
430 kfree(drv_data->extra); 415 kfree(drv_data->extra);
431 drv_data->extra = NULL; 416 drv_data->extra = NULL;
432 return ret; 417 return ret;
433#endif
434} 418}
435 419
436static void buzz_remove(struct hid_device *hdev) 420static void buzz_remove(struct hid_device *hdev)
437{ 421{
438 struct sony_sc *drv_data; 422 struct sony_sc *drv_data;
439 struct buzz_extra *buzz; 423 struct buzz_extra *buzz;
424 struct led_classdev *led;
425 int n;
440 426
441 drv_data = hid_get_drvdata(hdev); 427 drv_data = hid_get_drvdata(hdev);
442 BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); 428 BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
443 429
444 buzz = drv_data->extra; 430 buzz = drv_data->extra;
445 431
446#ifdef CONFIG_LEDS_CLASS 432 for (n = 0; n < 4; n++) {
447 { 433 led = buzz->leds[n];
448 int n; 434 buzz->leds[n] = NULL;
449 struct led_classdev *led; 435 if (!led)
450 436 continue;
451 for (n = 0; n < 4; n++) { 437 led_classdev_unregister(led);
452 led = buzz->leds[n]; 438 kfree(led);
453 buzz->leds[n] = NULL;
454 if (!led)
455 continue;
456 led_classdev_unregister(led);
457 kfree(led);
458 }
459 } 439 }
460#endif
461 440
462 kfree(drv_data->extra); 441 kfree(drv_data->extra);
463 drv_data->extra = NULL; 442 drv_data->extra = NULL;