Patchwork [18/48] drm: omapdrm: displays: Get panel source at connect time

login
register
mail settings
Submitter Laurent Pinchart
Date Oct. 13, 2017, 2:59 p.m.
Message ID <20171013145944.26557-19-laurent.pinchart@ideasonboard.com>
Download mbox | patch
Permalink /patch/10004995/
State New
Headers show

Comments

Laurent Pinchart - Oct. 13, 2017, 2:59 p.m.
The connector drivers need a handle to the source they are connected to
in order to control the source.

All drivers get that handle at probe time, resulting in probe deferral
when the source hasn't been probed yet. However they don't need the
handle until their connect handler is called.

Move retrieval of the source handle to the connect handler to avoid
probe deferrals.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/gpu/drm/omapdrm/displays/panel-dpi.c       | 35 +++++++---------
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c    | 27 +++++++------
 .../omapdrm/displays/panel-lgphilips-lb035q02.c    | 35 +++++++---------
 .../drm/omapdrm/displays/panel-nec-nl8048hl11.c    | 39 ++++++++----------
 .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | 35 +++++++---------
 .../drm/omapdrm/displays/panel-sony-acx565akm.c    | 26 ++++++------
 .../drm/omapdrm/displays/panel-tpo-td028ttec1.c    | 46 +++++++---------------
 .../drm/omapdrm/displays/panel-tpo-td043mtea1.c    | 29 +++++++-------
 8 files changed, 119 insertions(+), 153 deletions(-)
Sebastian Reichel - Oct. 14, 2017, 12:55 p.m.
Hi,

