aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2016-07-13 12:05:59 -0400
committerJiri Kosina <jkosina@suse.cz>2016-08-05 07:39:15 -0400
commit1c817c83e8ccea5f710d3c0d38edcfd362654ba2 (patch)
tree0637aba7e0f10bc40b961f1ecccf87940f450eee
parent19b643300181ccf2bd83cd751283508b9ae179f5 (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.c73
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
570static 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
582static 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
570static int wacom_add_shared_data(struct hid_device *hdev) 602static 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
604static 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
616static 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
635static int wacom_led_control(struct wacom *wacom) 643static int wacom_led_control(struct wacom *wacom)
636{ 644{
637 unsigned char *buf; 645 unsigned char *buf;
@@ -1731,7 +1739,6 @@ fail_remote:
1731fail_leds: 1739fail_leds:
1732fail_register_inputs: 1740fail_register_inputs:
1733fail_battery: 1741fail_battery:
1734 wacom_remove_shared_data(wacom);
1735fail_shared_data: 1742fail_shared_data:
1736fail_parsed: 1743fail_parsed:
1737fail_allocate_inputs: 1744fail_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}