In Linux DT,the pinctrl node acts as parent nodes with all other gpio banks as child nodes and a single driver in Linux handles both pinctrl settings and gpio requests.Current U-Boot DT maintains both pinctrl and gpio nodes as separate nodes and offers two different class of U-Boot drivers: UCLASS_PINCTRL which handles pin functions and UCLASS_GPIO which handles gpio requests. In order to align the DT of U-Boot with the DT of Linux, a hook is been added in the pinctrl driver to bind the gpio driver with the pinctrl driver so that when adding gpio nodes as subnodes to pinctrl node (as per the Linux ABI), the corresponding APIs will be redirected and handled by valid drivers attached to the pinctrl driver.
Signed-off-by: Manikandan Muralidharan <manikanda...@microchip.com> --- drivers/pinctrl/pinctrl-at91.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 5038cb535e3..2afa1b66821 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -9,6 +9,8 @@ #include <dm.h> #include <log.h> #include <asm/global_data.h> +#include <dm/device-internal.h> +#include <dm/lists.h> #include <dm/pinctrl.h> #include <asm/hardware.h> #include <linux/bitops.h> @@ -492,6 +494,30 @@ const struct pinctrl_ops at91_pinctrl_ops = { .set_state = at91_pinctrl_set_state, }; +/** + * at91_pinctrl_bind() - Iterates through all subnodes of the pinctrl device + * in the DT and binds them to U-Boot's device model. Each subnode + * typically represents a GPIO controller or pin configuration data. + * + * @dev: Pointer to the pinctrl device + * + * Returns 0 on success or negative error on failure + */ +static int at91_pinctrl_bind(struct udevice *dev) +{ + ofnode gpio_node; + struct udevice *gpio; + int ret; + + ofnode_for_each_subnode(gpio_node, dev_ofnode(dev)) { + ret = lists_bind_fdt(dev, gpio_node, &gpio, NULL, false); + if (ret) + return ret; + } + + return 0; +} + static int at91_pinctrl_probe(struct udevice *dev) { struct at91_pinctrl_priv *priv = dev_get_priv(dev); @@ -524,6 +550,7 @@ U_BOOT_DRIVER(atmel_sama5d3_pinctrl) = { .id = UCLASS_PINCTRL, .of_match = at91_pinctrl_match, .probe = at91_pinctrl_probe, + .bind = at91_pinctrl_bind, .priv_auto = sizeof(struct at91_pinctrl_priv), .ops = &at91_pinctrl_ops, }; -- 2.25.1