On Fri, Oct 13, 2017 at 05:59:14PM +0300, Laurent Pinchart wrote:
> The connector drivers need a handle to the source they are connected to
> in order to control the source.
> 
> All drivers get that handle at probe time, resulting in probe deferral
> when the source hasn't been probed yet. However they don't need the
> handle until their connect handler is called.
> 
> Move retrieval of the source handle to the connect handler to avoid
> probe deferrals.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  drivers/gpu/drm/omapdrm/displays/panel-dpi.c       | 35 +++++++---------
>  drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c    | 27 +++++++------
>  .../omapdrm/displays/panel-lgphilips-lb035q02.c    | 35 +++++++---------
>  .../drm/omapdrm/displays/panel-nec-nl8048hl11.c    | 39 ++++++++----------
>  .../drm/omapdrm/displays/panel-sharp-ls037v7dw01.c | 35 +++++++---------
>  .../drm/omapdrm/displays/panel-sony-acx565akm.c    | 26 ++++++------
>  .../drm/omapdrm/displays/panel-tpo-td028ttec1.c    | 46 +++++++---------------
>  .../drm/omapdrm/displays/panel-tpo-td043mtea1.c    | 29 +++++++-------
>  8 files changed, 119 insertions(+), 153 deletions(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
> index 6468a765f3d1..e48c4a7d5276 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
> @@ -38,16 +38,25 @@ struct panel_drv_data {
>  static int panel_dpi_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.dpi->connect(in, dssdev);
> -	if (r)
> +	if (r) {
> +		omap_dss_put_device(in);
>  		return r;
> +	}
>  
> +	ddata->in = in;
>  	return 0;
>  }
>  
> @@ -60,6 +69,9 @@ static void panel_dpi_disconnect(struct omap_dss_device *dssdev)
>  		return;
>  
>  	in->ops.dpi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int panel_dpi_enable(struct omap_dss_device *dssdev)
> @@ -165,7 +177,6 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
>  	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
>  	struct device_node *node = pdev->dev.of_node;
>  	struct device_node *bl_node;
> -	struct omap_dss_device *in;
>  	int r;
>  	struct display_timing timing;
>  	struct gpio_desc *gpio;
> @@ -207,15 +218,6 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
>  
>  	videomode_from_timing(&timing, &ddata->vm);
>  
> -	in = omapdss_of_find_source_for_first_ep(node);
> -	if (IS_ERR(in)) {
> -		dev_err(&pdev->dev, "failed to find video source\n");
> -		r = PTR_ERR(in);
> -		goto error_free_backlight;
> -	}
> -
> -	ddata->in = in;
> -
>  	return 0;
>  
>  error_free_backlight:
> @@ -251,29 +253,22 @@ static int panel_dpi_probe(struct platform_device *pdev)
>  	r = omapdss_register_display(dssdev);
>  	if (r) {
>  		dev_err(&pdev->dev, "Failed to register panel\n");
> -		goto err_reg;
> +		return r;
>  	}
>  
>  	return 0;
> -
> -err_reg:
> -	omap_dss_put_device(ddata->in);
> -	return r;
>  }
>  
>  static int __exit panel_dpi_remove(struct platform_device *pdev)
>  {
>  	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
>  	struct omap_dss_device *dssdev = &ddata->dssdev;
> -	struct omap_dss_device *in = ddata->in;
>  
>  	omapdss_unregister_display(dssdev);
>  
>  	panel_dpi_disable(dssdev);
>  	panel_dpi_disconnect(dssdev);
>  
> -	omap_dss_put_device(in);
> -
>  	if (ddata->backlight)
>  		put_device(&ddata->backlight->dev);
>  
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> index aac14f399657..1262b7b08ba2 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
> @@ -703,17 +703,23 @@ static int dsicm_panel_reset(struct panel_drv_data *ddata)
>  static int dsicm_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
>  	struct device *dev = &ddata->pdev->dev;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.dsi->connect(in, dssdev);
>  	if (r) {
>  		dev_err(dev, "Failed to connect to video source\n");
> -		return r;
> +		goto err_connect;
>  	}
>  
>  	r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
> @@ -728,12 +734,15 @@ static int dsicm_connect(struct omap_dss_device *dssdev)
>  		goto err_vc_id;
>  	}
>  
> +	ddata->in = in;
>  	return 0;
>  
>  err_vc_id:
>  	in->ops.dsi->release_vc(ddata->in, ddata->channel);
>  err_req_vc:
>  	in->ops.dsi->disconnect(in, dssdev);
> +err_connect:
> +	omap_dss_put_device(in);
>  	return r;
>  }
>  
> @@ -747,6 +756,9 @@ static void dsicm_disconnect(struct omap_dss_device *dssdev)
>  
>  	in->ops.dsi->release_vc(in, ddata->channel);
>  	in->ops.dsi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int dsicm_enable(struct omap_dss_device *dssdev)
> @@ -1119,7 +1131,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
>  {
>  	struct device_node *node = pdev->dev.of_node;
>  	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
> -	struct omap_dss_device *in;
>  	int gpio;
>  
>  	gpio = of_get_named_gpio(node, "reset-gpios", 0);
> @@ -1137,14 +1148,6 @@ static int dsicm_probe_of(struct platform_device *pdev)
>  		return gpio;
>  	}
>  
> -	in = omapdss_of_find_source_for_first_ep(node);
> -	if (IS_ERR(in)) {
> -		dev_err(&pdev->dev, "failed to find video source\n");
> -		return PTR_ERR(in);
> -	}
> -
> -	ddata->in = in;
> -
>  	/* TODO: ulps, backlight */
>  
>  	return 0;
> @@ -1298,8 +1301,6 @@ static int __exit dsicm_remove(struct platform_device *pdev)
>  		backlight_device_unregister(bldev);
>  	}
>  
> -	omap_dss_put_device(ddata->in);
> -
>  	dsicm_cancel_ulps_work(ddata);
>  	destroy_workqueue(ddata->workqueue);
>  
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
> index b955aa615a5f..bbcf18672433 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
> @@ -119,18 +119,27 @@ static void init_lb035q02_panel(struct spi_device *spi)
>  static int lb035q02_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.dpi->connect(in, dssdev);
> -	if (r)
> +	if (r) {
> +		omap_dss_put_device(in);
>  		return r;
> +	}
>  
>  	init_lb035q02_panel(ddata->spi);
>  
> +	ddata->in = in;
>  	return 0;
>  }
>  
> @@ -143,6 +152,9 @@ static void lb035q02_disconnect(struct omap_dss_device *dssdev)
>  		return;
>  
>  	in->ops.dpi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int lb035q02_enable(struct omap_dss_device *dssdev)
> @@ -230,9 +242,7 @@ static struct omap_dss_driver lb035q02_ops = {
>  
>  static int lb035q02_probe_of(struct spi_device *spi)
>  {
> -	struct device_node *node = spi->dev.of_node;
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
> -	struct omap_dss_device *in;
>  	struct gpio_desc *gpio;
>  
>  	gpio = devm_gpiod_get(&spi->dev, "enable", GPIOD_OUT_LOW);
> @@ -243,14 +253,6 @@ static int lb035q02_probe_of(struct spi_device *spi)
>  
>  	ddata->enable_gpio = gpio;
>  
> -	in = omapdss_of_find_source_for_first_ep(node);
> -	if (IS_ERR(in)) {
> -		dev_err(&spi->dev, "failed to find video source\n");
> -		return PTR_ERR(in);
> -	}
> -
> -	ddata->in = in;
> -
>  	return 0;
>  }
>  
> @@ -284,29 +286,22 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)
>  	r = omapdss_register_display(dssdev);
>  	if (r) {
>  		dev_err(&spi->dev, "Failed to register panel\n");
> -		goto err_reg;
> +		return r;
>  	}
>  
>  	return 0;
> -
> -err_reg:
> -	omap_dss_put_device(ddata->in);
> -	return r;
>  }
>  
>  static int lb035q02_panel_spi_remove(struct spi_device *spi)
>  {
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
>  	struct omap_dss_device *dssdev = &ddata->dssdev;
> -	struct omap_dss_device *in = ddata->in;
>  
>  	omapdss_unregister_display(dssdev);
>  
>  	lb035q02_disable(dssdev);
>  	lb035q02_disconnect(dssdev);
>  
> -	omap_dss_put_device(in);
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
> index 70fa5a04c00e..9e717cd4f194 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
> @@ -115,16 +115,25 @@ static int init_nec_8048_wvga_lcd(struct spi_device *spi)
>  static int nec_8048_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.dpi->connect(in, dssdev);
> -	if (r)
> +	if (r) {
> +		omap_dss_put_device(in);
>  		return r;
> +	}
>  
> +	ddata->in = in;
>  	return 0;
>  }
>  
> @@ -137,6 +146,9 @@ static void nec_8048_disconnect(struct omap_dss_device *dssdev)
>  		return;
>  
>  	in->ops.dpi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int nec_8048_enable(struct omap_dss_device *dssdev)
> @@ -226,7 +238,6 @@ static int nec_8048_probe_of(struct spi_device *spi)
>  {
>  	struct device_node *node = spi->dev.of_node;
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
> -	struct omap_dss_device *in;
>  	int gpio;
>  
>  	gpio = of_get_named_gpio(node, "reset-gpios", 0);
> @@ -239,14 +250,6 @@ static int nec_8048_probe_of(struct spi_device *spi)
>  	/* XXX the panel spec doesn't mention any QVGA pin?? */
>  	ddata->qvga_gpio = -ENOENT;
>  
> -	in = omapdss_of_find_source_for_first_ep(node);
> -	if (IS_ERR(in)) {
> -		dev_err(&spi->dev, "failed to find video source\n");
> -		return PTR_ERR(in);
> -	}
> -
> -	ddata->in = in;
> -
>  	return 0;
>  }
>  
> @@ -285,14 +288,14 @@ static int nec_8048_probe(struct spi_device *spi)
>  		r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio,
>  				GPIOF_OUT_INIT_HIGH, "lcd QVGA");
>  		if (r)
> -			goto err_gpio;
> +			return r;
>  	}
>  
>  	if (gpio_is_valid(ddata->res_gpio)) {
>  		r = devm_gpio_request_one(&spi->dev, ddata->res_gpio,
>  				GPIOF_OUT_INIT_LOW, "lcd RES");
>  		if (r)
> -			goto err_gpio;
> +			return r;
>  	}
>  
>  	ddata->vm = nec_8048_panel_vm;
> @@ -307,22 +310,16 @@ static int nec_8048_probe(struct spi_device *spi)
>  	r = omapdss_register_display(dssdev);
>  	if (r) {
>  		dev_err(&spi->dev, "Failed to register panel\n");
> -		goto err_reg;
> +		return r;
>  	}
>  
>  	return 0;
> -
> -err_reg:
> -err_gpio:
> -	omap_dss_put_device(ddata->in);
> -	return r;
>  }
>  
>  static int nec_8048_remove(struct spi_device *spi)
>  {
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
>  	struct omap_dss_device *dssdev = &ddata->dssdev;
> -	struct omap_dss_device *in = ddata->in;
>  
>  	dev_dbg(&ddata->spi->dev, "%s\n", __func__);
>  
> @@ -331,8 +328,6 @@ static int nec_8048_remove(struct spi_device *spi)
>  	nec_8048_disable(dssdev);
>  	nec_8048_disconnect(dssdev);
>  
> -	omap_dss_put_device(in);
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
> index 99048e430871..d67f09a7ba4f 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
> @@ -61,16 +61,25 @@ static const struct videomode sharp_ls_vm = {
>  static int sharp_ls_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.dpi->connect(in, dssdev);
> -	if (r)
> +	if (r) {
> +		omap_dss_put_device(in);
>  		return r;
> +	}
>  
> +	ddata->in = in;
>  	return 0;
>  }
>  
> @@ -83,6 +92,9 @@ static void sharp_ls_disconnect(struct omap_dss_device *dssdev)
>  		return;
>  
>  	in->ops.dpi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int sharp_ls_enable(struct omap_dss_device *dssdev)
> @@ -210,8 +222,6 @@ static  int sharp_ls_get_gpio_of(struct device *dev, int index, int val,
>  static int sharp_ls_probe_of(struct platform_device *pdev)
>  {
>  	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
> -	struct device_node *node = pdev->dev.of_node;
> -	struct omap_dss_device *in;
>  	int r;
>  
>  	ddata->vcc = devm_regulator_get(&pdev->dev, "envdd");
> @@ -245,14 +255,6 @@ static int sharp_ls_probe_of(struct platform_device *pdev)
>  	if (r)
>  		return r;
>  
> -	in = omapdss_of_find_source_for_first_ep(node);
> -	if (IS_ERR(in)) {
> -		dev_err(&pdev->dev, "failed to find video source\n");
> -		return PTR_ERR(in);
> -	}
> -
> -	ddata->in = in;
> -
>  	return 0;
>  }
>  
> @@ -284,29 +286,22 @@ static int sharp_ls_probe(struct platform_device *pdev)
>  	r = omapdss_register_display(dssdev);
>  	if (r) {
>  		dev_err(&pdev->dev, "Failed to register panel\n");
> -		goto err_reg;
> +		return r;
>  	}
>  
>  	return 0;
> -
> -err_reg:
> -	omap_dss_put_device(ddata->in);
> -	return r;
>  }
>  
>  static int __exit sharp_ls_remove(struct platform_device *pdev)
>  {
>  	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
>  	struct omap_dss_device *dssdev = &ddata->dssdev;
> -	struct omap_dss_device *in = ddata->in;
>  
>  	omapdss_unregister_display(dssdev);
>  
>  	sharp_ls_disable(dssdev);
>  	sharp_ls_disconnect(dssdev);
>  
> -	omap_dss_put_device(in);
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
> index cc5e9a68726a..c4bb33a247d0 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
> @@ -510,16 +510,25 @@ static const struct attribute_group bldev_attr_group = {
>  static int acx565akm_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.sdi->connect(in, dssdev);
> -	if (r)
> +	if (r) {
> +		omap_dss_put_device(in);
>  		return r;
> +	}
>  
> +	ddata->in = in;
>  	return 0;
>  }
>  
> @@ -532,6 +541,9 @@ static void acx565akm_disconnect(struct omap_dss_device *dssdev)
>  		return;
>  
>  	in->ops.sdi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
> @@ -700,12 +712,6 @@ static int acx565akm_probe_of(struct spi_device *spi)
>  
>  	ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
>  
> -	ddata->in = omapdss_of_find_source_for_first_ep(np);
> -	if (IS_ERR(ddata->in)) {
> -		dev_err(&spi->dev, "failed to find video source\n");
> -		return PTR_ERR(ddata->in);
> -	}
> -
>  	return 0;
>  }
>  
> @@ -823,7 +829,6 @@ static int acx565akm_probe(struct spi_device *spi)
>  err_reg_bl:
>  err_detect:
>  err_gpio:
> -	omap_dss_put_device(ddata->in);
>  	return r;
>  }
>  
> @@ -831,7 +836,6 @@ static int acx565akm_remove(struct spi_device *spi)
>  {
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
>  	struct omap_dss_device *dssdev = &ddata->dssdev;
> -	struct omap_dss_device *in = ddata->in;
>  
>  	dev_dbg(&ddata->spi->dev, "%s\n", __func__);
>  
> @@ -843,8 +847,6 @@ static int acx565akm_remove(struct spi_device *spi)
>  	acx565akm_disable(dssdev);
>  	acx565akm_disconnect(dssdev);
>  
> -	omap_dss_put_device(in);
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
> index 34d8f42fefbe..f49127afd17a 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
> @@ -169,16 +169,25 @@ enum jbt_register {
>  static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.dpi->connect(in, dssdev);
> -	if (r)
> +	if (r) {
> +		omap_dss_put_device(in);
>  		return r;
> +	}
>  
> +	ddata->in = in;
>  	return 0;
>  }
>  
> @@ -191,6 +200,9 @@ static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
>  		return;
>  
>  	in->ops.dpi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
> @@ -362,23 +374,6 @@ static struct omap_dss_driver td028ttec1_ops = {
>  	.check_timings	= td028ttec1_panel_check_timings,
>  };
>  
> -static int td028ttec1_probe_of(struct spi_device *spi)
> -{
> -	struct device_node *node = spi->dev.of_node;
> -	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
> -	struct omap_dss_device *in;
> -
> -	in = omapdss_of_find_source_for_first_ep(node);
> -	if (IS_ERR(in)) {
> -		dev_err(&spi->dev, "failed to find video source\n");
> -		return PTR_ERR(in);
> -	}
> -
> -	ddata->in = in;
> -
> -	return 0;
> -}
> -
>  static int td028ttec1_panel_probe(struct spi_device *spi)
>  {
>  	struct panel_drv_data *ddata;
> @@ -404,10 +399,6 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
>  
>  	ddata->spi_dev = spi;
>  
> -	r = td028ttec1_probe_of(spi);
> -	if (r)
> -		return r;
> -
>  	ddata->vm = td028ttec1_panel_vm;
>  
>  	dssdev = &ddata->dssdev;
> @@ -420,21 +411,16 @@ static int td028ttec1_panel_probe(struct spi_device *spi)
>  	r = omapdss_register_display(dssdev);
>  	if (r) {
>  		dev_err(&spi->dev, "Failed to register panel\n");
> -		goto err_reg;
> +		return r;
>  	}
>  
>  	return 0;
> -
> -err_reg:
> -	omap_dss_put_device(ddata->in);
> -	return r;
>  }
>  
>  static int td028ttec1_panel_remove(struct spi_device *spi)
>  {
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
>  	struct omap_dss_device *dssdev = &ddata->dssdev;
> -	struct omap_dss_device *in = ddata->in;
>  
>  	dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
>  
> @@ -443,8 +429,6 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
>  	td028ttec1_panel_disable(dssdev);
>  	td028ttec1_panel_disconnect(dssdev);
>  
> -	omap_dss_put_device(in);
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
> index 06fb5a995002..c08e22b43447 100644
> --- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
> +++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
> @@ -340,16 +340,25 @@ static void tpo_td043_power_off(struct panel_drv_data *ddata)
>  static int tpo_td043_connect(struct omap_dss_device *dssdev)
>  {
>  	struct panel_drv_data *ddata = to_panel_data(dssdev);
> -	struct omap_dss_device *in = ddata->in;
> +	struct omap_dss_device *in;
>  	int r;
>  
>  	if (omapdss_device_is_connected(dssdev))
>  		return 0;
>  
> +	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
> +	if (IS_ERR(in)) {
> +		dev_err(dssdev->dev, "failed to find video source\n");
> +		return PTR_ERR(in);
> +	}
> +
>  	r = in->ops.dpi->connect(in, dssdev);
> -	if (r)
> +	if (r) {
> +		omap_dss_put_device(in);
>  		return r;
> +	}
>  
> +	ddata->in = in;
>  	return 0;
>  }
>  
> @@ -362,6 +371,9 @@ static void tpo_td043_disconnect(struct omap_dss_device *dssdev)
>  		return;
>  
>  	in->ops.dpi->disconnect(in, dssdev);
> +
> +	omap_dss_put_device(in);
> +	ddata->in = NULL;
>  }
>  
>  static int tpo_td043_enable(struct omap_dss_device *dssdev)
> @@ -463,7 +475,6 @@ static int tpo_td043_probe_of(struct spi_device *spi)
>  {
>  	struct device_node *node = spi->dev.of_node;
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
> -	struct omap_dss_device *in;
>  	int gpio;
>  
>  	gpio = of_get_named_gpio(node, "reset-gpios", 0);
> @@ -473,14 +484,6 @@ static int tpo_td043_probe_of(struct spi_device *spi)
>  	}
>  	ddata->nreset_gpio = gpio;
>  
> -	in = omapdss_of_find_source_for_first_ep(node);
> -	if (IS_ERR(in)) {
> -		dev_err(&spi->dev, "failed to find video source\n");
> -		return PTR_ERR(in);
> -	}
> -
> -	ddata->in = in;
> -
>  	return 0;
>  }
>  
> @@ -561,7 +564,6 @@ static int tpo_td043_probe(struct spi_device *spi)
>  err_sysfs:
>  err_gpio_req:
>  err_regulator:
> -	omap_dss_put_device(ddata->in);
>  	return r;
>  }
>  
> @@ -569,7 +571,6 @@ static int tpo_td043_remove(struct spi_device *spi)
>  {
>  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
>  	struct omap_dss_device *dssdev = &ddata->dssdev;
> -	struct omap_dss_device *in = ddata->in;
>  
>  	dev_dbg(&ddata->spi->dev, "%s\n", __func__);
>  
> @@ -578,8 +579,6 @@ static int tpo_td043_remove(struct spi_device *spi)
>  	tpo_td043_disable(dssdev);
>  	tpo_td043_disconnect(dssdev);
>  
> -	omap_dss_put_device(in);
> -
>  	sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
>  
>  	return 0;
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

Patch

diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
index 6468a765f3d1..e48c4a7d5276 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dpi.c
@@ -38,16 +38,25 @@  struct panel_drv_data {
 static int panel_dpi_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.dpi->connect(in, dssdev);
-	if (r)
+	if (r) {
+		omap_dss_put_device(in);
 		return r;
+	}
 
+	ddata->in = in;
 	return 0;
 }
 
@@ -60,6 +69,9 @@  static void panel_dpi_disconnect(struct omap_dss_device *dssdev)
 		return;
 
 	in->ops.dpi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int panel_dpi_enable(struct omap_dss_device *dssdev)
@@ -165,7 +177,6 @@  static int panel_dpi_probe_of(struct platform_device *pdev)
 	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 	struct device_node *node = pdev->dev.of_node;
 	struct device_node *bl_node;
-	struct omap_dss_device *in;
 	int r;
 	struct display_timing timing;
 	struct gpio_desc *gpio;
@@ -207,15 +218,6 @@  static int panel_dpi_probe_of(struct platform_device *pdev)
 
 	videomode_from_timing(&timing, &ddata->vm);
 
-	in = omapdss_of_find_source_for_first_ep(node);
-	if (IS_ERR(in)) {
-		dev_err(&pdev->dev, "failed to find video source\n");
-		r = PTR_ERR(in);
-		goto error_free_backlight;
-	}
-
-	ddata->in = in;
-
 	return 0;
 
 error_free_backlight:
@@ -251,29 +253,22 @@  static int panel_dpi_probe(struct platform_device *pdev)
 	r = omapdss_register_display(dssdev);
 	if (r) {
 		dev_err(&pdev->dev, "Failed to register panel\n");
-		goto err_reg;
+		return r;
 	}
 
 	return 0;
-
-err_reg:
-	omap_dss_put_device(ddata->in);
-	return r;
 }
 
 static int __exit panel_dpi_remove(struct platform_device *pdev)
 {
 	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *in = ddata->in;
 
 	omapdss_unregister_display(dssdev);
 
 	panel_dpi_disable(dssdev);
 	panel_dpi_disconnect(dssdev);
 
-	omap_dss_put_device(in);
-
 	if (ddata->backlight)
 		put_device(&ddata->backlight->dev);
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index aac14f399657..1262b7b08ba2 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -703,17 +703,23 @@  static int dsicm_panel_reset(struct panel_drv_data *ddata)
 static int dsicm_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
 	struct device *dev = &ddata->pdev->dev;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.dsi->connect(in, dssdev);
 	if (r) {
 		dev_err(dev, "Failed to connect to video source\n");
-		return r;
+		goto err_connect;
 	}
 
 	r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
@@ -728,12 +734,15 @@  static int dsicm_connect(struct omap_dss_device *dssdev)
 		goto err_vc_id;
 	}
 
