[PATCH v2 3/6] dm: core: Support multiple drivers with same compatibles

Simon Glass sjg at chromium.org
Fri Jan 9 12:36:16 CET 2026


Hi Markus,

On Thu, 8 Jan 2026 at 04:17, Markus Schneider-Pargmann (TI.com)
<msp at baylibre.com> wrote:
>
> Currently once a driver matched the compatible string of a device, other
> drivers are ignored. If the first matching driver returns -ENODEV, no
> other possibly matching drivers are iterated with that compatible of the
> device. Instead the next compatible in the list of compatibles is
> selected, assuming only one driver matches one compatible at a time.
>
> To be able to use the bind function to return -ENODEV and continue
> matching other drivers with the same compatible, move the for loop a bit
> to continue the for loop after -ENODEV was returned. The loop had to be
> adjusted a bit to still support the 'drv' argument properly. Some
> simplifications where done as well.
>
> This is required for ti-musb-host and ti-musb-peripheral which both
> match on the same device but differ based on the dr_mode DT property.
> Depending on this property, the driver is either UCLASS_USB or
> UCLASS_USB_GADGET_GENERIc. By checking the DT property in the bind
> function and returning -ENODEV the other driver can probe instead.
>
> Signed-off-by: Markus Schneider-Pargmann (TI.com) <msp at baylibre.com>
> ---
>  drivers/core/lists.c | 65 ++++++++++++++++++++++++++--------------------------
>  1 file changed, 33 insertions(+), 32 deletions(-)
>

Reviewed-by: Simon Glass <simon.glass at canonical.com>

I would like to see some discussion about performance here. It seems
that all you are doing here is not exiting the loop early, so the
impact should be small?

> diff --git a/drivers/core/lists.c b/drivers/core/lists.c
> index 9d1ca38212ee7f53b8894f964f096611c8ec20a5..3d9f9bc93954efdd624dddb1833f3a855c3c28de 100644
> --- a/drivers/core/lists.c
> +++ b/drivers/core/lists.c
> @@ -235,50 +235,51 @@ int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
>                 log_debug("   - attempt to match compatible string '%s'\n",
>                           compat);
>
> -               id = NULL;
>                 for (entry = driver; entry != driver + n_ents; entry++) {
> +                       /* Search for drivers with matching drv or existing of_match */
>                         if (drv) {
>                                 if (drv != entry)
>                                         continue;
> -                               if (!entry->of_match)
> -                                       break;
> +                       } else if (!entry->of_match) {
> +                               continue;
>                         }
> -                       ret = driver_check_compatible(entry->of_match, &id,
> -                                                     compat);
> -                       if (!ret)
> -                               break;
> -               }
> -               if (entry == driver + n_ents)
> -                       continue;
>
> -               if (pre_reloc_only) {
> -                       if (!ofnode_pre_reloc(node) &&
> -                           !(entry->flags & DM_FLAG_PRE_RELOC)) {
> -                               log_debug("Skipping device pre-relocation\n");
> -                               return 0;
> +                       id = NULL;
> +                       if (entry->of_match) {
> +                               ret = driver_check_compatible(entry->of_match, &id,
> +                                                             compat);
> +                               if (ret)
> +                                       continue;
> +                               log_debug("   - found match at driver '%s' for '%s'\n",
> +                                         entry->name, id->compatible);
> +                       }
> +
> +                       if (pre_reloc_only) {
> +                               if (!ofnode_pre_reloc(node) &&
> +                                   !(entry->flags & DM_FLAG_PRE_RELOC)) {
> +                                       log_debug("   - Skipping device pre-relocation\n");
> +                                       return 0;
> +                               }
> +                       }
> +
> +                       ret = device_bind_with_driver_data(parent, entry, name,
> +                                                          id ? id->data : 0, node,
> +                                                          &dev);
> +                       if (!drv && ret == -ENODEV) {
> +                               log_debug("   - Driver '%s' refuses to bind\n", entry->name);
> +                               continue;
> +                       }
> +                       if (ret) {
> +                               dm_warn("Error binding driver '%s': %d\n", entry->name,
> +                                       ret);
> +                               return log_msg_ret("bind", ret);
>                         }
> -               }
>
> -               if (entry->of_match)
> -                       log_debug("   - found match at driver '%s' for '%s'\n",
> -                                 entry->name, id->compatible);
> -               ret = device_bind_with_driver_data(parent, entry, name,
> -                                                  id ? id->data : 0, node,
> -                                                  &dev);
> -               if (ret == -ENODEV) {
> -                       log_debug("Driver '%s' refuses to bind\n", entry->name);
> -                       continue;
> -               }
> -               if (ret) {
> -                       dm_warn("Error binding driver '%s': %d\n", entry->name,
> -                               ret);
> -                       return log_msg_ret("bind", ret);
> -               } else {
>                         if (devp)
>                                 *devp = dev;
> +
>                         return 0;
>                 }
> -               break;
>         }
>
>         if (ret != -ENODEV)
>
> --
> 2.51.0
>

Regards,
Simon


More information about the U-Boot mailing list