Commit 785d1c45 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

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: default avatarKuninori Morimoto <morimoto.kuninori@renesas.com>
Acked-by: default avatarPaul Mundt <lethal@linux-sh.org>
Acked-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent d53bd80c
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/clk.h> #include <linux/pm_runtime.h>
#include <linux/io.h> #include <linux/io.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -105,7 +105,6 @@ struct fsi_priv { ...@@ -105,7 +105,6 @@ struct fsi_priv {
struct fsi_master { struct fsi_master {
void __iomem *base; void __iomem *base;
int irq; int irq;
struct clk *clk;
struct fsi_priv fsia; struct fsi_priv fsia;
struct fsi_priv fsib; struct fsi_priv fsib;
struct sh_fsi_platform_info *info; struct sh_fsi_platform_info *info;
...@@ -559,7 +558,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, ...@@ -559,7 +558,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
int is_master; int is_master;
int ret = 0; int ret = 0;
clk_enable(master->clk); pm_runtime_get_sync(dai->dev);
/* CKG1 */ /* CKG1 */
data = is_play ? (1 << 0) : (1 << 4); data = is_play ? (1 << 0) : (1 << 4);
...@@ -674,7 +673,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, ...@@ -674,7 +673,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
fsi_irq_disable(fsi, is_play); fsi_irq_disable(fsi, is_play);
fsi_clk_ctrl(fsi, 0); fsi_clk_ctrl(fsi, 0);
clk_disable(master->clk); pm_runtime_put_sync(dai->dev);
} }
static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
...@@ -872,7 +871,6 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform); ...@@ -872,7 +871,6 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
static int fsi_probe(struct platform_device *pdev) static int fsi_probe(struct platform_device *pdev)
{ {
struct resource *res; struct resource *res;
char clk_name[8];
unsigned int irq; unsigned int irq;
int ret; int ret;
...@@ -903,14 +901,8 @@ static int fsi_probe(struct platform_device *pdev) ...@@ -903,14 +901,8 @@ static int fsi_probe(struct platform_device *pdev)
master->fsia.base = master->base; master->fsia.base = master->base;
master->fsib.base = master->base + 0x40; master->fsib.base = master->base + 0x40;
/* FSI is based on SPU mstp */ pm_runtime_enable(&pdev->dev);
snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id); pm_runtime_resume(&pdev->dev);
master->clk = clk_get(NULL, clk_name);
if (IS_ERR(master->clk)) {
dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
ret = -EIO;
goto exit_iounmap;
}
fsi_soc_dai[0].dev = &pdev->dev; fsi_soc_dai[0].dev = &pdev->dev;
fsi_soc_dai[1].dev = &pdev->dev; fsi_soc_dai[1].dev = &pdev->dev;
...@@ -935,6 +927,7 @@ exit_free_irq: ...@@ -935,6 +927,7 @@ exit_free_irq:
free_irq(irq, master); free_irq(irq, master);
exit_iounmap: exit_iounmap:
iounmap(master->base); iounmap(master->base);
pm_runtime_disable(&pdev->dev);
exit_kfree: exit_kfree:
kfree(master); kfree(master);
master = NULL; master = NULL;
...@@ -947,7 +940,7 @@ static int fsi_remove(struct platform_device *pdev) ...@@ -947,7 +940,7 @@ static int fsi_remove(struct platform_device *pdev)
snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
snd_soc_unregister_platform(&fsi_soc_platform); snd_soc_unregister_platform(&fsi_soc_platform);
clk_put(master->clk); pm_runtime_disable(&pdev->dev);
free_irq(master->irq, master); free_irq(master->irq, master);
...@@ -957,9 +950,27 @@ static int fsi_remove(struct platform_device *pdev) ...@@ -957,9 +950,27 @@ static int fsi_remove(struct platform_device *pdev)
return 0; return 0;
} }
static int fsi_runtime_nop(struct device *dev)
{
/* Runtime PM callback shared between ->runtime_suspend()
* and ->runtime_resume(). Simply returns success.
*
* This driver re-initializes all registers after
* pm_runtime_get_sync() anyway so there is no need
* to save and restore registers here.
*/
return 0;
}
static struct dev_pm_ops fsi_pm_ops = {
.runtime_suspend = fsi_runtime_nop,
.runtime_resume = fsi_runtime_nop,
};
static struct platform_driver fsi_driver = { static struct platform_driver fsi_driver = {
.driver = { .driver = {
.name = "sh_fsi", .name = "sh_fsi",
.pm = &fsi_pm_ops,
}, },
.probe = fsi_probe, .probe = fsi_probe,
.remove = fsi_remove, .remove = fsi_remove,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment