From: Benjamin Tissoires <benjamin.tissoi...@redhat.com> This will be useful when each remote will be assigned its own input device. We won't need to unregister each input and sysfs and other elements one at a time.
Signed-off-by: Benjamin Tissoires <benjamin.tissoi...@redhat.com> Acked-by: Ping Cheng <pi...@wacom.com> Signed-off-by: Jiri Kosina <jkos...@suse.cz> [aaron.sko...@wacom.com: Imported into input-wacom repository (f9036bd)] Signed-off-by: Aaron Armstrong Skomra <aaron.sko...@wacom.com> [aaron.sko...@wacom.com: Backported from input-wacom repository (5457b33)] Signed-off-by: Aaron Armstrong Skomra <aaron.sko...@wacom.com> --- 2.6.38/wacom_sys.c | 49 ++++++++++++++++++++++++++++++++++--------------- 3.17/wacom_sys.c | 44 ++++++++++++++++++++++++++++---------------- 3.7/wacom_sys.c | 49 ++++++++++++++++++++++++++++++++++--------------- 3 files changed, 96 insertions(+), 46 deletions(-) diff --git a/2.6.38/wacom_sys.c b/2.6.38/wacom_sys.c index 85f08f2..5ce0210 100644 --- a/2.6.38/wacom_sys.c +++ b/2.6.38/wacom_sys.c @@ -1050,7 +1050,8 @@ static void wacom_devm_sysfs_group_release(struct device *dev, void *res) sysfs_remove_group(kobj, devres->group); } -static int wacom_devm_sysfs_create_group(struct wacom *wacom, +static int __wacom_devm_sysfs_create_group(struct wacom *wacom, + struct kobject *root, struct attribute_group *group) { struct wacom_sysfs_group_devres *devres; @@ -1063,7 +1064,7 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, return -ENOMEM; devres->group = group; - devres->root = &wacom->intf->dev.kobj; + devres->root = root; error = sysfs_create_group(devres->root, group); if (error) @@ -1074,6 +1075,13 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, return 0; } +static int wacom_devm_sysfs_create_group(struct wacom *wacom, + struct attribute_group *group) +{ + return __wacom_devm_sysfs_create_group(wacom, &wacom->intf->dev.kobj, + group); +} + static int wacom_initialize_leds(struct wacom *wacom) { int error; @@ -1281,10 +1289,11 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, int if (!remote->remote_group[index].name) return -ENOMEM; - error = sysfs_create_group(remote->remote_dir, - &remote->remote_group[index]); + error = __wacom_devm_sysfs_create_group(wacom, remote->remote_dir, + &remote->remote_group[index]); if (error) { + remote->remote_group[index].name = NULL; dev_err(&wacom->intf->dev, "cannot create sysfs group err: %d\n", error); return error; @@ -1293,15 +1302,6 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, int return 0; } -static void wacom_remote_destroy_attr_group(struct wacom *wacom, int i) -{ - struct wacom_remote *remote = wacom->remote; - - sysfs_remove_group(remote->remote_dir, &remote->remote_group[i]); - kfree((char *)remote->remote_group[i].name); - remote->remote_group[i].name = NULL; -} - static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char selector) { const size_t buf_size = 2; @@ -1329,11 +1329,19 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) u32 serial = remote->serial[index]; int i; - wacom_remote_destroy_attr_group(wacom, index); + if (remote->remote_group[index].name) + devres_release_group(&wacom->usbdev->dev, &remote->serial[index]); for (i = 0; i < WACOM_MAX_REMOTES; i++) { if (remote->serial[i] == serial) { remote->serial[i] = 0; + + /* Destroy the attribute group parts not + * covered by devres for this kernel. + */ + kfree((char *)remote->remote_group[i].name); + remote->remote_group[i].name = NULL; + wacom->led.select[i] = WACOM_STATUS_UNKNOWN; } } @@ -1343,6 +1351,7 @@ static int wacom_remote_create_one(struct wacom *wacom, u32 serial, unsigned int index) { struct wacom_remote *remote = wacom->remote; + struct device *dev = &wacom->usbdev->dev; int error, k; /* A remote can pair more than once with an EKR, @@ -1358,13 +1367,23 @@ static int wacom_remote_create_one(struct wacom *wacom, u32 serial, return 0; } + if (!devres_open_group(dev, &remote->serial[index], GFP_KERNEL)) + return -ENOMEM; + error = wacom_remote_create_attr_group(wacom, serial, index); if (error) - return error; + goto fail; remote->serial[index] = serial; + devres_close_group(dev, &remote->serial[index]); + return 0; + +fail: + devres_release_group(dev, &remote->serial[index]); + remote->serial[index] = 0; + return error; } static ssize_t wacom_store_unpair_remote(struct kobject *kobj, diff --git a/3.17/wacom_sys.c b/3.17/wacom_sys.c index 4c5c76b..3b2c71c 100644 --- a/3.17/wacom_sys.c +++ b/3.17/wacom_sys.c @@ -938,8 +938,9 @@ static void wacom_devm_sysfs_group_release(struct device *dev, void *res) sysfs_remove_group(kobj, devres->group); } -static int wacom_devm_sysfs_create_group(struct wacom *wacom, - struct attribute_group *group) +static int __wacom_devm_sysfs_create_group(struct wacom *wacom, + struct kobject *root, + struct attribute_group *group) { struct wacom_sysfs_group_devres *devres; int error; @@ -951,7 +952,7 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, return -ENOMEM; devres->group = group; - devres->root = &wacom->hdev->dev.kobj; + devres->root = root; error = sysfs_create_group(devres->root, group); if (error) @@ -962,6 +963,13 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, return 0; } +static int wacom_devm_sysfs_create_group(struct wacom *wacom, + struct attribute_group *group) +{ + return __wacom_devm_sysfs_create_group(wacom, &wacom->hdev->dev.kobj, + group); +} + static void wacom_led_groups_release(void *data) { struct wacom *wacom = data; @@ -1358,9 +1366,10 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, if (!remote->remote_group[index].name) return -ENOMEM; - error = sysfs_create_group(remote->remote_dir, - &remote->remote_group[index]); + error = __wacom_devm_sysfs_create_group(wacom, remote->remote_dir, + &remote->remote_group[index]); if (error) { + remote->remote_group[index].name = NULL; hid_err(wacom->hdev, "cannot create sysfs group err: %d\n", error); return error; @@ -1369,15 +1378,6 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, return 0; } -static void wacom_remote_destroy_attr_group(struct wacom *wacom, unsigned int i) -{ - struct wacom_remote *remote = wacom->remote; - - sysfs_remove_group(remote->remote_dir, &remote->remote_group[i]); - devm_kfree(&wacom->hdev->dev, (char *)remote->remote_group[i].name); - remote->remote_group[i].name = NULL; -} - static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char selector) { const size_t buf_size = 2; @@ -1977,11 +1977,13 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) u32 serial = remote->serial[index]; int i; - wacom_remote_destroy_attr_group(wacom, index); + if (remote->remote_group[index].name) + devres_release_group(&wacom->hdev->dev, &remote->serial[index]); for (i = 0; i < WACOM_MAX_REMOTES; i++) { if (remote->serial[i] == serial) { remote->serial[i] = 0; + remote->remote_group[i].name = NULL; wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN; } } @@ -1991,6 +1993,7 @@ static int wacom_remote_create_one(struct wacom *wacom, u32 serial, unsigned int index) { struct wacom_remote *remote = wacom->remote; + struct device *dev = &wacom->hdev->dev; int error, k; /* A remote can pair more than once with an EKR, @@ -2006,13 +2009,22 @@ static int wacom_remote_create_one(struct wacom *wacom, u32 serial, return 0; } + if (!devres_open_group(dev, &remote->serial[index], GFP_KERNEL)) + return -ENOMEM; + error = wacom_remote_create_attr_group(wacom, serial, index); if (error) - return error; + goto fail; remote->serial[index] = serial; + devres_close_group(dev, &remote->serial[index]); return 0; + +fail: + devres_release_group(dev, &remote->serial[index]); + remote->serial[index] = 0; + return error; } static void wacom_remote_work(struct work_struct *work) diff --git a/3.7/wacom_sys.c b/3.7/wacom_sys.c index 453ddaa..ef241c9 100644 --- a/3.7/wacom_sys.c +++ b/3.7/wacom_sys.c @@ -1049,7 +1049,8 @@ static void wacom_devm_sysfs_group_release(struct device *dev, void *res) sysfs_remove_group(kobj, devres->group); } -static int wacom_devm_sysfs_create_group(struct wacom *wacom, +static int __wacom_devm_sysfs_create_group(struct wacom *wacom, + struct kobject *root, struct attribute_group *group) { struct wacom_sysfs_group_devres *devres; @@ -1062,7 +1063,7 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, return -ENOMEM; devres->group = group; - devres->root = &wacom->intf->dev.kobj; + devres->root = root; error = sysfs_create_group(devres->root, group); if (error) @@ -1073,6 +1074,13 @@ static int wacom_devm_sysfs_create_group(struct wacom *wacom, return 0; } +static int wacom_devm_sysfs_create_group(struct wacom *wacom, + struct attribute_group *group) +{ + return __wacom_devm_sysfs_create_group(wacom, &wacom->intf->dev.kobj, + group); +} + static int wacom_initialize_leds(struct wacom *wacom) { int error; @@ -1274,9 +1282,10 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, int if (!remote->remote_group[index].name) return -ENOMEM; - error = sysfs_create_group(remote->remote_dir, - &remote->remote_group[index]); + error = __wacom_devm_sysfs_create_group(wacom, remote->remote_dir, + &remote->remote_group[index]); if (error) { + remote->remote_group[index].name = NULL; dev_err(&wacom->intf->dev, "cannot create sysfs group err: %d\n", error); return error; @@ -1285,15 +1294,6 @@ static int wacom_remote_create_attr_group(struct wacom *wacom, __u32 serial, int return 0; } -static void wacom_remote_destroy_attr_group(struct wacom *wacom, int i) -{ - struct wacom_remote *remote = wacom->remote; - - sysfs_remove_group(remote->remote_dir, &remote->remote_group[i]); - kfree((char *)remote->remote_group[i].name); - remote->remote_group[i].name = NULL; -} - static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char selector) { const size_t buf_size = 2; @@ -1321,11 +1321,19 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) u32 serial = remote->serial[index]; int i; - wacom_remote_destroy_attr_group(wacom, index); + if (remote->remote_group[index].name) + devres_release_group(&wacom->usbdev->dev, &remote->serial[index]); for (i = 0; i < WACOM_MAX_REMOTES; i++) { if (remote->serial[i] == serial) { remote->serial[i] = 0; + + /* Destroy the attribute group parts not + * covered by devres for this kernel. + */ + kfree((char *)remote->remote_group[i].name); + remote->remote_group[i].name = NULL; + wacom->led.select[i] = WACOM_STATUS_UNKNOWN; } } @@ -1335,6 +1343,7 @@ static int wacom_remote_create_one(struct wacom *wacom, u32 serial, unsigned int index) { struct wacom_remote *remote = wacom->remote; + struct device *dev = &wacom->usbdev->dev; int error, k; /* A remote can pair more than once with an EKR, @@ -1350,13 +1359,23 @@ static int wacom_remote_create_one(struct wacom *wacom, u32 serial, return 0; } + if (!devres_open_group(dev, &remote->serial[index], GFP_KERNEL)) + return -ENOMEM; + error = wacom_remote_create_attr_group(wacom, serial, index); if (error) - return error; + goto fail; remote->serial[index] = serial; + devres_close_group(dev, &remote->serial[index]); + return 0; + +fail: + devres_release_group(dev, &remote->serial[index]); + remote->serial[index] = 0; + return error; } static ssize_t wacom_store_unpair_remote(struct kobject *kobj, -- 2.7.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ Linuxwacom-devel mailing list Linuxwacom-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel