diff options
-rw-r--r-- | arch/arm/plat-omap/devices.c | 7 | ||||
-rw-r--r-- | include/sound/omap-abe-dsp.h | 8 | ||||
-rw-r--r-- | sound/soc/omap/omap-abe-dsp.c | 55 |
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), |