From: Vinod Koul <vinod.koul@intel.com>
To: alsa-devel@alsa-project.org
Cc: Vinod Koul <vinod.koul@intel.com>,
broonie@kernel.org, subhransu.s.prusty@intel.com,
lgirdwood@gmail.com, Lars-Peter Clausen <lars@metafoo.de>
Subject: [PATCH 5/7] ASoC: Intel: sst: add power management handling
Date: Wed, 9 Jul 2014 14:57:53 +0530 [thread overview]
Message-ID: <1404898076-1882-6-git-send-email-vinod.koul@intel.com> (raw)
In-Reply-To: <1404898076-1882-1-git-send-email-vinod.koul@intel.com>
This patch adds the runtime pm handlers and legacy pm handlers for this driver.
The runtime and legacy handlers are quite similar in nature as we follow same
patch for both
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
---
sound/soc/intel/sst/sst.c | 126 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 126 insertions(+), 0 deletions(-)
diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c
index 916b38c..cb9863c 100644
--- a/sound/soc/intel/sst/sst.c
+++ b/sound/soc/intel/sst/sst.c
@@ -141,6 +141,47 @@ 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)
+{
+ unsigned int pvt_id;
+ struct ipc_post *msg = NULL;
+ struct ipc_dsp_hdr dsp_hdr;
+ struct sst_block *block;
+
+ /*send msg to fw*/
+ pvt_id = sst_assign_pvt_id(sst);
+ if (sst_create_block_and_ipc_msg(&msg, true, sst, &block,
+ IPC_CMD, pvt_id)) {
+ pr_err("msg/block alloc failed. Not proceeding with context save\n");
+ return 0;
+ }
+
+ sst_fill_header_mrfld(&msg->mrfld_header, IPC_CMD,
+ SST_TASK_ID_MEDIA, 1, pvt_id);
+ msg->mrfld_header.p.header_low_payload = sizeof(dsp_hdr);
+ msg->mrfld_header.p.header_high.part.res_rqd = 1;
+ sst_fill_header_dsp(&dsp_hdr, IPC_PREP_D3, PIPE_RSVD, pvt_id);
+ memcpy(msg->mailbox_data, &dsp_hdr, sizeof(dsp_hdr));
+
+ sst_add_to_dispatch_list_and_post(sst, msg);
+ /*wait for reply*/
+ if (sst_wait_timeout(sst, block)) {
+ pr_err("sst: err fw context save timeout ...\n");
+ pr_err("not suspending FW!!!");
+ sst_free_block(sst, block);
+ return -EIO;
+ }
+ if (block->ret_code) {
+ pr_err("fw responded w/ error %d", block->ret_code);
+ sst_free_block(sst, block);
+ return -EIO;
+ }
+
+ sst_free_block(sst, block);
+ return 0;
+}
+
+
static struct intel_sst_ops mrfld_ops = {
.interrupt = intel_sst_interrupt_mrfld,
.irq_thread = intel_sst_irq_thread_mrfld,
@@ -150,6 +191,7 @@ static struct intel_sst_ops mrfld_ops = {
.post_message = sst_post_message_mrfld,
.sync_post_message = sst_sync_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,
};
@@ -423,6 +465,85 @@ static void intel_sst_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
+/*
+ * The runtime_suspend/resume is pretty much similar to the legacy
+ * suspend/resume with the noted exception below: The PCI core takes care of
+ * taking the system through D3hot and restoring it back to D0 and so there is
+ * no need to duplicate that here.
+ */
+static int intel_sst_runtime_suspend(struct device *dev)
+{
+ int ret = 0;
+ struct intel_sst_drv *ctx = dev_get_drvdata(dev);
+
+ pr_info("runtime_suspend called\n");
+ if (ctx->sst_state == SST_RESET) {
+ pr_debug("LPE is already in RESET state, No action");
+ 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);
+
+ flush_workqueue(ctx->post_msg_wq);
+ synchronize_irq(ctx->irq_num);
+
+ return ret;
+}
+
+static int intel_sst_runtime_resume(struct device *dev)
+{
+ int ret = 0;
+ struct intel_sst_drv *ctx = dev_get_drvdata(dev);
+
+ pr_info("runtime_resume called\n");
+
+ /* When fw_clear_cache is set, clear the cached firmware copy */
+ /* fw_clear_cache is set through debugfs support */
+ if (atomic_read(&ctx->fw_clear_cache) && ctx->fw_in_mem) {
+ pr_debug("Clearing the cached firmware\n");
+ kfree(ctx->fw_in_mem);
+ ctx->fw_in_mem = NULL;
+ atomic_set(&ctx->fw_clear_cache, 0);
+ }
+
+ sst_set_fw_state_locked(ctx, SST_RESET);
+
+ return ret;
+}
+
+static int intel_sst_suspend(struct device *dev)
+{
+
+ return intel_sst_runtime_suspend(dev);
+}
+
+static int intel_sst_runtime_idle(struct device *dev)
+{
+ struct intel_sst_drv *ctx = dev_get_drvdata(dev);
+
+ pr_info("runtime_idle called\n");
+ if (ctx->sst_state != SST_RESET) {
+ pm_schedule_suspend(dev, SST_SUSPEND_DELAY);
+ return -EBUSY;
+ } else {
+ return 0;
+ }
+ return -EBUSY;
+
+}
+
+static const struct dev_pm_ops intel_sst_pm = {
+ .suspend = intel_sst_suspend,
+ .resume = intel_sst_runtime_resume,
+ .runtime_suspend = intel_sst_runtime_suspend,
+ .runtime_resume = intel_sst_runtime_resume,
+ .runtime_idle = intel_sst_runtime_idle,
+};
+
/* PCI Routines */
static struct pci_device_id intel_sst_ids[] = {
{ PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
@@ -434,6 +555,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);
--
1.7.0.4
next prev parent reply other threads:[~2014-07-09 9:30 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-09 9:27 [PATCH 0/8] ASoC: Intel: sst - add the merrifield DSP driver Vinod Koul
2014-07-09 9:27 ` [PATCH 1/7] ASoC: Intel: add sst shim register start-end variables Vinod Koul
2014-07-14 18:45 ` Mark Brown
2014-07-09 9:27 ` [PATCH 2/7] ASoC: Intel: mfld: add dsp error codes Vinod Koul
2014-07-14 18:45 ` Mark Brown
2014-07-09 9:27 ` [PATCH 3/7] ASoC: Intel: mrlfd - add generic parameter interface Vinod Koul
2014-07-14 18:46 ` Mark Brown
2014-07-15 5:25 ` Vinod Koul
2014-07-15 12:38 ` Mark Brown
2014-07-09 9:27 ` [PATCH 4/7] ASoC: Intel: mrfld - add the dsp sst driver Vinod Koul
2014-07-18 11:35 ` Mark Brown
2014-07-18 14:13 ` Vinod Koul
2014-07-18 16:59 ` Mark Brown
2014-07-19 6:31 ` Vinod Koul
2014-07-09 9:27 ` Vinod Koul [this message]
2014-07-18 11:46 ` [PATCH 5/7] ASoC: Intel: sst: add power management handling Mark Brown
2014-07-18 14:23 ` Vinod Koul
2014-07-18 17:14 ` Mark Brown
2014-07-19 6:37 ` Vinod Koul
2014-07-09 9:27 ` [PATCH 6/7] ASoC: Intel: sst: load firmware using async callback Vinod Koul
2014-07-09 9:27 ` [PATCH 7/7] ASoC: Intel: sst - add compressed ops handling Vinod Koul
2014-07-18 11:48 ` Mark Brown
2014-07-18 14:23 ` Vinod Koul
2014-07-09 9:27 ` [PATCH 0/8] ASoC: Intel: sst - add the merrifield DSP driver Vinod Koul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1404898076-1882-6-git-send-email-vinod.koul@intel.com \
--to=vinod.koul@intel.com \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=lars@metafoo.de \
--cc=lgirdwood@gmail.com \
--cc=subhransu.s.prusty@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).