slim_ngd: Serialize shutdown sequence during SSR down

During SSR down, work is queued for shutdown
sequence. Sometimes work is getting scheduled
on one CPU while SSR up sequence is running
on other CPU. This is leading to unexpecpted
scenarios and ending with crash.
To overcome this, serialize shutdown sequence
by doing function call instead of workqueue.
And remove ctrl_up signal reset in the shutdown
sequence as it is affecting the transactions
initiated by client.

Change-Id: If73999ad19441e2090c4ad181dbc90e62ad3d9d4
Signed-off-by: Dilip Kota <dkota@codeaurora.org>
This commit is contained in:
Dilip Kota 2015-07-09 16:52:57 +05:30 committed by Gerrit - the friendly Code Review server
parent fb84b72cd7
commit bd4ffadb36
1 changed files with 3 additions and 9 deletions

View File

@ -84,6 +84,7 @@ enum ngd_status {
static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf);
static int ngd_slim_runtime_resume(struct device *device);
static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart);
static void ngd_adsp_down(struct msm_slim_ctrl *dev);
static irqreturn_t ngd_slim_interrupt(int irq, void *d)
{
@ -188,15 +189,13 @@ static int dsp_ssr_notify_cb(struct notifier_block *n, unsigned long code,
/* make sure autosuspend is not called until ADSP comes up*/
pm_runtime_get_noresume(dev->dev);
dev->state = MSM_CTRL_DOWN;
/* Reset ctrl_up completion */
init_completion(&dev->ctrl_up);
/* disconnect BAM pipes */
if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
dev->use_rx_msgqs = MSM_MSGQ_DOWN;
if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
dev->use_tx_msgqs = MSM_MSGQ_DOWN;
msm_slim_sps_exit(dev, false);
schedule_work(&dev->qmi.ssr_down);
ngd_adsp_down(dev);
mutex_unlock(&dev->tx_lock);
break;
default:
@ -1391,12 +1390,8 @@ static int ngd_notify_slaves(void *data)
return 0;
}
static void ngd_adsp_down(struct work_struct *work)
static void ngd_adsp_down(struct msm_slim_ctrl *dev)
{
struct msm_slim_qmi *qmi =
container_of(work, struct msm_slim_qmi, ssr_down);
struct msm_slim_ctrl *dev =
container_of(qmi, struct msm_slim_ctrl, qmi);
struct slim_controller *ctrl = &dev->ctrl;
struct slim_device *sbdev;
@ -1638,7 +1633,6 @@ static int ngd_slim_probe(struct platform_device *pdev)
dev->ext_mdm.ssr);
}
INIT_WORK(&dev->qmi.ssr_down, ngd_adsp_down);
INIT_WORK(&dev->qmi.ssr_up, ngd_adsp_up);
dev->qmi.nb.notifier_call = ngd_qmi_available;
pm_runtime_get_noresume(dev->dev);