提交 e16a922a 编写于 作者: O Omar Ramirez Luna 提交者: Greg Kroah-Hartman

staging: tidspbridge: use prepare/unprepare on dsp clocks

This solves runtime failures while trying to enable WDT3 related
functionality on firmware load, however it does affect other clocks
controlled by the driver. Seen on 3.8-rc1.

CCF provides clk_prepare and clk_unprepare for enable and disable
operations respectively, this needs to be called in the correct
order while handling clocks.

Code path to enable/disable dsp clocks can still be reached from an
atomic context, hence we can't use clk_prepare_enable and
clk_disable_unprepare yet.
Signed-off-by: NOmar Ramirez Luna <omar.ramirez@copitl.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 fe025085
...@@ -121,9 +121,13 @@ void dsp_clk_exit(void) ...@@ -121,9 +121,13 @@ void dsp_clk_exit(void)
for (i = 0; i < DM_TIMER_CLOCKS; i++) for (i = 0; i < DM_TIMER_CLOCKS; i++)
omap_dm_timer_free(timer[i]); omap_dm_timer_free(timer[i]);
clk_unprepare(iva2_clk);
clk_put(iva2_clk); clk_put(iva2_clk);
clk_unprepare(ssi.sst_fck);
clk_put(ssi.sst_fck); clk_put(ssi.sst_fck);
clk_unprepare(ssi.ssr_fck);
clk_put(ssi.ssr_fck); clk_put(ssi.ssr_fck);
clk_unprepare(ssi.ick);
clk_put(ssi.ick); clk_put(ssi.ick);
} }
...@@ -145,14 +149,21 @@ void dsp_clk_init(void) ...@@ -145,14 +149,21 @@ void dsp_clk_init(void)
iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck"); iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck");
if (IS_ERR(iva2_clk)) if (IS_ERR(iva2_clk))
dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk); dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk);
else
clk_prepare(iva2_clk);
ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck"); ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck");
ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck"); ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck");
ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick"); ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick");
if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) {
dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n", dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n",
ssi.sst_fck, ssi.ssr_fck, ssi.ick); ssi.sst_fck, ssi.ssr_fck, ssi.ick);
} else {
clk_prepare(ssi.sst_fck);
clk_prepare(ssi.ssr_fck);
clk_prepare(ssi.ick);
}
} }
/** /**
......
...@@ -63,11 +63,15 @@ int dsp_wdt_init(void) ...@@ -63,11 +63,15 @@ int dsp_wdt_init(void)
dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
if (!IS_ERR(dsp_wdt.fclk)) { if (!IS_ERR(dsp_wdt.fclk)) {
clk_prepare(dsp_wdt.fclk);
dsp_wdt.iclk = clk_get(NULL, "wdt3_ick"); dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
if (IS_ERR(dsp_wdt.iclk)) { if (IS_ERR(dsp_wdt.iclk)) {
clk_put(dsp_wdt.fclk); clk_put(dsp_wdt.fclk);
dsp_wdt.fclk = NULL; dsp_wdt.fclk = NULL;
ret = -EFAULT; ret = -EFAULT;
} else {
clk_prepare(dsp_wdt.iclk);
} }
} else } else
ret = -EFAULT; ret = -EFAULT;
...@@ -95,10 +99,14 @@ void dsp_wdt_exit(void) ...@@ -95,10 +99,14 @@ void dsp_wdt_exit(void)
free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt); free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt);
tasklet_kill(&dsp_wdt.wdt3_tasklet); tasklet_kill(&dsp_wdt.wdt3_tasklet);
if (dsp_wdt.fclk) if (dsp_wdt.fclk) {
clk_unprepare(dsp_wdt.fclk);
clk_put(dsp_wdt.fclk); clk_put(dsp_wdt.fclk);
if (dsp_wdt.iclk) }
if (dsp_wdt.iclk) {
clk_unprepare(dsp_wdt.iclk);
clk_put(dsp_wdt.iclk); clk_put(dsp_wdt.iclk);
}
dsp_wdt.fclk = NULL; dsp_wdt.fclk = NULL;
dsp_wdt.iclk = NULL; dsp_wdt.iclk = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册