static void log_modem_sfr(void) { u32 size; char *smem_reason, reason[MAX_SSR_REASON_LEN]; smem_reason = smem_get_entry_no_rlock(SMEM_SSR_REASON_MSS0, &size); if (!smem_reason || !size) { pr_err("modem subsystem failure reason: (unknown, smem_get_entry_no_rlock failed).\n"); return; } if (!smem_reason[0]) { pr_err("modem subsystem failure reason: (unknown, empty string found).\n"); return; } strlcpy(reason, smem_reason, min(size, sizeof(reason))); pr_err("modem subsystem failure reason: %s.\n", reason); #if defined(CONFIG_PRE_SELF_DIAGNOSIS) lge_pre_self_diagnosis((char *) "modem",3,(char *) "modem failed",(char *) reason, 20001); #endif #ifdef FEATURE_LGE_MODEM_DEBUG_INFO if (modem_debug.modem_ssr_level != RESET_SOC) { strlcpy(modem_debug.save_ssr_reason, smem_reason, min(size, sizeof(reason))); modem_debug.modem_ssr_event = MODEM_SSR_ERR_FATAL; queue_work(modem_debug.modem_ssr_queue, &modem_debug.modem_ssr_report_work); } #endif smem_reason[0] = '\0'; wmb(); }
/* [END] [email protected], SSR FEATURE */ static void log_modem_sfr(void) { u32 size; char *smem_reason, reason[MAX_SSR_REASON_LEN]; smem_reason = smem_get_entry_no_rlock(SMEM_SSR_REASON_MSS0, &size); if (!smem_reason || !size) { pr_err("modem subsystem failure reason: (unknown, smem_get_entry_no_rlock failed).\n"); return; } if (!smem_reason[0]) { pr_err("modem subsystem failure reason: (unknown, empty string found).\n"); return; } strlcpy(reason, smem_reason, min(size, sizeof(reason))); pr_err("modem subsystem failure reason: %s.\n", reason); #if defined(CONFIG_PRE_SELF_DIAGNOSIS) lge_pre_self_diagnosis((char *) "modem", 3, (char *) "modem failed", (char *) reason, 20001); #endif /* [START] [email protected], SSR FEATURE */ strlcpy(ssr_noti, smem_reason, min(size, sizeof(ssr_noti))); /* [END] [email protected], SSR FEATURE */ smem_reason[0] = '\0'; wmb(); }
static irqreturn_t modem_err_fatal_intr_handler(int irq, void *dev_id) { struct modem_data *drv = subsys_to_drv(dev_id); /* Ignore if we're the one that set the force stop GPIO */ if (drv->crash_shutdown) return IRQ_HANDLED; if (check_modem_reset(drv) == 0) return IRQ_HANDLED; pr_err("Fatal error on the modem.\n"); #if defined(CONFIG_PRE_SELF_DIAGNOSIS) lge_pre_self_diagnosis((char *) "modem", 2, (char *) "modem fatal", (char *) "_", 20000); #endif subsys_set_crash_status(drv->subsys, true); restart_modem(drv); return IRQ_HANDLED; }
static void modem_fatal_fn(struct work_struct *work) { u32 modem_state; u32 panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD; u32 reset_smsm_states = SMSM_SYSTEM_REBOOT_USR | SMSM_SYSTEM_PWRDWN_USR; struct modem_data *drv; drv = container_of(work, struct modem_data, fatal_work); pr_err("Watchdog bite received from modem!\n"); modem_state = smsm_get_state(SMSM_MODEM_STATE); pr_err("Modem SMSM state = 0x%x!\n", modem_state); #if defined(CONFIG_PRE_SELF_DIAGNOSIS) lge_pre_self_diagnosis((char *) "modem",1,(char *) "Watchdog bite",(char *) "_", modem_state); #endif if (modem_state == 0 || modem_state & panic_smsm_states) { subsystem_restart_dev(drv->subsys); enable_irq(drv->irq); } else if (modem_state & reset_smsm_states) { pr_err("User-invoked system reset/powerdown."); kernel_restart(NULL); } else { unsigned long timeout = msecs_to_jiffies(6000); pr_err("Modem AHB locked up. Trying to free up modem!\n"); writel_relaxed(0x3, drv->cbase + MSS_MODEM_RESET); /* * If we are still alive (allowing for the 5 second * delayed-panic-reboot), the modem is either still wedged or * SMSM didn't come through. Force panic in that case. */ schedule_delayed_work(&drv->unlock_work, timeout); } }
static void modem_crash_shutdown(const struct subsys_desc *subsys) { struct modem_data *drv = subsys_to_drv(subsys); drv->crash_shutdown = true; #ifdef CONFIG_LGE_HANDLE_PANIC if (!subsys_get_crash_status(drv->subsys) && (lge_get_modem_panic() != 3)) { #else if (!subsys_get_crash_status(drv->subsys)) { #endif gpio_set_value(subsys->force_stop_gpio, 1); mdelay(STOP_ACK_TIMEOUT_MS); } } static int modem_ramdump(int enable, const struct subsys_desc *subsys) { struct modem_data *drv = subsys_to_drv(subsys); int ret; if (!enable) return 0; ret = pil_boot(&drv->q6->desc); if (ret) return ret; ret = pil_do_ramdump(&drv->mba->desc, drv->ramdump_dev); if (ret < 0) pr_err("Unable to dump modem fw memory (rc = %d).\n", ret); pil_shutdown(&drv->q6->desc); return ret; } static int adsp_state_notifier_fn(struct notifier_block *this, unsigned long code, void *ss_handle) { int ret; ret = sysmon_send_event(SYSMON_SS_MODEM, "adsp", code); if (ret < 0) pr_err("%s: sysmon_send_event failed (%d).", __func__, ret); return NOTIFY_DONE; } static struct notifier_block adsp_state_notifier_block = { .notifier_call = adsp_state_notifier_fn, }; static irqreturn_t modem_wdog_bite_intr_handler(int irq, void *dev_id) { struct modem_data *drv = subsys_to_drv(dev_id); if (drv->ignore_errors) return IRQ_HANDLED; /* START : subsys_modem_restart : testmode */ if (ignore_errors_by_subsys_modem_restart) { pr_err("IGNORE watchdog bite received from modem software!\n"); return IRQ_HANDLED; } /* END : subsys_modem_restart : testmode */ if (check_modem_reset(drv) == 0) { pr_err("IGNORE watchdog bite received from modem software during check_modem_reset!\n"); return IRQ_HANDLED; } pr_err("Watchdog bite received from modem software!\n"); #if defined(CONFIG_PRE_SELF_DIAGNOSIS) lge_pre_self_diagnosis((char *) "modem", 2, (char *) "Watchdog bite Intr", (char *) "_", 20000); #endif subsys_set_crash_status(drv->subsys, true); restart_modem(drv); return IRQ_HANDLED; } static int mss_start(const struct subsys_desc *desc) { int ret; struct modem_data *drv = subsys_to_drv(desc); if (desc->is_not_loadable) return 0; INIT_COMPLETION(drv->stop_ack); ret = pil_boot(&drv->q6->desc); if (ret) return ret; ret = pil_boot(&drv->mba->desc); if (ret) pil_shutdown(&drv->q6->desc); return ret; }