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;
}