diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-29 20:21:56 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-29 20:21:56 +0300 |
commit | f97e18a3f2fb78a4ed0d25e427535d9f853b9e9e (patch) | |
tree | 6693da811ca60834111b1143e856a088f7bee388 /drivers/gpio/gpio-sim.c | |
parent | 41e97d7acf5a45f19ade9139ca178bf9e8e236bb (diff) | |
parent | 3d0957b07e27abd3237b1fe0c7f06485ba80852f (diff) | |
download | linux-f97e18a3f2fb78a4ed0d25e427535d9f853b9e9e.tar.xz |
Merge tag 'gpio-updates-for-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio updates from Bartosz Golaszewski:
"We have a lot of code refactoring using common helpers and ended up
removing more lines then we're adding this release cycle.
Nothing really stands out, just small updates all over the place.
Core GPIOLIB updates:
- wake-up poll() in user-space on device unbind
- improve fwnode usage
- interrupt domain handling improvements
- correctly handle the ngpios property in gpio-mmio
Driver cleanups:
- remove unneeded calls to platform_set_drvdata() all around the
place
- remove unneeded of_match_ptr() expansions whenever a driver depends
on CONFIG_OF
- remove redundant calls to dev_err_probe() from gpio-omap and
gpio-davinci
Driver improvements:
- use autopointers and guards from cleanup.h in gpio-sim
- shrink code in gpio-sim using some common helpers
- convert the idio family of drivers to using gpio-regmap
- convert gpio-ws16c48 to using gpio-regmap
- use devres to simplify code in gpio-pisosr and gpio-mxc
- update gpio-sifive: support IRQ wake, improve interrupt handling,
allow building as module
- make gpio-ge and gpio-bcm-kona OF-independent (plus some minor
tweaks)
- add support for new models in gpio-pca953x and gpio-ds4520
- add runtime PM support to gpio-mxc
- fix a build warning in gpio-mxs
- add support for adding pin ranges to gpio-mlxbf3
- add counter/timer support to gpio-104-dio-48e
- switch to dynamic GPIO base allocation in gpio-vf610
- minor oneliners here and there
Device-tree bindings updates:
- enable the gpio-line-names property in snps,dw-apb and STMPE GPIO
- document new models in fsl-imx-gpio, ds4520 and pca95xx
- convert the bindings for brcm,kona-gpio to YAML"
* tag 'gpio-updates-for-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (94 commits)
gpio: pca953x: add support for TCA9538
dt-bindings: gpio: pca95xx: document new tca9538 chip
gpio: pca953x: Use i2c_get_match_data()
gpio: mlxbf3: use capital "OR" for multiple licenses in SPDX
gpio: pcf857x: Extend match data support for OF tables
gpio: vf610: switch to dynamic allocat GPIO base
gpiolib: provide and use gpiod_line_state_notify()
gpio: cdev: wake up lineevent poll() on device unbind
gpio: cdev: wake up linereq poll() on device unbind
gpio: cdev: wake up chardev poll() on device unbind
gpiolib: add a second blocking notifier to struct gpio_device
gpio: cdev: open-code to_gpio_chardev_data()
gpiolib: rename the gpio_device notifier
gpio: mlxbf3: Support add_pin_ranges()
gpio: mxc: Use helper function devm_clk_get_optional_enabled()
gpio: pca9570: fix kerneldoc
gpio: sim: simplify code with cleanup helpers
gpio: sim: replace memmove() + strstrip() with skip_spaces() + strim()
gpio: sim: simplify gpio_sim_device_config_live_store()
gpio: mxc: release the parent IRQ in runtime suspend
...
Diffstat (limited to 'drivers/gpio/gpio-sim.c')
-rw-r--r-- | drivers/gpio/gpio-sim.c | 285 |
1 files changed, 94 insertions, 191 deletions
diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index 533d81572579..271db3639a78 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -8,6 +8,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/bitmap.h> +#include <linux/cleanup.h> #include <linux/completion.h> #include <linux/configfs.h> #include <linux/device.h> @@ -68,7 +69,7 @@ static int gpio_sim_apply_pull(struct gpio_sim_chip *chip, gc = &chip->gc; desc = &gc->gpiodev->descs[offset]; - mutex_lock(&chip->lock); + guard(mutex)(&chip->lock); if (test_bit(FLAG_REQUESTED, &desc->flags) && !test_bit(FLAG_IS_OUT, &desc->flags)) { @@ -104,29 +105,24 @@ set_value: set_pull: __assign_bit(offset, chip->pull_map, value); - mutex_unlock(&chip->lock); return 0; } static int gpio_sim_get(struct gpio_chip *gc, unsigned int offset) { struct gpio_sim_chip *chip = gpiochip_get_data(gc); - int ret; - mutex_lock(&chip->lock); - ret = !!test_bit(offset, chip->value_map); - mutex_unlock(&chip->lock); + guard(mutex)(&chip->lock); - return ret; + return !!test_bit(offset, chip->value_map); } static void gpio_sim_set(struct gpio_chip *gc, unsigned int offset, int value) { struct gpio_sim_chip *chip = gpiochip_get_data(gc); - mutex_lock(&chip->lock); - __assign_bit(offset, chip->value_map, value); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + __assign_bit(offset, chip->value_map, value); } static int gpio_sim_get_multiple(struct gpio_chip *gc, @@ -134,9 +130,8 @@ static int gpio_sim_get_multiple(struct gpio_chip *gc, { struct gpio_sim_chip *chip = gpiochip_get_data(gc); - mutex_lock(&chip->lock); - bitmap_replace(bits, bits, chip->value_map, mask, gc->ngpio); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + bitmap_replace(bits, bits, chip->value_map, mask, gc->ngpio); return 0; } @@ -146,9 +141,9 @@ static void gpio_sim_set_multiple(struct gpio_chip *gc, { struct gpio_sim_chip *chip = gpiochip_get_data(gc); - mutex_lock(&chip->lock); - bitmap_replace(chip->value_map, chip->value_map, bits, mask, gc->ngpio); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + bitmap_replace(chip->value_map, chip->value_map, bits, mask, + gc->ngpio); } static int gpio_sim_direction_output(struct gpio_chip *gc, @@ -156,10 +151,10 @@ static int gpio_sim_direction_output(struct gpio_chip *gc, { struct gpio_sim_chip *chip = gpiochip_get_data(gc); - mutex_lock(&chip->lock); - __clear_bit(offset, chip->direction_map); - __assign_bit(offset, chip->value_map, value); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) { + __clear_bit(offset, chip->direction_map); + __assign_bit(offset, chip->value_map, value); + } return 0; } @@ -168,9 +163,8 @@ static int gpio_sim_direction_input(struct gpio_chip *gc, unsigned int offset) { struct gpio_sim_chip *chip = gpiochip_get_data(gc); - mutex_lock(&chip->lock); - __set_bit(offset, chip->direction_map); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + __set_bit(offset, chip->direction_map); return 0; } @@ -180,9 +174,8 @@ static int gpio_sim_get_direction(struct gpio_chip *gc, unsigned int offset) struct gpio_sim_chip *chip = gpiochip_get_data(gc); int direction; - mutex_lock(&chip->lock); - direction = !!test_bit(offset, chip->direction_map); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + direction = !!test_bit(offset, chip->direction_map); return direction ? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT; } @@ -215,9 +208,9 @@ static void gpio_sim_free(struct gpio_chip *gc, unsigned int offset) { struct gpio_sim_chip *chip = gpiochip_get_data(gc); - mutex_lock(&chip->lock); - __assign_bit(offset, chip->value_map, !!test_bit(offset, chip->pull_map)); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + __assign_bit(offset, chip->value_map, + !!test_bit(offset, chip->pull_map)); } static ssize_t gpio_sim_sysfs_val_show(struct device *dev, @@ -227,9 +220,8 @@ static ssize_t gpio_sim_sysfs_val_show(struct device *dev, struct gpio_sim_chip *chip = dev_get_drvdata(dev); int val; - mutex_lock(&chip->lock); - val = !!test_bit(line_attr->offset, chip->value_map); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + val = !!test_bit(line_attr->offset, chip->value_map); return sysfs_emit(buf, "%d\n", val); } @@ -258,9 +250,8 @@ static ssize_t gpio_sim_sysfs_pull_show(struct device *dev, struct gpio_sim_chip *chip = dev_get_drvdata(dev); int pull; - mutex_lock(&chip->lock); - pull = !!test_bit(line_attr->offset, chip->pull_map); - mutex_unlock(&chip->lock); + scoped_guard(mutex, &chip->lock) + pull = !!test_bit(line_attr->offset, chip->pull_map); return sysfs_emit(buf, "%s\n", gpio_sim_sysfs_pull_strings[pull]); } @@ -502,7 +493,7 @@ struct gpio_sim_device { * This structure however can be modified by callbacks of different * attributes so we need another lock. * - * We use this lock fo protecting all data structures owned by this + * We use this lock for protecting all data structures owned by this * object too. */ struct mutex lock; @@ -656,16 +647,13 @@ static bool gpio_sim_device_is_live_unlocked(struct gpio_sim_device *dev) static char *gpio_sim_strdup_trimmed(const char *str, size_t count) { - char *dup, *trimmed; + char *trimmed; - dup = kstrndup(str, count, GFP_KERNEL); - if (!dup) + trimmed = kstrndup(skip_spaces(str), count, GFP_KERNEL); + if (!trimmed) return NULL; - trimmed = strstrip(dup); - memmove(dup, trimmed, strlen(trimmed) + 1); - - return dup; + return strim(trimmed); } static ssize_t gpio_sim_device_config_dev_name_show(struct config_item *item, @@ -673,17 +661,14 @@ static ssize_t gpio_sim_device_config_dev_name_show(struct config_item *item, { struct gpio_sim_device *dev = to_gpio_sim_device(item); struct platform_device *pdev; - int ret; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); + pdev = dev->pdev; if (pdev) - ret = sprintf(page, "%s\n", dev_name(&pdev->dev)); - else - ret = sprintf(page, "gpio-sim.%d\n", dev->id); - mutex_unlock(&dev->lock); + return sprintf(page, "%s\n", dev_name(&pdev->dev)); - return ret; + return sprintf(page, "gpio-sim.%d\n", dev->id); } CONFIGFS_ATTR_RO(gpio_sim_device_config_, dev_name); @@ -694,9 +679,8 @@ gpio_sim_device_config_live_show(struct config_item *item, char *page) struct gpio_sim_device *dev = to_gpio_sim_device(item); bool live; - mutex_lock(&dev->lock); - live = gpio_sim_device_is_live_unlocked(dev); - mutex_unlock(&dev->lock); + scoped_guard(mutex, &dev->lock) + live = gpio_sim_device_is_live_unlocked(dev); return sprintf(page, "%c\n", live ? '1' : '0'); } @@ -851,8 +835,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, { struct property_entry properties[GPIO_SIM_PROP_MAX]; unsigned int prop_idx = 0, line_names_size = 0; - struct fwnode_handle *swnode; - char **line_names; + char **line_names __free(kfree) = NULL; memset(properties, 0, sizeof(properties)); @@ -871,9 +854,7 @@ gpio_sim_make_bank_swnode(struct gpio_sim_bank *bank, "gpio-line-names", line_names, line_names_size); - swnode = fwnode_create_software_node(properties, parent); - kfree(line_names); - return swnode; + return fwnode_create_software_node(properties, parent); } static void gpio_sim_remove_swnode_recursive(struct fwnode_handle *swnode) @@ -998,18 +979,15 @@ gpio_sim_device_config_live_store(struct config_item *item, if (ret) return ret; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if ((!live && !gpio_sim_device_is_live_unlocked(dev)) || - (live && gpio_sim_device_is_live_unlocked(dev))) + if (live == gpio_sim_device_is_live_unlocked(dev)) ret = -EPERM; else if (live) ret = gpio_sim_device_activate_unlocked(dev); else gpio_sim_device_deactivate_unlocked(dev); - mutex_unlock(&dev->lock); - return ret ?: count; } @@ -1046,17 +1024,14 @@ static ssize_t gpio_sim_bank_config_chip_name_show(struct config_item *item, struct gpio_sim_bank *bank = to_gpio_sim_bank(item); struct gpio_sim_device *dev = gpio_sim_bank_get_device(bank); struct gpio_sim_chip_name_ctx ctx = { bank->swnode, page }; - int ret; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) - ret = device_for_each_child(&dev->pdev->dev, &ctx, - gpio_sim_emit_chip_name); - else - ret = sprintf(page, "none\n"); - mutex_unlock(&dev->lock); + return device_for_each_child(&dev->pdev->dev, &ctx, + gpio_sim_emit_chip_name); - return ret; + return sprintf(page, "none\n"); } CONFIGFS_ATTR_RO(gpio_sim_bank_config_, chip_name); @@ -1066,13 +1041,10 @@ gpio_sim_bank_config_label_show(struct config_item *item, char *page) { struct gpio_sim_bank *bank = to_gpio_sim_bank(item); struct gpio_sim_device *dev = gpio_sim_bank_get_device(bank); - int ret; - mutex_lock(&dev->lock); - ret = sprintf(page, "%s\n", bank->label ?: ""); - mutex_unlock(&dev->lock); + guard(mutex)(&dev->lock); - return ret; + return sprintf(page, "%s\n", bank->label ?: ""); } static ssize_t gpio_sim_bank_config_label_store(struct config_item *item, @@ -1082,23 +1054,18 @@ static ssize_t gpio_sim_bank_config_label_store(struct config_item *item, struct gpio_sim_device *dev = gpio_sim_bank_get_device(bank); char *trimmed; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) { - mutex_unlock(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) return -EBUSY; - } trimmed = gpio_sim_strdup_trimmed(page, count); - if (!trimmed) { - mutex_unlock(&dev->lock); + if (!trimmed) return -ENOMEM; - } kfree(bank->label); bank->label = trimmed; - mutex_unlock(&dev->lock); return count; } @@ -1109,13 +1076,10 @@ gpio_sim_bank_config_num_lines_show(struct config_item *item, char *page) { struct gpio_sim_bank *bank = to_gpio_sim_bank(item); struct gpio_sim_device *dev = gpio_sim_bank_get_device(bank); - int ret; - mutex_lock(&dev->lock); - ret = sprintf(page, "%u\n", bank->num_lines); - mutex_unlock(&dev->lock); + guard(mutex)(&dev->lock); - return ret; + return sprintf(page, "%u\n", bank->num_lines); } static ssize_t @@ -1134,16 +1098,13 @@ gpio_sim_bank_config_num_lines_store(struct config_item *item, if (num_lines == 0) return -EINVAL; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) { - mutex_unlock(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) return -EBUSY; - } bank->num_lines = num_lines; - mutex_unlock(&dev->lock); return count; } @@ -1161,13 +1122,10 @@ gpio_sim_line_config_name_show(struct config_item *item, char *page) { struct gpio_sim_line *line = to_gpio_sim_line(item); struct gpio_sim_device *dev = gpio_sim_line_get_device(line); - int ret; - mutex_lock(&dev->lock); - ret = sprintf(page, "%s\n", line->name ?: ""); - mutex_unlock(&dev->lock); + guard(mutex)(&dev->lock); - return ret; + return sprintf(page, "%s\n", line->name ?: ""); } static ssize_t gpio_sim_line_config_name_store(struct config_item *item, @@ -1177,24 +1135,18 @@ static ssize_t gpio_sim_line_config_name_store(struct config_item *item, struct gpio_sim_device *dev = gpio_sim_line_get_device(line); char *trimmed; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) { - mutex_unlock(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) return -EBUSY; - } trimmed = gpio_sim_strdup_trimmed(page, count); - if (!trimmed) { - mutex_unlock(&dev->lock); + if (!trimmed) return -ENOMEM; - } kfree(line->name); line->name = trimmed; - mutex_unlock(&dev->lock); - return count; } @@ -1210,13 +1162,10 @@ static ssize_t gpio_sim_hog_config_name_show(struct config_item *item, { struct gpio_sim_hog *hog = to_gpio_sim_hog(item); struct gpio_sim_device *dev = gpio_sim_hog_get_device(hog); - int ret; - mutex_lock(&dev->lock); - ret = sprintf(page, "%s\n", hog->name ?: ""); - mutex_unlock(&dev->lock); + guard(mutex)(&dev->lock); - return ret; + return sprintf(page, "%s\n", hog->name ?: ""); } static ssize_t gpio_sim_hog_config_name_store(struct config_item *item, @@ -1226,24 +1175,18 @@ static ssize_t gpio_sim_hog_config_name_store(struct config_item *item, struct gpio_sim_device *dev = gpio_sim_hog_get_device(hog); char *trimmed; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) { - mutex_unlock(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) return -EBUSY; - } trimmed = gpio_sim_strdup_trimmed(page, count); - if (!trimmed) { - mutex_unlock(&dev->lock); + if (!trimmed) return -ENOMEM; - } kfree(hog->name); hog->name = trimmed; - mutex_unlock(&dev->lock); - return count; } @@ -1257,9 +1200,8 @@ static ssize_t gpio_sim_hog_config_direction_show(struct config_item *item, char *repr; int dir; - mutex_lock(&dev->lock); - dir = hog->dir; - mutex_unlock(&dev->lock); + scoped_guard(mutex, &dev->lock) + dir = hog->dir; switch (dir) { case GPIOD_IN: @@ -1286,42 +1228,24 @@ gpio_sim_hog_config_direction_store(struct config_item *item, { struct gpio_sim_hog *hog = to_gpio_sim_hog(item); struct gpio_sim_device *dev = gpio_sim_hog_get_device(hog); - char *trimmed; int dir; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) { - mutex_unlock(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) return -EBUSY; - } - trimmed = gpio_sim_strdup_trimmed(page, count); - if (!trimmed) { - mutex_unlock(&dev->lock); - return -ENOMEM; - } - - if (strcmp(trimmed, "input") == 0) + if (sysfs_streq(page, "input")) dir = GPIOD_IN; - else if (strcmp(trimmed, "output-high") == 0) + else if (sysfs_streq(page, "output-high")) dir = GPIOD_OUT_HIGH; - else if (strcmp(trimmed, "output-low") == 0) + else if (sysfs_streq(page, "output-low")) dir = GPIOD_OUT_LOW; else - dir = -EINVAL; - - kfree(trimmed); - - if (dir < 0) { - mutex_unlock(&dev->lock); - return dir; - } + return -EINVAL; hog->dir = dir; - mutex_unlock(&dev->lock); - return count; } @@ -1339,9 +1263,8 @@ static void gpio_sim_hog_config_item_release(struct config_item *item) struct gpio_sim_line *line = hog->parent; struct gpio_sim_device *dev = gpio_sim_hog_get_device(hog); - mutex_lock(&dev->lock); - line->hog = NULL; - mutex_unlock(&dev->lock); + scoped_guard(mutex, &dev->lock) + line->hog = NULL; kfree(hog->name); kfree(hog); @@ -1367,13 +1290,11 @@ gpio_sim_line_config_make_hog_item(struct config_group *group, const char *name) if (strcmp(name, "hog") != 0) return ERR_PTR(-EINVAL); - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); hog = kzalloc(sizeof(*hog), GFP_KERNEL); - if (!hog) { - mutex_unlock(&dev->lock); + if (!hog) return ERR_PTR(-ENOMEM); - } config_item_init_type_name(&hog->item, name, &gpio_sim_hog_config_type); @@ -1383,8 +1304,6 @@ gpio_sim_line_config_make_hog_item(struct config_group *group, const char *name) hog->parent = line; line->hog = hog; - mutex_unlock(&dev->lock); - return &hog->item; } @@ -1393,9 +1312,8 @@ static void gpio_sim_line_config_group_release(struct config_item *item) struct gpio_sim_line *line = to_gpio_sim_line(item); struct gpio_sim_device *dev = gpio_sim_line_get_device(line); - mutex_lock(&dev->lock); - list_del(&line->siblings); - mutex_unlock(&dev->lock); + scoped_guard(mutex, &dev->lock) + list_del(&line->siblings); kfree(line->name); kfree(line); @@ -1430,18 +1348,14 @@ gpio_sim_bank_config_make_line_group(struct config_group *group, if (ret != 1 || nchar != strlen(name)) return ERR_PTR(-EINVAL); - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) { - mutex_unlock(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) return ERR_PTR(-EBUSY); - } line = kzalloc(sizeof(*line), GFP_KERNEL); - if (!line) { - mutex_unlock(&dev->lock); + if (!line) return ERR_PTR(-ENOMEM); - } config_group_init_type_name(&line->group, name, &gpio_sim_line_config_type); @@ -1450,8 +1364,6 @@ gpio_sim_bank_config_make_line_group(struct config_group *group, line->offset = offset; list_add_tail(&line->siblings, &bank->line_list); - mutex_unlock(&dev->lock); - return &line->group; } @@ -1460,9 +1372,8 @@ static void gpio_sim_bank_config_group_release(struct config_item *item) struct gpio_sim_bank *bank = to_gpio_sim_bank(item); struct gpio_sim_device *dev = gpio_sim_bank_get_device(bank); - mutex_lock(&dev->lock); - list_del(&bank->siblings); - mutex_unlock(&dev->lock); + scoped_guard(mutex, &dev->lock) + list_del(&bank->siblings); kfree(bank->label); kfree(bank); @@ -1490,18 +1401,14 @@ gpio_sim_device_config_make_bank_group(struct config_group *group, struct gpio_sim_device *dev = to_gpio_sim_device(&group->cg_item); struct gpio_sim_bank *bank; - mutex_lock(&dev->lock); + guard(mutex)(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) { - mutex_unlock(&dev->lock); + if (gpio_sim_device_is_live_unlocked(dev)) return ERR_PTR(-EBUSY); - } bank = kzalloc(sizeof(*bank), GFP_KERNEL); - if (!bank) { - mutex_unlock(&dev->lock); + if (!bank) return ERR_PTR(-ENOMEM); - } config_group_init_type_name(&bank->group, name, &gpio_sim_bank_config_group_type); @@ -1510,8 +1417,6 @@ gpio_sim_device_config_make_bank_group(struct config_group *group, INIT_LIST_HEAD(&bank->line_list); list_add_tail(&bank->siblings, &dev->bank_list); - mutex_unlock(&dev->lock); - return &bank->group; } @@ -1519,10 +1424,10 @@ static void gpio_sim_device_config_group_release(struct config_item *item) { struct gpio_sim_device *dev = to_gpio_sim_device(item); - mutex_lock(&dev->lock); - if (gpio_sim_device_is_live_unlocked(dev)) - gpio_sim_device_deactivate_unlocked(dev); - mutex_unlock(&dev->lock); + scoped_guard(mutex, &dev->lock) { + if (gpio_sim_device_is_live_unlocked(dev)) + gpio_sim_device_deactivate_unlocked(dev); + } mutex_destroy(&dev->lock); ida_free(&gpio_sim_ida, dev->id); @@ -1547,7 +1452,7 @@ static const struct config_item_type gpio_sim_device_config_group_type = { static struct config_group * gpio_sim_config_make_device_group(struct config_group *group, const char *name) { - struct gpio_sim_device *dev; + struct gpio_sim_device *dev __free(kfree) = NULL; int id; dev = kzalloc(sizeof(*dev), GFP_KERNEL); @@ -1555,10 +1460,8 @@ gpio_sim_config_make_device_group(struct config_group *group, const char *name) return ERR_PTR(-ENOMEM); id = ida_alloc(&gpio_sim_ida, GFP_KERNEL); - if (id < 0) { - kfree(dev); + if (id < 0) return ERR_PTR(id); - } config_group_init_type_name(&dev->group, name, &gpio_sim_device_config_group_type); @@ -1569,7 +1472,7 @@ gpio_sim_config_make_device_group(struct config_group *group, const char *name) dev->bus_notifier.notifier_call = gpio_sim_bus_notifier_call; init_completion(&dev->probe_completion); - return &dev->group; + return &no_free_ptr(dev)->group; } static struct configfs_group_operations gpio_sim_config_group_ops = { |