drm/omap: Reverse direction of the DSS device enable/disable operations
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Fri, 24 Aug 2018 16:38:07 +0000 (19:38 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 18 Mar 2019 09:42:12 +0000 (11:42 +0200)
The omapdrm and omapdss drivers are architectured based on display
pipelines made of multiple components handled from sink (display) to
source (DSS output). This is incompatible with the DRM bridge and panel
APIs that handle components from source to sink.

Reconcile the omapdrm and omapdss drivers with the DRM bridge and panel
model by reversing the direction of the DSS device .enable() and
.disable() operations. This completes the move to the DRM bridge model,
with the notable exception of the DSI pipelines that will require more
work.

We also adapt the omapdss shutdown handler dss_shutdown() to shut down
all active pipelines starting from the pipeline output device instead of
the display device.

As a consequence the for_each_dss_display() macro isn't used and can be
removed, and the omapdss_device_get_next() function underlying the macro
can be simplified to search for output devices only.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
24 files changed:
drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
drivers/gpu/drm/omapdrm/displays/connector-dvi.c
drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
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/displays/panel-dpi.c
drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
drivers/gpu/drm/omapdrm/dss/base.c
drivers/gpu/drm/omapdrm/dss/dpi.c
drivers/gpu/drm/omapdrm/dss/dsi.c
drivers/gpu/drm/omapdrm/dss/dss.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
drivers/gpu/drm/omapdrm/omap_encoder.c

index 2b5b77627cfbafde5ea83acd178935493015cad1..1503563117f3e2f35e40040df774653967df7590 100644 (file)
@@ -35,26 +35,9 @@ static void tvc_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int tvc_enable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-
-       return src->ops->enable(src);
-}
-
-static void tvc_disable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-
-       src->ops->disable(src);
-}
-
 static const struct omap_dss_device_ops tvc_ops = {
        .connect                = tvc_connect,
        .disconnect             = tvc_disconnect,
-
-       .enable                 = tvc_enable,
-       .disable                = tvc_disable,
 };
 
 static int tvc_probe(struct platform_device *pdev)
@@ -85,13 +68,9 @@ static int tvc_probe(struct platform_device *pdev)
 static int __exit tvc_remove(struct platform_device *pdev)
 {
        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-       struct omap_dss_device *dssdev = &ddata->dssdev;
 
        omapdss_device_unregister(&ddata->dssdev);
 
-       if (omapdss_device_is_enabled(dssdev))
-               tvc_disable(dssdev);
-
        return 0;
 }
 
