From patchwork Thu Oct 19 03:48:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeffy Chen X-Patchwork-Id: 10015899 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3FC2060215 for ; Thu, 19 Oct 2017 03:49:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2EF6528A95 for ; Thu, 19 Oct 2017 03:49:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 221BE28ABC; Thu, 19 Oct 2017 03:49:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 5706628A95 for ; Thu, 19 Oct 2017 03:49:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A3ADD6E9B5; Thu, 19 Oct 2017 03:49:54 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from regular1.263xmail.com (regular1.263xmail.com [211.150.99.133]) by gabe.freedesktop.org (Postfix) with ESMTPS id 508316E9B5 for ; Thu, 19 Oct 2017 03:49:53 +0000 (UTC) Received: from jeffy.chen?rock-chips.com (unknown [192.168.167.239]) by regular1.263xmail.com (Postfix) with ESMTP id 2F1998F6E; Thu, 19 Oct 2017 11:49:50 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id 4432C3B5; Thu, 19 Oct 2017 11:49:33 +0800 (CST) X-RL-SENDER: jeffy.chen@rock-chips.com X-FST-TO: linux-kernel@vger.kernel.org X-SENDER-IP: 103.29.142.67 X-LOGIN-NAME: jeffy.chen@rock-chips.com X-UNIQUE-TAG: <97bd68dbe95922514489fc5929ab6ce3> X-ATTACHMENT-NUM: 0 X-SENDER: cjf@rock-chips.com X-DNS-TYPE: 0 Received: from localhost (unknown [103.29.142.67]) by smtp.263.net (Postfix) whith ESMTP id 21068LK8RIB; Thu, 19 Oct 2017 11:49:44 +0800 (CST) From: Jeffy Chen To: linux-kernel@vger.kernel.org Subject: [PATCH v6 09/10] drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata Date: Thu, 19 Oct 2017 11:48:11 +0800 Message-Id: <20171019034812.13768-10-jeffy.chen@rock-chips.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171019034812.13768-1-jeffy.chen@rock-chips.com> References: <20171019034812.13768-1-jeffy.chen@rock-chips.com> Cc: Neil Armstrong , dri-devel@lists.freedesktop.org, Hans Verkuil , Laurent Pinchart , Romain Perier , Jonathan Corbet , Kevin Hilman , briannorris@chromium.org, linux-rockchip@lists.infradead.org, Jose Abreu , Jeffy Chen , Russell King , linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, dianders@chromium.org, tfiga@chromium.org, linux-renesas-soc@vger.kernel.org, Kieran Bingham , Carlo Caione X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Let plat drivers own the drvdata, so that they could cleanup resources in their unbind(). Signed-off-by: Jeffy Chen Reviewed-by: Neil Armstrong --- Changes in v6: None Changes in v5: None drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 43 ++++++++++------------------- drivers/gpu/drm/imx/dw_hdmi-imx.c | 22 +++++++++------ drivers/gpu/drm/meson/meson_dw_hdmi.c | 20 ++++++++++---- drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 14 ++++++++-- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 23 ++++++++------- include/drm/bridge/dw_hdmi.h | 17 ++++++------ 6 files changed, 77 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index ff1b3d2b5d06..6fbfafc5832b 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2072,7 +2072,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id) return ret; } -void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) +void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) { mutex_lock(&hdmi->mutex); @@ -2098,13 +2098,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) } mutex_unlock(&hdmi->mutex); } - -void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense) -{ - struct dw_hdmi *hdmi = dev_get_drvdata(dev); - - __dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense); -} EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense); static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) @@ -2140,9 +2133,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) */ if (intr_stat & (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) { - __dw_hdmi_setup_rx_sense(hdmi, - phy_stat & HDMI_PHY_HPD, - phy_stat & HDMI_PHY_RX_SENSE); + dw_hdmi_setup_rx_sense(hdmi, phy_stat & HDMI_PHY_HPD, + phy_stat & HDMI_PHY_RX_SENSE); if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0) cec_notifier_set_phys_addr(hdmi->cec_notifier, @@ -2512,8 +2504,6 @@ __dw_hdmi_probe(struct platform_device *pdev, if (hdmi->i2c) dw_hdmi_i2c_init(hdmi); - platform_set_drvdata(pdev, hdmi); - return hdmi; err_iahb: @@ -2559,25 +2549,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi) /* ----------------------------------------------------------------------------- * Probe/remove API, used from platforms based on the DRM bridge API. */ -int dw_hdmi_probe(struct platform_device *pdev, - const struct dw_hdmi_plat_data *plat_data) +struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, + const struct dw_hdmi_plat_data *plat_data) { struct dw_hdmi *hdmi; hdmi = __dw_hdmi_probe(pdev, plat_data); if (IS_ERR(hdmi)) - return PTR_ERR(hdmi); + return hdmi; drm_bridge_add(&hdmi->bridge); - return 0; + return hdmi; } 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); __dw_hdmi_remove(hdmi); @@ -2587,31 +2575,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove); /* ----------------------------------------------------------------------------- * Bind/unbind API, used from platforms based on the component framework. */ -int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, - const struct dw_hdmi_plat_data *plat_data) +struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, + struct drm_encoder *encoder, + const struct dw_hdmi_plat_data *plat_data) { struct dw_hdmi *hdmi; int ret; hdmi = __dw_hdmi_probe(pdev, plat_data); if (IS_ERR(hdmi)) - return PTR_ERR(hdmi); + return hdmi; ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL); if (ret) { __dw_hdmi_remove(hdmi); 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); -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); } EXPORT_SYMBOL_GPL(dw_hdmi_unbind); diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index b62763aa8706..b01d03e02ce0 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -26,6 +26,8 @@ struct imx_hdmi { struct device *dev; struct drm_encoder encoder; struct regmap *regmap; + + struct dw_hdmi *hdmi; }; static inline struct imx_hdmi *enc_to_imx_hdmi(struct drm_encoder *e) @@ -239,22 +241,24 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); - ret = dw_hdmi_bind(pdev, encoder, plat_data); + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); + if (IS_ERR(hdmi->hdmi)) { + encoder->funcs->destroy(encoder); + return PTR_ERR(hdmi->hdmi); + } - /* - * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), - * which would have called the encoder cleanup. Do it manually. - */ - if (ret) - drm_encoder_cleanup(encoder); + dev_set_drvdata(dev, hdmi); - return ret; + return 0; } static void dw_hdmi_imx_unbind(struct device *dev, struct device *master, void *data) { - return dw_hdmi_unbind(dev); + struct imx_hdmi *hdmi = dev_get_drvdata(dev); + + dw_hdmi_unbind(hdmi->hdmi); + hdmi->encoder.funcs->destroy(&hdmi->encoder); } static const struct component_ops dw_hdmi_imx_ops = { diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index cef414466f9f..fc29f69f7108 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -138,6 +138,8 @@ struct meson_dw_hdmi { struct clk *hdmi_pclk; struct clk *venci_clk; u32 irq_stat; + + struct dw_hdmi *hdmi; }; #define encoder_to_meson_dw_hdmi(x) \ container_of(x, struct meson_dw_hdmi, encoder) @@ -526,7 +528,7 @@ static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id) if (stat & HDMITX_TOP_INTR_HPD_RISE) hpd_connected = true; - dw_hdmi_setup_rx_sense(dw_hdmi->dev, hpd_connected, + dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected, hpd_connected); drm_helper_hpd_irq_event(dw_hdmi->encoder.dev); @@ -865,9 +867,14 @@ 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_encoding = V4L2_YCBCR_ENC_709; - ret = dw_hdmi_bind(pdev, encoder, &meson_dw_hdmi->dw_plat_data); - 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)) { + encoder->funcs->destroy(encoder); + return PTR_ERR(meson_dw_hdmi->hdmi); + } + + dev_set_drvdata(dev, meson_dw_hdmi); DRM_DEBUG_DRIVER("HDMI controller initialized\n"); @@ -877,7 +884,10 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master, static void meson_dw_hdmi_unbind(struct device *dev, struct device *master, void *data) { - dw_hdmi_unbind(dev); + struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev); + + dw_hdmi_unbind(meson_dw_hdmi->hdmi); + meson_dw_hdmi->encoder.funcs->destroy(&meson_dw_hdmi->encoder); } static const struct component_ops meson_dw_hdmi_ops = { diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c index dc85b53d58ef..76210ae25094 100644 --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c @@ -68,12 +68,22 @@ static const struct dw_hdmi_plat_data rcar_dw_hdmi_plat_data = { 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); + + return 0; } static int rcar_dw_hdmi_remove(struct platform_device *pdev) { - dw_hdmi_remove(pdev); + struct dw_hdmi *hdmi = platform_get_drvdata(pdev); + + dw_hdmi_remove(hdmi); return 0; } diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index 1eb02a82fd91..791ab938f998 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -48,6 +48,8 @@ struct rockchip_hdmi { const struct rockchip_hdmi_chip_data *chip_data; struct clk *vpll_clk; struct clk *grf_clk; + + struct dw_hdmi *hdmi; }; #define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x) @@ -164,7 +166,6 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = { static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi) { struct device_node *np = hdmi->dev->of_node; - int ret; hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); if (IS_ERR(hdmi->regmap)) { @@ -377,22 +378,24 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); - ret = dw_hdmi_bind(pdev, encoder, plat_data); + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); + if (IS_ERR(hdmi->hdmi)) { + encoder->funcs->destroy(encoder); + return PTR_ERR(hdmi->hdmi); + } - /* - * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(), - * which would have called the encoder cleanup. Do it manually. - */ - if (ret) - drm_encoder_cleanup(encoder); + dev_set_drvdata(dev, hdmi); - return ret; + return 0; } static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master, void *data) { - return dw_hdmi_unbind(dev); + struct rockchip_hdmi *hdmi = dev_get_drvdata(dev); + + dw_hdmi_unbind(hdmi->hdmi); + hdmi->encoder.funcs->destroy(&hdmi->encoder); } static const struct component_ops dw_hdmi_rockchip_ops = { diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 182f83283e24..29b8900caaf7 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -143,14 +143,15 @@ struct dw_hdmi_plat_data { unsigned long mpixelclock); }; -int dw_hdmi_probe(struct platform_device *pdev, - const struct dw_hdmi_plat_data *plat_data); -void dw_hdmi_remove(struct platform_device *pdev); -void dw_hdmi_unbind(struct device *dev); -int dw_hdmi_bind(struct platform_device *pdev, 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); +struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, + const struct dw_hdmi_plat_data *plat_data); +void dw_hdmi_remove(struct dw_hdmi *hdmi); +void dw_hdmi_unbind(struct dw_hdmi *hdmi); +struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev, + struct drm_encoder *encoder, + const struct dw_hdmi_plat_data *plat_data); + +void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense); void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);