diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index ee4180d8db14..65c389d9c85d 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -485,11 +485,16 @@ static int tegra_dpaux_probe(struct platform_device *pdev) return err; } - dpaux->vdd = devm_regulator_get(&pdev->dev, "vdd"); + dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd"); if (IS_ERR(dpaux->vdd)) { - dev_err(&pdev->dev, "failed to get VDD supply: %ld\n", - PTR_ERR(dpaux->vdd)); - return PTR_ERR(dpaux->vdd); + if (PTR_ERR(dpaux->vdd) != -ENODEV) { + if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER) + dev_err(&pdev->dev, + "failed to get VDD supply: %ld\n", + PTR_ERR(dpaux->vdd)); + + return PTR_ERR(dpaux->vdd); + } } platform_set_drvdata(pdev, dpaux); diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 70154c253d45..488f36f00bd8 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -127,8 +127,7 @@ struct tegra_output { const struct edid *edid; struct cec_notifier *cec; unsigned int hpd_irq; - int hpd_gpio; - enum of_gpio_flags hpd_gpio_flags; + struct gpio_desc *hpd_gpio; struct drm_encoder encoder; struct drm_connector connector; diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c index 9c2b9dad55c3..e4d242ca27b8 100644 --- a/drivers/gpu/drm/tegra/output.c +++ b/drivers/gpu/drm/tegra/output.c @@ -53,18 +53,11 @@ tegra_output_connector_detect(struct drm_connector *connector, bool force) struct tegra_output *output = connector_to_output(connector); enum drm_connector_status status = connector_status_unknown; - if (gpio_is_valid(output->hpd_gpio)) { - if (output->hpd_gpio_flags & OF_GPIO_ACTIVE_LOW) { - if (gpio_get_value(output->hpd_gpio) != 0) - status = connector_status_disconnected; - else - status = connector_status_connected; - } else { - if (gpio_get_value(output->hpd_gpio) == 0) - status = connector_status_disconnected; - else - status = connector_status_connected; - } + if (output->hpd_gpio) { + if (gpiod_get_value(output->hpd_gpio) == 0) + status = connector_status_disconnected; + else + status = connector_status_connected; } else { if (!output->panel) status = connector_status_disconnected; @@ -102,6 +95,7 @@ static irqreturn_t hpd_irq(int irq, void *data) int tegra_output_probe(struct tegra_output *output) { struct device_node *ddc, *panel; + unsigned long flags; int err, size; if (!output->of_node) @@ -130,23 +124,18 @@ int tegra_output_probe(struct tegra_output *output) of_node_put(ddc); } - output->hpd_gpio = of_get_named_gpio_flags(output->of_node, - "nvidia,hpd-gpio", 0, - &output->hpd_gpio_flags); - if (gpio_is_valid(output->hpd_gpio)) { - unsigned long flags; + output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev, + output->of_node, + "nvidia,hpd-gpio", 0, + GPIOD_IN, + "HDMI hotplug detect"); + if (IS_ERR(output->hpd_gpio)) + return PTR_ERR(output->hpd_gpio); - err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN, - "HDMI hotplug detect"); + if (output->hpd_gpio) { + err = gpiod_to_irq(output->hpd_gpio); if (err < 0) { - dev_err(output->dev, "gpio_request_one(): %d\n", err); - return err; - } - - err = gpio_to_irq(output->hpd_gpio); - if (err < 0) { - dev_err(output->dev, "gpio_to_irq(): %d\n", err); - gpio_free(output->hpd_gpio); + dev_err(output->dev, "gpiod_to_irq(): %d\n", err); return err; } @@ -160,7 +149,6 @@ int tegra_output_probe(struct tegra_output *output) if (err < 0) { dev_err(output->dev, "failed to request IRQ#%u: %d\n", output->hpd_irq, err); - gpio_free(output->hpd_gpio); return err; } @@ -186,10 +174,8 @@ void tegra_output_remove(struct tegra_output *output) if (output->cec) cec_notifier_put(output->cec); - if (gpio_is_valid(output->hpd_gpio)) { + if (output->hpd_gpio) free_irq(output->hpd_irq, output); - gpio_free(output->hpd_gpio); - } if (output->ddc) put_device(&output->ddc->dev); @@ -209,7 +195,7 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output) * The connector is now registered and ready to receive hotplug events * so the hotplug interrupt can be enabled. */ - if (gpio_is_valid(output->hpd_gpio)) + if (output->hpd_gpio) enable_irq(output->hpd_irq); return 0; @@ -221,7 +207,7 @@ void tegra_output_exit(struct tegra_output *output) * The connector is going away, so the interrupt must be disabled to * prevent the hotplug interrupt handler from potentially crashing. */ - if (gpio_is_valid(output->hpd_gpio)) + if (output->hpd_gpio) disable_irq(output->hpd_irq); if (output->panel) diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 9797ccb0a073..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,12 +439,14 @@ 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; of_dma_configure(&device->dev, host1x->dev->of_node, true); + device->dev.dma_parms = &device->dma_parms; + dma_set_max_seg_size(&device->dev, SZ_4M); + err = host1x_device_parse_dt(device, driver); if (err < 0) { kfree(device); diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c index 070b30f72947..c0392672a842 100644 --- a/drivers/gpu/host1x/debug.c +++ b/drivers/gpu/host1x/debug.c @@ -162,9 +162,6 @@ static void host1x_debugfs_init(struct host1x *host1x) { struct dentry *de = debugfs_create_dir("tegra-host1x", NULL); - if (!de) - return; - /* Store the created entry */ host1x->debugfs = de; diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c index c55e2d634887..5a3f797240d4 100644 --- a/drivers/gpu/host1x/dev.c +++ b/drivers/gpu/host1x/dev.c @@ -247,8 +247,11 @@ static int host1x_probe(struct platform_device *pdev) host->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) { - dev_err(&pdev->dev, "failed to get clock\n"); err = PTR_ERR(host->clk); + + if (err != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to get clock: %d\n", err); + return err; } diff --git a/include/linux/host1x.h b/include/linux/host1x.h index cfff30b9a62e..e6eea45e1154 100644 --- a/include/linux/host1x.h +++ b/include/linux/host1x.h @@ -297,6 +297,8 @@ struct host1x_device { struct list_head clients; bool registered; + + struct device_dma_parameters dma_parms; }; static inline struct host1x_device *to_host1x_device(struct device *dev)