index a1784e2638356003f583323bf9e8d5e7d6d52890..bf5ee50ce5feeda1b37bc2767b736c34046b0870 100644 (file)
@@ -46,20 +46,6 @@ static void dvic_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int dvic_enable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-
-       return src->ops->enable(src);
-}
-
-static void dvic_disable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-
-       src->ops->disable(src);
-}
-
 static int dvic_ddc_read(struct i2c_adapter *adapter,
                unsigned char *buf, u16 count, u8 offset)
 {
@@ -163,9 +149,6 @@ static const struct omap_dss_device_ops dvic_ops = {
        .connect        = dvic_connect,
        .disconnect     = dvic_disconnect,
 
-       .enable         = dvic_enable,
-       .disable        = dvic_disable,
-
        .read_edid      = dvic_read_edid,
        .detect         = dvic_detect,
 
@@ -275,13 +258,9 @@ static int dvic_probe(struct platform_device *pdev)
 static int __exit dvic_remove(struct platform_device *pdev)
 {
        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-       struct omap_dss_device *dssdev = &ddata->dssdev;
 
        omapdss_device_unregister(&ddata->dssdev);
 
-       if (omapdss_device_is_enabled(dssdev))
-               dvic_disable(dssdev);
-
        i2c_put_adapter(ddata->i2c_adapter);
 
        mutex_destroy(&ddata->hpd_lock);
index 05cd503c4d29aa64e3d2ddffbd1b315485c3493a..797da4a3f22e48bea87ce4b38bb398405c44c37e 100644 (file)
@@ -41,20 +41,6 @@ static void hdmic_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int hdmic_enable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-
-       return src->ops->enable(src);
-}
-
-static void hdmic_disable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-
-       src->ops->disable(src);
-}
-
 static bool hdmic_detect(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -89,9 +75,6 @@ static const struct omap_dss_device_ops hdmic_ops = {
        .connect                = hdmic_connect,
        .disconnect             = hdmic_disconnect,
 
-       .enable                 = hdmic_enable,
-       .disable                = hdmic_disable,
-
        .detect                 = hdmic_detect,
        .register_hpd_cb        = hdmic_register_hpd_cb,
        .unregister_hpd_cb      = hdmic_unregister_hpd_cb,
@@ -172,13 +155,9 @@ static int hdmic_probe(struct platform_device *pdev)
 static int __exit hdmic_remove(struct platform_device *pdev)
 {
        struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-       struct omap_dss_device *dssdev = &ddata->dssdev;
 
        omapdss_device_unregister(&ddata->dssdev);
 
-       if (omapdss_device_is_enabled(dssdev))
-               hdmic_disable(dssdev);
-
        return 0;
 }
 
index ce116c28479fec2c173f86f5b711a8e53672e5f7..fc5e0c47054d090c72ccd980599d8c05f392995d 100644 (file)
@@ -41,39 +41,20 @@ static void opa362_disconnect(struct omap_dss_device *src,
        omapdss_device_disconnect(dst, dst->next);
 }
 
-static int opa362_enable(struct omap_dss_device *dssdev)
+static void opa362_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-       int r;
-
-       dev_dbg(dssdev->dev, "enable\n");
-
-       r = src->ops->enable(src);
-       if (r)
-               return r;
 
        if (ddata->enable_gpio)
                gpiod_set_value_cansleep(ddata->enable_gpio, 1);
-
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-       return 0;
 }
 
 static void opa362_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-
-       dev_dbg(dssdev->dev, "disable\n");
 
        if (ddata->enable_gpio)
                gpiod_set_value_cansleep(ddata->enable_gpio, 0);
-
-       src->ops->disable(src);
-
-       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
 static const struct omap_dss_device_ops opa362_ops = {
@@ -132,9 +113,7 @@ static int __exit opa362_remove(struct platform_device *pdev)
                omapdss_device_put(dssdev->next);
        omapdss_device_unregister(&ddata->dssdev);
 
-       WARN_ON(omapdss_device_is_enabled(dssdev));
-       if (omapdss_device_is_enabled(dssdev))
-               opa362_disable(dssdev);
+       opa362_disable(dssdev);
 
        return 0;
 }
index d51410ed1e133558210f46c4c9c0393a0992d782..82035078377ab1fa849316da64c52bc5bab05058 100644 (file)
@@ -36,35 +36,20 @@ static void tfp410_disconnect(struct omap_dss_device *src,
        omapdss_device_disconnect(dst, dst->next);
 }
 
-static int tfp410_enable(struct omap_dss_device *dssdev)
+static void tfp410_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-       int r;
-
-       r = src->ops->enable(src);
-       if (r)
-               return r;
 
        if (ddata->pd_gpio)
                gpiod_set_value_cansleep(ddata->pd_gpio, 0);
-
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-       return 0;
 }
 
 static void tfp410_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
 
        if (ddata->pd_gpio)
                gpiod_set_value_cansleep(ddata->pd_gpio, 0);
-
-       src->ops->disable(src);
-
-       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 }
 
 static const struct omap_dss_device_ops tfp410_ops = {
@@ -126,9 +111,7 @@ static int __exit tfp410_remove(struct platform_device *pdev)
                omapdss_device_put(dssdev->next);
        omapdss_device_unregister(&ddata->dssdev);
 
-       WARN_ON(omapdss_device_is_enabled(dssdev));
-       if (omapdss_device_is_enabled(dssdev))
-               tfp410_disable(dssdev);
+       tfp410_disable(dssdev);
 
        return 0;
 }
index 1a2bc59bf104e4ce300267908f860d9162a8a706..ced36718a95fc7707b2540831e2dc608b567620d 100644 (file)
@@ -62,35 +62,6 @@ static void tpd_disconnect(struct omap_dss_device *src,
        omapdss_device_disconnect(dst, dst->next);
 }
 
-static int tpd_enable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-       int r;
-
-       if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
-               return 0;
-
-       r = src->ops->enable(src);
-       if (r)
-               return r;
-
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
-       return r;
-}
-
-static void tpd_disable(struct omap_dss_device *dssdev)
-{
-       struct omap_dss_device *src = dssdev->src;
-
-       if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-               return;
-
-       src->ops->disable(src);
-
-       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-}
-
 static bool tpd_detect(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -124,8 +95,6 @@ static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev)
 static const struct omap_dss_device_ops tpd_ops = {
        .connect                = tpd_connect,
        .disconnect             = tpd_disconnect,
-       .enable                 = tpd_enable,
-       .disable                = tpd_disable,
        .detect                 = tpd_detect,
        .register_hpd_cb        = tpd_register_hpd_cb,
        .unregister_hpd_cb      = tpd_unregister_hpd_cb,
@@ -225,10 +194,6 @@ static int __exit tpd_remove(struct platform_device *pdev)
                omapdss_device_put(dssdev->next);
        omapdss_device_unregister(&ddata->dssdev);
 
-       WARN_ON(omapdss_device_is_enabled(dssdev));
-       if (omapdss_device_is_enabled(dssdev))
-               tpd_disable(dssdev);
-
        return 0;
 }
 
