Remove amazon logging function drivers
This commit is contained in:
@@ -140,6 +140,4 @@ source "drivers/staging/netlogic/Kconfig"
|
||||
|
||||
source "drivers/staging/dwc2/Kconfig"
|
||||
|
||||
source "drivers/staging/amazon/Kconfig"
|
||||
|
||||
endif # STAGING
|
||||
|
||||
@@ -62,4 +62,3 @@ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
|
||||
obj-$(CONFIG_ZCACHE) += zcache/
|
||||
obj-$(CONFIG_GOLDFISH) += goldfish/
|
||||
obj-$(CONFIG_USB_DWC2) += dwc2/
|
||||
obj-$(CONFIG_AMAZON) += amazon/
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
menu "AMAZON"
|
||||
|
||||
config AMAZON
|
||||
bool "Amazon Drivers"
|
||||
default N
|
||||
---help---
|
||||
Enable support for various drivers needed on the Amazon FireOS platform
|
||||
|
||||
if AMAZON
|
||||
|
||||
config IDME
|
||||
bool "IDME support"
|
||||
depends on PROC_FS
|
||||
default N
|
||||
help
|
||||
Select Y here to enable IDME support to read the data
|
||||
via userspace (i.e. /proc/idme/* entries)
|
||||
|
||||
config AMAZON_LOGD
|
||||
bool "Amazon Logd"
|
||||
depends on ANDROID_LOGGER
|
||||
default N
|
||||
---help---
|
||||
device uses logd for logging
|
||||
|
||||
config AMAZON_KLOG_CONSOLE
|
||||
bool "Amazon Kernel Log Console"
|
||||
depends on ANDROID_LOGGER
|
||||
default N
|
||||
help
|
||||
provide the kernel log console which will rewrite the kernel message to Android Logger buffer.
|
||||
|
||||
config AMAZON_SIGN_OF_LIFE
|
||||
bool "Amazon Sign of Life"
|
||||
help
|
||||
enable the life cycle metrics to log device boot and shutdown information
|
||||
|
||||
config AMAZON_SIGN_OF_LIFE_MTK
|
||||
bool "Amazon Sign of Life MTK platform implementation"
|
||||
help
|
||||
enable the life cycle metrics to log device boot and shutdown information on MTK Platform
|
||||
|
||||
config AMAZON_POWEROFF_LOG
|
||||
bool "Long press key power off log"
|
||||
default N
|
||||
help
|
||||
enable Long press key power off log
|
||||
|
||||
config MDUMP
|
||||
bool "Generic memory dump"
|
||||
default n
|
||||
help
|
||||
The module allow support mdump feature, It need bootloader's support. when
|
||||
panic, it will do a mark, and bootloader can store all memory to analyze.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config MDUMP_COMPRESS
|
||||
bool "Compress memory dump"
|
||||
default n
|
||||
help
|
||||
The module supports compressed ramdump, which allows ramdump to be written
|
||||
to userdata partition instead of a dedicate DUMP partition.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config MDUMP_BUFFER_ADDRESS
|
||||
hex "MDUMP Memory Buffer Address"
|
||||
default 0x81FC0000
|
||||
depends on MDUMP
|
||||
help
|
||||
Set mdump buffer address for mdump module. This address will share with bootloader
|
||||
Make sure you also changed this value on bootloader config code
|
||||
|
||||
config MDUMP_MESSAGE_SIZE
|
||||
hex "MDUMP Memory Buffer Message Size"
|
||||
default 0x10000
|
||||
depends on MDUMP
|
||||
help
|
||||
Set mdump buffer size for mdump module. This size will share with bootloader
|
||||
Make sure you also changed this value on bootloader config code
|
||||
There are two stage messages. So mdump buffer's real size is MDUMP_MESSAGE_SIZE * 2
|
||||
|
||||
config AMAZON_LL_LOG
|
||||
bool "Low Level Log Support"
|
||||
depends on PROC_FS
|
||||
default n
|
||||
help
|
||||
Cache the log of LK and Preloader at /proc/pllk.
|
||||
|
||||
config AMAZON_LOW_LEVEL_LOG_DRAM_ADDR
|
||||
hex "Amazon low level log dram addr"
|
||||
default 0
|
||||
depends on AMAZON_LL_LOG
|
||||
|
||||
config AMAZON_LOW_LEVEL_LOG_DRAM_SIZE
|
||||
hex "Amazon low level log dram size"
|
||||
default 0
|
||||
depends on AMAZON_LL_LOG
|
||||
|
||||
endif # if AMAZON
|
||||
|
||||
endmenu
|
||||
@@ -1,8 +0,0 @@
|
||||
obj-$(CONFIG_IDME) += idme.o
|
||||
obj-$(CONFIG_AMAZON_KLOG_CONSOLE) += klog_console.o
|
||||
obj-$(CONFIG_MDUMP) += mdump.o
|
||||
obj-$(CONFIG_AMAZON_SIGN_OF_LIFE) += sign_of_life.o
|
||||
obj-$(CONFIG_AMAZON_SIGN_OF_LIFE_MTK) += sign_of_life_mtk.o
|
||||
ifeq ($(CONFIG_AMAZON_LL_LOG),y)
|
||||
obj-$(CONFIG_AMAZON_LL_LOG) += amazon_ll_log.o
|
||||
endif
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* amazon_ll_log.c
|
||||
*
|
||||
* Store low level software log to /proc/pllk.
|
||||
*
|
||||
* Copyright (C) 2017 Amazon Technologies Inc. All rights reserved.
|
||||
* Qiang Liu (qanliu@amazon.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_fdt.h>
|
||||
#endif
|
||||
|
||||
#define LOG_MAGIC 0x414d5a4e /* "AMZN" */
|
||||
|
||||
static u32 amazonlog_base = CONFIG_AMAZON_LOW_LEVEL_LOG_DRAM_ADDR;
|
||||
static u32 amazonlog_size = CONFIG_AMAZON_LOW_LEVEL_LOG_DRAM_SIZE;
|
||||
|
||||
/* These variables are also protected by logbuf_lock */
|
||||
static char *amazon_log_buf;
|
||||
static unsigned int *amazon_log_pos;
|
||||
static unsigned int amazon_log_size;
|
||||
static int amazonlogging;
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int __init amazon_log_fdt_find_info(unsigned long node, const char *uname,
|
||||
int depth, void *data)
|
||||
{
|
||||
__be32 *prop;
|
||||
unsigned long len;
|
||||
|
||||
prop = of_get_flat_dt_prop(node, "amazonlog-base", &len);
|
||||
if (!prop || (len != sizeof(unsigned int))) {
|
||||
pr_err("%s: Can't find amazon log-base property\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
amazonlog_base = be32_to_cpu(prop[0]);
|
||||
|
||||
prop = of_get_flat_dt_prop(node, "amazonlog-size", &len);
|
||||
if (!prop || (len != sizeof(unsigned int))) {
|
||||
pr_err("%s: Can't find amazon log-size property\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
amazonlog_size = be32_to_cpu(prop[0]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void amazon_log_buf_write(struct console *console, const char *text,
|
||||
unsigned int size)
|
||||
{
|
||||
if (amazon_log_buf && amazon_log_pos) {
|
||||
unsigned int pos = *amazon_log_pos;
|
||||
|
||||
if (likely(size + pos <= amazon_log_size)) {
|
||||
memcpy(&amazon_log_buf[pos], text, size);
|
||||
} else {
|
||||
unsigned int first = amazon_log_size - pos;
|
||||
unsigned int second = size - first;
|
||||
memcpy(&amazon_log_buf[pos], text, first);
|
||||
memcpy(&amazon_log_buf[0], text + first, second);
|
||||
}
|
||||
|
||||
(*amazon_log_pos) += size; /* Check overflow */
|
||||
if (unlikely(*amazon_log_pos >= amazon_log_size))
|
||||
*amazon_log_pos -= amazon_log_size;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int amazon_ll_log_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_write(m, amazon_log_buf, amazonlog_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amazon_ll_log_file_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, amazon_ll_log_show, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations amazon_ll_log_file_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = amazon_ll_log_file_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static void *remap_lowmem(phys_addr_t start, phys_addr_t size)
|
||||
{
|
||||
struct page **pages;
|
||||
phys_addr_t page_start;
|
||||
unsigned int page_count;
|
||||
pgprot_t prot;
|
||||
unsigned int i;
|
||||
void *vaddr;
|
||||
|
||||
page_start = start - offset_in_page(start);
|
||||
page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE);
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
prot = pgprot_writecombine(PAGE_KERNEL);
|
||||
#else
|
||||
prot = pgprot_noncached(PAGE_KERNEL);
|
||||
#endif
|
||||
pages = kmalloc(sizeof(struct page *) * page_count, GFP_KERNEL);
|
||||
if (!pages) {
|
||||
pr_err("%s: Failed to allocate array for %u pages\n", __func__, page_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < page_count; i++) {
|
||||
phys_addr_t addr = page_start + i * PAGE_SIZE;
|
||||
pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
vaddr = vmap(pages, page_count, VM_MAP, prot);
|
||||
kfree(pages);
|
||||
if (!vaddr) {
|
||||
pr_err("%s: Failed to map %u pages\n", __func__, page_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vaddr + offset_in_page(start);
|
||||
}
|
||||
|
||||
static int __init amazon_log_buf_init(void)
|
||||
{
|
||||
unsigned int *amazon_log_mag;
|
||||
void *vaddr;
|
||||
struct proc_dir_entry *entry;
|
||||
unsigned int len = 0;
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
if (of_scan_flat_dt(amazonlog_fdt_find_info, NULL)) {
|
||||
BUG_ON(memblock_reserve(amazonlog_base, amazonlog_size) != 0);
|
||||
pr_info("Reserved amazon log memory : %dMB at %#.8x\n",
|
||||
((unsigned)amazonlog_size >> 20), (unsigned)amazonlog_base);
|
||||
}
|
||||
#endif
|
||||
vaddr = remap_lowmem(amazonlog_base, amazonlog_size);
|
||||
amazon_log_size = amazonlog_size - (sizeof(*amazon_log_pos) + sizeof(*amazon_log_mag));
|
||||
amazon_log_buf = vaddr;
|
||||
amazon_log_pos = (unsigned int *)(vaddr + amazon_log_size);
|
||||
amazon_log_mag = (unsigned int *)(vaddr + amazon_log_size + sizeof(*amazon_log_pos));
|
||||
|
||||
do {
|
||||
len += printk(KERN_WARNING "%s", amazon_log_buf+len);
|
||||
len++;
|
||||
} while (len < *amazon_log_pos);
|
||||
|
||||
pr_warning("%s: *amazon_log_mag:%x *amazon_log_pos:%x "
|
||||
"amazon_log_buf:%p amazon_log_size:%u\n",
|
||||
__func__, *amazon_log_mag, *amazon_log_pos, amazon_log_buf,
|
||||
amazon_log_size);
|
||||
|
||||
if (*amazon_log_mag != LOG_MAGIC) {
|
||||
pr_warning("%s: no old log found\n", __func__);
|
||||
*amazon_log_pos = 0;
|
||||
*amazon_log_mag = LOG_MAGIC;
|
||||
}
|
||||
|
||||
/* save the pre-console log into amazon log buffer */
|
||||
|
||||
amazonlogging = 1;
|
||||
/* register_log_text_hook(emit_amazon_log, amazon_log_buf, amazon_log_size); */
|
||||
entry = proc_create("pllk", 0444, NULL, &amazon_ll_log_file_ops);
|
||||
if (!entry) {
|
||||
pr_err("ram_console: failed to create proc entry\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
console_initcall(amazon_log_buf_init);
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* board IDME driver
|
||||
*
|
||||
* Copyright (C) 2015 Amazon Inc., All Rights Reserved.
|
||||
*
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/bugs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
|
||||
#define DRIVER_VER "2.0"
|
||||
|
||||
/* Idme proc dir */
|
||||
#define IDME_PROC_DIR "idme"
|
||||
#define IDME_MAGIC_NUMBER "beefdeed"
|
||||
#define IDME_MAX_NAME_LEN 16
|
||||
|
||||
#define MAC_SEC_KEY "mac_sec"
|
||||
#define MAC_SEC_OWNER 1000
|
||||
|
||||
#define DRIVER_INFO "Lab126 IDME driver version " DRIVER_VER
|
||||
#define IDME_ATAG_SIZE 2048
|
||||
#define IDME_MAX_ITEMS 50
|
||||
extern unsigned char system_idme[IDME_ATAG_SIZE+1];
|
||||
static unsigned char idme_item_name[IDME_MAX_ITEMS][IDME_MAX_NAME_LEN];
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#define IDME_ITEM_NEXT(curr_item) \
|
||||
curr_item = (struct item_t *)((char *)curr_item + sizeof(struct idme_desc) + curr_item->desc.size)
|
||||
|
||||
/* data structure definition for IDME */
|
||||
struct idme_desc {
|
||||
char name[IDME_MAX_NAME_LEN];
|
||||
unsigned int size;
|
||||
unsigned int exportable;
|
||||
unsigned int permission;
|
||||
};
|
||||
|
||||
struct item_t {
|
||||
struct idme_desc desc;
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
struct idme_t {
|
||||
char magic[8];
|
||||
char version[4];
|
||||
unsigned int items_num;
|
||||
|
||||
unsigned char item_data[0];
|
||||
};
|
||||
|
||||
|
||||
int idme_check_magic_number(struct idme_t *pidme)
|
||||
{
|
||||
if(pidme == NULL) {
|
||||
printk(KERN_ERR "IDME: the pointer of pidme_data is NULL.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(pidme->magic, IDME_MAGIC_NUMBER, strlen(IDME_MAGIC_NUMBER))){
|
||||
printk(KERN_ERR "IDME: idme data is invalid!\n");
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*#define FORD_HVT_DEVICE_ID_DEFAULT*/
|
||||
/* to be removed when this field is written in factory and populated in LK */
|
||||
#if defined(FORD_HVT_DEVICE_ID_DEFAULT)
|
||||
static unsigned char ford_device_type[]="A2M4YX06LWP8WI";
|
||||
static unsigned char ford_device_type_name[]="device_type_id";
|
||||
#endif
|
||||
|
||||
int idme_get_var(const char *name, char *buf, unsigned int length)
|
||||
{
|
||||
int ret = -1;
|
||||
unsigned int i = 0;
|
||||
struct idme_t *pdata = (struct idme_t *)&system_idme[0];
|
||||
struct item_t *pitem = NULL;
|
||||
|
||||
if (0 != idme_check_magic_number(pdata)){
|
||||
printk(KERN_ERR "The idme magic number error.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == buf)
|
||||
return -1;
|
||||
|
||||
#if defined(FORD_HVT_DEVICE_ID_DEFAULT)
|
||||
if (strcmp(name, ford_device_type_name) == 0)
|
||||
{
|
||||
ret = sizeof(ford_device_type);
|
||||
printk(KERN_ERR "%s: ford_device_type = %s[%d]\n",__func__,ford_device_type,ret);
|
||||
memcpy(buf,ford_device_type,ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
pitem = (struct item_t *)(&(pdata->item_data[0]));
|
||||
for (i = 0; i < pdata->items_num; i++) {
|
||||
if ( 0 == strcmp(name, pitem->desc.name) ) {
|
||||
memcpy(buf, &(pitem->data[0]), MIN( pitem->desc.size, length ) );
|
||||
ret = MIN(pitem->desc.size, length);
|
||||
break;
|
||||
}else{
|
||||
IDME_ITEM_NEXT(pitem);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t idme_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char *idme_item_name;
|
||||
unsigned char idme_item_data[1028] = {'\0'};
|
||||
int idme_item_size = 0;
|
||||
size_t size = 0;
|
||||
loff_t pos = *ppos;
|
||||
|
||||
idme_item_name = PDE_DATA(file_inode(file));
|
||||
if(!(idme_item_name)){
|
||||
printk(KERN_ERR "IDME Name is Null");
|
||||
return 0;
|
||||
}
|
||||
//printk(KERN_ERR "%s: item name is %s %zx %d\n", __func__, idme_item_name, count, (int)pos);
|
||||
|
||||
idme_item_size = idme_get_var((const char*)idme_item_name, idme_item_data, sizeof(idme_item_data));
|
||||
if (pos >= idme_item_size) return 0;
|
||||
if (idme_item_size > 0) {
|
||||
size = MIN(count, idme_item_size);
|
||||
copy_to_user(buf,idme_item_data, size);
|
||||
} else {
|
||||
printk(KERN_ERR "%s: idme read error\n", __func__);
|
||||
}
|
||||
|
||||
if ((ssize_t) size > 0)
|
||||
*ppos = pos + size;
|
||||
return size;
|
||||
}
|
||||
|
||||
static const struct file_operations idme_proc_fops = {
|
||||
.read = idme_read,
|
||||
};
|
||||
|
||||
void create_idme_proc(void)
|
||||
{
|
||||
int i = 0;
|
||||
struct proc_dir_entry *proc_item[100];
|
||||
unsigned char *pidme;
|
||||
unsigned int *scan;
|
||||
char name[32] = {'\0'};
|
||||
char idme_magic_number[9] = {'\0'};
|
||||
char idme_version[5] = {'\0'};
|
||||
unsigned int idme_item_num, exportable, permission, data_size;
|
||||
unsigned int *ptemp;
|
||||
unsigned char data[128] = {0};
|
||||
struct proc_dir_entry *idme_dir = NULL;
|
||||
bool access_restrict = false;
|
||||
|
||||
pidme = &system_idme[0];
|
||||
idme_dir = proc_mkdir(IDME_PROC_DIR, NULL);
|
||||
|
||||
/* check IDME magic number */
|
||||
strncpy(idme_magic_number, pidme, 8);
|
||||
if (strncmp(idme_magic_number, IDME_MAGIC_NUMBER, strlen(IDME_MAGIC_NUMBER))) {
|
||||
printk(KERN_ERR"%s: invalid IDME magic number %s\n", __func__, idme_magic_number);
|
||||
return;
|
||||
}
|
||||
pidme += 8;
|
||||
|
||||
/* check IDME version */
|
||||
strncpy(idme_version, pidme, 4);
|
||||
pidme += 4;
|
||||
|
||||
/* get the IDME item number */
|
||||
ptemp = (unsigned int *)pidme;
|
||||
idme_item_num = *ptemp;
|
||||
pidme += sizeof(unsigned int);
|
||||
printk(KERN_INFO"%s: IDME version %s, item size %d\n", __func__, idme_version, idme_item_num);
|
||||
|
||||
for (i = 0; i < idme_item_num; i++) {
|
||||
// set get name
|
||||
strncpy(name, pidme, 16);
|
||||
pidme += 16;
|
||||
|
||||
// get data size
|
||||
ptemp = (unsigned int *)pidme;
|
||||
data_size = *ptemp;
|
||||
pidme += sizeof(unsigned int);
|
||||
|
||||
// get exportable
|
||||
ptemp = (unsigned int *)pidme;
|
||||
exportable = *ptemp;
|
||||
pidme += sizeof(unsigned int);
|
||||
|
||||
// get permission
|
||||
ptemp = (unsigned int *)pidme;
|
||||
permission = *ptemp;
|
||||
pidme += sizeof(unsigned int);
|
||||
|
||||
// get data
|
||||
//memcpy(data, pidme, data_size);
|
||||
pidme += data_size;
|
||||
|
||||
/* Restrict mac_sec */
|
||||
if (strcmp(name, MAC_SEC_KEY) == 0) {
|
||||
access_restrict = true;
|
||||
permission = 0400;
|
||||
} else {
|
||||
access_restrict = false;
|
||||
}
|
||||
|
||||
// set name and read its function
|
||||
if(exportable > 0) {
|
||||
strncpy(idme_item_name[i], name, strlen(name));
|
||||
proc_item[i] = proc_create_data(name, permission, idme_dir, &idme_proc_fops, idme_item_name[i]);
|
||||
|
||||
if (proc_item[i] && access_restrict)
|
||||
proc_set_user(proc_item[i], MAC_SEC_OWNER, 0);
|
||||
}
|
||||
}
|
||||
#if defined(FORD_HVT_DEVICE_ID_DEFAULT)
|
||||
/* add device_type_id */
|
||||
proc_create_data(ford_device_type_name, permission, idme_dir, &idme_proc_fops, ford_device_type_name);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy initialize the idme */
|
||||
static void initialize_idme(void)
|
||||
{
|
||||
create_idme_proc();
|
||||
}
|
||||
|
||||
void init_idme(void)
|
||||
{
|
||||
printk(DRIVER_INFO "\n");
|
||||
initialize_idme();
|
||||
}
|
||||
|
||||
module_init(init_idme);
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (C) 2014 Amazon Incorporated
|
||||
*
|
||||
* Yang Liu <yangliu@lab126.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/klog_console.h>
|
||||
|
||||
static void klog_console_write(struct console *con, const char *buf,
|
||||
unsigned count)
|
||||
{
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
while (count) {
|
||||
unsigned int i;
|
||||
unsigned int lf;
|
||||
/* search for LF so we can insert CR if necessary */
|
||||
for (i = 0, lf = 0 ; i < count ; i++) {
|
||||
if (*(buf + i) == 10) {
|
||||
lf = 1;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
logger_kmsg_write(buf, i);
|
||||
|
||||
if (lf) {
|
||||
/* append CR after LF */
|
||||
unsigned char cr = 13;
|
||||
logger_kmsg_write(&cr, 1);
|
||||
}
|
||||
buf += i;
|
||||
count -= i;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static struct console klog_console = {
|
||||
.name = "klog",
|
||||
.write = klog_console_write,
|
||||
.flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,
|
||||
.index = -1,
|
||||
};
|
||||
|
||||
static int __init klog_console_init(void)
|
||||
{
|
||||
printk(KERN_ERR "Registering kernel log console\n");
|
||||
register_console(&klog_console);
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(klog_console_init);
|
||||
@@ -1,438 +0,0 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/mdump.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#ifdef CONFIG_MTK_KERNEL_POWER_OFF_CHARGING
|
||||
#include <mach/mt_boot_common.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MDUMP_COMPRESS
|
||||
#include <linux/vmalloc.h>
|
||||
#endif
|
||||
|
||||
struct mdbinattr {
|
||||
struct bin_attribute binattr;
|
||||
int readonly;
|
||||
char *address;
|
||||
};
|
||||
struct mdtxtattr {
|
||||
struct attribute attr;
|
||||
void *udata;
|
||||
ssize_t (*show)(void*, char *buffer);
|
||||
ssize_t (*store)(void*, const char *buffer, size_t size);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MDUMP_COMPRESS
|
||||
struct mdcompbinattr {
|
||||
struct bin_attribute binattr;
|
||||
void *vaddr;
|
||||
void *paddr;
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct mdump_buffer *s_mdump_buffer;
|
||||
static struct kobject s_mdump_kobj;
|
||||
|
||||
static ssize_t mdump_binary_read(struct file *filp,
|
||||
struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct mdbinattr *mdattr = (struct mdbinattr *) attr;
|
||||
|
||||
if (off > mdattr->binattr.size)
|
||||
return -ERANGE;
|
||||
if (off + count > mdattr->binattr.size)
|
||||
count = mdattr->binattr.size - off;
|
||||
if (count != 0)
|
||||
memcpy(buf, mdattr->address + off, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t mdump_binary_write(struct file *filp,
|
||||
struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *data, loff_t off, size_t count)
|
||||
{
|
||||
struct mdbinattr *mdattr = (struct mdbinattr *) attr;
|
||||
|
||||
if (mdattr->readonly == 0) {
|
||||
if (off > mdattr->binattr.size)
|
||||
return -ERANGE;
|
||||
if (off + count > mdattr->binattr.size)
|
||||
count = mdattr->binattr.size - off;
|
||||
if (count != 0)
|
||||
memcpy(mdattr->address + off, data, count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MDUMP_COMPRESS
|
||||
static void *remap_lowmem(phys_addr_t start, phys_addr_t size)
|
||||
{
|
||||
struct page **pages;
|
||||
phys_addr_t page_start;
|
||||
unsigned int page_count;
|
||||
pgprot_t prot;
|
||||
unsigned int i;
|
||||
void *vaddr;
|
||||
|
||||
page_start = start - offset_in_page(start);
|
||||
page_count = DIV_ROUND_UP(size + offset_in_page(start), PAGE_SIZE);
|
||||
|
||||
prot = pgprot_noncached(PAGE_KERNEL);
|
||||
|
||||
pages = kmalloc(sizeof(struct page *) * page_count, GFP_KERNEL);
|
||||
if (!pages) {
|
||||
pr_err("%s: Failed to allocate array for %u pages\n", __func__, page_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < page_count; i++) {
|
||||
phys_addr_t addr = page_start + i * PAGE_SIZE;
|
||||
pages[i] = pfn_to_page(addr >> PAGE_SHIFT);
|
||||
}
|
||||
vaddr = vmap(pages, page_count, VM_MAP, prot);
|
||||
kfree(pages);
|
||||
if (!vaddr) {
|
||||
pr_err("%s: Failed to map %u pages\n", __func__, page_count);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vaddr + offset_in_page(start);
|
||||
}
|
||||
|
||||
/* for safe, we only map 32MB per time */
|
||||
#define PHYMEM_MAP_CHUNK 0x2000000
|
||||
static ssize_t mdump_compdump_binary_read(struct file *filp,
|
||||
struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *buf, loff_t off, size_t count)
|
||||
{
|
||||
unsigned int expbase;
|
||||
struct mdcompbinattr *mdcattr = (struct mdcompbinattr *) attr;
|
||||
|
||||
if (off > mdcattr->binattr.size)
|
||||
return -ERANGE;
|
||||
if (off + count > mdcattr->binattr.size)
|
||||
count = mdcattr->binattr.size - off;
|
||||
expbase = (off & (~(PHYMEM_MAP_CHUNK-1))) + COMPRESS_START_ADDRESS;
|
||||
if (expbase > (unsigned int)(mdcattr->paddr)) {
|
||||
vunmap((void *)mdcattr->vaddr);
|
||||
mdcattr->vaddr = remap_lowmem((phys_addr_t)expbase, (phys_addr_t)PHYMEM_MAP_CHUNK);
|
||||
if (mdcattr->vaddr == NULL) {
|
||||
pr_err("compress dump function can not map physicall addr: 0x%x\n", expbase);
|
||||
return 0;
|
||||
}
|
||||
mdcattr->paddr = (void *)expbase;
|
||||
}
|
||||
/* make sure not to read beyond the mapped memory region */
|
||||
if ((off - (expbase - COMPRESS_START_ADDRESS) + count) > PHYMEM_MAP_CHUNK)
|
||||
count = PHYMEM_MAP_CHUNK - (off - (expbase - COMPRESS_START_ADDRESS));
|
||||
|
||||
if (count != 0)
|
||||
memcpy(buf, mdcattr->vaddr + off-(expbase-COMPRESS_START_ADDRESS), count);
|
||||
|
||||
if ((off % PHYMEM_MAP_CHUNK) == 0)
|
||||
pr_err("total %u MBytes had been sent!\n", (unsigned int)(off/PHYMEM_MAP_CHUNK)*32);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t mdump_compdump_binary_write(struct file *filp,
|
||||
struct kobject *kobj,
|
||||
struct bin_attribute *attr,
|
||||
char *data, loff_t off, size_t count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mdcompbinattr s_mdump_compdump = {
|
||||
{
|
||||
{ .name = "compmsg", .mode = S_IRUGO },
|
||||
.size = 0,
|
||||
.read = mdump_compdump_binary_read,
|
||||
.write = mdump_compdump_binary_write
|
||||
},
|
||||
.vaddr = NULL,
|
||||
.paddr = NULL
|
||||
};
|
||||
|
||||
static void check_compress_dump(void)
|
||||
{
|
||||
struct compress_file_header *compresshdr = NULL;
|
||||
|
||||
/*
|
||||
No action needed if mdump is not enabled, or reboot reason is not kernel panic or
|
||||
watchdog timeout.
|
||||
*/
|
||||
if (!s_mdump_buffer->enable_flags ||
|
||||
(s_mdump_buffer->backup_reason != MDUMP_REBOOT_PANIC &&
|
||||
s_mdump_buffer->backup_reason != MDUMP_REBOOT_WATCHDOG &&
|
||||
s_mdump_buffer->backup_reason != MDUMP_REBOOT_HARDWARE))
|
||||
return;
|
||||
|
||||
/* Map the first 32MB where the compressed content stores */
|
||||
s_mdump_compdump.vaddr = remap_lowmem((phys_addr_t)COMPRESS_START_ADDRESS, (phys_addr_t)PHYMEM_MAP_CHUNK);
|
||||
if (s_mdump_compdump.vaddr == NULL) {
|
||||
pr_err("%s: Can not map physical adress 0x%x\n", __func__, COMPRESS_START_ADDRESS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check the header string */
|
||||
compresshdr = (struct compress_file_header *)s_mdump_compdump.vaddr;
|
||||
if (strncmp(compresshdr->header_signature, COMP_HEAD_SIGNATURE, COMP_SIGNATURE_SIZE)) {
|
||||
pr_info("%s: The compressed content header signature is not valid!\n", __func__);
|
||||
goto error_exit;
|
||||
}
|
||||
/* check number of compressed segments and total file size. */
|
||||
if (!compresshdr->num_of_segments || (compresshdr->total_file_size <= sizeof(struct compress_file_header))) {
|
||||
pr_info("%s: No valid ccompressed conent!\n", __func__);
|
||||
goto error_exit;
|
||||
}
|
||||
/* create bin file style sysfs node */
|
||||
s_mdump_compdump.paddr = (void *) COMPRESS_START_ADDRESS;
|
||||
s_mdump_compdump.binattr.size = compresshdr->total_file_size;
|
||||
pr_info("%s: compression dump size is: 0x%x\n", __func__, s_mdump_compdump.binattr.size);
|
||||
if (sysfs_create_bin_file(&s_mdump_kobj, &s_mdump_compdump.binattr) == 0)
|
||||
return;
|
||||
|
||||
pr_err("%s: Create compression dump sysfs node failed!\n", __func__);
|
||||
|
||||
error_exit:
|
||||
vunmap((void *)s_mdump_compdump.vaddr);
|
||||
s_mdump_compdump.vaddr = NULL;
|
||||
s_mdump_compdump.paddr = NULL;
|
||||
s_mdump_compdump.binattr.size = 0;
|
||||
}
|
||||
#endif /* CONFIG_MDUMP_COMPRESS */
|
||||
|
||||
static ssize_t mdump_text_show(struct kobject *kobj,
|
||||
struct attribute *attr,
|
||||
char *buffer)
|
||||
{
|
||||
struct mdtxtattr *mdattr = (struct mdtxtattr *) attr;
|
||||
if (mdattr->show == NULL) {
|
||||
buffer[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
return mdattr->show(mdattr->udata, buffer);
|
||||
}
|
||||
|
||||
static ssize_t mdump_text_store(struct kobject *kobj,
|
||||
struct attribute *attr,
|
||||
const char *buffer, size_t size)
|
||||
{
|
||||
struct mdtxtattr *mdattr = (struct mdtxtattr *) attr;
|
||||
if (mdattr->store == NULL)
|
||||
return size;
|
||||
return mdattr->store(mdattr->udata, buffer, size);
|
||||
}
|
||||
|
||||
static ssize_t mdump_enable_show(void *ud, char *buffer)
|
||||
{
|
||||
if (!s_mdump_buffer->enable_flags) {
|
||||
strcpy(buffer, "OFF");
|
||||
return 3;
|
||||
} else {
|
||||
strcpy(buffer, "ON");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t mdump_enable_store(void *ud, const char *buffer, size_t size)
|
||||
{
|
||||
u16 flags = s_mdump_buffer->enable_flags;
|
||||
|
||||
if ((size >= 3) && !strncmp(buffer, "OFF", 3))
|
||||
flags = 0;
|
||||
else if ((size >= 3) && !strncmp(buffer, "off", 3))
|
||||
flags = 0;
|
||||
else if ((size >= 2) && !strncmp(buffer, "ON", 2))
|
||||
flags = 1;
|
||||
else if ((size >= 2) && !strncmp(buffer, "on", 2))
|
||||
flags = 1;
|
||||
else
|
||||
pr_err("Unknown store value: %s\n", buffer);
|
||||
if (flags != s_mdump_buffer->enable_flags) {
|
||||
s_mdump_buffer->enable_flags = flags;
|
||||
flush_cache_all();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t mdump_reason_show(void *ud, char *buffer)
|
||||
{
|
||||
const char *mesg = 0;
|
||||
|
||||
switch (s_mdump_buffer->backup_reason) {
|
||||
case MDUMP_COLD_RESET:
|
||||
mesg = "Cold reset";
|
||||
break;
|
||||
case MDUMP_REBOOT_WATCHDOG:
|
||||
mesg = "Watchdog";
|
||||
break;
|
||||
case MDUMP_REBOOT_PANIC:
|
||||
mesg = "Kernel Panic";
|
||||
break;
|
||||
case MDUMP_REBOOT_NORMAL:
|
||||
mesg = "Warm Reboot";
|
||||
break;
|
||||
case MDUMP_REBOOT_HARDWARE:
|
||||
mesg = "Hardware reset";
|
||||
break;
|
||||
default:
|
||||
mesg = "Unknown reason";
|
||||
break;
|
||||
}
|
||||
strcpy(buffer, mesg);
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
static ssize_t mdump_list_show(void *ud, char *buffer)
|
||||
{
|
||||
buffer[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mdump_list_store(void *ud, const char *buffer, size_t size)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void mdump_mark_reboot_reason(int reason)
|
||||
{
|
||||
if ((s_mdump_buffer != NULL)
|
||||
&& (reason < s_mdump_buffer->reboot_reason)) {
|
||||
s_mdump_buffer->reboot_reason = (u8) reason;
|
||||
flush_cache_all();
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(mdump_mark_reboot_reason);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static struct mdbinattr s_mdump_pblmsg = {
|
||||
{
|
||||
{ .name = "pblmsg", .mode = S_IRUGO },
|
||||
.size = 0,
|
||||
.read = mdump_binary_read,
|
||||
.write = mdump_binary_write
|
||||
},
|
||||
.readonly = 1,
|
||||
.address = NULL
|
||||
};
|
||||
static struct mdbinattr s_mdump_lkmsg = {
|
||||
{
|
||||
{ .name = "lkmsg", .mode = S_IRUGO },
|
||||
.size = 0,
|
||||
.read = mdump_binary_read,
|
||||
.write = mdump_binary_write
|
||||
},
|
||||
1,
|
||||
NULL
|
||||
};
|
||||
static struct mdtxtattr s_mdump_enable = {
|
||||
{ .name = "enable", .mode = S_IRUGO | S_IWUSR },
|
||||
NULL,
|
||||
mdump_enable_show,
|
||||
mdump_enable_store
|
||||
};
|
||||
static struct mdtxtattr s_mdump_reason = {
|
||||
{ .name = "reason", .mode = S_IRUGO },
|
||||
NULL,
|
||||
mdump_reason_show,
|
||||
NULL
|
||||
};
|
||||
static struct mdtxtattr s_mdump_list = {
|
||||
{ .name = "list", .mode = S_IRUGO | S_IWUSR },
|
||||
NULL,
|
||||
mdump_list_show,
|
||||
mdump_list_store
|
||||
};
|
||||
static const struct sysfs_ops s_mdump_sysfs_ops = {
|
||||
.show = mdump_text_show,
|
||||
.store = mdump_text_store,
|
||||
};
|
||||
static struct attribute *s_mdump_attributes[] = {
|
||||
&s_mdump_enable.attr,
|
||||
&s_mdump_reason.attr,
|
||||
&s_mdump_list.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct kobj_type s_mdump_type = {
|
||||
.sysfs_ops = &s_mdump_sysfs_ops,
|
||||
.default_attrs = s_mdump_attributes,
|
||||
};
|
||||
|
||||
|
||||
static int __init mdump_init(void)
|
||||
{
|
||||
pr_info("Check mdump buffer on address: 0x%x\n",
|
||||
CONFIG_MDUMP_BUFFER_ADDRESS);
|
||||
s_mdump_buffer = (struct mdump_buffer *)
|
||||
phys_to_virt(CONFIG_MDUMP_BUFFER_ADDRESS);
|
||||
if (s_mdump_buffer->signature != MDUMP_BUFFER_SIG) {
|
||||
memset(s_mdump_buffer, 0, sizeof(struct mdump_buffer));
|
||||
s_mdump_buffer->signature = MDUMP_BUFFER_SIG;
|
||||
s_mdump_buffer->backup_reason = MDUMP_COLD_RESET;
|
||||
pr_err("MDump buffer not found. initial.\n");
|
||||
} else {
|
||||
pr_info("MDump: found existing mdump_buffer\n");
|
||||
pr_info("MDump Boot Reason: 0x%x\n",
|
||||
s_mdump_buffer->backup_reason);
|
||||
}
|
||||
s_mdump_buffer->reboot_reason = MDUMP_REBOOT_HARDWARE;
|
||||
#ifdef CONFIG_MTK_KERNEL_POWER_OFF_CHARGING
|
||||
if (g_boot_mode != KERNEL_POWER_OFF_CHARGING_BOOT && g_boot_mode != LOW_POWER_OFF_CHARGING_BOOT)
|
||||
s_mdump_buffer->enable_flags = 1;
|
||||
else
|
||||
s_mdump_buffer->enable_flags = 0;
|
||||
#else
|
||||
s_mdump_buffer->enable_flags = 1;
|
||||
#endif
|
||||
|
||||
if (kobject_init_and_add(&s_mdump_kobj,
|
||||
&s_mdump_type, kernel_kobj, "mdump")) {
|
||||
kobject_put(&s_mdump_kobj);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
s_mdump_pblmsg.binattr.size = strlen(s_mdump_buffer->stage1_messages);
|
||||
s_mdump_pblmsg.address = s_mdump_buffer->stage1_messages;
|
||||
if (sysfs_create_bin_file(&s_mdump_kobj, &s_mdump_pblmsg.binattr) != 0)
|
||||
pr_err("Create Preloader message file failed.\n");
|
||||
|
||||
s_mdump_lkmsg.binattr.size = strlen(s_mdump_buffer->stage2_messages);
|
||||
s_mdump_lkmsg.address = s_mdump_buffer->stage2_messages;
|
||||
if (sysfs_create_bin_file(&s_mdump_kobj, &s_mdump_lkmsg.binattr) != 0)
|
||||
pr_err("Create LK message file failed.\n");
|
||||
|
||||
#ifdef CONFIG_MDUMP_COMPRESS
|
||||
/* create sysfs node if valid compressed dump presents in RAM */
|
||||
check_compress_dump();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(mdump_init);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
MODULE_AUTHOR("NEUSOFT");
|
||||
MODULE_DESCRIPTION("NEUSOFT MDUMP MODULE");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -1,505 +0,0 @@
|
||||
/*
|
||||
* sign_of_life.c
|
||||
*
|
||||
* Device Sign of Life information
|
||||
*
|
||||
* Copyright (C) Amazon Technologies Inc. All rights reserved.
|
||||
* Yang Liu (yangliu@lab126.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/sign_of_life.h>
|
||||
#include <mach/mt_boot_common.h>
|
||||
|
||||
#define DEV_SOL_VERSION "1.0"
|
||||
#define DEV_SOL_PROC_NAME "life_cycle_reason"
|
||||
#define MAX_SIZE 10
|
||||
|
||||
static struct proc_dir_entry *life_cycle_metrics_file;
|
||||
|
||||
typedef enum {
|
||||
LIFE_CYCLES_DEFAULT_REASON = 0,
|
||||
SW_SHUTDOWN,
|
||||
LONG_KEY_PRESSED_PWR_KEY_SHUTDOWN,
|
||||
PMIC_THERMAL_SHUTDOWN,
|
||||
BATTERY_THERMAL_SHUTDOWN,
|
||||
SOC_THERMAL_SHUTDOWN,
|
||||
PCB_THERMAL_SHUTDOWN,
|
||||
WIFI_THERMAL_SHUTDOWN,
|
||||
MODEM_THERMAL_SHUTDOWN,
|
||||
LOW_BATTERY_SHUTDOWN,
|
||||
SUDDEN_POWER_LOSS_SHUTDOWN,
|
||||
UNKNOWN_SHUTDOWN,
|
||||
COLD_BOOT_BY_PWR_KEY,
|
||||
COLD_BOOT_BY_USB_CHARGER,
|
||||
COLD_BOOT_BY_POWER_SUPPLY,
|
||||
WARM_BOOT_BY_SW,
|
||||
WARM_BOOT_BY_KERNEL_PANIC,
|
||||
WARM_BOOT_BY_KERNEL_WDG,
|
||||
WARM_BOOT_BY_HW_WDG,
|
||||
PWR_OFF_CHARGING_MODE,
|
||||
FACTORY_RESET_REBOOT,
|
||||
OTA_REBOOT,
|
||||
} life_cycle_reasons_idx;
|
||||
|
||||
static const char * const life_cycle_reasons[] = {
|
||||
"Life Cycle Reason Not Available",
|
||||
"Software Shutdown",
|
||||
"Long Pressed Power Key Shutdown",
|
||||
"PMIC Overheated Thermal Shutdown",
|
||||
"Battery Overheated Thermal Shutdown",
|
||||
"SOC Overheated Thermal Shutdown",
|
||||
"PCB Overheated Thermal Shutdown",
|
||||
"WIFI Overheated Thermal Shutdown",
|
||||
"Modem Overheated Thermal Shutdown",
|
||||
"Low Battery Shutdown",
|
||||
"Sudden Power Loss Shutdown",
|
||||
"Unknown Shutdown",
|
||||
"Cold Boot By Power Key",
|
||||
"Cold Boot By USB Charger",
|
||||
"Cold Boot By Power Supply",
|
||||
"Warm Boot By Software",
|
||||
"Warm Boot By Kernel Panic",
|
||||
"Warm Boot By Kernel Watchdog",
|
||||
"Warm Boot By HW Watchdog",
|
||||
"Power Off Charging Mode",
|
||||
"Factory Reset Reboot",
|
||||
"OTA Reboot",
|
||||
};
|
||||
|
||||
static const char * const life_cycle_metrics[] = {
|
||||
"not_available",
|
||||
"sw_shutdown",
|
||||
"long_key_press_pwr_key_shutdown",
|
||||
"pmic_thermal_shutdown",
|
||||
"battery_thermal_shutdown",
|
||||
"soc_thermal_shutdown",
|
||||
"pcb_thermal_shutdown",
|
||||
"wifi_thermal_shutdown",
|
||||
"modem_thermal_shutdown",
|
||||
"low_battery_shutdown",
|
||||
"sudden_power_loss",
|
||||
"unknown_shutdown",
|
||||
"cold_boot_pwr_key",
|
||||
"cold_boot_usb_charger",
|
||||
"cold_boot_power_supply",
|
||||
"warm_boot_sw",
|
||||
"warm_boot_kernel_panic",
|
||||
"warm_boot_kernel_wdog",
|
||||
"warm_boot_hw_wdog",
|
||||
"pwr_off_charging",
|
||||
"factory_reset",
|
||||
"ota_reboot",
|
||||
};
|
||||
|
||||
static const char * const life_cycle_vitals_source[] = {
|
||||
"LCR_abnormal",
|
||||
"LCR_normal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_normal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_normal",
|
||||
"LCR_normal",
|
||||
"LCR_normal",
|
||||
"LCR_normal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_abnormal",
|
||||
"LCR_normal",
|
||||
"LCR_normal",
|
||||
"LCR_normal",
|
||||
};
|
||||
|
||||
static const char * const life_cycle_vitals_key[] = {
|
||||
"Unknown_Shutdown",
|
||||
"Android_Shutdown",
|
||||
"Long_Key_Press_Shutdown",
|
||||
"Thermal_Shutdown",
|
||||
"Thermal_Shutdown",
|
||||
"Thermal_Shutdown",
|
||||
"Thermal_Shutdown",
|
||||
"Thermal_Shutdown",
|
||||
"Thermal_Shutdown",
|
||||
"Critically_Low_Battery_Shutdown",
|
||||
"Sudden_Power_Loss",
|
||||
"Unknown_Shutdown",
|
||||
"Cold_Boot_By_Power_Key",
|
||||
"Cold_Boot_By_USB",
|
||||
"Cold_Boot_By_Power_Supply",
|
||||
"Warm_Boot_By_Android",
|
||||
"Warm_Boot_Kernel_Panic",
|
||||
"Warm_Boot_Kernel_Watchdog",
|
||||
"Warm_Boot_Hardware_Watchdog",
|
||||
"Power_Off_Charging",
|
||||
"Factory_Reset_Reboot",
|
||||
"OTA_Reboot",
|
||||
};
|
||||
|
||||
static const char * const life_cycle_vitals_value2[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"PMIC",
|
||||
"BATTERY",
|
||||
"SOC",
|
||||
"PCB",
|
||||
"WIFI",
|
||||
"MODEM",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct dev_sol {
|
||||
u8 *data;
|
||||
u8 life_cycle_reason_idx;
|
||||
sign_of_life_ops sol_ops;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
static struct dev_sol *p_dev_sol;
|
||||
|
||||
static int life_cycle_reason_lookup(void)
|
||||
{
|
||||
life_cycle_boot_reason boot_reason = 0;
|
||||
life_cycle_shutdown_reason shutdown_reason = 0;
|
||||
life_cycle_thermal_shutdown_reason thermal_shutdown_reason = 0;
|
||||
life_cycle_special_mode s_mode = 0;
|
||||
bool lcr_found = false;
|
||||
|
||||
if (!p_dev_sol) {
|
||||
printk(KERN_ERR "%s: the life cycle driver is not initialized\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!((p_dev_sol->sol_ops.read_boot_reason) &&
|
||||
(p_dev_sol->sol_ops.read_shutdown_reason) &&
|
||||
(p_dev_sol->sol_ops.read_thermal_shutdown_reason) &&
|
||||
(p_dev_sol->sol_ops.read_special_mode))) {
|
||||
printk(KERN_ERR "%s: no platform supported\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_dev_sol->sol_ops.read_boot_reason(&boot_reason);
|
||||
p_dev_sol->sol_ops.read_shutdown_reason(&shutdown_reason);
|
||||
p_dev_sol->sol_ops.read_thermal_shutdown_reason(&thermal_shutdown_reason);
|
||||
p_dev_sol->sol_ops.read_special_mode(&s_mode);
|
||||
|
||||
/* thermal shutdown is considered as abnormal */
|
||||
switch (thermal_shutdown_reason) {
|
||||
case THERMAL_SHUTDOWN_REASON_BATTERY:
|
||||
p_dev_sol->life_cycle_reason_idx = BATTERY_THERMAL_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case THERMAL_SHUTDOWN_REASON_PMIC:
|
||||
p_dev_sol->life_cycle_reason_idx = PMIC_THERMAL_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case THERMAL_SHUTDOWN_REASON_SOC:
|
||||
p_dev_sol->life_cycle_reason_idx = SOC_THERMAL_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case THERMAL_SHUTDOWN_REASON_MODEM:
|
||||
p_dev_sol->life_cycle_reason_idx = MODEM_THERMAL_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case THERMAL_SHUTDOWN_REASON_WIFI:
|
||||
p_dev_sol->life_cycle_reason_idx = WIFI_THERMAL_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case THERMAL_SHUTDOWN_REASON_PCB:
|
||||
p_dev_sol->life_cycle_reason_idx = PCB_THERMAL_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (lcr_found)
|
||||
return 0;
|
||||
|
||||
switch (boot_reason) {
|
||||
case WARMBOOT_BY_SW:
|
||||
p_dev_sol->life_cycle_reason_idx = WARM_BOOT_BY_SW;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case WARMBOOT_BY_KERNEL_WATCHDOG:
|
||||
p_dev_sol->life_cycle_reason_idx = WARM_BOOT_BY_KERNEL_WDG;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case WARMBOOT_BY_KERNEL_PANIC:
|
||||
p_dev_sol->life_cycle_reason_idx = WARM_BOOT_BY_KERNEL_PANIC;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case WARMBOOT_BY_HW_WATCHDOG:
|
||||
p_dev_sol->life_cycle_reason_idx = WARM_BOOT_BY_HW_WDG;
|
||||
lcr_found = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (lcr_found)
|
||||
return 0;
|
||||
|
||||
switch (shutdown_reason) {
|
||||
case SHUTDOWN_BY_SW:
|
||||
p_dev_sol->life_cycle_reason_idx = SW_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case SHUTDOWN_BY_SW_LONG_PWR_KEY_PRESS:
|
||||
/*LCR reason should be same for SW/HW long pwr key press shutdown,
|
||||
do not introdcue new LCR as it might create confusion
|
||||
for others products*/
|
||||
p_dev_sol->life_cycle_reason_idx = LONG_KEY_PRESSED_PWR_KEY_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case SHUTDOWN_BY_LONG_PWR_KEY_PRESS:
|
||||
p_dev_sol->life_cycle_reason_idx = LONG_KEY_PRESSED_PWR_KEY_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
case SHUTDOWN_BY_UNKNOWN_REASONS:
|
||||
p_dev_sol->life_cycle_reason_idx = UNKNOWN_SHUTDOWN;
|
||||
lcr_found = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (lcr_found)
|
||||
return 0;
|
||||
|
||||
switch (boot_reason) {
|
||||
case COLDBOOT_BY_USB:
|
||||
p_dev_sol->life_cycle_reason_idx = COLD_BOOT_BY_USB_CHARGER;
|
||||
lcr_found = true;
|
||||
break;
|
||||
|
||||
case COLDBOOT_BY_POWER_KEY:
|
||||
p_dev_sol->life_cycle_reason_idx = COLD_BOOT_BY_PWR_KEY;
|
||||
lcr_found = true;
|
||||
break;
|
||||
|
||||
case COLDBOOT_BY_POWER_SUPPLY:
|
||||
p_dev_sol->life_cycle_reason_idx = COLD_BOOT_BY_POWER_SUPPLY;
|
||||
lcr_found = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int life_cycle_metrics_show(struct seq_file *m, void *v)
|
||||
{
|
||||
if (p_dev_sol) {
|
||||
seq_printf(m, "%s", life_cycle_reasons[p_dev_sol->life_cycle_reason_idx]);
|
||||
} else
|
||||
seq_printf(m, "life cycle reason driver is not initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int life_cycle_metrics_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, life_cycle_metrics_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations life_cycle_metrics_proc_fops = {
|
||||
.open = life_cycle_metrics_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
void life_cycle_metrics_proc_init(void)
|
||||
{
|
||||
life_cycle_metrics_file = proc_create(DEV_SOL_PROC_NAME,
|
||||
0444, NULL, &life_cycle_metrics_proc_fops);
|
||||
if (life_cycle_metrics_file == NULL) {
|
||||
printk(KERN_ERR "%s: Can't create life cycle metrics proc entry\n", __func__);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(life_cycle_metrics_proc_init);
|
||||
|
||||
void life_cycle_metrics_proc_done(void)
|
||||
{
|
||||
remove_proc_entry(DEV_SOL_PROC_NAME, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(life_cycle_metrics_proc_done);
|
||||
|
||||
|
||||
/*
|
||||
* life_cycle_set_boot_reason
|
||||
* Description: this function will set the boot reason which causing device booting
|
||||
*/
|
||||
int life_cycle_set_boot_reason(life_cycle_boot_reason boot_reason)
|
||||
{
|
||||
if (!p_dev_sol) {
|
||||
printk(KERN_ERR "%s: the life cycle driver is not initialized\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!p_dev_sol->sol_ops.write_boot_reason) {
|
||||
printk(KERN_ERR "%s: no platform supported\n", __func__);
|
||||
return -1;
|
||||
} else
|
||||
p_dev_sol->sol_ops.write_boot_reason(boot_reason);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(life_cycle_set_boot_reason);
|
||||
|
||||
|
||||
/*
|
||||
* life_cycle_set_shutdown_reason
|
||||
* Description: this function will set the Shutdown reason which causing device shutdown
|
||||
*/
|
||||
int life_cycle_set_shutdown_reason(life_cycle_shutdown_reason shutdown_reason)
|
||||
{
|
||||
if (!p_dev_sol) {
|
||||
printk(KERN_ERR "%s: the life cycle driver is not initialized\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!p_dev_sol->sol_ops.write_shutdown_reason) {
|
||||
printk(KERN_ERR "%s: no platform supported\n", __func__);
|
||||
return -1;
|
||||
} else
|
||||
p_dev_sol->sol_ops.write_shutdown_reason(shutdown_reason);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(life_cycle_set_shutdown_reason);
|
||||
|
||||
/*
|
||||
* life_cycle_set_thermal_shutdown_reason
|
||||
* Description: this function will set the Thermal Shutdown reason which causing device shutdown
|
||||
*/
|
||||
int life_cycle_set_thermal_shutdown_reason(life_cycle_thermal_shutdown_reason thermal_shutdown_reason)
|
||||
{
|
||||
if (!p_dev_sol) {
|
||||
printk(KERN_ERR "%s: the life cycle driver is not initialized\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!p_dev_sol->sol_ops.write_thermal_shutdown_reason) {
|
||||
printk(KERN_ERR "%s: no platform supported\n", __func__);
|
||||
return -1;
|
||||
} else
|
||||
p_dev_sol->sol_ops.write_thermal_shutdown_reason(thermal_shutdown_reason);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(life_cycle_set_thermal_shutdown_reason);
|
||||
|
||||
/*
|
||||
* life_cycle_set_special_mode
|
||||
* Description: this function will set the special mode which causing device life cycle change
|
||||
*/
|
||||
int life_cycle_set_special_mode(life_cycle_special_mode life_cycle_special_mode)
|
||||
{
|
||||
if (!p_dev_sol) {
|
||||
printk(KERN_ERR "%s: the life cycle driver is not initialized\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!p_dev_sol->sol_ops.write_special_mode) {
|
||||
printk(KERN_ERR "%s: no platform supported\n", __func__);
|
||||
return -1;
|
||||
} else
|
||||
p_dev_sol->sol_ops.write_special_mode(life_cycle_special_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(life_cycle_set_special_mode);
|
||||
|
||||
|
||||
extern int life_cycle_platform_init(sign_of_life_ops *sol_ops);
|
||||
int __weak life_cycle_platform_init(sign_of_life_ops *sol_ops)
|
||||
{
|
||||
printk(KERN_ERR "%s: no supported platform is configured\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init dev_sol_init(void)
|
||||
{
|
||||
printk(KERN_NOTICE "Amazon: sign of life device driver init\n");
|
||||
p_dev_sol = kzalloc(sizeof(struct dev_sol), GFP_KERNEL);
|
||||
if (!p_dev_sol) {
|
||||
printk (KERN_ERR "%s: kmalloc allocation failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mutex_init(&p_dev_sol->lock);
|
||||
|
||||
/* set the default life cycle reason */
|
||||
p_dev_sol->life_cycle_reason_idx = LIFE_CYCLES_DEFAULT_REASON;
|
||||
|
||||
/* create the proc entry for life cycle reason */
|
||||
life_cycle_metrics_proc_init();
|
||||
|
||||
/* initialize the platform dependent life cycle operation implementation */
|
||||
life_cycle_platform_init(&p_dev_sol->sol_ops);
|
||||
|
||||
/* look up the life cycle reason */
|
||||
life_cycle_reason_lookup();
|
||||
printk(KERN_NOTICE "%s: life cycle reason is %s\n",
|
||||
__func__, life_cycle_reasons[p_dev_sol->life_cycle_reason_idx]);
|
||||
|
||||
/* clean up the life cycle reason settings */
|
||||
if (get_boot_mode() == KERNEL_POWER_OFF_CHARGING_BOOT || get_boot_mode() == LOW_POWER_OFF_CHARGING_BOOT) {
|
||||
printk(KERN_NOTICE "%s: in charger mode. Don't reset LCR registers.\n", __func__);
|
||||
} else {
|
||||
printk(KERN_NOTICE "%s: not in charger mode. Reset LCR registers.\n", __func__);
|
||||
p_dev_sol->sol_ops.lcr_reset();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit dev_sol_cleanup(void)
|
||||
{
|
||||
life_cycle_metrics_proc_done();
|
||||
if (p_dev_sol)
|
||||
kfree(p_dev_sol);
|
||||
}
|
||||
|
||||
late_initcall(dev_sol_init);
|
||||
module_exit(dev_sol_cleanup);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -1,403 +0,0 @@
|
||||
/*
|
||||
* sign_of_life_mtk.c
|
||||
*
|
||||
* MTK platform implementation
|
||||
*
|
||||
* Copyright (C) Amazon Technologies Inc. All rights reserved.
|
||||
* Yang Liu (yangliu@lab126.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/sign_of_life.h>
|
||||
#include <mach/mtk_rtc.h>
|
||||
#include <mach/mtk_rtc_hal.h>
|
||||
#include <mach/mt_rtc_hw.h>
|
||||
#include <mach/mt_typedefs.h>
|
||||
#include <mach/mt_pmic_wrap.h>
|
||||
|
||||
|
||||
/* RTC Spare Register Definition */
|
||||
|
||||
/*
|
||||
* RTC_NEW_SPARE1: RTC_AL_DOM bit0~4
|
||||
* bit 8 ~ 15 : reserved bits for boot reasons
|
||||
*/
|
||||
#define RTC_NEW_SPARE1_WARM_BOOT_KERNEL_PANIC (1U << 8)
|
||||
#define RTC_NEW_SPARE1_WARM_BOOT_KERNEL_WDOG (1U << 9)
|
||||
#define RTC_NEW_SPARE1_WARM_BOOT_HW_WDOG (1U << 10)
|
||||
#define RTC_NEW_SPARE1_WARM_BOOT_SW (1U << 11)
|
||||
#define RTC_NEW_SPARE1_COLD_BOOT_USB (1U << 12)
|
||||
#define RTC_NEW_SPARE1_COLD_BOOT_POWER_KEY (1U << 13)
|
||||
#define RTC_NEW_SPARE1_COLD_BOOT_POWER_SUPPLY (1U << 14)
|
||||
|
||||
/*
|
||||
* RTC_NEW_SPARE2: RTC_AL_DOW bit0~2
|
||||
* bit 8 ~ 15 : reserved bits
|
||||
*/
|
||||
#define RTC_NEW_SPARE2_SHUTDOWN_LONG_PWR_KEY_PRESS (1U << 8)
|
||||
#define RTC_NEW_SPARE2_SHUTDOWN_SW (1U << 9)
|
||||
#define RTC_NEW_SPARE2_SHUTDOWN_PWR_KEY (1U << 10)
|
||||
#define RTC_NEW_SPARE2_SHUTDOWN_SUDDEN_PWR_LOSS (1U << 11)
|
||||
#define RTC_NEW_SPARE2_SHUTDOWN_UKNOWN (1U << 12)
|
||||
#define RTC_NEW_SPARE2_SHUTDOWN_SW_LONG_PWR_KEY_PRESS (1U << 13)
|
||||
|
||||
/*
|
||||
* RTC_NEW_SPARE3: RTC_AL_MTH bit0~3
|
||||
* bit 8 ~ 15 : reserved bits
|
||||
*/
|
||||
#define RTC_NEW_SPARE3_THERMAL_SHUTDOWN_BATTERY (1U << 8)
|
||||
#define RTC_NEW_SPARE3_THERMAL_SHUTDOWN_PMIC (1U << 9)
|
||||
#define RTC_NEW_SPARE3_THERMAL_SHUTDOWN_SOC (1U << 10)
|
||||
#define RTC_NEW_SPARE3_THERMAL_SHUTDOWN_MODEM (1U << 11)
|
||||
#define RTC_NEW_SPARE3_THERMAL_SHUTDOWN_WIFI (1U << 12)
|
||||
#define RTC_NEW_SPARE3_THERMAL_SHUTDOWN_PCB (1U << 13)
|
||||
|
||||
/*
|
||||
* RTC_SPAR0:
|
||||
* bit 0 - 5 : SEC in power-on time
|
||||
* bit 6 : 32K less bit. True:with 32K, False:Without 32K
|
||||
* bit 9 - 15: reserved bits
|
||||
*/
|
||||
#define RTC_SPAR0_SPECIAL_MODE_LOW_BATTERY (1U << 9)
|
||||
#define RTC_SPAR0_SPECIAL_MODE_WARM_BOOT_USB_CONNECTED (1U << 10)
|
||||
#define RTC_SPAR0_SPECIAL_MODE_OTA (1U << 11)
|
||||
#define RTC_SPAR0_SPECIAL_MODE_FACTORY_RESET (1U << 12)
|
||||
#define RTC_SPAR0_SPECIAL_MODE_MASK 0xfe00
|
||||
|
||||
|
||||
|
||||
static u16 rtc_read(u16 addr)
|
||||
{
|
||||
u32 rdata = 0;
|
||||
|
||||
pwrap_read((u32)addr, &rdata);
|
||||
return (u16)rdata;
|
||||
}
|
||||
|
||||
static void rtc_write(u16 addr, u16 data)
|
||||
{
|
||||
pwrap_write((u32)addr, (u32)data);
|
||||
}
|
||||
|
||||
void rtc_busy_wait(void)
|
||||
{
|
||||
u32 count = 0;
|
||||
do {
|
||||
while (rtc_read(RTC_BBPU) & RTC_BBPU_CBUSY) {
|
||||
if (count > 1000)
|
||||
break;
|
||||
mdelay(1);
|
||||
count++;
|
||||
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
||||
static void rtc_write_trigger(void)
|
||||
{
|
||||
rtc_write(RTC_WRTGR, 1);
|
||||
rtc_busy_wait();
|
||||
}
|
||||
|
||||
static int (mtk_read_boot_reason)(life_cycle_boot_reason *boot_reason)
|
||||
{
|
||||
u16 rtc_breason;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_breason = rtc_read(RTC_AL_DOM);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE"%s: boot_reason is 0x%x\n", __func__, (u32)(rtc_breason));
|
||||
if (rtc_breason & RTC_NEW_SPARE1_WARM_BOOT_KERNEL_WDOG)
|
||||
*boot_reason = WARMBOOT_BY_KERNEL_WATCHDOG;
|
||||
else if (rtc_breason & RTC_NEW_SPARE1_WARM_BOOT_KERNEL_PANIC)
|
||||
*boot_reason = WARMBOOT_BY_KERNEL_PANIC;
|
||||
else if (rtc_breason & RTC_NEW_SPARE1_WARM_BOOT_HW_WDOG)
|
||||
*boot_reason = WARMBOOT_BY_HW_WATCHDOG;
|
||||
else if (rtc_breason & RTC_NEW_SPARE1_WARM_BOOT_SW)
|
||||
*boot_reason = WARMBOOT_BY_SW;
|
||||
else if (rtc_breason & RTC_NEW_SPARE1_COLD_BOOT_USB)
|
||||
*boot_reason = COLDBOOT_BY_USB;
|
||||
else if (rtc_breason & RTC_NEW_SPARE1_COLD_BOOT_POWER_KEY)
|
||||
*boot_reason = COLDBOOT_BY_POWER_KEY;
|
||||
else if (rtc_breason & RTC_NEW_SPARE1_COLD_BOOT_POWER_SUPPLY)
|
||||
*boot_reason = COLDBOOT_BY_POWER_SUPPLY;
|
||||
else {
|
||||
printk(KERN_ERR"Failed to read boot rtc boot reason\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (mtk_write_boot_reason)(life_cycle_boot_reason boot_reason)
|
||||
{
|
||||
u16 rtc_breason;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_breason = rtc_read(RTC_AL_DOM);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE"%s: current 0x%x boot_reason 0x%x\n", __func__, rtc_breason, boot_reason);
|
||||
if (boot_reason == WARMBOOT_BY_KERNEL_PANIC)
|
||||
rtc_breason = rtc_breason | RTC_NEW_SPARE1_WARM_BOOT_KERNEL_PANIC;
|
||||
else if (boot_reason == WARMBOOT_BY_KERNEL_WATCHDOG)
|
||||
rtc_breason = rtc_breason | RTC_NEW_SPARE1_WARM_BOOT_KERNEL_WDOG;
|
||||
else if (boot_reason == WARMBOOT_BY_HW_WATCHDOG)
|
||||
rtc_breason = rtc_breason | RTC_NEW_SPARE1_WARM_BOOT_HW_WDOG;
|
||||
else if (boot_reason == WARMBOOT_BY_SW)
|
||||
rtc_breason = rtc_breason | RTC_NEW_SPARE1_WARM_BOOT_SW;
|
||||
else if (boot_reason == COLDBOOT_BY_USB)
|
||||
rtc_breason = rtc_breason | RTC_NEW_SPARE1_COLD_BOOT_USB;
|
||||
else if (boot_reason == COLDBOOT_BY_POWER_KEY)
|
||||
rtc_breason = rtc_breason | RTC_NEW_SPARE1_COLD_BOOT_POWER_KEY;
|
||||
else if (boot_reason == COLDBOOT_BY_POWER_SUPPLY)
|
||||
rtc_breason = rtc_breason | RTC_NEW_SPARE1_COLD_BOOT_POWER_SUPPLY;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_write(RTC_AL_DOM, rtc_breason);
|
||||
rtc_write_trigger();
|
||||
rtc_release_lock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (mtk_read_shutdown_reason)(life_cycle_shutdown_reason *shutdown_reason)
|
||||
{
|
||||
u16 rtc_shutdown_reason;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_shutdown_reason = rtc_read(RTC_AL_DOW);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE"%s: shutdown reason is 0x%x\n", __func__, rtc_shutdown_reason);
|
||||
if (rtc_shutdown_reason & RTC_NEW_SPARE2_SHUTDOWN_SW)
|
||||
*shutdown_reason = SHUTDOWN_BY_SW;
|
||||
else if (rtc_shutdown_reason & RTC_NEW_SPARE2_SHUTDOWN_SW_LONG_PWR_KEY_PRESS)
|
||||
*shutdown_reason = SHUTDOWN_BY_SW_LONG_PWR_KEY_PRESS;
|
||||
else if (rtc_shutdown_reason & RTC_NEW_SPARE2_SHUTDOWN_LONG_PWR_KEY_PRESS)
|
||||
*shutdown_reason = SHUTDOWN_BY_LONG_PWR_KEY_PRESS;
|
||||
else if (rtc_shutdown_reason & RTC_NEW_SPARE2_SHUTDOWN_PWR_KEY)
|
||||
*shutdown_reason = SHUTDOWN_BY_PWR_KEY;
|
||||
else if (rtc_shutdown_reason & RTC_NEW_SPARE2_SHUTDOWN_SUDDEN_PWR_LOSS)
|
||||
*shutdown_reason = SHUTDOWN_BY_SUDDEN_POWER_LOSS;
|
||||
else if (rtc_shutdown_reason & RTC_NEW_SPARE2_SHUTDOWN_UKNOWN)
|
||||
*shutdown_reason = SHUTDOWN_BY_UNKNOWN_REASONS;
|
||||
else {
|
||||
printk(KERN_ERR"Failed to read shutdown reason\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (mtk_write_shutdown_reason)(life_cycle_shutdown_reason shutdown_reason)
|
||||
{
|
||||
u16 rtc_shutdown_reason;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_shutdown_reason = rtc_read(RTC_AL_DOW);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE"%s: current 0x%x shutdown_reason 0x%x\n", __func__, rtc_shutdown_reason, shutdown_reason);
|
||||
|
||||
if (shutdown_reason == SHUTDOWN_BY_LONG_PWR_KEY_PRESS)
|
||||
rtc_shutdown_reason = rtc_shutdown_reason | RTC_NEW_SPARE2_SHUTDOWN_LONG_PWR_KEY_PRESS;
|
||||
else if (shutdown_reason == SHUTDOWN_BY_SW)
|
||||
rtc_shutdown_reason = rtc_shutdown_reason | RTC_NEW_SPARE2_SHUTDOWN_SW;
|
||||
else if (shutdown_reason == SHUTDOWN_BY_PWR_KEY)
|
||||
rtc_shutdown_reason = rtc_shutdown_reason | RTC_NEW_SPARE2_SHUTDOWN_PWR_KEY;
|
||||
else if (shutdown_reason == SHUTDOWN_BY_SUDDEN_POWER_LOSS)
|
||||
rtc_shutdown_reason = rtc_shutdown_reason | RTC_NEW_SPARE2_SHUTDOWN_SUDDEN_PWR_LOSS;
|
||||
else if (shutdown_reason == SHUTDOWN_BY_UNKNOWN_REASONS)
|
||||
rtc_shutdown_reason = rtc_shutdown_reason | RTC_NEW_SPARE2_SHUTDOWN_UKNOWN;
|
||||
else if (shutdown_reason == SHUTDOWN_BY_SW_LONG_PWR_KEY_PRESS)
|
||||
rtc_shutdown_reason = rtc_shutdown_reason | RTC_NEW_SPARE2_SHUTDOWN_SW_LONG_PWR_KEY_PRESS;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_write(RTC_AL_DOW, rtc_shutdown_reason);
|
||||
rtc_write_trigger();
|
||||
rtc_release_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (mtk_read_thermal_shutdown_reason)(life_cycle_thermal_shutdown_reason *thermal_shutdown_reason)
|
||||
{
|
||||
u16 rtc_thermal_shutdown_reason;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_thermal_shutdown_reason = rtc_read(RTC_AL_MTH);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE"%s: thermal shutdown reason 0x%x\n", __func__, rtc_thermal_shutdown_reason);
|
||||
if (rtc_thermal_shutdown_reason & RTC_NEW_SPARE3_THERMAL_SHUTDOWN_BATTERY)
|
||||
*thermal_shutdown_reason = THERMAL_SHUTDOWN_REASON_BATTERY;
|
||||
else if (rtc_thermal_shutdown_reason & RTC_NEW_SPARE3_THERMAL_SHUTDOWN_PMIC)
|
||||
*thermal_shutdown_reason = THERMAL_SHUTDOWN_REASON_PMIC;
|
||||
else if (rtc_thermal_shutdown_reason & RTC_NEW_SPARE3_THERMAL_SHUTDOWN_SOC)
|
||||
*thermal_shutdown_reason = THERMAL_SHUTDOWN_REASON_SOC;
|
||||
else if (rtc_thermal_shutdown_reason & RTC_NEW_SPARE3_THERMAL_SHUTDOWN_MODEM)
|
||||
*thermal_shutdown_reason = THERMAL_SHUTDOWN_REASON_MODEM;
|
||||
else if (rtc_thermal_shutdown_reason & RTC_NEW_SPARE3_THERMAL_SHUTDOWN_WIFI)
|
||||
*thermal_shutdown_reason = THERMAL_SHUTDOWN_REASON_WIFI;
|
||||
else if (rtc_thermal_shutdown_reason & RTC_NEW_SPARE3_THERMAL_SHUTDOWN_PCB)
|
||||
*thermal_shutdown_reason = THERMAL_SHUTDOWN_REASON_PCB;
|
||||
else {
|
||||
printk(KERN_ERR"Failed to read thermal shutdown reason\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (mtk_write_thermal_shutdown_reason)(life_cycle_thermal_shutdown_reason thermal_shutdown_reason)
|
||||
{
|
||||
u16 rtc_thermal_shutdown_reason;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_thermal_shutdown_reason = rtc_read(RTC_AL_MTH);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE "%s: current 0x%x thermal shutdown_reason 0x%0x\n",
|
||||
__func__, rtc_thermal_shutdown_reason, thermal_shutdown_reason);
|
||||
|
||||
|
||||
if (thermal_shutdown_reason == THERMAL_SHUTDOWN_REASON_BATTERY)
|
||||
rtc_thermal_shutdown_reason = rtc_thermal_shutdown_reason | RTC_NEW_SPARE3_THERMAL_SHUTDOWN_BATTERY;
|
||||
else if (thermal_shutdown_reason == THERMAL_SHUTDOWN_REASON_PMIC)
|
||||
rtc_thermal_shutdown_reason = rtc_thermal_shutdown_reason | RTC_NEW_SPARE3_THERMAL_SHUTDOWN_PMIC;
|
||||
else if (thermal_shutdown_reason == THERMAL_SHUTDOWN_REASON_SOC)
|
||||
rtc_thermal_shutdown_reason = rtc_thermal_shutdown_reason | RTC_NEW_SPARE3_THERMAL_SHUTDOWN_SOC;
|
||||
else if (thermal_shutdown_reason == THERMAL_SHUTDOWN_REASON_MODEM)
|
||||
rtc_thermal_shutdown_reason = rtc_thermal_shutdown_reason | RTC_NEW_SPARE3_THERMAL_SHUTDOWN_MODEM;
|
||||
else if (thermal_shutdown_reason == THERMAL_SHUTDOWN_REASON_WIFI)
|
||||
rtc_thermal_shutdown_reason = rtc_thermal_shutdown_reason | RTC_NEW_SPARE3_THERMAL_SHUTDOWN_WIFI;
|
||||
else if (thermal_shutdown_reason == THERMAL_SHUTDOWN_REASON_PCB)
|
||||
rtc_thermal_shutdown_reason = rtc_thermal_shutdown_reason | RTC_NEW_SPARE3_THERMAL_SHUTDOWN_PCB;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_write(RTC_AL_MTH, rtc_thermal_shutdown_reason);
|
||||
rtc_write_trigger();
|
||||
rtc_release_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (mtk_read_special_mode)(life_cycle_special_mode *special_mode)
|
||||
{
|
||||
u16 rtc_smode;
|
||||
rtc_acquire_lock();
|
||||
rtc_smode = rtc_read(RTC_SPAR1);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE"%s: special mode is 0x%x\n", __func__, rtc_smode);
|
||||
if (rtc_smode & RTC_SPAR0_SPECIAL_MODE_LOW_BATTERY)
|
||||
*special_mode = LIFE_CYCLE_SMODE_LOW_BATTERY;
|
||||
else if (rtc_smode & RTC_SPAR0_SPECIAL_MODE_WARM_BOOT_USB_CONNECTED)
|
||||
*special_mode = LIFE_CYCLE_SMODE_WARM_BOOT_USB_CONNECTED;
|
||||
else if (rtc_smode & RTC_SPAR0_SPECIAL_MODE_OTA)
|
||||
*special_mode = LIFE_CYCLE_SMODE_OTA;
|
||||
else if (rtc_smode & RTC_SPAR0_SPECIAL_MODE_FACTORY_RESET)
|
||||
*special_mode = LIFE_CYCLE_SMODE_FACTORY_RESET;
|
||||
else {
|
||||
printk(KERN_ERR"Failed to read special mode\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (mtk_write_special_mode)(life_cycle_special_mode special_mode)
|
||||
{
|
||||
u16 rtc_smode;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_smode = rtc_read(RTC_SPAR1);
|
||||
rtc_release_lock();
|
||||
|
||||
printk(KERN_NOTICE"%s: current 0x%x special_mode 0x%x\n", __func__, rtc_smode, special_mode);
|
||||
|
||||
if (special_mode == LIFE_CYCLE_SMODE_LOW_BATTERY)
|
||||
rtc_smode = rtc_smode | RTC_SPAR0_SPECIAL_MODE_LOW_BATTERY;
|
||||
else if (special_mode == LIFE_CYCLE_SMODE_WARM_BOOT_USB_CONNECTED)
|
||||
rtc_smode = rtc_smode | RTC_SPAR0_SPECIAL_MODE_WARM_BOOT_USB_CONNECTED;
|
||||
else if (special_mode == LIFE_CYCLE_SMODE_OTA)
|
||||
rtc_smode = rtc_smode | RTC_SPAR0_SPECIAL_MODE_OTA;
|
||||
else if (special_mode == LIFE_CYCLE_SMODE_FACTORY_RESET)
|
||||
rtc_smode = rtc_smode | RTC_SPAR0_SPECIAL_MODE_FACTORY_RESET;
|
||||
|
||||
rtc_acquire_lock();
|
||||
rtc_write(RTC_SPAR1, rtc_smode);
|
||||
rtc_write_trigger();
|
||||
rtc_release_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mtk_lcr_reset(void)
|
||||
{
|
||||
u16 data;
|
||||
|
||||
rtc_acquire_lock();
|
||||
/* clean up the boot reason */
|
||||
data = rtc_read(RTC_AL_DOM);
|
||||
data = data & ~RTC_NEW_SPARE1;
|
||||
rtc_write(RTC_AL_DOM, data);
|
||||
|
||||
/* clean up the shutdown reason */
|
||||
data = rtc_read(RTC_AL_DOW);
|
||||
data = data & ~RTC_NEW_SPARE2;
|
||||
rtc_write(RTC_AL_DOW, data);
|
||||
|
||||
/* clean up the thermal shutdown reason */
|
||||
data = rtc_read(RTC_AL_MTH);
|
||||
data = data & ~RTC_NEW_SPARE3;
|
||||
rtc_write(RTC_AL_MTH, data);
|
||||
|
||||
/* clean up special mode */
|
||||
data = rtc_read(RTC_SPAR1);
|
||||
data = data & ~RTC_SPAR0_SPECIAL_MODE_MASK;
|
||||
rtc_write(RTC_SPAR1, data);
|
||||
|
||||
rtc_write_trigger();
|
||||
rtc_release_lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int life_cycle_platform_init(sign_of_life_ops *sol_ops)
|
||||
{
|
||||
printk(KERN_NOTICE "%s: Support MTK platform\n", __func__);
|
||||
sol_ops->read_boot_reason = mtk_read_boot_reason;
|
||||
sol_ops->write_boot_reason = mtk_write_boot_reason;
|
||||
sol_ops->read_shutdown_reason = mtk_read_shutdown_reason;
|
||||
sol_ops->write_shutdown_reason = mtk_write_shutdown_reason;
|
||||
sol_ops->read_thermal_shutdown_reason = mtk_read_thermal_shutdown_reason;
|
||||
sol_ops->write_thermal_shutdown_reason = mtk_write_thermal_shutdown_reason;
|
||||
sol_ops->read_special_mode = mtk_read_special_mode;
|
||||
sol_ops->write_special_mode = mtk_write_special_mode;
|
||||
sol_ops->lcr_reset = mtk_lcr_reset;
|
||||
|
||||
if (rtc_lprst_detected()) {
|
||||
rtc_mark_clear_lprst();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Amazon Technologies, Inc.
|
||||
* Portions Copyright (C) 2007-2008 Google, 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.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_LOGGER_KLOG_H
|
||||
#define _LINUX_LOGGER_KLOG_H
|
||||
|
||||
void logger_kmsg_write(const char *log_msg, size_t len);
|
||||
|
||||
#endif /* _LINUX_LOGGER_KLOG_H */
|
||||
@@ -1,89 +0,0 @@
|
||||
|
||||
#ifndef __LINUX_MDUMP_H__
|
||||
#define __LINUX_MDUMP_H__
|
||||
|
||||
#define MDUMP_COLD_RESET 0x00
|
||||
#define MDUMP_FORCE_RESET 0x1E
|
||||
#define MDUMP_REBOOT_WATCHDOG 0x2D
|
||||
#define MDUMP_REBOOT_PANIC 0x3C
|
||||
#define MDUMP_REBOOT_NORMAL 0xC3
|
||||
#define MDUMP_REBOOT_HARDWARE 0xE1
|
||||
|
||||
#ifndef CONFIG_MDUMP
|
||||
|
||||
static inline void mdump_mark_reboot_reason(int mode) { }
|
||||
|
||||
#else
|
||||
|
||||
#define MDUMP_BUFFER_SIG 0x4842444dU /* MDBH */
|
||||
|
||||
#ifndef CONFIG_MDUMP_MESSAGE_SIZE
|
||||
#define CONFIG_MDUMP_MESSAGE_SIZE 65536
|
||||
#endif
|
||||
|
||||
#define BOOTLOADER_LK_ADDRESS 0x81E00000
|
||||
#define BOOTLOADER_LK_SIZE 0x00100000
|
||||
|
||||
#ifndef CONFIG_MDUMP_BUFFER_ADDRESS
|
||||
#define CONFIG_MDUMP_BUFFER_ADDRESS 0x81FC0000
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MDUMP_COMPRESS
|
||||
|
||||
/* when using compression feature, we need more space, therefore
|
||||
then whole 1MB from 0x81F00000 will be reserved */
|
||||
#define CONFIG_MDUMP_WITH_COMPRESS_ADDRESS 0x81F00000
|
||||
#define CONFIG_MDUMP_WITH_COMPRESS_WORKAREA_SIZE 0x100000
|
||||
|
||||
#define COMP_SIGNATURE_SIZE 16
|
||||
#define COMP_HEAD_SIGNATURE "UFBLCOMPDUMPSTA"
|
||||
|
||||
#define COMPRESS_START_ADDRESS 0x8D000000
|
||||
|
||||
struct compress_file_header {
|
||||
char header_signature[COMP_SIGNATURE_SIZE];
|
||||
uint32_t num_of_segments;
|
||||
uint32_t total_file_size;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_MDUMP_COMPRESS */
|
||||
|
||||
struct mdump_buffer {
|
||||
unsigned int signature;
|
||||
unsigned char reboot_reason;
|
||||
unsigned char backup_reason;
|
||||
unsigned short enable_flags;
|
||||
char stage1_messages[CONFIG_MDUMP_MESSAGE_SIZE - 12];
|
||||
char zero_pad1[4];
|
||||
char stage2_messages[CONFIG_MDUMP_MESSAGE_SIZE - 4];
|
||||
char zero_pad2[4];
|
||||
};
|
||||
|
||||
extern void mdump_mark_reboot_reason(int);
|
||||
|
||||
#endif
|
||||
|
||||
#define MDUMP_HEADER_SIG 0x524448504d55444dULL /* MDUMPHDR */
|
||||
|
||||
/* This block size will support all(maybe?) type block devices */
|
||||
#define MDUMP_BLOCK_SIZE 4096
|
||||
|
||||
#define MDUMP_BANK_MAXIMUM \
|
||||
((MDUMP_BLOCK_SIZE - 16) / sizeof(struct mdump_bank))
|
||||
|
||||
struct mdump_bank {
|
||||
char name[8];
|
||||
unsigned int size; /* bank size */
|
||||
unsigned int address;
|
||||
} __packed;
|
||||
struct mdump_header {
|
||||
unsigned long long signature;
|
||||
unsigned char reboot_reason;
|
||||
unsigned char bank_count;
|
||||
unsigned short block_size;
|
||||
unsigned int crc32;
|
||||
struct mdump_bank entries[MDUMP_BANK_MAXIMUM];
|
||||
} __packed;
|
||||
|
||||
#endif /* __LINUX_MDUMP_H__ */
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Amazon Technologies, Inc.
|
||||
* Portions Copyright (C) 2007-2008 Google, 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.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_METRICSLOG_H
|
||||
#define _LINUX_METRICSLOG_H
|
||||
|
||||
#ifdef CONFIG_AMAZON_METRICS_LOG
|
||||
|
||||
#include <linux/xlog.h>
|
||||
|
||||
typedef enum {
|
||||
VITALS_NORMAL = 0,
|
||||
VITALS_FGTRACKING,
|
||||
VITALS_TIME_BUCKET,
|
||||
} vitals_type;
|
||||
|
||||
void log_to_metrics(enum android_log_priority priority,
|
||||
const char *domain, const char *logmsg);
|
||||
|
||||
void log_counter_to_vitals(enum android_log_priority priority,
|
||||
const char *domain, const char *program,
|
||||
const char *source, const char *key,
|
||||
long counter_value, const char *unit,
|
||||
const char *metadata, vitals_type type);
|
||||
void log_timer_to_vitals(enum android_log_priority priority,
|
||||
const char *domain, const char *program,
|
||||
const char *source, const char *key,
|
||||
long timer_value, const char *unit, vitals_type type);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _LINUX_METRICSLOG_H */
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* sign_of_life.h
|
||||
*
|
||||
* Device sign of life header file
|
||||
*
|
||||
* Copyright (C) Amazon Technologies Inc. All rights reserved.
|
||||
* Yang Liu (yangliu@lab126.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef __SIGN_OF_LIFE_H
|
||||
#define __SIGN_OF_LIFE_H
|
||||
|
||||
/* Device Boot Reason */
|
||||
typedef enum {
|
||||
WARMBOOT_BY_KERNEL_PANIC = 0x100,
|
||||
WARMBOOT_BY_KERNEL_WATCHDOG = 0x101,
|
||||
WARMBOOT_BY_HW_WATCHDOG = 0x102,
|
||||
WARMBOOT_BY_SW = 0x103,
|
||||
COLDBOOT_BY_USB = 0x104,
|
||||
COLDBOOT_BY_POWER_KEY = 0x105,
|
||||
COLDBOOT_BY_POWER_SUPPLY = 0x106,
|
||||
} life_cycle_boot_reason;
|
||||
|
||||
/* Device Shutdown Reason */
|
||||
typedef enum {
|
||||
SHUTDOWN_BY_LONG_PWR_KEY_PRESS = 0x201,
|
||||
SHUTDOWN_BY_SW = 0x202,
|
||||
SHUTDOWN_BY_PWR_KEY = 0x203,
|
||||
SHUTDOWN_BY_SUDDEN_POWER_LOSS = 0x204,
|
||||
SHUTDOWN_BY_UNKNOWN_REASONS = 0x205,
|
||||
SHUTDOWN_BY_SW_LONG_PWR_KEY_PRESS = 0x206,
|
||||
} life_cycle_shutdown_reason;
|
||||
|
||||
/* THERMAL SHUTDOWN REASON */
|
||||
typedef enum {
|
||||
THERMAL_SHUTDOWN_REASON_BATTERY = 0x301,
|
||||
THERMAL_SHUTDOWN_REASON_PMIC = 0x302,
|
||||
THERMAL_SHUTDOWN_REASON_SOC = 0x303, // CPU, little and big cluster, GPU
|
||||
THERMAL_SHUTDOWN_REASON_MODEM = 0x304, // Modem
|
||||
THERMAL_SHUTDOWN_REASON_WIFI = 0x305, // WIFI
|
||||
THERMAL_SHUTDOWN_REASON_PCB = 0x306, // SKIN TEMPERATURE Sensor
|
||||
} life_cycle_thermal_shutdown_reason;
|
||||
|
||||
/* LIFE CYCLE Special Mode */
|
||||
typedef enum {
|
||||
LIFE_CYCLE_SMODE_NONE = 0x400,
|
||||
LIFE_CYCLE_SMODE_LOW_BATTERY = 0x401,
|
||||
LIFE_CYCLE_SMODE_WARM_BOOT_USB_CONNECTED = 0x402,
|
||||
LIFE_CYCLE_SMODE_OTA = 0x403,
|
||||
LIFE_CYCLE_SMODE_FACTORY_RESET = 0x404,
|
||||
} life_cycle_special_mode;
|
||||
|
||||
/* sign of life operations */
|
||||
typedef struct sign_of_life_ops {
|
||||
int (*read_boot_reason)(life_cycle_boot_reason *boot_reason);
|
||||
int (*write_boot_reason)(life_cycle_boot_reason boot_reason);
|
||||
int (*read_shutdown_reason)(life_cycle_shutdown_reason *shutdown_reason);
|
||||
int (*write_shutdown_reason)(life_cycle_shutdown_reason shutdown_reason);
|
||||
int (*read_thermal_shutdown_reason)(life_cycle_thermal_shutdown_reason *thermal_shutdown_reason);
|
||||
int (*write_thermal_shutdown_reason)(life_cycle_thermal_shutdown_reason thermal_shutdown_reason);
|
||||
int (*read_special_mode)(life_cycle_special_mode *special_mode);
|
||||
int (*write_special_mode)(life_cycle_special_mode special_mode);
|
||||
int (*lcr_reset)(void);
|
||||
} sign_of_life_ops;
|
||||
|
||||
|
||||
/*
|
||||
* life_cycle_set_boot_reason
|
||||
* Description: this function will set the boot reason which causing device booting
|
||||
*/
|
||||
int life_cycle_set_boot_reason(life_cycle_boot_reason boot_reason);
|
||||
|
||||
/*
|
||||
* life_cycle_set_shutdown_reason
|
||||
* Description: this function will set the Shutdown reason which causing device shutdown
|
||||
*/
|
||||
int life_cycle_set_shutdown_reason(life_cycle_shutdown_reason shutdown_reason);
|
||||
|
||||
/*
|
||||
* life_cycle_set_thermal_shutdown_reason
|
||||
* Description: this function will set the Thermal Shutdown reason which causing device shutdown
|
||||
*/
|
||||
int life_cycle_set_thermal_shutdown_reason(life_cycle_thermal_shutdown_reason thermal_shutdown_reason);
|
||||
|
||||
/*
|
||||
* life_cycle_set_special_mode
|
||||
* Description: this function will set the special mode which causing device life cycle change
|
||||
*/
|
||||
int life_cycle_set_special_mode(life_cycle_special_mode life_cycle_special_mode);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user