Re: [PATCH 1/1] pinctrl: sunxi: add GPIO get_direction callback
From: Chen-Yu Tsai <wens@kernel.org>
Date: 2026-02-11 03:49:50
Also in:
linux-gpio, linux-sunxi, lkml
On Wed, Feb 11, 2026 at 11:33 AM James Hilliard [off-list ref] wrote: Ah, you beat me to it.
Implement sunxi_pinctrl_gpio_get_direction() and wire it into the sunxi gpio_chip setup.
Can you also mention that without this, calls to gpiochip_get_direction() cause a big warning?
quoted hunk ↗ jump to hunk
The new callback reads the pin mux register and compares the mux value against the pin descriptor gpio_in and gpio_out functions to report GPIO_LINE_DIRECTION_IN or GPIO_LINE_DIRECTION_OUT. If the pin is muxed to irq, report it as input. Signed-off-by: James Hilliard <redacted> --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 0fb057a07dcc..424f23be27b2 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c@@ -995,6 +995,37 @@ static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip, chip->base + offset, false); } +static int sunxi_pinctrl_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct sunxi_pinctrl *pctl = gpiochip_get_data(chip); + struct sunxi_desc_function *in, *out, *irq; + u32 reg, shift, mask, val; + u16 pin = chip->base + offset; + + in = sunxi_pinctrl_desc_find_function_by_pin(pctl, pin, "gpio_in"); + out = sunxi_pinctrl_desc_find_function_by_pin(pctl, pin, "gpio_out"); + if (!in || !out) + return -EINVAL; + + irq = sunxi_pinctrl_desc_find_function_by_pin(pctl, pin, "irq");
This is less efficient, as you end up (linearly) searching the whole pin array three times. What I did in my version was implement a search based on pin and muxval. I can send that out if it's OK with you. ChenYu
quoted hunk ↗ jump to hunk
+ + sunxi_mux_reg(pctl, offset, ®, &shift, &mask); + val = (readl(pctl->membase + reg) & mask) >> shift; + + if (val == in->muxval) + return GPIO_LINE_DIRECTION_IN; + + if (val == out->muxval) + return GPIO_LINE_DIRECTION_OUT; + + /* IRQ function is effectively input. */ + if (irq && val == irq->muxval) + return GPIO_LINE_DIRECTION_IN; + + return -EINVAL; +} + static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags)@@ -1603,6 +1634,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_device *pdev, pctl->chip->set_config = gpiochip_generic_config; pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; + pctl->chip->get_direction = sunxi_pinctrl_gpio_get_direction; pctl->chip->get = sunxi_pinctrl_gpio_get; pctl->chip->set = sunxi_pinctrl_gpio_set; pctl->chip->of_xlate = sunxi_pinctrl_gpio_of_xlate; --2.43.0