
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 manikandan.m@microchip.com --- drivers/pinctrl/pinctrl-at91.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 5038cb535e3..2b871143fc0 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,18 @@ const struct pinctrl_ops at91_pinctrl_ops = { .set_state = at91_pinctrl_set_state, };
+static int at91_pinctrl_bind(struct udevice *dev) +{ + ofnode gpio_node; + struct udevice *gpio; + + ofnode_for_each_subnode(gpio_node, dev_ofnode(dev)) { + lists_bind_fdt(dev, gpio_node, &gpio, NULL, false); + } + + return 0; +} + static int at91_pinctrl_probe(struct udevice *dev) { struct at91_pinctrl_priv *priv = dev_get_priv(dev); @@ -524,6 +538,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, };