/** @brief finalize handling the PHONE_START command from CP @param mld the pointer to a mem_link_device instance */ static void finalize_cp_start(struct mem_link_device *mld) { int ap_wakeup = gpio_get_value(mld->gpio_ap_wakeup); int cp_status = gpio_get_value(mld->gpio_cp_status); change_irq_type(mld->irq_ap_wakeup.num, ap_wakeup); change_irq_type(mld->irq_cp_status.num, cp_status); if (ap_wakeup) { if (wake_lock_active(&mld->ap_wlock)) wake_lock(&mld->ap_wlock); } else { if (wake_lock_active(&mld->ap_wlock)) wake_unlock(&mld->ap_wlock); } if (cp_status) { if (!wake_lock_active(&mld->ap_wlock)) wake_lock(&mld->cp_wlock); } else { if (wake_lock_active(&mld->ap_wlock)) wake_unlock(&mld->cp_wlock); } print_pm_status(mld); }
static irqreturn_t cp_status_handler(int irq, void *data) { struct mem_link_device *mld = (struct mem_link_device *)data; struct link_device *ld = &mld->link_dev; struct modem_ctl *mc = ld->mc; int cp_status = gpio_get_value(mld->gpio_cp_status); unsigned long flags; spin_lock_irqsave(&mld->pm_lock, flags); change_irq_type(irq, cp_status); if (!cp_online(mc)) goto exit; if (cp_status) { if (!wake_lock_active(&mld->cp_wlock)) wake_lock(&mld->cp_wlock); } else { gpio_set_value(mld->gpio_ap_status, 0); if (wake_lock_active(&mld->cp_wlock)) wake_unlock(&mld->cp_wlock); } exit: print_pm_status(mld); spin_unlock_irqrestore(&mld->pm_lock, flags); return IRQ_HANDLED; }
static void start_pm(struct mem_link_device *mld) { if (pm_enable) { int ap_wakeup = gpio_get_value(mld->gpio_ap_wakeup); int cp_status = gpio_get_value(mld->gpio_cp_status); print_pm_status(mld); change_irq_type(mld->irq_ap_wakeup.num, ap_wakeup); mif_enable_irq(&mld->irq_ap_wakeup); change_irq_type(mld->irq_cp_status.num, cp_status); mif_enable_irq(&mld->irq_cp_status); } else { wake_lock(&mld->ap_wlock); } }
/** @brief interrupt handler for a wakeup interrupt 1) Reads the interrupt value\n 2) Performs interrupt handling\n @param irq the IRQ number @param data the pointer to a data */ static irqreturn_t ap_wakeup_interrupt(int irq, void *data) { struct mem_link_device *mld = (struct mem_link_device *)data; int ap_wakeup = gpio_get_value(mld->gpio_ap_wakeup); int cp_wakeup = gpio_get_value(mld->gpio_cp_wakeup); int cpu = raw_smp_processor_id(); change_irq_type(irq, ap_wakeup); if (work_pending(&mld->cp_sleep_dwork.work)) cancel_delayed_work(&mld->cp_sleep_dwork); if (ap_wakeup) { mld->last_cp2ap_intr = cpu_clock(cpu); if (!cp_wakeup) gpio_set_value(mld->gpio_cp_wakeup, 1); if (!wake_lock_active(&mld->ap_wlock)) wake_lock(&mld->ap_wlock); if (mipi_lli_get_link_status() == LLI_UNMOUNTED) mipi_lli_set_link_status(LLI_WAITFORMOUNT); if (!mipi_lli_suspended()) gpio_set_value(mld->gpio_ap_status, 1); } else { if (wake_lock_active(&mld->ap_wlock)) wake_unlock(&mld->ap_wlock); if (mipi_lli_get_link_status() & LLI_WAITFORMOUNT) mipi_lli_set_link_status(LLI_UNMOUNTED); queue_delayed_work(system_nrt_wq, &mld->cp_sleep_dwork, msecs_to_jiffies(sleep_timeout)); } print_pm_status(mld); return IRQ_HANDLED; }