c05564c4d8
Android 13
185 lines
5.6 KiB
C
Executable file
185 lines
5.6 KiB
C
Executable file
/*
|
|
* Copyright (c) 2016 Samsung Electronics Co., Ltd.
|
|
* http://www.samsung.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.
|
|
*/
|
|
|
|
#define DEBUG 1
|
|
|
|
#include <linux/delay.h>
|
|
#include <linux/pm.h>
|
|
#include <linux/io.h>
|
|
#include <linux/gpio.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_gpio.h>
|
|
#include <linux/input.h>
|
|
#include <asm/cacheflush.h>
|
|
#include <asm/system_misc.h>
|
|
#include <linux/power_supply.h>
|
|
#include <linux/sec_debug.h>
|
|
#if defined(CONFIG_SEC_ABC)
|
|
#include <linux/sti/abc_common.h>
|
|
#endif
|
|
|
|
/* function ptr for original arm_pm_restart */
|
|
void (*mach_power_off)(void);
|
|
EXPORT_SYMBOL(mach_power_off);
|
|
|
|
void (*mach_restart)(enum reboot_mode mode, const char *cmd);
|
|
EXPORT_SYMBOL(mach_restart);
|
|
|
|
#define psy_get_property(psy, property, value) \
|
|
{ \
|
|
int ret; \
|
|
if (!psy) { \
|
|
pr_err("%s: Fail to get "#psy" psy\n", __func__); \
|
|
value.intval = 0; \
|
|
} else { \
|
|
if (psy->desc->get_property != NULL) { \
|
|
ret = psy->desc->get_property(psy, (property), &(value)); \
|
|
if (ret < 0) { \
|
|
pr_err("%s: Fail to get property of "#psy" (%d=>%d)\n", \
|
|
__func__, (property), ret); \
|
|
value.intval = 0; \
|
|
} \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#if defined(CONFIG_SEC_DUMP_SINK)
|
|
void sec_set_reboot_magic(int magic)
|
|
{
|
|
int tmp;
|
|
|
|
tmp = LAST_RR_VAL(reboot_magic);
|
|
pr_info("%s: prev: %x\n", __func__, tmp);
|
|
tmp = magic;
|
|
pr_info("%s: set as: %x\n", __func__, tmp);
|
|
LAST_RR_SET(reboot_magic, tmp);
|
|
}
|
|
#endif
|
|
|
|
extern int mtk_pmic_pwrkey_status(void);
|
|
|
|
static void sec_power_off(void)
|
|
{
|
|
int pressed;
|
|
union power_supply_propval ac_val = {0, }, usb_val = {0, }, wc_val = {0, };
|
|
struct power_supply *ac_psy = power_supply_get_by_name("ac");
|
|
struct power_supply *usb_psy = power_supply_get_by_name("usb");
|
|
struct power_supply *wc_psy = power_supply_get_by_name("wireless");
|
|
|
|
psy_get_property(ac_psy, POWER_SUPPLY_PROP_ONLINE, ac_val);
|
|
psy_get_property(usb_psy, POWER_SUPPLY_PROP_ONLINE, usb_val);
|
|
psy_get_property(wc_psy, POWER_SUPPLY_PROP_ONLINE, wc_val);
|
|
|
|
pr_info("[%s] AC[%d] : USB[%d] : WC[%d]\n", __func__,
|
|
ac_val.intval, usb_val.intval, wc_val.intval);
|
|
|
|
/* This is NOT upload case */
|
|
LAST_RR_SET(is_upload, UPLOAD_MAGIC_NORMAL);
|
|
pr_emerg("%s: waiting for reboot\n", __func__);
|
|
__inner_flush_dcache_all();
|
|
|
|
while (1) {
|
|
/* wait for power button release */
|
|
pressed = mtk_pmic_pwrkey_status();
|
|
if (!pressed) {
|
|
pr_info("%s: PowerButton was released(%d)\n", __func__, pressed);
|
|
mach_power_off();
|
|
} else {
|
|
/* if power button is not released, wait and check TA again */
|
|
pr_info("%s: PowerButton wasn't released(%d)\n", __func__, pressed);
|
|
}
|
|
|
|
mdelay(1000);
|
|
}
|
|
}
|
|
|
|
static void sec_reboot(enum reboot_mode reboot_mode, const char *cmd)
|
|
{
|
|
local_irq_disable();
|
|
pr_emerg("%s (%d, %s)\n", __func__, reboot_mode, cmd ? cmd : "(null)");
|
|
|
|
/* LPM mode prevention */
|
|
LAST_RR_SET(is_power_reset, SEC_POWER_RESET);
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_UNKNOWN);
|
|
|
|
if (cmd) {
|
|
unsigned long value;
|
|
if (!strcmp(cmd, "recovery-update"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_FOTA);
|
|
else if (!strcmp(cmd, "fota_bl"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_FOTA_BL);
|
|
else if (!strcmp(cmd, "recovery"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_RECOVERY);
|
|
else if (!strcmp(cmd, "download"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_DOWNLOAD);
|
|
else if (!strcmp(cmd, "bootloader"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_BOOTLOADER);
|
|
else if (!strcmp(cmd, "upload"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_UPLOAD);
|
|
else if (!strcmp(cmd, "secure"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_SECURE);
|
|
else if (!strcmp(cmd, "fwup"))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_FWUP);
|
|
#if defined(CONFIG_SEC_ABC)
|
|
else if (!strncmp(cmd, "user_dram_test", 14) && sec_abc_get_enabled())
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_USER_DRAM_TEST);
|
|
#endif
|
|
else if (!strncmp(cmd, "emergency", 9))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_REASON_EMERGENCY);
|
|
else if (!strncmp(cmd, "debug", 5)
|
|
&& !kstrtoul(cmd + 5, 0, &value))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_SET_DEBUG | value);
|
|
#if defined(CONFIG_SEC_DUMP_SINK)
|
|
else if (!strncmp(cmd, "dump_sink", 9) && !kstrtoul(cmd + 9, 0, &value))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_SET_DUMPSINK | (SEC_DUMPSINK_MASK & value));
|
|
#endif
|
|
else if (!strncmp(cmd, "swsel", 5)
|
|
&& !kstrtoul(cmd + 5, 0, &value))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_SET_SWSEL | value);
|
|
else if (!strncmp(cmd, "sud", 3)
|
|
&& !kstrtoul(cmd + 3, 0, &value))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_SET_SUD | value);
|
|
else if (!strncmp(cmd, "cpmem_on", 8))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_CP_DBGMEM | 0x1);
|
|
else if (!strncmp(cmd, "cpmem_off", 9))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_CP_DBGMEM | 0x2);
|
|
#ifdef CONFIG_SEC_DEBUG_MDM_SEPERATE_CRASH
|
|
else if (!strncmp(cmd, "cpdebug", 7)
|
|
&& !kstrtoul(cmd + 7, 0, &value))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_SET_CP_DEBUG | value);
|
|
#endif
|
|
#ifdef CONFIG_DIAG_MODE
|
|
else if (!strncmp(cmd, "diag", 4)
|
|
&& !kstrtoul(cmd + 4, 0, &value))
|
|
LAST_RR_SET(power_reset_reason, SEC_RESET_SET_DIAG | (value & 0x1));
|
|
#endif
|
|
}
|
|
/* This is NOT upload case */
|
|
LAST_RR_SET(is_upload, UPLOAD_MAGIC_NORMAL);
|
|
pr_emerg("%s: waiting for reboot\n", __func__);
|
|
|
|
__inner_flush_dcache_all();
|
|
|
|
mach_restart(REBOOT_COLD, "hw reset");
|
|
|
|
while (1);
|
|
}
|
|
|
|
static int __init sec_reboot_init(void)
|
|
{
|
|
mach_restart = arm_pm_restart;
|
|
mach_power_off = pm_power_off;
|
|
|
|
pm_power_off = sec_power_off;
|
|
arm_pm_restart = sec_reboot;
|
|
|
|
return 0;
|
|
}
|
|
subsys_initcall(sec_reboot_init);
|