Currently, driver binding stops once it encounters the first
compatible driver that doesn't refuse to bind. However, there are
cases where a single node will need to be handled by multiple driver
classes. For those cases we provide a configurable option to continue
to bind after the first driver has been found.

The first use cases for this are from the DM conversion of the sunxi
(Allwinner) architecture:
 * pinctrl (UCLASS_PINCTRL) and gpio (UCLASS_GPIO) drivers need to
   bind against a single node
 * clock (UCLASS_CLK) and reset (UCLASS_RESET) drivers also need to
   bind against a single node

Signed-off-by: Philipp Tomsich <philipp.toms...@theobroma-systems.com>
---
 drivers/core/Kconfig | 14 ++++++++++++++
 drivers/core/lists.c | 12 +++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index 8749561..913101c 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -31,6 +31,20 @@ config DM_WARN
          This will cause dm_warn() to be compiled out - it will do nothing
          when called.
 
+config DM_ALLOW_MULTIPLE_DRIVERS
+        bool "Allow multiple drivers to bind for one node"
+       depends on DM
+       default n
+       help
+         The driver model in U-Boot originally did not allow multiple
+         drivers to bind for a single device node.
+
+         If enabled, multiple drivers can now bind for a single node
+         by using the same compatible string for matching: lists_bind_fdt()
+         will assume that binding multiple drivers is desirable, if the
+         caller does not request the pointer to the udevice structure to
+         be returned (i.e. if devp is NULL).
+
 config DM_DEVICE_REMOVE
        bool "Support device removal"
        depends on DM
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index 23b6ba7..52efe69 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -166,7 +166,11 @@ int lists_bind_fdt(struct udevice *parent, const void 
*blob, int offset,
                dm_dbg("   - attempt to match compatible string '%s'\n",
                       compat);
 
-               for (entry = driver; entry != driver + n_ents; entry++) {
+               entry = driver;
+#if defined(CONFIG_DM_ALLOW_MULTIPLE_DRIVERS)
+       allow_more_matches:
+#endif
+               for (; entry != driver + n_ents; entry++) {
                        ret = driver_check_compatible(entry->of_match, &id,
                                                      compat);
                        if (!ret)
@@ -190,6 +194,12 @@ int lists_bind_fdt(struct udevice *parent, const void 
*blob, int offset,
                        found = true;
                        if (devp)
                                *devp = dev;
+#if defined(CONFIG_DM_ALLOW_MULTIPLE_DRIVERS)
+                       else {
+                               entry++;
+                               goto allow_more_matches;
+                       }
+#endif
                }
                break;
        }
-- 
1.9.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to