drm/meson: dw-hdmi: Disable clocks on driver teardown
The HDMI driver request clocks early, but never disable them, leaving the clocks on even when the driver is removed. Fix it by slightly refactoring the clock code, and register a devm action that will eventually disable/unprepare the enabled clocks. Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201120094205.525228-2-maz@kernel.org
This commit is contained in:
parent
f0aee45ffc
commit
1dfeea9045
|
@ -145,8 +145,6 @@ struct meson_dw_hdmi {
|
|||
struct reset_control *hdmitx_apb;
|
||||
struct reset_control *hdmitx_ctrl;
|
||||
struct reset_control *hdmitx_phy;
|
||||
struct clk *hdmi_pclk;
|
||||
struct clk *venci_clk;
|
||||
struct regulator *hdmi_supply;
|
||||
u32 irq_stat;
|
||||
struct dw_hdmi *hdmi;
|
||||
|
@ -946,6 +944,29 @@ static void meson_disable_regulator(void *data)
|
|||
regulator_disable(data);
|
||||
}
|
||||
|
||||
static void meson_disable_clk(void *data)
|
||||
{
|
||||
clk_disable_unprepare(data);
|
||||
}
|
||||
|
||||
static int meson_enable_clk(struct device *dev, char *name)
|
||||
{
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk = devm_clk_get(dev, name);
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(dev, "Unable to get %s pclk\n", name);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(clk);
|
||||
if (!ret)
|
||||
ret = devm_add_action_or_reset(dev, meson_disable_clk, clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
|
||||
void *data)
|
||||
{
|
||||
|
@ -1026,19 +1047,13 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
|
|||
if (IS_ERR(meson_dw_hdmi->hdmitx))
|
||||
return PTR_ERR(meson_dw_hdmi->hdmitx);
|
||||
|
||||
meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr");
|
||||
if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) {
|
||||
dev_err(dev, "Unable to get HDMI pclk\n");
|
||||
return PTR_ERR(meson_dw_hdmi->hdmi_pclk);
|
||||
}
|
||||
clk_prepare_enable(meson_dw_hdmi->hdmi_pclk);
|
||||
ret = meson_enable_clk(dev, "isfr");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci");
|
||||
if (IS_ERR(meson_dw_hdmi->venci_clk)) {
|
||||
dev_err(dev, "Unable to get venci clk\n");
|
||||
return PTR_ERR(meson_dw_hdmi->venci_clk);
|
||||
}
|
||||
clk_prepare_enable(meson_dw_hdmi->venci_clk);
|
||||
ret = meson_enable_clk(dev, "venci");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi,
|
||||
&meson_dw_hdmi_regmap_config);
|
||||
|
|
Loading…
Reference in New Issue