aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2016-07-13 12:05:56 -0400
committerJiri Kosina <jkosina@suse.cz>2016-08-05 07:39:14 -0400
commit2df68a8864883ff006b76f50dfc32fd230247ef9 (patch)
treeb91765a2e79e34a96a88f86113f50946f1082f4b
parent84dfbd7f2a58c8c79ba7947159fc5f2c521348f6 (diff)
HID: wacom: convert LEDs to devres
Use our own wacom_devm_sysfs_create_group() as there is currently no generic one. It has been requested at least twice [1][2] but has been always rejected. However, in the Wacom case, for the wirelessly connected devices, we need to be able to release the created sysfs files without removing the parent kobject. [1] https://patchwork.kernel.org/patch/7526551/ [2] https://lkml.org/lkml/2013/3/14/728 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.h1
-rw-r--r--drivers/hid/wacom_sys.c95
2 files changed, 45 insertions, 51 deletions
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 6f5555fa1eab..bcfeb517221e 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -124,7 +124,6 @@ struct wacom {
124 u8 hlv; /* status led brightness button pressed (1..127) */ 124 u8 hlv; /* status led brightness button pressed (1..127) */
125 u8 img_lum; /* OLED matrix display brightness */ 125 u8 img_lum; /* OLED matrix display brightness */
126 } led; 126 } led;
127 bool led_initialized;
128 struct power_supply *battery; 127 struct power_supply *battery;
129 struct power_supply *ac; 128 struct power_supply *ac;
130 struct power_supply_desc battery_desc; 129 struct power_supply_desc battery_desc;
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 08f6d1f29c73..c08a7522fdb9 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -909,6 +909,45 @@ static struct attribute_group intuos5_led_attr_group = {
909 .attrs = intuos5_led_attrs, 909 .attrs = intuos5_led_attrs,
910}; 910};
911 911
912struct wacom_sysfs_group_devres {
913 struct attribute_group *group;
914 struct kobject *root;
915};
916
917static void wacom_devm_sysfs_group_release(struct device *dev, void *res)
918{
919 struct wacom_sysfs_group_devres *devres = res;
920 struct kobject *kobj = devres->root;
921
922 dev_dbg(dev, "%s: dropping reference to %s\n",
923 __func__, devres->group->name);
924 sysfs_remove_group(kobj, devres->group);
925}
926
927static int wacom_devm_sysfs_create_group(struct wacom *wacom,
928 struct attribute_group *group)
929{
930 struct wacom_sysfs_group_devres *devres;
931 int error;
932
933 devres = devres_alloc(wacom_devm_sysfs_group_release,
934 sizeof(struct wacom_sysfs_group_devres),
935 GFP_KERNEL);
936 if (!devres)
937 return -ENOMEM;
938
939 devres->group = group;
940 devres->root = &wacom->hdev->dev.kobj;
941
942 error = sysfs_create_group(devres->root, group);
943 if (error)
944 return error;
945
946 devres_add(&wacom->hdev->dev, devres);
947
948 return 0;
949}
950
912static int wacom_initialize_leds(struct wacom *wacom) 951static int wacom_initialize_leds(struct wacom *wacom)
913{ 952{
914 int error; 953 int error;
@@ -927,8 +966,8 @@ static int wacom_initialize_leds(struct wacom *wacom)
927 wacom->led.llv = 10; 966 wacom->led.llv = 10;
928 wacom->led.hlv = 20; 967 wacom->led.hlv = 20;
929 wacom->led.img_lum = 10; 968 wacom->led.img_lum = 10;
930 error = sysfs_create_group(&wacom->hdev->dev.kobj, 969 error = wacom_devm_sysfs_create_group(wacom,
931 &intuos4_led_attr_group); 970 &intuos4_led_attr_group);
932 break; 971 break;
933 972
934 case WACOM_24HD: 973 case WACOM_24HD:
@@ -939,8 +978,8 @@ static int wacom_initialize_leds(struct wacom *wacom)
939 wacom->led.hlv = 0; 978 wacom->led.hlv = 0;
940 wacom->led.img_lum = 0; 979 wacom->led.img_lum = 0;
941 980
942 error = sysfs_create_group(&wacom->hdev->dev.kobj, 981 error = wacom_devm_sysfs_create_group(wacom,
943 &cintiq_led_attr_group); 982 &cintiq_led_attr_group);
944 break; 983 break;
945 984
946 case INTUOS5S: 985 case INTUOS5S:
@@ -955,8 +994,8 @@ static int wacom_initialize_leds(struct wacom *wacom)
955 wacom->led.hlv = 0; 994 wacom->led.hlv = 0;
956 wacom->led.img_lum = 0; 995 wacom->led.img_lum = 0;
957 996
958 error = sysfs_create_group(&wacom->hdev->dev.kobj, 997 error = wacom_devm_sysfs_create_group(wacom,
959 &intuos5_led_attr_group); 998 &intuos5_led_attr_group);
960 break; 999 break;
961 1000
962 default: 1001 default:
@@ -969,48 +1008,10 @@ static int wacom_initialize_leds(struct wacom *wacom)
969 return error; 1008 return error;
970 } 1009 }
971 wacom_led_control(wacom); 1010 wacom_led_control(wacom);
972 wacom->led_initialized = true;
973 1011
974 return 0; 1012 return 0;
975} 1013}
976 1014
977static void wacom_destroy_leds(struct wacom *wacom)
978{
979 if (!wacom->led_initialized)
980 return;
981
982 if (!(wacom->wacom_wac.features.device_type & WACOM_DEVICETYPE_PAD))
983 return;
984
985 wacom->led_initialized = false;
986
987 switch (wacom->wacom_wac.features.type) {
988 case INTUOS4S:
989 case INTUOS4:
990 case INTUOS4WL:
991 case INTUOS4L:
992 sysfs_remove_group(&wacom->hdev->dev.kobj,
993 &intuos4_led_attr_group);
994 break;
995
996 case WACOM_24HD:
997 case WACOM_21UX2:
998 sysfs_remove_group(&wacom->hdev->dev.kobj,
999 &cintiq_led_attr_group);
1000 break;
1001
1002 case INTUOS5S:
1003 case INTUOS5:
1004 case INTUOS5L:
1005 case INTUOSPS:
1006 case INTUOSPM:
1007 case INTUOSPL:
1008 sysfs_remove_group(&wacom->hdev->dev.kobj,
1009 &intuos5_led_attr_group);
1010 break;
1011 }
1012}
1013
1014static enum power_supply_property wacom_battery_props[] = { 1015static enum power_supply_property wacom_battery_props[] = {
1015 POWER_SUPPLY_PROP_PRESENT, 1016 POWER_SUPPLY_PROP_PRESENT,
1016 POWER_SUPPLY_PROP_STATUS, 1017 POWER_SUPPLY_PROP_STATUS,
@@ -1729,7 +1730,6 @@ fail_quirks:
1729fail_hw_start: 1730fail_hw_start:
1730 kobject_put(wacom->remote_dir); 1731 kobject_put(wacom->remote_dir);
1731fail_remote: 1732fail_remote:
1732 wacom_destroy_leds(wacom);
1733fail_leds: 1733fail_leds:
1734fail_register_inputs: 1734fail_register_inputs:
1735fail_battery: 1735fail_battery:
@@ -1763,14 +1763,12 @@ static void wacom_wireless_work(struct work_struct *work)
1763 hdev1 = usb_get_intfdata(usbdev->config->interface[1]); 1763 hdev1 = usb_get_intfdata(usbdev->config->interface[1]);
1764 wacom1 = hid_get_drvdata(hdev1); 1764 wacom1 = hid_get_drvdata(hdev1);
1765 wacom_wac1 = &(wacom1->wacom_wac); 1765 wacom_wac1 = &(wacom1->wacom_wac);
1766 wacom_destroy_leds(wacom1);
1767 wacom_release_resources(wacom1); 1766 wacom_release_resources(wacom1);
1768 1767
1769 /* Touch interface */ 1768 /* Touch interface */
1770 hdev2 = usb_get_intfdata(usbdev->config->interface[2]); 1769 hdev2 = usb_get_intfdata(usbdev->config->interface[2]);
1771 wacom2 = hid_get_drvdata(hdev2); 1770 wacom2 = hid_get_drvdata(hdev2);
1772 wacom_wac2 = &(wacom2->wacom_wac); 1771 wacom_wac2 = &(wacom2->wacom_wac);
1773 wacom_destroy_leds(wacom2);
1774 wacom_release_resources(wacom2); 1772 wacom_release_resources(wacom2);
1775 1773
1776 if (wacom_wac->pid == 0) { 1774 if (wacom_wac->pid == 0) {
@@ -1825,9 +1823,7 @@ static void wacom_wireless_work(struct work_struct *work)
1825 return; 1823 return;
1826 1824
1827fail: 1825fail:
1828 wacom_destroy_leds(wacom1);
1829 wacom_release_resources(wacom1); 1826 wacom_release_resources(wacom1);
1830 wacom_destroy_leds(wacom2);
1831 wacom_release_resources(wacom2); 1827 wacom_release_resources(wacom2);
1832 return; 1828 return;
1833} 1829}
@@ -1917,7 +1913,6 @@ static void wacom_remove(struct hid_device *hdev)
1917 cancel_work_sync(&wacom->wireless_work); 1913 cancel_work_sync(&wacom->wireless_work);
1918 cancel_work_sync(&wacom->battery_work); 1914 cancel_work_sync(&wacom->battery_work);
1919 kobject_put(wacom->remote_dir); 1915 kobject_put(wacom->remote_dir);
1920 wacom_destroy_leds(wacom);
1921 if (hdev->bus == BUS_BLUETOOTH) 1916 if (hdev->bus == BUS_BLUETOOTH)
1922 device_remove_file(&hdev->dev, &dev_attr_speed); 1917 device_remove_file(&hdev->dev, &dev_attr_speed);
1923 wacom_remove_shared_data(wacom); 1918 wacom_remove_shared_data(wacom);