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

Commit 0d892007 authored by Rishabh Bhatnagar's avatar Rishabh Bhatnagar
Browse files

esoc: Service error fatal interrupt in BOOT and RUN mode



Start monitoring the error fatal interrupts after modem status
goes high. If we observe errfatal before modem is completely
up wait till mdm-helper returns BOOT_DONE/FAIL/RETRY to trigger
SSR.

Change-Id: Iecbe7870dd85831189830bf565a24738cfb5e373
Signed-off-by: default avatarRishabh Bhatnagar <rishabhb@codeaurora.org>
parent 39d484be
Loading
Loading
Loading
Loading
+25 −17
Original line number Diff line number Diff line
@@ -28,20 +28,21 @@ enum esoc_pon_state {

enum {
	 PWR_OFF = 0x1,
	 PWR_ON,
	 BOOT,
	 RUN,
	 CRASH,
	 IN_DEBUG,
	 SHUTDOWN,
	 RESET,
	 PEER_CRASH,
	 IN_DEBUG,
	 CRASH,
	 PWR_ON,
	 BOOT,
	 RUN,
};

struct mdm_drv {
	unsigned int mode;
	struct esoc_eng cmd_eng;
	struct completion pon_done;
	struct completion ssr_ready;
	struct completion req_eng_wait;
	struct esoc_clink *esoc_clink;
	enum esoc_pon_state pon_state;
@@ -142,6 +143,7 @@ static void mdm_handle_clink_evt(enum esoc_evt evt,
		"ESOC_INVALID_STATE: Calling complete with state: PON_FAIL\n");
		mdm_drv->pon_state = PON_FAIL;
		complete(&mdm_drv->pon_done);
		complete(&mdm_drv->ssr_ready);
		break;
	case ESOC_BOOT_STATE:
		if (mdm_drv->mode == PWR_OFF) {
@@ -156,12 +158,14 @@ static void mdm_handle_clink_evt(enum esoc_evt evt,
		mdm_drv->pon_state = PON_SUCCESS;
		mdm_drv->mode = RUN,
		complete(&mdm_drv->pon_done);
		complete(&mdm_drv->ssr_ready);
		break;
	case ESOC_RETRY_PON_EVT:
		esoc_mdm_log(
		"ESOC_RETRY_PON_EVT: Calling complete with state: PON_RETRY\n");
		mdm_drv->pon_state = PON_RETRY;
		complete(&mdm_drv->pon_done);
		complete(&mdm_drv->ssr_ready);
		break;
	case ESOC_UNEXPECTED_RESET:
		esoc_mdm_log("evt_state: ESOC_UNEXPECTED_RESET\n");
@@ -171,19 +175,14 @@ static void mdm_handle_clink_evt(enum esoc_evt evt,
			esoc_mdm_log("evt_state: ESOC_ERR_FATAL\n");

		/*
		 * Modem can crash while we are waiting for pon_done during
		 * a subsystem_get(). Setting mode to CRASH will prevent a
		 * subsequent subsystem_get() from entering poweron ops. Avoid
		 * this by seting mode to CRASH only if device was up and
		 * running.
		 * Ignore all modem errfatals if the status is not up
		 * or modem in run state.
		 */
		if (mdm_drv->mode == CRASH)
		if (mdm_drv->mode <= CRASH) {
			esoc_mdm_log(
			"Modem in crash state already. Ignoring.\n");
		if (mdm_drv->mode != RUN)
			esoc_mdm_log("Modem not up. Ignoring.\n");
		if (mdm_drv->mode == CRASH || mdm_drv->mode != RUN)
			"Modem in crash state or not booted. Ignoring.\n");
			return;
		}
		queue_work(mdm_drv->mdm_queue, &mdm_drv->ssr_work);
		break;
	case ESOC_REQ_ENG_ON:
@@ -201,10 +200,15 @@ static void mdm_ssr_fn(struct work_struct *work)
	struct mdm_drv *mdm_drv = container_of(work, struct mdm_drv, ssr_work);
	struct mdm_ctrl *mdm = get_esoc_clink_data(mdm_drv->esoc_clink);

	esoc_client_link_mdm_crash(mdm_drv->esoc_clink);
	/* Wait for pon to complete. Start SSR only if pon is success */
	wait_for_completion(&mdm_drv->ssr_ready);
	if (mdm_drv->pon_state != PON_SUCCESS) {
		esoc_mdm_log("Got errfatal but ignoring as boot failed\n");
		return;
	}

	esoc_client_link_mdm_crash(mdm_drv->esoc_clink);
	mdm_wait_for_status_low(mdm, false);

	esoc_mdm_log("Starting SSR work and setting crash state\n");
	mdm_drv->mode = CRASH;

@@ -367,7 +371,9 @@ static void mdm_subsys_retry_powerup_cleanup(struct esoc_clink *esoc_clink,
	esoc_client_link_power_off(esoc_clink, poff_flags);
	mdm_disable_irqs(mdm);
	mdm_drv->pon_state = PON_INIT;
	mdm_drv->mode = PWR_OFF;
	reinit_completion(&mdm_drv->pon_done);
	reinit_completion(&mdm_drv->ssr_ready);
	reinit_completion(&mdm_drv->req_eng_wait);
}

@@ -415,6 +421,7 @@ static int mdm_handle_boot_fail(struct esoc_clink *esoc_clink, u8 *pon_trial)
		break;
	case BOOT_FAIL_ACTION_NOP:
		esoc_mdm_log("Leaving the modem in its curent state\n");
		mdm_drv->mode = PWR_OFF;
		return -EIO;
	case BOOT_FAIL_ACTION_SHUTDOWN:
	default:
@@ -578,6 +585,7 @@ int esoc_ssr_probe(struct esoc_clink *esoc_clink, struct esoc_drv *drv)
	}
	esoc_set_drv_data(esoc_clink, mdm_drv);
	init_completion(&mdm_drv->pon_done);
	init_completion(&mdm_drv->ssr_ready);
	init_completion(&mdm_drv->req_eng_wait);
	INIT_WORK(&mdm_drv->ssr_work, mdm_ssr_fn);
	mdm_drv->esoc_clink = esoc_clink;