1 #define pr_fmt(fmt) "["KBUILD_MODNAME"] " fmt
2 #include <linux/module.h>
3 #include <linux/device.h>
5 #include <linux/cdev.h>
6 #include <linux/interrupt.h>
7 #include <linux/spinlock.h>
8 #include <linux/uaccess.h>
10 #include <linux/kfifo.h>
12 #include <linux/firmware.h>
13 #include <linux/syscalls.h>
14 #include <linux/uaccess.h>
15 #include <linux/platform_device.h>
16 #include <linux/proc_fs.h>
17 #include <linux/seq_file.h>
20 #include <linux/of_fdt.h>
22 #include <asm/setup.h>
23 #include <asm/atomic.h>
24 #include <mach/mt_typedefs.h>
25 #include <mach/mt_boot_reason.h>
29 BOOT_REASON_UNINIT
= 0,
30 BOOT_REASON_INITIALIZING
= 1,
31 BOOT_REASON_INITIALIZED
= 2,
34 boot_reason_t g_boot_reason __nosavedata
= BR_UNKNOWN
;
36 static atomic_t g_br_state
= ATOMIC_INIT(BOOT_REASON_UNINIT
);
37 static atomic_t g_br_errcnt
= ATOMIC_INIT(0);
38 static atomic_t g_br_status
= ATOMIC_INIT(0);
41 static int __init
dt_get_boot_reason(unsigned long node
, const char *uname
, int depth
, void *data
)
43 char *ptr
= NULL
, *br_ptr
= NULL
;
45 if (depth
!= 1 || (strcmp(uname
, "chosen") != 0 && strcmp(uname
, "chosen@0") != 0))
48 ptr
= (char *)of_get_flat_dt_prop(node
, "bootargs", NULL
);
50 if ((br_ptr
= strstr(ptr
, "boot_reason=")) != 0) {
51 g_boot_reason
= br_ptr
[12] - '0'; /* get boot reason */
52 atomic_set(&g_br_status
, 1);
55 pr_warn("'boot_reason=' is not found\n");
56 pr_debug("%s\n", ptr
);
58 pr_warn("'bootargs' is not found\n");
66 void init_boot_reason(unsigned int line
)
71 if (BOOT_REASON_INITIALIZING
== atomic_read(&g_br_state
)) {
72 pr_warn("%s (%d) state(%d)\n", __func__
, line
, atomic_read(&g_br_state
));
73 atomic_inc(&g_br_errcnt
);
77 if (BOOT_REASON_UNINIT
== atomic_read(&g_br_state
))
78 atomic_set(&g_br_state
, BOOT_REASON_INITIALIZING
);
82 if ((BR_UNKNOWN
!= g_boot_reason
)) {
83 atomic_set(&g_br_state
, BOOT_REASON_INITIALIZED
);
84 pr_alert("boot_reason = %d\n", g_boot_reason
);
88 pr_info("%s %d %d %d\n", __func__
, line
, g_boot_reason
,
89 atomic_read(&g_br_state
));
90 rc
= of_scan_flat_dt(dt_get_boot_reason
, NULL
);
92 atomic_set(&g_br_state
, BOOT_REASON_INITIALIZED
);
94 atomic_set(&g_br_state
, BOOT_REASON_UNINIT
);
95 pr_info("%s %d %d %d\n", __func__
, line
, g_boot_reason
,
96 atomic_read(&g_br_state
));
100 /* return boot reason */
101 boot_reason_t
get_boot_reason(void)
103 init_boot_reason(__LINE__
);
104 return g_boot_reason
;
107 static int __init
boot_reason_core(void)
109 init_boot_reason(__LINE__
);
113 static int __init
boot_reason_init(void)
115 pr_alert("boot_reason = %d, state(%d,%d,%d)", g_boot_reason
,
116 atomic_read(&g_br_state
), atomic_read(&g_br_errcnt
),
117 atomic_read(&g_br_status
));
121 early_initcall(boot_reason_core
);
122 module_init(boot_reason_init
);
123 MODULE_DESCRIPTION("Mediatek Boot Reason Driver");
124 MODULE_LICENSE("GPL");