All of lore.kernel.org
 help / color / mirror / Atom feed
From: Geert Uytterhoeven <geert+renesas@glider.be>
To: Peter Maydell <peter.maydell@linaro.org>,
	Alex Williamson <alex.williamson@redhat.com>
Cc: Eric Auger <eric.auger@redhat.com>,
	Magnus Damm <damm+renesas@opensource.se>,
	Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,
	Wolfram Sang <wsa+renesas@sang-engineering.com>,
	Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>,
	qemu-arm@nongnu.org, qemu-devel@nongnu.org,
	linux-renesas-soc@vger.kernel.org,
	Geert Uytterhoeven <geert+renesas@glider.be>
Subject: [PATCH QEMU v5] hw/arm/sysbus-fdt: Add support for instantiating generic devices
Date: Thu,  3 Jan 2019 10:42:11 +0100	[thread overview]
Message-ID: <20190103094211.28473-1-geert+renesas@glider.be> (raw)

Add a fallback for instantiating generic devices without a type-specific
or compatible-specific instantiation method.  This will be used when no
other match is found.

Generic device instantiation avoids having to write device-specific
instantiation methods for each and every "simple" device using only a
set of generic properties.  Devices that need more specialized handling
can still provide their own instantiation methods.

The generic instantiation method creates a device node with remapped
"reg" and (optional) "interrupts" properties, and copies properties from
the host, if deemed appropriate:
  - In general, properties without phandles are safe to be copied.
    Unfortunately, the FDT does not carry type information, hence an
    explicit whitelist is used, which can be extended when needed.
  - Properties related to power management (power and/or clock domain),
    isolation, and pin control, are handled by the host, and must not to
    be copied.

Devices nodes with subnodes are rejected, as subnodes cannot easily be
handled in a generic way.

This has been tested on a Renesas Salvator-XS board (R-Car H3 ES2.0)
with SATA, using:

    -device vfio-platform,host=ee300000.sata

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Note: Also tested with GPIO, which needs "vfio: No-IOMMU mode support":

    -device vfio-platform,host=e6055400.gpio

v5:
  - Replace copying of a fixed list of properties (and ignoring all
    others), by scanning all properties on the host, and deciding if
    they need to be ignored, copied, or rejected,
  - Reject device nodes with subnodes,
  - Handle edge interrupts,

v3:
  - New.
---
 hw/arm/sysbus-fdt.c | 238 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 238 insertions(+)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index ad698d4832c694be..52de8c9a040c282a 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -28,6 +28,9 @@
 #ifdef CONFIG_LINUX
 #include <linux/vfio.h>
 #endif
+#ifdef CONFIG_FNMATCH
+#include <fnmatch.h>
+#endif
 #include "hw/arm/sysbus-fdt.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
@@ -415,6 +418,232 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
     return 0;
 }
 
