mhi: core: fix fast forward recycling of event rings

Some low priority event rings operate on a fast forwarding
mechanism where only the latest event is processed and the rest
are skipped. The recycle API only handles updating the
context write pointer in sequence which causes an out of bounds
doorbell issued to the device due to mismatched values. Add
another API to support handling updates for context write
pointer separately with the fast forwarding use case.

Change-Id: If628b49e063d14920fe734ebd113c9c4c733204b
Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
This commit is contained in:
Bhaumik Bhatt 2019-12-19 18:01:57 -08:00 • committed by Gerrit - the friendly Code Review server
commit d0a4940862

View file

@ -292,6 +292,29 @@ static void mhi_recycle_ev_ring_element(struct mhi_controller *mhi_cntrl,
smp_wmb();
}
static void mhi_recycle_fwd_ev_ring_element(struct mhi_controller *mhi_cntrl,
struct mhi_ring *ring)
{
dma_addr_t ctxt_wp;
/* update the WP */
ring->wp += ring->el_size;
if (ring->wp >= (ring->base + ring->len))
ring->wp = ring->base;
/* update the context WP based on the RP to support fast forwarding */
ctxt_wp = ring->iommu_base + (ring->wp - ring->base);
*ring->ctxt_wp = ctxt_wp;
/* update the RP */
ring->rp += ring->el_size;
if (ring->rp >= (ring->base + ring->len))
ring->rp = ring->base;
/* visible to other cores */
smp_wmb();
}
static bool mhi_is_ring_full(struct mhi_controller *mhi_cntrl,
struct mhi_ring *ring)
{
@ -1451,7 +1474,7 @@ int mhi_process_bw_scale_ev_ring(struct mhi_controller *mhi_cntrl,
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_ev_ring_element(mhi_cntrl, ev_ring);
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)))