pinctrl: sunxi: Implement gpiochip::get_direction()
Subsystems (3)
Chen-Yu Tsai
maintainerPATCH 1/1 pinctrl: sunxi: Implement gpiochip::get_direction()
After commit e623c4303ed1 ("gpiolib: sanitize the return value of gpio_chip::get_direction()"), a warning will be printed if the gpio driver does not implement this callback.
Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is.
---
This is an alternative to James's version. My version does one lookup instead of three.
drivers/pinctrl/sunxi/pinctrl-sunxi.c | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
drivers/pinctrl/sunxi/pinctrl-sunxi.c +51 -0
@@ -204,6 +204,32 @@ sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,return NULL ; } +static struct sunxi_desc_function * +sunxi_pinctrl_desc_find_function_by_pin_and_mux (struct sunxi_pinctrl *pctl, +const u16 pin_num, +const u8 muxval) +{ +for (unsigned int i =0 ; i < pctl->desc->npins; i++) { +const struct sunxi_desc_pin *pin = pctl->desc->pins + i; +struct sunxi_desc_function *func = pin->functions; + +if (pin->pin.number != pin_num) +continue ; + +if (pin->variant && !(pctl->variant & pin->variant)) +continue ; + +while (func->name) { +if (func->muxval == muxval) +return func; + + func++; + } + } + +return NULL ; +} +static int sunxi_pctrl_get_groups_count (struct pinctrl_dev *pctldev) {struct sunxi_pinctrl *pctl =pinctrl_dev_get_drvdata (pctldev);
@@ -930,6 +956,30 @@ static const struct pinmux_ops sunxi_pmx_ops = { .strict = true, }; +static int sunxi_pinctrl_gpio_get_direction (struct gpio_chip *chip, +unsigned int offset) +{ +struct sunxi_pinctrl *pctl =gpiochip_get_data (chip); +const struct sunxi_desc_function *func; +u32 pin = offset + chip->base; +u32 reg, shift, mask; +u8 muxval; + +sunxi_mux_reg (pctl, offset, ®, &shift, &mask); + + muxval = (readl (pctl->membase + reg) & mask) >> shift; + + func =sunxi_pinctrl_desc_find_function_by_pin_and_mux (pctl, pin, muxval); +if (!func) +return -ENODEV ; + +if (!strcmp (func->name,"gpio_out" )) +return GPIO_LINE_DIRECTION_OUT ; +if (!strcmp (func->name,"gpio_in" ) || !strcmp (func->name,"irq" )) +return GPIO_LINE_DIRECTION_IN ; +return -EINVAL ; +} +static int sunxi_pinctrl_gpio_direction_input (struct gpio_chip *chip,unsigned offset) {
@@ -1601,6 +1651,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_device *pdev, pctl->chip->request = gpiochip_generic_request; pctl->chip->free = gpiochip_generic_free; pctl->chip->set_config = gpiochip_generic_config; + pctl->chip->get_direction = sunxi_pinctrl_gpio_get_direction; pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; pctl->chip->get = sunxi_pinctrl_gpio_get;
Signature · 1 line
2.47.3
Dne ponedeljek, 16. februar 2026 ob 17:09:45 Srednjeevropski standardni čas je Chen-Yu Tsai napisal(a):
Quoted 9 lines
After commit
e623c4303ed1("gpiolib: sanitize the return value ofgpio_chip::get_direction()"), a warning will be printed if the gpio driver does not implement this callback.Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is.
Signed-off-by Chen-Yu Tsai <[email protected]>
Best regards,
Jernej
Quoted 10 lines · Chen-Yu Tsai
After commit
e623c4303ed1("gpiolib: sanitize the return value ofgpio_chip::get_direction()"), a warning will be printed if the gpio driver does not implement this callback.Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is.
Signed-off-by Chen-Yu Tsai <[email protected]>---
Quoted 3 lines · On Tue, 17 Feb 2026 00:09:45 +0800 Chen-Yu Tsai <[email protected]> wrote:
After commit
e623c4303ed1("gpiolib: sanitize the return value ofgpio_chip::get_direction()"), a warning will be printed if the gpio driver does not implement this callback.
I am curious how this could slip through? Did the get_direction() callback become mandatory at one point, but no one noticed that it was missing for sunxi? It looks like the situation was even worse before that patch, as it was dereferencing the function pointer without any check?
Quoted 3 lines
Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is.
Mmh, it feels a bit backwards to resort to the function name *string* for comparison, when it's always 0 for in and 1 for out (which we actually set in pinctrl-sunxi-dt.c now). But the mux value for IRQ is different between SoC generations, and I guess for historic reasons function strings are a thing in pinctrl, so this is probably the best solution after all:
Quoted 1 line
Signed-off-by Chen-Yu Tsai <[email protected]>
FWIW:
Cheers,
Andre
P.S. Should we have some CC: stable tag here?
Quoted 83 lines
---
This is an alternative to James's version. My version does one lookup instead of three.drivers/pinctrl/sunxi/pinctrl-sunxi.c | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)drivers/pinctrl/sunxi/pinctrl-sunxi.c +51
-0@@ -204,6 +204,32 @@ sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,return NULL ; } +static struct sunxi_desc_function * +sunxi_pinctrl_desc_find_function_by_pin_and_mux (struct sunxi_pinctrl *pctl, +const u16 pin_num, +const u8 muxval) +{ +for (unsigned int i =0 ; i < pctl->desc->npins; i++) { +const struct sunxi_desc_pin *pin = pctl->desc->pins + i; +struct sunxi_desc_function *func = pin->functions; + +if (pin->pin.number != pin_num) +continue ; + +if (pin->variant && !(pctl->variant & pin->variant)) +continue ; + +while (func->name) { +if (func->muxval == muxval) +return func; + + func++; + } + } + +return NULL ; +} +static int sunxi_pctrl_get_groups_count (struct pinctrl_dev *pctldev) {struct sunxi_pinctrl *pctl =pinctrl_dev_get_drvdata (pctldev);@@ -930,6 +956,30 @@ static const struct pinmux_ops sunxi_pmx_ops = { .strict = true, }; +static int sunxi_pinctrl_gpio_get_direction (struct gpio_chip *chip, +unsigned int offset) +{ +struct sunxi_pinctrl *pctl =gpiochip_get_data (chip); +const struct sunxi_desc_function *func; +u32 pin = offset + chip->base; +u32 reg, shift, mask; +u8 muxval; + +sunxi_mux_reg (pctl, offset, ®, &shift, &mask); + + muxval = (readl (pctl->membase + reg) & mask) >> shift; + + func =sunxi_pinctrl_desc_find_function_by_pin_and_mux (pctl, pin, muxval); +if (!func) +return -ENODEV ; + +if (!strcmp (func->name,"gpio_out" )) +return GPIO_LINE_DIRECTION_OUT ; +if (!strcmp (func->name,"gpio_in" ) || !strcmp (func->name,"irq" )) +return GPIO_LINE_DIRECTION_IN ; +return -EINVAL ; +} +static int sunxi_pinctrl_gpio_direction_input (struct gpio_chip *chip,unsigned offset) {@@ -1601,6 +1651,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_device *pdev, pctl->chip->request = gpiochip_generic_request; pctl->chip->free = gpiochip_generic_free; pctl->chip->set_config = gpiochip_generic_config; + pctl->chip->get_direction = sunxi_pinctrl_gpio_get_direction; pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; pctl->chip->get = sunxi_pinctrl_gpio_get;
Chen-Yu Tsai
maintainerQuoted 4 lines · Andre Przywara
On Tue, 17 Feb 2026 00:09:45 +0800
Chen-Yu Tsai <[email protected]> wrote:
Quoted 8 lines
Quoted 3 lines
After commit
e623c4303ed1("gpiolib: sanitize the return value ofgpio_chip::get_direction()"), a warning will be printed if the gpio driver does not implement this callback.I am curious how this could slip through? Did the
get_direction()callback become mandatory at one point, but no one noticed that it was missing for sunxi? It looks like the situation was even worse before that patch, as it was dereferencing the function pointer without any check?
Digging deeper, my attribution is incorrect. The actual commit that triggers the warning is 471e998c0e31 ("gpiolib: remove redundant callback check"), in which a check of .get_direction before calling it was removed. So I believe this just landed for the next release.
Thanks for spotting that. I'll send a v2 to add that information.
Quoted 9 lines
Quoted 3 lines
Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is.
Mmh, it feels a bit backwards to resort to the function name *string* for comparison, when it's always 0 for in and 1 for out (which we actually set in
pinctrl-sunxi-dt.cnow). But the mux value for IRQ is different between SoC generations, and I guess for historic reasons function strings are a thing in pinctrl, so this is probably the best solution after all:
Yeah, I was a bit undecided, but using the raw values for in / out and then having a string comparison for irq made things even weirder.
Quoted 4 lines
Quoted 1 line
Signed-off-by Chen-Yu Tsai <[email protected]>FWIW:
Reviewed-by Andre Przywara <[email protected]>
Thanks!
Linus Walleij
maintainerQuoted 9 lines · Chen-Yu Tsai
After commit
e623c4303ed1("gpiolib: sanitize the return value ofgpio_chip::get_direction()"), a warning will be printed if the gpio driver does not implement this callback.Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is.
Signed-off-by Chen-Yu Tsai <[email protected]>
Patch applied for fixes since everyone likes this patch and everyone is unhappy with the warning.
Yours,
Linus Walleij
Chen-Yu Tsai
maintainerHi Linus,
Quoted 7 lines · Linus Walleij
Quoted 4 lines · Chen-Yu Tsai
After commit
e623c4303ed1("gpiolib: sanitize the return value ofgpio_chip::get_direction()"), a warning will be printed if the gpio driver does not implement this callback.
Quoted 8 lines
Quoted 5 lines
Implement it for the sunxi driver. This is simply a matter of reading out the mux value from the registers, then checking if it is one of the GPIO functions and which direction it is.
Signed-off-by Chen-Yu Tsai <[email protected]>Patch applied for fixes since everyone likes this patch and everyone is unhappy with the warning.
I was about to send v2 with an updated commit message but didn't get around to sending it out. Would you consider dropping this one?
Sorry about the delay.
ChenYu