mako: debug: porting lge crash handler

Change-Id: I913d372131a25bb9c0d90680f5e96cebb8883055
Signed-off-by: Iliyan Malchev <malchev@google.com>
This commit is contained in:
Jaeseong GIM
2012-06-26 10:36:57 -07:00
committed by Iliyan Malchev
parent 7e8f0f7574
commit 93c86c992b
16 changed files with 560 additions and 13 deletions

View File

@@ -45,6 +45,7 @@ CONFIG_MSM_KRAIT_TBB_ABORT_HANDLER=y
CONFIG_MACH_MSM_DUMMY=y
CONFIG_BOARD_HEADER_FILE="mach/lge/board_mako.h"
CONFIG_MACH_APQ8064_MAKO=y
CONFIG_LGE_CRASH_HANDLER=y
CONFIG_LGE_QFPROM_INTERFACE=y
CONFIG_UPDATE_LCDC_LUT=y
CONFIG_LCD_KCAL=y

View File

@@ -412,6 +412,12 @@ void __show_regs(struct pt_regs *regs)
unsigned long flags;
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",
raw_smp_processor_id(), print_tainted(),
init_utsname()->release,
@@ -419,7 +425,11 @@ void __show_regs(struct pt_regs *regs)
init_utsname()->version);
print_symbol("PC is at %s\n", instruction_pointer(regs));
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"
#endif
"sp : %08lx ip : %08lx fp : %08lx\n",
regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
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",
regs->ARM_r3, regs->ARM_r2,
regs->ARM_r1, regs->ARM_r0);
#ifdef CONFIG_LGE_CRASH_HANDLER
set_crash_store_disable();
#endif
flags = regs->ARM_cpsr;
buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
@@ -459,11 +472,18 @@ void __show_regs(struct pt_regs *regs)
: "=r" (transbase), "=r" (dac));
snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
transbase, dac);
#if defined(CONFIG_CPU_CP15_MMU) && defined(CONFIG_LGE_CRASH_HANDLER)
c1 = transbase;
c2 = dac;
#endif
}
#endif
asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
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

View File

@@ -39,6 +39,10 @@
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;
#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)
{
#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);
#ifdef CONFIG_LGE_CRASH_HANDLER
set_crash_store_disable();
#endif
#else
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
@@ -239,9 +250,22 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
static int die_counter;
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
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 */
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
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));
dump_backtrace(regs, tsk);
dump_instr(KERN_EMERG, regs);
#ifdef CONFIG_LGE_CRASH_HANDLER
first_call_chain = 0;
#endif
}
return ret;

View File

@@ -23,7 +23,7 @@
#define LGE_RAM_CONSOLE_SIZE (124*SZ_1K * 2)
#endif
#ifdef CONFIG_LGE_HANDLE_PANIC
#ifdef CONFIG_LGE_CRASH_HANDLER
#define LGE_CRASH_LOG_SIZE (4*SZ_1K)
#endif
@@ -129,10 +129,10 @@ enum lge_boot_mode_type {
void __init lge_add_ramconsole_devices(void);
#endif
#ifdef CONFIG_LGE_HANDLE_PANIC
#ifdef CONFIG_LGE_CRASH_HANDLER
void __init lge_add_panic_handler_devices(void);
int lge_get_magic_for_subsystem(void);
void lge_set_magic_for_subsystem(const char *subsys_name);
int get_ssr_magic_number(void);
void set_ssr_magic_number(const char *subsys_name);
#endif
#ifdef CONFIG_LGE_QFPROM_INTERFACE

View File

@@ -94,6 +94,10 @@ extern void l2x0_cache_sync(void);
#if defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
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)
#endif

View File

@@ -17,6 +17,14 @@
#define RESTART_NORMAL 0x0
#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)
void msm_set_restart_mode(int mode);
void msm_restart(char mode, const char *cmd);

View File

@@ -35,4 +35,11 @@ config EARJACK_DEBUGGER
default n
help
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

View File

@@ -6,4 +6,5 @@ obj-$(CONFIG_MACH_LGE) += devices_lge.o
obj-$(CONFIG_LGE_QFPROM_INTERFACE) += lge_qfprom_access.o
obj-$(CONFIG_LGE_QC_LCDC_LUT) += lge_qc_lcdc_luts.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

View File

