diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 083507774089..60d84444ac1f 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -1763,6 +1763,47 @@ void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) } EXPORT_SYMBOL_GPL(mhi_unprepare_from_transfer); +static int mhi_update_transfer_state(struct mhi_device *mhi_dev, + enum mhi_ch_state_type to_state) +{ + struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; + struct mhi_chan *mhi_chan; + int dir, ret; + + for (dir = 0; dir < 2; dir++) { + mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; + + if (!mhi_chan) + continue; + + /* + * Bail out if one of the channels fails as client will reset + * both upon failure + */ + mutex_lock(&mhi_chan->mutex); + ret = mhi_update_channel_state(mhi_cntrl, mhi_chan, to_state); + if (ret) { + mutex_unlock(&mhi_chan->mutex); + return ret; + } + mutex_unlock(&mhi_chan->mutex); + } + + return 0; +} + +int mhi_stop_transfer(struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev, MHI_CH_STATE_TYPE_STOP); +} +EXPORT_SYMBOL(mhi_stop_transfer); + +int mhi_start_transfer(struct mhi_device *mhi_dev) +{ + return mhi_update_transfer_state(mhi_dev, MHI_CH_STATE_TYPE_START); +} +EXPORT_SYMBOL(mhi_start_transfer); + int mhi_poll(struct mhi_device *mhi_dev, u32 budget) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl;