diff options
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi.c')
| -rw-r--r-- | drivers/gpu/drm/msm/dsi/dsi.c | 71 | 
1 files changed, 44 insertions, 27 deletions
| diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 75ae3008b68f..0fe02529b5e7 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -40,7 +40,12 @@ static int dsi_get_phy(struct msm_dsi *msm_dsi)  	of_node_put(phy_node); -	if (!phy_pdev || !msm_dsi->phy) { +	if (!phy_pdev) { +		DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); +		return -EPROBE_DEFER; +	} +	if (!msm_dsi->phy) { +		put_device(&phy_pdev->dev);  		DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__);  		return -EPROBE_DEFER;  	} @@ -110,20 +115,8 @@ destroy_dsi:  static int dsi_bind(struct device *dev, struct device *master, void *data)  { -	struct drm_device *drm = dev_get_drvdata(master); -	struct msm_drm_private *priv = drm->dev_private; -	struct platform_device *pdev = to_platform_device(dev); -	struct msm_dsi *msm_dsi; - -	DBG(""); -	msm_dsi = dsi_init(pdev); -	if (IS_ERR(msm_dsi)) { -		/* Don't fail the bind if the dsi port is not connected */ -		if (PTR_ERR(msm_dsi) == -ENODEV) -			return 0; -		else -			return PTR_ERR(msm_dsi); -	} +	struct msm_drm_private *priv = dev_get_drvdata(master); +	struct msm_dsi *msm_dsi = dev_get_drvdata(dev);  	priv->dsi[msm_dsi->id] = msm_dsi; @@ -133,15 +126,10 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)  static void dsi_unbind(struct device *dev, struct device *master,  		void *data)  { -	struct drm_device *drm = dev_get_drvdata(master); -	struct msm_drm_private *priv = drm->dev_private; +	struct msm_drm_private *priv = dev_get_drvdata(master);  	struct msm_dsi *msm_dsi = dev_get_drvdata(dev); -	int id = msm_dsi->id; -	if (priv->dsi[id]) { -		dsi_destroy(msm_dsi); -		priv->dsi[id] = NULL; -	} +	priv->dsi[msm_dsi->id] = NULL;  }  static const struct component_ops dsi_ops = { @@ -149,15 +137,40 @@ static const struct component_ops dsi_ops = {  	.unbind = dsi_unbind,  }; -static int dsi_dev_probe(struct platform_device *pdev) +int dsi_dev_attach(struct platform_device *pdev)  {  	return component_add(&pdev->dev, &dsi_ops);  } +void dsi_dev_detach(struct platform_device *pdev) +{ +	component_del(&pdev->dev, &dsi_ops); +} + +static int dsi_dev_probe(struct platform_device *pdev) +{ +	struct msm_dsi *msm_dsi; + +	DBG(""); +	msm_dsi = dsi_init(pdev); +	if (IS_ERR(msm_dsi)) { +		/* Don't fail the bind if the dsi port is not connected */ +		if (PTR_ERR(msm_dsi) == -ENODEV) +			return 0; +		else +			return PTR_ERR(msm_dsi); +	} + +	return 0; +} +  static int dsi_dev_remove(struct platform_device *pdev)  { +	struct msm_dsi *msm_dsi = platform_get_drvdata(pdev); +  	DBG(""); -	component_del(&pdev->dev, &dsi_ops); +	dsi_destroy(msm_dsi); +  	return 0;  } @@ -215,9 +228,13 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,  		goto fail;  	} -	if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) { -		ret = -EINVAL; -		goto fail; +	if (msm_dsi_is_bonded_dsi(msm_dsi) && +	    !msm_dsi_is_master_dsi(msm_dsi)) { +		/* +		 * Do not return an eror here, +		 * Just skip creating encoder/connector for the slave-DSI. +		 */ +		return 0;  	}  	msm_dsi->encoder = encoder; |