From: luodw1 Date: Thu, 18 Oct 2018 02:24:59 +0000 (+0800) Subject: driver: add moto reboot reason X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=8294c23445931d2db836ca8fa2296c7701b6f997;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git driver: add moto reboot reason Change-Id: Ic0550e74736cbf0b39f2130d2be52be328b30099 Signed-off-by: luodw1 Reviewed-on: https://gerrit.mot.com/1258098 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Xiangpo Zhao Submit-Approved: Jira Key --- diff --git a/drivers/soc/samsung/exynos-reboot.c b/drivers/soc/samsung/exynos-reboot.c index 61c4add4d8b9..1add46a724f4 100644 --- a/drivers/soc/samsung/exynos-reboot.c +++ b/drivers/soc/samsung/exynos-reboot.c @@ -70,7 +70,7 @@ int soc_has_big(void) #define RESET_SEQUENCER_CONFIGURATION (0x0500) #define PS_HOLD_CONTROL (0x330C) #define EXYNOS_PMU_SYSIP_DAT0 (0x0810) -#define LAST_POWERUP_REASON_REG (0x0854) /*EXYNOS9610_POWER_INFORM9*/ +#define EXYNOS_PMU_SYSIP_DAT3 (0x081C) /* defines for BIG reset */ #define PEND_BIG (1 << 0) #define PEND_LITTLE (1 << 1) @@ -118,6 +118,18 @@ int soc_has_big(void) | RESET_DISABLE_PRESET_DBG \ | RESET_DISABLE_L2RESET) +static int in_panic = 0; +static int panic_prep_restart(struct notifier_block *this, + unsigned long event, void *ptr) +{ + in_panic = 1; + return NOTIFY_DONE; +} + +static struct notifier_block panic_blk = { + .notifier_call = panic_prep_restart, +}; + static void dfd_set_dump_gpr(int en) { u32 reg_val; @@ -211,15 +223,6 @@ void big_reset_control(int en) /* Reboot into recovery */ #define REBOOT_MODE_FACTORY 0xFD -#define RESET_EXTRA_RESET_KUNPOW_REASON BIT(9) -#define RESET_EXTRA_POST_PANIC_REASON (BIT(4) | BIT(5)) -#define RESET_EXTRA_POST_PMICWDT_REASON BIT(5) -#define RESET_EXTRA_POST_WDT_REASON BIT(4) -#define RESET_EXTRA_POST_REBOOT_MASK (BIT(4) | BIT(5) | BIT(6)) -#define RESET_EXTRA_PANIC_REASON BIT(3) -#define RESET_EXTRA_REBOOT_BL_REASON BIT(2) -#define RESET_EXTRA_HW_RESET_REASON BIT(1) - #if !defined(CONFIG_SEC_REBOOT) #ifdef CONFIG_OF static void exynos_power_off(void) @@ -280,11 +283,13 @@ static void exynos_power_off(void) #endif #endif +#define PON_RESTART_REASON_OEM_MIN 0x20 + static void exynos_reboot(enum reboot_mode mode, const char *cmd) { u32 soc_id, revision; void __iomem *addr; - void __iomem *addr_extra; + void __iomem *restart_reason; if (!exynos_pmu_base) return; #ifdef CONFIG_EXYNOS_ACPM @@ -293,9 +298,8 @@ static void exynos_reboot(enum reboot_mode mode, const char *cmd) printk("[%s] reboot cmd: %s\n", __func__, cmd); addr = exynos_pmu_base + EXYNOS_PMU_SYSIP_DAT0; - addr_extra = exynos_pmu_base + LAST_POWERUP_REASON_REG; - /*Clear the last power up reason first*/ - __raw_writel(0, addr_extra); + restart_reason = exynos_pmu_base + EXYNOS_PMU_SYSIP_DAT3; + if (cmd) { if (!strcmp((char *)cmd, "charge")) { __raw_writel(REBOOT_MODE_CHARGE, addr); @@ -306,15 +310,54 @@ static void exynos_reboot(enum reboot_mode mode, const char *cmd) __raw_writel(REBOOT_MODE_RECOVERY, addr); } else if (!strcmp(cmd, "sfactory")) { __raw_writel(REBOOT_MODE_FACTORY, addr); - } else if (!strncmp(cmd, "post-wdt",8)) { - __raw_writel(RESET_EXTRA_POST_WDT_REASON, addr_extra); - } else if (!strncmp(cmd, "post-pmicwdt",12)) { - __raw_writel(RESET_EXTRA_POST_PMICWDT_REASON, addr_extra); - } else if (!strncmp(cmd, "post-panic",10)) { - __raw_writel(RESET_EXTRA_POST_PANIC_REASON, addr_extra); } } + if (cmd != NULL) { + if (!strncmp(cmd, "bootloader", 10)) { + __raw_writel(0x77665500, restart_reason); + } else if (!strncmp(cmd, "recovery", 8)) { + __raw_writel(0x77665502, restart_reason); + } else if (!strcmp(cmd, "rtc")) { + __raw_writel(0x77665503, restart_reason); + } else if (!strcmp(cmd, "dm-verity device corrupted")) { + __raw_writel(0x77665508, restart_reason); + } else if (!strcmp(cmd, "dm-verity enforcing")) { + __raw_writel(0x77665509, restart_reason); + } else if (!strcmp(cmd, "keys clear")) { + __raw_writel(0x7766550a, restart_reason); + } else if (!strncmp(cmd, "oem-", 4)) { + unsigned long code; + unsigned long reset_reason; + int ret; + + ret = kstrtoul(cmd + 4, 16, &code); + if (!ret) { + /* Bit-2 to bit-7 of SOFT_RB_SPARE for hard + * reset reason: + * Value 0 to 31 for common defined features + * Value 32 to 63 for oem specific features + */ + reset_reason = code + + PON_RESTART_REASON_OEM_MIN; + __raw_writel(0x6f656d00 | (code & 0xff), + restart_reason); + } + } else if (!strncmp(cmd, "post-wdt", 8)) { + __raw_writel(0x77665508, restart_reason); + } else if (!strncmp(cmd, "post-pmicwdt", 12)) { + __raw_writel(0x77665507, restart_reason); + } else if (!strncmp(cmd, "post-panic", 10)) { + __raw_writel(0x77665506, restart_reason); + } else { + __raw_writel(0x77665501, restart_reason); + } + } else if (in_panic == 1) { + __raw_writel(0x77665505, restart_reason); + } else { + __raw_writel(0x77665501, restart_reason); + } + /* Check by each SoC */ soc_id = exynos_soc_info.product_id; revision = exynos_soc_info.revision; @@ -391,6 +434,7 @@ static int __init exynos_reboot_init(void) if (!np) return -ENODEV; + atomic_notifier_chain_register(&panic_notifier_list, &panic_blk); arm_pm_restart = exynos_reboot; #if !defined(CONFIG_SEC_REBOOT) pm_power_off = exynos_power_off;