static void start_link_pm(struct modem_link_pm *pm, enum pm_event event) { int cp2ap_wakeup; int cp2ap_status; enum pm_state state; unsigned long flags; spin_lock_irqsave(&pm->lock, flags); if (pm->active) { mif_err("%s: PM is already ACTIVE\n", pm->link_name); goto exit; } lock_pm_wake(pm); if (event == PM_EVENT_LOCK_ON) { state = PM_STATE_LOCKED_ON; assert_ap2cp_wakeup(pm); assert_ap2cp_status(pm); } else if (event == PM_EVENT_CP_BOOTING) { state = PM_STATE_CP_BOOTING; assert_ap2cp_wakeup(pm); assert_ap2cp_status(pm); } else { state = PM_STATE_UNMOUNTED; release_ap2cp_wakeup(pm); release_ap2cp_status(pm); } /* Enable every CP-to-AP IRQ and set it as a wake-up source */ cp2ap_wakeup = gpio_get_value(pm->gpio_cp2ap_wakeup); change_irq_level(pm->cp2ap_wakeup_irq.num, cp2ap_wakeup); mif_enable_irq(&pm->cp2ap_wakeup_irq); cp2ap_status = gpio_get_value(pm->gpio_cp2ap_status); change_irq_level(pm->cp2ap_status_irq.num, cp2ap_status); mif_enable_irq(&pm->cp2ap_status_irq); set_pm_fsm(pm, PM_STATE_UNMOUNTED, state, event); pm->hold_requested = false; pm->active = true; #ifdef DEBUG_MODEM_IF print_pm_fsm(pm); #endif exit: spin_unlock_irqrestore(&pm->lock, flags); }
static inline void decide_pm_wake(struct modem_link_pm *pm, enum pm_state c_state, enum pm_state n_state) { if (n_state == c_state) return; switch (n_state) { case PM_STATE_UNMOUNTED: unlock_pm_wake(pm); break; case PM_STATE_ACTIVE: lock_pm_wake(pm); break; default: break; } }
static inline void prepare_mount(struct modem_link_pm *pm) { lock_pm_wake(pm); forbid_link_suspend(pm); }