summaryrefslogtreecommitdiff
path: root/target/linux/ar71xx/patches-3.8/041-watchdog-ath79_wdt-get-register-base-from-platform-d.patch
blob: b86382949e39337bb08957b62e50381ecf317359 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
From 9c0785757dacd1aaf9e6e58b4f559e345093f1d4 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Thu, 27 Dec 2012 15:38:26 +0100
Subject: [PATCH] watchdog: ath79_wdt: get register base from platform
 device's resources

commit 09f5100a592d11dad06b218f41d560ff1f87f666 upstream.

The ath79_wdt driver uses a fixed memory address
currently. Although this is working with each
currently supported SoCs, but this may change
in the future. Additionally, the driver includes
platform specific header files in order to be
able to get the memory base of the watchdog
device.

The patch adds a memory resource to the platform
device, and converts the driver to get the base
address of the watchdog device from that.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
---
 arch/mips/ath79/dev-common.c |   10 ++++++++-
 drivers/watchdog/ath79_wdt.c |   48 +++++++++++++++++++++++++++++++++---------
 2 files changed, 47 insertions(+), 11 deletions(-)

--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -104,5 +104,13 @@ void __init ath79_register_uart(void)
 
 void __init ath79_register_wdt(void)
 {
-	platform_device_register_simple("ath79-wdt", -1, NULL, 0);
+	struct resource res;
+
+	memset(&res, 0, sizeof(res));
+
+	res.flags = IORESOURCE_MEM;
+	res.start = AR71XX_RESET_BASE + AR71XX_RESET_REG_WDOG_CTRL;
+	res.end = res.start + 0x8 - 1;
+
+	platform_device_register_simple("ath79-wdt", -1, &res, 1);
 }
--- a/drivers/watchdog/ath79_wdt.c
+++ b/drivers/watchdog/ath79_wdt.c
@@ -23,6 +23,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
@@ -33,13 +34,13 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-
 #define DRIVER_NAME	"ath79-wdt"
 
 #define WDT_TIMEOUT	15	/* seconds */
 
+#define WDOG_REG_CTRL		0x00
+#define WDOG_REG_TIMER		0x04
+
 #define WDOG_CTRL_LAST_RESET	BIT(31)
 #define WDOG_CTRL_ACTION_MASK	3
 #define WDOG_CTRL_ACTION_NONE	0	/* no action */
@@ -66,27 +67,38 @@ static struct clk *wdt_clk;
 static unsigned long wdt_freq;
 static int boot_status;
 static int max_timeout;
+static void __iomem *wdt_base;
+
+static inline void ath79_wdt_wr(unsigned reg, u32 val)
+{
+	iowrite32(val, wdt_base + reg);
+}
+
+static inline u32 ath79_wdt_rr(unsigned reg)
+{
+	return ioread32(wdt_base + reg);
+}
 
 static inline void ath79_wdt_keepalive(void)
 {
-	ath79_reset_wr(AR71XX_RESET_REG_WDOG, wdt_freq * timeout);
+	ath79_wdt_wr(WDOG_REG_TIMER, wdt_freq * timeout);
 	/* flush write */
-	ath79_reset_rr(AR71XX_RESET_REG_WDOG);
+	ath79_wdt_rr(WDOG_REG_TIMER);
 }
 
 static inline void ath79_wdt_enable(void)
 {
 	ath79_wdt_keepalive();
-	ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
+	ath79_wdt_wr(WDOG_REG_CTRL, WDOG_CTRL_ACTION_FCR);
 	/* flush write */
-	ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
+	ath79_wdt_rr(WDOG_REG_CTRL);
 }
 
 static inline void ath79_wdt_disable(void)
 {
-	ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
+	ath79_wdt_wr(WDOG_REG_CTRL, WDOG_CTRL_ACTION_NONE);
 	/* flush write */
-	ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
+	ath79_wdt_rr(WDOG_REG_CTRL);
 }
 
 static int ath79_wdt_set_timeout(int val)
@@ -226,9 +238,25 @@ static struct miscdevice ath79_wdt_miscd
 
 static int ath79_wdt_probe(struct platform_device *pdev)
 {
+	struct resource *res;
 	u32 ctrl;
 	int err;
 
+	if (wdt_base)
+		return -EBUSY;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no memory resource found\n");
+		return -EINVAL;
+	}
+
+	wdt_base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!wdt_base) {
+		dev_err(&pdev->dev, "unable to remap memory region\n");
+		return -ENOMEM;
+	}
+
 	wdt_clk = devm_clk_get(&pdev->dev, "wdt");
 	if (IS_ERR(wdt_clk))
 		return PTR_ERR(wdt_clk);
@@ -251,7 +279,7 @@ static int ath79_wdt_probe(struct platfo
 			max_timeout, timeout);
 	}
 
-	ctrl = ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
+	ctrl = ath79_wdt_rr(WDOG_REG_CTRL);
 	boot_status = (ctrl & WDOG_CTRL_LAST_RESET) ? WDIOF_CARDRESET : 0;
 
 	err = misc_register(&ath79_wdt_miscdev);