Skip to content

Commit

Permalink
bus: mhi: ep: Add support for suspending and resuming channels
Browse files Browse the repository at this point in the history
Add support for suspending and resuming the channels in MHI endpoint stack.
The channels will be moved to the suspended state during M3 state
transition and will be resumed during M0 transition.

Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20220405135754.6622-18-manivannan.sadhasivam@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Mani-Sadhasivam authored and gregkh committed Apr 26, 2022
1 parent 2d945a3 commit e4b7b5f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/bus/mhi/ep/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,5 +212,7 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl);
int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl);
int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl);
void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl);
void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl);
void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl);

#endif
58 changes: 58 additions & 0 deletions drivers/bus/mhi/ep/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,64 @@ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl)
}
EXPORT_SYMBOL_GPL(mhi_ep_power_down);

void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl)
{
struct mhi_ep_chan *mhi_chan;
u32 tmp;
int i;

for (i = 0; i < mhi_cntrl->max_chan; i++) {
mhi_chan = &mhi_cntrl->mhi_chan[i];

if (!mhi_chan->mhi_dev)
continue;

mutex_lock(&mhi_chan->lock);
/* Skip if the channel is not currently running */
tmp = le32_to_cpu(mhi_cntrl->ch_ctx_cache[i].chcfg);
if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) != MHI_CH_STATE_RUNNING) {
mutex_unlock(&mhi_chan->lock);
continue;
}

dev_dbg(&mhi_chan->mhi_dev->dev, "Suspending channel\n");
/* Set channel state to SUSPENDED */
tmp &= ~CHAN_CTX_CHSTATE_MASK;
tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_SUSPENDED);
mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp);
mutex_unlock(&mhi_chan->lock);
}
}

void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl)
{
struct mhi_ep_chan *mhi_chan;
u32 tmp;
int i;

for (i = 0; i < mhi_cntrl->max_chan; i++) {
mhi_chan = &mhi_cntrl->mhi_chan[i];

if (!mhi_chan->mhi_dev)
continue;

mutex_lock(&mhi_chan->lock);
/* Skip if the channel is not currently suspended */
tmp = le32_to_cpu(mhi_cntrl->ch_ctx_cache[i].chcfg);
if (FIELD_GET(CHAN_CTX_CHSTATE_MASK, tmp) != MHI_CH_STATE_SUSPENDED) {
mutex_unlock(&mhi_chan->lock);
continue;
}

dev_dbg(&mhi_chan->mhi_dev->dev, "Resuming channel\n");
/* Set channel state to RUNNING */
tmp &= ~CHAN_CTX_CHSTATE_MASK;
tmp |= FIELD_PREP(CHAN_CTX_CHSTATE_MASK, MHI_CH_STATE_RUNNING);
mhi_cntrl->ch_ctx_cache[i].chcfg = cpu_to_le32(tmp);
mutex_unlock(&mhi_chan->lock);
}
}

static void mhi_ep_release_device(struct device *dev)
{
struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev);
Expand Down
5 changes: 5 additions & 0 deletions drivers/bus/mhi/ep/sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl)
enum mhi_state old_state;
int ret;

/* If MHI is in M3, resume suspended channels */
spin_lock_bh(&mhi_cntrl->state_lock);
old_state = mhi_cntrl->mhi_state;
if (old_state == MHI_STATE_M3)
mhi_ep_resume_channels(mhi_cntrl);

ret = mhi_ep_set_mhi_state(mhi_cntrl, MHI_STATE_M0);
spin_unlock_bh(&mhi_cntrl->state_lock);
Expand Down Expand Up @@ -106,6 +109,8 @@ int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl)
return ret;
}

mhi_ep_suspend_channels(mhi_cntrl);

/* Signal host that the device moved to M3 */
ret = mhi_ep_send_state_change_event(mhi_cntrl, MHI_STATE_M3);
if (ret) {
Expand Down

0 comments on commit e4b7b5f

Please sign in to comment.