Loading arch/arm64/boot/dts/qcom/sdm670.dtsi +15 −10 Original line number Diff line number Diff line Loading @@ -1138,6 +1138,11 @@ reg = <0x10 8>; }; dload_type@1c { compatible = "qcom,msm-imem-dload-type"; reg = <0x1c 0x4>; }; restart_reason@65c { compatible = "qcom,msm-imem-restart_reason"; reg = <0x65c 4>; Loading Loading @@ -1312,52 +1317,52 @@ compatible = "qcom,mem-dump"; memory-region = <&dump_mem>; rpmh_dump { rpmh { qcom,dump-size = <0x2000000>; qcom,dump-id = <0xec>; }; rpm_sw_dump { rpm_sw { qcom,dump-size = <0x28000>; qcom,dump-id = <0xea>; }; pmic_dump { pmic { qcom,dump-size = <0x10000>; qcom,dump-id = <0xe4>; }; tmc_etf_dump { tmc_etf { qcom,dump-size = <0x10000>; qcom,dump-id = <0xf0>; }; tmc_etf_swao_dump { tmc_etfswao { qcom,dump-size = <0x8400>; qcom,dump-id = <0xf1>; }; tmc_etr_reg_dump { tmc_etr_reg { qcom,dump-size = <0x1000>; qcom,dump-id = <0x100>; }; tmc_etf_reg_dump { tmc_etf_reg { qcom,dump-size = <0x1000>; qcom,dump-id = <0x101>; }; tmc_etf_swao_reg_dump { etfswao_reg { qcom,dump-size = <0x1000>; qcom,dump-id = <0x102>; }; misc_data_dump { misc_data { qcom,dump-size = <0x1000>; qcom,dump-id = <0xe8>; }; power_regs_data_dump { power_regs { qcom,dump-size = <0x100000>; qcom,dump-id = <0xed>; }; Loading arch/arm64/kernel/smp.c +2 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ #include <asm/tlbflush.h> #include <asm/ptrace.h> #include <asm/virt.h> #include <soc/qcom/minidump.h> #define CREATE_TRACE_POINTS #include <trace/events/ipi.h> Loading Loading @@ -844,6 +845,7 @@ static void ipi_cpu_stop(unsigned int cpu, struct pt_regs *regs) pr_crit("CPU%u: stopping\n", cpu); show_regs(regs); dump_stack(); dump_stack_minidump(regs->sp); raw_spin_unlock(&stop_lock); } Loading drivers/cpuidle/lpm-levels.c +10 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <soc/qcom/event_timer.h> #include <soc/qcom/lpm-stats.h> #include <soc/qcom/system_pm.h> #include <soc/qcom/minidump.h> #include <asm/arch_timer.h> #include <asm/suspend.h> #include <asm/cpuidle.h> Loading Loading @@ -1638,6 +1639,7 @@ static int lpm_probe(struct platform_device *pdev) int ret; int size; struct kobject *module_kobj = NULL; struct md_region md_entry; get_online_cpus(); lpm_root_node = lpm_of_parse_cluster(pdev); Loading Loading @@ -1694,6 +1696,14 @@ static int lpm_probe(struct platform_device *pdev) goto failed; } /* Add lpm_debug to Minidump*/ strlcpy(md_entry.name, "KLPMDEBUG", sizeof(md_entry.name)); md_entry.virt_addr = (uintptr_t)lpm_debug; md_entry.phys_addr = lpm_debug_phys; md_entry.size = size; if (msm_minidump_add_region(&md_entry)) pr_info("Failed to add lpm_debug in Minidump\n"); return 0; failed: free_cluster_node(lpm_root_node); Loading drivers/power/reset/msm-poweroff.c +59 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <soc/qcom/scm.h> #include <soc/qcom/restart.h> #include <soc/qcom/watchdog.h> #include <soc/qcom/minidump.h> #define EMERGENCY_DLOAD_MAGIC1 0x322A4F99 #define EMERGENCY_DLOAD_MAGIC2 0xC67E4350 Loading @@ -42,10 +43,11 @@ #define SCM_IO_DISABLE_PMIC_ARBITER 1 #define SCM_IO_DEASSERT_PS_HOLD 2 #define SCM_WDOG_DEBUG_BOOT_PART 0x9 #define SCM_DLOAD_MODE 0X10 #define SCM_DLOAD_FULLDUMP 0X10 #define SCM_EDLOAD_MODE 0X01 #define SCM_DLOAD_CMD 0x10 #define SCM_DLOAD_MINIDUMP 0X20 #define SCM_DLOAD_BOTHDUMPS (SCM_DLOAD_MINIDUMP | SCM_DLOAD_FULLDUMP) static int restart_mode; static void __iomem *restart_reason, *dload_type_addr; Loading @@ -65,6 +67,7 @@ static struct kobject dload_kobj; #endif static int in_panic; static int dload_type = SCM_DLOAD_FULLDUMP; static void *dload_mode_addr; static bool dload_mode_enabled; static void *emergency_dload_mode_addr; Loading Loading @@ -137,7 +140,7 @@ static void set_dload_mode(int on) mb(); } ret = scm_set_dload_mode(on ? SCM_DLOAD_MODE : 0, 0); ret = scm_set_dload_mode(on ? dload_type : 0, 0); if (ret) pr_err("Failed to set secure DLOAD mode: %d\n", ret); Loading Loading @@ -452,6 +455,9 @@ static ssize_t show_emmc_dload(struct kobject *kobj, struct attribute *attr, { uint32_t read_val, show_val; if (!dload_type_addr) return -ENODEV; read_val = __raw_readl(dload_type_addr); if (read_val == EMMC_DLOAD_TYPE) show_val = 1; Loading @@ -467,6 +473,9 @@ static size_t store_emmc_dload(struct kobject *kobj, struct attribute *attr, uint32_t enabled; int ret; if (!dload_type_addr) return -ENODEV; ret = kstrtouint(buf, 0, &enabled); if (ret < 0) return ret; Loading @@ -481,10 +490,57 @@ static size_t store_emmc_dload(struct kobject *kobj, struct attribute *attr, return count; } #ifdef CONFIG_QCOM_MINIDUMP static DEFINE_MUTEX(tcsr_lock); static ssize_t show_dload_mode(struct kobject *kobj, struct attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "DLOAD dump type: %s\n", (dload_type == SCM_DLOAD_BOTHDUMPS) ? "both" : ((dload_type == SCM_DLOAD_MINIDUMP) ? "mini" : "full")); } static size_t store_dload_mode(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { if (sysfs_streq(buf, "full")) { dload_type = SCM_DLOAD_FULLDUMP; } else if (sysfs_streq(buf, "mini")) { if (!msm_minidump_enabled()) { pr_err("Minidump is not enabled\n"); return -ENODEV; } dload_type = SCM_DLOAD_MINIDUMP; } else if (sysfs_streq(buf, "both")) { if (!msm_minidump_enabled()) { pr_err("Minidump not enabled, setting fulldump only\n"); dload_type = SCM_DLOAD_FULLDUMP; return count; } dload_type = SCM_DLOAD_BOTHDUMPS; } else{ pr_err("Invalid Dump setup request..\n"); pr_err("Supported dumps:'full', 'mini', or 'both'\n"); return -EINVAL; } mutex_lock(&tcsr_lock); /*Overwrite TCSR reg*/ set_dload_mode(dload_type); mutex_unlock(&tcsr_lock); return count; } RESET_ATTR(dload_mode, 0644, show_dload_mode, store_dload_mode); #endif RESET_ATTR(emmc_dload, 0644, show_emmc_dload, store_emmc_dload); static struct attribute *reset_attrs[] = { &reset_attr_emmc_dload.attr, #ifdef CONFIG_QCOM_MINIDUMP &reset_attr_dload_mode.attr, #endif NULL }; Loading drivers/soc/qcom/Kconfig +18 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,23 @@ config QCOM_MEMORY_DUMP_V2 of deadlocks or cpu hangs these dump regions are captured to give a snapshot of the system at the time of the crash. config QCOM_MINIDUMP bool "QCOM Minidump Support" depends on MSM_SMEM && QCOM_DLOAD_MODE help This enables minidump feature. It allows various clients to register to dump their state at system bad state (panic/WDT,etc.,). Minidump would dump all registered entries, only when DLOAD mode is enabled. config MINIDUMP_MAX_ENTRIES int "Minidump Maximum num of entries" default 200 depends on QCOM_MINIDUMP help This defines maximum number of entries to be allocated for application subsytem in Minidump table. config QCOM_BUS_SCALING bool "Bus scaling driver" help Loading Loading
arch/arm64/boot/dts/qcom/sdm670.dtsi +15 −10 Original line number Diff line number Diff line Loading @@ -1138,6 +1138,11 @@ reg = <0x10 8>; }; dload_type@1c { compatible = "qcom,msm-imem-dload-type"; reg = <0x1c 0x4>; }; restart_reason@65c { compatible = "qcom,msm-imem-restart_reason"; reg = <0x65c 4>; Loading Loading @@ -1312,52 +1317,52 @@ compatible = "qcom,mem-dump"; memory-region = <&dump_mem>; rpmh_dump { rpmh { qcom,dump-size = <0x2000000>; qcom,dump-id = <0xec>; }; rpm_sw_dump { rpm_sw { qcom,dump-size = <0x28000>; qcom,dump-id = <0xea>; }; pmic_dump { pmic { qcom,dump-size = <0x10000>; qcom,dump-id = <0xe4>; }; tmc_etf_dump { tmc_etf { qcom,dump-size = <0x10000>; qcom,dump-id = <0xf0>; }; tmc_etf_swao_dump { tmc_etfswao { qcom,dump-size = <0x8400>; qcom,dump-id = <0xf1>; }; tmc_etr_reg_dump { tmc_etr_reg { qcom,dump-size = <0x1000>; qcom,dump-id = <0x100>; }; tmc_etf_reg_dump { tmc_etf_reg { qcom,dump-size = <0x1000>; qcom,dump-id = <0x101>; }; tmc_etf_swao_reg_dump { etfswao_reg { qcom,dump-size = <0x1000>; qcom,dump-id = <0x102>; }; misc_data_dump { misc_data { qcom,dump-size = <0x1000>; qcom,dump-id = <0xe8>; }; power_regs_data_dump { power_regs { qcom,dump-size = <0x100000>; qcom,dump-id = <0xed>; }; Loading
arch/arm64/kernel/smp.c +2 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ #include <asm/tlbflush.h> #include <asm/ptrace.h> #include <asm/virt.h> #include <soc/qcom/minidump.h> #define CREATE_TRACE_POINTS #include <trace/events/ipi.h> Loading Loading @@ -844,6 +845,7 @@ static void ipi_cpu_stop(unsigned int cpu, struct pt_regs *regs) pr_crit("CPU%u: stopping\n", cpu); show_regs(regs); dump_stack(); dump_stack_minidump(regs->sp); raw_spin_unlock(&stop_lock); } Loading
drivers/cpuidle/lpm-levels.c +10 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <soc/qcom/event_timer.h> #include <soc/qcom/lpm-stats.h> #include <soc/qcom/system_pm.h> #include <soc/qcom/minidump.h> #include <asm/arch_timer.h> #include <asm/suspend.h> #include <asm/cpuidle.h> Loading Loading @@ -1638,6 +1639,7 @@ static int lpm_probe(struct platform_device *pdev) int ret; int size; struct kobject *module_kobj = NULL; struct md_region md_entry; get_online_cpus(); lpm_root_node = lpm_of_parse_cluster(pdev); Loading Loading @@ -1694,6 +1696,14 @@ static int lpm_probe(struct platform_device *pdev) goto failed; } /* Add lpm_debug to Minidump*/ strlcpy(md_entry.name, "KLPMDEBUG", sizeof(md_entry.name)); md_entry.virt_addr = (uintptr_t)lpm_debug; md_entry.phys_addr = lpm_debug_phys; md_entry.size = size; if (msm_minidump_add_region(&md_entry)) pr_info("Failed to add lpm_debug in Minidump\n"); return 0; failed: free_cluster_node(lpm_root_node); Loading
drivers/power/reset/msm-poweroff.c +59 −3 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <soc/qcom/scm.h> #include <soc/qcom/restart.h> #include <soc/qcom/watchdog.h> #include <soc/qcom/minidump.h> #define EMERGENCY_DLOAD_MAGIC1 0x322A4F99 #define EMERGENCY_DLOAD_MAGIC2 0xC67E4350 Loading @@ -42,10 +43,11 @@ #define SCM_IO_DISABLE_PMIC_ARBITER 1 #define SCM_IO_DEASSERT_PS_HOLD 2 #define SCM_WDOG_DEBUG_BOOT_PART 0x9 #define SCM_DLOAD_MODE 0X10 #define SCM_DLOAD_FULLDUMP 0X10 #define SCM_EDLOAD_MODE 0X01 #define SCM_DLOAD_CMD 0x10 #define SCM_DLOAD_MINIDUMP 0X20 #define SCM_DLOAD_BOTHDUMPS (SCM_DLOAD_MINIDUMP | SCM_DLOAD_FULLDUMP) static int restart_mode; static void __iomem *restart_reason, *dload_type_addr; Loading @@ -65,6 +67,7 @@ static struct kobject dload_kobj; #endif static int in_panic; static int dload_type = SCM_DLOAD_FULLDUMP; static void *dload_mode_addr; static bool dload_mode_enabled; static void *emergency_dload_mode_addr; Loading Loading @@ -137,7 +140,7 @@ static void set_dload_mode(int on) mb(); } ret = scm_set_dload_mode(on ? SCM_DLOAD_MODE : 0, 0); ret = scm_set_dload_mode(on ? dload_type : 0, 0); if (ret) pr_err("Failed to set secure DLOAD mode: %d\n", ret); Loading Loading @@ -452,6 +455,9 @@ static ssize_t show_emmc_dload(struct kobject *kobj, struct attribute *attr, { uint32_t read_val, show_val; if (!dload_type_addr) return -ENODEV; read_val = __raw_readl(dload_type_addr); if (read_val == EMMC_DLOAD_TYPE) show_val = 1; Loading @@ -467,6 +473,9 @@ static size_t store_emmc_dload(struct kobject *kobj, struct attribute *attr, uint32_t enabled; int ret; if (!dload_type_addr) return -ENODEV; ret = kstrtouint(buf, 0, &enabled); if (ret < 0) return ret; Loading @@ -481,10 +490,57 @@ static size_t store_emmc_dload(struct kobject *kobj, struct attribute *attr, return count; } #ifdef CONFIG_QCOM_MINIDUMP static DEFINE_MUTEX(tcsr_lock); static ssize_t show_dload_mode(struct kobject *kobj, struct attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "DLOAD dump type: %s\n", (dload_type == SCM_DLOAD_BOTHDUMPS) ? "both" : ((dload_type == SCM_DLOAD_MINIDUMP) ? "mini" : "full")); } static size_t store_dload_mode(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { if (sysfs_streq(buf, "full")) { dload_type = SCM_DLOAD_FULLDUMP; } else if (sysfs_streq(buf, "mini")) { if (!msm_minidump_enabled()) { pr_err("Minidump is not enabled\n"); return -ENODEV; } dload_type = SCM_DLOAD_MINIDUMP; } else if (sysfs_streq(buf, "both")) { if (!msm_minidump_enabled()) { pr_err("Minidump not enabled, setting fulldump only\n"); dload_type = SCM_DLOAD_FULLDUMP; return count; } dload_type = SCM_DLOAD_BOTHDUMPS; } else{ pr_err("Invalid Dump setup request..\n"); pr_err("Supported dumps:'full', 'mini', or 'both'\n"); return -EINVAL; } mutex_lock(&tcsr_lock); /*Overwrite TCSR reg*/ set_dload_mode(dload_type); mutex_unlock(&tcsr_lock); return count; } RESET_ATTR(dload_mode, 0644, show_dload_mode, store_dload_mode); #endif RESET_ATTR(emmc_dload, 0644, show_emmc_dload, store_emmc_dload); static struct attribute *reset_attrs[] = { &reset_attr_emmc_dload.attr, #ifdef CONFIG_QCOM_MINIDUMP &reset_attr_dload_mode.attr, #endif NULL }; Loading
drivers/soc/qcom/Kconfig +18 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,23 @@ config QCOM_MEMORY_DUMP_V2 of deadlocks or cpu hangs these dump regions are captured to give a snapshot of the system at the time of the crash. config QCOM_MINIDUMP bool "QCOM Minidump Support" depends on MSM_SMEM && QCOM_DLOAD_MODE help This enables minidump feature. It allows various clients to register to dump their state at system bad state (panic/WDT,etc.,). Minidump would dump all registered entries, only when DLOAD mode is enabled. config MINIDUMP_MAX_ENTRIES int "Minidump Maximum num of entries" default 200 depends on QCOM_MINIDUMP help This defines maximum number of entries to be allocated for application subsytem in Minidump table. config QCOM_BUS_SCALING bool "Bus scaling driver" help Loading