aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/hid-sony.c58
1 files changed, 17 insertions, 41 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index cdb24192db96..2f93aab11056 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -223,6 +223,7 @@ static const unsigned int buzz_keymap[] = {
223}; 223};
224 224
225struct sony_sc { 225struct sony_sc {
226 struct led_classdev *leds[4];
226 unsigned long quirks; 227 unsigned long quirks;
227 228
228#ifdef CONFIG_SONY_FF 229#ifdef CONFIG_SONY_FF
@@ -232,12 +233,7 @@ struct sony_sc {
232 __u8 right; 233 __u8 right;
233#endif 234#endif
234 235
235 void *extra; 236 __u8 led_state;
236};
237
238struct buzz_extra {
239 int led_state;
240 struct led_classdev *leds[4];
241}; 237};
242 238
243static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, 239static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -472,26 +468,24 @@ static void sony_led_set_brightness(struct led_classdev *led,
472 struct device *dev = led->dev->parent; 468 struct device *dev = led->dev->parent;
473 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 469 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
474 struct sony_sc *drv_data; 470 struct sony_sc *drv_data;
475 struct buzz_extra *buzz;
476 471
477 int n; 472 int n;
478 473
479 drv_data = hid_get_drvdata(hdev); 474 drv_data = hid_get_drvdata(hdev);
480 if (!drv_data || !drv_data->extra) { 475 if (!drv_data) {
481 hid_err(hdev, "No device data\n"); 476 hid_err(hdev, "No device data\n");
482 return; 477 return;
483 } 478 }
484 buzz = drv_data->extra;
485 479
486 for (n = 0; n < 4; n++) { 480 for (n = 0; n < 4; n++) {
487 if (led == buzz->leds[n]) { 481 if (led == drv_data->leds[n]) {
488 int on = !! (buzz->led_state & (1 << n)); 482 int on = !!(drv_data->led_state & (1 << n));
489 if (value == LED_OFF && on) { 483 if (value == LED_OFF && on) {
490 buzz->led_state &= ~(1 << n); 484 drv_data->led_state &= ~(1 << n);
491 buzz_set_leds(hdev, buzz->led_state); 485 buzz_set_leds(hdev, drv_data->led_state);
492 } else if (value != LED_OFF && !on) { 486 } else if (value != LED_OFF && !on) {
493 buzz->led_state |= (1 << n); 487 drv_data->led_state |= (1 << n);
494 buzz_set_leds(hdev, buzz->led_state); 488 buzz_set_leds(hdev, drv_data->led_state);
495 } 489 }
496 break; 490 break;
497 } 491 }
@@ -503,21 +497,19 @@ static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
503 struct device *dev = led->dev->parent; 497 struct device *dev = led->dev->parent;
504 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 498 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
505 struct sony_sc *drv_data; 499 struct sony_sc *drv_data;
506 struct buzz_extra *buzz;
507 500
508 int n; 501 int n;
509 int on = 0; 502 int on = 0;
510 503
511 drv_data = hid_get_drvdata(hdev); 504 drv_data = hid_get_drvdata(hdev);
512 if (!drv_data || !drv_data->extra) { 505 if (!drv_data) {
513 hid_err(hdev, "No device data\n"); 506 hid_err(hdev, "No device data\n");
514 return LED_OFF; 507 return LED_OFF;
515 } 508 }
516 buzz = drv_data->extra;
517 509
518 for (n = 0; n < 4; n++) { 510 for (n = 0; n < 4; n++) {
519 if (led == buzz->leds[n]) { 511 if (led == drv_data->leds[n]) {
520 on = !! (buzz->led_state & (1 << n)); 512 on = !!(drv_data->led_state & (1 << n));
521 break; 513 break;
522 } 514 }
523 } 515 }
@@ -528,7 +520,6 @@ static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
528static int sony_leds_init(struct hid_device *hdev) 520static int sony_leds_init(struct hid_device *hdev)
529{ 521{
530 struct sony_sc *drv_data; 522 struct sony_sc *drv_data;
531 struct buzz_extra *buzz;
532 int n, ret = 0; 523 int n, ret = 0;
533 struct led_classdev *led; 524 struct led_classdev *led;
534 size_t name_sz; 525 size_t name_sz;
@@ -541,13 +532,6 @@ static int sony_leds_init(struct hid_device *hdev)
541 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) 532 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
542 return -ENODEV; 533 return -ENODEV;
543 534
544 buzz = kzalloc(sizeof(*buzz), GFP_KERNEL);
545 if (!buzz) {
546 hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
547 return -ENOMEM;
548 }
549 drv_data->extra = buzz;
550
551 /* Clear LEDs as we have no way of reading their initial state. This is 535 /* Clear LEDs as we have no way of reading their initial state. This is
552 * only relevant if the driver is loaded after somebody actively set the 536 * only relevant if the driver is loaded after somebody actively set the
553 * LEDs to on */ 537 * LEDs to on */
@@ -576,49 +560,41 @@ static int sony_leds_init(struct hid_device *hdev)
576 goto error_leds; 560 goto error_leds;
577 } 561 }
578 562
579 buzz->leds[n] = led; 563 drv_data->leds[n] = led;
580 } 564 }
581 565
582 return ret; 566 return ret;
583 567
584error_leds: 568error_leds:
585 for (n = 0; n < 4; n++) { 569 for (n = 0; n < 4; n++) {
586 led = buzz->leds[n]; 570 led = drv_data->leds[n];
587 buzz->leds[n] = NULL; 571 drv_data->leds[n] = NULL;
588 if (!led) 572 if (!led)
589 continue; 573 continue;
590 led_classdev_unregister(led); 574 led_classdev_unregister(led);
591 kfree(led); 575 kfree(led);
592 } 576 }
593 577
594 kfree(drv_data->extra);
595 drv_data->extra = NULL;
596 return ret; 578 return ret;
597} 579}
598 580
599static void sony_leds_remove(struct hid_device *hdev) 581static void sony_leds_remove(struct hid_device *hdev)
600{ 582{
601 struct sony_sc *drv_data; 583 struct sony_sc *drv_data;
602 struct buzz_extra *buzz;
603 struct led_classdev *led; 584 struct led_classdev *led;
604 int n; 585 int n;
605 586
606 drv_data = hid_get_drvdata(hdev); 587 drv_data = hid_get_drvdata(hdev);
607 BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER)); 588 BUG_ON(!(drv_data->quirks & BUZZ_CONTROLLER));
608 589
609 buzz = drv_data->extra;
610
611 for (n = 0; n < 4; n++) { 590 for (n = 0; n < 4; n++) {
612 led = buzz->leds[n]; 591 led = drv_data->leds[n];
613 buzz->leds[n] = NULL; 592 drv_data->leds[n] = NULL;
614 if (!led) 593 if (!led)
615 continue; 594 continue;
616 led_classdev_unregister(led); 595 led_classdev_unregister(led);
617 kfree(led); 596 kfree(led);
618 } 597 }
619
620 kfree(drv_data->extra);
621 drv_data->extra = NULL;
622} 598}
623 599
624#ifdef CONFIG_SONY_FF 600#ifdef CONFIG_SONY_FF