index 3ef4596a3698bf7cb5aed6349256717341752294..eee44d9ea0c3ba470fdecafec615fac28125a4df 100644 (file)
@@ -45,39 +45,27 @@ static void panel_dpi_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int panel_dpi_enable(struct omap_dss_device *dssdev)
+static void panel_dpi_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
        int r;
 
-       r = src->ops->enable(src);
-       if (r)
-               return r;
-
        r = regulator_enable(ddata->vcc_supply);
-       if (r) {
-               src->ops->disable(src);
-               return r;
-       }
+       if (r)
+               return;
 
        gpiod_set_value_cansleep(ddata->enable_gpio, 1);
        backlight_enable(ddata->backlight);
-
-       return 0;
 }
 
 static void panel_dpi_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
 
        backlight_disable(ddata->backlight);
 
        gpiod_set_value_cansleep(ddata->enable_gpio, 0);
        regulator_disable(ddata->vcc_supply);
-
-       src->ops->disable(src);
 }
 
 static void panel_dpi_get_timings(struct omap_dss_device *dssdev,
index a7c8688237fbdc59229dfb6194457162192b15f3..ffbf20e6ebe907214361e90ac0e37d70556b0042 100644 (file)
@@ -315,12 +315,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
        if (!ddata->ulps_enabled)
                return 0;
 
-       r = src->ops->enable(src);
-       if (r) {
-               dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
-               goto err1;
-       }
-
+       src->ops->enable(src);
        src->ops->dsi.enable_hs(src, ddata->channel, true);
 
        r = _dsicm_enable_te(ddata, true);
@@ -347,7 +342,7 @@ err2:
                        enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
                ddata->ulps_enabled = false;
        }
-err1:
+
        dsicm_queue_ulps_work(ddata);
 
        return r;
@@ -649,11 +644,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
                goto err_vddi;
        }
 
-       r = src->ops->enable(src);
-       if (r) {
-               dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
-               goto err_vddi;
-       }
+       src->ops->enable(src);
 
        dsicm_hw_reset(ddata);
 
@@ -787,7 +778,7 @@ static void dsicm_disconnect(struct omap_dss_device *src,
        src->ops->dsi.release_vc(src, ddata->channel);
 }
 
-static int dsicm_enable(struct omap_dss_device *dssdev)
+static void dsicm_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
        struct omap_dss_device *src = dssdev->src;
@@ -808,11 +799,10 @@ static int dsicm_enable(struct omap_dss_device *dssdev)
 
        dsicm_bl_power(ddata, true);
 
-       return 0;
+       return;
 err:
-       dev_dbg(&ddata->pdev->dev, "enable failed\n");
+       dev_dbg(&ddata->pdev->dev, "enable failed (%d)\n", r);
        mutex_unlock(&ddata->lock);
-       return r;
 }
 
 static void dsicm_disable(struct omap_dss_device *dssdev)
index 2c3b15ba5a398160b2832723f32daedf50203110..e043cab0a0c933fd7c00e1d4c37dbbe146d8e5e5 100644 (file)
@@ -123,31 +123,20 @@ static void lb035q02_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int lb035q02_enable(struct omap_dss_device *dssdev)
+static void lb035q02_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-       int r;
-
-       r = src->ops->enable(src);
-       if (r)
-               return r;
 
        if (ddata->enable_gpio)
                gpiod_set_value_cansleep(ddata->enable_gpio, 1);
-
-       return 0;
 }
 
 static void lb035q02_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
 
        if (ddata->enable_gpio)
                gpiod_set_value_cansleep(ddata->enable_gpio, 0);
-
-       src->ops->disable(src);
 }
 
 static void lb035q02_get_timings(struct omap_dss_device *dssdev,
@@ -232,8 +221,7 @@ static int lb035q02_panel_spi_remove(struct spi_device *spi)
 
        omapdss_device_unregister(dssdev);
 
-       if (omapdss_device_is_enabled(dssdev))
-               lb035q02_disable(dssdev);
+       lb035q02_disable(dssdev);
 
        return 0;
 }
index ef83459611befc351dba780640cd0fc6e62df99b..44fd6134317d04ec595023a77c4fab79d435db61 100644 (file)
@@ -118,29 +118,18 @@ static void nec_8048_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int nec_8048_enable(struct omap_dss_device *dssdev)
+static void nec_8048_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-       int r;
-
-       r = src->ops->enable(src);
-       if (r)
-               return r;
 
        gpiod_set_value_cansleep(ddata->res_gpio, 1);
