]>
Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
75f10b46 DB |
2 | #include <linux/kernel.h> |
3 | #include <linux/module.h> | |
4 | #include <linux/delay.h> | |
5 | #include <linux/gpio.h> | |
fced80c7 | 6 | #include <linux/io.h> |
75f10b46 | 7 | #include <asm/proc-fns.h> |
9f97da78 | 8 | #include <asm/system_misc.h> |
75f10b46 | 9 | |
5bf3df3f | 10 | #include <mach/regs-ost.h> |
afd2fc02 | 11 | #include <mach/reset.h> |
ff88b472 | 12 | #include <mach/smemc.h> |
75f10b46 | 13 | |
04fef228 EM |
14 | unsigned int reset_status; |
15 | EXPORT_SYMBOL(reset_status); | |
75f10b46 DB |
16 | |
17 | static void do_hw_reset(void); | |
18 | ||
19 | static int reset_gpio = -1; | |
20 | ||
216e3b7a | 21 | int init_gpio_reset(int gpio, int output, int level) |
75f10b46 DB |
22 | { |
23 | int rc; | |
24 | ||
25 | rc = gpio_request(gpio, "reset generator"); | |
26 | if (rc) { | |
27 | printk(KERN_ERR "Can't request reset_gpio\n"); | |
28 | goto out; | |
29 | } | |
30 | ||
69fc7eed | 31 | if (output) |
216e3b7a | 32 | rc = gpio_direction_output(gpio, level); |
69fc7eed DB |
33 | else |
34 | rc = gpio_direction_input(gpio); | |
75f10b46 | 35 | if (rc) { |
69fc7eed | 36 | printk(KERN_ERR "Can't configure reset_gpio\n"); |
75f10b46 DB |
37 | gpio_free(gpio); |
38 | goto out; | |
39 | } | |
40 | ||
41 | out: | |
42 | if (!rc) | |
43 | reset_gpio = gpio; | |
44 | ||
45 | return rc; | |
46 | } | |
47 | ||
48 | /* | |
49 | * Trigger GPIO reset. | |
50 | * This covers various types of logic connecting gpio pin | |
51 | * to RESET pins (nRESET or GPIO_RESET): | |
52 | */ | |
53 | static void do_gpio_reset(void) | |
54 | { | |
55 | BUG_ON(reset_gpio == -1); | |
56 | ||
57 | /* drive it low */ | |
58 | gpio_direction_output(reset_gpio, 0); | |
59 | mdelay(2); | |
60 | /* rising edge or drive high */ | |
61 | gpio_set_value(reset_gpio, 1); | |
62 | mdelay(2); | |
63 | /* falling edge */ | |
64 | gpio_set_value(reset_gpio, 0); | |
65 | ||
66 | /* give it some time */ | |
67 | mdelay(10); | |
68 | ||
69 | WARN_ON(1); | |
70 | /* fallback */ | |
71 | do_hw_reset(); | |
72 | } | |
73 | ||
74 | static void do_hw_reset(void) | |
75 | { | |
76 | /* Initialize the watchdog and let it fire */ | |
3169663a RK |
77 | writel_relaxed(OWER_WME, OWER); |
78 | writel_relaxed(OSSR_M3, OSSR); | |
79 | /* ... in 100 ms */ | |
80 | writel_relaxed(readl_relaxed(OSCR) + 368640, OSMR3); | |
ff88b472 SI |
81 | /* |
82 | * SDRAM hangs on watchdog reset on Marvell PXA270 (erratum 71) | |
83 | * we put SDRAM into self-refresh to prevent that | |
84 | */ | |
85 | while (1) | |
86 | writel_relaxed(MDREFR_SLFRSH, MDREFR); | |
75f10b46 DB |
87 | } |
88 | ||
7b6d864b | 89 | void pxa_restart(enum reboot_mode mode, const char *cmd) |
75f10b46 | 90 | { |
271a74fc RK |
91 | local_irq_disable(); |
92 | local_fiq_disable(); | |
93 | ||
04fef228 | 94 | clear_reset_status(RESET_STATUS_ALL); |
75f10b46 DB |
95 | |
96 | switch (mode) { | |
7b6d864b | 97 | case REBOOT_SOFT: |
75f10b46 | 98 | /* Jump into ROM at address 0 */ |
e879c862 | 99 | soft_restart(0); |
75f10b46 | 100 | break; |
7b6d864b | 101 | case REBOOT_GPIO: |
75f10b46 DB |
102 | do_gpio_reset(); |
103 | break; | |
7b6d864b | 104 | case REBOOT_HARD: |
28105fda JK |
105 | default: |
106 | do_hw_reset(); | |
107 | break; | |
75f10b46 DB |
108 | } |
109 | } |