* [PATCH 1/4] gpio: add slice support
2024-02-21 14:27 [PATCH 0/4] make I2C GPIO expander provided buttons work Sascha Hauer
@ 2024-02-21 14:27 ` Sascha Hauer
2024-02-21 14:27 ` [PATCH 2/4] gpio: pca953x: depend on i2c slice Sascha Hauer
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2024-02-21 14:27 UTC (permalink / raw)
To: Barebox List
GPIOs are not only provided by raw register accesses but also by I2C
devices. Add a slice to a gpio chip so that a gpio user can check if the
slice is acquired before using it in a poller.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/gpio/gpiolib.c | 11 +++++++++++
include/gpio.h | 15 +++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index bcfdd5a0dd..5bc261a010 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -172,6 +172,16 @@ int gpio_request(unsigned gpio, const char *label)
return gpiodesc_request(desc, label);
}
+bool gpio_slice_acquired(unsigned gpio)
+{
+ struct gpio_desc *desc = gpio_to_desc(gpio);
+
+ if (!desc)
+ return false;
+
+ return slice_acquired(&desc->chip->slice);
+}
+
static void gpiodesc_free(struct gpio_desc *desc)
{
if (!desc->requested)
@@ -1013,6 +1023,7 @@ int gpiochip_add(struct gpio_chip *chip)
return -ENOSPC;
}
+ slice_init(&chip->slice, dev_name(chip->dev));
list_add_tail(&chip->list, &chip_list);
diff --git a/include/gpio.h b/include/gpio.h
index 9951532084..adc1eb39ac 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -2,6 +2,7 @@
#ifndef __GPIO_H
#define __GPIO_H
+#include <slice.h>
#include <linux/types.h>
#include <linux/list.h>
#include <linux/iopoll.h>
@@ -156,6 +157,12 @@ static inline int gpio_array_to_id(const struct gpio *array, size_t num, u32 *va
{
return -EINVAL;
}
+
+static inline bool gpio_slice_acquired(unsigned gpio)
+{
+ return false;
+}
+
#else
int gpio_request(unsigned gpio, const char *label);
int gpio_find_by_name(const char *name);
@@ -165,6 +172,7 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
int gpio_request_array(const struct gpio *array, size_t num);
void gpio_free_array(const struct gpio *array, size_t num);
int gpio_array_to_id(const struct gpio *array, size_t num, u32 *val);
+bool gpio_slice_acquired(unsigned gpio);
#endif
struct gpio_chip;
@@ -213,9 +221,16 @@ struct gpio_chip {
struct gpio_ops *ops;
+ struct slice slice;
+
struct list_head list;
};
+static inline struct slice *gpiochip_slice(struct gpio_chip *chip)
+{
+ return &chip->slice;
+}
+
int gpiochip_add(struct gpio_chip *chip);
void gpiochip_remove(struct gpio_chip *chip);
--
2.39.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/4] gpio: pca953x: depend on i2c slice
2024-02-21 14:27 [PATCH 0/4] make I2C GPIO expander provided buttons work Sascha Hauer
2024-02-21 14:27 ` [PATCH 1/4] gpio: add slice support Sascha Hauer
@ 2024-02-21 14:27 ` Sascha Hauer
2024-02-21 14:27 ` [PATCH 3/4] input: gpio_keys: limit poll rate Sascha Hauer
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2024-02-21 14:27 UTC (permalink / raw)
To: Barebox List
The GPIOs provided by the pca953x cannot be used inside a poller while
the I2C controller is in use. Add a dependency to from the GPIO
controller to the I2C controller for this purpose.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/gpio/gpio-pca953x.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index cee60f7a65..e303f6b21f 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -475,6 +475,8 @@ static int pca953x_probe(struct device *dev)
if (ret)
return ret;
+ slice_depends_on(gpiochip_slice(&chip->gpio_chip), i2c_client_slice(client));
+
if (pdata && pdata->setup) {
ret = pdata->setup(client, chip->gpio_chip.base,
chip->gpio_chip.ngpio, pdata->context);
--
2.39.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/4] input: gpio_keys: limit poll rate
2024-02-21 14:27 [PATCH 0/4] make I2C GPIO expander provided buttons work Sascha Hauer
2024-02-21 14:27 ` [PATCH 1/4] gpio: add slice support Sascha Hauer
2024-02-21 14:27 ` [PATCH 2/4] gpio: pca953x: depend on i2c slice Sascha Hauer
@ 2024-02-21 14:27 ` Sascha Hauer
2024-02-21 14:28 ` [PATCH 4/4] input: gpio_keys: only use gpios in poller when not in use Sascha Hauer
2024-02-23 7:32 ` [PATCH 0/4] make I2C GPIO expander provided buttons work Sascha Hauer
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2024-02-21 14:27 UTC (permalink / raw)
To: Barebox List
GPIOs a sometimes slow to read out, for example when they are provided
by I2C GPIO expanders. Limit the poll rate so that we do not slow down
barebox more than necessary in these cases.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/input/gpio_keys.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/drivers/input/gpio_keys.c b/drivers/input/gpio_keys.c
index 77013be133..fd3995d01f 100644
--- a/drivers/input/gpio_keys.c
+++ b/drivers/input/gpio_keys.c
@@ -29,20 +29,14 @@ struct gpio_keys {
struct gpio_key *buttons;
int nbuttons;
- struct poller_struct poller;
+ struct poller_async poller;
struct input_device input;
struct device *dev;
};
-static inline struct gpio_keys *
-poller_to_gk_pdata(struct poller_struct *poller)
+static void gpio_key_poller(void *data)
{
- return container_of(poller, struct gpio_keys, poller);
-}
-
-static void gpio_key_poller(struct poller_struct *poller)
-{
- struct gpio_keys *gk = poller_to_gk_pdata(poller);
+ struct gpio_keys *gk = data;
struct gpio_key *gb;
int i, val;
@@ -64,6 +58,8 @@ static void gpio_key_poller(struct poller_struct *poller)
gb->previous_state = val;
}
}
+
+ poller_call_async(&gk->poller, 10 * MSECOND, gpio_key_poller, gk);
}
static int gpio_keys_probe_pdata(struct gpio_keys *gk, struct device *dev)
@@ -159,16 +155,16 @@ static int __init gpio_keys_probe(struct device *dev)
gk->buttons[i].previous_state = gk->buttons[i].active_low;
}
- gk->poller.func = gpio_key_poller;
-
ret = input_device_register(&gk->input);
if (ret)
return ret;
- ret = poller_register(&gk->poller, dev_name(dev));
+ ret = poller_async_register(&gk->poller, dev_name(dev));
if (ret)
return ret;
+ poller_call_async(&gk->poller, 10 * MSECOND, gpio_key_poller, gk);
+
return 0;
}
--
2.39.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/4] input: gpio_keys: only use gpios in poller when not in use
2024-02-21 14:27 [PATCH 0/4] make I2C GPIO expander provided buttons work Sascha Hauer
` (2 preceding siblings ...)
2024-02-21 14:27 ` [PATCH 3/4] input: gpio_keys: limit poll rate Sascha Hauer
@ 2024-02-21 14:28 ` Sascha Hauer
2024-02-23 7:32 ` [PATCH 0/4] make I2C GPIO expander provided buttons work Sascha Hauer
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2024-02-21 14:28 UTC (permalink / raw)
To: Barebox List
Before reading GPIOs in a poller check if they are available.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/input/gpio_keys.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/input/gpio_keys.c b/drivers/input/gpio_keys.c
index fd3995d01f..c23d20563c 100644
--- a/drivers/input/gpio_keys.c
+++ b/drivers/input/gpio_keys.c
@@ -40,6 +40,13 @@ static void gpio_key_poller(void *data)
struct gpio_key *gb;
int i, val;
+ for (i = 0; i < gk->nbuttons; i++) {
+ gb = &gk->buttons[i];
+
+ if (gpio_slice_acquired(gb->gpio))
+ goto out;
+ }
+
for (i = 0; i < gk->nbuttons; i++) {
gb = &gk->buttons[i];
@@ -58,7 +65,7 @@ static void gpio_key_poller(void *data)
gb->previous_state = val;
}
}
-
+out:
poller_call_async(&gk->poller, 10 * MSECOND, gpio_key_poller, gk);
}
--
2.39.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] make I2C GPIO expander provided buttons work
2024-02-21 14:27 [PATCH 0/4] make I2C GPIO expander provided buttons work Sascha Hauer
` (3 preceding siblings ...)
2024-02-21 14:28 ` [PATCH 4/4] input: gpio_keys: only use gpios in poller when not in use Sascha Hauer
@ 2024-02-23 7:32 ` Sascha Hauer
4 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2024-02-23 7:32 UTC (permalink / raw)
To: Barebox List, Sascha Hauer
On Wed, 21 Feb 2024 15:27:56 +0100, Sascha Hauer wrote:
> The TQMa6UL board uses the gpio-keys driver with GPIOs provided by a
> PCA9554 I2C GPIO expander. This currently doesn't work as the GPIOs
> are read in a poller during an ongoing I2C transfer on the same bus.
>
> This series fixes that by adding a slice to struct gpio_chip and
> checking its availability before using it.
>
> [...]
Applied, thanks!
[1/4] gpio: add slice support
https://git.pengutronix.de/cgit/barebox/commit/?id=cb046503d2c2 (link may not be stable)
[2/4] gpio: pca953x: depend on i2c slice
https://git.pengutronix.de/cgit/barebox/commit/?id=73b7973cee7d (link may not be stable)
[3/4] input: gpio_keys: limit poll rate
https://git.pengutronix.de/cgit/barebox/commit/?id=ff5e5b69d643 (link may not be stable)
[4/4] input: gpio_keys: only use gpios in poller when not in use
https://git.pengutronix.de/cgit/barebox/commit/?id=b01bba2f2bea (link may not be stable)
Best regards,
--
Sascha Hauer <s.hauer@pengutronix.de>
^ permalink raw reply [flat|nested] 6+ messages in thread