-
-       return 0;
 }
 
 static void nec_8048_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
 
        gpiod_set_value_cansleep(ddata->res_gpio, 0);
-
-       src->ops->disable(src);
 }
 
 static void nec_8048_get_timings(struct omap_dss_device *dssdev,
@@ -223,8 +212,7 @@ static int nec_8048_remove(struct spi_device *spi)
 
        omapdss_device_unregister(dssdev);
 
-       if (omapdss_device_is_enabled(dssdev))
-               nec_8048_disable(dssdev);
+       nec_8048_disable(dssdev);
 
        return 0;
 }
index 0c5b405b4c9ecd482079a917ec488ba83d8ef8c6..907abf8ef4e6d2320742971b9459ebaeccd808c2 100644 (file)
@@ -62,23 +62,22 @@ static void sharp_ls_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int sharp_ls_enable(struct omap_dss_device *dssdev)
+static void sharp_ls_pre_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
        int r;
 
        if (ddata->vcc) {
                r = regulator_enable(ddata->vcc);
-               if (r != 0)
-                       return r;
+               if (r)
+                       dev_err(dssdev->dev, "%s: failed to enable regulator\n",
+                               __func__);
        }
+}
 
-       r = src->ops->enable(src);
-       if (r) {
-               regulator_disable(ddata->vcc);
-               return r;
-       }
+static void sharp_ls_enable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
 
        /* wait couple of vsyncs until enabling the LCD */
        msleep(50);
@@ -88,14 +87,11 @@ static int sharp_ls_enable(struct omap_dss_device *dssdev)
 
        if (ddata->ini_gpio)
                gpiod_set_value_cansleep(ddata->ini_gpio, 1);
-
-       return 0;
 }
 
 static void sharp_ls_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
 
        if (ddata->ini_gpio)
                gpiod_set_value_cansleep(ddata->ini_gpio, 0);
@@ -104,10 +100,12 @@ static void sharp_ls_disable(struct omap_dss_device *dssdev)
                gpiod_set_value_cansleep(ddata->resb_gpio, 0);
 
        /* wait at least 5 vsyncs after disabling the LCD */
-
        msleep(100);
+}
 
-       src->ops->disable(src);
+static void sharp_ls_post_disable(struct omap_dss_device *dssdev)
+{
+       struct panel_drv_data *ddata = to_panel_data(dssdev);
 
        if (ddata->vcc)
                regulator_disable(ddata->vcc);
@@ -125,8 +123,10 @@ static const struct omap_dss_device_ops sharp_ls_ops = {
        .connect        = sharp_ls_connect,
        .disconnect     = sharp_ls_disconnect,
 
+       .pre_enable     = sharp_ls_pre_enable,
        .enable         = sharp_ls_enable,
        .disable        = sharp_ls_disable,
+       .post_disable   = sharp_ls_post_disable,
 
        .get_timings    = sharp_ls_get_timings,
 };
@@ -230,8 +230,10 @@ static int __exit sharp_ls_remove(struct platform_device *pdev)
 
        omapdss_device_unregister(dssdev);
 
-       if (omapdss_device_is_enabled(dssdev))
+       if (omapdss_device_is_enabled(dssdev)) {
                sharp_ls_disable(dssdev);
+               sharp_ls_post_disable(dssdev);
+       }
 
        return 0;
 }
index 99c2c4f27dd5beb1e20305d85b1f87f0bcb30ae3..eeaea752f171929ad156edbc399e58209435fc25 100644 (file)
@@ -516,17 +516,9 @@ static void acx565akm_disconnect(struct omap_dss_device *src,
 static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-       int r;
 
        dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 
-       r = src->ops->enable(src);
-       if (r) {
-               pr_err("%s sdi enable failed\n", __func__);
-               return r;
-       }
-
        /*FIXME tweak me */
        msleep(50);
 
@@ -562,7 +554,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
 static void acx565akm_panel_power_off(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
 
        dev_dbg(dssdev->dev, "%s\n", __func__);
 
@@ -585,20 +576,15 @@ static void acx565akm_panel_power_off(struct omap_dss_device *dssdev)
 
        /* FIXME need to tweak this delay */
        msleep(100);
-
-       src->ops->disable(src);
 }
 
-static int acx565akm_enable(struct omap_dss_device *dssdev)
+static void acx565akm_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       int r;
 
        mutex_lock(&ddata->mutex);
-       r = acx565akm_panel_power_on(dssdev);
+       acx565akm_panel_power_on(dssdev);
        mutex_unlock(&ddata->mutex);
-
-       return r;
 }
 
 static void acx565akm_disable(struct omap_dss_device *dssdev)
