aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/ath79/dev-common.c10
-rw-r--r--drivers/watchdog/ath79_wdt.c48
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
104void __init ath79_register_wdt(void) 104void __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;
66static unsigned long wdt_freq; 67static unsigned long wdt_freq;
67static int boot_status; 68static int boot_status;
68static int max_timeout; 69static int max_timeout;
70static void __iomem *wdt_base;
71
72static inline void ath79_wdt_wr(unsigned reg, u32 val)
73{
74 iowrite32(val, wdt_base + reg);
75}
76
77static inline u32 ath79_wdt_rr(unsigned reg)
78{
79 return ioread32(wdt_base + reg);
80}
69 81
70static inline void ath79_wdt_keepalive(void) 82static 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
77static inline void ath79_wdt_enable(void) 89static 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
85static inline void ath79_wdt_disable(void) 97static 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
92static int ath79_wdt_set_timeout(int val) 104static int ath79_wdt_set_timeout(int val)
@@ -226,9 +238,25 @@ static struct miscdevice ath79_wdt_miscdev = {
226 238
227static int ath79_wdt_probe(struct platform_device *pdev) 239static 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);