Loading drivers/esoc/esoc-mdm-4x.c +1 −0 Original line number Diff line number Diff line Loading @@ -556,6 +556,7 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id) cancel_delayed_work(&mdm->mdm2ap_status_check_work); dev_dbg(dev, "status = 1: mdm is now ready\n"); mdm->ready = true; esoc_clink_evt_notify(ESOC_BOOT_STATE, esoc); mdm_trigger_dbg(mdm); queue_work(mdm->mdm_queue, &mdm->mdm_status_work); if (mdm->get_restart_reason) Loading drivers/esoc/esoc-mdm-drv.c +32 −17 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -142,6 +143,14 @@ 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) { esoc_mdm_log( "ESOC_BOOT_STATE: Observed status high from modem.\n"); mdm_drv->mode = BOOT; } break; case ESOC_RUN_STATE: esoc_mdm_log( Loading @@ -149,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"); Loading @@ -164,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: Loading @@ -194,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; Loading Loading @@ -360,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); } Loading Loading @@ -408,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: Loading Loading @@ -571,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; Loading include/uapi/linux/esoc_ctrl.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef _UAPI_ESOC_CTRL_H_ #define _UAPI_ESOC_CTRL_H_ Loading Loading @@ -57,6 +57,7 @@ enum esoc_evt { ESOC_CMD_ENG_OFF, ESOC_INVALID_STATE, ESOC_RETRY_PON_EVT, ESOC_BOOT_STATE, }; enum esoc_cmd { Loading Loading
drivers/esoc/esoc-mdm-4x.c +1 −0 Original line number Diff line number Diff line Loading @@ -556,6 +556,7 @@ static irqreturn_t mdm_status_change(int irq, void *dev_id) cancel_delayed_work(&mdm->mdm2ap_status_check_work); dev_dbg(dev, "status = 1: mdm is now ready\n"); mdm->ready = true; esoc_clink_evt_notify(ESOC_BOOT_STATE, esoc); mdm_trigger_dbg(mdm); queue_work(mdm->mdm_queue, &mdm->mdm_status_work); if (mdm->get_restart_reason) Loading
drivers/esoc/esoc-mdm-drv.c +32 −17 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -142,6 +143,14 @@ 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) { esoc_mdm_log( "ESOC_BOOT_STATE: Observed status high from modem.\n"); mdm_drv->mode = BOOT; } break; case ESOC_RUN_STATE: esoc_mdm_log( Loading @@ -149,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"); Loading @@ -164,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: Loading @@ -194,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; Loading Loading @@ -360,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); } Loading Loading @@ -408,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: Loading Loading @@ -571,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; Loading
include/uapi/linux/esoc_ctrl.h +2 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. */ #ifndef _UAPI_ESOC_CTRL_H_ #define _UAPI_ESOC_CTRL_H_ Loading Loading @@ -57,6 +57,7 @@ enum esoc_evt { ESOC_CMD_ENG_OFF, ESOC_INVALID_STATE, ESOC_RETRY_PON_EVT, ESOC_BOOT_STATE, }; enum esoc_cmd { Loading