soc: swr-mstr: Avoid race condition during device up

During device up call from platform driver, if master
is already up pm get_sync is currently skipped. However
pm suspend can get called after this check. Hence do a pm
get_sync even if master is already up to avoid race
condition.

Change-Id: I1779db3d65f58bda220d1ec07706e91745814c1f
Signed-off-by: Ramprasad Katkam <katkam@codeaurora.org>
This commit is contained in:
Ramprasad Katkam 2018-10-16 19:31:51 +05:30
commit 86c45e0761

View file

@ -1191,6 +1191,7 @@ static int swrm_disconnect_port(struct swr_master *master,
if (!port_req) {
dev_err(&master->dev, "%s:port not enabled : port %d\n",
__func__, portinfo->port_id[i]);
mutex_unlock(&swrm->mlock);
return -EINVAL;
}
port_req->req_ch &= ~portinfo->ch_en[i];
@ -2108,29 +2109,20 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
case SWR_DEVICE_UP:
dev_dbg(swrm->dev, "%s: swr master up called\n", __func__);
mutex_lock(&swrm->mlock);
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
mutex_lock(&swrm->reslock);
if (swrm->state == SWR_MSTR_UP) {
dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n",
__func__, swrm->state);
list_for_each_entry(swr_dev, &mstr->devices, dev_list)
swr_reset_device(swr_dev);
} else {
pm_runtime_mark_last_busy(&pdev->dev);
mutex_unlock(&swrm->reslock);
pm_runtime_get_sync(&pdev->dev);
mutex_lock(&swrm->reslock);
list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
ret = swr_reset_device(swr_dev);
if (ret) {
dev_err(swrm->dev,
"%s: failed to reset swr device %d\n",
__func__, swr_dev->dev_num);
swrm_clk_request(swrm, false);
}
list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
ret = swr_reset_device(swr_dev);
if (ret) {
dev_err(swrm->dev,
"%s: failed to reset swr device %d\n",
__func__, swr_dev->dev_num);
swrm_clk_request(swrm, false);
}
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
}
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
mutex_unlock(&swrm->reslock);
mutex_unlock(&swrm->mlock);
break;