index 8551a1df3ad672e6dbcc44e436d3bbf5cc3d0b0e..f1a5c14407a4f739a07a9bee0661348962171841 100644 (file)
@@ -169,18 +169,12 @@ static void td028ttec1_panel_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
+static void td028ttec1_panel_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-       int r;
-
-       r = src->ops->enable(src);
-       if (r)
-               return r;
+       int r = 0;
 
-       dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
-               dssdev->state);
+       dev_dbg(dssdev->dev, "%s: state %d\n", __func__, dssdev->state);
 
        /* three times command zero */
        r |= jbt_ret_write_0(ddata, 0x00);
@@ -191,8 +185,8 @@ static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
        usleep_range(1000, 2000);
 
        if (r) {
-               dev_warn(dssdev->dev, "transfer error\n");
-               return -EIO;
+               dev_warn(dssdev->dev, "%s: transfer error\n", __func__);
+               return;
        }
 
        /* deep standby out */
@@ -262,13 +256,13 @@ static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
 
        r |= jbt_ret_write_0(ddata, JBT_REG_DISPLAY_ON);
 
-       return r ? -EIO : 0;
+       if (r)
+               dev_err(dssdev->dev, "%s: write error\n", __func__);
 }
 
 static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
 
        dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
 
@@ -276,8 +270,6 @@ static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
        jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
        jbt_ret_write_0(ddata, JBT_REG_SLEEP_IN);
        jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x00);
-
-       src->ops->disable(src);
 }
 
 static void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev,
@@ -354,8 +346,7 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
 
        omapdss_device_unregister(dssdev);
 
-       if (omapdss_device_is_enabled(dssdev))
-               td028ttec1_panel_disable(dssdev);
+       td028ttec1_panel_disable(dssdev);
 
        return 0;
 }
index 527abed69d34fcbcef5eb82a566e0d0fdcdc7ad5..996a16736d105d41db4a10bb99536529e00700bc 100644 (file)
@@ -320,16 +320,11 @@ static void tpo_td043_disconnect(struct omap_dss_device *src,
 {
 }
 
-static int tpo_td043_enable(struct omap_dss_device *dssdev)
+static void tpo_td043_enable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
        int r;
 
-       r = src->ops->enable(src);
-       if (r)
-               return r;
-
        /*
         * If we are resuming from system suspend, SPI clocks might not be
         * enabled yet, so we'll program the LCD from SPI PM resume callback.
@@ -337,20 +332,16 @@ static int tpo_td043_enable(struct omap_dss_device *dssdev)
        if (!ddata->spi_suspended) {
                r = tpo_td043_power_on(ddata);
                if (r) {
-                       src->ops->disable(src);
-                       return r;
+                       dev_err(&ddata->spi->dev, "%s: power on failed (%d)\n",
+                               __func__, r);
+                       return;
                }
        }
-
-       return 0;
 }
 
 static void tpo_td043_disable(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
-       struct omap_dss_device *src = dssdev->src;
-
-       src->ops->disable(src);
 
        if (!ddata->spi_suspended)
                tpo_td043_power_off(ddata);
index 787157b0069495ac1e7cc17632cd74ff03440dd0..916225d62cc2a33131610684a6849bdb091d2361 100644 (file)
@@ -126,13 +126,10 @@ struct omap_dss_device *omapdss_find_device_by_port(struct device_node *src,
 }
 
 /*
- * Search for the next device starting at @from. The type argument specfies
- * which device types to consider when searching. Searching for multiple types
- * is supported by and'ing their type flags. Release the reference to the @from
- * device, and acquire a reference to the returned device if found.
+ * Search for the next output device starting at @from. Release the reference to
+ * the @from device, and acquire a reference to the returned device if found.
  */
-struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from,
-                                               enum omap_dss_device_type type)
+struct omap_dss_device *omapdss_device_next_output(struct omap_dss_device *from)
 {
        struct omap_dss_device *dssdev;
        struct list_head *list;
@@ -160,15 +157,7 @@ struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from,
                        goto done;
                }
 
-               /*
-                * Accept display entities if the display type is requested,
-                * and output entities if the output type is requested.
-                */
-               if ((type & OMAP_DSS_DEVICE_TYPE_DISPLAY) &&
-                   !dssdev->output_type)
-                       goto done;
-               if ((type & OMAP_DSS_DEVICE_TYPE_OUTPUT) && dssdev->id &&
-                   dssdev->next)
+               if (dssdev->id && dssdev->next)
                        goto done;
        }
 
@@ -183,7 +172,7 @@ done:
        mutex_unlock(&omapdss_devices_lock);
        return dssdev;
 }
-EXPORT_SYMBOL(omapdss_device_get_next);
+EXPORT_SYMBOL(omapdss_device_next_output);
 
 static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
 {
@@ -244,6 +233,58 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
 }
 EXPORT_SYMBOL_GPL(omapdss_device_disconnect);
 
