Commit eea034af authored by Jernej Skrabec's avatar Jernej Skrabec Committed by Maxime Ripard

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:
8242ecbd ("drm/bridge/synopsys: stop clobbering drvdata")

Cc: p.zabel@pengutronix.de
Cc: Laurent.pinchart@ideasonboard.com
Cc: hjc@rock-chips.com
Acked-by: default avatarHeiko Stuebner <heiko@sntech.de>
Acked-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Reviewed-by: default avatarArchit Taneja <architt@codeaurora.org>
Tested-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarJernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@bootlin.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180214200906.31509-6-jernej.skrabec@siol.net
parent 5765916a
...@@ -2543,8 +2543,6 @@ __dw_hdmi_probe(struct platform_device *pdev, ...@@ -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) ...@@ -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); ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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 = { ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment