diff options
author | Robin Gong <b38343@freescale.com> | 2013-09-12 04:34:01 -0400 |
---|---|---|
committer | Nitin Garg <nitin.garg@freescale.com> | 2014-04-16 09:05:39 -0400 |
commit | da4a080a12375cecc2d9dff4680ec9d93c9a02ba (patch) | |
tree | bdd4a610b02aabb2cf368980933a7caab2b1a3b0 | |
parent | a3c9d3a0f8165a20eb4c9ae1ea22c3173c2b93ea (diff) |
ENGR00279402-2 ARM: imx6q: imx6sl: System reset by checking the source setting
Check the source setting in dts file to support different WDOG reset event.
Correct imx6sl_restart instead of mxc_restart.
Signed-off-by: Robin Gong <b38343@freescale.com>
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6sl.c | 59 |
2 files changed, 84 insertions, 3 deletions
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index e92ee05b98a8..72b4d9fbc5d3 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -45,6 +45,13 @@ static void imx6q_restart(char mode, const char *cmd) | |||
45 | { | 45 | { |
46 | struct device_node *np; | 46 | struct device_node *np; |
47 | void __iomem *wdog_base; | 47 | void __iomem *wdog_base; |
48 | u32 wdog_source = 1; /* use WDOG1 default */ | ||
49 | unsigned int value; | ||
50 | |||
51 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpc"); | ||
52 | if (np) | ||
53 | of_property_read_u32(np, "fsl,wdog-reset", &wdog_source); | ||
54 | pr_info("Use WDOG%d as reset source\n", wdog_source); | ||
48 | 55 | ||
49 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt"); | 56 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-wdt"); |
50 | wdog_base = of_iomap(np, 0); | 57 | wdog_base = of_iomap(np, 0); |
@@ -53,10 +60,27 @@ static void imx6q_restart(char mode, const char *cmd) | |||
53 | 60 | ||
54 | imx_src_prepare_restart(); | 61 | imx_src_prepare_restart(); |
55 | 62 | ||
63 | if (wdog_source == 2) { | ||
64 | /* | ||
65 | * Some boards use WDOG2 to reset external pmic in bypass mode, | ||
66 | * so do WDOG2 reset here. Do not set SRS,since we will | ||
67 | * trigger external POR later. Use WDOG1 to reset in ldo-enable | ||
68 | * mode. | ||
69 | */ | ||
70 | np = of_find_compatible_node(np, NULL, "fsl,imx6q-wdt"); | ||
71 | wdog_base = of_iomap(np, 0); | ||
72 | if (!wdog_base) { | ||
73 | pr_warn("Not found wdt2, please check your dts!\n"); | ||
74 | goto soft; | ||
75 | } | ||
76 | value = 0x14; | ||
77 | } else { | ||
78 | value = (1 << 2); | ||
79 | } | ||
56 | /* enable wdog */ | 80 | /* enable wdog */ |
57 | writew_relaxed(1 << 2, wdog_base); | 81 | writew_relaxed(value, wdog_base); |
58 | /* write twice to ensure the request will not get ignored */ | 82 | /* write twice to ensure the request will not get ignored */ |
59 | writew_relaxed(1 << 2, wdog_base); | 83 | writew_relaxed(value, wdog_base); |
60 | 84 | ||
61 | /* wait for reset to assert ... */ | 85 | /* wait for reset to assert ... */ |
62 | mdelay(500); | 86 | mdelay(500); |
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index e1c83798bc3d..4265f1105b51 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c | |||
@@ -8,8 +8,10 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/clk-provider.h> | 10 | #include <linux/clk-provider.h> |
11 | #include <linux/delay.h> | ||
11 | #include <linux/irqchip.h> | 12 | #include <linux/irqchip.h> |
12 | #include <linux/of.h> | 13 | #include <linux/of.h> |
14 | #include <linux/of_address.h> | ||
13 | #include <linux/of_platform.h> | 15 | #include <linux/of_platform.h> |
14 | #include <linux/opp.h> | 16 | #include <linux/opp.h> |
15 | #include <linux/regmap.h> | 17 | #include <linux/regmap.h> |
@@ -17,6 +19,7 @@ | |||
17 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | 19 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
18 | #include <asm/mach/arch.h> | 20 | #include <asm/mach/arch.h> |
19 | #include <asm/mach/map.h> | 21 | #include <asm/mach/map.h> |
22 | #include <asm/system_misc.h> | ||
20 | 23 | ||
21 | #include "common.h" | 24 | #include "common.h" |
22 | #include "cpuidle.h" | 25 | #include "cpuidle.h" |
@@ -26,6 +29,60 @@ static struct platform_device imx6sl_cpufreq_pdev = { | |||
26 | .name = "imx6-cpufreq", | 29 | .name = "imx6-cpufreq", |
27 | }; | 30 | }; |
28 | 31 | ||
32 | static void imx6sl_restart(char mode, const char *cmd) | ||
33 | { | ||
34 | struct device_node *np; | ||
35 | void __iomem *wdog_base; | ||
36 | u32 wdog_source = 1; /* use WDOG1 default */ | ||
37 | unsigned int value; | ||
38 | |||
39 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpc"); | ||
40 | if (np) | ||
41 | of_property_read_u32(np, "fsl,wdog-reset", &wdog_source); | ||
42 | pr_info("Use WDOG%d as reset source\n", wdog_source); | ||
43 | |||
44 | np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-wdt"); | ||
45 | wdog_base = of_iomap(np, 0); | ||
46 | if (!wdog_base) | ||
47 | goto soft; | ||
48 | |||
49 | imx_src_prepare_restart(); | ||
50 | |||
51 | if (wdog_source == 2) { | ||
52 | /* | ||
53 | * Some boards use WDOG2 to reset external pmic in bypass mode, | ||
54 | * so do WDOG2 reset here. Do not set SRS,since we will | ||
55 | * trigger external POR later. Use WDOG1 to reset in ldo-enable | ||
56 | * mode. You can set it by "fsl,wodog-reset" in dts. | ||
57 | */ | ||
58 | np = of_find_compatible_node(np, NULL, "fsl,imx6sl-wdt"); | ||
59 | wdog_base = of_iomap(np, 0); | ||
60 | if (!wdog_base) { | ||
61 | pr_warn("Not found wdt2, please check your dts!\n"); | ||
62 | goto soft; | ||
63 | } | ||
64 | value = 0x14; | ||
65 | } else { | ||
66 | value = (1 << 2); | ||
67 | } | ||
68 | /* enable wdog */ | ||
69 | writew_relaxed(value, wdog_base); | ||
70 | /* write twice to ensure the request will not get ignored */ | ||
71 | writew_relaxed(value, wdog_base); | ||
72 | |||
73 | /* wait for reset to assert ... */ | ||
74 | mdelay(500); | ||
75 | |||
76 | pr_err("Watchdog reset failed to assert reset\n"); | ||
77 | |||
78 | /* delay to allow the serial port to show the message */ | ||
79 | mdelay(50); | ||
80 | |||
81 | soft: | ||
82 | /* we'll take a jump through zero as a poor second */ | ||
83 | soft_restart(0); | ||
84 | } | ||
85 | |||
29 | static void __init imx6sl_fec_init(void) | 86 | static void __init imx6sl_fec_init(void) |
30 | { | 87 | { |
31 | struct regmap *gpr; | 88 | struct regmap *gpr; |
@@ -137,5 +194,5 @@ DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)") | |||
137 | .init_machine = imx6sl_init_machine, | 194 | .init_machine = imx6sl_init_machine, |
138 | .init_late = imx6sl_init_late, | 195 | .init_late = imx6sl_init_late, |
139 | .dt_compat = imx6sl_dt_compat, | 196 | .dt_compat = imx6sl_dt_compat, |
140 | .restart = mxc_restart, | 197 | .restart = imx6sl_restart, |
141 | MACHINE_END | 198 | MACHINE_END |