The platform bus currently matches a DPDK driver to a device only by
comparing the kernel driver name bound to the device against the DPDK
driver name. Devices bound to the generic vfio-platform kernel driver
all report the same driver name, which carries no device identity, so a
specific DPDK driver cannot claim its device this way.

Add of_device_is_compatible(), which reads the device-tree "compatible"
strings exposed under the device's of_node in sysfs and compares them
against a requested string. platform_bus_match() now falls back to
matching the DPDK driver name or its alias against these compatible
strings, letting a driver bind to a device identified by its
device-tree "compatible" value.

Signed-off-by: Gagandeep Singh <[email protected]>
---
 drivers/bus/platform/bus_platform_driver.h |  3 +-
 drivers/bus/platform/platform.c            | 67 +++++++++++++++++++++-
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/platform/bus_platform_driver.h 
b/drivers/bus/platform/bus_platform_driver.h
index e4dcbacf5e..8eabe4a1fd 100644
--- a/drivers/bus/platform/bus_platform_driver.h
+++ b/drivers/bus/platform/bus_platform_driver.h
@@ -121,7 +121,8 @@ static const char *pdrvinit_ ## nm ## _alias; \
 RTE_INIT(pdrvinitfn_ ##nm) \
 { \
        (platform_drv).driver.name = RTE_STR(nm); \
-       (platform_drv).driver.alias = pdrvinit_ ## nm ## _alias; \
+       if (pdrvinit_ ## nm ## _alias != NULL) \
+               (platform_drv).driver.alias = pdrvinit_ ## nm ## _alias; \
        rte_platform_register(&(platform_drv)); \
 } \
 RTE_PMD_EXPORT_NAME(nm)
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index 90d865a8df..78ca896526 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  * Copyright(C) 2023 Marvell.
+ * Copyright 2026 NXP
  */
 
 #include <uapi/linux/vfio.h>
@@ -230,6 +231,57 @@ of_resource_name(const char *dev_name, int index)
        return NULL;
 }
 
+/*
+ * Check whether any of the NUL-separated device-tree "compatible" strings
+ * exposed by the platform device matches the given string. A single pair of
+ * enclosing double quotes is stripped from the requested compatible so both
+ * quoted and unquoted spellings match the raw device-tree value.
+ */
+static bool
+of_device_is_compatible(const char *dev_name, const char *compat)
+{
+       char path[PATH_MAX], buf[BUFSIZ] = { };
+       char want[BUFSIZ];
+       const char *s;
+       size_t c_len;
+       FILE *f;
+       size_t len;
+
+       if (compat == NULL)
+               return false;
+
+       /* Copy the requested compatible, dropping a pair of enclosing quotes. 
*/
+       c_len = strlen(compat);
+       if (c_len >= 2 && compat[0] == '"' && compat[c_len - 1] == '"') {
+               c_len -= 2;
+               if (c_len >= sizeof(want))
+                       c_len = sizeof(want) - 1;
+               memcpy(want, compat + 1, c_len);
+               want[c_len] = '\0';
+       } else {
+               rte_strscpy(want, compat, sizeof(want));
+       }
+
+       snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH 
"/%s/of_node/compatible", dev_name);
+       f = fopen(path, "r");
+       if (f == NULL)
+               return false;
+
+       /* Read the raw contents, preserving embedded NULL separators. */
+       len = fread(buf, 1, sizeof(buf) - 1, f);
+       fclose(f);
+       if (len == 0)
+               return false;
+
+       /* Bound the walk by the read length: some kernels omit the trailing 
NULL. */
+       for (s = buf; s < buf + len; s += strlen(s) + 1) {
+               if (!strcmp(s, want))
+                       return true;
+       }
+
+       return false;
+}
+
 static int
 device_map_resources(struct rte_platform_device *pdev, unsigned int num)
 {
@@ -386,8 +438,21 @@ platform_bus_match(const struct rte_driver *drv, const 
struct rte_device *dev)
        }
 
        /* match by device name */
-       if (!strcmp(pdev->name, pdrv->driver.name))
+       if (!strcmp(pdev->name, pdrv->driver.name)) {
                match = true;
+               goto out;
+       }
+
+       /*
+        * The generic vfio-platform kernel driver name carries no device
+        * identity, so fall back to matching the device-tree "compatible"
+        * strings against the DPDK driver name or alias.
+        */
+       if (of_device_is_compatible(pdev->name, pdrv->driver.name) ||
+           of_device_is_compatible(pdev->name, pdrv->driver.alias)) {
+               match = true;
+               goto out;
+       }
 
 out:
        free(kdrv);
-- 
2.25.1

Reply via email to