aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2014-10-31 03:08:20 -0400
committerMark Brown <broonie@kernel.org>2014-10-31 08:46:45 -0400
commitd62f2a08b9d657344b2e271e8274f9d8f746e543 (patch)
treed6e6a73b8f824be8afcd27ebb23edece55e94b1c
parent1a6db0bd26a72027d6a5ea006d64d4021fd0326e (diff)
ASoC: Intel: sst: add runtime power management handling
This patch adds the runtime pm handlers, the driver already has code for get/put for runtime pm and only these handlers being missing. Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/intel/sst/sst.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c
index fa3421706e4e..7b8a110b213d 100644
--- a/sound/soc/intel/sst/sst.c
+++ b/sound/soc/intel/sst/sst.c
@@ -152,6 +152,23 @@ static irqreturn_t intel_sst_irq_thread_mrfld(int irq, void *context)
152 return IRQ_HANDLED; 152 return IRQ_HANDLED;
153} 153}
154 154
155static int sst_save_dsp_context_v2(struct intel_sst_drv *sst)
156{
157 int ret = 0;
158
159 ret = sst_prepare_and_post_msg(sst, SST_TASK_ID_MEDIA, IPC_CMD,
160 IPC_PREP_D3, PIPE_RSVD, 0, NULL, NULL,
161 true, true, false, true);
162
163 if (ret < 0) {
164 dev_err(sst->dev, "not suspending FW!!, Err: %d\n", ret);
165 return -EIO;
166 }
167
168 return 0;
169}
170
171
155static struct intel_sst_ops mrfld_ops = { 172static struct intel_sst_ops mrfld_ops = {
156 .interrupt = intel_sst_interrupt_mrfld, 173 .interrupt = intel_sst_interrupt_mrfld,
157 .irq_thread = intel_sst_irq_thread_mrfld, 174 .irq_thread = intel_sst_irq_thread_mrfld,
@@ -160,6 +177,7 @@ static struct intel_sst_ops mrfld_ops = {
160 .reset = intel_sst_reset_dsp_mrfld, 177 .reset = intel_sst_reset_dsp_mrfld,
161 .post_message = sst_post_message_mrfld, 178 .post_message = sst_post_message_mrfld,
162 .process_reply = sst_process_reply_mrfld, 179 .process_reply = sst_process_reply_mrfld,
180 .save_dsp_context = sst_save_dsp_context_v2,
163 .alloc_stream = sst_alloc_stream_mrfld, 181 .alloc_stream = sst_alloc_stream_mrfld,
164 .post_download = sst_post_download_mrfld, 182 .post_download = sst_post_download_mrfld,
165}; 183};
@@ -418,6 +436,50 @@ static void intel_sst_remove(struct pci_dev *pci)
418 pci_set_drvdata(pci, NULL); 436 pci_set_drvdata(pci, NULL);
419} 437}
420 438
439static int intel_sst_runtime_suspend(struct device *dev)
440{
441 int ret = 0;
442 struct intel_sst_drv *ctx = dev_get_drvdata(dev);
443
444 if (ctx->sst_state == SST_RESET) {
445 dev_dbg(dev, "LPE is already in RESET state, No action\n");
446 return 0;
447 }
448 /* save fw context */
449 if (ctx->ops->save_dsp_context(ctx))
450 return -EBUSY;
451
452 /* Move the SST state to Reset */
453 sst_set_fw_state_locked(ctx, SST_RESET);
454
455 synchronize_irq(ctx->irq_num);
456 flush_workqueue(ctx->post_msg_wq);
457
458 return ret;
459}
460
461static int intel_sst_runtime_resume(struct device *dev)
462{
463 int ret = 0;
464 struct intel_sst_drv *ctx = dev_get_drvdata(dev);
465
466 mutex_lock(&ctx->sst_lock);
467 if (ctx->sst_state == SST_RESET) {
468 ret = sst_load_fw(ctx);
469 if (ret) {
470 dev_err(dev, "FW download fail %d\n", ret);
471 ctx->sst_state = SST_RESET;
472 }
473 }
474 mutex_unlock(&ctx->sst_lock);
475 return ret;
476}
477
478static const struct dev_pm_ops intel_sst_pm = {
479 .runtime_suspend = intel_sst_runtime_suspend,
480 .runtime_resume = intel_sst_runtime_resume,
481};
482
421/* PCI Routines */ 483/* PCI Routines */
422static struct pci_device_id intel_sst_ids[] = { 484static struct pci_device_id intel_sst_ids[] = {
423 { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0}, 485 { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
@@ -429,6 +491,11 @@ static struct pci_driver sst_driver = {
429 .id_table = intel_sst_ids, 491 .id_table = intel_sst_ids,
430 .probe = intel_sst_probe, 492 .probe = intel_sst_probe,
431 .remove = intel_sst_remove, 493 .remove = intel_sst_remove,
494#ifdef CONFIG_PM
495 .driver = {
496 .pm = &intel_sst_pm,
497 },
498#endif
432}; 499};
433 500
434module_pci_driver(sst_driver); 501module_pci_driver(sst_driver);