summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-07-05 20:48:14 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2021-07-05 20:48:14 +0200
commitb8052599420cd94505baec1f22b4e7c9e5ae5fce (patch)
tree80775d4b6c6d67948a1c5e9aa6bd70cb00838b7a /drivers/gpio/gpiolib.c
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dto... (diff)
parentdocs: driver-api: gpio: using-gpio.rst: avoid using ReST :doc:`foo` markup (diff)
downloadlinux-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.c59
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;
}