From dd0fe1d092738a2aca0c2b8389b0bce8f853964c Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 14 Feb 2020 15:59:10 -0800 Subject: [PATCH 1/2] mhi: core: unconditionally trigger resume to assert device wake In order to ensure that a DRV resume follows immediately after a client calls device wake assert or deassert, MHI core driver must unconditionally increment the PM runtime usage count and post a wake source before waiting for the state change. Change-Id: I50228742c090a5df6fcb06f89f53723179bcd76d Signed-off-by: Bhaumik Bhatt --- drivers/bus/mhi/core/mhi_pm.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 71c07fb84811..bcb9e52fc16a 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -1499,10 +1499,11 @@ int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) read_lock_bh(&mhi_cntrl->pm_lock); mhi_cntrl->wake_get(mhi_cntrl, true); - if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) - mhi_trigger_resume(mhi_cntrl); read_unlock_bh(&mhi_cntrl->pm_lock); + pm_wakeup_hard_event(&mhi_cntrl->mhi_dev->dev); + mhi_cntrl->runtime_get(mhi_cntrl, mhi_cntrl->priv_data); + mhi_force_reg_write(mhi_cntrl); ret = wait_event_timeout(mhi_cntrl->state_event, @@ -1517,9 +1518,11 @@ int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) read_lock_bh(&mhi_cntrl->pm_lock); mhi_cntrl->wake_put(mhi_cntrl, false); read_unlock_bh(&mhi_cntrl->pm_lock); + mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data); return -EIO; } + mhi_cntrl->runtime_put(mhi_cntrl, mhi_cntrl->priv_data); return 0; } @@ -1579,9 +1582,7 @@ void mhi_device_put(struct mhi_device *mhi_dev, int vote) if (vote & MHI_VOTE_DEVICE) { atomic_dec(&mhi_dev->dev_vote); read_lock_bh(&mhi_cntrl->pm_lock); - if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) - mhi_trigger_resume(mhi_cntrl); - + mhi_trigger_resume(mhi_cntrl); mhi_cntrl->wake_put(mhi_cntrl, false); read_unlock_bh(&mhi_cntrl->pm_lock); } From ff5352870f63cdcec9ce26e870082e99ae1a76e5 Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Thu, 13 Feb 2020 16:24:08 -0800 Subject: [PATCH 2/2] mhi: core: fix error handling in time synchronization function Error handling in time synchronization function is not appropriate as an error in disabling link level low power modes could cause a spin lock to be unlocked without being locked. Change-Id: I06177e587f4010b0558bf1331d3b80daf6948e53 Signed-off-by: Bhaumik Bhatt --- drivers/bus/mhi/core/mhi_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index a6fe4f261cb5..898187130a18 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -2453,13 +2453,13 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, /* not all devices support time feature */ if (!mhi_tsync) { ret = -EIO; - goto err_unlock; + goto error_unlock; } /* bring to M0 state */ ret = __mhi_device_get_sync(mhi_cntrl); if (ret) - goto err_unlock; + goto error_unlock; read_lock_bh(&mhi_cntrl->pm_lock); if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))) { @@ -2472,8 +2472,10 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, /* disable link level low power modes */ ret = mhi_cntrl->lpm_disable(mhi_cntrl, mhi_cntrl->priv_data); - if (ret) + if (ret) { + read_lock_bh(&mhi_cntrl->pm_lock); goto error_invalid_state; + } /* * time critical code to fetch device times, @@ -2495,7 +2497,7 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, error_invalid_state: mhi_cntrl->wake_put(mhi_cntrl, false); read_unlock_bh(&mhi_cntrl->pm_lock); -err_unlock: +error_unlock: mutex_unlock(&mhi_cntrl->tsync_mutex); return ret; }