MHI_STATUS process_READY_transition(mhi_device_ctxt *mhi_dev_ctxt, STATE_TRANSITION cur_work_item) { MHI_STATUS ret_val = MHI_STATUS_SUCCESS; mhi_log(MHI_MSG_INFO, "Processing READY state transition\n"); mhi_dev_ctxt->mhi_state = MHI_STATE_READY; ret_val = mhi_reset_all_thread_queues(mhi_dev_ctxt); if (MHI_STATUS_SUCCESS != ret_val) mhi_log(MHI_MSG_ERROR, "Failed to reset thread queues\n"); /* Initialize MMIO */ if (MHI_STATUS_SUCCESS != mhi_init_mmio(mhi_dev_ctxt)) { mhi_log(MHI_MSG_ERROR, "Failure during MMIO initialization\n"); return MHI_STATUS_ERROR; } ret_val = mhi_add_elements_to_event_rings(mhi_dev_ctxt, cur_work_item); if (MHI_STATUS_SUCCESS != ret_val) { mhi_log(MHI_MSG_ERROR, "Failure during event ring init\n"); return MHI_STATUS_ERROR; } mhi_reg_write_field(mhi_dev_ctxt->mmio_addr, MHICTRL, MHICTRL_MHISTATE_MASK, MHICTRL_MHISTATE_SHIFT, MHI_STATE_M0); return MHI_STATUS_SUCCESS; }
static enum MHI_STATUS process_amss_transition( struct mhi_device_ctxt *mhi_dev_ctxt, enum STATE_TRANSITION cur_work_item) { enum MHI_STATUS ret_val; struct mhi_client_handle *client_handle = NULL; int i = 0; mhi_log(MHI_MSG_INFO, "Processing AMSS state transition\n"); mhi_dev_ctxt->dev_exec_env = MHI_EXEC_ENV_AMSS; atomic_inc(&mhi_dev_ctxt->flags.data_pending); mhi_assert_device_wake(mhi_dev_ctxt); if (0 == mhi_dev_ctxt->flags.mhi_initialized) { ret_val = mhi_add_elements_to_event_rings(mhi_dev_ctxt, cur_work_item); if (MHI_STATUS_SUCCESS != ret_val) return MHI_STATUS_ERROR; mhi_dev_ctxt->flags.mhi_initialized = 1; if (MHI_STATUS_SUCCESS != ret_val) mhi_log(MHI_MSG_CRITICAL, "Failed to set local chan state\n"); ring_all_chan_dbs(mhi_dev_ctxt); mhi_log(MHI_MSG_INFO, "Notifying clients that MHI is enabled\n"); if (ret_val != MHI_STATUS_SUCCESS) mhi_log(MHI_MSG_CRITICAL, "Failed to probe MHI CORE clients, ret 0x%x\n", ret_val); enable_clients(mhi_dev_ctxt, mhi_dev_ctxt->dev_exec_env); } else { mhi_log(MHI_MSG_INFO, "MHI is initialized\n"); for (i = 0; i < MHI_MAX_CHANNELS; ++i) { client_handle = mhi_dev_ctxt->client_handle_list[i]; if (client_handle && client_handle->chan_status) ret_val = start_chan_sync(client_handle); if (ret_val) mhi_log(MHI_MSG_ERROR, "Failed to start chan %d ret %d\n", i, ret_val); } ring_all_chan_dbs(mhi_dev_ctxt); } atomic_dec(&mhi_dev_ctxt->flags.data_pending); if (!mhi_dev_ctxt->flags.pending_M3 && mhi_dev_ctxt->flags.link_up) mhi_deassert_device_wake(mhi_dev_ctxt); mhi_log(MHI_MSG_INFO, "Exited\n"); return MHI_STATUS_SUCCESS; }
MHI_STATUS process_AMSS_transition(mhi_device_ctxt *mhi_dev_ctxt, STATE_TRANSITION cur_work_item) { MHI_STATUS ret_val; u32 chan; unsigned long flags; mhi_chan_ctxt *chan_ctxt; mhi_log(MHI_MSG_INFO, "Processing AMSS state transition\n"); write_lock_irqsave(&mhi_dev_ctxt->xfer_lock, flags); atomic_inc(&mhi_dev_ctxt->flags.data_pending); mhi_assert_device_wake(mhi_dev_ctxt); write_unlock_irqrestore(&mhi_dev_ctxt->xfer_lock, flags); ret_val = mhi_add_elements_to_event_rings(mhi_dev_ctxt, cur_work_item); if (MHI_STATUS_SUCCESS != ret_val) return MHI_STATUS_ERROR; for (chan = 0; chan <= MHI_MAX_CHANNELS; ++chan) { if (VALID_CHAN_NR(chan)) { chan_ctxt = &mhi_dev_ctxt->mhi_ctrl_seg->mhi_cc_list[chan]; if (MHI_CHAN_STATE_ENABLED == chan_ctxt->mhi_chan_state) { mhi_log(MHI_MSG_INFO, "Starting Channel 0x%x \n", chan); ret_val = mhi_send_cmd(mhi_dev_ctxt, MHI_COMMAND_START_CHAN, chan); if (MHI_STATUS_SUCCESS != ret_val) { mhi_log(MHI_MSG_CRITICAL, "Failed to start chan0x%x,0x%x\n", chan, ret_val); return MHI_STATUS_ERROR; } else { atomic_inc( &mhi_dev_ctxt->start_cmd_pending_ack); } } } } mhi_log(MHI_MSG_INFO, "Waiting for cmd completions\n"); wait_event_interruptible(*mhi_dev_ctxt->chan_start_complete, atomic_read(&mhi_dev_ctxt->start_cmd_pending_ack) == 0); if (0 == mhi_dev_ctxt->flags.mhi_initialized) { mhi_dev_ctxt->flags.mhi_initialized = 1; ret_val = mhi_set_state_of_all_channels(mhi_dev_ctxt, MHI_CHAN_STATE_RUNNING); if (MHI_STATUS_SUCCESS != ret_val) mhi_log(MHI_MSG_CRITICAL, "Failed to set local chan state\n"); if (!mhi_dev_ctxt->flags.mhi_clients_probed) { ret_val = probe_clients(mhi_dev_ctxt, cur_work_item); if (ret_val != MHI_STATUS_SUCCESS) mhi_log(MHI_MSG_CRITICAL, "Failed to probe MHI CORE clients.\n"); mhi_dev_ctxt->flags.mhi_clients_probed = 1; ring_all_ev_dbs(mhi_dev_ctxt); ring_all_chan_dbs(mhi_dev_ctxt); ring_all_cmd_dbs(mhi_dev_ctxt); } else { ring_all_chan_dbs(mhi_dev_ctxt); mhi_log(MHI_MSG_CRITICAL, "Notifying clients that MHI is enabled\n"); mhi_notify_clients(mhi_dev_ctxt, MHI_CB_MHI_ENABLED); } if (ret_val != MHI_STATUS_SUCCESS) mhi_log(MHI_MSG_CRITICAL, "Failed to probe MHI CORE clients, ret 0x%x \n", ret_val); } atomic_dec(&mhi_dev_ctxt->flags.data_pending); mhi_log(MHI_MSG_INFO, "Exited\n"); return MHI_STATUS_SUCCESS; }