Loading drivers/bus/mhi/core/mhi_init.c +13 −7 Original line number Diff line number Diff line Loading @@ -1037,7 +1037,7 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl, if (!mhi_cntrl->mhi_event) return -ENOMEM; INIT_LIST_HEAD(&mhi_cntrl->lp_ev_rings); INIT_LIST_HEAD(&mhi_cntrl->sp_ev_rings); /* populate ev ring */ mhi_event = mhi_cntrl->mhi_event; Loading Loading @@ -1120,13 +1120,13 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl, "mhi,offload"); /* * low priority events are handled in a separate worker thread * special purpose events are handled in a separate kthread * to allow for sleeping functions to be called. */ if (!mhi_event->offload_ev) { if (IS_MHI_ER_PRIORITY_LOW(mhi_event)) if (IS_MHI_ER_PRIORITY_SPECIAL(mhi_event)) list_add_tail(&mhi_event->node, &mhi_cntrl->lp_ev_rings); &mhi_cntrl->sp_ev_rings); else mhi_event->request_irq = true; } Loading Loading @@ -1417,10 +1417,15 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) spin_lock_init(&mhi_cntrl->transition_lock); spin_lock_init(&mhi_cntrl->wlock); INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker); INIT_WORK(&mhi_cntrl->syserr_worker, mhi_pm_sys_err_worker); INIT_WORK(&mhi_cntrl->low_priority_worker, mhi_low_priority_worker); init_waitqueue_head(&mhi_cntrl->state_event); mhi_cntrl->special_wq = alloc_ordered_workqueue("mhi_special_w", WQ_MEM_RECLAIM | WQ_HIGHPRI); if (!mhi_cntrl->special_wq) goto error_alloc_cmd; INIT_WORK(&mhi_cntrl->special_work, mhi_special_purpose_work); mhi_cmd = mhi_cntrl->mhi_cmd; for (i = 0; i < NR_OF_CMD_RINGS; i++, mhi_cmd++) spin_lock_init(&mhi_cmd->lock); Loading @@ -1433,7 +1438,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) mhi_event->mhi_cntrl = mhi_cntrl; spin_lock_init(&mhi_event->lock); if (IS_MHI_ER_PRIORITY_LOW(mhi_event)) if (IS_MHI_ER_PRIORITY_SPECIAL(mhi_event)) continue; if (mhi_event->data_type == MHI_ER_CTRL_ELEMENT_TYPE) Loading Loading @@ -1541,6 +1546,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) error_alloc_dev: kfree(mhi_cntrl->mhi_cmd); destroy_workqueue(mhi_cntrl->special_wq); error_alloc_cmd: vfree(mhi_cntrl->mhi_chan); Loading drivers/bus/mhi/core/mhi_internal.h +4 −4 Original line number Diff line number Diff line Loading @@ -551,10 +551,10 @@ enum MHI_ER_TYPE { enum mhi_er_priority { MHI_ER_PRIORITY_HIGH, MHI_ER_PRIORITY_MEDIUM, MHI_ER_PRIORITY_LOW, MHI_ER_PRIORITY_SPECIAL, }; #define IS_MHI_ER_PRIORITY_LOW(ev) (ev->priority >= MHI_ER_PRIORITY_LOW) #define IS_MHI_ER_PRIORITY_SPECIAL(ev) (ev->priority >= MHI_ER_PRIORITY_SPECIAL) #define IS_MHI_ER_PRIORITY_HIGH(ev) (ev->priority == MHI_ER_PRIORITY_HIGH) enum mhi_er_data_type { Loading Loading @@ -772,8 +772,8 @@ int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, enum MHI_ST_TRANSITION state); void mhi_pm_st_worker(struct work_struct *work); void mhi_fw_load_worker(struct work_struct *work); void mhi_pm_sys_err_worker(struct work_struct *work); void mhi_low_priority_worker(struct work_struct *work); void mhi_special_purpose_work(struct work_struct *work); void mhi_process_sys_err(struct mhi_controller *mhi_cntrl); int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl); void mhi_ctrl_ev_task(unsigned long data); int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl); Loading drivers/bus/mhi/core/mhi_main.c +4 −5 Original line number Diff line number Diff line Loading @@ -1317,8 +1317,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, MHI_PM_SYS_ERR_DETECT); write_unlock_irq(&mhi_cntrl->pm_lock); if (new_state == MHI_PM_SYS_ERR_DETECT) schedule_work( &mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); break; } default: Loading Loading @@ -1668,7 +1667,7 @@ void mhi_ctrl_ev_task(unsigned long data) } write_unlock_irq(&mhi_cntrl->pm_lock); if (pm_state == MHI_PM_SYS_ERR_DETECT) schedule_work(&mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); } } Loading Loading @@ -1753,7 +1752,7 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_FATAL_ERROR); else schedule_work(&mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); } exit_intvec: Loading @@ -1779,7 +1778,7 @@ irqreturn_t mhi_intvec_handlr(int irq_number, void *dev) MHI_VERB("Exit\n"); if (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) schedule_work(&mhi_cntrl->low_priority_worker); queue_work(mhi_cntrl->special_wq, &mhi_cntrl->special_work); return IRQ_WAKE_THREAD; } Loading drivers/bus/mhi/core/mhi_pm.c +30 −35 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #include <linux/mhi.h> #include "mhi_internal.h" static void mhi_special_events_pending(struct mhi_controller *mhi_cntrl); /* * Not all MHI states transitions are sync transitions. Linkdown, SSR, and * shutdown can happen anytime asynchronously. This function will transition to Loading Loading @@ -515,6 +517,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) mhi_timesync_log(mhi_cntrl); mhi_special_events_pending(mhi_cntrl); MHI_LOG("Adding new devices\n"); /* add supported devices */ Loading Loading @@ -558,20 +562,9 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, mhi_reset_reg_write_q(mhi_cntrl); /* We must notify MHI control driver so it can clean up first */ if (transition_state == MHI_PM_SYS_ERR_PROCESS) { /* * if controller support rddm, we do not process * sys error state, instead we will jump directly * to rddm state */ if (mhi_cntrl->rddm_image) { MHI_LOG( "Controller Support RDDM, skipping SYS_ERR_PROCESS\n"); return; } if (transition_state == MHI_PM_SYS_ERR_PROCESS) mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_SYS_ERROR); } mutex_lock(&mhi_cntrl->pm_mutex); write_lock_irq(&mhi_cntrl->pm_lock); Loading Loading @@ -646,7 +639,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, MHI_LOG("Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); flush_work(&mhi_cntrl->low_priority_worker); flush_work(&mhi_cntrl->special_work); if (sfr_info && sfr_info->buf_addr) { mhi_free_coherent(mhi_cntrl, sfr_info->len, sfr_info->buf_addr, Loading Loading @@ -740,7 +733,7 @@ int mhi_debugfs_trigger_reset(void *data, u64 val) write_unlock_irq(&mhi_cntrl->pm_lock); if (cur_state == MHI_PM_SYS_ERR_DETECT) schedule_work(&mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); return 0; } Loading Loading @@ -786,18 +779,19 @@ int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, return 0; } static void mhi_low_priority_events_pending(struct mhi_controller *mhi_cntrl) static void mhi_special_events_pending(struct mhi_controller *mhi_cntrl) { struct mhi_event *mhi_event; list_for_each_entry(mhi_event, &mhi_cntrl->lp_ev_rings, node) { list_for_each_entry(mhi_event, &mhi_cntrl->sp_ev_rings, node) { struct mhi_event_ctxt *er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; struct mhi_ring *ev_ring = &mhi_event->ring; spin_lock_bh(&mhi_event->lock); if (ev_ring->rp != mhi_to_virtual(ev_ring, er_ctxt->rp)) { schedule_work(&mhi_cntrl->low_priority_worker); queue_work(mhi_cntrl->special_wq, &mhi_cntrl->special_work); spin_unlock_bh(&mhi_event->lock); break; } Loading @@ -805,11 +799,11 @@ static void mhi_low_priority_events_pending(struct mhi_controller *mhi_cntrl) } } void mhi_low_priority_worker(struct work_struct *work) void mhi_special_purpose_work(struct work_struct *work) { struct mhi_controller *mhi_cntrl = container_of(work, struct mhi_controller, low_priority_worker); special_work); struct mhi_event *mhi_event; MHI_VERB("Enter with pm_state:%s MHI_STATE:%s ee:%s\n", Loading @@ -817,20 +811,21 @@ void mhi_low_priority_worker(struct work_struct *work) TO_MHI_STATE_STR(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); /* check low priority event rings and process events */ list_for_each_entry(mhi_event, &mhi_cntrl->lp_ev_rings, node) /* check special purpose event rings and process events */ list_for_each_entry(mhi_event, &mhi_cntrl->sp_ev_rings, node) mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); } void mhi_pm_sys_err_worker(struct work_struct *work) void mhi_process_sys_err(struct mhi_controller *mhi_cntrl) { struct mhi_controller *mhi_cntrl = container_of(work, struct mhi_controller, syserr_worker); MHI_LOG("Enter with pm_state:%s MHI_STATE:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_STATE_STR(mhi_cntrl->dev_state)); /* * if controller supports rddm, we do not process sys error state, * instead we will jump directly to rddm state */ if (mhi_cntrl->rddm_image) { MHI_LOG("Controller supports RDDM, skipping SYS_ERR_PROCESS\n"); return; } mhi_queue_disable_transition(mhi_cntrl, MHI_PM_SYS_ERR_PROCESS); } Loading Loading @@ -1370,11 +1365,11 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) /* * If MHI on host is in suspending/suspended state, we do not process * any low priority requests, for example, bandwidth scaling events * from the device. Check for low priority event rings and handle the * pending events upon resume. * any special purpose requests, for example, bandwidth scaling events * from the device. Check for special purpose event rings and handle * the pending events upon resume. */ mhi_low_priority_events_pending(mhi_cntrl); mhi_special_events_pending(mhi_cntrl); return 0; } Loading Loading @@ -1444,8 +1439,8 @@ int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client) mhi_msi_handlr(0, mhi_event); } /* schedules worker if any low priority events need to be handled */ mhi_low_priority_events_pending(mhi_cntrl); /* schedules worker if any special purpose events need to be handled */ mhi_special_events_pending(mhi_cntrl); MHI_LOG("Exit with pm_state:%s dev_state:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), Loading include/linux/mhi.h +4 −3 Original line number Diff line number Diff line Loading @@ -268,7 +268,7 @@ struct mhi_controller { u32 msi_allocated; int *irq; /* interrupt table */ struct mhi_event *mhi_event; struct list_head lp_ev_rings; /* low priority event rings */ struct list_head sp_ev_rings; /* special purpose event rings */ /* cmd rings */ struct mhi_cmd *mhi_cmd; Loading Loading @@ -307,8 +307,9 @@ struct mhi_controller { /* worker for different state transitions */ struct work_struct st_worker; struct work_struct fw_worker; struct work_struct syserr_worker; struct work_struct low_priority_worker; struct work_struct special_work; struct workqueue_struct *special_wq; wait_queue_head_t state_event; /* shadow functions */ Loading Loading
drivers/bus/mhi/core/mhi_init.c +13 −7 Original line number Diff line number Diff line Loading @@ -1037,7 +1037,7 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl, if (!mhi_cntrl->mhi_event) return -ENOMEM; INIT_LIST_HEAD(&mhi_cntrl->lp_ev_rings); INIT_LIST_HEAD(&mhi_cntrl->sp_ev_rings); /* populate ev ring */ mhi_event = mhi_cntrl->mhi_event; Loading Loading @@ -1120,13 +1120,13 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl, "mhi,offload"); /* * low priority events are handled in a separate worker thread * special purpose events are handled in a separate kthread * to allow for sleeping functions to be called. */ if (!mhi_event->offload_ev) { if (IS_MHI_ER_PRIORITY_LOW(mhi_event)) if (IS_MHI_ER_PRIORITY_SPECIAL(mhi_event)) list_add_tail(&mhi_event->node, &mhi_cntrl->lp_ev_rings); &mhi_cntrl->sp_ev_rings); else mhi_event->request_irq = true; } Loading Loading @@ -1417,10 +1417,15 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) spin_lock_init(&mhi_cntrl->transition_lock); spin_lock_init(&mhi_cntrl->wlock); INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker); INIT_WORK(&mhi_cntrl->syserr_worker, mhi_pm_sys_err_worker); INIT_WORK(&mhi_cntrl->low_priority_worker, mhi_low_priority_worker); init_waitqueue_head(&mhi_cntrl->state_event); mhi_cntrl->special_wq = alloc_ordered_workqueue("mhi_special_w", WQ_MEM_RECLAIM | WQ_HIGHPRI); if (!mhi_cntrl->special_wq) goto error_alloc_cmd; INIT_WORK(&mhi_cntrl->special_work, mhi_special_purpose_work); mhi_cmd = mhi_cntrl->mhi_cmd; for (i = 0; i < NR_OF_CMD_RINGS; i++, mhi_cmd++) spin_lock_init(&mhi_cmd->lock); Loading @@ -1433,7 +1438,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) mhi_event->mhi_cntrl = mhi_cntrl; spin_lock_init(&mhi_event->lock); if (IS_MHI_ER_PRIORITY_LOW(mhi_event)) if (IS_MHI_ER_PRIORITY_SPECIAL(mhi_event)) continue; if (mhi_event->data_type == MHI_ER_CTRL_ELEMENT_TYPE) Loading Loading @@ -1541,6 +1546,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl) error_alloc_dev: kfree(mhi_cntrl->mhi_cmd); destroy_workqueue(mhi_cntrl->special_wq); error_alloc_cmd: vfree(mhi_cntrl->mhi_chan); Loading
drivers/bus/mhi/core/mhi_internal.h +4 −4 Original line number Diff line number Diff line Loading @@ -551,10 +551,10 @@ enum MHI_ER_TYPE { enum mhi_er_priority { MHI_ER_PRIORITY_HIGH, MHI_ER_PRIORITY_MEDIUM, MHI_ER_PRIORITY_LOW, MHI_ER_PRIORITY_SPECIAL, }; #define IS_MHI_ER_PRIORITY_LOW(ev) (ev->priority >= MHI_ER_PRIORITY_LOW) #define IS_MHI_ER_PRIORITY_SPECIAL(ev) (ev->priority >= MHI_ER_PRIORITY_SPECIAL) #define IS_MHI_ER_PRIORITY_HIGH(ev) (ev->priority == MHI_ER_PRIORITY_HIGH) enum mhi_er_data_type { Loading Loading @@ -772,8 +772,8 @@ int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, enum MHI_ST_TRANSITION state); void mhi_pm_st_worker(struct work_struct *work); void mhi_fw_load_worker(struct work_struct *work); void mhi_pm_sys_err_worker(struct work_struct *work); void mhi_low_priority_worker(struct work_struct *work); void mhi_special_purpose_work(struct work_struct *work); void mhi_process_sys_err(struct mhi_controller *mhi_cntrl); int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl); void mhi_ctrl_ev_task(unsigned long data); int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl); Loading
drivers/bus/mhi/core/mhi_main.c +4 −5 Original line number Diff line number Diff line Loading @@ -1317,8 +1317,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller *mhi_cntrl, MHI_PM_SYS_ERR_DETECT); write_unlock_irq(&mhi_cntrl->pm_lock); if (new_state == MHI_PM_SYS_ERR_DETECT) schedule_work( &mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); break; } default: Loading Loading @@ -1668,7 +1667,7 @@ void mhi_ctrl_ev_task(unsigned long data) } write_unlock_irq(&mhi_cntrl->pm_lock); if (pm_state == MHI_PM_SYS_ERR_DETECT) schedule_work(&mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); } } Loading Loading @@ -1753,7 +1752,7 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_FATAL_ERROR); else schedule_work(&mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); } exit_intvec: Loading @@ -1779,7 +1778,7 @@ irqreturn_t mhi_intvec_handlr(int irq_number, void *dev) MHI_VERB("Exit\n"); if (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) schedule_work(&mhi_cntrl->low_priority_worker); queue_work(mhi_cntrl->special_wq, &mhi_cntrl->special_work); return IRQ_WAKE_THREAD; } Loading
drivers/bus/mhi/core/mhi_pm.c +30 −35 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ #include <linux/mhi.h> #include "mhi_internal.h" static void mhi_special_events_pending(struct mhi_controller *mhi_cntrl); /* * Not all MHI states transitions are sync transitions. Linkdown, SSR, and * shutdown can happen anytime asynchronously. This function will transition to Loading Loading @@ -515,6 +517,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) mhi_timesync_log(mhi_cntrl); mhi_special_events_pending(mhi_cntrl); MHI_LOG("Adding new devices\n"); /* add supported devices */ Loading Loading @@ -558,20 +562,9 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, mhi_reset_reg_write_q(mhi_cntrl); /* We must notify MHI control driver so it can clean up first */ if (transition_state == MHI_PM_SYS_ERR_PROCESS) { /* * if controller support rddm, we do not process * sys error state, instead we will jump directly * to rddm state */ if (mhi_cntrl->rddm_image) { MHI_LOG( "Controller Support RDDM, skipping SYS_ERR_PROCESS\n"); return; } if (transition_state == MHI_PM_SYS_ERR_PROCESS) mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data, MHI_CB_SYS_ERROR); } mutex_lock(&mhi_cntrl->pm_mutex); write_lock_irq(&mhi_cntrl->pm_lock); Loading Loading @@ -646,7 +639,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl, MHI_LOG("Waiting for all pending threads to complete\n"); wake_up_all(&mhi_cntrl->state_event); flush_work(&mhi_cntrl->low_priority_worker); flush_work(&mhi_cntrl->special_work); if (sfr_info && sfr_info->buf_addr) { mhi_free_coherent(mhi_cntrl, sfr_info->len, sfr_info->buf_addr, Loading Loading @@ -740,7 +733,7 @@ int mhi_debugfs_trigger_reset(void *data, u64 val) write_unlock_irq(&mhi_cntrl->pm_lock); if (cur_state == MHI_PM_SYS_ERR_DETECT) schedule_work(&mhi_cntrl->syserr_worker); mhi_process_sys_err(mhi_cntrl); return 0; } Loading Loading @@ -786,18 +779,19 @@ int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, return 0; } static void mhi_low_priority_events_pending(struct mhi_controller *mhi_cntrl) static void mhi_special_events_pending(struct mhi_controller *mhi_cntrl) { struct mhi_event *mhi_event; list_for_each_entry(mhi_event, &mhi_cntrl->lp_ev_rings, node) { list_for_each_entry(mhi_event, &mhi_cntrl->sp_ev_rings, node) { struct mhi_event_ctxt *er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index]; struct mhi_ring *ev_ring = &mhi_event->ring; spin_lock_bh(&mhi_event->lock); if (ev_ring->rp != mhi_to_virtual(ev_ring, er_ctxt->rp)) { schedule_work(&mhi_cntrl->low_priority_worker); queue_work(mhi_cntrl->special_wq, &mhi_cntrl->special_work); spin_unlock_bh(&mhi_event->lock); break; } Loading @@ -805,11 +799,11 @@ static void mhi_low_priority_events_pending(struct mhi_controller *mhi_cntrl) } } void mhi_low_priority_worker(struct work_struct *work) void mhi_special_purpose_work(struct work_struct *work) { struct mhi_controller *mhi_cntrl = container_of(work, struct mhi_controller, low_priority_worker); special_work); struct mhi_event *mhi_event; MHI_VERB("Enter with pm_state:%s MHI_STATE:%s ee:%s\n", Loading @@ -817,20 +811,21 @@ void mhi_low_priority_worker(struct work_struct *work) TO_MHI_STATE_STR(mhi_cntrl->dev_state), TO_MHI_EXEC_STR(mhi_cntrl->ee)); /* check low priority event rings and process events */ list_for_each_entry(mhi_event, &mhi_cntrl->lp_ev_rings, node) /* check special purpose event rings and process events */ list_for_each_entry(mhi_event, &mhi_cntrl->sp_ev_rings, node) mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX); } void mhi_pm_sys_err_worker(struct work_struct *work) void mhi_process_sys_err(struct mhi_controller *mhi_cntrl) { struct mhi_controller *mhi_cntrl = container_of(work, struct mhi_controller, syserr_worker); MHI_LOG("Enter with pm_state:%s MHI_STATE:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), TO_MHI_STATE_STR(mhi_cntrl->dev_state)); /* * if controller supports rddm, we do not process sys error state, * instead we will jump directly to rddm state */ if (mhi_cntrl->rddm_image) { MHI_LOG("Controller supports RDDM, skipping SYS_ERR_PROCESS\n"); return; } mhi_queue_disable_transition(mhi_cntrl, MHI_PM_SYS_ERR_PROCESS); } Loading Loading @@ -1370,11 +1365,11 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) /* * If MHI on host is in suspending/suspended state, we do not process * any low priority requests, for example, bandwidth scaling events * from the device. Check for low priority event rings and handle the * pending events upon resume. * any special purpose requests, for example, bandwidth scaling events * from the device. Check for special purpose event rings and handle * the pending events upon resume. */ mhi_low_priority_events_pending(mhi_cntrl); mhi_special_events_pending(mhi_cntrl); return 0; } Loading Loading @@ -1444,8 +1439,8 @@ int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client) mhi_msi_handlr(0, mhi_event); } /* schedules worker if any low priority events need to be handled */ mhi_low_priority_events_pending(mhi_cntrl); /* schedules worker if any special purpose events need to be handled */ mhi_special_events_pending(mhi_cntrl); MHI_LOG("Exit with pm_state:%s dev_state:%s\n", to_mhi_pm_state_str(mhi_cntrl->pm_state), Loading
include/linux/mhi.h +4 −3 Original line number Diff line number Diff line Loading @@ -268,7 +268,7 @@ struct mhi_controller { u32 msi_allocated; int *irq; /* interrupt table */ struct mhi_event *mhi_event; struct list_head lp_ev_rings; /* low priority event rings */ struct list_head sp_ev_rings; /* special purpose event rings */ /* cmd rings */ struct mhi_cmd *mhi_cmd; Loading Loading @@ -307,8 +307,9 @@ struct mhi_controller { /* worker for different state transitions */ struct work_struct st_worker; struct work_struct fw_worker; struct work_struct syserr_worker; struct work_struct low_priority_worker; struct work_struct special_work; struct workqueue_struct *special_wq; wait_queue_head_t state_event; /* shadow functions */ Loading