@@ -343,7 +343,7 @@ void __init lge_add_ramconsole_devices(void)
struct resource* res = ram_console_resource;
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;
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);
}
#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[] = {
{
.name = "crash_log",
@@ -383,7 +383,7 @@ void __init lge_add_panic_handler_devices(void)
platform_device_register(&panic_handler_device);
}
#endif // CONFIG_LGE_HANDLE_PANIC
#endif /* CONFIG_LGE_CRASH_HANDLER */
#ifdef CONFIG_LGE_QFPROM_INTERFACE
static struct platform_device qfprom_device = {

View 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");

View File

@@ -25,6 +25,11 @@
#include <mach/subsystem_restart.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 "ramdump.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,
__func__);
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");
}
@@ -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, old_state);
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");
}
}

View File

@@ -47,6 +47,12 @@
#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;
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 ? 0xCE14091A : 0,
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();
}
}
@@ -177,6 +187,43 @@ static irqreturn_t resout_irq_handler(int irq, void *dev_id)
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)
{
@@ -189,8 +236,13 @@ void msm_restart(char mode, const char *cmd)
set_dload_mode(in_panic);
/* Write download mode flags if restart_mode says so */
if (restart_mode == RESTART_DLOAD)
if (restart_mode == RESTART_DLOAD) {
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 */
if (!download_mode)
@@ -201,6 +253,28 @@ void msm_restart(char mode, const char *cmd)
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 (!strncmp(cmd, "bootloader", 10)) {
__raw_writel(0x77665500, restart_reason);
@@ -214,6 +288,7 @@ void msm_restart(char mode, const char *cmd)
__raw_writel(0x77665501, restart_reason);
}
}
#endif /* CONFIG_LGE_CRASH_HANDLER */
__raw_writel(0, msm_tmr0_base + WDT0_EN);
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");
}
#ifdef CONFIG_LGE_CRASH_HANDLER
__raw_writel(0x6d63ad00, restart_reason);
#endif
return 0;
}
@@ -256,6 +335,10 @@ static int __init msm_restart_init(void)
#ifdef CONFIG_MSM_DLOAD_MODE
atomic_notifier_chain_register(&panic_notifier_list, &panic_blk);
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);
#endif
msm_tmr0_base = msm_timer_get_timer0_base();

View File

@@ -35,6 +35,10 @@
#include <mach/subsystem_notif.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"
struct subsys_soc_restart_order {
@@ -209,6 +213,9 @@ static void do_epoch_check(struct subsys_device *dev)
struct restart_log *r_log, *temp;
static int max_restarts_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);
@@ -250,10 +257,14 @@ static void do_epoch_check(struct subsys_device *dev)
if (time_first && n >= max_restarts_check) {
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 "
"%ld seconds!", max_restarts_check,
max_history_time_check);
}
}
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)
{
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);
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!",
current, name);
}
}
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 long flags;
#if defined(CONFIG_LGE_CRASH_HANDLER)
int ssr_magic_number = get_ssr_magic_number();
#endif
if (restart_level != RESET_SUBSYS_INDEPENDENT)
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
* 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!",
__func__, current);
}
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)
{
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",
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) {
case RESET_SUBSYS_COUPLED:
@@ -448,9 +482,15 @@ int subsystem_restart_dev(struct subsys_device *dev)
__subsystem_restart_dev(dev);
break;
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);
break;
default:
#if defined(CONFIG_LGE_CRASH_HANDLER)
msm_set_restart_mode(ssr_magic_number | SUB_UNKNOWN);
#endif
panic("subsys-restart: Unknown restart level!\n");
break;
}

View File

@@ -349,6 +349,17 @@ extern int func_ptr_is_kernel_text(void *ptr);
struct pid;
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);
extern void bust_spinlocks(int yes);

View File

@@ -106,7 +106,14 @@ void panic(const char *fmt, ...)
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, 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);
#ifdef CONFIG_LGE_CRASH_HANDLER
set_crash_store_disable();
#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
/*
* Avoid nested stack-dumping if a panic occurs during oops processing

View File

@@ -940,6 +940,9 @@ asmlinkage int vprintk(const char *fmt, va_list args)
p = printk_buf;
#ifdef CONFIG_LGE_CRASH_HANDLER
store_crash_log(p);
#endif
/* Read log level and handle special printk prefix */
plen = log_prefix(p, &current_log_level, &special);