Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ddce5d8 authored by Sujeev Dias's avatar Sujeev Dias
Browse files

mhi: core: prepare all the descriptors before ringing hardware doorbell



While mhi host queues new buffers to transfer ring during
start, process completion transfer thread will queue a
buffer to same channel after receiving a completion
event. To avoid this scenario, prepare all descriptors
before ringing the hardware doorbell so there will not be
any completion packets to process.

CRs-Fixed: 2236500
Change-Id: I91f065932ef46dc3520fd1a8ad634e2b65badff1
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent 8c5ca64d
Loading
Loading
Loading
Loading
+21 −8
Original line number Diff line number Diff line
@@ -1101,13 +1101,8 @@ static int __mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
	mhi_chan->ch_state = MHI_CH_STATE_ENABLED;
	write_unlock_irq(&mhi_chan->lock);

	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	/* pre allocate buffer for xfer ring */
	if (mhi_chan->pre_alloc) {
		struct mhi_device *mhi_dev = mhi_chan->mhi_dev;
		int nr_el = get_nr_avail_ring_elements(mhi_cntrl,
						       &mhi_chan->tre_ring);

@@ -1120,17 +1115,30 @@ static int __mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
				goto error_pre_alloc;
			}

			ret = mhi_queue_buf(mhi_dev, mhi_chan, buf, MHI_MAX_MTU,
					    MHI_EOT);
			/* prepare transfer descriptors */
			ret = mhi_chan->gen_tre(mhi_cntrl, mhi_chan, buf, buf,
						MHI_MAX_MTU, MHI_EOT);
			if (ret) {
				MHI_ERR("Chan:%d error queue buffer\n",
				MHI_ERR("Chan:%d error prepare buffer\n",
					mhi_chan->chan);
				kfree(buf);
				goto error_pre_alloc;
			}
		}

		read_lock_bh(&mhi_cntrl->pm_lock);
		if (MHI_DB_ACCESS_VALID(mhi_cntrl->pm_state)) {
			read_lock_irq(&mhi_chan->lock);
			mhi_ring_chan_db(mhi_cntrl, mhi_chan);
			read_unlock_irq(&mhi_chan->lock);
		}
		read_unlock_bh(&mhi_cntrl->pm_lock);
	}

	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	mutex_unlock(&mhi_chan->mutex);

	MHI_LOG("Chan:%d successfully moved to start state\n", mhi_chan->chan);
@@ -1152,6 +1160,11 @@ static int __mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
	return ret;

error_pre_alloc:

	read_lock_bh(&mhi_cntrl->pm_lock);
	mhi_cntrl->wake_put(mhi_cntrl, false);
	read_unlock_bh(&mhi_cntrl->pm_lock);

	mutex_unlock(&mhi_chan->mutex);
	__mhi_unprepare_channel(mhi_cntrl, mhi_chan);