forked from mirrors/linux
		
	drm/bridge/synopsys: dw-hdmi: don't clobber drvdata
dw_hdmi shouldn't set drvdata since some drivers might need to store
it's own data there. Rework dw_hdmi in a way to return struct dw_hdmi
instead to store it in drvdata. This way drivers are responsible to
store and pass structure when needed.
Idea was taken from the following commit:
8242ecbd59 ("drm/bridge/synopsys: stop clobbering drvdata")
Cc: p.zabel@pengutronix.de
Cc: Laurent.pinchart@ideasonboard.com
Cc: hjc@rock-chips.com
Acked-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Archit Taneja <architt@codeaurora.org>
Tested-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180214200906.31509-6-jernej.skrabec@siol.net
			
			
This commit is contained in:
		
							parent
							
								
									5765916afa
								
							
						
					
					
						commit
						eea034af90
					
				
					 6 changed files with 60 additions and 36 deletions
				
			
		| 
						 | 
					@ -2543,8 +2543,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
 | 
				
			||||||
	if (hdmi->i2c)
 | 
						if (hdmi->i2c)
 | 
				
			||||||
		dw_hdmi_i2c_init(hdmi);
 | 
							dw_hdmi_i2c_init(hdmi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	platform_set_drvdata(pdev, hdmi);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return hdmi;
 | 
						return hdmi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
err_iahb:
 | 
					err_iahb:
 | 
				
			||||||
| 
						 | 
					@ -2594,25 +2592,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
 | 
				
			||||||
/* -----------------------------------------------------------------------------
 | 
					/* -----------------------------------------------------------------------------
 | 
				
			||||||
 * Probe/remove API, used from platforms based on the DRM bridge API.
 | 
					 * Probe/remove API, used from platforms based on the DRM bridge API.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int dw_hdmi_probe(struct platform_device *pdev,
 | 
					struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
 | 
				
			||||||
		  const struct dw_hdmi_plat_data *plat_data)
 | 
								      const struct dw_hdmi_plat_data *plat_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dw_hdmi *hdmi;
 | 
						struct dw_hdmi *hdmi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hdmi = __dw_hdmi_probe(pdev, plat_data);
 | 
						hdmi = __dw_hdmi_probe(pdev, plat_data);
 | 
				
			||||||
	if (IS_ERR(hdmi))
 | 
						if (IS_ERR(hdmi))
 | 
				
			||||||
		return PTR_ERR(hdmi);
 | 
							return hdmi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drm_bridge_add(&hdmi->bridge);
 | 
						drm_bridge_add(&hdmi->bridge);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return hdmi;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(dw_hdmi_probe);
 | 
					EXPORT_SYMBOL_GPL(dw_hdmi_probe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dw_hdmi_remove(struct platform_device *pdev)
 | 
					void dw_hdmi_remove(struct dw_hdmi *hdmi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	drm_bridge_remove(&hdmi->bridge);
 | 
						drm_bridge_remove(&hdmi->bridge);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__dw_hdmi_remove(hdmi);
 | 
						__dw_hdmi_remove(hdmi);
 | 
				
			||||||
| 
						 | 
					@ -2622,31 +2618,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
 | 
				
			||||||
/* -----------------------------------------------------------------------------
 | 
					/* -----------------------------------------------------------------------------
 | 
				
			||||||
 * Bind/unbind API, used from platforms based on the component framework.
 | 
					 * Bind/unbind API, used from platforms based on the component framework.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 | 
					struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
 | 
				
			||||||
		 const struct dw_hdmi_plat_data *plat_data)
 | 
								     struct drm_encoder *encoder,
 | 
				
			||||||
 | 
								     const struct dw_hdmi_plat_data *plat_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dw_hdmi *hdmi;
 | 
						struct dw_hdmi *hdmi;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hdmi = __dw_hdmi_probe(pdev, plat_data);
 | 
						hdmi = __dw_hdmi_probe(pdev, plat_data);
 | 
				
			||||||
	if (IS_ERR(hdmi))
 | 
						if (IS_ERR(hdmi))
 | 
				
			||||||
		return PTR_ERR(hdmi);
 | 
							return hdmi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL);
 | 
						ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL);
 | 
				
			||||||
	if (ret) {
 | 
						if (ret) {
 | 
				
			||||||
		dw_hdmi_remove(pdev);
 | 
							dw_hdmi_remove(hdmi);
 | 
				
			||||||
		DRM_ERROR("Failed to initialize bridge with drm\n");
 | 
							DRM_ERROR("Failed to initialize bridge with drm\n");
 | 
				
			||||||
		return ret;
 | 
							return ERR_PTR(ret);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return hdmi;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 | 
					EXPORT_SYMBOL_GPL(dw_hdmi_bind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dw_hdmi_unbind(struct device *dev)
 | 
					void dw_hdmi_unbind(struct dw_hdmi *hdmi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	__dw_hdmi_remove(hdmi);
 | 
						__dw_hdmi_remove(hdmi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
 | 
					EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@
 | 
				
			||||||
struct imx_hdmi {
 | 
					struct imx_hdmi {
 | 
				
			||||||
	struct device *dev;
 | 
						struct device *dev;
 | 
				
			||||||
	struct drm_encoder encoder;
 | 
						struct drm_encoder encoder;
 | 
				
			||||||
 | 
						struct dw_hdmi *hdmi;
 | 
				
			||||||
	struct regmap *regmap;
 | 
						struct regmap *regmap;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -239,14 +240,18 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 | 
				
			||||||
	drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
 | 
						drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs,
 | 
				
			||||||
			 DRM_MODE_ENCODER_TMDS, NULL);
 | 
								 DRM_MODE_ENCODER_TMDS, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = dw_hdmi_bind(pdev, encoder, plat_data);
 | 
						platform_set_drvdata(pdev, hdmi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
 | 
						 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
 | 
				
			||||||
	 * which would have called the encoder cleanup.  Do it manually.
 | 
						 * which would have called the encoder cleanup.  Do it manually.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (ret)
 | 
						if (IS_ERR(hdmi->hdmi)) {
 | 
				
			||||||
 | 
							ret = PTR_ERR(hdmi->hdmi);
 | 
				
			||||||
		drm_encoder_cleanup(encoder);
 | 
							drm_encoder_cleanup(encoder);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -254,7 +259,9 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,
 | 
				
			||||||
static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
 | 
					static void dw_hdmi_imx_unbind(struct device *dev, struct device *master,
 | 
				
			||||||
			       void *data)
 | 
								       void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return dw_hdmi_unbind(dev);
 | 
						struct imx_hdmi *hdmi = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dw_hdmi_unbind(hdmi->hdmi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct component_ops dw_hdmi_imx_ops = {
 | 
					static const struct component_ops dw_hdmi_imx_ops = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,6 +140,7 @@ struct meson_dw_hdmi {
 | 
				
			||||||
	struct clk *venci_clk;
 | 
						struct clk *venci_clk;
 | 
				
			||||||
	struct regulator *hdmi_supply;
 | 
						struct regulator *hdmi_supply;
 | 
				
			||||||
	u32 irq_stat;
 | 
						u32 irq_stat;
 | 
				
			||||||
 | 
						struct dw_hdmi *hdmi;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
#define encoder_to_meson_dw_hdmi(x) \
 | 
					#define encoder_to_meson_dw_hdmi(x) \
 | 
				
			||||||
	container_of(x, struct meson_dw_hdmi, encoder)
 | 
						container_of(x, struct meson_dw_hdmi, encoder)
 | 
				
			||||||
| 
						 | 
					@ -878,9 +879,12 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 | 
				
			||||||
	dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
 | 
						dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
 | 
				
			||||||
	dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709;
 | 
						dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = dw_hdmi_bind(pdev, encoder, &meson_dw_hdmi->dw_plat_data);
 | 
						platform_set_drvdata(pdev, meson_dw_hdmi);
 | 
				
			||||||
	if (ret)
 | 
					
 | 
				
			||||||
		return ret;
 | 
						meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder,
 | 
				
			||||||
 | 
										   &meson_dw_hdmi->dw_plat_data);
 | 
				
			||||||
 | 
						if (IS_ERR(meson_dw_hdmi->hdmi))
 | 
				
			||||||
 | 
							return PTR_ERR(meson_dw_hdmi->hdmi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DRM_DEBUG_DRIVER("HDMI controller initialized\n");
 | 
						DRM_DEBUG_DRIVER("HDMI controller initialized\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -890,7 +894,9 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
 | 
				
			||||||
static void meson_dw_hdmi_unbind(struct device *dev, struct device *master,
 | 
					static void meson_dw_hdmi_unbind(struct device *dev, struct device *master,
 | 
				
			||||||
				   void *data)
 | 
									   void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dw_hdmi_unbind(dev);
 | 
						struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dw_hdmi_unbind(meson_dw_hdmi->hdmi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct component_ops meson_dw_hdmi_ops = {
 | 
					static const struct component_ops meson_dw_hdmi_ops = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,12 +68,20 @@ static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rcar_dw_hdmi_probe(struct platform_device *pdev)
 | 
					static int rcar_dw_hdmi_probe(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data);
 | 
						struct dw_hdmi *hdmi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdmi = dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data);
 | 
				
			||||||
 | 
						if (IS_ERR(hdmi))
 | 
				
			||||||
 | 
							return PTR_ERR(hdmi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						platform_set_drvdata(pdev, hdmi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int rcar_dw_hdmi_remove(struct platform_device *pdev)
 | 
					static int rcar_dw_hdmi_remove(struct platform_device *pdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	dw_hdmi_remove(pdev);
 | 
						struct dw_hdmi *hdmi = platform_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dw_hdmi_remove(hdmi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,7 @@ struct rockchip_hdmi {
 | 
				
			||||||
	const struct rockchip_hdmi_chip_data *chip_data;
 | 
						const struct rockchip_hdmi_chip_data *chip_data;
 | 
				
			||||||
	struct clk *vpll_clk;
 | 
						struct clk *vpll_clk;
 | 
				
			||||||
	struct clk *grf_clk;
 | 
						struct clk *grf_clk;
 | 
				
			||||||
 | 
						struct dw_hdmi *hdmi;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define to_rockchip_hdmi(x)	container_of(x, struct rockchip_hdmi, x)
 | 
					#define to_rockchip_hdmi(x)	container_of(x, struct rockchip_hdmi, x)
 | 
				
			||||||
| 
						 | 
					@ -377,14 +378,18 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 | 
				
			||||||
	drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
 | 
						drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs,
 | 
				
			||||||
			 DRM_MODE_ENCODER_TMDS, NULL);
 | 
								 DRM_MODE_ENCODER_TMDS, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = dw_hdmi_bind(pdev, encoder, plat_data);
 | 
						platform_set_drvdata(pdev, hdmi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
 | 
						 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
 | 
				
			||||||
	 * which would have called the encoder cleanup.  Do it manually.
 | 
						 * which would have called the encoder cleanup.  Do it manually.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (ret)
 | 
						if (IS_ERR(hdmi->hdmi)) {
 | 
				
			||||||
 | 
							ret = PTR_ERR(hdmi->hdmi);
 | 
				
			||||||
		drm_encoder_cleanup(encoder);
 | 
							drm_encoder_cleanup(encoder);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -392,7 +397,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 | 
				
			||||||
static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
 | 
					static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
 | 
				
			||||||
				    void *data)
 | 
									    void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return dw_hdmi_unbind(dev);
 | 
						struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dw_hdmi_unbind(hdmi->hdmi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct component_ops dw_hdmi_rockchip_ops = {
 | 
					static const struct component_ops dw_hdmi_rockchip_ops = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,12 +143,13 @@ struct dw_hdmi_plat_data {
 | 
				
			||||||
			     unsigned long mpixelclock);
 | 
								     unsigned long mpixelclock);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int dw_hdmi_probe(struct platform_device *pdev,
 | 
					struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
 | 
				
			||||||
		  const struct dw_hdmi_plat_data *plat_data);
 | 
								      const struct dw_hdmi_plat_data *plat_data);
 | 
				
			||||||
void dw_hdmi_remove(struct platform_device *pdev);
 | 
					void dw_hdmi_remove(struct dw_hdmi *hdmi);
 | 
				
			||||||
void dw_hdmi_unbind(struct device *dev);
 | 
					void dw_hdmi_unbind(struct dw_hdmi *hdmi);
 | 
				
			||||||
int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
 | 
					struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
 | 
				
			||||||
		 const struct dw_hdmi_plat_data *plat_data);
 | 
								     struct drm_encoder *encoder,
 | 
				
			||||||
 | 
								     const struct dw_hdmi_plat_data *plat_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense);
 | 
					void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue