Loading drivers/bus/mhi/core/mhi_main.c +6 −0 Original line number Diff line number Diff line Loading @@ -1734,9 +1734,15 @@ irqreturn_t mhi_intvec_handlr(int irq_number, void *dev) { struct mhi_controller *mhi_cntrl = dev; u32 in_reset = -1; /* wake up any events waiting for state change */ MHI_VERB("Enter\n"); if (unlikely(mhi_cntrl->initiate_mhi_reset)) { mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, &in_reset); mhi_cntrl->initiate_mhi_reset = !!in_reset; } wake_up_all(&mhi_cntrl->state_event); MHI_VERB("Exit\n"); Loading drivers/bus/mhi/core/mhi_pm.c +11 −8 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, if (state == MHI_STATE_RESET) { mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 1); mhi_cntrl->initiate_mhi_reset = true; } else { mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->regs, MHICTRL, (state << MHICTRL_MHISTATE_SHIFT)); Loading Loading @@ -602,20 +603,18 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, /* trigger MHI RESET so device will not access host ddr */ if (MHI_REG_ACCESS_VALID(prev_state)) { u32 in_reset = -1; unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms); MHI_LOG("Trigger device into MHI_RESET\n"); write_lock_irq(&mhi_cntrl->pm_lock); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); write_unlock_irq(&mhi_cntrl->pm_lock); /* wait for reset to be cleared */ ret = wait_event_timeout(mhi_cntrl->state_event, mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, &in_reset) || !in_reset, timeout); if ((!ret || in_reset) && cur_state == MHI_PM_SYS_ERR_PROCESS) { !mhi_cntrl->initiate_mhi_reset, timeout); if (!ret && cur_state == MHI_PM_SYS_ERR_PROCESS) { MHI_CRITICAL("Device failed to exit RESET state\n"); mutex_unlock(&mhi_cntrl->pm_mutex); return; Loading @@ -625,7 +624,11 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, * device cleares INTVEC as part of RESET processing, * re-program it */ mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); if (!mhi_cntrl->initiate_mhi_reset) mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); mhi_cntrl->initiate_mhi_reset = false; } MHI_LOG("Waiting for all pending event ring processing to complete\n"); Loading include/linux/mhi.h +1 −0 Original line number Diff line number Diff line Loading @@ -399,6 +399,7 @@ struct mhi_controller { /* controller specific data */ const char *name; bool power_down; bool initiate_mhi_reset; void *priv_data; void *log_buf; struct dentry *dentry; Loading Loading
drivers/bus/mhi/core/mhi_main.c +6 −0 Original line number Diff line number Diff line Loading @@ -1734,9 +1734,15 @@ irqreturn_t mhi_intvec_handlr(int irq_number, void *dev) { struct mhi_controller *mhi_cntrl = dev; u32 in_reset = -1; /* wake up any events waiting for state change */ MHI_VERB("Enter\n"); if (unlikely(mhi_cntrl->initiate_mhi_reset)) { mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, &in_reset); mhi_cntrl->initiate_mhi_reset = !!in_reset; } wake_up_all(&mhi_cntrl->state_event); MHI_VERB("Exit\n"); Loading
drivers/bus/mhi/core/mhi_pm.c +11 −8 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, if (state == MHI_STATE_RESET) { mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 1); mhi_cntrl->initiate_mhi_reset = true; } else { mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->regs, MHICTRL, (state << MHICTRL_MHISTATE_SHIFT)); Loading Loading @@ -602,20 +603,18 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, /* trigger MHI RESET so device will not access host ddr */ if (MHI_REG_ACCESS_VALID(prev_state)) { u32 in_reset = -1; unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms); MHI_LOG("Trigger device into MHI_RESET\n"); write_lock_irq(&mhi_cntrl->pm_lock); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); write_unlock_irq(&mhi_cntrl->pm_lock); /* wait for reset to be cleared */ ret = wait_event_timeout(mhi_cntrl->state_event, mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, &in_reset) || !in_reset, timeout); if ((!ret || in_reset) && cur_state == MHI_PM_SYS_ERR_PROCESS) { !mhi_cntrl->initiate_mhi_reset, timeout); if (!ret && cur_state == MHI_PM_SYS_ERR_PROCESS) { MHI_CRITICAL("Device failed to exit RESET state\n"); mutex_unlock(&mhi_cntrl->pm_mutex); return; Loading @@ -625,7 +624,11 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, * device cleares INTVEC as part of RESET processing, * re-program it */ mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); if (!mhi_cntrl->initiate_mhi_reset) mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); mhi_cntrl->initiate_mhi_reset = false; } MHI_LOG("Waiting for all pending event ring processing to complete\n"); Loading
include/linux/mhi.h +1 −0 Original line number Diff line number Diff line Loading @@ -399,6 +399,7 @@ struct mhi_controller { /* controller specific data */ const char *name; bool power_down; bool initiate_mhi_reset; void *priv_data; void *log_buf; struct dentry *dentry; Loading