aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/intel_sst/intel_sst.c
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2010-11-22 10:33:28 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-29 11:13:32 -0800
commit964c6975e8a4314c451d420f1cb54880ab535433 (patch)
tree4fb6508faa63a638d5fbd44f4f4674b426619039 /drivers/staging/intel_sst/intel_sst.c
parent951c44e0dbfaa580d5b4fb13427ab93ee252636a (diff)
downloadkernel_samsung_smdk4412-964c6975e8a4314c451d420f1cb54880ab535433.zip
kernel_samsung_smdk4412-964c6975e8a4314c451d420f1cb54880ab535433.tar.gz
kernel_samsung_smdk4412-964c6975e8a4314c451d420f1cb54880ab535433.tar.bz2
Staging: sst: Add runtime PM support
This adds runtime PM support for audio driver. This also fixes LPA audio mode for moorestown platform Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/intel_sst/intel_sst.c')
-rw-r--r--drivers/staging/intel_sst/intel_sst.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c
index 0ba6742..bd92549 100644
--- a/drivers/staging/intel_sst/intel_sst.c
+++ b/drivers/staging/intel_sst/intel_sst.c
@@ -36,6 +36,7 @@
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/miscdevice.h>
+#include <linux/pm_runtime.h>
#include <asm/mrst.h>
#include "intel_sst.h"
#include "intel_sst_ioctl.h"
@@ -320,6 +321,9 @@ static int __devinit intel_sst_probe(struct pci_dev *pci,
}
}
sst_drv_ctx->lpe_stalled = 0;
+ pm_runtime_set_active(&pci->dev);
+ pm_runtime_enable(&pci->dev);
+ pm_runtime_allow(&pci->dev);
pr_debug("...successfully done!!!\n");
return ret;
@@ -408,8 +412,10 @@ int intel_sst_suspend(struct pci_dev *pci, pm_message_t state)
pr_debug("intel_sst_suspend called\n");
- if (sst_drv_ctx->pb_streams != 0 || sst_drv_ctx->cp_streams != 0)
- return -EPERM;
+ if (sst_drv_ctx->stream_cnt) {
+ pr_err("active streams,not able to suspend\n");
+ return -EBUSY;
+ }
/*Assert RESET on LPE Processor*/
csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
csr.full = csr.full | 0x2;
@@ -439,7 +445,7 @@ int intel_sst_resume(struct pci_dev *pci)
pr_debug("intel_sst_resume called\n");
if (sst_drv_ctx->sst_state != SST_SUSPENDED) {
pr_err("SST is not in suspended state\n");
- return -EPERM;
+ return 0;
}
sst_drv_ctx = pci_get_drvdata(pci);
pci_set_power_state(pci, PCI_D0);
@@ -454,6 +460,34 @@ int intel_sst_resume(struct pci_dev *pci)
return 0;
}
+static int intel_sst_runtime_suspend(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ pr_debug("runtime_suspend called\n");
+ return intel_sst_suspend(pci_dev, PMSG_SUSPEND);
+}
+
+static int intel_sst_runtime_resume(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ pr_debug("runtime_resume called\n");
+ return intel_sst_resume(pci_dev);
+}
+
+static int intel_sst_runtime_idle(struct device *dev)
+{
+ pr_debug("runtime_idle called\n");
+ if (sst_drv_ctx->stream_cnt == 0 && sst_drv_ctx->am_cnt == 0)
+ pm_schedule_suspend(dev, SST_SUSPEND_DELAY);
+ return -EBUSY;
+}
+
+static const struct dev_pm_ops intel_sst_pm = {
+ .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_MRST_PCI_ID), 3},
@@ -470,6 +504,9 @@ static struct pci_driver driver = {
#ifdef CONFIG_PM
.suspend = intel_sst_suspend,
.resume = intel_sst_resume,
+ .driver = {
+ .pm = &intel_sst_pm,
+ },
#endif
};