+	ddata->in = in;
 	return 0;
 
 err_vc_id:
 	in->ops.dsi->release_vc(ddata->in, ddata->channel);
 err_req_vc:
 	in->ops.dsi->disconnect(in, dssdev);
+err_connect:
+	omap_dss_put_device(in);
 	return r;
 }
 
@@ -747,6 +756,9 @@  static void dsicm_disconnect(struct omap_dss_device *dssdev)
 
 	in->ops.dsi->release_vc(in, ddata->channel);
 	in->ops.dsi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int dsicm_enable(struct omap_dss_device *dssdev)
@@ -1119,7 +1131,6 @@  static int dsicm_probe_of(struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
 	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-	struct omap_dss_device *in;
 	int gpio;
 
 	gpio = of_get_named_gpio(node, "reset-gpios", 0);
@@ -1137,14 +1148,6 @@  static int dsicm_probe_of(struct platform_device *pdev)
 		return gpio;
 	}
 
-	in = omapdss_of_find_source_for_first_ep(node);
-	if (IS_ERR(in)) {
-		dev_err(&pdev->dev, "failed to find video source\n");
-		return PTR_ERR(in);
-	}
-
-	ddata->in = in;
-
 	/* TODO: ulps, backlight */
 
 	return 0;
@@ -1298,8 +1301,6 @@  static int __exit dsicm_remove(struct platform_device *pdev)
 		backlight_device_unregister(bldev);
 	}
 
