diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c index 939e259d601d..f661ba8f3fa0 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 55549c5a5af2..3be35ba564da 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 58a831c3f74c..cee53346f6fc 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 5839009f272e..ae35aa1bf2c5 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 ab0426fab22e..631bf5805649 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 89fdce02278c..118c015624b9 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 64b45a612439..7af60ca4e7b2 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 dc2f8167f61b..5d3e4ced73d1 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 e9b280784264..fd7c11ebda5d 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 5adf8510d67b..298e86cc9e14 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);