+void omapdss_device_pre_enable(struct omap_dss_device *dssdev)
+{
+       if (!dssdev)
+               return;
+
+       omapdss_device_pre_enable(dssdev->next);
+
+       if (dssdev->ops->pre_enable)
+               dssdev->ops->pre_enable(dssdev);
+}
+EXPORT_SYMBOL_GPL(omapdss_device_pre_enable);
+
+void omapdss_device_enable(struct omap_dss_device *dssdev)
+{
+       if (!dssdev)
+               return;
+
+       if (dssdev->ops->enable)
+               dssdev->ops->enable(dssdev);
+
+       omapdss_device_enable(dssdev->next);
+
+       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+}
+EXPORT_SYMBOL_GPL(omapdss_device_enable);
+
+void omapdss_device_disable(struct omap_dss_device *dssdev)
+{
+       if (!dssdev)
+               return;
+
+       omapdss_device_disable(dssdev->next);
+
+       if (dssdev->ops->disable)
+               dssdev->ops->disable(dssdev);
+}
+EXPORT_SYMBOL_GPL(omapdss_device_disable);
+
+void omapdss_device_post_disable(struct omap_dss_device *dssdev)
+{
+       if (!dssdev)
+               return;
+
+       if (dssdev->ops->post_disable)
+               dssdev->ops->post_disable(dssdev);
+
+       omapdss_device_post_disable(dssdev->next);
+
+       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+EXPORT_SYMBOL_GPL(omapdss_device_post_disable);
+
 /* -----------------------------------------------------------------------------
  * Components Handling
  */
index 0cf3b220e35f5510d5d5ff10bf765b0c1dc49333..74e841a2b4eb41814e00773cbcf1029016747ba4 100644 (file)
@@ -378,7 +378,7 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
        dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
 }
 
-static int dpi_display_enable(struct omap_dss_device *dssdev)
+static void dpi_display_enable(struct omap_dss_device *dssdev)
 {
        struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
        struct omap_dss_device *out = &dpi->output;
@@ -420,7 +420,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
 
        mutex_unlock(&dpi->lock);
 
-       return 0;
+       return;
 
 err_mgr_enable:
 err_set_mode:
@@ -434,7 +434,6 @@ err_get_dispc:
                regulator_disable(dpi->vdds_dsi_reg);
 err_reg_enable:
        mutex_unlock(&dpi->lock);
-       return r;
 }
 
 static void dpi_display_disable(struct omap_dss_device *dssdev)
index c14f8fb2a99b5d76de32bcd804a589bbe5716d0f..4dad2bf6b551a2f94a176065eda42a334f9402de 100644 (file)
@@ -4154,10 +4154,10 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
        dsi_pll_uninit(dsi, disconnect_lanes);
 }
 