-	omap_dss_put_device(ddata->in);
-
 	dsicm_cancel_ulps_work(ddata);
 	destroy_workqueue(ddata->workqueue);
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
index b955aa615a5f..bbcf18672433 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
@@ -119,18 +119,27 @@  static void init_lb035q02_panel(struct spi_device *spi)
 static int lb035q02_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.dpi->connect(in, dssdev);
-	if (r)
+	if (r) {
+		omap_dss_put_device(in);
 		return r;
+	}
 
 	init_lb035q02_panel(ddata->spi);
 
+	ddata->in = in;
 	return 0;
 }
 
@@ -143,6 +152,9 @@  static void lb035q02_disconnect(struct omap_dss_device *dssdev)
 		return;
 
 	in->ops.dpi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int lb035q02_enable(struct omap_dss_device *dssdev)
@@ -230,9 +242,7 @@  static struct omap_dss_driver lb035q02_ops = {
 
 static int lb035q02_probe_of(struct spi_device *spi)
 {
-	struct device_node *node = spi->dev.of_node;
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-	struct omap_dss_device *in;
 	struct gpio_desc *gpio;
 
 	gpio = devm_gpiod_get(&spi->dev, "enable", GPIOD_OUT_LOW);
@@ -243,14 +253,6 @@  static int lb035q02_probe_of(struct spi_device *spi)
 
 	ddata->enable_gpio = gpio;
 
-	in = omapdss_of_find_source_for_first_ep(node);
-	if (IS_ERR(in)) {
-		dev_err(&spi->dev, "failed to find video source\n");
-		return PTR_ERR(in);
-	}
-
-	ddata->in = in;
-
 	return 0;
 }
 
@@ -284,29 +286,22 @@  static int lb035q02_panel_spi_probe(struct spi_device *spi)
 	r = omapdss_register_display(dssdev);
 	if (r) {
 		dev_err(&spi->dev, "Failed to register panel\n");
-		goto err_reg;
+		return r;
 	}
 
 	return 0;
-
-err_reg:
-	omap_dss_put_device(ddata->in);
-	return r;
 }
 
 static int lb035q02_panel_spi_remove(struct spi_device *spi)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *in = ddata->in;
 
 	omapdss_unregister_display(dssdev);
 
 	lb035q02_disable(dssdev);
 	lb035q02_disconnect(dssdev);
 
