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

Commit 12815f05 authored by Chris Lew's avatar Chris Lew Committed by Gerrit - the friendly Code Review server
Browse files

mhi: core: auto-start uplink channel before client driver probe



For auto-start feature, MHI client can queue data uplink as soon
as the probe is received. If that is attempted, there is a
chance of NULL pointer access as channel may not be initialized.
Change the order to allow initializing the uplink channel before
probe is called.

CRs-Fixed: 2501803
Change-Id: I90b65bd9a015534d38ba0e4e931d3a2b13bcbf18
Acked-by: default avatarBhaumik Vasav Bhatt <bbhatt@qti.qualcomm.com>
Signed-off-by: default avatarChris Lew <clew@codeaurora.org>
parent 65119ded
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -1579,7 +1579,6 @@ static int mhi_driver_probe(struct device *dev)
	struct mhi_event *mhi_event;
	struct mhi_chan *ul_chan = mhi_dev->ul_chan;
	struct mhi_chan *dl_chan = mhi_dev->dl_chan;
	bool auto_start = false;
	int ret;

	/* bring device out of lpm */
@@ -1598,7 +1597,11 @@ static int mhi_driver_probe(struct device *dev)

		ul_chan->xfer_cb = mhi_drv->ul_xfer_cb;
		mhi_dev->status_cb = mhi_drv->status_cb;
		auto_start = ul_chan->auto_start;
		if (ul_chan->auto_start) {
			ret = mhi_prepare_channel(mhi_cntrl, ul_chan);
			if (ret)
				goto exit_probe;
		}
	}

	if (dl_chan) {
@@ -1622,15 +1625,22 @@ static int mhi_driver_probe(struct device *dev)

		/* ul & dl uses same status cb */
		mhi_dev->status_cb = mhi_drv->status_cb;
		auto_start = (auto_start || dl_chan->auto_start);
	}

	ret = mhi_drv->probe(mhi_dev, mhi_dev->id);
	if (ret)
		goto exit_probe;

	if (!ret && auto_start)
		mhi_prepare_for_transfer(mhi_dev);
	if (dl_chan && dl_chan->auto_start)
		mhi_prepare_channel(mhi_cntrl, dl_chan);

	mhi_device_put(mhi_dev, MHI_VOTE_DEVICE);

	return ret;

exit_probe:
	mhi_unprepare_from_transfer(mhi_dev);

	mhi_device_put(mhi_dev, MHI_VOTE_DEVICE);

	return ret;
+2 −0
Original line number Diff line number Diff line
@@ -867,6 +867,8 @@ void mhi_deinit_free_irq(struct mhi_controller *mhi_cntrl);
int mhi_dtr_init(void);
void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
		      struct image_info *img_info);
int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
			struct mhi_chan *mhi_chan);

/* isr handlers */
irqreturn_t mhi_msi_handlr(int irq_number, void *dev);
+3 −3
Original line number Diff line number Diff line
@@ -1690,7 +1690,7 @@ int mhi_send_cmd(struct mhi_controller *mhi_cntrl,
	return 0;
}

static int __mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
int mhi_prepare_channel(struct mhi_controller *mhi_cntrl,
			struct mhi_chan *mhi_chan)
{
	int ret = 0;
@@ -2078,7 +2078,7 @@ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev)
		if (!mhi_chan)
			continue;

		ret = __mhi_prepare_channel(mhi_cntrl, mhi_chan);
		ret = mhi_prepare_channel(mhi_cntrl, mhi_chan);
		if (ret) {
			MHI_ERR("Error moving chan %s,%d to START state\n",
				mhi_chan->name, mhi_chan->chan);