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>
This commit is contained in:
Vinod Koul 2014-10-31 12:38:20 +05:30 committed by Mark Brown
parent 1a6db0bd26
commit d62f2a08b9
1 changed files with 67 additions and 0 deletions

View File

@ -152,6 +152,23 @@ static irqreturn_t intel_sst_irq_thread_mrfld(int irq, void *context)
return IRQ_HANDLED;
}
static int sst_save_dsp_context_v2(struct intel_sst_drv *sst)
{
int ret = 0;
ret = sst_prepare_and_post_msg(sst, SST_TASK_ID_MEDIA, IPC_CMD,
IPC_PREP_D3, PIPE_RSVD, 0, NULL, NULL,
true, true, false, true);
if (ret < 0) {
dev_err(sst->dev, "not suspending FW!!, Err: %d\n", ret);
return -EIO;
}
return 0;
}
static struct intel_sst_ops mrfld_ops = {
.interrupt = intel_sst_interrupt_mrfld,
.irq_thread = intel_sst_irq_thread_mrfld,
@ -160,6 +177,7 @@ static struct intel_sst_ops mrfld_ops = {
.reset = intel_sst_reset_dsp_mrfld,
.post_message = sst_post_message_mrfld,
.process_reply = sst_process_reply_mrfld,
.save_dsp_context = sst_save_dsp_context_v2,
.alloc_stream = sst_alloc_stream_mrfld,
.post_download = sst_post_download_mrfld,
};
@ -418,6 +436,50 @@ static void intel_sst_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
static int intel_sst_runtime_suspend(struct device *dev)
{
int ret = 0;
struct intel_sst_drv *ctx = dev_get_drvdata(dev);
if (ctx->sst_state == SST_RESET) {
dev_dbg(dev, "LPE is already in RESET state, No action\n");
return 0;
}
/* save fw context */
if (ctx->ops->save_dsp_context(ctx))
return -EBUSY;
/* Move the SST state to Reset */
sst_set_fw_state_locked(ctx, SST_RESET);
synchronize_irq(ctx->irq_num);
flush_workqueue(ctx->post_msg_wq);
return ret;
}
static int intel_sst_runtime_resume(struct device *dev)
{
int ret = 0;
struct intel_sst_drv *ctx = dev_get_drvdata(dev);
mutex_lock(&ctx->sst_lock);
if (ctx->sst_state == SST_RESET) {
ret = sst_load_fw(ctx);
if (ret) {
dev_err(dev, "FW download fail %d\n", ret);
ctx->sst_state = SST_RESET;
}
}
mutex_unlock(&ctx->sst_lock);
return ret;
}
static const struct dev_pm_ops intel_sst_pm = {
.runtime_suspend = intel_sst_runtime_suspend,
.runtime_resume = intel_sst_runtime_resume,
};
/* PCI Routines */
static struct pci_device_id intel_sst_ids[] = {
{ PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
@ -429,6 +491,11 @@ static struct pci_driver sst_driver = {
.id_table = intel_sst_ids,
.probe = intel_sst_probe,
.remove = intel_sst_remove,
#ifdef CONFIG_PM
.driver = {
.pm = &intel_sst_pm,
},
#endif
};
module_pci_driver(sst_driver);