-	omap_dss_put_device(in);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
index 70fa5a04c00e..9e717cd4f194 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
@@ -115,16 +115,25 @@  static int init_nec_8048_wvga_lcd(struct spi_device *spi)
 static int nec_8048_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.dpi->connect(in, dssdev);
-	if (r)
+	if (r) {
+		omap_dss_put_device(in);
 		return r;
+	}
 
+	ddata->in = in;
 	return 0;
 }
 
@@ -137,6 +146,9 @@  static void nec_8048_disconnect(struct omap_dss_device *dssdev)
 		return;
 
 	in->ops.dpi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int nec_8048_enable(struct omap_dss_device *dssdev)
@@ -226,7 +238,6 @@  static int nec_8048_probe_of(struct spi_device *spi)
 {
 	struct device_node *node = spi->dev.of_node;
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-	struct omap_dss_device *in;
 	int gpio;
 
 	gpio = of_get_named_gpio(node, "reset-gpios", 0);
@@ -239,14 +250,6 @@  static int nec_8048_probe_of(struct spi_device *spi)
 	/* XXX the panel spec doesn't mention any QVGA pin?? */
 	ddata->qvga_gpio = -ENOENT;
 
-	in = omapdss_of_find_source_for_first_ep(node);
-	if (IS_ERR(in)) {
-		dev_err(&spi->dev, "failed to find video source\n");
-		return PTR_ERR(in);
-	}
-
-	ddata->in = in;
-
 	return 0;
 }
 
