Re: [PATCH 4/9] gpio: regmap: add the .get_direction() callback
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Date: 2025-07-14 13:18:05
Also in:
linux-devicetree, linux-gpio, lkml
On Wed, Jul 09, 2025 at 05:01:38PM +0200, Michael Walle wrote:
Hi Ioana, great to see another user of gpio-regmap. On Wed Jul 9, 2025 at 1:26 PM CEST, Ioana Ciornei wrote:quoted
There are GPIO controllers such as the one present in the LX2160ARDB QIXIS CPLD which are single register fixed-direction. This cannot be modeled using the gpio-regmap as-is since there is no way to present the true direction of a GPIO line.You mean input and output mixed together in one register? At least to me, that wasn't so obvious by the commit message, I had to look at the actual driver.
Yes, that is right. I will update the commit message to make it more clear for everybody.
quoted
In order to make this use case possible, add a new callback to the gpio_config structure - .get_direction() - which can be used by user drivers to provide the fixed direction per GPIO line. Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com> --- drivers/gpio/gpio-regmap.c | 17 ++++++++++++++++- include/linux/gpio/regmap.h | 3 +++ 2 files changed, 19 insertions(+), 1 deletion(-)diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 87c4225784cf..dac2acb26655 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c@@ -32,6 +32,8 @@ struct gpio_regmap { unsigned int reg_dir_in_base; unsigned int reg_dir_out_base; + int (*get_direction)(struct gpio_regmap *gpio, unsigned int offset); + int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base, unsigned int offset, unsigned int *reg, unsigned int *mask);@@ -129,6 +131,9 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip, unsigned int base, val, reg, mask; int invert, ret; + if (gpio->get_direction) + return gpio->get_direction(gpio, offset); + if (gpio->reg_dat_base && !gpio->reg_set_base) return GPIO_LINE_DIRECTION_IN; if (gpio->reg_set_base && !gpio->reg_dat_base)@@ -163,7 +168,16 @@ static int gpio_regmap_set_direction(struct gpio_chip *chip, { struct gpio_regmap *gpio = gpiochip_get_data(chip); unsigned int base, val, reg, mask; - int invert, ret; + int invert, ret, dir; + + if (gpio->get_direction) { + dir = gpio->get_direction(gpio, offset); + if (dir == GPIO_LINE_DIRECTION_IN && output) + return -EOPNOTSUPP; + if (dir == GPIO_LINE_DIRECTION_OUT && !output) + return -EOPNOTSUPP; + return 0; + }What is the intention here? Shouldn't there be just a .set_direction op and if there isn't one, return EOPNOTSUPP? In any case, that is unused code for your driver as far as I see, because you neither set .reg_dir_in_base nor .reg_dir_out_base and thus, .direction_input nor .direction_output are set within the gpio_chip struct (see gpio_regmap_register()).
Yes, you are right. I did want to return ealier an EOPNOTSUPP to make sure that in my specific case no directions would be changed. But that is not needed indeed since, as you said, I do not use .reg_dir_in_base nor .reg_dir_out_base. I will remove this in v2. And since we are on the subject, I will try out Andrew's suggestion with giving gpio-regmap a bitmap to use directly. Thanks! Ioana