From 31fa25f100ec0ce25ccf61d1468928c64d1c2fd9 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 5 Jun 2019 10:47:16 +0200 Subject: gpu: host1x: Do not link logical devices to DT nodes 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 --- drivers/gpu/host1x/bus.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/host1x') diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index c9a637d9417e..66d60f943f33 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -316,6 +316,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); @@ -333,6 +363,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, }; @@ -419,7 +450,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; -- cgit v1.2.3