@@ -285,14 +288,14 @@  static int nec_8048_probe(struct spi_device *spi)
 		r = devm_gpio_request_one(&spi->dev, ddata->qvga_gpio,
 				GPIOF_OUT_INIT_HIGH, "lcd QVGA");
 		if (r)
-			goto err_gpio;
+			return r;
 	}
 
 	if (gpio_is_valid(ddata->res_gpio)) {
 		r = devm_gpio_request_one(&spi->dev, ddata->res_gpio,
 				GPIOF_OUT_INIT_LOW, "lcd RES");
 		if (r)
-			goto err_gpio;
+			return r;
 	}
 
 	ddata->vm = nec_8048_panel_vm;
@@ -307,22 +310,16 @@  static int nec_8048_probe(struct spi_device *spi)
 	r = omapdss_register_display(dssdev);
 	if (r) {
 		dev_err(&spi->dev, "Failed to register panel\n");
-		goto err_reg;
+		return r;
 	}
 
 	return 0;
-
-err_reg:
-err_gpio:
-	omap_dss_put_device(ddata->in);
-	return r;
 }
 
 static int nec_8048_remove(struct spi_device *spi)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *in = ddata->in;
 
 	dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 
@@ -331,8 +328,6 @@  static int nec_8048_remove(struct spi_device *spi)
 	nec_8048_disable(dssdev);
 	nec_8048_disconnect(dssdev);
 