+enum GenericPropertyAction {
+    PROP_IGNORE,
+    PROP_WARN,
+    PROP_COPY,
+    PROP_REJECT,
+};
+
+static struct {
+    const char *name;
+    enum GenericPropertyAction action;
+} generic_properties[] = {
+    { "name",            PROP_IGNORE }, /* handled automatically */
+    { "phandle",         PROP_IGNORE }, /* not needed for the generic case */
+
+    /* The following are copied and remapped by dedicated code */
+    { "reg",             PROP_IGNORE },
+    { "interrupts",      PROP_IGNORE },
+
+    /* The following are handled by the host */
+    { "power-domains",   PROP_IGNORE }, /* power management (+ opt. clocks) */
+    { "iommus",          PROP_IGNORE }, /* isolation */
+    { "resets",          PROP_IGNORE }, /* isolation */
+    { "pinctrl-*",       PROP_IGNORE }, /* pin control */
+
+    /* Ignoring the following may or may not work, hence the warning */
+    { "gpio-ranges",     PROP_WARN },   /* no support for pinctrl yet */
+    { "dmas",            PROP_WARN },   /* no support for external DMACs yet */
+
+    /* The following are irrelevant, as corresponding specifiers are ignored */
+    { "clock-names",     PROP_IGNORE },
+    { "reset-names",     PROP_IGNORE },
+    { "dma-names",       PROP_IGNORE },
+
+    /* Whitelist of properties not taking phandles, and thus safe to copy */
+    { "compatible",      PROP_COPY },
+    { "status",          PROP_COPY },
+    { "reg-names",       PROP_COPY },
+    { "interrupt-names", PROP_COPY },
+    { "#*-cells",        PROP_COPY },
+};
+
+#ifndef CONFIG_FNMATCH
+/* Fall back to exact string matching instead of allowing wildcards */
+static inline int fnmatch(const char *pattern, const char *string, int flags)
+{
+        return strcmp(pattern, string);
+}
+#endif
+
+static enum GenericPropertyAction get_generic_property_action(const char *name)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(generic_properties); i++) {
+        if (!fnmatch(generic_properties[i].name, name, 0)) {
+            return generic_properties[i].action;
+        }
+    }
+
+    /*
+     * Unfortunately DT properties do not carry type information,
+     * so we have to assume everything else contains a phandle,
+     * and must be rejected
+     */
+    return PROP_REJECT;
+}
+
+/**
+ * copy_generic_node
+ *
+ * Copy the generic part of a DT node from the host
+ */
+static void copy_generic_node(void *host_fdt, void *guest_fdt, char *host_path,
+                              char *guest_path)
+{
+    int node, prop, len;
+    const void *data;
+    const char *name;
+    enum GenericPropertyAction action;
+
+    node = fdt_path_offset(host_fdt, host_path);
+    if (node < 0) {
+        error_report("Cannot find node %s: %s", host_path, fdt_strerror(node));
+        exit(1);
+    }
+
+    /* Submodes are not yet supported */
+    if (fdt_first_subnode(host_fdt, node) >= 0) {
+        error_report("%s has unsupported subnodes", host_path);
+        goto unsupported;
+    }
+
+    /* Copy generic properties */
+    fdt_for_each_property_offset(prop, host_fdt, node) {
+        data = fdt_getprop_by_offset(host_fdt, prop, &name, &len);
+        if (!data) {
+            error_report("Cannot get property of %s: %s", host_path,
+                         fdt_strerror(len));
+            exit(1);
+        }
+
+        if (!len) {
+            /* Zero-sized properties are safe to copy */
+            action = PROP_COPY;
+        } else if (!strcmp(name, "clocks")) {
+            /* Reject "clocks" if "power-domains" is not present */
+            action = fdt_getprop(host_fdt, node, "power-domains", NULL)
+                     ? PROP_WARN : PROP_REJECT;
+        } else {
+            action = get_generic_property_action(name);
+        }
+
+        switch (action) {
+        case PROP_WARN:
+            warn_report("%s: Ignoring %s property", host_path, name);
+        case PROP_IGNORE:
+            break;
+
+        case PROP_COPY:
+            qemu_fdt_setprop(guest_fdt, guest_path, name, data, len);
+            break;
+
+        case PROP_REJECT:
+            error_report("%s has unsupported %s property", host_path, name);
+            goto unsupported;
+        }
+    }
+    return;
+
+unsupported:
+    error_report("You can ask a wizard to enhance me");
+    exit(1);
+}
+
+/**
+ * add_generic_fdt_node
+ *
+ * Generates a generic DT node by copying properties from the host
+ */
+static int add_generic_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+    PlatformBusFDTData *data = opaque;
+    VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
+    const char *parent_node = data->pbus_node_name;
+    void *guest_fdt = data->fdt, *host_fdt;
+    VFIODevice *vbasedev = &vdev->vbasedev;
+    char **node_path, *node_name, *dt_name;
+    PlatformBusDevice *pbus = data->pbus;
+    uint32_t *reg_attr, *irq_attr;
+    uint64_t mmio_base;
+    int i, irq_number;
+    VFIOINTp *intp;
+
+    host_fdt = load_device_tree_from_sysfs();
+
+    dt_name = sysfs_to_dt_name(vbasedev->name);
+    if (!dt_name) {
+        error_report("%s incorrect sysfs device name %s", __func__,
+                     vbasedev->name);
+        exit(1);
+    }
+    node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
+                                   &error_fatal);
+    if (!node_path || !node_path[0]) {
+        error_report("%s unable to retrieve node path for %s/%s", __func__,
+                     dt_name, vdev->compat);
+        exit(1);
+    }
+
+    if (node_path[1]) {
+        error_report("%s more than one node matching %s/%s!", __func__,
+                     dt_name, vdev->compat);
+        exit(1);
+    }
+
+    mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+    node_name = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
+                               vbasedev->name, mmio_base);
+    qemu_fdt_add_subnode(guest_fdt, node_name);
+
+    /* Copy generic parts from host */
+    copy_generic_node(host_fdt, guest_fdt, node_path[0], node_name);
+
+    /* Copy reg (remapped) */
+    reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
+    for (i = 0; i < vbasedev->num_regions; i++) {
+        mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
+        reg_attr[2 * i] = cpu_to_be32(mmio_base);
+        reg_attr[2 * i + 1] = cpu_to_be32(
+                                memory_region_size(vdev->regions[i]->mem));
+    }
+    qemu_fdt_setprop(guest_fdt, node_name, "reg", reg_attr,
+                     vbasedev->num_regions * 2 * sizeof(uint32_t));
+
+    /* Copy interrupts (remapped) */
+    if (vbasedev->num_irqs) {
+        irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
+        for (i = 0; i < vbasedev->num_irqs; i++) {
+            irq_number = platform_bus_get_irqn(pbus, sbdev, i) +
+                         data->irq_start;
+            irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
+            irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
+            QLIST_FOREACH(intp, &vdev->intp_list, next) {
+                if (intp->pin == i) {
+                    break;
+                }
+            }
+            if (intp->flags & VFIO_IRQ_INFO_AUTOMASKED) {
+                irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+            } else {
+                irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+            }
+        }
+        qemu_fdt_setprop(guest_fdt, node_name, "interrupts",
+                         irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
+        g_free(irq_attr);
+    }
+
+    g_free(reg_attr);
+    g_free(node_name);
+    g_strfreev(node_path);
+    g_free(dt_name);
+    g_free(host_fdt);
+    return 0;
+}
+
 /* DT compatible matching */
 static bool vfio_platform_match(SysBusDevice *sbdev,
                                 const BindingEntry *entry)
