There is a custom loop that repeats parts of gpiod_get_array_value_cansleep().
Use that in conjunction with bitmap API to make code shorter and easier to
follow.
With this done, add an upper check for amount of GPIOs given based on
the driver's code.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
drivers/input/misc/gpio_decoder.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/input/misc/gpio_decoder.c b/drivers/input/misc/gpio_decoder.c
index a2ae400790f9..8c07f7ff66e5 100644
--- a/drivers/input/misc/gpio_decoder.c
+++ b/drivers/input/misc/gpio_decoder.c
@@ -6,11 +6,13 @@
* encoded numeric value into an input event.
*/
+#include <linux/bitmap.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/kernel.h>
+#include <linux/minmax.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -26,23 +28,18 @@ struct gpio_decoder {
static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder)
{
struct gpio_descs *gpios = decoder->input_gpios;
- unsigned int ret = 0;
- int i, val;
+ DECLARE_BITMAP(values, 32);
+ unsigned int size;
+ int err;
- for (i = 0; i < gpios->ndescs; i++) {
- val = gpiod_get_value_cansleep(gpios->desc[i]);
- if (val < 0) {
- dev_err(decoder->dev,
- "Error reading gpio %d: %d\n",
- desc_to_gpio(gpios->desc[i]), val);
- return val;
- }
-
- val = !!val;
- ret = (ret << 1) | val;
+ size = min(gpios->ndescs, 32U);
+ err = gpiod_get_array_value_cansleep(size, gpios->desc, gpios->info, values);
+ if (err) {
+ dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
+ return err;
}
- return ret;
+ return bitmap_read(values, 0, size);
}
static void gpio_decoder_poll_gpios(struct input_dev *input)
@@ -81,6 +78,9 @@ static int gpio_decoder_probe(struct platform_device *pdev)
if (decoder->input_gpios->ndescs < 2)
return dev_err_probe(dev, -EINVAL, "not enough gpios found\n");
+ if (decoder->input_gpios->ndescs > 31)
+ return dev_err_probe(dev, -EINVAL, "too many gpios found\n");
+
if (device_property_read_u32(dev, "decoder-max-value", &max))
max = (1U << decoder->input_gpios->ndescs) - 1;
--
2.50.1
Hi Andy,
kernel test robot noticed the following build errors:
[auto build test ERROR on dtor-input/next]
[also build test ERROR on dtor-input/for-linus hid/for-next linus/master v6.18-rc5 next-20251113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Andy-Shevchenko/Input-gpio_decoder-make-use-of-device-properties/20251113-032111
base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
patch link: https://lore.kernel.org/r/20251112191412.2088105-4-andriy.shevchenko%40linux.intel.com
patch subject: [PATCH v1 3/5] Input: gpio_decoder - replace custom loop by gpiod_get_array_value_cansleep()
config: x86_64-buildonly-randconfig-002-20251113 (https://download.01.org/0day-ci/archive/20251113/202511131958.6ItfY60O-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251113/202511131958.6ItfY60O-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511131958.6ItfY60O-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/input/misc/gpio_decoder.c:38:53: error: use of undeclared identifier 'val'
38 | dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
| ^
1 error generated.
vim +/val +38 drivers/input/misc/gpio_decoder.c
27
28 static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder)
29 {
30 struct gpio_descs *gpios = decoder->input_gpios;
31 DECLARE_BITMAP(values, 32);
32 unsigned int size;
33 int err;
34
35 size = min(gpios->ndescs, 32U);
36 err = gpiod_get_array_value_cansleep(size, gpios->desc, gpios->info, values);
37 if (err) {
> 38 dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
39 return err;
40 }
41
42 return bitmap_read(values, 0, size);
43 }
44
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Hi Andy,
kernel test robot noticed the following build errors:
[auto build test ERROR on dtor-input/next]
[also build test ERROR on dtor-input/for-linus hid/for-next linus/master v6.18-rc5 next-20251113]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Andy-Shevchenko/Input-gpio_decoder-make-use-of-device-properties/20251113-032111
base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
patch link: https://lore.kernel.org/r/20251112191412.2088105-4-andriy.shevchenko%40linux.intel.com
patch subject: [PATCH v1 3/5] Input: gpio_decoder - replace custom loop by gpiod_get_array_value_cansleep()
config: x86_64-buildonly-randconfig-004-20251113 (https://download.01.org/0day-ci/archive/20251113/202511131832.JljMfKrW-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251113/202511131832.JljMfKrW-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511131832.JljMfKrW-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from include/linux/device.h:15,
from drivers/input/misc/gpio_decoder.c:10:
drivers/input/misc/gpio_decoder.c: In function 'gpio_decoder_get_gpios_state':
>> drivers/input/misc/gpio_decoder.c:38:67: error: 'val' undeclared (first use in this function)
38 | dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
| ^~~
include/linux/dev_printk.h:110:37: note: in definition of macro 'dev_printk_index_wrap'
110 | _p_func(dev, fmt, ##__VA_ARGS__); \
| ^~~~~~~~~~~
drivers/input/misc/gpio_decoder.c:38:17: note: in expansion of macro 'dev_err'
38 | dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
| ^~~~~~~
drivers/input/misc/gpio_decoder.c:38:67: note: each undeclared identifier is reported only once for each function it appears in
38 | dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
| ^~~
include/linux/dev_printk.h:110:37: note: in definition of macro 'dev_printk_index_wrap'
110 | _p_func(dev, fmt, ##__VA_ARGS__); \
| ^~~~~~~~~~~
drivers/input/misc/gpio_decoder.c:38:17: note: in expansion of macro 'dev_err'
38 | dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
| ^~~~~~~
vim +/val +38 drivers/input/misc/gpio_decoder.c
27
28 static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder)
29 {
30 struct gpio_descs *gpios = decoder->input_gpios;
31 DECLARE_BITMAP(values, 32);
32 unsigned int size;
33 int err;
34
35 size = min(gpios->ndescs, 32U);
36 err = gpiod_get_array_value_cansleep(size, gpios->desc, gpios->info, values);
37 if (err) {
> 38 dev_err(decoder->dev, "Error reading GPIO: %d\n", val);
39 return err;
40 }
41
42 return bitmap_read(values, 0, size);
43 }
44
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2026 Red Hat, Inc.