-	omap_dss_put_device(in);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
index 99048e430871..d67f09a7ba4f 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
@@ -61,16 +61,25 @@  static const struct videomode sharp_ls_vm = {
 static int sharp_ls_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.dpi->connect(in, dssdev);
-	if (r)
+	if (r) {
+		omap_dss_put_device(in);
 		return r;
+	}
 
+	ddata->in = in;
 	return 0;
 }
 
@@ -83,6 +92,9 @@  static void sharp_ls_disconnect(struct omap_dss_device *dssdev)
 		return;
 
 	in->ops.dpi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int sharp_ls_enable(struct omap_dss_device *dssdev)
@@ -210,8 +222,6 @@  static  int sharp_ls_get_gpio_of(struct device *dev, int index, int val,
 static int sharp_ls_probe_of(struct platform_device *pdev)
 {
 	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
-	struct device_node *node = pdev->dev.of_node;
-	struct omap_dss_device *in;
 	int r;
 
 	ddata->vcc = devm_regulator_get(&pdev->dev, "envdd");
@@ -245,14 +255,6 @@  static int sharp_ls_probe_of(struct platform_device *pdev)
 	if (r)
 		return r;
 
-	in = omapdss_of_find_source_for_first_ep(node);
-	if (IS_ERR(in)) {
-		dev_err(&pdev->dev, "failed to find video source\n");
-		return PTR_ERR(in);
-	}
-
-	ddata->in = in;
-
 	return 0;
 }
 
@@ -284,29 +286,22 @@  static int sharp_ls_probe(struct platform_device *pdev)
 	r = omapdss_register_display(dssdev);
 	if (r) {
 		dev_err(&pdev->dev, "Failed to register panel\n");
-		goto err_reg;
+		return r;
 	}
 
 	return 0;
-
-err_reg:
-	omap_dss_put_device(ddata->in);
-	return r;
 }
 
 static int __exit sharp_ls_remove(struct platform_device *pdev)
 {
 	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *in = ddata->in;
 
 	omapdss_unregister_display(dssdev);
 
 	sharp_ls_disable(dssdev);
 	sharp_ls_disconnect(dssdev);
 
-	omap_dss_put_device(in);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
index cc5e9a68726a..c4bb33a247d0 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
@@ -510,16 +510,25 @@  static const struct attribute_group bldev_attr_group = {
 static int acx565akm_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.sdi->connect(in, dssdev);
-	if (r)
+	if (r) {
+		omap_dss_put_device(in);
 		return r;
+	}
 
+	ddata->in = in;
 	return 0;
 }
 
@@ -532,6 +541,9 @@  static void acx565akm_disconnect(struct omap_dss_device *dssdev)
 		return;
 
 	in->ops.sdi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
@@ -700,12 +712,6 @@  static int acx565akm_probe_of(struct spi_device *spi)
 
 	ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
 
-	ddata->in = omapdss_of_find_source_for_first_ep(np);
-	if (IS_ERR(ddata->in)) {
-		dev_err(&spi->dev, "failed to find video source\n");
-		return PTR_ERR(ddata->in);
-	}
-
 	return 0;
 }
 
@@ -823,7 +829,6 @@  static int acx565akm_probe(struct spi_device *spi)
 err_reg_bl:
 err_detect:
 err_gpio:
-	omap_dss_put_device(ddata->in);
 	return r;
 }
 
@@ -831,7 +836,6 @@  static int acx565akm_remove(struct spi_device *spi)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *in = ddata->in;
 
 	dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 
@@ -843,8 +847,6 @@  static int acx565akm_remove(struct spi_device *spi)
 	acx565akm_disable(dssdev);
 	acx565akm_disconnect(dssdev);
 
