]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/omap: dss: Acquire next dssdev at probe time
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Fri, 2 Mar 2018 20:13:06 +0000 (22:13 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 3 Sep 2018 13:13:27 +0000 (16:13 +0300)
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@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
drivers/gpu/drm/omapdrm/displays/encoder-tfp410.c
drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
drivers/gpu/drm/omapdrm/dss/dpi.c
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/hdmi4.c
drivers/gpu/drm/omapdrm/dss/hdmi5.c
drivers/gpu/drm/omapdrm/dss/omapdss.h
drivers/gpu/drm/omapdrm/dss/sdi.c
drivers/gpu/drm/omapdrm/dss/venc.c

index 939e259d601d341ae7783f835f15fcc750474ba6..f661ba8f3fa05238d48e3639c2753a078aca1c58 100644 (file)
@@ -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));
index 55549c5a5af2f1dc05b66b2fe93cba4dd95d2772..3be35ba564dab09cd3f4f277b5bcbbeb4c219646 100644 (file)
@@ -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));
index 58a831c3f74ca7c1d40667164b6b1adbb4ed2b05..cee53346f6fcfe903f896a23c2a55bd8bf4d79e5 100644 (file)
@@ -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));
index 5839009f272e00522940daf03360faafc16c9b22..ae35aa1bf2c5d8eade3fd69ed26ccb982f253a40 100644 (file)
@@ -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)
index ab0426fab22e5feef373df51818ef0c79e46aa76..631bf58056496df05b7e7a4c658886d35456d4ad 100644 (file)
@@ -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;
 }
index 89fdce02278c8b8fa00cede4a86db7ff4cdf21ef..118c015624b9518863707f87b111b5d564a264e6 100644 (file)
@@ -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);
index 64b45a612439d9ca7d2fe2de8fc0c39b0a9ba558..7af60ca4e7b27466aea7a4c18338bb0d62b98991 100644 (file)
@@ -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);
index dc2f8167f61b5513378c39ed8ea8a353171407e5..5d3e4ced73d1ad71d527ee08cd51ddc34a760198 100644 (file)
@@ -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;
 
index e9b280784264ac68dd8fdc7bfc3cf74991507593..fd7c11ebda5d676e6e23bb06c68e7723bd1ddf16 100644 (file)
@@ -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;
 
index 5adf8510d67b9a2f587bec9317c0b1d6e165c7a7..298e86cc9e14df816d3449b126e30a88c09c2ba4 100644 (file)
@@ -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);