Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7315fe8c authored by Siddartha Mohanadoss's avatar Siddartha Mohanadoss
Browse files

msm: mhi_dev: Add reset command support



The modem host driver can issue a reset command to
the device on scenarios such as uninstalling the
host driver components on fatal error detection.
The host issues a reset to the device to indicate
the host driver is uninstalling and preparing to
reinitialize the MHI (modem host interface) driver
on the host. The device prepares the channels to
stop sending data and sends completion command to
the host.

Change-Id: Ic0b86e1521247b8d11c2f5d3b9068ca990d99a63
Signed-off-by: default avatarSiddartha Mohanadoss <smohanad@codeaurora.org>
parent 1a5123de
Loading
Loading
Loading
Loading
+56 −14
Original line number Diff line number Diff line
@@ -352,6 +352,7 @@ static int mhi_hwc_chcmd(struct mhi_dev *mhi, uint chid,
	memset(&connect_params, 0, sizeof(connect_params));

	switch (type) {
	case MHI_DEV_RING_EL_RESET:
	case MHI_DEV_RING_EL_STOP:
		rc = ipa_mhi_disconnect_pipe(
			mhi->ipa_clnt_hndl[chid-HW_CHANNEL_BASE]);
@@ -651,9 +652,9 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
	union mhi_dev_ring_element_type event;
	struct mhi_addr host_addr;

	mhi_log(MHI_MSG_ERROR, "for channel:%d and cmd:%d\n",
		ch_id, el->generic.type);
	ch_id = el->generic.chid;
	mhi_log(MHI_MSG_VERBOSE, "for channel:%d and cmd:%d\n",
		ch_id, el->generic.type);

	switch (el->generic.type) {
	case MHI_DEV_RING_EL_START:
@@ -710,6 +711,9 @@ send_start_completion_event:

		break;
	case MHI_DEV_RING_EL_STOP:
		mhi_log(MHI_MSG_VERBOSE, "recived stop cmd for channel %d\n",
								ch_id);

		if (ch_id >= HW_CHANNEL_BASE) {
			rc = mhi_hwc_chcmd(mhi, ch_id, el->generic.type);
			if (rc) {
@@ -755,9 +759,46 @@ send_start_completion_event:
		}
		break;
	case MHI_DEV_RING_EL_RESET:
		mhi_log(MHI_MSG_VERBOSE,
			"received reset cmd for channel %d\n", ch_id);
		if (ch_id >= HW_CHANNEL_BASE) {
			rc = mhi_hwc_chcmd(mhi, ch_id, el->generic.type);
			if (rc) {
				mhi_log(MHI_MSG_VERBOSE,
					"send channel stop cmd event failed\n");
				return;
			}

			/* send the completion event to the host */
			event.evt_cmd_comp.ptr = mhi->cmd_ctx_cache->rbase +
				(mhi->ring[MHI_RING_CMD_ID].rd_offset *
				(sizeof(union mhi_dev_ring_element_type)));
			event.evt_cmd_comp.type =
					MHI_DEV_RING_EL_CMD_COMPLETION_EVT;
			if (rc == 0)
				event.evt_cmd_comp.code =
					MHI_CMD_COMPL_CODE_SUCCESS;
			else
				event.evt_cmd_comp.code =
					MHI_CMD_COMPL_CODE_UNDEFINED;

			rc = mhi_dev_send_event(mhi, 0, &event);
			if (rc) {
				pr_err("stop event send failed\n");
				return;
			}
		} else {

			mhi_log(MHI_MSG_VERBOSE,
					"received reset cmd for channel %d\n",
					ch_id);

			/* hard stop and set the channel to stop */
		mhi->ch_ctx_cache[ch_id].ch_state = MHI_DEV_CH_STATE_STOP;
		host_addr.host_pa = mhi->ch_ctx_shadow.host_pa +
			mhi->ch_ctx_cache[ch_id].ch_state =
						MHI_DEV_CH_STATE_STOP;
			host_addr.device_va = mhi->ch_ctx_shadow.device_va +
				sizeof(struct mhi_dev_ch_ctx)*ch_id;
			host_addr.device_pa = mhi->ch_ctx_shadow.device_pa +
				sizeof(struct mhi_dev_ch_ctx)*ch_id;

			/* update the channel state in the host */
@@ -769,6 +810,7 @@ send_start_completion_event:
			rc = mhi_dev_send_cmd_comp_event(mhi);
			if (rc)
				pr_err("Error sending command completion event\n");
		}
		break;
	default:
		pr_err("%s: Invalid command:%d\n", __func__, el->generic.type);