mako: debug: porting lge crash handler
Change-Id: I913d372131a25bb9c0d90680f5e96cebb8883055 Signed-off-by: Iliyan Malchev <malchev@google.com>
This commit is contained in:
committed by
Iliyan Malchev
parent
7e8f0f7574
commit
93c86c992b
@@ -45,6 +45,7 @@ CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
|
|||||||
CONFIG_MACH_MSM_DUMMY=y
|
CONFIG_MACH_MSM_DUMMY=y
|
||||||
CONFIG_BOARD_HEADER_FILE="mach/lge/board_mako.h"
|
CONFIG_BOARD_HEADER_FILE="mach/lge/board_mako.h"
|
||||||
CONFIG_MACH_APQ8064_MAKO=y
|
CONFIG_MACH_APQ8064_MAKO=y
|
||||||
|
CONFIG_LGE_CRASH_HANDLER=y
|
||||||
CONFIG_LGE_QFPROM_INTERFACE=y
|
CONFIG_LGE_QFPROM_INTERFACE=y
|
||||||
CONFIG_UPDATE_LCDC_LUT=y
|
CONFIG_UPDATE_LCDC_LUT=y
|
||||||
CONFIG_LCD_KCAL=y
|
CONFIG_LCD_KCAL=y
|
||||||
|
|||||||
@@ -412,6 +412,12 @@ void __show_regs(struct pt_regs *regs)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
#ifdef CONFIG_CPU_CP15_MMU
|
||||||
|
unsigned int c1, c2;
|
||||||
|
#endif
|
||||||
|
set_crash_store_enable();
|
||||||
|
#endif
|
||||||
printk("CPU: %d %s (%s %.*s)\n",
|
printk("CPU: %d %s (%s %.*s)\n",
|
||||||
raw_smp_processor_id(), print_tainted(),
|
raw_smp_processor_id(), print_tainted(),
|
||||||
init_utsname()->release,
|
init_utsname()->release,
|
||||||
@@ -419,7 +425,11 @@ void __show_regs(struct pt_regs *regs)
|
|||||||
init_utsname()->version);
|
init_utsname()->version);
|
||||||
print_symbol("PC is at %s\n", instruction_pointer(regs));
|
print_symbol("PC is at %s\n", instruction_pointer(regs));
|
||||||
print_symbol("LR is at %s\n", regs->ARM_lr);
|
print_symbol("LR is at %s\n", regs->ARM_lr);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
printk("pc : <%08lx> lr : <%08lx> psr: %08lx\n"
|
||||||
|
#else
|
||||||
printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n"
|
printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n"
|
||||||
|
#endif
|
||||||
"sp : %08lx ip : %08lx fp : %08lx\n",
|
"sp : %08lx ip : %08lx fp : %08lx\n",
|
||||||
regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
|
regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
|
||||||
regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
|
regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
|
||||||
@@ -432,6 +442,9 @@ void __show_regs(struct pt_regs *regs)
|
|||||||
printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
|
printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
|
||||||
regs->ARM_r3, regs->ARM_r2,
|
regs->ARM_r3, regs->ARM_r2,
|
||||||
regs->ARM_r1, regs->ARM_r0);
|
regs->ARM_r1, regs->ARM_r0);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
set_crash_store_disable();
|
||||||
|
#endif
|
||||||
|
|
||||||
flags = regs->ARM_cpsr;
|
flags = regs->ARM_cpsr;
|
||||||
buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
|
buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
|
||||||
@@ -459,11 +472,18 @@ void __show_regs(struct pt_regs *regs)
|
|||||||
: "=r" (transbase), "=r" (dac));
|
: "=r" (transbase), "=r" (dac));
|
||||||
snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
|
snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
|
||||||
transbase, dac);
|
transbase, dac);
|
||||||
|
#if defined(CONFIG_CPU_CP15_MMU) && defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
c1 = transbase;
|
||||||
|
c2 = dac;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
|
asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
|
||||||
|
|
||||||
printk("Control: %08x%s\n", ctrl, buf);
|
printk("Control: %08x%s\n", ctrl, buf);
|
||||||
|
#if defined(CONFIG_CPU_CP15_MMU) && defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
lge_save_ctx(regs, ctrl, c1, c2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,10 @@
|
|||||||
|
|
||||||
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
|
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
static int first_call_chain = 0;
|
||||||
|
static int first_die = 1;
|
||||||
|
#endif
|
||||||
void *vectors_page;
|
void *vectors_page;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_USER
|
#ifdef CONFIG_DEBUG_USER
|
||||||
@@ -57,7 +61,14 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
|
|||||||
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
|
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_KALLSYMS
|
#ifdef CONFIG_KALLSYMS
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
if (first_call_chain)
|
||||||
|
set_crash_store_enable();
|
||||||
|
#endif
|
||||||
printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
|
printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
set_crash_store_disable();
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
|
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
|
||||||
#endif
|
#endif
|
||||||
@@ -239,9 +250,22 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
|
|||||||
static int die_counter;
|
static int die_counter;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
if (first_die) {
|
||||||
|
first_call_chain = 1;
|
||||||
|
first_die = 0;
|
||||||
|
}
|
||||||
|
set_kernel_crash_magic_number();
|
||||||
|
set_crash_store_enable();
|
||||||
|
#endif
|
||||||
|
|
||||||
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP
|
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP
|
||||||
S_ISA "\n", str, err, ++die_counter);
|
S_ISA "\n", str, err, ++die_counter);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
set_crash_store_disable();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* trap and error numbers are mostly meaningless on ARM */
|
/* trap and error numbers are mostly meaningless on ARM */
|
||||||
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
|
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
|
||||||
if (ret == NOTIFY_STOP)
|
if (ret == NOTIFY_STOP)
|
||||||
@@ -257,6 +281,9 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
|
|||||||
THREAD_SIZE + (unsigned long)task_stack_page(tsk));
|
THREAD_SIZE + (unsigned long)task_stack_page(tsk));
|
||||||
dump_backtrace(regs, tsk);
|
dump_backtrace(regs, tsk);
|
||||||
dump_instr(KERN_EMERG, regs);
|
dump_instr(KERN_EMERG, regs);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
first_call_chain = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#define LGE_RAM_CONSOLE_SIZE (124*SZ_1K * 2)
|
#define LGE_RAM_CONSOLE_SIZE (124*SZ_1K * 2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_LGE_HANDLE_PANIC
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
#define LGE_CRASH_LOG_SIZE (4*SZ_1K)
|
#define LGE_CRASH_LOG_SIZE (4*SZ_1K)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -129,10 +129,10 @@ enum lge_boot_mode_type {
|
|||||||
void __init lge_add_ramconsole_devices(void);
|
void __init lge_add_ramconsole_devices(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_LGE_HANDLE_PANIC
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
void __init lge_add_panic_handler_devices(void);
|
void __init lge_add_panic_handler_devices(void);
|
||||||
int lge_get_magic_for_subsystem(void);
|
int get_ssr_magic_number(void);
|
||||||
void lge_set_magic_for_subsystem(const char *subsys_name);
|
void set_ssr_magic_number(const char *subsys_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_LGE_QFPROM_INTERFACE
|
#ifdef CONFIG_LGE_QFPROM_INTERFACE
|
||||||
|
|||||||
@@ -94,6 +94,10 @@ extern void l2x0_cache_sync(void);
|
|||||||
|
|
||||||
#if defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
|
#if defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
|
||||||
extern void store_ttbr0(void);
|
extern void store_ttbr0(void);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
extern void store_ctrl(void);
|
||||||
|
extern void store_dac(void);
|
||||||
|
#endif
|
||||||
#define finish_arch_switch(prev) do { store_ttbr0(); } while (0)
|
#define finish_arch_switch(prev) do { store_ttbr0(); } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,14 @@
|
|||||||
#define RESTART_NORMAL 0x0
|
#define RESTART_NORMAL 0x0
|
||||||
#define RESTART_DLOAD 0x1
|
#define RESTART_DLOAD 0x1
|
||||||
|
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
#define SUB_THD_F_PWR 0x0190
|
||||||
|
#define SUB_THD_F_SD 0x0110
|
||||||
|
#define SUB_UNAB_THD 0x0120
|
||||||
|
#define SUB_RESET_SOC 0x0130
|
||||||
|
#define SUB_UNKNOWN 0x0140
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_MSM_NATIVE_RESTART)
|
#if defined(CONFIG_MSM_NATIVE_RESTART)
|
||||||
void msm_set_restart_mode(int mode);
|
void msm_set_restart_mode(int mode);
|
||||||
void msm_restart(char mode, const char *cmd);
|
void msm_restart(char mode, const char *cmd);
|
||||||
|
|||||||
@@ -35,4 +35,11 @@ config EARJACK_DEBUGGER
|
|||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Saying Y here will support earjack type UART debugger cable
|
Saying Y here will support earjack type UART debugger cable
|
||||||
|
|
||||||
|
config LGE_CRASH_HANDLER
|
||||||
|
tristate "Support LGE Crash Handler"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
LGE Crash Handler
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ obj-$(CONFIG_LGE_QFPROM_INTERFACE) += lge_qfprom_access.o
|
|||||||
obj-$(CONFIG_LGE_QC_LCDC_LUT) += lge_qc_lcdc_luts.o
|
obj-$(CONFIG_LGE_QC_LCDC_LUT) += lge_qc_lcdc_luts.o
|
||||||
obj-$(CONFIG_LGE_KCAL) += lge_kcal_ctrl.o
|
obj-$(CONFIG_LGE_KCAL) += lge_kcal_ctrl.o
|
||||||
obj-$(CONFIG_LGE_KCAL_QLUT) += kcal_qlut.o
|
obj-$(CONFIG_LGE_KCAL_QLUT) += kcal_qlut.o
|
||||||
|
obj-$(CONFIG_LGE_CRASH_HANDLER) += lge_panic_handler.o
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ void __init lge_add_ramconsole_devices(void)
|
|||||||
struct resource* res = ram_console_resource;
|
struct resource* res = ram_console_resource;
|
||||||
struct membank* bank = &meminfo.bank[0];
|
struct membank* bank = &meminfo.bank[0];
|
||||||
|
|
||||||
res->start = PHYS_OFFSET + bank->size;
|
res->start = bank->start + bank->size;
|
||||||
res->end = res->start + LGE_RAM_CONSOLE_SIZE - 1;
|
res->end = res->start + LGE_RAM_CONSOLE_SIZE - 1;
|
||||||
|
|
||||||
printk(KERN_INFO "RAM CONSOLE START ADDR : %X\n", res->start);
|
printk(KERN_INFO "RAM CONSOLE START ADDR : %X\n", res->start);
|
||||||
@@ -351,9 +351,9 @@ void __init lge_add_ramconsole_devices(void)
|
|||||||
|
|
||||||
platform_device_register(&ram_console_device);
|
platform_device_register(&ram_console_device);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_ANDROID_RAM_CONSOLE
|
#endif /* CONFIG_ANDROID_RAM_CONSOLE */
|
||||||
|
|
||||||
#ifdef CONFIG_LGE_HANDLE_PANIC
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
static struct resource crash_log_resource[] = {
|
static struct resource crash_log_resource[] = {
|
||||||
{
|
{
|
||||||
.name = "crash_log",
|
.name = "crash_log",
|
||||||
@@ -383,7 +383,7 @@ void __init lge_add_panic_handler_devices(void)
|
|||||||
|
|
||||||
platform_device_register(&panic_handler_device);
|
platform_device_register(&panic_handler_device);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_LGE_HANDLE_PANIC
|
#endif /* CONFIG_LGE_CRASH_HANDLER */
|
||||||
|
|
||||||
#ifdef CONFIG_LGE_QFPROM_INTERFACE
|
#ifdef CONFIG_LGE_QFPROM_INTERFACE
|
||||||
static struct platform_device qfprom_device = {
|
static struct platform_device qfprom_device = {
|
||||||
|
|||||||
322
arch/arm/mach-msm/lge/lge_panic_handler.c
Normal file
322
arch/arm/mach-msm/lge/lge_panic_handler.c
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
/*
|
||||||
|
* arch/arm/mach-msm/lge/lge_panic_handler.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 LGE, Inc
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the GNU General Public
|
||||||
|
* License version 2, as published by the Free Software Foundation, and
|
||||||
|
* may be copied, distributed, and modified under those terms.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <asm/setup.h>
|
||||||
|
#include <mach/board_lge.h>
|
||||||
|
|
||||||
|
#include <mach/subsystem_restart.h>
|
||||||
|
#ifdef CONFIG_CPU_CP15_MMU
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PANIC_HANDLER_NAME "panic-handler"
|
||||||
|
#define PANIC_DUMP_CONSOLE 0
|
||||||
|
#define PANIC_MAGIC_KEY 0x12345678
|
||||||
|
#define CRASH_ARM9 0x87654321
|
||||||
|
#define CRASH_REBOOT 0x618E1000
|
||||||
|
|
||||||
|
struct crash_log_dump {
|
||||||
|
unsigned int magic_key;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned char buffer[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct crash_log_dump *crash_dump_log;
|
||||||
|
static unsigned int crash_buf_size = 0;
|
||||||
|
static int crash_store_flag = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPU_CP15_MMU
|
||||||
|
unsigned long *cpu_crash_ctx=NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned int msm_mmuctrl;
|
||||||
|
unsigned int msm_mmudac;
|
||||||
|
|
||||||
|
void store_ctrl(void)
|
||||||
|
{
|
||||||
|
asm("mrc p15, 0, %0, c1, c0, 0\n"
|
||||||
|
: "=r" (msm_mmuctrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
void store_dac(void)
|
||||||
|
{
|
||||||
|
asm("mrc p15, 0, %0, c3, c0, 0\n"
|
||||||
|
: "=r" (msm_mmudac));
|
||||||
|
}
|
||||||
|
static DEFINE_SPINLOCK(panic_lock);
|
||||||
|
|
||||||
|
static int dummy_arg;
|
||||||
|
static int gen_bug(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_bug, gen_bug, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
static int gen_panic(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
panic("generate test-panic");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_panic, gen_panic, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
static int gen_mdm_ssr(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
subsystem_restart("external_modem");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_mdm_ssr, gen_mdm_ssr, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
static int gen_modem_ssr(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
subsystem_restart("modem");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_modem_ssr, gen_modem_ssr, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
static int gen_riva_ssr(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
subsystem_restart("riva");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_riva_ssr, gen_riva_ssr, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
static int gen_dsps_ssr(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
subsystem_restart("dsps");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_dsps_ssr, gen_dsps_ssr, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
static int gen_lpass_ssr(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
subsystem_restart("lpass");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_lpass_ssr, gen_lpass_ssr, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
#define WDT0_RST 0x38
|
||||||
|
#define WDT0_EN 0x40
|
||||||
|
#define WDT0_BARK_TIME 0x4C
|
||||||
|
#define WDT0_BITE_TIME 0x5C
|
||||||
|
|
||||||
|
extern void __iomem *msm_timer_get_timer0_base(void);
|
||||||
|
|
||||||
|
static int gen_wdt_bark(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
static void __iomem *msm_tmr0_base;
|
||||||
|
msm_tmr0_base = msm_timer_get_timer0_base();
|
||||||
|
__raw_writel(0, msm_tmr0_base + WDT0_EN);
|
||||||
|
__raw_writel(1, msm_tmr0_base + WDT0_RST);
|
||||||
|
__raw_writel(0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
|
||||||
|
__raw_writel(5 * 0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
|
||||||
|
__raw_writel(1, msm_tmr0_base + WDT0_EN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_wdt_bark, gen_wdt_bark, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
static int gen_hw_reset(const char *val, struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
static void __iomem *msm_tmr0_base;
|
||||||
|
msm_tmr0_base = msm_timer_get_timer0_base();
|
||||||
|
__raw_writel(0, msm_tmr0_base + WDT0_EN);
|
||||||
|
__raw_writel(1, msm_tmr0_base + WDT0_RST);
|
||||||
|
__raw_writel(5 * 0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
|
||||||
|
__raw_writel(0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
|
||||||
|
__raw_writel(1, msm_tmr0_base + WDT0_EN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
module_param_call(gen_hw_reset, gen_hw_reset, param_get_bool,
|
||||||
|
&dummy_arg, S_IWUSR | S_IRUGO);
|
||||||
|
|
||||||
|
void set_crash_store_enable(void)
|
||||||
|
{
|
||||||
|
crash_store_flag = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_crash_store_disable(void)
|
||||||
|
{
|
||||||
|
crash_store_flag = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void store_crash_log(char *p)
|
||||||
|
{
|
||||||
|
if (!crash_store_flag)
|
||||||
|
return;
|
||||||
|
if (crash_dump_log->size == crash_buf_size)
|
||||||
|
return;
|
||||||
|
for ( ; *p; p++) {
|
||||||
|
if (*p == '[') {
|
||||||
|
for ( ; *p != ']'; p++)
|
||||||
|
;
|
||||||
|
p++;
|
||||||
|
if (*p == ' ')
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (*p == '<') {
|
||||||
|
for ( ; *p != '>'; p++)
|
||||||
|
;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
crash_dump_log->buffer[crash_dump_log->size] = *p;
|
||||||
|
crash_dump_log->size++;
|
||||||
|
}
|
||||||
|
crash_dump_log->buffer[crash_dump_log->size] = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CPU_CP15_MMU
|
||||||
|
void lge_save_ctx(struct pt_regs* regs, unsigned int ctrl,
|
||||||
|
unsigned int transbase, unsigned int dac)
|
||||||
|
{
|
||||||
|
/* save cpu register for simulation */
|
||||||
|
cpu_crash_ctx[0] = regs->ARM_r0;
|
||||||
|
cpu_crash_ctx[1] = regs->ARM_r1;
|
||||||
|
cpu_crash_ctx[2] = regs->ARM_r2;
|
||||||
|
cpu_crash_ctx[3] = regs->ARM_r3;
|
||||||
|
cpu_crash_ctx[4] = regs->ARM_r4;
|
||||||
|
cpu_crash_ctx[5] = regs->ARM_r5;
|
||||||
|
cpu_crash_ctx[6] = regs->ARM_r6;
|
||||||
|
cpu_crash_ctx[7] = regs->ARM_r7;
|
||||||
|
cpu_crash_ctx[8] = regs->ARM_r8;
|
||||||
|
cpu_crash_ctx[9] = regs->ARM_r9;
|
||||||
|
cpu_crash_ctx[10] = regs->ARM_r10;
|
||||||
|
cpu_crash_ctx[11] = regs->ARM_fp;
|
||||||
|
cpu_crash_ctx[12] = regs->ARM_ip;
|
||||||
|
cpu_crash_ctx[13] = regs->ARM_sp;
|
||||||
|
cpu_crash_ctx[14] = regs->ARM_lr;
|
||||||
|
cpu_crash_ctx[15] = regs->ARM_pc;
|
||||||
|
cpu_crash_ctx[16] = regs->ARM_cpsr;
|
||||||
|
/* save mmu register for simulation */
|
||||||
|
cpu_crash_ctx[17] = ctrl;
|
||||||
|
cpu_crash_ctx[18] = transbase;
|
||||||
|
cpu_crash_ctx[19] = dac;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int restore_crash_log(struct notifier_block *this,
|
||||||
|
unsigned long event, void *ptr)
|
||||||
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
crash_store_flag = 0;
|
||||||
|
spin_lock_irqsave(&panic_lock, flags);
|
||||||
|
crash_dump_log->magic_key = PANIC_MAGIC_KEY;
|
||||||
|
spin_unlock_irqrestore(&panic_lock, flags);
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block panic_handler_block = {
|
||||||
|
.notifier_call = restore_crash_log,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init panic_handler_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct resource *res = pdev->resource;
|
||||||
|
size_t start;
|
||||||
|
size_t buffer_size;
|
||||||
|
void *buffer;
|
||||||
|
int ret = 0;
|
||||||
|
#ifdef CONFIG_CPU_CP15_MMU
|
||||||
|
void *ctx_buf;
|
||||||
|
size_t ctx_start;
|
||||||
|
#endif
|
||||||
|
if (res == NULL || pdev->num_resources != 1 ||
|
||||||
|
!(res->flags & IORESOURCE_MEM)) {
|
||||||
|
printk(KERN_ERR "lge_panic_handler: invalid resource, %p %d "
|
||||||
|
"flags %lx\n", res, pdev->num_resources,
|
||||||
|
res ? res->flags : 0);
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_size = res->end - res->start + 1;
|
||||||
|
start = res->start;
|
||||||
|
printk(KERN_INFO "lge_panic_handler: got buffer at %zx, size %zx\n",
|
||||||
|
start, buffer_size);
|
||||||
|
buffer = ioremap(res->start, buffer_size);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
printk(KERN_ERR "lge_panic_handler: failed to map memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
crash_dump_log = (struct crash_log_dump *)buffer;
|
||||||
|
memset(crash_dump_log, 0, buffer_size);
|
||||||
|
crash_dump_log->magic_key = 0;
|
||||||
|
crash_dump_log->size = 0;
|
||||||
|
crash_buf_size = buffer_size - offsetof(struct crash_log_dump, buffer);
|
||||||
|
#ifdef CONFIG_CPU_CP15_MMU
|
||||||
|
ctx_start = res->end + 1;
|
||||||
|
ctx_buf = ioremap(ctx_start,1024);
|
||||||
|
if (ctx_buf == NULL) {
|
||||||
|
printk(KERN_ERR "cpu crash ctx buffer: "
|
||||||
|
"failed to map memory\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
cpu_crash_ctx = (unsigned long *)ctx_buf;
|
||||||
|
#endif
|
||||||
|
atomic_notifier_chain_register(&panic_notifier_list,
|
||||||
|
&panic_handler_block);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devexit panic_handler_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver panic_handler_driver __refdata = {
|
||||||
|
.probe = panic_handler_probe,
|
||||||
|
.remove = __devexit_p(panic_handler_remove),
|
||||||
|
.driver = {
|
||||||
|
.name = PANIC_HANDLER_NAME,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init lge_panic_handler_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&panic_handler_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit lge_panic_handler_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&panic_handler_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(lge_panic_handler_init);
|
||||||
|
module_exit(lge_panic_handler_exit);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("LGE panic handler driver");
|
||||||
|
MODULE_AUTHOR("SungEun Kim <cleaneye.kim@lge.com>");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
@@ -25,6 +25,11 @@
|
|||||||
#include <mach/subsystem_restart.h>
|
#include <mach/subsystem_restart.h>
|
||||||
#include <mach/subsystem_notif.h>
|
#include <mach/subsystem_notif.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
#include <mach/restart.h>
|
||||||
|
#include <mach/board_lge.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "smd_private.h"
|
#include "smd_private.h"
|
||||||
#include "ramdump.h"
|
#include "ramdump.h"
|
||||||
#include "sysmon.h"
|
#include "sysmon.h"
|
||||||
@@ -120,6 +125,10 @@ static void lpass_fatal_fn(struct work_struct *work)
|
|||||||
pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
|
pr_err("%s %s: Watchdog bite received from Q6!\n", MODULE_NAME,
|
||||||
__func__);
|
__func__);
|
||||||
lpass_log_failure_reason();
|
lpass_log_failure_reason();
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
set_ssr_magic_number("lpass");
|
||||||
|
msm_set_restart_mode(0x6d634130);
|
||||||
|
#endif
|
||||||
panic(MODULE_NAME ": Resetting the SoC");
|
panic(MODULE_NAME ": Resetting the SoC");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +144,10 @@ static void lpass_smsm_state_cb(void *data, uint32_t old_state,
|
|||||||
" new_state = 0x%x, old_state = 0x%x\n", __func__,
|
" new_state = 0x%x, old_state = 0x%x\n", __func__,
|
||||||
new_state, old_state);
|
new_state, old_state);
|
||||||
lpass_log_failure_reason();
|
lpass_log_failure_reason();
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
set_ssr_magic_number("lpass");
|
||||||
|
msm_set_restart_mode(0x6d634130);
|
||||||
|
#endif
|
||||||
panic(MODULE_NAME ": Resetting the SoC");
|
panic(MODULE_NAME ": Resetting the SoC");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,12 @@
|
|||||||
|
|
||||||
#define SCM_IO_DISABLE_PMIC_ARBITER 1
|
#define SCM_IO_DISABLE_PMIC_ARBITER 1
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
#define LGE_ERROR_HANDLER_MAGIC_NUM 0xA97F2C46
|
||||||
|
#define LGE_ERROR_HANDLER_MAGIC_ADDR 0x18
|
||||||
|
void *lge_error_handler_cookie_addr;
|
||||||
|
#endif
|
||||||
|
|
||||||
static int restart_mode;
|
static int restart_mode;
|
||||||
void *restart_reason;
|
void *restart_reason;
|
||||||
|
|
||||||
@@ -80,6 +86,10 @@ static void set_dload_mode(int on)
|
|||||||
__raw_writel(on ? 0xE47B337D : 0, dload_mode_addr);
|
__raw_writel(on ? 0xE47B337D : 0, dload_mode_addr);
|
||||||
__raw_writel(on ? 0xCE14091A : 0,
|
__raw_writel(on ? 0xCE14091A : 0,
|
||||||
dload_mode_addr + sizeof(unsigned int));
|
dload_mode_addr + sizeof(unsigned int));
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
__raw_writel(on ? LGE_ERROR_HANDLER_MAGIC_NUM : 0,
|
||||||
|
lge_error_handler_cookie_addr);
|
||||||
|
#endif
|
||||||
mb();
|
mb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,6 +187,43 @@ static irqreturn_t resout_irq_handler(int irq, void *dev_id)
|
|||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
static int ssr_magic_number = 0;
|
||||||
|
#define SUBSYS_NAME_MAX_LENGTH 40
|
||||||
|
|
||||||
|
int get_ssr_magic_number(void)
|
||||||
|
{
|
||||||
|
return ssr_magic_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ssr_magic_number(const char* subsys_name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *subsys_list[] = {
|
||||||
|
"modem", "riva", "dsps", "lpass",
|
||||||
|
"external_modem", "gss",
|
||||||
|
};
|
||||||
|
|
||||||
|
ssr_magic_number = (0x6d630000 | 0x0000f000);
|
||||||
|
|
||||||
|
for (i=0; i < ARRAY_SIZE(subsys_list); i++) {
|
||||||
|
if (!strncmp(subsys_list[i], subsys_name,
|
||||||
|
SUBSYS_NAME_MAX_LENGTH)) {
|
||||||
|
ssr_magic_number = (0x6d630000 | ((i+1)<<12));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_kernel_crash_magic_number(void)
|
||||||
|
{
|
||||||
|
if (ssr_magic_number == 0)
|
||||||
|
__raw_writel(0x6d630100, restart_reason);
|
||||||
|
else
|
||||||
|
__raw_writel(restart_mode, restart_reason);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_LGE_CRASH_HANDLER */
|
||||||
|
|
||||||
void msm_restart(char mode, const char *cmd)
|
void msm_restart(char mode, const char *cmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -189,8 +236,13 @@ void msm_restart(char mode, const char *cmd)
|
|||||||
set_dload_mode(in_panic);
|
set_dload_mode(in_panic);
|
||||||
|
|
||||||
/* Write download mode flags if restart_mode says so */
|
/* Write download mode flags if restart_mode says so */
|
||||||
if (restart_mode == RESTART_DLOAD)
|
if (restart_mode == RESTART_DLOAD) {
|
||||||
set_dload_mode(1);
|
set_dload_mode(1);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
writel(0x6d63c421, restart_reason);
|
||||||
|
goto reset;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Kill download mode if master-kill switch is set */
|
/* Kill download mode if master-kill switch is set */
|
||||||
if (!download_mode)
|
if (!download_mode)
|
||||||
@@ -201,6 +253,28 @@ void msm_restart(char mode, const char *cmd)
|
|||||||
|
|
||||||
pm8xxx_reset_pwr_off(1);
|
pm8xxx_reset_pwr_off(1);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
if (in_panic == 1) {
|
||||||
|
set_kernel_crash_magic_number();
|
||||||
|
} else {
|
||||||
|
if (cmd != NULL) {
|
||||||
|
if (!strncmp(cmd, "bootloader", 10)) {
|
||||||
|
__raw_writel(0x77665500, restart_reason);
|
||||||
|
} else if (!strncmp(cmd, "recovery", 8)) {
|
||||||
|
__raw_writel(0x77665502, restart_reason);
|
||||||
|
} else if (!strncmp(cmd, "oem-", 4)) {
|
||||||
|
unsigned long code;
|
||||||
|
code = simple_strtoul(cmd+4, NULL, 16) & 0xff;
|
||||||
|
__raw_writel(0x6f656d00, restart_reason);
|
||||||
|
} else if (!strncmp(cmd, "recovery", 8)) {
|
||||||
|
__raw_writel(0x77665502, restart_reason);
|
||||||
|
} else {
|
||||||
|
__raw_writel(0x77665501, restart_reason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reset:
|
||||||
|
#else
|
||||||
if (cmd != NULL) {
|
if (cmd != NULL) {
|
||||||
if (!strncmp(cmd, "bootloader", 10)) {
|
if (!strncmp(cmd, "bootloader", 10)) {
|
||||||
__raw_writel(0x77665500, restart_reason);
|
__raw_writel(0x77665500, restart_reason);
|
||||||
@@ -214,6 +288,7 @@ void msm_restart(char mode, const char *cmd)
|
|||||||
__raw_writel(0x77665501, restart_reason);
|
__raw_writel(0x77665501, restart_reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_LGE_CRASH_HANDLER */
|
||||||
|
|
||||||
__raw_writel(0, msm_tmr0_base + WDT0_EN);
|
__raw_writel(0, msm_tmr0_base + WDT0_EN);
|
||||||
if (!(machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())) {
|
if (!(machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())) {
|
||||||
@@ -246,6 +321,10 @@ static int __init msm_pmic_restart_init(void)
|
|||||||
pr_warn("no pmic restart interrupt specified\n");
|
pr_warn("no pmic restart interrupt specified\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
__raw_writel(0x6d63ad00, restart_reason);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,6 +335,10 @@ static int __init msm_restart_init(void)
|
|||||||
#ifdef CONFIG_MSM_DLOAD_MODE
|
#ifdef CONFIG_MSM_DLOAD_MODE
|
||||||
atomic_notifier_chain_register(&panic_notifier_list, &panic_blk);
|
atomic_notifier_chain_register(&panic_notifier_list, &panic_blk);
|
||||||
dload_mode_addr = MSM_IMEM_BASE + DLOAD_MODE_ADDR;
|
dload_mode_addr = MSM_IMEM_BASE + DLOAD_MODE_ADDR;
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
lge_error_handler_cookie_addr = MSM_IMEM_BASE +
|
||||||
|
LGE_ERROR_HANDLER_MAGIC_ADDR;
|
||||||
|
#endif
|
||||||
set_dload_mode(download_mode);
|
set_dload_mode(download_mode);
|
||||||
#endif
|
#endif
|
||||||
msm_tmr0_base = msm_timer_get_timer0_base();
|
msm_tmr0_base = msm_timer_get_timer0_base();
|
||||||
|
|||||||
@@ -35,6 +35,10 @@
|
|||||||
#include <mach/subsystem_notif.h>
|
#include <mach/subsystem_notif.h>
|
||||||
#include <mach/subsystem_restart.h>
|
#include <mach/subsystem_restart.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
#include <mach/restart.h>
|
||||||
|
#include <mach/board_lge.h>
|
||||||
|
#endif
|
||||||
#include "smd_private.h"
|
#include "smd_private.h"
|
||||||
|
|
||||||
struct subsys_soc_restart_order {
|
struct subsys_soc_restart_order {
|
||||||
@@ -209,6 +213,9 @@ static void do_epoch_check(struct subsys_device *dev)
|
|||||||
struct restart_log *r_log, *temp;
|
struct restart_log *r_log, *temp;
|
||||||
static int max_restarts_check;
|
static int max_restarts_check;
|
||||||
static long max_history_time_check;
|
static long max_history_time_check;
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
int ssr_magic_number = get_ssr_magic_number();
|
||||||
|
#endif
|
||||||
|
|
||||||
mutex_lock(&restart_log_mutex);
|
mutex_lock(&restart_log_mutex);
|
||||||
|
|
||||||
@@ -250,10 +257,14 @@ static void do_epoch_check(struct subsys_device *dev)
|
|||||||
|
|
||||||
if (time_first && n >= max_restarts_check) {
|
if (time_first && n >= max_restarts_check) {
|
||||||
if ((curr_time->tv_sec - time_first->tv_sec) <
|
if ((curr_time->tv_sec - time_first->tv_sec) <
|
||||||
max_history_time_check)
|
max_history_time_check) {
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
msm_set_restart_mode(ssr_magic_number | SUB_UNAB_THD);
|
||||||
|
#endif
|
||||||
panic("Subsystems have crashed %d times in less than "
|
panic("Subsystems have crashed %d times in less than "
|
||||||
"%ld seconds!", max_restarts_check,
|
"%ld seconds!", max_restarts_check,
|
||||||
max_history_time_check);
|
max_history_time_check);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -287,11 +298,18 @@ static void send_notification_to_order(struct subsys_device **l, unsigned n,
|
|||||||
static void subsystem_shutdown(struct subsys_device *dev, void *data)
|
static void subsystem_shutdown(struct subsys_device *dev, void *data)
|
||||||
{
|
{
|
||||||
const char *name = dev->desc->name;
|
const char *name = dev->desc->name;
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
int ssr_magic_number = get_ssr_magic_number();
|
||||||
|
#endif
|
||||||
|
|
||||||
pr_info("[%p]: Shutting down %s\n", current, name);
|
pr_info("[%p]: Shutting down %s\n", current, name);
|
||||||
if (dev->desc->shutdown(dev->desc) < 0)
|
if (dev->desc->shutdown(dev->desc) < 0) {
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
msm_set_restart_mode(ssr_magic_number | SUB_THD_F_SD);
|
||||||
|
#endif
|
||||||
panic("subsys-restart: [%p]: Failed to shutdown %s!",
|
panic("subsys-restart: [%p]: Failed to shutdown %s!",
|
||||||
current, name);
|
current, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subsystem_ramdump(struct subsys_device *dev, void *data)
|
static void subsystem_ramdump(struct subsys_device *dev, void *data)
|
||||||
@@ -324,6 +342,10 @@ static void subsystem_restart_wq_func(struct work_struct *work)
|
|||||||
unsigned count;
|
unsigned count;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
int ssr_magic_number = get_ssr_magic_number();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (restart_level != RESET_SUBSYS_INDEPENDENT)
|
if (restart_level != RESET_SUBSYS_INDEPENDENT)
|
||||||
soc_restart_order = dev->restart_order;
|
soc_restart_order = dev->restart_order;
|
||||||
|
|
||||||
@@ -361,9 +383,13 @@ static void subsystem_restart_wq_func(struct work_struct *work)
|
|||||||
* sequence for these subsystems. In the latter case, panic and bail
|
* sequence for these subsystems. In the latter case, panic and bail
|
||||||
* out, since a subsystem died in its powerup sequence.
|
* out, since a subsystem died in its powerup sequence.
|
||||||
*/
|
*/
|
||||||
if (!mutex_trylock(powerup_lock))
|
if (!mutex_trylock(powerup_lock)) {
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
msm_set_restart_mode(ssr_magic_number | SUB_THD_F_PWR);
|
||||||
|
#endif
|
||||||
panic("%s[%p]: Subsystem died during powerup!",
|
panic("%s[%p]: Subsystem died during powerup!",
|
||||||
__func__, current);
|
__func__, current);
|
||||||
|
}
|
||||||
|
|
||||||
do_epoch_check(dev);
|
do_epoch_check(dev);
|
||||||
|
|
||||||
@@ -437,10 +463,18 @@ static void __subsystem_restart_dev(struct subsys_device *dev)
|
|||||||
int subsystem_restart_dev(struct subsys_device *dev)
|
int subsystem_restart_dev(struct subsys_device *dev)
|
||||||
{
|
{
|
||||||
const char *name = dev->desc->name;
|
const char *name = dev->desc->name;
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
u32 ssr_magic_number;
|
||||||
|
#endif
|
||||||
|
|
||||||
pr_info("Restart sequence requested for %s, restart_level = %d.\n",
|
pr_info("Restart sequence requested for %s, restart_level = %d.\n",
|
||||||
name, restart_level);
|
name, restart_level);
|
||||||
|
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
set_ssr_magic_number(subsys_name);
|
||||||
|
ssr_magic_number = get_ssr_magic_number();
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (restart_level) {
|
switch (restart_level) {
|
||||||
|
|
||||||
case RESET_SUBSYS_COUPLED:
|
case RESET_SUBSYS_COUPLED:
|
||||||
@@ -448,9 +482,15 @@ int subsystem_restart_dev(struct subsys_device *dev)
|
|||||||
__subsystem_restart_dev(dev);
|
__subsystem_restart_dev(dev);
|
||||||
break;
|
break;
|
||||||
case RESET_SOC:
|
case RESET_SOC:
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
msm_set_restart_mode(ssr_magic_number | SUB_RESET_SOC);
|
||||||
|
#endif
|
||||||
panic("subsys-restart: Resetting the SoC - %s crashed.", name);
|
panic("subsys-restart: Resetting the SoC - %s crashed.", name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#if defined(CONFIG_LGE_CRASH_HANDLER)
|
||||||
|
msm_set_restart_mode(ssr_magic_number | SUB_UNKNOWN);
|
||||||
|
#endif
|
||||||
panic("subsys-restart: Unknown restart level!\n");
|
panic("subsys-restart: Unknown restart level!\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,6 +349,17 @@ extern int func_ptr_is_kernel_text(void *ptr);
|
|||||||
struct pid;
|
struct pid;
|
||||||
extern struct pid *session_of_pgrp(struct pid *pgrp);
|
extern struct pid *session_of_pgrp(struct pid *pgrp);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
extern void set_crash_store_enable(void);
|
||||||
|
extern void set_crash_store_disable(void);
|
||||||
|
extern void store_crash_log(char *p);
|
||||||
|
extern void set_kernel_crash_magic_number(void);
|
||||||
|
#ifdef CONFIG_CPU_CP15_MMU
|
||||||
|
extern void lge_save_ctx(struct pt_regs*, unsigned int, unsigned int,
|
||||||
|
unsigned int);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long int_sqrt(unsigned long);
|
unsigned long int_sqrt(unsigned long);
|
||||||
|
|
||||||
extern void bust_spinlocks(int yes);
|
extern void bust_spinlocks(int yes);
|
||||||
|
|||||||
@@ -106,7 +106,14 @@ void panic(const char *fmt, ...)
|
|||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
set_kernel_crash_magic_number();
|
||||||
|
set_crash_store_enable();
|
||||||
|
#endif
|
||||||
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
|
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
set_crash_store_disable();
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||||
/*
|
/*
|
||||||
* Avoid nested stack-dumping if a panic occurs during oops processing
|
* Avoid nested stack-dumping if a panic occurs during oops processing
|
||||||
|
|||||||
@@ -940,6 +940,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
|
|||||||
|
|
||||||
|
|
||||||
p = printk_buf;
|
p = printk_buf;
|
||||||
|
#ifdef CONFIG_LGE_CRASH_HANDLER
|
||||||
|
store_crash_log(p);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Read log level and handle special printk prefix */
|
/* Read log level and handle special printk prefix */
|
||||||
plen = log_prefix(p, ¤t_log_level, &special);
|
plen = log_prefix(p, ¤t_log_level, &special);
|
||||||
|
|||||||
Reference in New Issue
Block a user