driver: add moto reboot reason
authorluodw1 <luodw1@motorola.com>
Thu, 18 Oct 2018 02:24:59 +0000 (10:24 +0800)
committerxiest1 <xiest1@lenovo.com>
Tue, 5 Nov 2019 09:30:19 +0000 (17:30 +0800)
Change-Id: Ic0550e74736cbf0b39f2130d2be52be328b30099
Signed-off-by: luodw1 <luodw1@motorola.com>
Reviewed-on: https://gerrit.mot.com/1258098
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key

drivers/soc/samsung/exynos-reboot.c

index 61c4add4d8b9416f500917e97a328f368dbb2681..1add46a724f4a5314cc123e44ac81f7eef147820 100644 (file)
@@ -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;