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

Reply via email to