/* * intel_sst_suspend - PCI suspend function * * @pci: PCI device structure * @state: PM message * * This function is called by OS when a power event occurs */ int intel_sst_suspend(struct pci_dev *pci, pm_message_t state) { union config_status_reg csr; pr_debug("intel_sst_suspend called\n"); if (sst_drv_ctx->stream_cnt) { pr_err("active streams,not able to suspend\n"); return -EBUSY; } /*save fw context*/ sst_save_dsp_context(); /*Assert RESET on LPE Processor*/ csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR); csr.full = csr.full | 0x2; /* Move the SST state to Suspended */ mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_SUSPENDED; sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); mutex_unlock(&sst_drv_ctx->sst_lock); pci_set_drvdata(pci, sst_drv_ctx); pci_save_state(pci); pci_disable_device(pci); pci_set_power_state(pci, PCI_D3hot); return 0; }
/* * 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) { union config_status_reg csr; pr_debug("runtime_suspend called\n"); if (sst_drv_ctx->sst_state == SST_SUSPENDED) { pr_err("System already in Suspended state"); return 0; } /*save fw context*/ sst_save_dsp_context(); /*Assert RESET on LPE Processor*/ csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR); sst_drv_ctx->csr_value = csr.full; csr.full = csr.full | 0x2; /* Move the SST state to Suspended */ mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_SUSPENDED; sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); mutex_unlock(&sst_drv_ctx->sst_lock); if (sst_drv_ctx->pci_id == SST_CLV_PCI_ID) vibra_pwm_configure(false); flush_workqueue(sst_drv_ctx->post_msg_wq); flush_workqueue(sst_drv_ctx->process_msg_wq); flush_workqueue(sst_drv_ctx->process_reply_wq); return 0; }
/* 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) { union config_status_reg csr; pr_debug("intel_sst_runtime_suspend called\n"); if (sst_drv_ctx->stream_cnt) { pr_err("active streams,not able to suspend\n"); return -EBUSY; } /*save fw context*/ sst_save_dsp_context(); /*Assert RESET on LPE Processor*/ csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR); csr.full = csr.full | 0x2; /* Move the SST state to Suspended */ mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_SUSPENDED; /* Only needed by Medfield */ if (sst_drv_ctx->pci_id != SST_MRST_PCI_ID) sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); mutex_unlock(&sst_drv_ctx->sst_lock); return 0; }