diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-05 20:48:14 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-05 20:48:14 +0200 |
commit | b8052599420cd94505baec1f22b4e7c9e5ae5fce (patch) | |
tree | 80775d4b6c6d67948a1c5e9aa6bd70cb00838b7a /drivers/gpio/gpiolib.c | |
parent | Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dto... (diff) | |
parent | docs: driver-api: gpio: using-gpio.rst: avoid using ReST :doc:`foo` markup (diff) | |
download | linux-b8052599420cd94505baec1f22b4e7c9e5ae5fce.tar.xz linux-b8052599420cd94505baec1f22b4e7c9e5ae5fce.zip |
Merge tag 'gpio-updates-for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio updates from Bartosz Golaszewski:
"One new driver, support for new models in existing ones, dt-bindings
conversions for several modules and improvements all over the place.
Summary:
- new driver for the IDT 79RC3243x GPIO controller
- device tree bindings coversion to YAML for the following drivers:
gpio-rk3328-grf, gpio-omap, gpio-davinci, gpio-zynq, gpio-stp,
gpio-pcf857x
- cleanup of probe functions in many drivers from Alexandru Ardelean,
mostly dropping unnecessary calls to platform_set_drvdata() and
removing error messages where none are needed (handled by the
subsystem already)
- several improvements to the core gpiolib and the sysfs interface
code from Andy Shevchenko
- conversion of the gpio-xilinx driver to using the bitmap API +
improvements of suspend/resume handling + minor tweaks
- convert the gpio-stmpe to using devres helpers exclusively in probe
for improved robustness
- updates for the generic gpio-regmap driver
- updates for the gpio-dwapb driver
- support for a new model in gpio-pca953x
- cleanups in gpio-tegra186, gpio-104-idio-16, gpio-mxs & gpio-xgene
- slight code refactoring of the gpio-zynq driver
- documentation fixes from Mauro Carvalho Chehab
- a bunch of minor tweaks and improvements all over the place"
* tag 'gpio-updates-for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (57 commits)
docs: driver-api: gpio: using-gpio.rst: avoid using ReST :doc:`foo` markup
dt-bindings: gpio: pcf857x: Convert to json-schema
gpio: mxs: Prefer unsigned int to bare use of unsigned
dt-bindings: gpio: stp: convert to json-schema
dt-bindings: gpio: zynq: convert bindings to YAML
dt-bindings: gpio: gpio-davinci: Convert to json-schema
gpio: pca953x: Add support for the On Semi pca9655
gpio: gpio-xilinx: update on suspend and resume calls
gpio: zynq: Check return value of irq_get_irq_data
gpio: zynq: Check return value of pm_runtime_get_sync
gpio: zynq: use module_platform_driver to simplify the code
gpio: idt3243x: Fix return value check in idt_gpio_probe()
MAINTAINERS: update ti,omap-gpio.yaml reference
dt-bindings: gpio: Add devicetree binding for IDT 79RC32434 GPIO controller
gpio: Add support for IDT 79RC3243x GPIO controller
gpio: regmap: move drvdata to config data
gpio-dwapb: Drop unused headers and sort the rest
gpio: gpio-regmap: Use devm_add_action_or_reset()
gpio: dwapb: Switch to use fwnode_irq_get()
gpio: dwapb: Drop redundant check in dwapb_irq_set_type()
...
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1427c1be749b..27c07108496d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2004,9 +2004,6 @@ const char *gpiochip_is_requested(struct gpio_chip *gc, unsigned int offset) { struct gpio_desc *desc; - if (offset >= gc->ngpio) - return NULL; - desc = gpiochip_get_desc(gc, offset); if (IS_ERR(desc)) return NULL; @@ -2543,21 +2540,28 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, while (i < array_size) { struct gpio_chip *gc = desc_array[i]->gdev->chip; - unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)]; + DECLARE_BITMAP(fastpath_mask, FASTPATH_NGPIO); + DECLARE_BITMAP(fastpath_bits, FASTPATH_NGPIO); unsigned long *mask, *bits; int first, j; if (likely(gc->ngpio <= FASTPATH_NGPIO)) { - mask = fastpath; + mask = fastpath_mask; + bits = fastpath_bits; } else { - mask = kmalloc_array(2 * BITS_TO_LONGS(gc->ngpio), - sizeof(*mask), - can_sleep ? GFP_KERNEL : GFP_ATOMIC); + gfp_t flags = can_sleep ? GFP_KERNEL : GFP_ATOMIC; + + mask = bitmap_alloc(gc->ngpio, flags); if (!mask) return -ENOMEM; + + bits = bitmap_alloc(gc->ngpio, flags); + if (!bits) { + bitmap_free(mask); + return -ENOMEM; + } } - bits = mask + BITS_TO_LONGS(gc->ngpio); bitmap_zero(mask, gc->ngpio); if (!can_sleep) @@ -2580,8 +2584,10 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, ret = gpio_chip_get_multiple(gc, mask, bits); if (ret) { - if (mask != fastpath) - kfree(mask); + if (mask != fastpath_mask) + bitmap_free(mask); + if (bits != fastpath_bits) + bitmap_free(bits); return ret; } @@ -2601,8 +2607,10 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep, j); } - if (mask != fastpath) - kfree(mask); + if (mask != fastpath_mask) + bitmap_free(mask); + if (bits != fastpath_bits) + bitmap_free(bits); } return 0; } @@ -2826,21 +2834,28 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, while (i < array_size) { struct gpio_chip *gc = desc_array[i]->gdev->chip; - unsigned long fastpath[2 * BITS_TO_LONGS(FASTPATH_NGPIO)]; + DECLARE_BITMAP(fastpath_mask, FASTPATH_NGPIO); + DECLARE_BITMAP(fastpath_bits, FASTPATH_NGPIO); unsigned long *mask, *bits; int count = 0; if (likely(gc->ngpio <= FASTPATH_NGPIO)) { - mask = fastpath; + mask = fastpath_mask; + bits = fastpath_bits; } else { - mask = kmalloc_array(2 * BITS_TO_LONGS(gc->ngpio), - sizeof(*mask), - can_sleep ? GFP_KERNEL : GFP_ATOMIC); + gfp_t flags = can_sleep ? GFP_KERNEL : GFP_ATOMIC; + + mask = bitmap_alloc(gc->ngpio, flags); if (!mask) return -ENOMEM; + + bits = bitmap_alloc(gc->ngpio, flags); + if (!bits) { + bitmap_free(mask); + return -ENOMEM; + } } - bits = mask + BITS_TO_LONGS(gc->ngpio); bitmap_zero(mask, gc->ngpio); if (!can_sleep) @@ -2885,8 +2900,10 @@ int gpiod_set_array_value_complex(bool raw, bool can_sleep, if (count != 0) gpio_chip_set_multiple(gc, mask, bits); - if (mask != fastpath) - kfree(mask); + if (mask != fastpath_mask) + bitmap_free(mask); + if (bits != fastpath_bits) + bitmap_free(bits); } return 0; } |