diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2016-07-13 12:05:59 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2016-08-05 07:39:15 -0400 |
commit | 1c817c83e8ccea5f710d3c0d38edcfd362654ba2 (patch) | |
tree | 0637aba7e0f10bc40b961f1ecccf87940f450eee | |
parent | 19b643300181ccf2bd83cd751283508b9ae179f5 (diff) |
HID: wacom: devres manage the shared data too
wacom_release_shared_data() and wacom_remove_shared_data() are moved up
so they can be referenced in wacom_add_shared_data().
There is no point in explicitly setting wacom_wac1->shared->type to 0 in
wacom_wireless_work() (plus this would give an oops).
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/wacom_sys.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 56d62e8a400b..d0f57647cd5e 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -567,6 +567,38 @@ static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev) | |||
567 | return NULL; | 567 | return NULL; |
568 | } | 568 | } |
569 | 569 | ||
570 | static void wacom_release_shared_data(struct kref *kref) | ||
571 | { | ||
572 | struct wacom_hdev_data *data = | ||
573 | container_of(kref, struct wacom_hdev_data, kref); | ||
574 | |||
575 | mutex_lock(&wacom_udev_list_lock); | ||
576 | list_del(&data->list); | ||
577 | mutex_unlock(&wacom_udev_list_lock); | ||
578 | |||
579 | kfree(data); | ||
580 | } | ||
581 | |||
582 | static void wacom_remove_shared_data(void *res) | ||
583 | { | ||
584 | struct wacom *wacom = res; | ||
585 | struct wacom_hdev_data *data; | ||
586 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
587 | |||
588 | if (wacom_wac->shared) { | ||
589 | data = container_of(wacom_wac->shared, struct wacom_hdev_data, | ||
590 | shared); | ||
591 | |||
592 | if (wacom_wac->shared->touch == wacom->hdev) | ||
593 | wacom_wac->shared->touch = NULL; | ||
594 | else if (wacom_wac->shared->pen == wacom->hdev) | ||
595 | wacom_wac->shared->pen = NULL; | ||
596 | |||
597 | kref_put(&data->kref, wacom_release_shared_data); | ||
598 | wacom_wac->shared = NULL; | ||
599 | } | ||
600 | } | ||
601 | |||
570 | static int wacom_add_shared_data(struct hid_device *hdev) | 602 | static int wacom_add_shared_data(struct hid_device *hdev) |
571 | { | 603 | { |
572 | struct wacom *wacom = hid_get_drvdata(hdev); | 604 | struct wacom *wacom = hid_get_drvdata(hdev); |
@@ -591,6 +623,13 @@ static int wacom_add_shared_data(struct hid_device *hdev) | |||
591 | 623 | ||
592 | wacom_wac->shared = &data->shared; | 624 | wacom_wac->shared = &data->shared; |
593 | 625 | ||
626 | retval = devm_add_action(&hdev->dev, wacom_remove_shared_data, wacom); | ||
627 | if (retval) { | ||
628 | mutex_unlock(&wacom_udev_list_lock); | ||
629 | wacom_remove_shared_data(wacom); | ||
630 | return retval; | ||
631 | } | ||
632 | |||
594 | if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) | 633 | if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) |
595 | wacom_wac->shared->touch = hdev; | 634 | wacom_wac->shared->touch = hdev; |
596 | else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN) | 635 | else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN) |
@@ -601,37 +640,6 @@ out: | |||
601 | return retval; | 640 | return retval; |
602 | } | 641 | } |
603 | 642 | ||
604 | static void wacom_release_shared_data(struct kref *kref) | ||
605 | { | ||
606 | struct wacom_hdev_data *data = | ||
607 | container_of(kref, struct wacom_hdev_data, kref); | ||
608 | |||
609 | mutex_lock(&wacom_udev_list_lock); | ||
610 | list_del(&data->list); | ||
611 | mutex_unlock(&wacom_udev_list_lock); | ||
612 | |||
613 | kfree(data); | ||
614 | } | ||
615 | |||
616 | static void wacom_remove_shared_data(struct wacom *wacom) | ||
617 | { | ||
618 | struct wacom_hdev_data *data; | ||
619 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
620 | |||
621 | if (wacom_wac->shared) { | ||
622 | data = container_of(wacom_wac->shared, struct wacom_hdev_data, | ||
623 | shared); | ||
624 | |||
625 | if (wacom_wac->shared->touch == wacom->hdev) | ||
626 | wacom_wac->shared->touch = NULL; | ||
627 | else if (wacom_wac->shared->pen == wacom->hdev) | ||
628 | wacom_wac->shared->pen = NULL; | ||
629 | |||
630 | kref_put(&data->kref, wacom_release_shared_data); | ||
631 | wacom_wac->shared = NULL; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | static int wacom_led_control(struct wacom *wacom) | 643 | static int wacom_led_control(struct wacom *wacom) |
636 | { | 644 | { |
637 | unsigned char *buf; | 645 | unsigned char *buf; |
@@ -1731,7 +1739,6 @@ fail_remote: | |||
1731 | fail_leds: | 1739 | fail_leds: |
1732 | fail_register_inputs: | 1740 | fail_register_inputs: |
1733 | fail_battery: | 1741 | fail_battery: |
1734 | wacom_remove_shared_data(wacom); | ||
1735 | fail_shared_data: | 1742 | fail_shared_data: |
1736 | fail_parsed: | 1743 | fail_parsed: |
1737 | fail_allocate_inputs: | 1744 | fail_allocate_inputs: |
@@ -1771,7 +1778,6 @@ static void wacom_wireless_work(struct work_struct *work) | |||
1771 | 1778 | ||
1772 | if (wacom_wac->pid == 0) { | 1779 | if (wacom_wac->pid == 0) { |
1773 | hid_info(wacom->hdev, "wireless tablet disconnected\n"); | 1780 | hid_info(wacom->hdev, "wireless tablet disconnected\n"); |
1774 | wacom_wac1->shared->type = 0; | ||
1775 | } else { | 1781 | } else { |
1776 | const struct hid_device_id *id = wacom_ids; | 1782 | const struct hid_device_id *id = wacom_ids; |
1777 | 1783 | ||
@@ -1912,7 +1918,6 @@ static void wacom_remove(struct hid_device *hdev) | |||
1912 | kobject_put(wacom->remote_dir); | 1918 | kobject_put(wacom->remote_dir); |
1913 | if (hdev->bus == BUS_BLUETOOTH) | 1919 | if (hdev->bus == BUS_BLUETOOTH) |
1914 | device_remove_file(&hdev->dev, &dev_attr_speed); | 1920 | device_remove_file(&hdev->dev, &dev_attr_speed); |
1915 | wacom_remove_shared_data(wacom); | ||
1916 | 1921 | ||
1917 | hid_set_drvdata(hdev, NULL); | 1922 | hid_set_drvdata(hdev, NULL); |
1918 | } | 1923 | } |