Lines Matching refs:mhi_cntrl
111 enum mhi_pm_state __must_check mhi_tryset_pm_state(struct mhi_controller *mhi_cntrl, in mhi_tryset_pm_state() argument
114 unsigned long cur_state = mhi_cntrl->pm_state; in mhi_tryset_pm_state()
126 mhi_cntrl->pm_state = state; in mhi_tryset_pm_state()
127 return mhi_cntrl->pm_state; in mhi_tryset_pm_state()
130 void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_state state) in mhi_set_mhi_state() argument
132 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_set_mhi_state()
136 ret = mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, in mhi_set_mhi_state()
139 ret = mhi_write_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, in mhi_set_mhi_state()
149 static void mhi_toggle_dev_wake_nop(struct mhi_controller *mhi_cntrl) in mhi_toggle_dev_wake_nop() argument
153 static void mhi_toggle_dev_wake(struct mhi_controller *mhi_cntrl) in mhi_toggle_dev_wake() argument
155 mhi_cntrl->wake_get(mhi_cntrl, false); in mhi_toggle_dev_wake()
156 mhi_cntrl->wake_put(mhi_cntrl, true); in mhi_toggle_dev_wake()
160 int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl) in mhi_ready_state_transition() argument
164 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_ready_state_transition()
169 if (MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { in mhi_ready_state_transition()
175 ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, in mhi_ready_state_transition()
182 ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, in mhi_ready_state_transition()
190 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_ready_state_transition()
191 cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_POR); in mhi_ready_state_transition()
192 mhi_cntrl->dev_state = MHI_STATE_READY; in mhi_ready_state_transition()
193 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_ready_state_transition()
202 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_ready_state_transition()
203 if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) { in mhi_ready_state_transition()
209 ret = mhi_init_mmio(mhi_cntrl); in mhi_ready_state_transition()
216 mhi_event = mhi_cntrl->mhi_event; in mhi_ready_state_transition()
217 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { in mhi_ready_state_transition()
236 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M0); in mhi_ready_state_transition()
237 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_ready_state_transition()
242 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_ready_state_transition()
247 int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl) in mhi_pm_m0_transition() argument
251 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_m0_transition()
254 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_m0_transition()
255 mhi_cntrl->dev_state = MHI_STATE_M0; in mhi_pm_m0_transition()
256 cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M0); in mhi_pm_m0_transition()
257 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_m0_transition()
262 mhi_cntrl->M0++; in mhi_pm_m0_transition()
265 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_pm_m0_transition()
266 mhi_cntrl->wake_get(mhi_cntrl, true); in mhi_pm_m0_transition()
269 if (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) { in mhi_pm_m0_transition()
270 struct mhi_event *mhi_event = mhi_cntrl->mhi_event; in mhi_pm_m0_transition()
272 &mhi_cntrl->mhi_cmd[PRIMARY_CMD_RING]; in mhi_pm_m0_transition()
274 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { in mhi_pm_m0_transition()
286 mhi_ring_cmd_db(mhi_cntrl, mhi_cmd); in mhi_pm_m0_transition()
291 mhi_chan = mhi_cntrl->mhi_chan; in mhi_pm_m0_transition()
292 for (i = 0; i < mhi_cntrl->max_chan; i++, mhi_chan++) { in mhi_pm_m0_transition()
305 mhi_ring_chan_db(mhi_cntrl, mhi_chan); in mhi_pm_m0_transition()
309 mhi_cntrl->wake_put(mhi_cntrl, false); in mhi_pm_m0_transition()
310 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_pm_m0_transition()
311 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_m0_transition()
321 void mhi_pm_m1_transition(struct mhi_controller *mhi_cntrl) in mhi_pm_m1_transition() argument
324 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_m1_transition()
326 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_m1_transition()
327 state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M2); in mhi_pm_m1_transition()
329 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M2); in mhi_pm_m1_transition()
330 mhi_cntrl->dev_state = MHI_STATE_M2; in mhi_pm_m1_transition()
332 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_m1_transition()
334 mhi_cntrl->M2++; in mhi_pm_m1_transition()
335 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_m1_transition()
338 if (unlikely(atomic_read(&mhi_cntrl->pending_pkts) || in mhi_pm_m1_transition()
339 atomic_read(&mhi_cntrl->dev_wake))) { in mhi_pm_m1_transition()
342 atomic_read(&mhi_cntrl->pending_pkts), in mhi_pm_m1_transition()
343 atomic_read(&mhi_cntrl->dev_wake)); in mhi_pm_m1_transition()
344 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_pm_m1_transition()
345 mhi_cntrl->wake_get(mhi_cntrl, true); in mhi_pm_m1_transition()
346 mhi_cntrl->wake_put(mhi_cntrl, true); in mhi_pm_m1_transition()
347 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_pm_m1_transition()
349 mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_IDLE); in mhi_pm_m1_transition()
352 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_m1_transition()
357 int mhi_pm_m3_transition(struct mhi_controller *mhi_cntrl) in mhi_pm_m3_transition() argument
360 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_m3_transition()
362 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_m3_transition()
363 mhi_cntrl->dev_state = MHI_STATE_M3; in mhi_pm_m3_transition()
364 state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3); in mhi_pm_m3_transition()
365 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_m3_transition()
371 mhi_cntrl->M3++; in mhi_pm_m3_transition()
372 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_m3_transition()
378 static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl) in mhi_pm_mission_mode_transition() argument
381 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_mission_mode_transition()
382 enum mhi_ee_type ee = MHI_EE_MAX, current_ee = mhi_cntrl->ee; in mhi_pm_mission_mode_transition()
387 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_mission_mode_transition()
388 if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) in mhi_pm_mission_mode_transition()
389 ee = mhi_get_exec_env(mhi_cntrl); in mhi_pm_mission_mode_transition()
392 mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT; in mhi_pm_mission_mode_transition()
393 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_mission_mode_transition()
394 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_mission_mode_transition()
397 mhi_cntrl->ee = ee; in mhi_pm_mission_mode_transition()
398 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_mission_mode_transition()
400 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_mission_mode_transition()
402 device_for_each_child(&mhi_cntrl->mhi_dev->dev, ¤t_ee, in mhi_pm_mission_mode_transition()
404 mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_EE_MISSION_MODE); in mhi_pm_mission_mode_transition()
407 ret = __mhi_device_get_sync(mhi_cntrl); in mhi_pm_mission_mode_transition()
411 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_pm_mission_mode_transition()
413 if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { in mhi_pm_mission_mode_transition()
419 mhi_event = mhi_cntrl->mhi_event; in mhi_pm_mission_mode_transition()
420 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { in mhi_pm_mission_mode_transition()
432 if (MHI_DB_ACCESS_VALID(mhi_cntrl)) in mhi_pm_mission_mode_transition()
437 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_pm_mission_mode_transition()
443 mhi_create_devices(mhi_cntrl); in mhi_pm_mission_mode_transition()
445 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_pm_mission_mode_transition()
448 mhi_cntrl->wake_put(mhi_cntrl, false); in mhi_pm_mission_mode_transition()
449 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_pm_mission_mode_transition()
455 static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl) in mhi_pm_disable_transition() argument
462 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_disable_transition()
466 to_mhi_pm_state_str(mhi_cntrl->pm_state)); in mhi_pm_disable_transition()
468 mutex_lock(&mhi_cntrl->pm_mutex); in mhi_pm_disable_transition()
471 if (!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { in mhi_pm_disable_transition()
473 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); in mhi_pm_disable_transition()
476 ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, in mhi_pm_disable_transition()
485 mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); in mhi_pm_disable_transition()
487 if (!MHI_IN_PBL(mhi_get_exec_env(mhi_cntrl))) { in mhi_pm_disable_transition()
489 ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, in mhi_pm_disable_transition()
499 mhi_event = mhi_cntrl->mhi_event; in mhi_pm_disable_transition()
500 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { in mhi_pm_disable_transition()
503 disable_irq(mhi_cntrl->irq[mhi_event->irq]); in mhi_pm_disable_transition()
508 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_pm_disable_transition()
510 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_disable_transition()
513 device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); in mhi_pm_disable_transition()
515 mutex_lock(&mhi_cntrl->pm_mutex); in mhi_pm_disable_transition()
517 WARN_ON(atomic_read(&mhi_cntrl->dev_wake)); in mhi_pm_disable_transition()
518 WARN_ON(atomic_read(&mhi_cntrl->pending_pkts)); in mhi_pm_disable_transition()
522 mhi_cmd = mhi_cntrl->mhi_cmd; in mhi_pm_disable_transition()
523 cmd_ctxt = mhi_cntrl->mhi_ctxt->cmd_ctxt; in mhi_pm_disable_transition()
533 mhi_event = mhi_cntrl->mhi_event; in mhi_pm_disable_transition()
534 er_ctxt = mhi_cntrl->mhi_ctxt->er_ctxt; in mhi_pm_disable_transition()
535 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, er_ctxt++, in mhi_pm_disable_transition()
550 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_disable_transition()
551 cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_DISABLE); in mhi_pm_disable_transition()
552 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_disable_transition()
559 to_mhi_pm_state_str(mhi_cntrl->pm_state), in mhi_pm_disable_transition()
560 mhi_state_str(mhi_cntrl->dev_state)); in mhi_pm_disable_transition()
562 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_pm_disable_transition()
566 static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) in mhi_pm_sys_error_transition() argument
574 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_sys_error_transition()
578 to_mhi_pm_state_str(mhi_cntrl->pm_state), in mhi_pm_sys_error_transition()
582 mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_SYS_ERROR); in mhi_pm_sys_error_transition()
584 mutex_lock(&mhi_cntrl->pm_mutex); in mhi_pm_sys_error_transition()
585 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_sys_error_transition()
586 prev_state = mhi_cntrl->pm_state; in mhi_pm_sys_error_transition()
587 cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_SYS_ERR_PROCESS); in mhi_pm_sys_error_transition()
588 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_sys_error_transition()
597 mhi_cntrl->ee = MHI_EE_DISABLE_TRANSITION; in mhi_pm_sys_error_transition()
598 mhi_cntrl->dev_state = MHI_STATE_RESET; in mhi_pm_sys_error_transition()
601 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_sys_error_transition()
606 unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms); in mhi_pm_sys_error_transition()
609 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); in mhi_pm_sys_error_transition()
612 ret = wait_event_timeout(mhi_cntrl->state_event, in mhi_pm_sys_error_transition()
613 mhi_read_reg_field(mhi_cntrl, in mhi_pm_sys_error_transition()
614 mhi_cntrl->regs, in mhi_pm_sys_error_transition()
628 mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); in mhi_pm_sys_error_transition()
633 mhi_event = mhi_cntrl->mhi_event; in mhi_pm_sys_error_transition()
634 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { in mhi_pm_sys_error_transition()
641 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_pm_sys_error_transition()
643 wake_up_all(&mhi_cntrl->state_event); in mhi_pm_sys_error_transition()
646 device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_destroy_device); in mhi_pm_sys_error_transition()
648 mutex_lock(&mhi_cntrl->pm_mutex); in mhi_pm_sys_error_transition()
650 WARN_ON(atomic_read(&mhi_cntrl->dev_wake)); in mhi_pm_sys_error_transition()
651 WARN_ON(atomic_read(&mhi_cntrl->pending_pkts)); in mhi_pm_sys_error_transition()
655 mhi_cmd = mhi_cntrl->mhi_cmd; in mhi_pm_sys_error_transition()
656 cmd_ctxt = mhi_cntrl->mhi_ctxt->cmd_ctxt; in mhi_pm_sys_error_transition()
666 mhi_event = mhi_cntrl->mhi_event; in mhi_pm_sys_error_transition()
667 er_ctxt = mhi_cntrl->mhi_ctxt->er_ctxt; in mhi_pm_sys_error_transition()
668 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, er_ctxt++, in mhi_pm_sys_error_transition()
683 if (MHI_IN_PBL(mhi_get_exec_env(mhi_cntrl))) { in mhi_pm_sys_error_transition()
684 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_sys_error_transition()
685 cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_POR); in mhi_pm_sys_error_transition()
686 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_sys_error_transition()
698 mhi_queue_state_transition(mhi_cntrl, next_state); in mhi_pm_sys_error_transition()
702 to_mhi_pm_state_str(mhi_cntrl->pm_state), in mhi_pm_sys_error_transition()
703 mhi_state_str(mhi_cntrl->dev_state)); in mhi_pm_sys_error_transition()
705 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_pm_sys_error_transition()
709 int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, in mhi_queue_state_transition() argument
719 spin_lock_irqsave(&mhi_cntrl->transition_lock, flags); in mhi_queue_state_transition()
720 list_add_tail(&item->node, &mhi_cntrl->transition_list); in mhi_queue_state_transition()
721 spin_unlock_irqrestore(&mhi_cntrl->transition_lock, flags); in mhi_queue_state_transition()
723 queue_work(mhi_cntrl->hiprio_wq, &mhi_cntrl->st_worker); in mhi_queue_state_transition()
729 void mhi_pm_sys_err_handler(struct mhi_controller *mhi_cntrl) in mhi_pm_sys_err_handler() argument
731 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_sys_err_handler()
734 if (mhi_cntrl->rddm_image) { in mhi_pm_sys_err_handler()
739 mhi_queue_state_transition(mhi_cntrl, DEV_ST_TRANSITION_SYS_ERR); in mhi_pm_sys_err_handler()
747 struct mhi_controller *mhi_cntrl = container_of(work, in mhi_pm_st_worker() local
750 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_st_worker()
752 spin_lock_irq(&mhi_cntrl->transition_lock); in mhi_pm_st_worker()
753 list_splice_tail_init(&mhi_cntrl->transition_list, &head); in mhi_pm_st_worker()
754 spin_unlock_irq(&mhi_cntrl->transition_lock); in mhi_pm_st_worker()
763 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_st_worker()
764 if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) in mhi_pm_st_worker()
765 mhi_cntrl->ee = mhi_get_exec_env(mhi_cntrl); in mhi_pm_st_worker()
766 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_st_worker()
767 mhi_fw_load_handler(mhi_cntrl); in mhi_pm_st_worker()
770 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_st_worker()
771 mhi_cntrl->ee = MHI_EE_SBL; in mhi_pm_st_worker()
772 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_st_worker()
778 mhi_create_devices(mhi_cntrl); in mhi_pm_st_worker()
779 if (mhi_cntrl->fbc_download) in mhi_pm_st_worker()
780 mhi_download_amss_image(mhi_cntrl); in mhi_pm_st_worker()
783 mhi_pm_mission_mode_transition(mhi_cntrl); in mhi_pm_st_worker()
786 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_st_worker()
787 mhi_cntrl->ee = MHI_EE_FP; in mhi_pm_st_worker()
788 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_st_worker()
789 mhi_create_devices(mhi_cntrl); in mhi_pm_st_worker()
792 mhi_ready_state_transition(mhi_cntrl); in mhi_pm_st_worker()
795 mhi_pm_sys_error_transition(mhi_cntrl); in mhi_pm_st_worker()
798 mhi_pm_disable_transition(mhi_cntrl); in mhi_pm_st_worker()
807 int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) in mhi_pm_suspend() argument
810 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_pm_suspend()
814 if (mhi_cntrl->pm_state == MHI_PM_DISABLE) in mhi_pm_suspend()
817 if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) in mhi_pm_suspend()
821 if (atomic_read(&mhi_cntrl->dev_wake) || in mhi_pm_suspend()
822 atomic_read(&mhi_cntrl->pending_pkts)) in mhi_pm_suspend()
826 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
827 mhi_cntrl->wake_get(mhi_cntrl, false); in mhi_pm_suspend()
828 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
830 ret = wait_event_timeout(mhi_cntrl->state_event, in mhi_pm_suspend()
831 mhi_cntrl->dev_state == MHI_STATE_M0 || in mhi_pm_suspend()
832 mhi_cntrl->dev_state == MHI_STATE_M1 || in mhi_pm_suspend()
833 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), in mhi_pm_suspend()
834 msecs_to_jiffies(mhi_cntrl->timeout_ms)); in mhi_pm_suspend()
836 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
837 mhi_cntrl->wake_put(mhi_cntrl, false); in mhi_pm_suspend()
838 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
840 if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { in mhi_pm_suspend()
846 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
848 if (atomic_read(&mhi_cntrl->dev_wake) || in mhi_pm_suspend()
849 atomic_read(&mhi_cntrl->pending_pkts)) { in mhi_pm_suspend()
850 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
855 new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3_ENTER); in mhi_pm_suspend()
857 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
861 to_mhi_pm_state_str(mhi_cntrl->pm_state)); in mhi_pm_suspend()
866 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M3); in mhi_pm_suspend()
867 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_pm_suspend()
870 ret = wait_event_timeout(mhi_cntrl->state_event, in mhi_pm_suspend()
871 mhi_cntrl->dev_state == MHI_STATE_M3 || in mhi_pm_suspend()
872 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), in mhi_pm_suspend()
873 msecs_to_jiffies(mhi_cntrl->timeout_ms)); in mhi_pm_suspend()
875 if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { in mhi_pm_suspend()
878 mhi_state_str(mhi_cntrl->dev_state), in mhi_pm_suspend()
879 to_mhi_pm_state_str(mhi_cntrl->pm_state)); in mhi_pm_suspend()
884 list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { in mhi_pm_suspend()
895 static int __mhi_pm_resume(struct mhi_controller *mhi_cntrl, bool force) in __mhi_pm_resume() argument
898 struct device *dev = &mhi_cntrl->mhi_dev->dev; in __mhi_pm_resume()
903 to_mhi_pm_state_str(mhi_cntrl->pm_state), in __mhi_pm_resume()
904 mhi_state_str(mhi_cntrl->dev_state)); in __mhi_pm_resume()
906 if (mhi_cntrl->pm_state == MHI_PM_DISABLE) in __mhi_pm_resume()
909 if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) in __mhi_pm_resume()
912 if (mhi_get_mhi_state(mhi_cntrl) != MHI_STATE_M3) { in __mhi_pm_resume()
914 mhi_state_str(mhi_get_mhi_state(mhi_cntrl))); in __mhi_pm_resume()
920 list_for_each_entry_safe(itr, tmp, &mhi_cntrl->lpm_chans, node) { in __mhi_pm_resume()
927 write_lock_irq(&mhi_cntrl->pm_lock); in __mhi_pm_resume()
928 cur_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3_EXIT); in __mhi_pm_resume()
930 write_unlock_irq(&mhi_cntrl->pm_lock); in __mhi_pm_resume()
934 to_mhi_pm_state_str(mhi_cntrl->pm_state)); in __mhi_pm_resume()
939 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_M0); in __mhi_pm_resume()
940 write_unlock_irq(&mhi_cntrl->pm_lock); in __mhi_pm_resume()
942 ret = wait_event_timeout(mhi_cntrl->state_event, in __mhi_pm_resume()
943 mhi_cntrl->dev_state == MHI_STATE_M0 || in __mhi_pm_resume()
944 mhi_cntrl->dev_state == MHI_STATE_M2 || in __mhi_pm_resume()
945 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), in __mhi_pm_resume()
946 msecs_to_jiffies(mhi_cntrl->timeout_ms)); in __mhi_pm_resume()
948 if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { in __mhi_pm_resume()
951 mhi_state_str(mhi_cntrl->dev_state), in __mhi_pm_resume()
952 to_mhi_pm_state_str(mhi_cntrl->pm_state)); in __mhi_pm_resume()
959 int mhi_pm_resume(struct mhi_controller *mhi_cntrl) in mhi_pm_resume() argument
961 return __mhi_pm_resume(mhi_cntrl, false); in mhi_pm_resume()
965 int mhi_pm_resume_force(struct mhi_controller *mhi_cntrl) in mhi_pm_resume_force() argument
967 return __mhi_pm_resume(mhi_cntrl, true); in mhi_pm_resume_force()
971 int __mhi_device_get_sync(struct mhi_controller *mhi_cntrl) in __mhi_device_get_sync() argument
976 read_lock_bh(&mhi_cntrl->pm_lock); in __mhi_device_get_sync()
977 if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { in __mhi_device_get_sync()
978 read_unlock_bh(&mhi_cntrl->pm_lock); in __mhi_device_get_sync()
981 mhi_cntrl->wake_get(mhi_cntrl, true); in __mhi_device_get_sync()
982 if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) in __mhi_device_get_sync()
983 mhi_trigger_resume(mhi_cntrl); in __mhi_device_get_sync()
984 read_unlock_bh(&mhi_cntrl->pm_lock); in __mhi_device_get_sync()
986 ret = wait_event_timeout(mhi_cntrl->state_event, in __mhi_device_get_sync()
987 mhi_cntrl->pm_state == MHI_PM_M0 || in __mhi_device_get_sync()
988 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), in __mhi_device_get_sync()
989 msecs_to_jiffies(mhi_cntrl->timeout_ms)); in __mhi_device_get_sync()
991 if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) { in __mhi_device_get_sync()
992 read_lock_bh(&mhi_cntrl->pm_lock); in __mhi_device_get_sync()
993 mhi_cntrl->wake_put(mhi_cntrl, false); in __mhi_device_get_sync()
994 read_unlock_bh(&mhi_cntrl->pm_lock); in __mhi_device_get_sync()
1002 static void mhi_assert_dev_wake(struct mhi_controller *mhi_cntrl, bool force) in mhi_assert_dev_wake() argument
1011 spin_lock_irqsave(&mhi_cntrl->wlock, flags); in mhi_assert_dev_wake()
1012 atomic_inc(&mhi_cntrl->dev_wake); in mhi_assert_dev_wake()
1013 if (MHI_WAKE_DB_FORCE_SET_VALID(mhi_cntrl->pm_state) && in mhi_assert_dev_wake()
1014 !mhi_cntrl->wake_set) { in mhi_assert_dev_wake()
1015 mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 1); in mhi_assert_dev_wake()
1016 mhi_cntrl->wake_set = true; in mhi_assert_dev_wake()
1018 spin_unlock_irqrestore(&mhi_cntrl->wlock, flags); in mhi_assert_dev_wake()
1024 if (likely(atomic_add_unless(&mhi_cntrl->dev_wake, 1, 0))) in mhi_assert_dev_wake()
1027 spin_lock_irqsave(&mhi_cntrl->wlock, flags); in mhi_assert_dev_wake()
1028 if ((atomic_inc_return(&mhi_cntrl->dev_wake) == 1) && in mhi_assert_dev_wake()
1029 MHI_WAKE_DB_SET_VALID(mhi_cntrl->pm_state) && in mhi_assert_dev_wake()
1030 !mhi_cntrl->wake_set) { in mhi_assert_dev_wake()
1031 mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 1); in mhi_assert_dev_wake()
1032 mhi_cntrl->wake_set = true; in mhi_assert_dev_wake()
1034 spin_unlock_irqrestore(&mhi_cntrl->wlock, flags); in mhi_assert_dev_wake()
1039 static void mhi_deassert_dev_wake(struct mhi_controller *mhi_cntrl, in mhi_deassert_dev_wake() argument
1048 if (likely(atomic_add_unless(&mhi_cntrl->dev_wake, -1, 1))) in mhi_deassert_dev_wake()
1051 spin_lock_irqsave(&mhi_cntrl->wlock, flags); in mhi_deassert_dev_wake()
1052 if ((atomic_dec_return(&mhi_cntrl->dev_wake) == 0) && in mhi_deassert_dev_wake()
1053 MHI_WAKE_DB_CLEAR_VALID(mhi_cntrl->pm_state) && !override && in mhi_deassert_dev_wake()
1054 mhi_cntrl->wake_set) { in mhi_deassert_dev_wake()
1055 mhi_write_db(mhi_cntrl, mhi_cntrl->wake_db, 0); in mhi_deassert_dev_wake()
1056 mhi_cntrl->wake_set = false; in mhi_deassert_dev_wake()
1058 spin_unlock_irqrestore(&mhi_cntrl->wlock, flags); in mhi_deassert_dev_wake()
1061 int mhi_async_power_up(struct mhi_controller *mhi_cntrl) in mhi_async_power_up() argument
1063 struct mhi_event *mhi_event = mhi_cntrl->mhi_event; in mhi_async_power_up()
1067 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_async_power_up()
1074 if (!mhi_cntrl->wake_get || !mhi_cntrl->wake_put || in mhi_async_power_up()
1075 !mhi_cntrl->wake_toggle) { in mhi_async_power_up()
1076 mhi_cntrl->wake_get = mhi_assert_dev_wake; in mhi_async_power_up()
1077 mhi_cntrl->wake_put = mhi_deassert_dev_wake; in mhi_async_power_up()
1078 mhi_cntrl->wake_toggle = (mhi_cntrl->db_access & MHI_PM_M2) ? in mhi_async_power_up()
1082 mutex_lock(&mhi_cntrl->pm_mutex); in mhi_async_power_up()
1083 mhi_cntrl->pm_state = MHI_PM_DISABLE; in mhi_async_power_up()
1086 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_async_power_up()
1087 mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); in mhi_async_power_up()
1088 mhi_cntrl->pm_state = MHI_PM_POR; in mhi_async_power_up()
1089 mhi_cntrl->ee = MHI_EE_MAX; in mhi_async_power_up()
1090 current_ee = mhi_get_exec_env(mhi_cntrl); in mhi_async_power_up()
1091 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_async_power_up()
1101 state = mhi_get_mhi_state(mhi_cntrl); in mhi_async_power_up()
1106 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); in mhi_async_power_up()
1107 ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, in mhi_async_power_up()
1118 mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); in mhi_async_power_up()
1122 enable_irq(mhi_cntrl->irq[0]); in mhi_async_power_up()
1124 for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) { in mhi_async_power_up()
1128 enable_irq(mhi_cntrl->irq[mhi_event->irq]); in mhi_async_power_up()
1135 mhi_queue_state_transition(mhi_cntrl, next_state); in mhi_async_power_up()
1137 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_async_power_up()
1144 mhi_cntrl->pm_state = MHI_PM_DISABLE; in mhi_async_power_up()
1145 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_async_power_up()
1151 void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) in mhi_power_down() argument
1154 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_power_down()
1156 mutex_lock(&mhi_cntrl->pm_mutex); in mhi_power_down()
1157 write_lock_irq(&mhi_cntrl->pm_lock); in mhi_power_down()
1158 cur_state = mhi_cntrl->pm_state; in mhi_power_down()
1160 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_power_down()
1161 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_power_down()
1169 cur_state = mhi_tryset_pm_state(mhi_cntrl, transition_state); in mhi_power_down()
1173 to_mhi_pm_state_str(mhi_cntrl->pm_state)); in mhi_power_down()
1175 mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT; in mhi_power_down()
1179 mhi_cntrl->ee = MHI_EE_DISABLE_TRANSITION; in mhi_power_down()
1180 mhi_cntrl->dev_state = MHI_STATE_RESET; in mhi_power_down()
1182 wake_up_all(&mhi_cntrl->state_event); in mhi_power_down()
1184 write_unlock_irq(&mhi_cntrl->pm_lock); in mhi_power_down()
1185 mutex_unlock(&mhi_cntrl->pm_mutex); in mhi_power_down()
1187 mhi_queue_state_transition(mhi_cntrl, DEV_ST_TRANSITION_DISABLE); in mhi_power_down()
1190 flush_work(&mhi_cntrl->st_worker); in mhi_power_down()
1192 disable_irq(mhi_cntrl->irq[0]); in mhi_power_down()
1196 int mhi_sync_power_up(struct mhi_controller *mhi_cntrl) in mhi_sync_power_up() argument
1198 int ret = mhi_async_power_up(mhi_cntrl); in mhi_sync_power_up()
1203 wait_event_timeout(mhi_cntrl->state_event, in mhi_sync_power_up()
1204 MHI_IN_MISSION_MODE(mhi_cntrl->ee) || in mhi_sync_power_up()
1205 MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), in mhi_sync_power_up()
1206 msecs_to_jiffies(mhi_cntrl->timeout_ms)); in mhi_sync_power_up()
1208 ret = (MHI_IN_MISSION_MODE(mhi_cntrl->ee)) ? 0 : -ETIMEDOUT; in mhi_sync_power_up()
1210 mhi_power_down(mhi_cntrl, false); in mhi_sync_power_up()
1216 int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) in mhi_force_rddm_mode() argument
1218 struct device *dev = &mhi_cntrl->mhi_dev->dev; in mhi_force_rddm_mode()
1222 if (mhi_cntrl->ee == MHI_EE_RDDM) in mhi_force_rddm_mode()
1226 mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR); in mhi_force_rddm_mode()
1229 ret = wait_event_timeout(mhi_cntrl->state_event, in mhi_force_rddm_mode()
1230 mhi_cntrl->ee == MHI_EE_RDDM, in mhi_force_rddm_mode()
1231 msecs_to_jiffies(mhi_cntrl->timeout_ms)); in mhi_force_rddm_mode()
1240 struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; in mhi_device_get() local
1243 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_device_get()
1244 if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) in mhi_device_get()
1245 mhi_trigger_resume(mhi_cntrl); in mhi_device_get()
1247 mhi_cntrl->wake_get(mhi_cntrl, true); in mhi_device_get()
1248 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_device_get()
1254 struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; in mhi_device_get_sync() local
1257 ret = __mhi_device_get_sync(mhi_cntrl); in mhi_device_get_sync()
1267 struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; in mhi_device_put() local
1270 read_lock_bh(&mhi_cntrl->pm_lock); in mhi_device_put()
1271 if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) in mhi_device_put()
1272 mhi_trigger_resume(mhi_cntrl); in mhi_device_put()
1274 mhi_cntrl->wake_put(mhi_cntrl, false); in mhi_device_put()
1275 read_unlock_bh(&mhi_cntrl->pm_lock); in mhi_device_put()