aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorKuninori Morimoto <morimoto.kuninori@renesas.com>2009-11-30 06:24:48 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-11-30 07:56:44 -0500
commit785d1c45ce11820d5838eb6399caa0ac98c836cf (patch)
tree48a6ef11e402d484804dcb1a95b2bb4b6b3836c7 /sound/soc
parentd53bd80cb32d917e224b19925bb8f500941a3659 (diff)
ASoC: sh: fsi: Add runtime PM support
This patch add support runtime PM. Driver callbacks for Runtime PM are empty because the device registers are always re-initialized after pm_runtime_get_sync(). The Runtime PM functions replaces the clock framework module stop bit handling in this driver. Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com> Acked-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/sh/fsi.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index e1a3d1a2b4c8..9c49c11c43ce 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -17,7 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/clk.h> 20#include <linux/pm_runtime.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -105,7 +105,6 @@ struct fsi_priv {
105struct fsi_master { 105struct fsi_master {
106 void __iomem *base; 106 void __iomem *base;
107 int irq; 107 int irq;
108 struct clk *clk;
109 struct fsi_priv fsia; 108 struct fsi_priv fsia;
110 struct fsi_priv fsib; 109 struct fsi_priv fsib;
111 struct sh_fsi_platform_info *info; 110 struct sh_fsi_platform_info *info;
@@ -559,7 +558,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
559 int is_master; 558 int is_master;
560 int ret = 0; 559 int ret = 0;
561 560
562 clk_enable(master->clk); 561 pm_runtime_get_sync(dai->dev);
563 562
564 /* CKG1 */ 563 /* CKG1 */
565 data = is_play ? (1 << 0) : (1 << 4); 564 data = is_play ? (1 << 0) : (1 << 4);
@@ -674,7 +673,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
674 fsi_irq_disable(fsi, is_play); 673 fsi_irq_disable(fsi, is_play);
675 fsi_clk_ctrl(fsi, 0); 674 fsi_clk_ctrl(fsi, 0);
676 675
677 clk_disable(master->clk); 676 pm_runtime_put_sync(dai->dev);
678} 677}
679 678
680static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 679static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -872,7 +871,6 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
872static int fsi_probe(struct platform_device *pdev) 871static int fsi_probe(struct platform_device *pdev)
873{ 872{
874 struct resource *res; 873 struct resource *res;
875 char clk_name[8];
876 unsigned int irq; 874 unsigned int irq;
877 int ret; 875 int ret;
878 876
@@ -903,14 +901,8 @@ static int fsi_probe(struct platform_device *pdev)
903 master->fsia.base = master->base; 901 master->fsia.base = master->base;
904 master->fsib.base = master->base + 0x40; 902 master->fsib.base = master->base + 0x40;
905 903
906 /* FSI is based on SPU mstp */ 904 pm_runtime_enable(&pdev->dev);
907 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id); 905 pm_runtime_resume(&pdev->dev);
908 master->clk = clk_get(NULL, clk_name);
909 if (IS_ERR(master->clk)) {
910 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
911 ret = -EIO;
912 goto exit_iounmap;
913 }
914 906
915 fsi_soc_dai[0].dev = &pdev->dev; 907 fsi_soc_dai[0].dev = &pdev->dev;
916 fsi_soc_dai[1].dev = &pdev->dev; 908 fsi_soc_dai[1].dev = &pdev->dev;
@@ -935,6 +927,7 @@ exit_free_irq:
935 free_irq(irq, master); 927 free_irq(irq, master);
936exit_iounmap: 928exit_iounmap:
937 iounmap(master->base); 929 iounmap(master->base);
930 pm_runtime_disable(&pdev->dev);
938exit_kfree: 931exit_kfree:
939 kfree(master); 932 kfree(master);
940 master = NULL; 933 master = NULL;
@@ -947,7 +940,7 @@ static int fsi_remove(struct platform_device *pdev)
947 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 940 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
948 snd_soc_unregister_platform(&fsi_soc_platform); 941 snd_soc_unregister_platform(&fsi_soc_platform);
949 942
950 clk_put(master->clk); 943 pm_runtime_disable(&pdev->dev);
951 944
952 free_irq(master->irq, master); 945 free_irq(master->irq, master);
953 946
@@ -957,9 +950,27 @@ static int fsi_remove(struct platform_device *pdev)
957 return 0; 950 return 0;
958} 951}
959 952
953static int fsi_runtime_nop(struct device *dev)
954{
955 /* Runtime PM callback shared between ->runtime_suspend()
956 * and ->runtime_resume(). Simply returns success.
957 *
958 * This driver re-initializes all registers after
959 * pm_runtime_get_sync() anyway so there is no need
960 * to save and restore registers here.
961 */
962 return 0;
963}
964
965static struct dev_pm_ops fsi_pm_ops = {
966 .runtime_suspend = fsi_runtime_nop,
967 .runtime_resume = fsi_runtime_nop,
968};
969
960static struct platform_driver fsi_driver = { 970static struct platform_driver fsi_driver = {
961 .driver = { 971 .driver = {
962 .name = "sh_fsi", 972 .name = "sh_fsi",
973 .pm = &fsi_pm_ops,
963 }, 974 },
964 .probe = fsi_probe, 975 .probe = fsi_probe,
965 .remove = fsi_remove, 976 .remove = fsi_remove,