Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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:
8242ecbd597d ("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

authored by

Jernej Skrabec and committed by
Maxime Ripard
eea034af 5765916a

+60 -36
+13 -18
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
··· 2543 2543 if (hdmi->i2c) 2544 2544 dw_hdmi_i2c_init(hdmi); 2545 2545 2546 - platform_set_drvdata(pdev, hdmi); 2547 - 2548 2546 return hdmi; 2549 2547 2550 2548 err_iahb: ··· 2592 2594 /* ----------------------------------------------------------------------------- 2593 2595 * Probe/remove API, used from platforms based on the DRM bridge API. 2594 2596 */ 2595 - int dw_hdmi_probe(struct platform_device *pdev, 2596 - const struct dw_hdmi_plat_data *plat_data) 2597 + struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, 2598 + const struct dw_hdmi_plat_data *plat_data) 2597 2599 { 2598 2600 struct dw_hdmi *hdmi; 2599 2601 2600 2602 hdmi = __dw_hdmi_probe(pdev, plat_data); 2601 2603 if (IS_ERR(hdmi)) 2602 - return PTR_ERR(hdmi); 2604 + return hdmi; 2603 2605 2604 2606 drm_bridge_add(&hdmi->bridge); 2605 2607 2606 - return 0; 2608 + return hdmi; 2607 2609 } 2608 2610 EXPORT_SYMBOL_GPL(dw_hdmi_probe); 2609 2611 2610 - void dw_hdmi_remove(struct platform_device *pdev) 2612 + void dw_hdmi_remove(struct dw_hdmi *hdmi) 2611 2613 { 2612 - struct dw_hdmi *hdmi = platform_get_drvdata(pdev); 2613 - 2614 2614 drm_bridge_remove(&hdmi->bridge); 2615 2615 2616 2616 __dw_hdmi_remove(hdmi); ··· 2618 2622 /* ----------------------------------------------------------------------------- 2619 2623 * Bind/unbind API, used from platforms based on the component framework. 2620 2624 */ 2621 - int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, 2622 - const struct dw_hdmi_plat_data *plat_data) 2625 + struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, 2626 + struct drm_encoder *encoder, 2627 + const struct dw_hdmi_plat_data *plat_data) 2623 2628 { 2624 2629 struct dw_hdmi *hdmi; 2625 2630 int ret; 2626 2631 2627 2632 hdmi = __dw_hdmi_probe(pdev, plat_data); 2628 2633 if (IS_ERR(hdmi)) 2629 - return PTR_ERR(hdmi); 2634 + return hdmi; 2630 2635 2631 2636 ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); 2632 2637 if (ret) { 2633 - dw_hdmi_remove(pdev); 2638 + dw_hdmi_remove(hdmi); 2634 2639 DRM_ERROR("Failed to initialize bridge with drm\n"); 2635 - return ret; 2640 + return ERR_PTR(ret); 2636 2641 } 2637 2642 2638 - return 0; 2643 + return hdmi; 2639 2644 } 2640 2645 EXPORT_SYMBOL_GPL(dw_hdmi_bind); 2641 2646 2642 - void dw_hdmi_unbind(struct device *dev) 2647 + void dw_hdmi_unbind(struct dw_hdmi *hdmi) 2643 2648 { 2644 - struct dw_hdmi *hdmi = dev_get_drvdata(dev); 2645 - 2646 2649 __dw_hdmi_remove(hdmi); 2647 2650 } 2648 2651 EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
+10 -3
drivers/gpu/drm/imx/dw_hdmi-imx.c
··· 25 25 struct imx_hdmi { 26 26 struct device *dev; 27 27 struct drm_encoder encoder; 28 + struct dw_hdmi *hdmi; 28 29 struct regmap *regmap; 29 30 }; 30 31 ··· 240 239 drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, 241 240 DRM_MODE_ENCODER_TMDS, NULL); 242 241 243 - ret = dw_hdmi_bind(pdev, encoder, plat_data); 242 + platform_set_drvdata(pdev, hdmi); 243 + 244 + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); 244 245 245 246 /* 246 247 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), 247 248 * which would have called the encoder cleanup. Do it manually. 248 249 */ 249 - if (ret) 250 + if (IS_ERR(hdmi->hdmi)) { 251 + ret = PTR_ERR(hdmi->hdmi); 250 252 drm_encoder_cleanup(encoder); 253 + } 251 254 252 255 return ret; 253 256 } ··· 259 254 static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, 260 255 void *data) 261 256 { 262 - return dw_hdmi_unbind(dev); 257 + struct imx_hdmi *hdmi = dev_get_drvdata(dev); 258 + 259 + dw_hdmi_unbind(hdmi->hdmi); 263 260 } 264 261 265 262 static const struct component_ops dw_hdmi_imx_ops = {
+10 -4
drivers/gpu/drm/meson/meson_dw_hdmi.c
··· 140 140 struct clk *venci_clk; 141 141 struct regulator *hdmi_supply; 142 142 u32 irq_stat; 143 + struct dw_hdmi *hdmi; 143 144 }; 144 145 #define encoder_to_meson_dw_hdmi(x) \ 145 146 container_of(x, struct meson_dw_hdmi, encoder) ··· 879 878 dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24; 880 879 dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709; 881 880 882 - ret = dw_hdmi_bind(pdev, encoder, &meson_dw_hdmi->dw_plat_data); 883 - if (ret) 884 - return ret; 881 + platform_set_drvdata(pdev, meson_dw_hdmi); 882 + 883 + meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder, 884 + &meson_dw_hdmi->dw_plat_data); 885 + if (IS_ERR(meson_dw_hdmi->hdmi)) 886 + return PTR_ERR(meson_dw_hdmi->hdmi); 885 887 886 888 DRM_DEBUG_DRIVER("HDMI controller initialized\n"); 887 889 ··· 894 890 static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, 895 891 void *data) 896 892 { 897 - dw_hdmi_unbind(dev); 893 + struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); 894 + 895 + dw_hdmi_unbind(meson_dw_hdmi->hdmi); 898 896 } 899 897 900 898 static const struct component_ops meson_dw_hdmi_ops = {
+10 -2
drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c
··· 68 68 69 69 static int rcar_dw_hdmi_probe(struct platform_device *pdev) 70 70 { 71 - return dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data); 71 + struct dw_hdmi *hdmi; 72 + 73 + hdmi = dw_hdmi_probe(pdev, &rcar_dw_hdmi_plat_data); 74 + if (IS_ERR(hdmi)) 75 + return PTR_ERR(hdmi); 76 + 77 + platform_set_drvdata(pdev, hdmi); 72 78 } 73 79 74 80 static int rcar_dw_hdmi_remove(struct platform_device *pdev) 75 81 { 76 - dw_hdmi_remove(pdev); 82 + struct dw_hdmi *hdmi = platform_get_drvdata(dev); 83 + 84 + dw_hdmi_remove(hdmi); 77 85 78 86 return 0; 79 87 }
+10 -3
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
··· 48 48 const struct rockchip_hdmi_chip_data *chip_data; 49 49 struct clk *vpll_clk; 50 50 struct clk *grf_clk; 51 + struct dw_hdmi *hdmi; 51 52 }; 52 53 53 54 #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) ··· 378 377 drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, 379 378 DRM_MODE_ENCODER_TMDS, NULL); 380 379 381 - ret = dw_hdmi_bind(pdev, encoder, plat_data); 380 + platform_set_drvdata(pdev, hdmi); 381 + 382 + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); 382 383 383 384 /* 384 385 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), 385 386 * which would have called the encoder cleanup. Do it manually. 386 387 */ 387 - if (ret) 388 + if (IS_ERR(hdmi->hdmi)) { 389 + ret = PTR_ERR(hdmi->hdmi); 388 390 drm_encoder_cleanup(encoder); 391 + } 389 392 390 393 return ret; 391 394 } ··· 397 392 static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, 398 393 void *data) 399 394 { 400 - return dw_hdmi_unbind(dev); 395 + struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); 396 + 397 + dw_hdmi_unbind(hdmi->hdmi); 401 398 } 402 399 403 400 static const struct component_ops dw_hdmi_rockchip_ops = {
+7 -6
include/drm/bridge/dw_hdmi.h
··· 143 143 unsigned long mpixelclock); 144 144 }; 145 145 146 - int dw_hdmi_probe(struct platform_device *pdev, 147 - const struct dw_hdmi_plat_data *plat_data); 148 - void dw_hdmi_remove(struct platform_device *pdev); 149 - void dw_hdmi_unbind(struct device *dev); 150 - int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, 151 - const struct dw_hdmi_plat_data *plat_data); 146 + struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, 147 + const struct dw_hdmi_plat_data *plat_data); 148 + void dw_hdmi_remove(struct dw_hdmi *hdmi); 149 + void dw_hdmi_unbind(struct dw_hdmi *hdmi); 150 + struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, 151 + struct drm_encoder *encoder, 152 + const struct dw_hdmi_plat_data *plat_data); 152 153 153 154 void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense); 154 155