summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-omap/devices.c7
-rw-r--r--include/sound/omap-abe-dsp.h8
-rw-r--r--sound/soc/omap/omap-abe-dsp.c55
3 files changed, 60 insertions, 10 deletions
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index d12ec1b7612a..e84b733f8762 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -35,6 +35,7 @@
#include <plat/omap44xx.h>
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
#include <sound/omap-abe-dsp.h>
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
@@ -391,15 +392,15 @@ static void omap_init_aess(void)
return;
}
- pdata->device_enable = omap_device_enable;
- pdata->device_idle = omap_device_idle;
- pdata->device_shutdown = omap_device_shutdown;
+ pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
od = omap_device_build("omap-aess-audio", -1, oh, pdata,
sizeof(struct omap4_abe_dsp_pdata),
omap_aess_latency,
ARRAY_SIZE(omap_aess_latency), 0);
+ kfree(pdata);
+
if (IS_ERR(od))
printk(KERN_ERR "Could not build omap_device for omap-aess-audio\n");
}
diff --git a/include/sound/omap-abe-dsp.h b/include/sound/omap-abe-dsp.h
index 16f17e5f49fb..60c405d48c61 100644
--- a/include/sound/omap-abe-dsp.h
+++ b/include/sound/omap-abe-dsp.h
@@ -11,13 +11,9 @@
#ifndef _OMAP4_ABE_DSP_H
#define _OMAP4_ABE_DSP_H
-#include <linux/platform_device.h>
-
struct omap4_abe_dsp_pdata {
- /* aess */
- int (*device_enable) (struct platform_device *pdev);
- int (*device_shutdown) (struct platform_device *pdev);
- int (*device_idle) (struct platform_device *pdev);
+ /* Return context loss count due to PM states changing */
+ int (*get_context_loss_count)(struct device *dev);
};
#endif
diff --git a/sound/soc/omap/omap-abe-dsp.c b/sound/soc/omap/omap-abe-dsp.c
index bc4d95a36bd3..1dda164fe44f 100644
--- a/sound/soc/omap/omap-abe-dsp.c
+++ b/sound/soc/omap/omap-abe-dsp.c
@@ -167,6 +167,8 @@ struct abe_data {
u16 router[16];
+ int loss_count;
+
struct snd_pcm_substream *psubs;
#ifdef CONFIG_DEBUG_FS
@@ -2221,9 +2223,59 @@ static struct snd_soc_platform_driver omap_aess_platform = {
.stream_event = aess_stream_event,
};
+#if CONFIG_PM
+static int aess_suspend(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct omap4_abe_dsp_pdata *pdata;
+ struct abe_data *abe = dev_get_drvdata(dev);
+
+ pdev = to_platform_device(dev);
+ pdata = pdev->dev.platform_data;
+
+ if (pdata->get_context_loss_count)
+ abe->loss_count = pdata->get_context_loss_count(dev);
+
+ return 0;
+}
+
+static int aess_resume(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct omap4_abe_dsp_pdata *pdata;
+ struct abe_data *abe = dev_get_drvdata(dev);
+ int loss_count = 0;
+
+ pdev = to_platform_device(dev);
+ pdata = pdev->dev.platform_data;
+
+ if (pdata->get_context_loss_count)
+ loss_count = pdata->get_context_loss_count(dev);
+
+ pm_runtime_get_sync(&pdev->dev);
+
+ if (loss_count != abe->loss_count)
+ abe_reload_fw();
+
+ pm_runtime_put_sync(&pdev->dev);
+
+ return 0;
+}
+
+#else
+#define aess_runtime_suspend NULL
+#define aess_runtime_resume NULL
+#endif
+
+static const struct dev_pm_ops aess_pm_ops = {
+ .suspend = aess_suspend,
+ .resume = aess_resume,
+};
+
static int __devinit abe_engine_probe(struct platform_device *pdev)
{
struct resource *res;
+ struct omap4_abe_dsp_pdata *pdata = pdev->dev.platform_data;
int ret = -EINVAL, i;
abe = kzalloc(sizeof(struct abe_data), GFP_KERNEL);
@@ -2255,7 +2307,7 @@ static int __devinit abe_engine_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
- abe->abe_pdata = pdev->dev.platform_data;
+ abe->abe_pdata = pdata;
abe->pdev = pdev;
mutex_init(&abe->mutex);
@@ -2298,6 +2350,7 @@ static struct platform_driver omap_aess_driver = {
.driver = {
.name = "omap-aess-audio",
.owner = THIS_MODULE,
+ .pm = &aess_pm_ops,
},
.probe = abe_engine_probe,
.remove = __devexit_p(abe_engine_remove),