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

Commit b63aeed8 authored by Raghavendra Rao Ananta's avatar Raghavendra Rao Ananta Committed by Rishabh Bhatnagar
Browse files

esoc: Check for modem status LOW prior to error handling



With the check for the modem status to come LOW, the APQ
could be sure that the modem has not landed into any other
problems on its way to the debug path. Currently, we wait
for the modem status to come LOW only for the situation
where the APQ panics. However, this check is also needed
when the modem panics. The necessary action to handle the
crash is now placed after the check is done.

Change-Id: I16cf1e3a4fdacd1fc98c6f2ec6173de7ea22933a
Signed-off-by: default avatarRaghavendra Rao Ananta <rananta@codeaurora.org>
Signed-off-by: default avatarVenkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>
parent 38087921
Loading
Loading
Loading
Loading
+24 −25
Original line number Diff line number Diff line
@@ -389,11 +389,32 @@ static void mdm_get_restart_reason(struct work_struct *work)
	mdm->get_restart_reason = false;
}

static void mdm_notify(enum esoc_notify notify, struct esoc_clink *esoc)
void mdm_wait_for_status_low(struct mdm_ctrl *mdm)
{
	bool status_down;
	uint64_t timeout;
	uint64_t now;

	esoc_mdm_log("Waiting for MDM2AP_STATUS to go LOW\n");
	timeout = local_clock();
	do_div(timeout, NSEC_PER_MSEC);
	timeout += MDM_MODEM_TIMEOUT;
	do {
		if (gpio_get_value(MDM_GPIO(mdm, MDM2AP_STATUS)) == 0) {
			esoc_mdm_log("MDM2AP_STATUS went LOW\n");
			return;
		}
		now = local_clock();
		do_div(now, NSEC_PER_MSEC);
	} while (!time_after64(now, timeout));

	esoc_mdm_log("MDM2AP_STATUS didn't go LOW. Warm-resetting modem\n");
	dev_err(mdm->dev, "MDM2AP status did not go low\n");

	mdm_toggle_soft_reset(mdm, true);
}

static void mdm_notify(enum esoc_notify notify, struct esoc_clink *esoc)
{
	struct mdm_ctrl *mdm = get_esoc_clink_data(esoc);
	struct device *dev = mdm->dev;

@@ -449,35 +470,13 @@ static void mdm_notify(enum esoc_notify notify, struct esoc_clink *esoc)
		break;
	case ESOC_PRIMARY_CRASH:
		mdm_disable_irqs(mdm);
		status_down = false;
		dev_dbg(dev, "signal apq err fatal for graceful restart\n");
		esoc_mdm_log(
		"ESOC_PRIMARY_CRASH: Setting AP2MDM_ERRFATAL = 1\n");
		gpio_set_value(MDM_GPIO(mdm, AP2MDM_ERRFATAL), 1);
		if (esoc->primary)
			break;
		esoc_mdm_log(
		"ESOC_PRIMARY_CRASH: Waiting for MDM2AP_STATUS to go LOW\n");
		timeout = local_clock();
		do_div(timeout, NSEC_PER_MSEC);
		timeout += MDM_MODEM_TIMEOUT;
		do {
			if (gpio_get_value(MDM_GPIO(mdm,
						MDM2AP_STATUS)) == 0) {
				status_down = true;
				break;
			}
			now = local_clock();
			do_div(now, NSEC_PER_MSEC);
		} while (!time_after64(now, timeout));

		if (!status_down) {
			esoc_mdm_log(
	"ESOC_PRIMARY_CRASH: MDM2AP_STATUS didn't go LOW. Resetting modem\n");
			dev_err(mdm->dev, "%s MDM2AP status did not go low\n",
								__func__);
			mdm_toggle_soft_reset(mdm, true);
		}
		mdm_wait_for_status_low(mdm);
		break;
	case ESOC_PRIMARY_REBOOT:
		mdm_disable_irqs(mdm);
+3 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ static void mdm_handle_clink_evt(enum esoc_evt evt,
					struct esoc_eng *eng)
{
	struct mdm_drv *mdm_drv = to_mdm_drv(eng);
	struct mdm_ctrl *mdm;
	bool unexpected_state = false;

	switch (evt) {
@@ -130,6 +131,8 @@ static void mdm_handle_clink_evt(enum esoc_evt evt,
		if (mdm_drv->mode == CRASH || mdm_drv->mode != RUN)
			return;
		mdm_drv->mode = CRASH;
		mdm = get_esoc_clink_data(mdm_drv->esoc_clink);
		mdm_wait_for_status_low(mdm);
		esoc_mdm_log("Starting SSR work\n");
		queue_work(mdm_drv->mdm_queue, &mdm_drv->ssr_work);
		break;
+1 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ struct mdm_ops {
};

void mdm_disable_irqs(struct mdm_ctrl *mdm);
void mdm_wait_for_status_low(struct mdm_ctrl *mdm);

static inline int mdm_toggle_soft_reset(struct mdm_ctrl *mdm, bool atomic)
{