@@ -550,7 +550,6 @@ static const struct class gpio_class = {
int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
{
struct gpio_device *gdev;
- struct gpiod_data *data;
struct device *dev;
int status;
@@ -574,24 +573,25 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
gdev = desc->gdev;
- mutex_lock(&sysfs_lock);
+ guard(mutex)(&sysfs_lock);
/* check if chip is being removed */
if (!gdev->mockdev) {
status = -ENODEV;
- goto err_unlock;
+ goto err_clear_bit;
}
if (!test_bit(FLAG_REQUESTED, &desc->flags)) {
gpiod_dbg(desc, "%s: unavailable (not requested)\n", __func__);
status = -EPERM;
- goto err_unlock;
+ goto err_clear_bit;
}
- data = kzalloc(sizeof(*data), GFP_KERNEL);
+ struct gpiod_data *data __free(kfree) = kzalloc(sizeof(*data),
+ GFP_KERNEL);
if (!data) {
status = -ENOMEM;
- goto err_unlock;
+ goto err_clear_bit;
}
data->desc = desc;
@@ -606,16 +606,13 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
"gpio%u", desc_to_gpio(desc));
if (IS_ERR(dev)) {
status = PTR_ERR(dev);
- goto err_free_data;
+ goto err_clear_bit;
}
- mutex_unlock(&sysfs_lock);
+ data = NULL;
return 0;
-err_free_data:
- kfree(data);
-err_unlock:
- mutex_unlock(&sysfs_lock);
+err_clear_bit:
clear_bit(FLAG_EXPORT, &desc->flags);
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
return status;
@@ -679,36 +676,28 @@ void gpiod_unexport(struct gpio_desc *desc)
return;
}
- mutex_lock(&sysfs_lock);
+ scoped_guard(mutex, &sysfs_lock) {
+ if (!test_bit(FLAG_EXPORT, &desc->flags))
+ return;
- if (!test_bit(FLAG_EXPORT, &desc->flags))
- goto err_unlock;
+ dev = class_find_device(&gpio_class, NULL, desc, match_export);
+ if (!dev)
+ return;
- dev = class_find_device(&gpio_class, NULL, desc, match_export);
- if (!dev)
- goto err_unlock;
+ data = dev_get_drvdata(dev);
+ clear_bit(FLAG_EXPORT, &desc->flags);
+ device_unregister(dev);
- data = dev_get_drvdata(dev);
-
- clear_bit(FLAG_EXPORT, &desc->flags);
-
- device_unregister(dev);
-
- /*
- * Release irq after deregistration to prevent race with edge_store.
- */
- if (data->irq_flags)
- gpio_sysfs_free_irq(dev);
-
- mutex_unlock(&sysfs_lock);
+ /*
+ * Release irq after deregistration to prevent race with
+ * edge_store.
+ */
+ if (data->irq_flags)
+ gpio_sysfs_free_irq(dev);
+ }
put_device(dev);
kfree(data);
-
- return;
-
-err_unlock:
- mutex_unlock(&sysfs_lock);
}
EXPORT_SYMBOL_GPL(gpiod_unexport);
@@ -749,9 +738,8 @@ int gpiochip_sysfs_register(struct gpio_device *gdev)
if (IS_ERR(dev))
return PTR_ERR(dev);
- mutex_lock(&sysfs_lock);
+ guard(mutex)(&sysfs_lock);
gdev->mockdev = dev;
- mutex_unlock(&sysfs_lock);
return 0;
}