@@ -423,6 +652,11 @@ static bool vfio_platform_match(SysBusDevice *sbdev,
     const char *compat;
     unsigned int n;
 
+    if (!entry->compat) {
+        /* Generic DT fallback */
+        return true;
+    }
+
     for (n = vdev->num_compat, compat = vdev->compat; n > 0;
          n--, compat += strlen(compat) + 1) {
         if (!strcmp(entry->compat, compat)) {
@@ -459,6 +693,10 @@ static const BindingEntry bindings[] = {
     VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
 #endif
     TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
+#ifdef CONFIG_LINUX
+    /* Generic DT fallback must be last */
+    VFIO_PLATFORM_BINDING(NULL, add_generic_fdt_node),
+#endif
     TYPE_BINDING("", NULL), /* last element */
 };
 
-- 
2.17.1


WARNING: multiple messages have this Message-ID (diff)
From: Geert Uytterhoeven <geert+renesas@glider.be>
To: Peter Maydell <peter.maydell@linaro.org>,
	Alex Williamson <alex.williamson@redhat.com>
Cc: Eric Auger <eric.auger@redhat.com>,
	Magnus Damm <damm+renesas@opensource.se>,
	Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>,
	Wolfram Sang <wsa+renesas@sang-engineering.com>,
	Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>,
	qemu-arm@nongnu.org, qemu-devel@nongnu.org,
	linux-renesas-soc@vger.kernel.org,
	Geert Uytterhoeven <geert+renesas@glider.be>
Subject: [Qemu-devel] [PATCH QEMU v5] hw/arm/sysbus-fdt: Add support for instantiating generic devices
Date: Thu,  3 Jan 2019 10:42:11 +0100	[thread overview]
Message-ID: <20190103094211.28473-1-geert+renesas@glider.be> (raw)

Add a fallback for instantiating generic devices without a type-specific
or compatible-specific instantiation method.  This will be used when no
other match is found.

Generic device instantiation avoids having to write device-specific
instantiation methods for each and every "simple" device using only a
set of generic properties.  Devices that need more specialized handling
can still provide their own instantiation methods.

The generic instantiation method creates a device node with remapped
"reg" and (optional) "interrupts" properties, and copies properties from
the host, if deemed appropriate:
  - In general, properties without phandles are safe to be copied.
    Unfortunately, the FDT does not carry type information, hence an
    explicit whitelist is used, which can be extended when needed.
  - Properties related to power management (power and/or clock domain),
    isolation, and pin control, are handled by the host, and must not to
    be copied.

Devices nodes with subnodes are rejected, as subnodes cannot easily be
handled in a generic way.

This has been tested on a Renesas Salvator-XS board (R-Car H3 ES2.0)
with SATA, using:

    -device vfio-platform,host=ee300000.sata

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Note: Also tested with GPIO, which needs "vfio: No-IOMMU mode support":

    -device vfio-platform,host=e6055400.gpio

v5:
  - Replace copying of a fixed list of properties (and ignoring all
    others), by scanning all properties on the host, and deciding if
    they need to be ignored, copied, or rejected,
  - Reject device nodes with subnodes,
  - Handle edge interrupts,

v3:
  - New.
---
 hw/arm/sysbus-fdt.c | 238 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 238 insertions(+)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index ad698d4832c694be..52de8c9a040c282a 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -28,6 +28,9 @@
 #ifdef CONFIG_LINUX
 #include <linux/vfio.h>
 #endif
+#ifdef CONFIG_FNMATCH
+#include <fnmatch.h>
+#endif
 #include "hw/arm/sysbus-fdt.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
@@ -415,6 +418,232 @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
     return 0;
 }
 
+enum GenericPropertyAction {
+    PROP_IGNORE,
+    PROP_WARN,
+    PROP_COPY,
+    PROP_REJECT,
+};
+
+static struct {
+    const char *name;
+    enum GenericPropertyAction action;
+} generic_properties[] = {
+    { "name",            PROP_IGNORE }, /* handled automatically */
+    { "phandle",         PROP_IGNORE }, /* not needed for the generic case */
+
+    /* The following are copied and remapped by dedicated code */
+    { "reg",             PROP_IGNORE },
+    { "interrupts",      PROP_IGNORE },
+
+    /* The following are handled by the host */
+    { "power-domains",   PROP_IGNORE }, /* power management (+ opt. clocks) */
+    { "iommus",          PROP_IGNORE }, /* isolation */
+    { "resets",          PROP_IGNORE }, /* isolation */
+    { "pinctrl-*",       PROP_IGNORE }, /* pin control */
+
+    /* Ignoring the following may or may not work, hence the warning */
+    { "gpio-ranges",     PROP_WARN },   /* no support for pinctrl yet */
+    { "dmas",            PROP_WARN },   /* no support for external DMACs yet */
+
+    /* The following are irrelevant, as corresponding specifiers are ignored */
+    { "clock-names",     PROP_IGNORE },
+    { "reset-names",     PROP_IGNORE },
+    { "dma-names",       PROP_IGNORE },
+
+    /* Whitelist of properties not taking phandles, and thus safe to copy */
+    { "compatible",      PROP_COPY },
+    { "status",          PROP_COPY },
+    { "reg-names",       PROP_COPY },
+    { "interrupt-names", PROP_COPY },
+    { "#*-cells",        PROP_COPY },
+};
+
+#ifndef CONFIG_FNMATCH
+/* Fall back to exact string matching instead of allowing wildcards */
+static inline int fnmatch(const char *pattern, const char *string, int flags)
+{
+        return strcmp(pattern, string);
+}
+#endif
+
+static enum GenericPropertyAction get_generic_property_action(const char *name)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(generic_properties); i++) {
+        if (!fnmatch(generic_properties[i].name, name, 0)) {
+            return generic_properties[i].action;
+        }
+    }
+
+    /*
+     * Unfortunately DT properties do not carry type information,
+     * so we have to assume everything else contains a phandle,
+     * and must be rejected
+     */
+    return PROP_REJECT;
+}
+
+/**
+ * copy_generic_node
+ *
+ * Copy the generic part of a DT node from the host
+ */
+static void copy_generic_node(void *host_fdt, void *guest_fdt, char *host_path,
+                              char *guest_path)
+{
+    int node, prop, len;
+    const void *data;
+    const char *name;
+    enum GenericPropertyAction action;
+
+    node = fdt_path_offset(host_fdt, host_path);
+    if (node < 0) {
+        error_report("Cannot find node %s: %s", host_path, fdt_strerror(node));
+        exit(1);
+    }
+
+    /* Submodes are not yet supported */
+    if (fdt_first_subnode(host_fdt, node) >= 0) {
+        error_report("%s has unsupported subnodes", host_path);
+        goto unsupported;
+    }
+
+    /* Copy generic properties */
+    fdt_for_each_property_offset(prop, host_fdt, node) {
+        data = fdt_getprop_by_offset(host_fdt, prop, &name, &len);
+        if (!data) {
+            error_report("Cannot get property of %s: %s", host_path,
+                         fdt_strerror(len));
+            exit(1);
+        }
+
+        if (!len) {
+            /* Zero-sized properties are safe to copy */
+            action = PROP_COPY;
+        } else if (!strcmp(name, "clocks")) {
+            /* Reject "clocks" if "power-domains" is not present */
+            action = fdt_getprop(host_fdt, node, "power-domains", NULL)
+                     ? PROP_WARN : PROP_REJECT;
+        } else {
+            action = get_generic_property_action(name);
+        }
+
+        switch (action) {
+        case PROP_WARN:
+            warn_report("%s: Ignoring %s property", host_path, name);
+        case PROP_IGNORE:
+            break;
+
+        case PROP_COPY:
+            qemu_fdt_setprop(guest_fdt, guest_path, name, data, len);
+            break;
+
+        case PROP_REJECT:
+            error_report("%s has unsupported %s property", host_path, name);
+            goto unsupported;
+        }
+    }
+    return;
+
+unsupported:
+    error_report("You can ask a wizard to enhance me");
+    exit(1);
+}
+
+/**
+ * add_generic_fdt_node
+ *
+ * Generates a generic DT node by copying properties from the host
+ */
+static int add_generic_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+    PlatformBusFDTData *data = opaque;
+    VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
+    const char *parent_node = data->pbus_node_name;
+    void *guest_fdt = data->fdt, *host_fdt;
+    VFIODevice *vbasedev = &vdev->vbasedev;
+    char **node_path, *node_name, *dt_name;
+    PlatformBusDevice *pbus = data->pbus;
+    uint32_t *reg_attr, *irq_attr;
+    uint64_t mmio_base;
+    int i, irq_number;
+    VFIOINTp *intp;
+
+    host_fdt = load_device_tree_from_sysfs();
+
+    dt_name = sysfs_to_dt_name(vbasedev->name);
+    if (!dt_name) {
+        error_report("%s incorrect sysfs device name %s", __func__,
+                     vbasedev->name);
+        exit(1);
+    }
+    node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
+                                   &error_fatal);
+    if (!node_path || !node_path[0]) {
+        error_report("%s unable to retrieve node path for %s/%s", __func__,
+                     dt_name, vdev->compat);
+        exit(1);
+    }
+
+    if (node_path[1]) {
+        error_report("%s more than one node matching %s/%s!", __func__,
+                     dt_name, vdev->compat);
+        exit(1);
+    }
+
+    mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+    node_name = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
+                               vbasedev->name, mmio_base);
+    qemu_fdt_add_subnode(guest_fdt, node_name);
+
+    /* Copy generic parts from host */
+    copy_generic_node(host_fdt, guest_fdt, node_path[0], node_name);
+
+    /* Copy reg (remapped) */
+    reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
+    for (i = 0; i < vbasedev->num_regions; i++) {
+        mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
+        reg_attr[2 * i] = cpu_to_be32(mmio_base);
+        reg_attr[2 * i + 1] = cpu_to_be32(
+                                memory_region_size(vdev->regions[i]->mem));
+    }
+    qemu_fdt_setprop(guest_fdt, node_name, "reg", reg_attr,
+                     vbasedev->num_regions * 2 * sizeof(uint32_t));
+
+    /* Copy interrupts (remapped) */
+    if (vbasedev->num_irqs) {
+        irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
+        for (i = 0; i < vbasedev->num_irqs; i++) {
+            irq_number = platform_bus_get_irqn(pbus, sbdev, i) +
+                         data->irq_start;
+            irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
+            irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
+            QLIST_FOREACH(intp, &vdev->intp_list, next) {
+                if (intp->pin == i) {
+                    break;
+                }
+            }
+            if (intp->flags & VFIO_IRQ_INFO_AUTOMASKED) {
+                irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
+            } else {
+                irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+            }
+        }
+        qemu_fdt_setprop(guest_fdt, node_name, "interrupts",
+                         irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
+        g_free(irq_attr);
+    }
+
+    g_free(reg_attr);
+    g_free(node_name);
+    g_strfreev(node_path);
+    g_free(dt_name);
+    g_free(host_fdt);
+    return 0;
+}
+
 /* DT compatible matching */
 static bool vfio_platform_match(SysBusDevice *sbdev,
                                 const BindingEntry *entry)
