diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-03-29 10:53:41 +0800 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-01 11:28:29 +0100 |
commit | 95cd98f9a6dcf112d2abf724ac07c56ec745180f (patch) | |
tree | 21f5cfda29c1e666e0391c4c0b94452d32e6fc27 /sound/soc/fsl | |
parent | 01651babb66fb7b51719ff3389a7bfc3ad25fe13 (diff) |
ASoC: fsl: enable ssi clock in probe function
For power saving, most IMX platform initilization code turns off
modules' clock, and expects driver turn on clock as needed.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 4f76b5df0ce4..4ed2afd47782 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -14,6 +14,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/interrupt.h> +#include <linux/clk.h> #include <linux/device.h> #include <linux/delay.h> #include <linux/slab.h> @@ -119,6 +120,7 @@ struct fsl_ssi_private { bool new_binding; bool ssi_on_imx; + struct clk *clk; struct platform_device *imx_pcm_pdev; struct imx_pcm_dma_params dma_params_tx; struct imx_pcm_dma_params dma_params_rx; @@ -722,6 +724,15 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { u32 dma_events[2]; ssi_private->ssi_on_imx = true; + + ssi_private->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(ssi_private->clk)) { + ret = PTR_ERR(ssi_private->clk); + dev_err(&pdev->dev, "could not get clock: %d\n", ret); + goto error_irq; + } + clk_prepare_enable(ssi_private->clk); + /* * We have burstsize be "fifo_depth - 2" to match the SSI * watermark setting in fsl_ssi_startup(). @@ -742,7 +753,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) "fsl,ssi-dma-events", dma_events, 2); if (ret) { dev_err(&pdev->dev, "could not get dma events\n"); - goto error_irq; + goto error_clk; } ssi_private->dma_params_tx.dma = dma_events[0]; ssi_private->dma_params_rx.dma = dma_events[1]; @@ -830,6 +841,12 @@ error_dev: dev_set_drvdata(&pdev->dev, NULL); device_remove_file(&pdev->dev, dev_attr); +error_clk: + if (ssi_private->ssi_on_imx) { + clk_disable_unprepare(ssi_private->clk); + clk_put(ssi_private->clk); + } + error_irq: free_irq(ssi_private->irq, ssi_private); @@ -851,8 +868,11 @@ static int fsl_ssi_remove(struct platform_device *pdev) if (!ssi_private->new_binding) platform_device_unregister(ssi_private->pdev); - if (ssi_private->ssi_on_imx) + if (ssi_private->ssi_on_imx) { platform_device_unregister(ssi_private->imx_pcm_pdev); + clk_disable_unprepare(ssi_private->clk); + clk_put(ssi_private->clk); + } snd_soc_unregister_dai(&pdev->dev); device_remove_file(&pdev->dev, &ssi_private->dev_attr); |