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

Reply via email to