-static int dsi_display_enable(struct omap_dss_device *dssdev)
+static void dsi_display_enable(struct omap_dss_device *dssdev)
 {
        struct dsi_data *dsi = to_dsi_data(dssdev);
-       int r = 0;
+       int r;
 
        DSSDBG("dsi_display_enable\n");
 
@@ -4177,14 +4177,13 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
 
        mutex_unlock(&dsi->lock);
 
-       return 0;
+       return;
 
 err_init_dsi:
        dsi_runtime_put(dsi);
 err_get_dsi:
        mutex_unlock(&dsi->lock);
        DSSDBG("dsi_display_enable FAILED\n");
-       return r;
 }
 
 static void dsi_display_disable(struct omap_dss_device *dssdev,
index 7553c7fc1c457f23bb456046c17408ba89fc9d24..55e68863ef15885f4419122297345bba6808ce3e 100644 (file)
@@ -1560,7 +1560,7 @@ static void dss_shutdown(struct platform_device *pdev)
 
        DSSDBG("shutdown\n");
 
-       for_each_dss_display(dssdev) {
+       for_each_dss_output(dssdev) {
                if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
                        dssdev->ops->disable(dssdev);
        }
index b6b44f07c74e23711bd6a6b366e210398d23f64c..6f88fb4d6344a37dff57c870a63a7e96c5b80410 100644 (file)
@@ -312,11 +312,11 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
        hdmi_wp_audio_enable(&hd->wp, false);
 }
 
-static int hdmi_display_enable(struct omap_dss_device *dssdev)
+static void hdmi_display_enable(struct omap_dss_device *dssdev)
 {
        struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
        unsigned long flags;
-       int r = 0;
+       int r;
 
        DSSDBG("ENTER hdmi_display_enable\n");
 
@@ -325,7 +325,7 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
        r = hdmi_power_on_full(hdmi);
        if (r) {
                DSSERR("failed to power on device\n");
-               goto err0;
+               goto done;
        }
 
        if (hdmi->audio_configured) {
@@ -345,12 +345,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
        hdmi->display_enabled = true;
        spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
 
+done:
        mutex_unlock(&hdmi->lock);
-       return 0;
-
-err0:
-       mutex_unlock(&hdmi->lock);
-       return r;
 }
 
 static void hdmi_display_disable(struct omap_dss_device *dssdev)
index beef25703eab71a7ca55d3f29dfcf0bebe10558a..28cf1c32b1587768e11d73c94de5bfe24cfc1363 100644 (file)
@@ -320,11 +320,11 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
        REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
 }
 
-static int hdmi_display_enable(struct omap_dss_device *dssdev)
+static void hdmi_display_enable(struct omap_dss_device *dssdev)
 {
        struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
        unsigned long flags;
-       int r = 0;
+       int r;
 
        DSSDBG("ENTER hdmi_display_enable\n");
 
@@ -333,7 +333,7 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
        r = hdmi_power_on_full(hdmi);
        if (r) {
                DSSERR("failed to power on device\n");
-               goto err0;
+               goto done;
        }
 
        if (hdmi->audio_configured) {
@@ -353,12 +353,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
        hdmi->display_enabled = true;
        spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
 
+done:
        mutex_unlock(&hdmi->lock);
-       return 0;
-
-err0:
-       mutex_unlock(&hdmi->lock);
-       return r;
 }
 
 static void hdmi_display_disable(struct omap_dss_device *dssdev)
index 698155dd7941f6b26a64474a0d42d42e4f669f56..4cd3874228a569c282e28bd250135971a1234ab5 100644 (file)
@@ -359,8 +359,10 @@ struct omap_dss_device_ops {
        void (*disconnect)(struct omap_dss_device *dssdev,
                        struct omap_dss_device *dst);
 
-       int (*enable)(struct omap_dss_device *dssdev);
+       void (*pre_enable)(struct omap_dss_device *dssdev);
+       void (*enable)(struct omap_dss_device *dssdev);
        void (*disable)(struct omap_dss_device *dssdev);
+       void (*post_disable)(struct omap_dss_device *dssdev);
 
        int (*check_timings)(struct omap_dss_device *dssdev,
                             struct videomode *vm);
@@ -397,11 +399,6 @@ enum omap_dss_device_ops_flag {
        OMAP_DSS_DEVICE_OP_EDID = BIT(2),
 };
 
-enum omap_dss_device_type {
-       OMAP_DSS_DEVICE_TYPE_OUTPUT = (1 << 0),
-       OMAP_DSS_DEVICE_TYPE_DISPLAY = (1 << 1),
-};
-
 struct omap_dss_device {
        struct device *dev;
 
@@ -471,8 +468,6 @@ static inline bool omapdss_is_initialized(void)
        return !!omapdss_get_dss();
 }
 
-#define for_each_dss_display(d) \
-       while ((d = omapdss_device_get_next(d, OMAP_DSS_DEVICE_TYPE_DISPLAY)) != NULL)
 void omapdss_display_init(struct omap_dss_device *dssdev);
 struct omap_dss_device *omapdss_display_get(struct omap_dss_device *output);
 
@@ -482,20 +477,23 @@ struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev);
 void omapdss_device_put(struct omap_dss_device *dssdev);
 struct omap_dss_device *omapdss_find_device_by_port(struct device_node *src,
                                                    unsigned int port);
-struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from,
-                                               enum omap_dss_device_type type);
 int omapdss_device_connect(struct dss_device *dss,
                           struct omap_dss_device *src,
                           struct omap_dss_device *dst);
 void omapdss_device_disconnect(struct omap_dss_device *src,
                               struct omap_dss_device *dst);
+void omapdss_device_pre_enable(struct omap_dss_device *dssdev);
+void omapdss_device_enable(struct omap_dss_device *dssdev);
+void omapdss_device_disable(struct omap_dss_device *dssdev);
+void omapdss_device_post_disable(struct omap_dss_device *dssdev);
 
 int omap_dss_get_num_overlay_managers(void);
 
 int omap_dss_get_num_overlays(void);
 
 #define for_each_dss_output(d) \
-       while ((d = omapdss_device_get_next(d, OMAP_DSS_DEVICE_TYPE_OUTPUT)) != NULL)
+       while ((d = omapdss_device_next_output(d)) != NULL)
+struct omap_dss_device *omapdss_device_next_output(struct omap_dss_device *from);
 int omapdss_output_validate(struct omap_dss_device *out);
 
 typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
index 7de817c699137cadff4d5eb2d47f98c88b943ccc..20e88c6e3d9859d07567286b23fed284c8a6d097 100644 (file)
@@ -129,7 +129,7 @@ static void sdi_config_lcd_manager(struct sdi_device *sdi)
        dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config);
 }
 
