mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 23:24:22 -04:00
mhi: core: improve bandwidth switch events processing
We may unnecessarily wake up the device when there is no pending bandwidth switch request. Avoid that by only asserting device wake if one is pending. We can also have the underlying MHI bus go to suspend while a device requested bandwidth switch is yet to be processed. Prevent host suspends by capturing both bus and device votes and increment pending packets to reject suspends while the processing is ongoing. Change-Id: I4eddb6bf9eaa973be5c0b0ac516269e54599b9f2 Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
This commit is contained in:
parent
a6ae9f824c
commit
649971df7a
1 changed files with 25 additions and 32 deletions
|
|
@ -1437,29 +1437,12 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
|
|||
struct mhi_link_info link_info, *cur_info = &mhi_cntrl->mhi_link_info;
|
||||
int result, ret = 0;
|
||||
|
||||
if (unlikely(MHI_EVENT_ACCESS_INVALID(mhi_cntrl->pm_state))) {
|
||||
MHI_LOG("No EV access, PM_STATE:%s\n",
|
||||
to_mhi_pm_state_str(mhi_cntrl->pm_state));
|
||||
ret = -EIO;
|
||||
goto exit_no_lock;
|
||||
}
|
||||
|
||||
ret = __mhi_device_get_sync(mhi_cntrl);
|
||||
if (ret)
|
||||
goto exit_no_lock;
|
||||
|
||||
mutex_lock(&mhi_cntrl->pm_mutex);
|
||||
|
||||
spin_lock_bh(&mhi_event->lock);
|
||||
dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp);
|
||||
|
||||
if (ev_ring->rp == dev_rp) {
|
||||
spin_unlock_bh(&mhi_event->lock);
|
||||
read_lock_bh(&mhi_cntrl->pm_lock);
|
||||
mhi_cntrl->wake_put(mhi_cntrl, false);
|
||||
read_unlock_bh(&mhi_cntrl->pm_lock);
|
||||
MHI_VERB("no pending event found\n");
|
||||
goto exit_bw_process;
|
||||
goto exit_bw_scale_process;
|
||||
}
|
||||
|
||||
/* if rp points to base, we need to wrap it around */
|
||||
|
|
@ -1467,6 +1450,13 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
|
|||
dev_rp = ev_ring->base + ev_ring->len;
|
||||
dev_rp--;
|
||||
|
||||
/* fast forward to currently processed element and recycle er */
|
||||
ev_ring->rp = dev_rp;
|
||||
ev_ring->wp = dev_rp - 1;
|
||||
if (ev_ring->wp < ev_ring->base)
|
||||
ev_ring->wp = ev_ring->base + ev_ring->len - ev_ring->el_size;
|
||||
mhi_recycle_fwd_ev_ring_element(mhi_cntrl, ev_ring);
|
||||
|
||||
MHI_ASSERT(MHI_TRE_GET_EV_TYPE(dev_rp) != MHI_PKT_TYPE_BW_REQ_EVENT,
|
||||
"!BW SCALE REQ event");
|
||||
|
||||
|
|
@ -1479,19 +1469,22 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
|
|||
link_info.target_link_speed,
|
||||
link_info.target_link_width);
|
||||
|
||||
/* fast forward to currently processed element and recycle er */
|
||||
ev_ring->rp = dev_rp;
|
||||
ev_ring->wp = dev_rp - 1;
|
||||
if (ev_ring->wp < ev_ring->base)
|
||||
ev_ring->wp = ev_ring->base + ev_ring->len - ev_ring->el_size;
|
||||
mhi_recycle_fwd_ev_ring_element(mhi_cntrl, ev_ring);
|
||||
|
||||
read_lock_bh(&mhi_cntrl->pm_lock);
|
||||
if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl)))
|
||||
mhi_ring_er_db(mhi_event);
|
||||
read_unlock_bh(&mhi_cntrl->pm_lock);
|
||||
spin_unlock_bh(&mhi_event->lock);
|
||||
|
||||
atomic_inc(&mhi_cntrl->pending_pkts);
|
||||
ret = mhi_device_get_sync(mhi_cntrl->mhi_dev,
|
||||
MHI_VOTE_DEVICE | MHI_VOTE_BUS);
|
||||
if (ret) {
|
||||
atomic_dec(&mhi_cntrl->pending_pkts);
|
||||
goto exit_bw_scale_process;
|
||||
}
|
||||
|
||||
mutex_lock(&mhi_cntrl->pm_mutex);
|
||||
|
||||
ret = mhi_cntrl->bw_scale(mhi_cntrl, &link_info);
|
||||
if (!ret)
|
||||
*cur_info = link_info;
|
||||
|
|
@ -1501,17 +1494,17 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
|
|||
read_lock_bh(&mhi_cntrl->pm_lock);
|
||||
if (likely(MHI_DB_ACCESS_VALID(mhi_cntrl)))
|
||||
mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bw_scale_db, 0,
|
||||
MHI_BW_SCALE_RESULT(result,
|
||||
link_info.sequence_num));
|
||||
|
||||
mhi_cntrl->wake_put(mhi_cntrl, false);
|
||||
MHI_BW_SCALE_RESULT(result,
|
||||
link_info.sequence_num));
|
||||
read_unlock_bh(&mhi_cntrl->pm_lock);
|
||||
|
||||
exit_bw_process:
|
||||
mhi_device_put(mhi_cntrl->mhi_dev, MHI_VOTE_DEVICE | MHI_VOTE_BUS);
|
||||
atomic_dec(&mhi_cntrl->pending_pkts);
|
||||
|
||||
mutex_unlock(&mhi_cntrl->pm_mutex);
|
||||
|
||||
exit_no_lock:
|
||||
MHI_VERB("exit er_index:%u\n", mhi_event->er_index);
|
||||
exit_bw_scale_process:
|
||||
MHI_VERB("exit er_index:%u ret:%d\n", mhi_event->er_index, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue