Re: [PATCH v4 3/8] drm/bridge/synopsys: dsi: add ability to have glue-specific attach and detach

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 14.08.2018 12:26, Heiko Stuebner wrote:
> With the regular means of adding the dsi-component in probe it creates
> a race condition with the panel probing, as the panel device only gets
> created after the dsi-bus got created.
>
> When the panel-driver is build as a module it currently fails hard as the
> panel cannot be probed directly:
>
> dw_mipi_dsi_bind()
>   __dw_mipi_dsi_probe()
>     creates dsi bus
>     creates panel device
>     triggers panel module load
>     panel not probed (module not loaded or panel probe slow)
>   drm_bridge_attach
>     fails with -EINVAL due to empty panel_bridge
>
> Additionally the panel probing can run concurrently with dsi bringup
> making it possible that the panel can already be found but dsi-attach
> hasn't finished running.
>
> To solve that cleanly we may want to only create the component after
> the panel has finished probing, by calling component_add from the
> host-attach dsi callback.
>
> As that is specific to glue drivers, add a new struct for host_ops
> so that glue drivers can tell the bridge to call specific functions
> after the common host-attach and before the common host-detach run.

Sometimes I have an impression that core/glue driver architecture with
callbacks to glue drivers is quite complicated, and smells mid-layer
mistake :), I wonder if simple bunch of helpers with some base object
wouldn't be better, but this is subject for other discussion.

>
> Suggested-by: Andrzej Hajda <a.hajda@xxxxxxxxxxx>
> Signed-off-by: Heiko Stuebner <heiko@xxxxxxxxx>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 15 +++++++++++++++
>  include/drm/bridge/dw_mipi_dsi.h              |  8 ++++++++
>  2 files changed, 23 insertions(+)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> index bb4aeca5c0f9..3962e5d84e1e 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> @@ -270,6 +270,7 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
>  				   struct mipi_dsi_device *device)
>  {
>  	struct dw_mipi_dsi *dsi = host_to_dsi(host);
> +	const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
>  	struct drm_bridge *bridge;
>  	struct drm_panel *panel;
>  	int ret;
> @@ -300,6 +301,12 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
>  
>  	drm_bridge_add(&dsi->bridge);
>  
> +	if (pdata->host_ops && pdata->host_ops->attach) {
> +		ret = pdata->host_ops->attach(pdata->priv_data, device);
> +		if (ret < 0)
> +			return ret;

It could be replaced by:
    return pdata->host_ops->attach(pdata->priv_data, device);

But no strong feelings. With or without the change:

Reviewed-by: Andrzej Hajda <a.hajda@xxxxxxxxxxx>

 --
Regards
Andrzej

> +	}
> +
>  	return 0;
>  }
>  
> @@ -307,6 +314,14 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
>  				   struct mipi_dsi_device *device)
>  {
>  	struct dw_mipi_dsi *dsi = host_to_dsi(host);
> +	const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
> +	int ret;
> +
> +	if (pdata->host_ops && pdata->host_ops->detach) {
> +		ret = pdata->host_ops->detach(pdata->priv_data, device);
> +		if (ret < 0)
> +			return ret;
> +	}
>  
>  	drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
>  
> diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h
> index 6d7f8eb5d9f2..a9c03099cf3e 100644
> --- a/include/drm/bridge/dw_mipi_dsi.h
> +++ b/include/drm/bridge/dw_mipi_dsi.h
> @@ -19,6 +19,13 @@ struct dw_mipi_dsi_phy_ops {
>  			     unsigned int *lane_mbps);
>  };
>  
> +struct dw_mipi_dsi_host_ops {
> +	int (*attach)(void *priv_data,
> +		      struct mipi_dsi_device *dsi);
> +	int (*detach)(void *priv_data,
> +		      struct mipi_dsi_device *dsi);
> +};
> +
>  struct dw_mipi_dsi_plat_data {
>  	void __iomem *base;
>  	unsigned int max_data_lanes;
> @@ -27,6 +34,7 @@ struct dw_mipi_dsi_plat_data {
>  					   const struct drm_display_mode *mode);
>  
>  	const struct dw_mipi_dsi_phy_ops *phy_ops;
> +	const struct dw_mipi_dsi_host_ops *host_ops;
>  
>  	void *priv_data;
>  };





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux