Remove amazon logging function drivers

This commit is contained in:
ggow
2019-04-20 02:24:52 +01:00
parent 60c2ceebfd
commit 55194e165f
14 changed files with 0 additions and 2248 deletions
-2
View File
@@ -140,6 +140,4 @@ source "drivers/staging/netlogic/Kconfig"
source "drivers/staging/dwc2/Kconfig"
source "drivers/staging/amazon/Kconfig"
endif # STAGING
-1
View File
@@ -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/
-103
View File
@@ -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
-8
View File
@@ -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
-202
View File
@@ -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);
-270
View File
@@ -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);
-67
View File
@@ -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);
-438
View File
@@ -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");
-505
View File
@@ -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");
-403
View File
@@ -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;
}
-20
View File
@@ -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 */
-89
View File
@@ -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__ */
-44
View File
@@ -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 */
-96
View File
@@ -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