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

Commit 143c2283 authored by Sujeev Dias's avatar Sujeev Dias Committed by Gerrit - the friendly Code Review server
Browse files

mhi: core: release channel locks before removing mhi devices



There could be a deadlock between mhi device remove, and client
calling channel start\stop operation because of common lock. To
avoid this deadlock, release channel lock before calling client
device remove function.

CRs-Fixed: 2281958
Change-Id: I332fee417c3ebaae113e11375d10f4487b2194a2
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent d18a2e31
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1395,12 +1395,14 @@ static int mhi_driver_remove(struct device *dev)
		mutex_lock(&mhi_chan->mutex);
		write_lock_irq(&mhi_chan->lock);
		ch_state[dir] = mhi_chan->ch_state;
		mhi_chan->ch_state = MHI_CH_STATE_DISABLED;
		mhi_chan->ch_state = MHI_CH_STATE_SUSPENDED;
		write_unlock_irq(&mhi_chan->lock);

		/* reset the channel */
		if (!mhi_chan->offload_ch)
			mhi_reset_chan(mhi_cntrl, mhi_chan);

		mutex_unlock(&mhi_chan->mutex);
	}

	/* destroy the device */
@@ -1413,10 +1415,14 @@ static int mhi_driver_remove(struct device *dev)
		if (!mhi_chan)
			continue;

		mutex_lock(&mhi_chan->mutex);

		if (ch_state[dir] == MHI_CH_STATE_ENABLED &&
		    !mhi_chan->offload_ch)
			mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan);

		mhi_chan->ch_state = MHI_CH_STATE_DISABLED;

		/* remove associated device */
		mhi_chan->mhi_dev = NULL;

+9 −0
Original line number Diff line number Diff line
@@ -1329,6 +1329,15 @@ static int __mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
	}

	mutex_lock(&mhi_chan->mutex);

	/* if channel is not disable state do not allow to start */
	if (mhi_chan->ch_state != MHI_CH_STATE_DISABLED) {
		ret = -EIO;
		MHI_LOG("channel:%d is not in disabled state, ch_state%d\n",
			mhi_chan->chan, mhi_chan->ch_state);
		goto error_init_chan;
	}

	/* client manages channel context for offload channels */
	if (!mhi_chan->offload_ch) {
		ret = mhi_init_chan_ctxt(mhi_cntrl, mhi_chan);