|
@@ -316,9 +316,25 @@ static int __devinit intel_sst_probe(struct pci_dev *pci,
|
|
|
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
|
|
|
ret = misc_register(&lpe_dev);
|
|
|
if (ret) {
|
|
|
- pr_err("couldn't register misc driver\n");
|
|
|
+ pr_err("couldn't register LPE device\n");
|
|
|
goto do_free_misc;
|
|
|
}
|
|
|
+ } else if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID) {
|
|
|
+ u32 csr;
|
|
|
+
|
|
|
+ /*allocate mem for fw context save during suspend*/
|
|
|
+ sst_drv_ctx->fw_cntx = kzalloc(FW_CONTEXT_MEM, GFP_KERNEL);
|
|
|
+ if (!sst_drv_ctx->fw_cntx) {
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto do_free_misc;
|
|
|
+ }
|
|
|
+ /*setting zero as that is valid mem to restore*/
|
|
|
+ sst_drv_ctx->fw_cntx_size = 0;
|
|
|
+
|
|
|
+ /*set lpe start clock and ram size*/
|
|
|
+ csr = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
|
|
|
+ csr |= 0x30060; /*remove the clock ratio after fw fix*/
|
|
|
+ sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr);
|
|
|
}
|
|
|
sst_drv_ctx->lpe_stalled = 0;
|
|
|
pm_runtime_set_active(&pci->dev);
|
|
@@ -374,16 +390,17 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)
|
|
|
sst_drv_ctx->sst_state = SST_UN_INIT;
|
|
|
mutex_unlock(&sst_drv_ctx->sst_lock);
|
|
|
misc_deregister(&lpe_ctrl);
|
|
|
- if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
|
|
|
- misc_deregister(&lpe_dev);
|
|
|
free_irq(pci->irq, sst_drv_ctx);
|
|
|
iounmap(sst_drv_ctx->dram);
|
|
|
iounmap(sst_drv_ctx->iram);
|
|
|
iounmap(sst_drv_ctx->mailbox);
|
|
|
iounmap(sst_drv_ctx->shim);
|
|
|
sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
|
|
|
- if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
|
|
|
+ if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
|
|
|
+ misc_deregister(&lpe_dev);
|
|
|
kfree(sst_drv_ctx->mmap_mem);
|
|
|
+ } else
|
|
|
+ kfree(sst_drv_ctx->fw_cntx);
|
|
|
flush_scheduled_work();
|
|
|
destroy_workqueue(sst_drv_ctx->process_reply_wq);
|
|
|
destroy_workqueue(sst_drv_ctx->process_msg_wq);
|
|
@@ -398,6 +415,46 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)
|
|
|
pci_set_drvdata(pci, NULL);
|
|
|
}
|
|
|
|
|
|
+void sst_save_dsp_context(void)
|
|
|
+{
|
|
|
+ struct snd_sst_ctxt_params fw_context;
|
|
|
+ unsigned int pvt_id, i;
|
|
|
+ struct ipc_post *msg = NULL;
|
|
|
+
|
|
|
+ /*check cpu type*/
|
|
|
+ if (sst_drv_ctx->pci_id != SST_MFLD_PCI_ID)
|
|
|
+ return;
|
|
|
+ /*not supported for rest*/
|
|
|
+ if (sst_drv_ctx->sst_state != SST_FW_RUNNING) {
|
|
|
+ pr_debug("fw not running no context save ...\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*send msg to fw*/
|
|
|
+ if (sst_create_large_msg(&msg))
|
|
|
+ return;
|
|
|
+ pvt_id = sst_assign_pvt_id(sst_drv_ctx);
|
|
|
+ i = sst_get_block_stream(sst_drv_ctx);
|
|
|
+ sst_drv_ctx->alloc_block[i].sst_id = pvt_id;
|
|
|
+ sst_fill_header(&msg->header, IPC_IA_GET_FW_CTXT, 1, pvt_id);
|
|
|
+ msg->header.part.data = sizeof(fw_context) + sizeof(u32);
|
|
|
+ fw_context.address = virt_to_phys((void *)sst_drv_ctx->fw_cntx);
|
|
|
+ fw_context.size = FW_CONTEXT_MEM;
|
|
|
+ memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
|
|
|
+ memcpy(msg->mailbox_data + sizeof(u32),
|
|
|
+ &fw_context, sizeof(fw_context));
|
|
|
+ spin_lock(&sst_drv_ctx->list_spin_lock);
|
|
|
+ list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
|
|
|
+ spin_unlock(&sst_drv_ctx->list_spin_lock);
|
|
|
+ sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
|
|
|
+ /*wait for reply*/
|
|
|
+ if (sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]))
|
|
|
+ pr_debug("err fw context save timeout ...\n");
|
|
|
+ sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
|
|
|
+ pr_debug("fw context saved ...\n");
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
/* Power Management */
|
|
|
/*
|
|
|
* intel_sst_suspend - PCI suspend function
|
|
@@ -417,6 +474,8 @@ int intel_sst_suspend(struct pci_dev *pci, pm_message_t state)
|
|
|
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;
|