diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c index 939e259d601d341ae7783f835f15fcc750474ba6..f661ba8f3fa05238d48e3639c2753a078aca1c58 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c @@ -169,6 +169,13 @@ static int opa362_probe(struct platform_device *pdev) dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(1) | BIT(0); + dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); + if (IS_ERR(dssdev->next)) { + if (PTR_ERR(dssdev->next) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to find video sink\n"); + return PTR_ERR(dssdev->next); + } + omapdss_device_register(dssdev); return 0; @@ -179,6 +186,8 @@ static int __exit opa362_remove(struct platform_device *pdev) struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *dssdev = &ddata->dssdev; + if (dssdev->next) + omapdss_device_put(dssdev->next); omapdss_device_unregister(&ddata->dssdev); WARN_ON(omapdss_device_is_enabled(dssdev)); diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c index 55549c5a5af2f1dc05b66b2fe93cba4dd95d2772..3be35ba564dab09cd3f4f277b5bcbbeb4c219646 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c @@ -192,6 +192,13 @@ static int tfp410_probe(struct platform_device *pdev) dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(1) | BIT(0); + dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); + if (IS_ERR(dssdev->next)) { + if (PTR_ERR(dssdev->next) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to find video sink\n"); + return PTR_ERR(dssdev->next); + } + omapdss_device_register(dssdev); return 0; @@ -202,6 +209,8 @@ static int __exit tfp410_remove(struct platform_device *pdev) struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *dssdev = &ddata->dssdev; + if (dssdev->next) + omapdss_device_put(dssdev->next); omapdss_device_unregister(&ddata->dssdev); WARN_ON(omapdss_device_is_enabled(dssdev)); diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c index 58a831c3f74ca7c1d40667164b6b1adbb4ed2b05..cee53346f6fcfe903f896a23c2a55bd8bf4d79e5 100644 --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c @@ -301,6 +301,13 @@ static int tpd_probe(struct platform_device *pdev) dssdev->owner = THIS_MODULE; dssdev->of_ports = BIT(1) | BIT(0); + dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1); + if (IS_ERR(dssdev->next)) { + if (PTR_ERR(dssdev->next) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to find video sink\n"); + return PTR_ERR(dssdev->next); + } + omapdss_device_register(dssdev); return 0; @@ -311,6 +318,8 @@ static int __exit tpd_remove(struct platform_device *pdev) struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *dssdev = &ddata->dssdev; + if (dssdev->next) + omapdss_device_put(dssdev->next); omapdss_device_unregister(&ddata->dssdev); WARN_ON(omapdss_device_is_enabled(dssdev)); diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c index 5839009f272e00522940daf03360faafc16c9b22..ae35aa1bf2c5d8eade3fd69ed26ccb982f253a40 100644 --- a/drivers/gpu/drm/omapdrm/dss/dpi.c +++ b/drivers/gpu/drm/omapdrm/dss/dpi.c @@ -688,7 +688,7 @@ static const struct omap_dss_device_ops dpi_ops = { .set_timings = dpi_set_timings, }; -static void dpi_init_output_port(struct dpi_data *dpi, struct device_node *port) +static int dpi_init_output_port(struct dpi_data *dpi, struct device_node *port) { struct omap_dss_device *out = &dpi->output; u32 port_num = 0; @@ -717,7 +717,16 @@ static void dpi_init_output_port(struct dpi_data *dpi, struct device_node *port) out->ops = &dpi_ops; out->owner = THIS_MODULE; + out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); + if (IS_ERR(out->next)) { + if (PTR_ERR(out->next) != -EPROBE_DEFER) + dev_err(out->dev, "failed to find video sink\n"); + return PTR_ERR(out->next); + } + omapdss_device_register(out); + + return 0; } static void dpi_uninit_output_port(struct device_node *port) @@ -725,6 +734,8 @@ static void dpi_uninit_output_port(struct device_node *port) struct dpi_data *dpi = port->data; struct omap_dss_device *out = &dpi->output; + if (out->next) + omapdss_device_put(out->next); omapdss_device_unregister(out); } @@ -760,9 +771,7 @@ int dpi_init_port(struct dss_device *dss, struct platform_device *pdev, mutex_init(&dpi->lock); - dpi_init_output_port(dpi, port); - - return 0; + return dpi_init_output_port(dpi, port); } void dpi_uninit_port(struct device_node *port) diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index ab0426fab22e5feef373df51818ef0c79e46aa76..631bf58056496df05b7e7a4c658886d35456d4ad 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -5165,7 +5165,7 @@ static const struct component_ops dsi_component_ops = { * Probe & Remove, Suspend & Resume */ -static void dsi_init_output(struct dsi_data *dsi) +static int dsi_init_output(struct dsi_data *dsi) { struct omap_dss_device *out = &dsi->output; @@ -5180,13 +5180,24 @@ static void dsi_init_output(struct dsi_data *dsi) out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); + if (IS_ERR(out->next)) { + if (PTR_ERR(out->next) != -EPROBE_DEFER) + dev_err(out->dev, "failed to find video sink\n"); + return PTR_ERR(out->next); + } + omapdss_device_register(out); + + return 0; } static void dsi_uninit_output(struct dsi_data *dsi) { struct omap_dss_device *out = &dsi->output; + if (out->next) + omapdss_device_put(out->next); omapdss_device_unregister(out); } @@ -5431,7 +5442,9 @@ static int dsi_probe(struct platform_device *pdev) else dsi->num_lanes_supported = 3; - dsi_init_output(dsi); + r = dsi_init_output(dsi); + if (r) + goto err_pm_disable; r = dsi_probe_of(dsi); if (r) { @@ -5451,6 +5464,7 @@ static int dsi_probe(struct platform_device *pdev) err_uninit_output: dsi_uninit_output(dsi); +err_pm_disable: pm_runtime_disable(dev); return r; } diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c index 89fdce02278c8b8fa00cede4a86db7ff4cdf21ef..118c015624b9518863707f87b111b5d564a264e6 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c @@ -731,7 +731,7 @@ static const struct component_ops hdmi4_component_ops = { * Probe & Remove, Suspend & Resume */ -static void hdmi4_init_output(struct omap_hdmi *hdmi) +static int hdmi4_init_output(struct omap_hdmi *hdmi) { struct omap_dss_device *out = &hdmi->output; @@ -744,13 +744,24 @@ static void hdmi4_init_output(struct omap_hdmi *hdmi) out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); + if (IS_ERR(out->next)) { + if (PTR_ERR(out->next) != -EPROBE_DEFER) + dev_err(out->dev, "failed to find video sink\n"); + return PTR_ERR(out->next); + } + omapdss_device_register(out); + + return 0; } static void hdmi4_uninit_output(struct omap_hdmi *hdmi) { struct omap_dss_device *out = &hdmi->output; + if (out->next) + omapdss_device_put(out->next); omapdss_device_unregister(out); } @@ -820,7 +831,9 @@ static int hdmi4_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - hdmi4_init_output(hdmi); + r = hdmi4_init_output(hdmi); + if (r) + goto err_pm_disable; r = component_add(&pdev->dev, &hdmi4_component_ops); if (r) @@ -830,6 +843,7 @@ static int hdmi4_probe(struct platform_device *pdev) err_uninit_output: hdmi4_uninit_output(hdmi); +err_pm_disable: pm_runtime_disable(&pdev->dev); err_free: kfree(hdmi); diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c index 64b45a612439d9ca7d2fe2de8fc0c39b0a9ba558..7af60ca4e7b27466aea7a4c18338bb0d62b98991 100644 --- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c +++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c @@ -721,7 +721,7 @@ static const struct component_ops hdmi5_component_ops = { * Probe & Remove, Suspend & Resume */ -static void hdmi5_init_output(struct omap_hdmi *hdmi) +static int hdmi5_init_output(struct omap_hdmi *hdmi) { struct omap_dss_device *out = &hdmi->output; @@ -734,13 +734,24 @@ static void hdmi5_init_output(struct omap_hdmi *hdmi) out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); + if (IS_ERR(out->next)) { + if (PTR_ERR(out->next) != -EPROBE_DEFER) + dev_err(out->dev, "failed to find video sink\n"); + return PTR_ERR(out->next); + } + omapdss_device_register(out); + + return 0; } static void hdmi5_uninit_output(struct omap_hdmi *hdmi) { struct omap_dss_device *out = &hdmi->output; + if (out->next) + omapdss_device_put(out->next); omapdss_device_unregister(out); } @@ -810,7 +821,9 @@ static int hdmi5_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - hdmi5_init_output(hdmi); + r = hdmi5_init_output(hdmi); + if (r) + goto err_pm_disable; r = component_add(&pdev->dev, &hdmi5_component_ops); if (r) @@ -820,6 +833,7 @@ static int hdmi5_probe(struct platform_device *pdev) err_uninit_output: hdmi5_uninit_output(hdmi); +err_pm_disable: pm_runtime_disable(&pdev->dev); err_free: kfree(hdmi); diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h index dc2f8167f61b5513378c39ed8ea8a353171407e5..5d3e4ced73d1ad71d527ee08cd51ddc34a760198 100644 --- a/drivers/gpu/drm/omapdrm/dss/omapdss.h +++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h @@ -394,6 +394,7 @@ struct omap_dss_device { struct dss_device *dss; struct omap_dss_device *src; struct omap_dss_device *dst; + struct omap_dss_device *next; struct list_head list; diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c b/drivers/gpu/drm/omapdrm/dss/sdi.c index e9b280784264ac68dd8fdc7bfc3cf74991507593..fd7c11ebda5d676e6e23bb06c68e7723bd1ddf16 100644 --- a/drivers/gpu/drm/omapdrm/dss/sdi.c +++ b/drivers/gpu/drm/omapdrm/dss/sdi.c @@ -317,7 +317,7 @@ static const struct omap_dss_device_ops sdi_ops = { .set_timings = sdi_set_timings, }; -static void sdi_init_output(struct sdi_device *sdi) +static int sdi_init_output(struct sdi_device *sdi) { struct omap_dss_device *out = &sdi->output; @@ -331,11 +331,22 @@ static void sdi_init_output(struct sdi_device *sdi) out->ops = &sdi_ops; out->owner = THIS_MODULE; + out->next = omapdss_of_find_connected_device(out->dev->of_node, 1); + if (IS_ERR(out->next)) { + if (PTR_ERR(out->next) != -EPROBE_DEFER) + dev_err(out->dev, "failed to find video sink\n"); + return PTR_ERR(out->next); + } + omapdss_device_register(out); + + return 0; } static void sdi_uninit_output(struct sdi_device *sdi) { + if (sdi->output.next) + omapdss_device_put(sdi->output.next); omapdss_device_unregister(&sdi->output); } @@ -370,7 +381,9 @@ int sdi_init_port(struct dss_device *dss, struct platform_device *pdev, sdi->pdev = pdev; port->data = sdi; - sdi_init_output(sdi); + r = sdi_init_output(sdi); + if (r) + goto err_free; return 0; diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c index 5adf8510d67b9a2f587bec9317c0b1d6e165c7a7..298e86cc9e14df816d3449b126e30a88c09c2ba4 100644 --- a/drivers/gpu/drm/omapdrm/dss/venc.c +++ b/drivers/gpu/drm/omapdrm/dss/venc.c @@ -800,7 +800,7 @@ static const struct component_ops venc_component_ops = { * Probe & Remove, Suspend & Resume */ -static void venc_init_output(struct venc_device *venc) +static int venc_init_output(struct venc_device *venc) { struct omap_dss_device *out = &venc->output; @@ -813,11 +813,22 @@ static void venc_init_output(struct venc_device *venc) out->owner = THIS_MODULE; out->of_ports = BIT(0); + out->next = omapdss_of_find_connected_device(out->dev->of_node, 0); + if (IS_ERR(out->next)) { + if (PTR_ERR(out->next) != -EPROBE_DEFER) + dev_err(out->dev, "failed to find video sink\n"); + return PTR_ERR(out->next); + } + omapdss_device_register(out); + + return 0; } static void venc_uninit_output(struct venc_device *venc) { + if (venc->output.next) + omapdss_device_put(venc->output.next); omapdss_device_unregister(&venc->output); } @@ -909,7 +920,9 @@ static int venc_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - venc_init_output(venc); + r = venc_init_output(venc); + if (r) + goto err_pm_disable; r = component_add(&pdev->dev, &venc_component_ops); if (r) @@ -919,6 +932,7 @@ static int venc_probe(struct platform_device *pdev) err_uninit_output: venc_uninit_output(venc); +err_pm_disable: pm_runtime_disable(&pdev->dev); err_free: kfree(venc);