1 /*
2  *  This program is free software; you can redistribute it and/or modify it
3  *  under the terms of the GNU General Public License version 2 as published
4  *  by the Free Software Foundation.
5  *
6  *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
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 /* register definitions */
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 
28 static 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 /* remapped base addr of the reset control unit */
36 static void __iomem *ltq_rcu_membase;
37 
38 /* This function is used by the watchdog driver */
ltq_reset_cause(void)39 int ltq_reset_cause(void)
40 {
41 	u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
42 	return val >> LTQ_RCU_STAT_SHIFT;
43 }
44 EXPORT_SYMBOL_GPL(ltq_reset_cause);
45 
ltq_machine_restart(char * command)46 static 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 
ltq_machine_halt(void)54 static void ltq_machine_halt(void)
55 {
56 	pr_notice("System halted.\n");
57 	local_irq_disable();
58 	unreachable();
59 }
60 
ltq_machine_power_off(void)61 static 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 
mips_reboot_setup(void)68 static int __init mips_reboot_setup(void)
69 {
70 	/* insert and request the memory region */
71 	if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
72 		panic("Failed to insert rcu memory");
73 
74 	if (request_mem_region(ltq_rcu_resource.start,
75 			resource_size(&ltq_rcu_resource), "rcu") < 0)
76 		panic("Failed to request rcu memory");
77 
78 	/* remap rcu register range */
79 	ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
80 				resource_size(&ltq_rcu_resource));
81 	if (!ltq_rcu_membase)
82 		panic("Failed to remap rcu memory");
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 
91 arch_initcall(mips_reboot_setup);
92