-	omap_dss_put_device(in);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
index 34d8f42fefbe..f49127afd17a 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
@@ -169,16 +169,25 @@  enum jbt_register {
 static int td028ttec1_panel_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.dpi->connect(in, dssdev);
-	if (r)
+	if (r) {
+		omap_dss_put_device(in);
 		return r;
+	}
 
+	ddata->in = in;
 	return 0;
 }
 
@@ -191,6 +200,9 @@  static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev)
 		return;
 
 	in->ops.dpi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
@@ -362,23 +374,6 @@  static struct omap_dss_driver td028ttec1_ops = {
 	.check_timings	= td028ttec1_panel_check_timings,
 };
 
-static int td028ttec1_probe_of(struct spi_device *spi)
-{
-	struct device_node *node = spi->dev.of_node;
-	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-	struct omap_dss_device *in;
-
-	in = omapdss_of_find_source_for_first_ep(node);
-	if (IS_ERR(in)) {
-		dev_err(&spi->dev, "failed to find video source\n");
-		return PTR_ERR(in);
-	}
-
-	ddata->in = in;
-
-	return 0;
-}
-
 static int td028ttec1_panel_probe(struct spi_device *spi)
 {
 	struct panel_drv_data *ddata;
@@ -404,10 +399,6 @@  static int td028ttec1_panel_probe(struct spi_device *spi)
 
 	ddata->spi_dev = spi;
 
-	r = td028ttec1_probe_of(spi);
-	if (r)
-		return r;
-
 	ddata->vm = td028ttec1_panel_vm;
 
 	dssdev = &ddata->dssdev;
@@ -420,21 +411,16 @@  static int td028ttec1_panel_probe(struct spi_device *spi)
 	r = omapdss_register_display(dssdev);
 	if (r) {
 		dev_err(&spi->dev, "Failed to register panel\n");
-		goto err_reg;
+		return r;
 	}
 
 	return 0;
-
-err_reg:
-	omap_dss_put_device(ddata->in);
-	return r;
 }
 
 static int td028ttec1_panel_remove(struct spi_device *spi)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *in = ddata->in;
 
 	dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__);
 
@@ -443,8 +429,6 @@  static int td028ttec1_panel_remove(struct spi_device *spi)
 	td028ttec1_panel_disable(dssdev);
 	td028ttec1_panel_disconnect(dssdev);
 
-	omap_dss_put_device(in);
-
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
index 06fb5a995002..c08e22b43447 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c
@@ -340,16 +340,25 @@  static void tpo_td043_power_off(struct panel_drv_data *ddata)
 static int tpo_td043_connect(struct omap_dss_device *dssdev)
 {
 	struct panel_drv_data *ddata = to_panel_data(dssdev);
-	struct omap_dss_device *in = ddata->in;
+	struct omap_dss_device *in;
 	int r;
 
 	if (omapdss_device_is_connected(dssdev))
 		return 0;
 
+	in = omapdss_of_find_source_for_first_ep(dssdev->dev->of_node);
+	if (IS_ERR(in)) {
+		dev_err(dssdev->dev, "failed to find video source\n");
+		return PTR_ERR(in);
+	}
+
 	r = in->ops.dpi->connect(in, dssdev);
-	if (r)
+	if (r) {
+		omap_dss_put_device(in);
 		return r;
+	}
 
+	ddata->in = in;
 	return 0;
 }
 
@@ -362,6 +371,9 @@  static void tpo_td043_disconnect(struct omap_dss_device *dssdev)
 		return;
 
 	in->ops.dpi->disconnect(in, dssdev);
+
+	omap_dss_put_device(in);
+	ddata->in = NULL;
 }
 
 static int tpo_td043_enable(struct omap_dss_device *dssdev)
@@ -463,7 +475,6 @@  static int tpo_td043_probe_of(struct spi_device *spi)
 {
 	struct device_node *node = spi->dev.of_node;
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
-	struct omap_dss_device *in;
 	int gpio;
 
 	gpio = of_get_named_gpio(node, "reset-gpios", 0);
@@ -473,14 +484,6 @@  static int tpo_td043_probe_of(struct spi_device *spi)
 	}
 	ddata->nreset_gpio = gpio;
 
-	in = omapdss_of_find_source_for_first_ep(node);
-	if (IS_ERR(in)) {
-		dev_err(&spi->dev, "failed to find video source\n");
-		return PTR_ERR(in);
-	}
-
-	ddata->in = in;
-
 	return 0;
 }
 
@@ -561,7 +564,6 @@  static int tpo_td043_probe(struct spi_device *spi)
 err_sysfs:
 err_gpio_req:
 err_regulator:
-	omap_dss_put_device(ddata->in);
 	return r;
 }
 
@@ -569,7 +571,6 @@  static int tpo_td043_remove(struct spi_device *spi)
 {
 	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);
 	struct omap_dss_device *dssdev = &ddata->dssdev;
-	struct omap_dss_device *in = ddata->in;
 
 	dev_dbg(&ddata->spi->dev, "%s\n", __func__);
 
@@ -578,8 +579,6 @@  static int tpo_td043_remove(struct spi_device *spi)
 	tpo_td043_disable(dssdev);
 	tpo_td043_disconnect(dssdev);
 
-	omap_dss_put_device(in);
-
 	sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
 
 	return 0;