reboot: add reboot reason sys infterface [1/1]
authorHong Guo <hong.guo@amlogic.com>
Sat, 7 Sep 2019 07:21:22 +0000 (15:21 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Tue, 22 Oct 2019 08:47:08 +0000 (01:47 -0700)
PD#TV-9896

Problem:
provide sys interface to get last reboot reason

Solution:
add reboot reason sys infterface

Verify:
test pass on tl1_x301

Change-Id: I6c4046c892eff9f92506fadb0cddee7041c8f882
Signed-off-by: Hong Guo <hong.guo@amlogic.com>
arch/arm/boot/dts/amlogic/mesontl1.dtsi
arch/arm64/boot/dts/amlogic/mesontl1.dtsi
drivers/amlogic/reboot/reboot.c

index ac996dd..bf1ce84 100644 (file)
                compatible = "amlogic,reboot";
                sys_reset = <0x84000009>;
                sys_poweroff = <0x84000008>;
+               reboot_reason_addr = <0xff80023c>;
        };
 
        ram-dump {
index 07d5952..e8b8aa4 100644 (file)
                compatible = "amlogic,reboot";
                sys_reset = <0x84000009>;
                sys_poweroff = <0x84000008>;
+               reboot_reason_addr = <0xff80023c>;
        };
 
        ram-dump {
index 80cf737..c9b9f20 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/kdebug.h>
 #include <linux/arm-smccc.h>
 
+static void __iomem *reboot_reason_vaddr;
 static u32 psci_function_id_restart;
 static u32 psci_function_id_poweroff;
 static char *kernel_panic;
@@ -126,10 +127,27 @@ static struct notifier_block panic_notifier = {
        .notifier_call  = panic_notify,
 };
 
+ssize_t reboot_reason_show(struct device *dev,
+                          struct device_attribute *attr, char *buf)
+{
+       unsigned int value, len;
+
+       if (!reboot_reason_vaddr)
+               return 0;
+       value = readl(reboot_reason_vaddr);
+       value = (value >> 12) & 0xf;
+       len = sprintf(buf, "%d\n", value);
+
+       return len;
+}
+
+DEVICE_ATTR(reboot_reason, 0444, reboot_reason_show, NULL);
+
 static int aml_restart_probe(struct platform_device *pdev)
 {
        u32 id;
        int ret;
+       u32 paddr = 0;
 
        if (!of_property_read_u32(pdev->dev.of_node, "sys_reset", &id)) {
                psci_function_id_restart = id;
@@ -141,6 +159,14 @@ static int aml_restart_probe(struct platform_device *pdev)
                pm_power_off = do_aml_poweroff;
        }
 
+       ret = of_property_read_u32(pdev->dev.of_node,
+                                  "reboot_reason_addr", &paddr);
+       if (!ret) {
+               pr_debug("reboot_reason paddr: 0x%x\n", paddr);
+               reboot_reason_vaddr = ioremap(paddr, 0x4);
+               device_create_file(&pdev->dev, &dev_attr_reboot_reason);
+       }
+
        ret = register_die_notifier(&panic_notifier);
        if (ret != 0) {
                pr_err("%s,register die notifier failed,ret =%d!\n",