aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Gong <b38343@freescale.com>2013-09-12 04:34:01 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:05:39 -0400
commitda4a080a12375cecc2d9dff4680ec9d93c9a02ba (patch)
treebdd4a610b02aabb2cf368980933a7caab2b1a3b0
parenta3c9d3a0f8165a20eb4c9ae1ea22c3173c2b93ea (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.c28
-rw-r--r--arch/arm/mach-imx/mach-imx6sl.c59
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
32static 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
81soft:
82 /* we'll take a jump through zero as a poor second */
83 soft_restart(0);
84}
85
29static void __init imx6sl_fec_init(void) 86static 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,
141MACHINE_END 198MACHINE_END