@@ -423,6 +652,11 @@ static bool vfio_platform_match(SysBusDevice *sbdev,
     const char *compat;
     unsigned int n;
 
+    if (!entry->compat) {
+        /* Generic DT fallback */
+        return true;
+    }
+
     for (n = vdev->num_compat, compat = vdev->compat; n > 0;
          n--, compat += strlen(compat) + 1) {
         if (!strcmp(entry->compat, compat)) {
@@ -459,6 +693,10 @@ static const BindingEntry bindings[] = {
     VFIO_PLATFORM_BINDING("amd,xgbe-seattle-v1a", add_amd_xgbe_fdt_node),
 #endif
     TYPE_BINDING(TYPE_RAMFB_DEVICE, no_fdt_node),
+#ifdef CONFIG_LINUX
+    /* Generic DT fallback must be last */
+    VFIO_PLATFORM_BINDING(NULL, add_generic_fdt_node),
+#endif
     TYPE_BINDING("", NULL), /* last element */
 };
 
-- 
2.17.1

             reply	other threads:[~2019-01-03  9:42 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-03  9:42 Geert Uytterhoeven [this message]
2019-01-03  9:42 ` [Qemu-devel] [PATCH QEMU v5] hw/arm/sysbus-fdt: Add support for instantiating generic devices Geert Uytterhoeven
2019-01-09 15:55 ` Auger Eric
2019-01-09 15:55   ` [Qemu-devel] " Auger Eric
2019-01-09 16:03   ` Peter Maydell
2019-01-09 16:03     ` [Qemu-devel] " Peter Maydell
2019-01-09 16:30     ` Geert Uytterhoeven
2019-01-09 16:30       ` [Qemu-devel] " Geert Uytterhoeven
2019-01-09 23:28       ` Peter Maydell
2019-01-09 23:28         ` [Qemu-devel] " Peter Maydell
2019-01-09 16:15   ` Geert Uytterhoeven
2019-01-09 16:15     ` [Qemu-devel] " Geert Uytterhoeven
2019-01-09 17:13     ` Auger Eric
2019-01-09 17:13       ` [Qemu-devel] " Auger Eric
2019-01-09 17:16   ` Auger Eric

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190103094211.28473-1-geert+renesas@glider.be \
    --to=geert+renesas@glider.be \
    --cc=alex.williamson@redhat.com \
    --cc=damm+renesas@opensource.se \
    --cc=eric.auger@redhat.com \
    --cc=kieran.bingham+renesas@ideasonboard.com \
    --cc=laurent.pinchart+renesas@ideasonboard.com \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=wsa+renesas@sang-engineering.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.