int mhi_resume(struct pci_dev *pcie_dev) { int r = 0; mhi_device_ctxt *mhi_dev_ctxt = *(mhi_device_ctxt **)((pcie_dev->dev).platform_data); mhi_log(MHI_MSG_ERROR, "[%s]\n", __func__); r = mhi_initiate_m0(mhi_dev_ctxt); if (r) goto exit; r = wait_event_interruptible_timeout(*mhi_dev_ctxt->M0_event, mhi_dev_ctxt->mhi_state == MHI_STATE_M0 || mhi_dev_ctxt->mhi_state == MHI_STATE_M1, msecs_to_jiffies(MHI_MAX_SUSPEND_TIMEOUT)); switch(r) { case 0: mhi_log(MHI_MSG_CRITICAL | MHI_DBG_POWER, "Timeout: No M0 event after %d ms\n", MHI_MAX_SUSPEND_TIMEOUT); mhi_dev_ctxt->counters.m0_event_timeouts++; r = -ETIME; break; case -ERESTARTSYS: mhi_log(MHI_MSG_CRITICAL | MHI_DBG_POWER, "Going Down...\n"); break; default: mhi_log(MHI_MSG_INFO | MHI_DBG_POWER, "Wait complete state: %d\n", mhi_dev_ctxt->mhi_state); r = 0; } exit: atomic_set(&mhi_dev_ctxt->flags.pending_resume, 0); return r; }
void m0_work(struct work_struct *work) { mhi_device_ctxt *mhi_dev_ctxt = container_of(work, mhi_device_ctxt, m0_work); if (!atomic_read(&mhi_dev_ctxt->flags.pending_resume)) { mhi_log(MHI_MSG_INFO, "No pending resume, initiating M0.\n"); mhi_initiate_m0(mhi_dev_ctxt); } else { mhi_log(MHI_MSG_INFO, "Pending resume, quitting.\n"); } }
ssize_t sysfs_init_M0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { mhi_device_ctxt *mhi_dev_ctxt = mhi_devices.device_list[0].mhi_ctxt; if (MHI_STATUS_SUCCESS != mhi_turn_on_pcie_link(mhi_dev_ctxt)) { mhi_log(MHI_MSG_CRITICAL | MHI_DBG_POWER, "Failed to resume link\n"); return count; } mhi_initiate_m0(mhi_dev_ctxt); mhi_log(MHI_MSG_CRITICAL | MHI_DBG_POWER, "Current mhi_state = 0x%x\n", mhi_dev_ctxt->mhi_state); return count; }
MHI_STATUS process_WAKE_transition(mhi_device_ctxt *mhi_dev_ctxt, STATE_TRANSITION cur_work_item) { MHI_STATUS ret_val = MHI_STATUS_SUCCESS; mhi_log(MHI_MSG_INFO, "Entered\n"); __pm_stay_awake(&mhi_dev_ctxt->wake_lock); ret_val = mhi_turn_on_pcie_link(mhi_dev_ctxt); if (MHI_STATUS_SUCCESS != ret_val) { mhi_log(MHI_MSG_CRITICAL, "Failed to turn on PCIe link.\n"); goto exit; } mhi_dev_ctxt->flags.stop_threads = 0; if (mhi_dev_ctxt->flags.mhi_initialized && mhi_dev_ctxt->flags.link_up) { mhi_log(MHI_MSG_CRITICAL, "MHI is initialized, transitioning to M0.\n"); mhi_initiate_m0(mhi_dev_ctxt); } if (!mhi_dev_ctxt->flags.mhi_initialized) { mhi_log(MHI_MSG_CRITICAL, "MHI is not initialized transitioning to base.\n"); ret_val = init_mhi_base_state(mhi_dev_ctxt); if (MHI_STATUS_SUCCESS != ret_val) mhi_log(MHI_MSG_CRITICAL, "Failed to transition to base state %d.\n", ret_val); } exit: mhi_log(MHI_MSG_INFO, "Exited.\n"); __pm_relax(&mhi_dev_ctxt->wake_lock); return ret_val; }