static void mdm_crash_dump_dbg_info(void) { dump_mdm_related_gpio(); printk(KERN_INFO "=== Show qcks stack ===\n"); show_thread_group_state_filter("qcks", 0); printk(KERN_INFO "\n"); printk(KERN_INFO "=== Show efsks stack ===\n"); show_thread_group_state_filter("efsks", 0); printk(KERN_INFO "\n"); printk(KERN_INFO "=== Show ks stack ===\n"); show_thread_group_state_filter("ks", 0); printk(KERN_INFO "\n"); pr_info("### Show Blocked State in ###\n"); show_state_filter(TASK_UNINTERRUPTIBLE); if (get_restart_level() == RESET_SOC) msm_rtb_disable(); if (get_restart_level() == RESET_SOC) set_mdm2ap_errfatal_restart_flag(1); }
static void mdm_fatal_fn(struct work_struct *work) { int i; int value = gpio_get_value(mdm_drv->mdm2ap_errfatal_gpio); if (value == 1) { for (i = HTC_MDM_ERROR_CONFIRM_TIME_MS; i > 0; i--) { msleep(1); if (gpio_get_value(mdm_drv->mdm2ap_errfatal_gpio) == 0) { pr_info("%s: mdm fatal high %d(ms) confirm failed... Abort!\n", __func__, HTC_MDM_ERROR_CONFIRM_TIME_MS); return; } } } else if (value == 0) { pr_info("%s: mdm fatal high is a false alarm!\n", __func__); return; } dump_mdm_related_gpio(); pr_info("### Show Blocked State in ###\n"); show_state_filter(TASK_UNINTERRUPTIBLE); if (get_restart_level() == RESET_SOC) msm_rtb_disable(); if (get_restart_level() == RESET_SOC) set_mdm2ap_errfatal_restart_flag(1); pr_info("%s: Reseting the mdm due to an errfatal\n", __func__); subsystem_restart(EXTERNAL_MODEM); }
static irqreturn_t modem_wdog_bite_irq(int irq, void *dev_id) { switch (irq) { case Q6SW_WDOG_EXPIRED_IRQ: pr_err("Watchdog bite received from modem software!\n"); if (get_restart_level() == RESET_SOC) ssr_set_restart_reason( "modem fatal: Modem SW Watchdog Bite!"); restart_modem(); break; case Q6FW_WDOG_EXPIRED_IRQ: pr_err("Watchdog bite received from modem firmware!\n"); if (get_restart_level() == RESET_SOC) ssr_set_restart_reason( "modem fatal: Modem FW Watchdog Bite!"); restart_modem(); break; break; default: pr_err("%s: Unknown IRQ!\n", __func__); } return IRQ_HANDLED; }
static void mdm_status_fn(struct work_struct *work) { int i; int value = gpio_get_value(mdm_drv->mdm2ap_status_gpio); if (!mdm_drv->mdm_ready) return; if (value == 0) { for (i = HTC_MDM_ERROR_CONFIRM_TIME_MS; i > 0; i--) { msleep(1); if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 1) { pr_info("%s: mdm status low %d(ms) confirm failed... Abort!\n", __func__, HTC_MDM_ERROR_CONFIRM_TIME_MS); return; } } } if ( ( get_radio_flag() & RADIO_FLAG_USB_UPLOAD ) ) { if ( value == 0 ) { int val_gpio = 0; msleep(40); val_gpio = gpio_get_value(mdm_drv->mdm2ap_hsic_ready_gpio); pr_info("%s:mdm2ap_hsic_ready_gpio=[%d]\n", __func__, val_gpio); } } mdm_status_change_notified = true; mdm_drv->ops->status_cb(mdm_drv, value); pr_debug("%s: status:%d\n", __func__, value); if (value == 0) { pr_info("%s: unexpected reset external modem\n", __func__); dump_mdm_related_gpio(); pr_info("### Show Blocked State in ###\n"); show_state_filter(TASK_UNINTERRUPTIBLE); if (get_restart_level() == RESET_SOC) msm_rtb_disable(); if (get_restart_level() == RESET_SOC) set_mdm2ap_errfatal_restart_flag(1); subsystem_restart(EXTERNAL_MODEM); } else if (value == 1) { pr_info("%s: status = 1: mdm is now ready\n", __func__); } }
static void dsps_restart_handler(struct dsps_data *drv) { pr_debug("%s: Restart lvl %d\n", __func__, get_restart_level()); if (atomic_add_return(1, &drv->crash_in_progress) > 1) { pr_err("%s: DSPS already resetting. Count %d\n", __func__, atomic_read(&drv->crash_in_progress)); } else { subsystem_restart_dev(drv->subsys); } }
int subsys_q6_shutdown(const char * const crashed_subsys) { void __iomem *q6_wdog_addr = ioremap_nocache(Q6SS_WDOG_ENABLE, 8); send_q6_nmi(); writel_relaxed(0x0, q6_wdog_addr); /* The write needs to go through before the q6 is shutdown. */ mb(); iounmap(q6_wdog_addr); pil_force_shutdown("q6"); disable_irq_nosync(LPASS_Q6SS_WDOG_EXPIRED); if (get_restart_level() == RESET_SUBSYS_MIXED) smsm_reset_modem(SMSM_RESET); return 0; }
/** * Fatal error handler * Resets DSPS. */ static void dsps_restart_handler(struct work_struct *work) { uint32_t dsps_state; int restart_level; char *smem_reset_reason; unsigned smem_reset_size; const char dflt_reason[] = "Died too early due to unknown reason"; dsps_state = smsm_get_state(SMSM_DSPS_STATE); restart_level = get_restart_level(); pr_debug("%s: DSPS state 0x%x. Restart lvl %d\n", __func__, dsps_state, restart_level); if ((dsps_state & SMSM_RESET) || (atomic_read(&drv->wd_crash) == 1)) { smem_reset_reason = smem_get_entry(SMEM_SSR_REASON_DSPS0, &smem_reset_size); if (smem_reset_reason != NULL && smem_reset_reason[0] != 0) { smem_reset_reason[smem_reset_size-1] = 0; pr_err("%s: DSPS failure: %s\nResetting DSPS\n", __func__, smem_reset_reason); memset(smem_reset_reason, 0, smem_reset_size); wmb(); } else pr_err("%s: DSPS failure: %s\nResetting DSPS\n", __func__, dflt_reason); } else pr_err("%s: User-initiated DSPS reset.\nResetting DSPS\n", __func__); if (atomic_add_return(1, &drv->crash_in_progress) > 1) { pr_err("%s: DSPS already resetting. Count %d\n", __func__, atomic_read(&drv->crash_in_progress)); } else { subsystem_restart("dsps"); } }