gpio: sysfs: fix gpio-chip device-attribute leak
authorJohan Hovold <johan@kernel.org>
Tue, 13 Jan 2015 12:00:04 +0000 (13:00 +0100)
committerBen Hutchings <ben@decadent.org.uk>
Fri, 20 Feb 2015 00:49:37 +0000 (00:49 +0000)
commit 121b6a79955a3a3fd7bbb9b8cb88d5b9dad6283d upstream.

The gpio-chip device attributes were never destroyed when the device was
removed.

Fix by using device_create_with_groups() to create the device attributes
of the chip class device.

Note that this also fixes the attribute-creation race with userspace.

Fixes: d8f388d8dc8d ("gpio: sysfs interface")
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/gpio/gpiolib.c

index 503104a..f4e4363 100644 (file)
@@ -587,16 +587,13 @@ static ssize_t chip_ngpio_show(struct device *dev,
 }
 static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL);
 
-static const struct attribute *gpiochip_attrs[] = {
+static struct attribute *gpiochip_attrs[] = {
        &dev_attr_base.attr,
        &dev_attr_label.attr,
        &dev_attr_ngpio.attr,
        NULL,
 };
-
-static const struct attribute_group gpiochip_attr_group = {
-       .attrs = (struct attribute **) gpiochip_attrs,
-};
+ATTRIBUTE_GROUPS(gpiochip);
 
 /*
  * /sys/class/gpio/export ... write-only
@@ -918,13 +915,13 @@ static int gpiochip_export(struct gpio_chip *chip)
 
        /* use chip->base for the ID; it's already known to be unique */
        mutex_lock(&sysfs_lock);
-       dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,
-                               "gpiochip%d", chip->base);
-       if (!IS_ERR(dev)) {
-               status = sysfs_create_group(&dev->kobj,
-                               &gpiochip_attr_group);
-       } else
+       dev = device_create_with_groups(&gpio_class, chip->dev, MKDEV(0, 0),
+                                       chip, gpiochip_groups,
+                                       "gpiochip%d", chip->base);
+       if (IS_ERR(dev))
                status = PTR_ERR(dev);
+       else
+               status = 0;
        chip->exported = (status == 0);
        mutex_unlock(&sysfs_lock);