From e623db906d62a1da61a6812c68b7d57fc4283c28 Mon Sep 17 00:00:00 2001 From: Nitesh Gupta Date: Fri, 5 Mar 2021 18:11:20 +0530 Subject: [PATCH] msm: mhi: Queue channel db only if channel is open Channel interrupts are seen on device even before, channel ring is initialized. Queuing pending work without checking ring status can lead to processing of spurious interrupts. Adding proper checks in place before queuing channel doorbell. Change-Id: I3ccd7302b535d2b8ef63eada9d7a1fe553dccdaa Signed-off-by: Nitesh Gupta Signed-off-by: Gauri Joshi --- drivers/platform/msm/mhi_dev/mhi.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index 5eca5c2d3214..573911877588 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -2236,11 +2236,12 @@ static int mhi_dev_get_event_notify(enum mhi_dev_state state, return rc; } -static void mhi_dev_queue_channel_db(struct mhi_dev *mhi, +static bool mhi_dev_queue_channel_db(struct mhi_dev *mhi, uint32_t chintr_value, uint32_t ch_num) { struct mhi_dev_ring *ring; struct mhi_dev_channel *ch; + bool work_pending = false; int rc = 0; for (; chintr_value; ch_num++, chintr_value >>= 1) { @@ -2255,14 +2256,16 @@ static void mhi_dev_queue_channel_db(struct mhi_dev *mhi, ch = &mhi->ch[ch_num]; mutex_lock(&ch->ch_lock); ch->db_pending = true; + work_pending = true; mutex_unlock(&ch->ch_lock); rc = mhi_dev_mmio_disable_chdb_a7(mhi, ch_num); if (rc) { pr_err("Error disabling chdb\n"); - return; + return work_pending; } } } + return work_pending; } /* @@ -2291,11 +2294,11 @@ static bool mhi_dev_check_channel_interrupt(struct mhi_dev *mhi) /* Process channel status whose mask is enabled */ chintr_value = (mhi->chdb[i].status & mhi->chdb[i].mask); if (chintr_value) { - pending_work = true; mhi_log(MHI_MSG_VERBOSE, "processing id: %d, ch interrupt 0x%x\n", i, chintr_value); - mhi_dev_queue_channel_db(mhi, chintr_value, ch_num); + pending_work |= mhi_dev_queue_channel_db(mhi, + chintr_value, ch_num); rc = mhi_dev_mmio_write(mhi, MHI_CHDB_INT_CLEAR_A7_n(i), mhi->chdb[i].status); if (rc) {