diff options
| -rw-r--r-- | drivers/hid/hid-sony.c | 58 |
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 | ||
| 225 | struct sony_sc { | 225 | struct 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 | |||
| 238 | struct buzz_extra { | ||
| 239 | int led_state; | ||
| 240 | struct led_classdev *leds[4]; | ||
| 241 | }; | 237 | }; |
| 242 | 238 | ||
| 243 | static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, | 239 | static __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) | |||
| 528 | static int sony_leds_init(struct hid_device *hdev) | 520 | static 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 | ||
| 584 | error_leds: | 568 | error_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 | ||
| 599 | static void sony_leds_remove(struct hid_device *hdev) | 581 | static 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 |
