diff mbox

[13/21] drm/omap: Don't call .detect() operation recursively

Message ID 20180606093650.26034-14-laurent.pinchart@ideasonboard.com (mailing list archive)
State New, archived
Headers show

Commit Message

Laurent Pinchart June 6, 2018, 9:36 a.m. UTC
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>
---
 drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  2 ++
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  6 ++--
 .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  4 ++-
 drivers/gpu/drm/omapdrm/omap_connector.c           | 36 ++++++++++++++--------
 4 files changed, 30 insertions(+), 18 deletions(-)

Comments

Sebastian Reichel June 11, 2018, 4:09 p.m. UTC | #1
Hi,

On Wed, Jun 06, 2018 at 12:36:42PM +0300, Laurent Pinchart wrote:
> 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>

-- Sebastian

>  drivers/gpu/drm/omapdrm/displays/connector-dvi.c   |  2 ++
>  drivers/gpu/drm/omapdrm/displays/connector-hdmi.c  |  6 ++--
>  .../gpu/drm/omapdrm/displays/encoder-tpd12s015.c   |  4 ++-
>  drivers/gpu/drm/omapdrm/omap_connector.c           | 36 ++++++++++++++--------
>  4 files changed, 30 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
> index a639a86cd47b..f1674b3eee50 100644
> --- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
> +++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
> @@ -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);
> diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
> index 54bfd7156360..0d22d7004c98 100644
> --- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
> +++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
> @@ -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);
> diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
> index 545a06e6ca11..f37878ca6077 100644
> --- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
> +++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
> @@ -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)) {
> diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
> index a5e581c8c8d6..6c02c2492d47 100644
> --- a/drivers/gpu/drm/omapdrm/omap_connector.c
> +++ b/drivers/gpu/drm/omapdrm/omap_connector.c
> @@ -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)
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
index a639a86cd47b..f1674b3eee50 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-dvi.c
@@ -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);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 54bfd7156360..0d22d7004c98 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -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);
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index 545a06e6ca11..f37878ca6077 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -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)) {
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index a5e581c8c8d6..6c02c2492d47 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -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)