From: Omair Mohammed Abdullah Date: Wed, 12 Oct 2011 10:52:34 +0000 (+0530) Subject: Audio: sst: Prevents concurrent access to firmware download code X-Git-Tag: 2.1b_release~1558 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=be54eb96c09e3ca8a01af476bafe305c1a20fa1e;p=kernel%2Fkernel-mfld-blackbay.git Audio: sst: Prevents concurrent access to firmware download code BZ: 20940 OldBZ:9443 The code to download firmware can be accessed by more than one thread at a time leading to panic. Proper locking along with a new sst state (firmware starting to download) prevents this. (Ported to gb-stable) Change-Id: Ic56e3bfd68cf89c2b8937a572a70f01b80e3b27e Old-Change-Id: I16ef33e6ed26407ffe2e7c7693976ce1ec8e09cb Signed-off-by: Omair Mohammed Abdullah Reviewed-on: http://android.intel.com:8080/32721 Reviewed-by: M, Arulselvan Tested-by: M, Arulselvan Reviewed-by: buildbot Tested-by: buildbot --- diff --git a/sound/pci/sst/intel_sst.c b/sound/pci/sst/intel_sst.c index 1a79083..1b6712d 100644 --- a/sound/pci/sst/intel_sst.c +++ b/sound/pci/sst/intel_sst.c @@ -307,9 +307,7 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, goto do_unmap_iram; pr_debug("DRAM Ptr %p\n", sst_drv_ctx->dram); - mutex_lock(&sst_drv_ctx->sst_lock); - sst_drv_ctx->sst_state = SST_UN_INIT; - mutex_unlock(&sst_drv_ctx->sst_lock); + sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT); /* Register the ISR */ ret = request_irq(pci->irq, intel_sst_interrupt, IRQF_SHARED, SST_DRV_NAME, sst_drv_ctx); @@ -414,9 +412,7 @@ static void __devexit intel_sst_remove(struct pci_dev *pci) pm_runtime_get_noresume(&pci->dev); pm_runtime_forbid(&pci->dev); pci_dev_put(sst_drv_ctx->pci); - mutex_lock(&sst_drv_ctx->sst_lock); - sst_drv_ctx->sst_state = SST_UN_INIT; - mutex_unlock(&sst_drv_ctx->sst_lock); + sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT); misc_deregister(&lpe_ctrl); free_irq(pci->irq, sst_drv_ctx); iounmap(sst_drv_ctx->dram); @@ -582,9 +578,7 @@ static int intel_sst_runtime_resume(struct device *dev) sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr); intel_sst_set_pll(true, SST_PLL_AUDIO); - mutex_lock(&sst_drv_ctx->sst_lock); - sst_drv_ctx->sst_state = SST_UN_INIT; - mutex_unlock(&sst_drv_ctx->sst_lock); + sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT); return 0; } diff --git a/sound/pci/sst/intel_sst_app_interface.c b/sound/pci/sst/intel_sst_app_interface.c index 240258e..2fe916b 100644 --- a/sound/pci/sst/intel_sst_app_interface.c +++ b/sound/pci/sst/intel_sst_app_interface.c @@ -61,18 +61,25 @@ static int intel_sst_check_device(void) { int retval = 0; + + mutex_lock(&sst_drv_ctx->sst_lock); if (sst_drv_ctx->sst_state == SST_UN_INIT) { sst_drv_ctx->sst_state = SST_START_INIT; + mutex_unlock(&sst_drv_ctx->sst_lock); /* FW is not downloaded */ retval = sst_download_fw(); - if (retval) + if (retval) { + sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT); return -ENODEV; + } if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) { retval = sst_drv_ctx->rx_time_slot_status; if (retval != RX_TIMESLOT_UNINIT && sst_drv_ctx->pmic_vendor != SND_NC) sst_enable_rx_timeslot(retval); } + } else { + mutex_unlock(&sst_drv_ctx->sst_lock); } return 0; } diff --git a/sound/pci/sst/intel_sst_drv_interface.c b/sound/pci/sst/intel_sst_drv_interface.c index 46f3d93..7ffdfe7 100644 --- a/sound/pci/sst/intel_sst_drv_interface.c +++ b/sound/pci/sst/intel_sst_drv_interface.c @@ -89,9 +89,14 @@ int sst_download_fw(void) { int retval; + char name[20]; + if (sst_drv_ctx->sst_state != SST_START_INIT) return -EAGAIN; + snprintf(name, sizeof(name), "%s%04x%s", "fw_sst_", + sst_drv_ctx->pci_id, ".bin"); + retval = sst_request_fw(); if (retval) return retval; @@ -323,8 +328,8 @@ void sst_prepare_fw(void) pr_debug("DSP Downloading FW now...\n"); retval = sst_download_fw(); if (retval) { - pr_err("FW download fail %x\n", retval); - pr_debug("doing rtpm_put\n"); + pr_err("sst: FW download fail %x\n", retval); + pr_debug("sst: doing rtpm_put\n"); sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT); pm_runtime_put(&sst_drv_ctx->pci->dev); } @@ -406,8 +411,8 @@ static int sst_open_pcm_stream(struct snd_sst_params *str_param) pr_debug("DSP Downloading FW now...\n"); retval = sst_download_fw(); if (retval) { - pr_err("FW download fail %x, abort\n", retval); - pr_debug("open_pcm, doing rtpm_put\n"); + pr_err("sst: FW download fail %x, abort\n", retval); + pr_debug("sst: open_pcm, doing rtpm_put\n"); sst_set_fw_state_locked(sst_drv_ctx, SST_UN_INIT); pm_runtime_put(&sst_drv_ctx->pci->dev); return retval; diff --git a/sound/pci/sst/intel_sst_ipc.c b/sound/pci/sst/intel_sst_ipc.c index d5c894b..65aa0d5 100644 --- a/sound/pci/sst/intel_sst_ipc.c +++ b/sound/pci/sst/intel_sst_ipc.c @@ -169,8 +169,8 @@ static int process_fw_init(struct sst_ipc_msg_wq *msg) pr_debug("*** FW Init msg came***\n"); if (init->result) { sst_set_fw_state_locked(sst_drv_ctx, SST_ERROR); - pr_debug("FW Init failed, Error %x\n", init->result); - pr_err("FW Init failed, Error %x\n", init->result); + pr_debug("sst: FW Init failed, Error %x\n", init->result); + pr_err("sst: FW Init failed, Error %x\n", init->result); retval = -init->result; return retval; }