diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 43d680778704..73663e7c1120 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1620,6 +1620,7 @@ static void mhi_ep_remove(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); + struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl; struct mhi_result result = {}; struct mhi_ep_chan *mhi_chan; int dir; @@ -1628,6 +1629,22 @@ static void mhi_ep_remove(struct device *dev) if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) return; + /* Disable the channels to prevent new transfers */ + for (dir = 0; dir < 2; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + + if (!mhi_chan) + continue; + + mutex_lock(&mhi_chan->lock); + mhi_chan->state = MHI_CH_STATE_DISABLED; + mutex_unlock(&mhi_chan->lock); + } + + /* Flush in-flight transfers before notifying disconnect */ + if (mhi_cntrl->flush_async) + mhi_cntrl->flush_async(mhi_cntrl); + /* Disconnect the channels associated with the driver */ for (dir = 0; dir < 2; dir++) { mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; @@ -1643,7 +1660,6 @@ static void mhi_ep_remove(struct device *dev) mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); } - mhi_chan->state = MHI_CH_STATE_DISABLED; mhi_chan->xfer_cb = NULL; mutex_unlock(&mhi_chan->lock); } diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 7b40fc8cbe77..f6383a57a872 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -107,6 +107,7 @@ struct mhi_ep_buf_info { * @write_sync: CB function for writing to host memory synchronously * @read_async: CB function for reading from host memory asynchronously * @write_async: CB function for writing to host memory asynchronously + * @flush_async: CB function for flushing asynchronous read/writes * @mhi_state: MHI Endpoint state * @max_chan: Maximum channels supported by the endpoint controller * @mru: MRU (Maximum Receive Unit) value of the endpoint controller @@ -164,6 +165,7 @@ struct mhi_ep_cntrl { int (*write_sync)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info); int (*read_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info); int (*write_async)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info); + void (*flush_async)(struct mhi_ep_cntrl *mhi_cntrl); enum mhi_state mhi_state;