diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 79d276a5bb17..beb38b6c1b8e 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -697,6 +697,9 @@ struct mhi_chan { struct completion completion; rwlock_t lock; struct list_head node; + + /* stats */ + u64 mode_change; }; struct tsync_node { diff --git a/drivers/bus/mhi/core/mhi_main.c b/drivers/bus/mhi/core/mhi_main.c index 50ed82dddf5e..bad39fbacbe2 100644 --- a/drivers/bus/mhi/core/mhi_main.c +++ b/drivers/bus/mhi/core/mhi_main.c @@ -558,9 +558,9 @@ int mhi_queue_dma(struct mhi_device *mhi_dev, mhi_tre->dword[1] = MHI_TRE_DATA_DWORD1(mhi_chan->bei, 1, 0, 0); } - MHI_VERB("chan:%d WP:0x%llx TRE:0x%llx 0x%08x 0x%08x\n", mhi_chan->chan, - (u64)mhi_to_physical(tre_ring, mhi_tre), mhi_tre->ptr, - mhi_tre->dword[0], mhi_tre->dword[1]); + MHI_VERB("chan:%d WP:0x%llx TRE:0x%llx 0x%08x 0x%08x rDB %d\n", + mhi_chan->chan, (u64)mhi_to_physical(tre_ring, mhi_tre), + mhi_tre->ptr, mhi_tre->dword[0], mhi_tre->dword[1], ring_db); /* increment WP */ mhi_add_ring_element(mhi_cntrl, tre_ring); @@ -988,6 +988,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, unsigned long flags = 0; bool ring_db = true; int n_free_tre, n_queued_tre; + unsigned long rflags; ev_code = MHI_TRE_GET_EV_CODE(event); buf_ring = &mhi_chan->buf_ring; @@ -1077,12 +1078,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, break; } /* CC_EOT */ case MHI_EV_CC_OOB: - case MHI_EV_CC_DB_MODE: - { - unsigned long flags; - - MHI_VERB("DB_MODE/OOB Detected chan %d.\n", mhi_chan->chan); mhi_chan->db_cfg.db_mode = true; + mhi_chan->mode_change++; /* * on RSC channel IPA HW has a minimum credit requirement before @@ -1096,14 +1093,27 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, ring_db = false; } - read_lock_irqsave(&mhi_cntrl->pm_lock, flags); + MHI_VERB("OOB_MODE chan %d ring_db %d\n", mhi_chan->chan, + ring_db); + + read_lock_irqsave(&mhi_cntrl->pm_lock, rflags); if (tre_ring->wp != tre_ring->rp && - MHI_DB_ACCESS_VALID(mhi_cntrl) && ring_db) { + MHI_DB_ACCESS_VALID(mhi_cntrl) && ring_db) mhi_ring_chan_db(mhi_cntrl, mhi_chan); - } - read_unlock_irqrestore(&mhi_cntrl->pm_lock, flags); + read_unlock_irqrestore(&mhi_cntrl->pm_lock, rflags); + break; + case MHI_EV_CC_DB_MODE: + MHI_VERB("DB_MODE chan %d.\n", mhi_chan->chan); + mhi_chan->db_cfg.db_mode = true; + mhi_chan->mode_change++; + + read_lock_irqsave(&mhi_cntrl->pm_lock, rflags); + if (tre_ring->wp != tre_ring->rp && + MHI_DB_ACCESS_VALID(mhi_cntrl)) + mhi_ring_chan_db(mhi_cntrl, mhi_chan); + + read_unlock_irqrestore(&mhi_cntrl->pm_lock, rflags); break; - } case MHI_EV_CC_BAD_TRE: MHI_ASSERT(1, "Received BAD TRE event for ring"); break; @@ -2205,12 +2215,14 @@ int mhi_debugfs_mhi_chan_show(struct seq_file *m, void *d) chan_ctxt->pollcfg, chan_ctxt->chtype, chan_ctxt->erindex); seq_printf(m, - " base:0x%llx len:0x%llx wp:0x%llx local_rp:0x%llx local_wp:0x%llx db:0x%llx\n", + " base:0x%llx len:0x%llx wp:0x%llx local_rp:0x%llx local_wp:0x%llx db:0x%llx mode_change:0x%llx\n", chan_ctxt->rbase, chan_ctxt->rlen, chan_ctxt->wp, mhi_to_physical(ring, ring->rp), mhi_to_physical(ring, ring->wp), - mhi_chan->db_cfg.db_val); + mhi_chan->db_cfg.db_val, + mhi_chan->mode_change); + mhi_chan->mode_change = 0; } }