[PATCH v2 43/60] drm/omap: dss: Acquire next dssdev at probe time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Look up the next dssdev at probe time based on device tree links for all
DSS outputs and encoders. This will be used to reverse the order of the
dssdev connect and disconnect call chains.

Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
---
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c    |  9 +++++++++
 drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c    |  9 +++++++++
 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c |  9 +++++++++
 drivers/gpu/drm/omapdrm/dss/dpi.c                    | 17 +++++++++++++----
 drivers/gpu/drm/omapdrm/dss/dsi.c                    | 18 ++++++++++++++++--
 drivers/gpu/drm/omapdrm/dss/hdmi4.c                  | 18 ++++++++++++++++--
 drivers/gpu/drm/omapdrm/dss/hdmi5.c                  | 18 ++++++++++++++++--
 drivers/gpu/drm/omapdrm/dss/omapdss.h                |  1 +
 drivers/gpu/drm/omapdrm/dss/sdi.c                    | 17 +++++++++++++++--
 drivers/gpu/drm/omapdrm/dss/venc.c                   | 18 ++++++++++++++++--
 10 files changed, 120 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 904ebec5f5e1..a94d6d0cead9 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 cd442f66fa1d..d40a0fd93e67 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 d21d0829774e..e6adeebb91d1 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 e97f54d5f3e1..650becdf2763 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 79312e53bfd9..b48ee792244b 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 0ace553a21c5..8be01ca79817 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -314,7 +314,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;
 
@@ -328,11 +328,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);
 }
 
@@ -367,7 +378,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 84069e79ca6a..7bd3156a52a9 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);
-- 
Regards,

Laurent Pinchart

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




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux