Loading drivers/bus/mhi/core/mhi_init.c +39 −8 Original line number Diff line number Diff line Loading @@ -1940,7 +1940,8 @@ static int mhi_driver_remove(struct device *dev) MHI_CH_STATE_DISABLED, MHI_CH_STATE_DISABLED }; int dir; int dir, ret; bool interrupted = false; /* control device has no work to do */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) Loading @@ -1948,11 +1949,11 @@ static int mhi_driver_remove(struct device *dev) MHI_LOG("Removing device for chan:%s\n", mhi_dev->chan_name); /* reset both channels */ /* move both channels to suspended state and disallow processing */ for (dir = 0; dir < 2; dir++) { mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; if (!mhi_chan) if (!mhi_chan || mhi_chan->offload_ch) continue; /* wake all threads waiting for completion */ Loading @@ -1961,15 +1962,45 @@ static int mhi_driver_remove(struct device *dev) complete_all(&mhi_chan->completion); write_unlock_irq(&mhi_chan->lock); /* move channel state to disable, no more processing */ mutex_lock(&mhi_chan->mutex); write_lock_irq(&mhi_chan->lock); if (mhi_chan->ch_state != MHI_CH_STATE_DISABLED) { ch_state[dir] = mhi_chan->ch_state; mhi_chan->ch_state = MHI_CH_STATE_SUSPENDED; } write_unlock_irq(&mhi_chan->lock); mutex_unlock(&mhi_chan->mutex); } /* wait for each channel to close and reset both channels */ for (dir = 0; dir < 2; dir++) { mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; if (!mhi_chan || mhi_chan->offload_ch) continue; /* unbind request from userspace, wait for channel reset */ if (!(mhi_cntrl->power_down || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) && ch_state[dir] != MHI_CH_STATE_DISABLED && !interrupted) { MHI_ERR("Channel %s busy, wait for it to be reset\n", mhi_dev->chan_name); ret = wait_event_interruptible(mhi_cntrl->state_event, mhi_chan->ch_state == MHI_CH_STATE_DISABLED || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)); if (unlikely(ret)) interrupted = true; } /* update channel state as an error can exit above wait */ mutex_lock(&mhi_chan->mutex); write_lock_irq(&mhi_chan->lock); ch_state[dir] = mhi_chan->ch_state; write_unlock_irq(&mhi_chan->lock); /* reset the channel */ if (!mhi_chan->offload_ch) /* reset channel if it was left enabled */ if (ch_state[dir] != MHI_CH_STATE_DISABLED) mhi_reset_chan(mhi_cntrl, mhi_chan); mutex_unlock(&mhi_chan->mutex); Loading @@ -1987,7 +2018,7 @@ static int mhi_driver_remove(struct device *dev) mutex_lock(&mhi_chan->mutex); if (ch_state[dir] == MHI_CH_STATE_ENABLED && if (ch_state[dir] != MHI_CH_STATE_DISABLED && !mhi_chan->offload_ch) mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan); Loading drivers/bus/mhi/core/mhi_main.c +11 −3 Original line number Diff line number Diff line Loading @@ -2055,19 +2055,22 @@ static void __mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, { int ret; bool in_mission_mode = false; bool notify = false; MHI_LOG("Entered: unprepare channel:%d\n", mhi_chan->chan); /* no more processing events for this channel */ mutex_lock(&mhi_chan->mutex); write_lock_irq(&mhi_chan->lock); if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED) { if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED && mhi_chan->ch_state != MHI_CH_STATE_SUSPENDED) { MHI_LOG("chan:%d is already disabled\n", mhi_chan->chan); write_unlock_irq(&mhi_chan->lock); mutex_unlock(&mhi_chan->mutex); return; } if (mhi_chan->ch_state == MHI_CH_STATE_SUSPENDED) notify = true; mhi_chan->ch_state = MHI_CH_STATE_DISABLED; write_unlock_irq(&mhi_chan->lock); Loading Loading @@ -2108,6 +2111,10 @@ static void __mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, if (!mhi_chan->offload_ch) { mhi_reset_chan(mhi_cntrl, mhi_chan); mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan); /* notify waiters to proceed with unbinding channel */ if (notify) wake_up_all(&mhi_cntrl->state_event); } MHI_LOG("chan:%d successfully resetted\n", mhi_chan->chan); mutex_unlock(&mhi_chan->mutex); Loading Loading @@ -2382,7 +2389,8 @@ static int mhi_update_channel_state(struct mhi_controller *mhi_cntrl, mhi_chan->chan, cmd == MHI_CMD_START_CHAN ? "START" : "STOP"); /* if channel is not active state state do not allow to state change */ if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED) { if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED && mhi_chan->ch_state != MHI_CH_STATE_SUSPENDED) { ret = -EINVAL; MHI_LOG("channel:%d is not in active state, ch_state%d\n", mhi_chan->chan, mhi_chan->ch_state); Loading Loading
drivers/bus/mhi/core/mhi_init.c +39 −8 Original line number Diff line number Diff line Loading @@ -1940,7 +1940,8 @@ static int mhi_driver_remove(struct device *dev) MHI_CH_STATE_DISABLED, MHI_CH_STATE_DISABLED }; int dir; int dir, ret; bool interrupted = false; /* control device has no work to do */ if (mhi_dev->dev_type == MHI_CONTROLLER_TYPE) Loading @@ -1948,11 +1949,11 @@ static int mhi_driver_remove(struct device *dev) MHI_LOG("Removing device for chan:%s\n", mhi_dev->chan_name); /* reset both channels */ /* move both channels to suspended state and disallow processing */ for (dir = 0; dir < 2; dir++) { mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; if (!mhi_chan) if (!mhi_chan || mhi_chan->offload_ch) continue; /* wake all threads waiting for completion */ Loading @@ -1961,15 +1962,45 @@ static int mhi_driver_remove(struct device *dev) complete_all(&mhi_chan->completion); write_unlock_irq(&mhi_chan->lock); /* move channel state to disable, no more processing */ mutex_lock(&mhi_chan->mutex); write_lock_irq(&mhi_chan->lock); if (mhi_chan->ch_state != MHI_CH_STATE_DISABLED) { ch_state[dir] = mhi_chan->ch_state; mhi_chan->ch_state = MHI_CH_STATE_SUSPENDED; } write_unlock_irq(&mhi_chan->lock); mutex_unlock(&mhi_chan->mutex); } /* wait for each channel to close and reset both channels */ for (dir = 0; dir < 2; dir++) { mhi_chan = dir ? mhi_dev->ul_chan : mhi_dev->dl_chan; if (!mhi_chan || mhi_chan->offload_ch) continue; /* unbind request from userspace, wait for channel reset */ if (!(mhi_cntrl->power_down || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) && ch_state[dir] != MHI_CH_STATE_DISABLED && !interrupted) { MHI_ERR("Channel %s busy, wait for it to be reset\n", mhi_dev->chan_name); ret = wait_event_interruptible(mhi_cntrl->state_event, mhi_chan->ch_state == MHI_CH_STATE_DISABLED || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)); if (unlikely(ret)) interrupted = true; } /* update channel state as an error can exit above wait */ mutex_lock(&mhi_chan->mutex); write_lock_irq(&mhi_chan->lock); ch_state[dir] = mhi_chan->ch_state; write_unlock_irq(&mhi_chan->lock); /* reset the channel */ if (!mhi_chan->offload_ch) /* reset channel if it was left enabled */ if (ch_state[dir] != MHI_CH_STATE_DISABLED) mhi_reset_chan(mhi_cntrl, mhi_chan); mutex_unlock(&mhi_chan->mutex); Loading @@ -1987,7 +2018,7 @@ static int mhi_driver_remove(struct device *dev) mutex_lock(&mhi_chan->mutex); if (ch_state[dir] == MHI_CH_STATE_ENABLED && if (ch_state[dir] != MHI_CH_STATE_DISABLED && !mhi_chan->offload_ch) mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan); Loading
drivers/bus/mhi/core/mhi_main.c +11 −3 Original line number Diff line number Diff line Loading @@ -2055,19 +2055,22 @@ static void __mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, { int ret; bool in_mission_mode = false; bool notify = false; MHI_LOG("Entered: unprepare channel:%d\n", mhi_chan->chan); /* no more processing events for this channel */ mutex_lock(&mhi_chan->mutex); write_lock_irq(&mhi_chan->lock); if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED) { if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED && mhi_chan->ch_state != MHI_CH_STATE_SUSPENDED) { MHI_LOG("chan:%d is already disabled\n", mhi_chan->chan); write_unlock_irq(&mhi_chan->lock); mutex_unlock(&mhi_chan->mutex); return; } if (mhi_chan->ch_state == MHI_CH_STATE_SUSPENDED) notify = true; mhi_chan->ch_state = MHI_CH_STATE_DISABLED; write_unlock_irq(&mhi_chan->lock); Loading Loading @@ -2108,6 +2111,10 @@ static void __mhi_unprepare_channel(struct mhi_controller *mhi_cntrl, if (!mhi_chan->offload_ch) { mhi_reset_chan(mhi_cntrl, mhi_chan); mhi_deinit_chan_ctxt(mhi_cntrl, mhi_chan); /* notify waiters to proceed with unbinding channel */ if (notify) wake_up_all(&mhi_cntrl->state_event); } MHI_LOG("chan:%d successfully resetted\n", mhi_chan->chan); mutex_unlock(&mhi_chan->mutex); Loading Loading @@ -2382,7 +2389,8 @@ static int mhi_update_channel_state(struct mhi_controller *mhi_cntrl, mhi_chan->chan, cmd == MHI_CMD_START_CHAN ? "START" : "STOP"); /* if channel is not active state state do not allow to state change */ if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED) { if (mhi_chan->ch_state != MHI_CH_STATE_ENABLED && mhi_chan->ch_state != MHI_CH_STATE_SUSPENDED) { ret = -EINVAL; MHI_LOG("channel:%d is not in active state, ch_state%d\n", mhi_chan->chan, mhi_chan->ch_state); Loading