Loading drivers/bus/mhi/core/mhi_boot.c +7 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include <linux/debugfs.h> #include <linux/delay.h> Loading Loading @@ -321,6 +321,9 @@ static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl, mhi_buf->len); mhi_cntrl->sequence_id = prandom_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK; if (unlikely(!mhi_cntrl->sequence_id)) mhi_cntrl->sequence_id = 1; mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS, BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT, mhi_cntrl->sequence_id); Loading Loading @@ -383,6 +386,9 @@ static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl, lower_32_bits(dma_addr)); mhi_cntrl->write_reg(mhi_cntrl, base, BHI_IMGSIZE, size); mhi_cntrl->session_id = prandom_u32() & BHI_TXDB_SEQNUM_BMSK; if (unlikely(!mhi_cntrl->session_id)) mhi_cntrl->session_id = 1; mhi_cntrl->write_reg(mhi_cntrl, base, BHI_IMGTXDB, mhi_cntrl->session_id); read_unlock_bh(pm_lock); Loading drivers/bus/mhi/core/mhi_init.c +1 −1 Original line number Diff line number Diff line Loading @@ -703,7 +703,7 @@ static int mhi_init_bw_scale(struct mhi_controller *mhi_cntrl) /* No ER configured to support BW scale */ er_index = mhi_get_er_index(mhi_cntrl, MHI_ER_BW_SCALE_ELEMENT_TYPE); if (ret < 0) if (er_index < 0) return er_index; bw_cfg_offset += BW_SCALE_CFG_OFFSET; Loading drivers/bus/mhi/core/mhi_main.c +30 −21 Original line number Diff line number Diff line Loading @@ -1294,6 +1294,10 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, TO_MHI_EXEC_STR(event)); switch (event) { case MHI_EE_SBL: write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = MHI_EE_SBL; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); st = MHI_ST_TRANSITION_SBL; break; case MHI_EE_WFW: Loading @@ -1301,13 +1305,6 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, st = MHI_ST_TRANSITION_MISSION_MODE; break; case MHI_EE_RDDM: mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_RDDM); write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = event; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); break; default: MHI_ERR("Unhandled EE event:%s\n", Loading Loading @@ -1674,13 +1671,17 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) } state = mhi_get_mhi_state(mhi_cntrl); ee = mhi_cntrl->ee; mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); ee = mhi_get_exec_env(mhi_cntrl); MHI_LOG("local ee:%s device ee:%s dev_state:%s\n", TO_MHI_EXEC_STR(ee), TO_MHI_EXEC_STR(mhi_cntrl->ee), TO_MHI_EXEC_STR(ee), TO_MHI_STATE_STR(state)); if (mhi_cntrl->power_down) { write_unlock_irq(&mhi_cntrl->pm_lock); goto exit_intvec; } if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, Loading @@ -1688,20 +1689,28 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) } write_unlock_irq(&mhi_cntrl->pm_lock); /* if device in rddm don't bother processing sys error */ if (mhi_cntrl->ee == MHI_EE_RDDM && ee != MHI_EE_DISABLE_TRANSITION) { if (mhi_cntrl->ee != ee) { if (ee == MHI_EE_RDDM) { write_lock_irq(&mhi_cntrl->pm_lock); if (mhi_cntrl->ee == MHI_EE_RDDM) { write_unlock_irq(&mhi_cntrl->pm_lock); goto exit_intvec; } mhi_cntrl->ee = MHI_EE_RDDM; write_unlock_irq(&mhi_cntrl->pm_lock); MHI_ERR("RDDM event occurred!\n"); mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_RDDM); wake_up_all(&mhi_cntrl->state_event); /* notify critical clients with early notifications */ mhi_control_error(mhi_cntrl); } goto exit_intvec; } if (pm_state == MHI_PM_SYS_ERR_DETECT) { /* if device is in RDDM, don't bother processing SYS_ERR */ if (ee != MHI_EE_RDDM && pm_state == MHI_PM_SYS_ERR_DETECT) { wake_up_all(&mhi_cntrl->state_event); /* for fatal errors, we let controller decide next step */ Loading drivers/bus/mhi/core/mhi_pm.c +19 −14 Original line number Diff line number Diff line Loading @@ -474,12 +474,16 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) ee = mhi_get_exec_env(mhi_cntrl); write_unlock_irq(&mhi_cntrl->pm_lock); if (!MHI_IN_MISSION_MODE(ee)) if (!MHI_IN_MISSION_MODE(ee)) { MHI_ERR("Invalid EE:%s\n", TO_MHI_EXEC_STR(ee)); return -EIO; } mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_MISSION_MODE); write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = ee; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); Loading Loading @@ -585,8 +589,6 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, mhi_cntrl->ee = MHI_EE_DISABLE_TRANSITION; mhi_cntrl->dev_state = MHI_STATE_RESET; } /* notify controller of power down regardless of state transitions */ mhi_cntrl->power_down = true; write_unlock_irq(&mhi_cntrl->pm_lock); /* wake up any threads waiting for state transitions */ Loading Loading @@ -830,6 +832,10 @@ void mhi_process_sys_err(struct mhi_controller *mhi_cntrl) return; } write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->power_down = true; write_unlock_irq(&mhi_cntrl->pm_lock); mhi_queue_disable_transition(mhi_cntrl, MHI_PM_SYS_ERR_PROCESS); } Loading @@ -855,14 +861,9 @@ void mhi_pm_st_worker(struct work_struct *work) if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); write_unlock_irq(&mhi_cntrl->pm_lock); if (MHI_IN_PBL(mhi_cntrl->ee)) mhi_fw_load_handler(mhi_cntrl); break; case MHI_ST_TRANSITION_SBL: write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = MHI_EE_SBL; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); mhi_create_devices(mhi_cntrl); break; case MHI_ST_TRANSITION_MISSION_MODE: Loading Loading @@ -949,6 +950,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) } mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); mhi_cntrl->power_down = false; mhi_cntrl->pm_state = MHI_PM_POR; mhi_cntrl->ee = MHI_EE_MAX; current_ee = mhi_get_exec_env(mhi_cntrl); Loading Loading @@ -976,6 +978,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) return 0; error_bhi_offset: mhi_cntrl->power_down = true; mhi_deinit_free_irq(mhi_cntrl); error_setup_irq: Loading Loading @@ -1034,21 +1037,23 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) enum MHI_PM_STATE cur_state; enum MHI_PM_STATE transition_state = MHI_PM_SHUTDOWN_PROCESS; /* if it's not graceful shutdown, force MHI to a linkdown state */ if (!graceful) { mutex_lock(&mhi_cntrl->pm_mutex); write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->power_down = true; /* if it's not graceful shutdown, force MHI to a linkdown state */ if (!graceful) { cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_LD_ERR_FATAL_DETECT); write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT) MHI_ERR("Failed to move to state:%s from:%s\n", to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT), to_mhi_pm_state_str(mhi_cntrl->pm_state)); transition_state = MHI_PM_SHUTDOWN_NO_ACCESS; } write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); mhi_queue_disable_transition(mhi_cntrl, transition_state); Loading Loading
drivers/bus/mhi/core/mhi_boot.c +7 −1 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */ /* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ #include <linux/debugfs.h> #include <linux/delay.h> Loading Loading @@ -321,6 +321,9 @@ static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl, mhi_buf->len); mhi_cntrl->sequence_id = prandom_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK; if (unlikely(!mhi_cntrl->sequence_id)) mhi_cntrl->sequence_id = 1; mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS, BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT, mhi_cntrl->sequence_id); Loading Loading @@ -383,6 +386,9 @@ static int mhi_fw_load_sbl(struct mhi_controller *mhi_cntrl, lower_32_bits(dma_addr)); mhi_cntrl->write_reg(mhi_cntrl, base, BHI_IMGSIZE, size); mhi_cntrl->session_id = prandom_u32() & BHI_TXDB_SEQNUM_BMSK; if (unlikely(!mhi_cntrl->session_id)) mhi_cntrl->session_id = 1; mhi_cntrl->write_reg(mhi_cntrl, base, BHI_IMGTXDB, mhi_cntrl->session_id); read_unlock_bh(pm_lock); Loading
drivers/bus/mhi/core/mhi_init.c +1 −1 Original line number Diff line number Diff line Loading @@ -703,7 +703,7 @@ static int mhi_init_bw_scale(struct mhi_controller *mhi_cntrl) /* No ER configured to support BW scale */ er_index = mhi_get_er_index(mhi_cntrl, MHI_ER_BW_SCALE_ELEMENT_TYPE); if (ret < 0) if (er_index < 0) return er_index; bw_cfg_offset += BW_SCALE_CFG_OFFSET; Loading
drivers/bus/mhi/core/mhi_main.c +30 −21 Original line number Diff line number Diff line Loading @@ -1294,6 +1294,10 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, TO_MHI_EXEC_STR(event)); switch (event) { case MHI_EE_SBL: write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = MHI_EE_SBL; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); st = MHI_ST_TRANSITION_SBL; break; case MHI_EE_WFW: Loading @@ -1301,13 +1305,6 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, st = MHI_ST_TRANSITION_MISSION_MODE; break; case MHI_EE_RDDM: mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_RDDM); write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = event; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); break; default: MHI_ERR("Unhandled EE event:%s\n", Loading Loading @@ -1674,13 +1671,17 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) } state = mhi_get_mhi_state(mhi_cntrl); ee = mhi_cntrl->ee; mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); ee = mhi_get_exec_env(mhi_cntrl); MHI_LOG("local ee:%s device ee:%s dev_state:%s\n", TO_MHI_EXEC_STR(ee), TO_MHI_EXEC_STR(mhi_cntrl->ee), TO_MHI_EXEC_STR(ee), TO_MHI_STATE_STR(state)); if (mhi_cntrl->power_down) { write_unlock_irq(&mhi_cntrl->pm_lock); goto exit_intvec; } if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, Loading @@ -1688,20 +1689,28 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) } write_unlock_irq(&mhi_cntrl->pm_lock); /* if device in rddm don't bother processing sys error */ if (mhi_cntrl->ee == MHI_EE_RDDM && ee != MHI_EE_DISABLE_TRANSITION) { if (mhi_cntrl->ee != ee) { if (ee == MHI_EE_RDDM) { write_lock_irq(&mhi_cntrl->pm_lock); if (mhi_cntrl->ee == MHI_EE_RDDM) { write_unlock_irq(&mhi_cntrl->pm_lock); goto exit_intvec; } mhi_cntrl->ee = MHI_EE_RDDM; write_unlock_irq(&mhi_cntrl->pm_lock); MHI_ERR("RDDM event occurred!\n"); mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_RDDM); wake_up_all(&mhi_cntrl->state_event); /* notify critical clients with early notifications */ mhi_control_error(mhi_cntrl); } goto exit_intvec; } if (pm_state == MHI_PM_SYS_ERR_DETECT) { /* if device is in RDDM, don't bother processing SYS_ERR */ if (ee != MHI_EE_RDDM && pm_state == MHI_PM_SYS_ERR_DETECT) { wake_up_all(&mhi_cntrl->state_event); /* for fatal errors, we let controller decide next step */ Loading
drivers/bus/mhi/core/mhi_pm.c +19 −14 Original line number Diff line number Diff line Loading @@ -474,12 +474,16 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) ee = mhi_get_exec_env(mhi_cntrl); write_unlock_irq(&mhi_cntrl->pm_lock); if (!MHI_IN_MISSION_MODE(ee)) if (!MHI_IN_MISSION_MODE(ee)) { MHI_ERR("Invalid EE:%s\n", TO_MHI_EXEC_STR(ee)); return -EIO; } mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_EE_MISSION_MODE); write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = ee; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); Loading Loading @@ -585,8 +589,6 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, mhi_cntrl->ee = MHI_EE_DISABLE_TRANSITION; mhi_cntrl->dev_state = MHI_STATE_RESET; } /* notify controller of power down regardless of state transitions */ mhi_cntrl->power_down = true; write_unlock_irq(&mhi_cntrl->pm_lock); /* wake up any threads waiting for state transitions */ Loading Loading @@ -830,6 +832,10 @@ void mhi_process_sys_err(struct mhi_controller *mhi_cntrl) return; } write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->power_down = true; write_unlock_irq(&mhi_cntrl->pm_lock); mhi_queue_disable_transition(mhi_cntrl, MHI_PM_SYS_ERR_PROCESS); } Loading @@ -855,14 +861,9 @@ void mhi_pm_st_worker(struct work_struct *work) if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); write_unlock_irq(&mhi_cntrl->pm_lock); if (MHI_IN_PBL(mhi_cntrl->ee)) mhi_fw_load_handler(mhi_cntrl); break; case MHI_ST_TRANSITION_SBL: write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->ee = MHI_EE_SBL; write_unlock_irq(&mhi_cntrl->pm_lock); wake_up_all(&mhi_cntrl->state_event); mhi_create_devices(mhi_cntrl); break; case MHI_ST_TRANSITION_MISSION_MODE: Loading Loading @@ -949,6 +950,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) } mhi_cntrl->write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); mhi_cntrl->power_down = false; mhi_cntrl->pm_state = MHI_PM_POR; mhi_cntrl->ee = MHI_EE_MAX; current_ee = mhi_get_exec_env(mhi_cntrl); Loading Loading @@ -976,6 +978,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) return 0; error_bhi_offset: mhi_cntrl->power_down = true; mhi_deinit_free_irq(mhi_cntrl); error_setup_irq: Loading Loading @@ -1034,21 +1037,23 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) enum MHI_PM_STATE cur_state; enum MHI_PM_STATE transition_state = MHI_PM_SHUTDOWN_PROCESS; /* if it's not graceful shutdown, force MHI to a linkdown state */ if (!graceful) { mutex_lock(&mhi_cntrl->pm_mutex); write_lock_irq(&mhi_cntrl->pm_lock); mhi_cntrl->power_down = true; /* if it's not graceful shutdown, force MHI to a linkdown state */ if (!graceful) { cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_LD_ERR_FATAL_DETECT); write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); if (cur_state != MHI_PM_LD_ERR_FATAL_DETECT) MHI_ERR("Failed to move to state:%s from:%s\n", to_mhi_pm_state_str(MHI_PM_LD_ERR_FATAL_DETECT), to_mhi_pm_state_str(mhi_cntrl->pm_state)); transition_state = MHI_PM_SHUTDOWN_NO_ACCESS; } write_unlock_irq(&mhi_cntrl->pm_lock); mutex_unlock(&mhi_cntrl->pm_mutex); mhi_queue_disable_transition(mhi_cntrl, transition_state); Loading