[PATCH v4 2/3] gpiolib: add get_config() and gpiochip_generic_get_config()
Mehmet Fide
mehmet.fide at gmail.com
Thu Sep 3 00:31:42 PDT 2026
From: Mehmet Fide <mehmet.fide at screeningeagle.com>
A chip with a pin control backend sets a line's configuration through
set_config() and gpiochip_generic_config(), but has no way to read one
back. gpio-mmio needs that to learn the direction of a line whose
direction lives in the pin controller.
Add the optional get_config() callback, taking the packed parameter to
query and returning the packed answer the way pinctrl_gpio_get_config()
does, and gpiochip_generic_get_config() as the pin control backed
implementation, the mirror of gpiochip_generic_config(). Without
CONFIG_PINCTRL the pinctrl stub returns 0 and leaves the config alone,
so the helper answers -ENOTSUPP there instead.
Nothing in gpiolib calls get_config() and there is no consumer API; it
is for the chip's own use.
Suggested-by: Linus Walleij <linusw at kernel.org>
Signed-off-by: Mehmet Fide <mehmet.fide at screeningeagle.com>
---
Documentation/driver-api/gpio/driver.rst | 6 ++++++
drivers/gpio/gpiolib.c | 23 +++++++++++++++++++++++
include/linux/gpio/driver.h | 9 +++++++++
3 files changed, 38 insertions(+)
diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst
index a4f160b95089..5be217815c9b 100644
--- a/Documentation/driver-api/gpio/driver.rst
+++ b/Documentation/driver-api/gpio/driver.rst
@@ -134,6 +134,12 @@ ending up in the pin control back-end "behind" the GPIO controller, usually
closer to the actual pins. This way the pin controller can manage the below
listed GPIO configurations.
+The optional .get_config() callback reads a configuration back with the same
+packed format: the parameter to query goes in, the packed parameter and
+argument come out. gpiochip_generic_get_config() is its pin control backed
+counterpart. Nothing in gpiolib calls it; it is for the GPIO driver's own use,
+for example to learn the direction of a line when the pin controller owns it.
+
If a pin controller back-end is used, the GPIO controller or hardware
description needs to provide "GPIO ranges" mapping the GPIO line offsets to pin
numbers on the pin controller so they can properly cross-reference each other.
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index ef8ccaf17c9c..44328aed1646 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2440,6 +2440,29 @@ int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset,
}
EXPORT_SYMBOL_GPL(gpiochip_generic_config);
+/**
+ * gpiochip_generic_get_config() - read back the configuration of a pin
+ * @gc: the gpiochip owning the GPIO
+ * @offset: the offset of the GPIO to query
+ * @config: the packed parameter to query, replaced by the packed answer
+ *
+ * Returns:
+ * 0 on success, or negative errno on failure.
+ */
+int gpiochip_generic_get_config(struct gpio_chip *gc, unsigned int offset,
+ unsigned long *config)
+{
+#ifdef CONFIG_PINCTRL
+ if (list_empty(&gc->gpiodev->pin_ranges))
+ return -ENOTSUPP;
+
+ return pinctrl_gpio_get_config(gc, offset, config);
+#else
+ return -ENOTSUPP;
+#endif
+}
+EXPORT_SYMBOL_GPL(gpiochip_generic_get_config);
+
#ifdef CONFIG_PINCTRL
/**
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index 17511434ed07..5c81cce69173 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -359,6 +359,10 @@ struct gpio_irq_chip {
* @set_config: optional hook for all kinds of settings. Uses the same
* packed config format as generic pinconf. Must return 0 on success and
* a negative error number on failure.
+ * @get_config: optional hook to read back a setting. Uses the same packed
+ * config format as generic pinconf: the parameter to query goes in, the
+ * packed parameter and argument come out. Must return 0 on success and a
+ * negative error number on failure.
* @to_irq: optional hook supporting non-static gpiod_to_irq() mappings;
* implementation may not sleep
* @dbg_show: optional routine to show contents in debugfs; default code
@@ -434,6 +438,9 @@ struct gpio_chip {
int (*set_config)(struct gpio_chip *gc,
unsigned int offset,
unsigned long config);
+ int (*get_config)(struct gpio_chip *gc,
+ unsigned int offset,
+ unsigned long *config);
int (*to_irq)(struct gpio_chip *gc,
unsigned int offset);
@@ -708,6 +715,8 @@ int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset);
void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset);
int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset,
unsigned long config);
+int gpiochip_generic_get_config(struct gpio_chip *gc, unsigned int offset,
+ unsigned long *config);
/**
* struct gpio_pin_range - pin range controlled by a gpio chip
--
2.54.0
More information about the linux-arm-kernel
mailing list