Loading drivers/bus/mhi/core/mhi_boot.c +26 −10 Original line number Diff line number Diff line Loading @@ -52,8 +52,10 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) u32 rx_status; enum mhi_ee ee; struct image_info *rddm_image = mhi_cntrl->rddm_image; const u32 delayus = 100; const u32 delayus = 2000; u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus; const u32 rddm_timeout_us = 200000; int rddm_retry = rddm_timeout_us / delayus; /* time to enter rddm */ void __iomem *base = mhi_cntrl->bhie; MHI_LOG("Entered with pm_state:%s dev_state:%s ee:%s\n", Loading @@ -67,14 +69,8 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) * returning from this function, we expect device to reset. * * Normaly, we would read/write pm_state only after grabbing * pm_lock, since we're in a panic, skipping it. */ if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) return -EIO; /* * There is no gurantee this state change would take effect since * pm_lock, since we're in a panic, skipping it. Also there is no * gurantee this state change would take effect since * we're setting it w/o grabbing pmlock, it's best effort */ mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT; Loading Loading @@ -107,7 +103,27 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) MHI_LOG("Trigger device into RDDM mode\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); MHI_LOG("Waiting for image download completion\n"); MHI_LOG("Waiting for device to enter RDDM\n"); while (rddm_retry--) { ee = mhi_get_exec_env(mhi_cntrl); if (ee == MHI_EE_RDDM) break; udelay(delayus); } if (rddm_retry <= 0) { /* This is a hardware reset, will force device to enter rddm */ MHI_LOG( "Did not enter RDDM triggering host req. reset to force rddm\n"); mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, MHI_SOC_RESET_REQ_OFFSET, MHI_SOC_RESET_REQ); udelay(delayus); } ee = mhi_get_exec_env(mhi_cntrl); MHI_LOG("Waiting for image download completion, current EE:%s\n", TO_MHI_EXEC_STR(ee)); while (retry--) { ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, BHIE_RXVECSTATUS_STATUS_BMSK, Loading drivers/bus/mhi/core/mhi_internal.h +4 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,10 @@ extern struct bus_type mhi_bus_type; #define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK (0xFFFFFFFF) #define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT (0) /* Host request register */ #define MHI_SOC_RESET_REQ_OFFSET (0xB0) #define MHI_SOC_RESET_REQ BIT(0) /* MHI misc capability registers */ #define MISC_OFFSET (0x24) #define MISC_CAP_MASK (0xFFFFFFFF) Loading drivers/bus/mhi/core/mhi_main.c +12 −3 Original line number Diff line number Diff line Loading @@ -1389,12 +1389,20 @@ void mhi_ctrl_ev_task(unsigned long data) { struct mhi_event *mhi_event = (struct mhi_event *)data; struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl; enum mhi_dev_state state = MHI_STATE_MAX; enum mhi_dev_state state; enum MHI_PM_STATE pm_state = 0; int ret; MHI_VERB("Enter for ev_index:%d\n", mhi_event->er_index); /* * we can check pm_state w/o a lock here because there is no way * pm_state can change from reg access valid to no access while this * therad being executed. */ if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) return; /* process ctrl events events */ ret = mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); Loading @@ -1404,7 +1412,6 @@ void mhi_ctrl_ev_task(unsigned long data) */ if (!ret) { write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) state = mhi_get_mhi_state(mhi_cntrl); if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); Loading Loading @@ -1457,6 +1464,8 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { state = mhi_get_mhi_state(mhi_cntrl); ee = mhi_get_exec_env(mhi_cntrl); MHI_LOG("device ee:%s dev_state:%s\n", TO_MHI_EXEC_STR(ee), TO_MHI_STATE_STR(state)); } if (state == MHI_STATE_SYS_ERR) { Loading drivers/bus/mhi/core/mhi_pm.c +6 −21 Original line number Diff line number Diff line Loading @@ -1054,6 +1054,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) MHI_ERR("Did not enter M0 state, cur_state:%s pm_state:%s\n", TO_MHI_STATE_STR(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); /* * It's possible device already in error state and we didn't * process it due to low power mode, force a check */ mhi_intvec_threaded_handlr(0, mhi_cntrl); return -EIO; } Loading Loading @@ -1133,22 +1139,8 @@ int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); /* before rddm mode, we need to enter M0 state */ ret = __mhi_device_get_sync(mhi_cntrl); if (ret) return ret; mutex_lock(&mhi_cntrl->pm_mutex); write_lock_irq(&mhi_cntrl->pm_lock); if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) goto no_reg_access; MHI_LOG("Triggering SYS_ERR to force rddm state\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); mhi_cntrl->wake_put(mhi_cntrl, false); write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); /* wait for rddm event */ MHI_LOG("Waiting for device to enter RDDM state\n"); Loading @@ -1162,12 +1154,5 @@ int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) TO_MHI_EXEC_STR(mhi_cntrl->ee), ret); return ret; no_reg_access: mhi_cntrl->wake_put(mhi_cntrl, false); write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); return -EIO; } EXPORT_SYMBOL(mhi_force_rddm_mode); Loading
drivers/bus/mhi/core/mhi_boot.c +26 −10 Original line number Diff line number Diff line Loading @@ -52,8 +52,10 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) u32 rx_status; enum mhi_ee ee; struct image_info *rddm_image = mhi_cntrl->rddm_image; const u32 delayus = 100; const u32 delayus = 2000; u32 retry = (mhi_cntrl->timeout_ms * 1000) / delayus; const u32 rddm_timeout_us = 200000; int rddm_retry = rddm_timeout_us / delayus; /* time to enter rddm */ void __iomem *base = mhi_cntrl->bhie; MHI_LOG("Entered with pm_state:%s dev_state:%s ee:%s\n", Loading @@ -67,14 +69,8 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) * returning from this function, we expect device to reset. * * Normaly, we would read/write pm_state only after grabbing * pm_lock, since we're in a panic, skipping it. */ if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) return -EIO; /* * There is no gurantee this state change would take effect since * pm_lock, since we're in a panic, skipping it. Also there is no * gurantee this state change would take effect since * we're setting it w/o grabbing pmlock, it's best effort */ mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT; Loading Loading @@ -107,7 +103,27 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl) MHI_LOG("Trigger device into RDDM mode\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); MHI_LOG("Waiting for image download completion\n"); MHI_LOG("Waiting for device to enter RDDM\n"); while (rddm_retry--) { ee = mhi_get_exec_env(mhi_cntrl); if (ee == MHI_EE_RDDM) break; udelay(delayus); } if (rddm_retry <= 0) { /* This is a hardware reset, will force device to enter rddm */ MHI_LOG( "Did not enter RDDM triggering host req. reset to force rddm\n"); mhi_write_reg(mhi_cntrl, mhi_cntrl->regs, MHI_SOC_RESET_REQ_OFFSET, MHI_SOC_RESET_REQ); udelay(delayus); } ee = mhi_get_exec_env(mhi_cntrl); MHI_LOG("Waiting for image download completion, current EE:%s\n", TO_MHI_EXEC_STR(ee)); while (retry--) { ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, BHIE_RXVECSTATUS_STATUS_BMSK, Loading
drivers/bus/mhi/core/mhi_internal.h +4 −0 Original line number Diff line number Diff line Loading @@ -134,6 +134,10 @@ extern struct bus_type mhi_bus_type; #define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_MASK (0xFFFFFFFF) #define MHIDATALIMIT_HIGHER_MHIDATALIMIT_HIGHER_SHIFT (0) /* Host request register */ #define MHI_SOC_RESET_REQ_OFFSET (0xB0) #define MHI_SOC_RESET_REQ BIT(0) /* MHI misc capability registers */ #define MISC_OFFSET (0x24) #define MISC_CAP_MASK (0xFFFFFFFF) Loading
drivers/bus/mhi/core/mhi_main.c +12 −3 Original line number Diff line number Diff line Loading @@ -1389,12 +1389,20 @@ void mhi_ctrl_ev_task(unsigned long data) { struct mhi_event *mhi_event = (struct mhi_event *)data; struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl; enum mhi_dev_state state = MHI_STATE_MAX; enum mhi_dev_state state; enum MHI_PM_STATE pm_state = 0; int ret; MHI_VERB("Enter for ev_index:%d\n", mhi_event->er_index); /* * we can check pm_state w/o a lock here because there is no way * pm_state can change from reg access valid to no access while this * therad being executed. */ if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) return; /* process ctrl events events */ ret = mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); Loading @@ -1404,7 +1412,6 @@ void mhi_ctrl_ev_task(unsigned long data) */ if (!ret) { write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) state = mhi_get_mhi_state(mhi_cntrl); if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); Loading Loading @@ -1457,6 +1464,8 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { state = mhi_get_mhi_state(mhi_cntrl); ee = mhi_get_exec_env(mhi_cntrl); MHI_LOG("device ee:%s dev_state:%s\n", TO_MHI_EXEC_STR(ee), TO_MHI_STATE_STR(state)); } if (state == MHI_STATE_SYS_ERR) { Loading
drivers/bus/mhi/core/mhi_pm.c +6 −21 Original line number Diff line number Diff line Loading @@ -1054,6 +1054,12 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) MHI_ERR("Did not enter M0 state, cur_state:%s pm_state:%s\n", TO_MHI_STATE_STR(mhi_cntrl->dev_state), to_mhi_pm_state_str(mhi_cntrl->pm_state)); /* * It's possible device already in error state and we didn't * process it due to low power mode, force a check */ mhi_intvec_threaded_handlr(0, mhi_cntrl); return -EIO; } Loading Loading @@ -1133,22 +1139,8 @@ int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); /* before rddm mode, we need to enter M0 state */ ret = __mhi_device_get_sync(mhi_cntrl); if (ret) return ret; mutex_lock(&mhi_cntrl->pm_mutex); write_lock_irq(&mhi_cntrl->pm_lock); if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) goto no_reg_access; MHI_LOG("Triggering SYS_ERR to force rddm state\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); mhi_cntrl->wake_put(mhi_cntrl, false); write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); /* wait for rddm event */ MHI_LOG("Waiting for device to enter RDDM state\n"); Loading @@ -1162,12 +1154,5 @@ int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) TO_MHI_EXEC_STR(mhi_cntrl->ee), ret); return ret; no_reg_access: mhi_cntrl->wake_put(mhi_cntrl, false); write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); return -EIO; } EXPORT_SYMBOL(mhi_force_rddm_mode);