diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-03-28 22:53:41 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-01 06:28:29 -0400 |
commit | 95cd98f9a6dcf112d2abf724ac07c56ec745180f (patch) | |
tree | 21f5cfda29c1e666e0391c4c0b94452d32e6fc27 | |
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>
-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 @@ | |||
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/clk.h> | ||
17 | #include <linux/device.h> | 18 | #include <linux/device.h> |
18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
@@ -119,6 +120,7 @@ struct fsl_ssi_private { | |||
119 | 120 | ||
120 | bool new_binding; | 121 | bool new_binding; |
121 | bool ssi_on_imx; | 122 | bool ssi_on_imx; |
123 | struct clk *clk; | ||
122 | struct platform_device *imx_pcm_pdev; | 124 | struct platform_device *imx_pcm_pdev; |
123 | struct imx_pcm_dma_params dma_params_tx; | 125 | struct imx_pcm_dma_params dma_params_tx; |
124 | struct imx_pcm_dma_params dma_params_rx; | 126 | struct imx_pcm_dma_params dma_params_rx; |
@@ -722,6 +724,15 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
722 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { | 724 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { |
723 | u32 dma_events[2]; | 725 | u32 dma_events[2]; |
724 | ssi_private->ssi_on_imx = true; | 726 | ssi_private->ssi_on_imx = true; |
727 | |||
728 | ssi_private->clk = clk_get(&pdev->dev, NULL); | ||
729 | if (IS_ERR(ssi_private->clk)) { | ||
730 | ret = PTR_ERR(ssi_private->clk); | ||
731 | dev_err(&pdev->dev, "could not get clock: %d\n", ret); | ||
732 | goto error_irq; | ||
733 | } | ||
734 | clk_prepare_enable(ssi_private->clk); | ||
735 | |||
725 | /* | 736 | /* |
726 | * We have burstsize be "fifo_depth - 2" to match the SSI | 737 | * We have burstsize be "fifo_depth - 2" to match the SSI |
727 | * watermark setting in fsl_ssi_startup(). | 738 | * watermark setting in fsl_ssi_startup(). |
@@ -742,7 +753,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
742 | "fsl,ssi-dma-events", dma_events, 2); | 753 | "fsl,ssi-dma-events", dma_events, 2); |
743 | if (ret) { | 754 | if (ret) { |
744 | dev_err(&pdev->dev, "could not get dma events\n"); | 755 | dev_err(&pdev->dev, "could not get dma events\n"); |
745 | goto error_irq; | 756 | goto error_clk; |
746 | } | 757 | } |
747 | ssi_private->dma_params_tx.dma = dma_events[0]; | 758 | ssi_private->dma_params_tx.dma = dma_events[0]; |
748 | ssi_private->dma_params_rx.dma = dma_events[1]; | 759 | ssi_private->dma_params_rx.dma = dma_events[1]; |
@@ -830,6 +841,12 @@ error_dev: | |||
830 | dev_set_drvdata(&pdev->dev, NULL); | 841 | dev_set_drvdata(&pdev->dev, NULL); |
831 | device_remove_file(&pdev->dev, dev_attr); | 842 | device_remove_file(&pdev->dev, dev_attr); |
832 | 843 | ||
844 | error_clk: | ||
845 | if (ssi_private->ssi_on_imx) { | ||
846 | clk_disable_unprepare(ssi_private->clk); | ||
847 | clk_put(ssi_private->clk); | ||
848 | } | ||
849 | |||
833 | error_irq: | 850 | error_irq: |
834 | free_irq(ssi_private->irq, ssi_private); | 851 | free_irq(ssi_private->irq, ssi_private); |
835 | 852 | ||
@@ -851,8 +868,11 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
851 | 868 | ||
852 | if (!ssi_private->new_binding) | 869 | if (!ssi_private->new_binding) |
853 | platform_device_unregister(ssi_private->pdev); | 870 | platform_device_unregister(ssi_private->pdev); |
854 | if (ssi_private->ssi_on_imx) | 871 | if (ssi_private->ssi_on_imx) { |
855 | platform_device_unregister(ssi_private->imx_pcm_pdev); | 872 | platform_device_unregister(ssi_private->imx_pcm_pdev); |
873 | clk_disable_unprepare(ssi_private->clk); | ||
874 | clk_put(ssi_private->clk); | ||
875 | } | ||
856 | snd_soc_unregister_dai(&pdev->dev); | 876 | snd_soc_unregister_dai(&pdev->dev); |
857 | device_remove_file(&pdev->dev, &ssi_private->dev_attr); | 877 | device_remove_file(&pdev->dev, &ssi_private->dev_attr); |
858 | 878 | ||