-static int sdi_display_enable(struct omap_dss_device *dssdev)
+static void sdi_display_enable(struct omap_dss_device *dssdev)
 {
        struct sdi_device *sdi = dssdev_to_sdi(dssdev);
        struct dispc_clock_info dispc_cinfo;
@@ -138,7 +138,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
 
        r = regulator_enable(sdi->vdds_sdi_reg);
        if (r)
-               goto err_reg_enable;
+               return;
 
        r = dispc_runtime_get(sdi->dss->dispc);
        if (r)
@@ -180,7 +180,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
        if (r)
                goto err_mgr_enable;
 
-       return 0;
+       return;
 
 err_mgr_enable:
        dss_sdi_disable(sdi->dss);
@@ -190,8 +190,6 @@ err_calc_clock_div:
        dispc_runtime_put(sdi->dss->dispc);
 err_get_dispc:
        regulator_disable(sdi->vdds_sdi_reg);
-err_reg_enable:
-       return r;
 }
 
 static void sdi_display_disable(struct omap_dss_device *dssdev)
index bc9a3d52f34d7fe31de0b3b6506913d8e987185b..dc4133718875e6dd7a5f6bffc0ae647d08d93fd9 100644 (file)
@@ -522,25 +522,17 @@ static void venc_power_off(struct venc_device *venc)
        venc_runtime_put(venc);
 }
 
-static int venc_display_enable(struct omap_dss_device *dssdev)
+static void venc_display_enable(struct omap_dss_device *dssdev)
 {
        struct venc_device *venc = dssdev_to_venc(dssdev);
-       int r;
 
        DSSDBG("venc_display_enable\n");
 
        mutex_lock(&venc->venc_lock);
 
-       r = venc_power_on(venc);
-       if (r)
-               goto err0;
-
-       mutex_unlock(&venc->venc_lock);
+       venc_power_on(venc);
 
-       return 0;
-err0:
        mutex_unlock(&venc->venc_lock);
-       return r;
 }
 
 static void venc_display_disable(struct omap_dss_device *dssdev)
index d14d465392dd1c83247736cb79f4d6c858f8f818..acdfd217642386ef555ec686c0acd43ce903628c 100644 (file)
@@ -146,33 +146,60 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
 static void omap_encoder_disable(struct drm_encoder *encoder)
 {
        struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-       struct omap_dss_device *dssdev = omap_encoder->display;
+       struct omap_dss_device *dssdev = omap_encoder->output;
        struct drm_device *dev = encoder->dev;
 
        dev_dbg(dev->dev, "disable(%s)\n", dssdev->name);
 
-       dssdev->ops->disable(dssdev);
+       /*
+        * Disable the chain of external devices, starting at the one at the
+        * internal encoder's output.
+        */
+       omapdss_device_disable(dssdev->next);
+
+       /*
+        * Disable the internal encoder. This will disable the DSS output. The
+        * DSI is treated as an exception as DSI pipelines still use the legacy
+        * flow where the pipeline output controls the encoder.
+        */
+       if (dssdev->output_type != OMAP_DISPLAY_TYPE_DSI) {
+               dssdev->ops->disable(dssdev);
+               dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+       }
 
-       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+       /*
+        * Perform the post-disable operations on the chain of external devices
+        * to complete the display pipeline disable.
+        */
+       omapdss_device_post_disable(dssdev->next);
 }
 
 static void omap_encoder_enable(struct drm_encoder *encoder)
 {
        struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-       struct omap_dss_device *dssdev = omap_encoder->display;
+       struct omap_dss_device *dssdev = omap_encoder->output;
        struct drm_device *dev = encoder->dev;
-       int r;
 
        dev_dbg(dev->dev, "enable(%s)\n", dssdev->name);
 
-       r = dssdev->ops->enable(dssdev);
-       if (r) {
-               dev_err(dev->dev, "Failed to enable display '%s': %d\n",
-                       dssdev->name, r);
-               return;
+       /* Prepare the chain of external devices for pipeline enable. */
+       omapdss_device_pre_enable(dssdev->next);
+
+       /*
+        * Enable the internal encoder. This will enable the DSS output. The
+        * DSI is treated as an exception as DSI pipelines still use the legacy
+        * flow where the pipeline output controls the encoder.
+        */
+       if (dssdev->output_type != OMAP_DISPLAY_TYPE_DSI) {
+               dssdev->ops->enable(dssdev);
+               dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
        }
 
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+       /*
+        * Enable the chain of external devices, starting at the one at the
+        * internal encoder's output.
+        */
+       omapdss_device_enable(dssdev->next);
 }
 
 static int omap_encoder_atomic_check(struct drm_encoder *encoder,