drm/omap: Don't call .detect() operation recursively
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Mon, 28 May 2018 13:49:36 +0000 (16:49 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 3 Sep 2018 13:13:29 +0000 (16:13 +0300)
Instead of calling the .detect() operation recursively from the display
device back to the first device that provides hot plug detection
support, iterate over the devices manually in the DRM connector
.detect() implementation. This moves the complexity to a single central
location and simplifies the logic in omap_dss_device drivers.

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/connector-dvi.c
drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
drivers/gpu/drm/omapdrm/omap_connector.c

index a639a86cd47b1fa43907f20975b96d0390105406..f1674b3eee5063a25158e57a7ab3ba73edc45e13 100644 (file)
@@ -372,6 +372,8 @@ static int dvic_probe(struct platform_device *pdev)
        dssdev->type = OMAP_DISPLAY_TYPE_DVI;
        dssdev->owner = THIS_MODULE;
        dssdev->of_ports = BIT(0);
+       dssdev->ops_flags = ddata->hpd_gpio || ddata->i2c_adapter
+                         ? OMAP_DSS_DEVICE_OP_DETECT : 0;
 
        omapdss_display_init(dssdev);
        omapdss_device_register(dssdev);
index 54bfd715636090c727c7bad5af4c1fda77d1477c..0d22d7004c98d958780ce2098344fb3bef6e4aa8 100644 (file)
@@ -141,10 +141,7 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
        struct omap_dss_device *src = dssdev->src;
        bool connected;
 
-       if (ddata->hpd_gpio)
-               connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
-       else
-               connected = src->ops->detect(src);
+       connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
        if (!connected && src->ops->hdmi.lost_hotplug)
                src->ops->hdmi.lost_hotplug(src);
        return connected;
@@ -317,6 +314,7 @@ static int hdmic_probe(struct platform_device *pdev)
        dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
        dssdev->owner = THIS_MODULE;
        dssdev->of_ports = BIT(0);
+       dssdev->ops_flags = ddata->hpd_gpio ? OMAP_DSS_DEVICE_OP_DETECT : 0;
 
        omapdss_display_init(dssdev);
        omapdss_device_register(dssdev);
index 0cc7bd65647301716287d45f48e28f906e80d49b..e30ead0cacb725910b96fc2b35c69d8e5cfa380a 100644 (file)
@@ -132,8 +132,9 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
 {
        struct panel_drv_data *ddata = to_panel_data(dssdev);
        struct omap_dss_device *src = dssdev->src;
-       bool connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
+       bool connected;
 
+       connected = gpiod_get_value_cansleep(ddata->hpd_gpio);
        if (!connected && src->ops->hdmi.lost_hotplug)
                src->ops->hdmi.lost_hotplug(src);
        return connected;
@@ -288,6 +289,7 @@ static int tpd_probe(struct platform_device *pdev)
        dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI;
        dssdev->owner = THIS_MODULE;
        dssdev->of_ports = BIT(1) | BIT(0);
+       dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT;
 
        dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1);
        if (IS_ERR(dssdev->next)) {
index f9cc04c7c0fafc40f26e1a6be4b4bef4865030f4..4729af3951560c043a40ddc5862d93b75ee73469 100644 (file)
@@ -61,26 +61,36 @@ static enum drm_connector_status omap_connector_detect(
                struct drm_connector *connector, bool force)
 {
        struct omap_connector *omap_connector = to_omap_connector(connector);
-       struct omap_dss_device *dssdev = omap_connector->dssdev;
-       enum drm_connector_status ret;
+       struct omap_dss_device *dssdev;
+       enum drm_connector_status status;
+
+       for (dssdev = omap_connector->dssdev; dssdev; dssdev = dssdev->src) {
+               if (dssdev->ops_flags & OMAP_DSS_DEVICE_OP_DETECT)
+                       break;
+       }
 
-       if (dssdev->ops->detect) {
+       if (dssdev) {
                if (dssdev->ops->detect(dssdev))
-                       ret = connector_status_connected;
+                       status = connector_status_connected;
                else
-                       ret = connector_status_disconnected;
-       } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI ||
-                       dssdev->type == OMAP_DISPLAY_TYPE_DBI ||
-                       dssdev->type == OMAP_DISPLAY_TYPE_SDI ||
-                       dssdev->type == OMAP_DISPLAY_TYPE_DSI) {
-               ret = connector_status_connected;
+                       status = connector_status_disconnected;
        } else {
-               ret = connector_status_unknown;
+               switch (omap_connector->dssdev->type) {
+               case OMAP_DISPLAY_TYPE_DPI:
+               case OMAP_DISPLAY_TYPE_DBI:
+               case OMAP_DISPLAY_TYPE_SDI:
+               case OMAP_DISPLAY_TYPE_DSI:
+                       status = connector_status_connected;
+                       break;
+               default:
+                       status = connector_status_unknown;
+                       break;
+               }
        }
 
-       VERB("%s: %d (force=%d)", omap_connector->dssdev->name, ret, force);
+       VERB("%s: %d (force=%d)", omap_connector->dssdev->name, status, force);
 
-       return ret;
+       return status;
 }
 
 static void omap_connector_destroy(struct drm_connector *connector)