1
2
3
4
5
6
7
8
9#include <linux/init.h>
10#include <linux/io.h>
11#include <linux/ioport.h>
12#include <linux/pm.h>
13#include <linux/export.h>
14#include <asm/reboot.h>
15
16#include <lantiq_soc.h>
17
18#define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y))
19#define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x))
20
21
22#define LTQ_RCU_RST 0x0010
23#define LTQ_RCU_RST_ALL 0x40000000
24
25#define LTQ_RCU_RST_STAT 0x0014
26#define LTQ_RCU_STAT_SHIFT 26
27
28static struct resource ltq_rcu_resource = {
29 .name = "rcu",
30 .start = LTQ_RCU_BASE_ADDR,
31 .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
32 .flags = IORESOURCE_MEM,
33};
34
35
36static void __iomem *ltq_rcu_membase;
37
38
39int ltq_reset_cause(void)
40{
41 u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
42 return val >> LTQ_RCU_STAT_SHIFT;
43}
44EXPORT_SYMBOL_GPL(ltq_reset_cause);
45
46static void ltq_machine_restart(char *command)
47{
48 pr_notice("System restart\n");
49 local_irq_disable();
50 ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST);
51 unreachable();
52}
53
54static void ltq_machine_halt(void)
55{
56 pr_notice("System halted.\n");
57 local_irq_disable();
58 unreachable();
59}
60
61static void ltq_machine_power_off(void)
62{
63 pr_notice("Please turn off the power now.\n");
64 local_irq_disable();
65 unreachable();
66}
67
68static int __init mips_reboot_setup(void)
69{
70
71 if (insert_resource(&iomem_resource, <q_rcu_resource) < 0)
72 panic("Failed to insert rcu memory\n");
73
74 if (request_mem_region(ltq_rcu_resource.start,
75 resource_size(<q_rcu_resource), "rcu") < 0)
76 panic("Failed to request rcu memory\n");
77
78
79 ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
80 resource_size(<q_rcu_resource));
81 if (!ltq_rcu_membase)
82 panic("Failed to remap rcu memory\n");
83
84 _machine_restart = ltq_machine_restart;
85 _machine_halt = ltq_machine_halt;
86 pm_power_off = ltq_machine_power_off;
87
88 return 0;
89}
90
91arch_initcall(mips_reboot_setup);
92