| From cf2eeafdcd6c58ed5a24bf607d1cc3aec8c1497a Mon Sep 17 00:00:00 2001 |
| From: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> |
| Date: Tue, 16 Aug 2016 23:26:43 +0300 |
| Subject: [PATCH 297/299] drm: dw_hdmi: use of_get_i2c_adapter_by_node |
| interface |
| |
| This change is needed to properly lock I2C bus driver, which serves |
| DDC. |
| |
| The change fixes an overflow over zero of I2C bus driver user counter: |
| |
| root@imx6q:~# lsmod |
| Not tainted |
| dw_hdmi_ahb_audio 4082 0 - Live 0xbf02c000 |
| dw_hdmi_imx 3498 0 - Live 0xbf00d000 |
| dw_hdmi 16398 2 dw_hdmi_ahb_audio,dw_hdmi_imx, Live 0xbf004000 |
| i2c_imx 16687 0 - Live 0xbf017000 |
| |
| root@imx6q:~# rmmod dw_hdmi_imx |
| root@imx6q:~# lsmod |
| Not tainted |
| dw_hdmi_ahb_audio 4082 0 - Live 0xbf02c000 |
| dw_hdmi 16398 1 dw_hdmi_ahb_audio, Live 0xbf004000 |
| i2c_imx 16687 -1 - Live 0xbf017000 |
| ^^ |
| |
| root@imx6q:~# rmmod i2c_imx |
| rmmod: ERROR: Module i2c_imx is in use |
| |
| Note that prior to this change put_device() coupled with |
| of_find_i2c_adapter_by_node() was missing on error path of |
| dw_hdmi_bind(), added i2c_put_adapter() there along with the change. |
| |
| Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> |
| Acked-by: Russell King <rmk+kernel@arm.linux.org.uk> |
| Cc: Fabio Estevam <fabio.estevam@nxp.com> |
| Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> |
| (cherry picked from commit 9f04a1f2b389a656486c1f9f918a3305569fba6a) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/gpu/drm/bridge/dw-hdmi.c | 14 +++++++++----- |
| 1 file changed, 9 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/gpu/drm/bridge/dw-hdmi.c |
| +++ b/drivers/gpu/drm/bridge/dw-hdmi.c |
| @@ -1681,7 +1681,7 @@ int dw_hdmi_bind(struct device *dev, str |
| |
| ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); |
| if (ddc_node) { |
| - hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); |
| + hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node); |
| of_node_put(ddc_node); |
| if (!hdmi->ddc) { |
| dev_dbg(hdmi->dev, "failed to read ddc node\n"); |
| @@ -1693,20 +1693,22 @@ int dw_hdmi_bind(struct device *dev, str |
| } |
| |
| hdmi->regs = devm_ioremap_resource(dev, iores); |
| - if (IS_ERR(hdmi->regs)) |
| - return PTR_ERR(hdmi->regs); |
| + if (IS_ERR(hdmi->regs)) { |
| + ret = PTR_ERR(hdmi->regs); |
| + goto err_res; |
| + } |
| |
| hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); |
| if (IS_ERR(hdmi->isfr_clk)) { |
| ret = PTR_ERR(hdmi->isfr_clk); |
| dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret); |
| - return ret; |
| + goto err_res; |
| } |
| |
| ret = clk_prepare_enable(hdmi->isfr_clk); |
| if (ret) { |
| dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret); |
| - return ret; |
| + goto err_res; |
| } |
| |
| hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); |
| @@ -1792,6 +1794,8 @@ err_iahb: |
| clk_disable_unprepare(hdmi->iahb_clk); |
| err_isfr: |
| clk_disable_unprepare(hdmi->isfr_clk); |
| +err_res: |
| + i2c_put_adapter(hdmi->ddc); |
| |
| return ret; |
| } |