huawei-mrd-kernel/drivers/hwzerohung/watchpoint/zrhung_wp_sochalt.c

148 lines
4 KiB
C
Executable file

#include <linux/sched.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
#include <linux/aio.h>
#include <uapi/linux/uio.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/syscalls.h>
#include <chipset_common/hwzrhung/zrhung.h>
#include "../zrhung_common.h"
#include <chipset_common/hwerecovery/erecovery.h>
#include "zrhung_wp_sochalt.h"
static int is_soc_halt;
static int is_longpress;
static int is_coldboot;
#define SOCHALT_INFO "BR_PRESS_10S"
#define ZRHUNG_POWERKEY_LONGPRESS_EVENT "AP_S_PRESS6S"
#define ZRHUNG_RECOVERY_COLDBOOT "COLDBOOT"
#define ZRHUNG_VMWTG_ERECOVERYID 401006000
#define ZRHUNG_VMWTG_FAULTID 901004000
#define SR_POSITION_KEYWORD "sr position:"
#define FASTBOOT_LOG_PATH "/proc/balong/log/fastboot_log"
#define BUFFER_SIZE_FASTBOOT (4 * 1024) //4KB buffer for reading fastboot log
static int __init wp_reboot_reason_cmdline(char *reboot_reason_cmdline)
{
if (!strcmp(reboot_reason_cmdline, SOCHALT_INFO)) { /*lint !e421*/
printk(KERN_ERR "%s %d: LONGPRESS10S_EVENT happen! should report zerohung. \n", __FUNCTION__, __LINE__);
#ifndef CONFIG_MTK_PLATFORM
printk(KERN_ERR "%s %d: LONGPRESS10S_EVENT happen! should report zerohung. not mtk platform \n", __FUNCTION__, __LINE__);
is_soc_halt = 1;
#endif
return 0;
}
if (!strcmp(reboot_reason_cmdline, ZRHUNG_POWERKEY_LONGPRESS_EVENT)) { /*lint !e421*/
printk(KERN_ERR "%s %d: LONGPRESS6S_EVENT happen! should report zerohung. \n", __FUNCTION__, __LINE__);
is_longpress = 1;
} else if (!strcmp(reboot_reason_cmdline, ZRHUNG_RECOVERY_COLDBOOT)) {/* lint !e421*/
printk(KERN_ERR "%s %d: COLDBOOT, maybe VMWTG-surfaceflinger recovery. \n", __FUNCTION__, __LINE__);
is_coldboot = 1;
}
return 0;
}
early_param("reboot_reason", wp_reboot_reason_cmdline);
void zrhung_report_endrecovery(void)
{
#ifdef CONFIG_HW_ERECOVERY
if (is_coldboot) {
erecovery_eventobj rp;
long ret = 0;
memset(&rp, 0, sizeof(erecovery_eventobj));
rp.erecovery_id = ZRHUNG_VMWTG_ERECOVERYID;
rp.fault_id = ZRHUNG_VMWTG_FAULTID;
rp.state = EVENT_END;
ret = erecovery_report(&rp);
if (!ret)
printk(KERN_ERR "%s %d: VMWTG-surfaceflinger recovery end report failed. \n", __FUNCTION__, __LINE__);
}
#endif
}
void zrhung_get_longpress_event(void)
{
if (is_soc_halt || is_longpress) {
printk(KERN_ERR "%s %d: POWERKEY_LONGPRESS_EVENT send to zerohung. \n", __FUNCTION__, __LINE__);
zrhung_send_event(ZRHUNG_EVENT_LONGPRESS, NULL, NULL);
}
}
int wp_get_sochalt(zrhung_write_event* we)
{
if (!we) {
printk(KERN_ERR "%s %d: param error\n", __FUNCTION__, __LINE__);
return -1;
}
memset(we, 0, sizeof(*we));
if (is_soc_halt) {
we->magic = MAGIC_NUM;
we->len = sizeof(*we);
we->wp_id = ZRHUNG_WP_SR;
printk(KERN_ERR "%s %d: soc halt\n", __FUNCTION__, __LINE__);
}
return 0;
}
void get_sr_position_from_fastboot(char *dst, unsigned int max_dst_size)
{
mm_segment_t old_fs;
char * reading_buf = NULL;
char *plog = NULL;
int fd;
unsigned int i;
old_fs = get_fs();
set_fs(KERNEL_DS);
fd = sys_open(FASTBOOT_LOG_PATH, O_RDONLY, 0);
if ( fd < 0 ){
printk(KERN_ERR "%s %d: fail to open fastbootlog\n", __FUNCTION__, __LINE__);
goto __out ;
}
reading_buf = (char *)kzalloc(BUFFER_SIZE_FASTBOOT + 1, GFP_KERNEL);
if ( NULL == reading_buf ) {
printk(KERN_ERR "%s %d: alloc fail\n", __FUNCTION__, __LINE__);
goto __out;
}
while ( sys_read( fd, reading_buf, BUFFER_SIZE_FASTBOOT ) >0 ){
if ( (plog = strstr(reading_buf, SR_POSITION_KEYWORD) ) != NULL ){
if ( (BUFFER_SIZE_FASTBOOT - (plog - reading_buf)) < max_dst_size ){
strncpy(dst, plog, BUFFER_SIZE_FASTBOOT - (plog - reading_buf));
break;
}
i = 0;
while ( plog[i] != '\r' && plog[i] != '\n' && i < max_dst_size ){
dst[i] = plog[i];
i ++;
}
dst[max_dst_size -1] = 0;
break ;
}
}
__out:
if (fd >= 0){
sys_close(fd);
}
if (reading_buf != NULL){
kfree(reading_buf);
}
set_fs(old_fs);
return ;
}