diff options
-rw-r--r-- | arch/mips/ath79/dev-common.c | 10 | ||||
-rw-r--r-- | drivers/watchdog/ath79_wdt.c | 48 |
2 files changed, 47 insertions, 11 deletions
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c index 2093b1b2a1d1..ea3a8140e728 100644 --- a/arch/mips/ath79/dev-common.c +++ b/arch/mips/ath79/dev-common.c | |||
@@ -103,5 +103,13 @@ void __init ath79_register_uart(void) | |||
103 | 103 | ||
104 | void __init ath79_register_wdt(void) | 104 | void __init ath79_register_wdt(void) |
105 | { | 105 | { |
106 | platform_device_register_simple("ath79-wdt", -1, NULL, 0); | 106 | struct resource res; |
107 | |||
108 | memset(&res, 0, sizeof(res)); | ||
109 | |||
110 | res.flags = IORESOURCE_MEM; | ||
111 | res.start = AR71XX_RESET_BASE + AR71XX_RESET_REG_WDOG_CTRL; | ||
112 | res.end = res.start + 0x8 - 1; | ||
113 | |||
114 | platform_device_register_simple("ath79-wdt", -1, &res, 1); | ||
107 | } | 115 | } |
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index dcd18ec1821b..e786f644e14b 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/io.h> | ||
26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
27 | #include <linux/miscdevice.h> | 28 | #include <linux/miscdevice.h> |
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -33,13 +34,13 @@ | |||
33 | #include <linux/clk.h> | 34 | #include <linux/clk.h> |
34 | #include <linux/err.h> | 35 | #include <linux/err.h> |
35 | 36 | ||
36 | #include <asm/mach-ath79/ath79.h> | ||
37 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
38 | |||
39 | #define DRIVER_NAME "ath79-wdt" | 37 | #define DRIVER_NAME "ath79-wdt" |
40 | 38 | ||
41 | #define WDT_TIMEOUT 15 /* seconds */ | 39 | #define WDT_TIMEOUT 15 /* seconds */ |
42 | 40 | ||
41 | #define WDOG_REG_CTRL 0x00 | ||
42 | #define WDOG_REG_TIMER 0x04 | ||
43 | |||
43 | #define WDOG_CTRL_LAST_RESET BIT(31) | 44 | #define WDOG_CTRL_LAST_RESET BIT(31) |
44 | #define WDOG_CTRL_ACTION_MASK 3 | 45 | #define WDOG_CTRL_ACTION_MASK 3 |
45 | #define WDOG_CTRL_ACTION_NONE 0 /* no action */ | 46 | #define WDOG_CTRL_ACTION_NONE 0 /* no action */ |
@@ -66,27 +67,38 @@ static struct clk *wdt_clk; | |||
66 | static unsigned long wdt_freq; | 67 | static unsigned long wdt_freq; |
67 | static int boot_status; | 68 | static int boot_status; |
68 | static int max_timeout; | 69 | static int max_timeout; |
70 | static void __iomem *wdt_base; | ||
71 | |||
72 | static inline void ath79_wdt_wr(unsigned reg, u32 val) | ||
73 | { | ||
74 | iowrite32(val, wdt_base + reg); | ||
75 | } | ||
76 | |||
77 | static inline u32 ath79_wdt_rr(unsigned reg) | ||
78 | { | ||
79 | return ioread32(wdt_base + reg); | ||
80 | } | ||
69 | 81 | ||
70 | static inline void ath79_wdt_keepalive(void) | 82 | static inline void ath79_wdt_keepalive(void) |
71 | { | 83 | { |
72 | ath79_reset_wr(AR71XX_RESET_REG_WDOG, wdt_freq * timeout); | 84 | ath79_wdt_wr(WDOG_REG_TIMER, wdt_freq * timeout); |
73 | /* flush write */ | 85 | /* flush write */ |
74 | ath79_reset_rr(AR71XX_RESET_REG_WDOG); | 86 | ath79_wdt_rr(WDOG_REG_TIMER); |
75 | } | 87 | } |
76 | 88 | ||
77 | static inline void ath79_wdt_enable(void) | 89 | static inline void ath79_wdt_enable(void) |
78 | { | 90 | { |
79 | ath79_wdt_keepalive(); | 91 | ath79_wdt_keepalive(); |
80 | ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR); | 92 | ath79_wdt_wr(WDOG_REG_CTRL, WDOG_CTRL_ACTION_FCR); |
81 | /* flush write */ | 93 | /* flush write */ |
82 | ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL); | 94 | ath79_wdt_rr(WDOG_REG_CTRL); |
83 | } | 95 | } |
84 | 96 | ||
85 | static inline void ath79_wdt_disable(void) | 97 | static inline void ath79_wdt_disable(void) |
86 | { | 98 | { |
87 | ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE); | 99 | ath79_wdt_wr(WDOG_REG_CTRL, WDOG_CTRL_ACTION_NONE); |
88 | /* flush write */ | 100 | /* flush write */ |
89 | ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL); | 101 | ath79_wdt_rr(WDOG_REG_CTRL); |
90 | } | 102 | } |
91 | 103 | ||
92 | static int ath79_wdt_set_timeout(int val) | 104 | static int ath79_wdt_set_timeout(int val) |
@@ -226,9 +238,25 @@ static struct miscdevice ath79_wdt_miscdev = { | |||
226 | 238 | ||
227 | static int ath79_wdt_probe(struct platform_device *pdev) | 239 | static int ath79_wdt_probe(struct platform_device *pdev) |
228 | { | 240 | { |
241 | struct resource *res; | ||
229 | u32 ctrl; | 242 | u32 ctrl; |
230 | int err; | 243 | int err; |
231 | 244 | ||
245 | if (wdt_base) | ||
246 | return -EBUSY; | ||
247 | |||
248 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
249 | if (!res) { | ||
250 | dev_err(&pdev->dev, "no memory resource found\n"); | ||
251 | return -EINVAL; | ||
252 | } | ||
253 | |||
254 | wdt_base = devm_request_and_ioremap(&pdev->dev, res); | ||
255 | if (!wdt_base) { | ||
256 | dev_err(&pdev->dev, "unable to remap memory region\n"); | ||
257 | return -ENOMEM; | ||
258 | } | ||
259 | |||
232 | wdt_clk = devm_clk_get(&pdev->dev, "wdt"); | 260 | wdt_clk = devm_clk_get(&pdev->dev, "wdt"); |
233 | if (IS_ERR(wdt_clk)) | 261 | if (IS_ERR(wdt_clk)) |
234 | return PTR_ERR(wdt_clk); | 262 | return PTR_ERR(wdt_clk); |
@@ -251,7 +279,7 @@ static int ath79_wdt_probe(struct platform_device *pdev) | |||
251 | max_timeout, timeout); | 279 | max_timeout, timeout); |
252 | } | 280 | } |
253 | 281 | ||
254 | ctrl = ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL); | 282 | ctrl = ath79_wdt_rr(WDOG_REG_CTRL); |
255 | boot_status = (ctrl & WDOG_CTRL_LAST_RESET) ? WDIOF_CARDRESET : 0; | 283 | boot_status = (ctrl & WDOG_CTRL_LAST_RESET) ? WDIOF_CARDRESET : 0; |
256 | 284 | ||
257 | err = misc_register(&ath79_wdt_miscdev); | 285 | err = misc_register(&ath79_wdt_miscdev); |