From: Thierry Reding <tred...@nvidia.com>

Logical devices created by the host1x bus infrastructure don't need to
be associated with a device tree node. Doing so will cause the driver
core to attempt to hook up IOMMU operations and fail because it is not
a real device.

However, for backwards-compatibility, we need to provide various OF_*
uevent variables that were previously provided by of_device_uevent() and
which are parsed by libdrm in userspace when querying the available
devices. Do this by implementing a uevent callback for the host1x bus.

Signed-off-by: Thierry Reding <tred...@nvidia.com>
---
 drivers/gpu/host1x/bus.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c
index 6387302c1245..742aa9ff21b8 100644
--- a/drivers/gpu/host1x/bus.c
+++ b/drivers/gpu/host1x/bus.c
@@ -305,6 +305,36 @@ static int host1x_device_match(struct device *dev, struct 
device_driver *drv)
        return strcmp(dev_name(dev), drv->name) == 0;
 }
 
+static int host1x_device_uevent(struct device *dev,
+                               struct kobj_uevent_env *env)
+{
+       struct device_node *np = dev->parent->of_node;
+       unsigned int count = 0;
+       struct property *p;
+       const char *compat;
+
+       /*
+        * This duplicates most of of_device_uevent(), but the latter cannot
+        * be called from modules and operates on dev->of_node, which is not
+        * available in this case.
+        *
+        * Note that this is really only needed for backwards compatibility
+        * with libdrm, which parses this information from sysfs and will
+        * fail if it can't find the OF_FULLNAME, specifically.
+        */
+       add_uevent_var(env, "OF_NAME=%pOFn", np);
+       add_uevent_var(env, "OF_FULLNAME=%pOF", np);
+
+       of_property_for_each_string(np, "compatible", p, compat) {
+               add_uevent_var(env, "OF_COMPATIBLE_%u=%s", count, compat);
+               count++;
+       }
+
+       add_uevent_var(env, "OF_COMPATIBLE_N=%u", count);
+
+       return 0;
+}
+
 static int host1x_dma_configure(struct device *dev)
 {
        return of_dma_configure(dev, dev->of_node, true);
@@ -322,6 +352,7 @@ static const struct dev_pm_ops host1x_device_pm_ops = {
 struct bus_type host1x_bus_type = {
        .name = "host1x",
        .match = host1x_device_match,
+       .uevent = host1x_device_uevent,
        .dma_configure = host1x_dma_configure,
        .pm = &host1x_device_pm_ops,
 };
@@ -408,7 +439,6 @@ static int host1x_device_add(struct host1x *host1x,
        device->dev.dma_mask = &device->dev.coherent_dma_mask;
        dev_set_name(&device->dev, "%s", driver->driver.name);
        device->dev.release = host1x_device_release;
-       device->dev.of_node = host1x->dev->of_node;
        device->dev.bus = &host1x_bus_type;
        device->dev.parent = host1x->dev;
 
-- 
2.21.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to