aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@nokia.com>2008-09-19 21:14:01 -0400
committerWim Van Sebroeck <wim@iguana.be>2008-10-10 09:11:10 -0400
commit2817142f31bfbf26c216bf4f9192540c81b2d071 (patch)
tree4cc6e07cadde49821499800f91310e12e49d0ce9
parente6bb42e3d669afbeb4c971994614bcf241687666 (diff)
[WATCHDOG] omap_wdt.c: sync linux-omap changes
These are changes that have been sitting in linux-omap and were never sent upstream. Hopefully, it'll never happen again at least for this driver. Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-rw-r--r--arch/arm/plat-omap/devices.c21
-rw-r--r--drivers/watchdog/omap_wdt.c283
-rw-r--r--drivers/watchdog/omap_wdt.h28
3 files changed, 203 insertions, 129 deletions
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 01da719a7453..cc62cec1b75a 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -441,16 +441,8 @@ static inline void omap_init_uwire(void) {}
441 441
442#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) 442#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
443 443
444#ifdef CONFIG_ARCH_OMAP24XX
445#define OMAP_WDT_BASE 0x48022000
446#else
447#define OMAP_WDT_BASE 0xfffeb000
448#endif
449
450static struct resource wdt_resources[] = { 444static struct resource wdt_resources[] = {
451 { 445 {
452 .start = OMAP_WDT_BASE,
453 .end = OMAP_WDT_BASE + 0x4f,
454 .flags = IORESOURCE_MEM, 446 .flags = IORESOURCE_MEM,
455 }, 447 },
456}; 448};
@@ -464,6 +456,19 @@ static struct platform_device omap_wdt_device = {
464 456
465static void omap_init_wdt(void) 457static void omap_init_wdt(void)
466{ 458{
459 if (cpu_is_omap16xx())
460 wdt_resources[0].start = 0xfffeb000;
461 else if (cpu_is_omap2420())
462 wdt_resources[0].start = 0x48022000; /* WDT2 */
463 else if (cpu_is_omap2430())
464 wdt_resources[0].start = 0x49016000; /* WDT2 */
465 else if (cpu_is_omap343x())
466 wdt_resources[0].start = 0x48314000; /* WDT2 */
467 else
468 return;
469
470 wdt_resources[0].end = wdt_resources[0].start + 0x4f;
471
467 (void) platform_device_register(&omap_wdt_device); 472 (void) platform_device_register(&omap_wdt_device);
468} 473}
469#else 474#else
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 3a11dadfd8e7..7de16a3f6849 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/char/watchdog/omap_wdt.c 2 * omap_wdt.c
3 * 3 *
4 * Watchdog driver for the TI OMAP 16xx & 24xx 32KHz (non-secure) watchdog 4 * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
5 * 5 *
6 * Author: MontaVista Software, Inc. 6 * Author: MontaVista Software, Inc.
7 * <gdavis@mvista.com> or <source@mvista.com> 7 * <gdavis@mvista.com> or <source@mvista.com>
@@ -47,50 +47,63 @@
47 47
48#include "omap_wdt.h" 48#include "omap_wdt.h"
49 49
50static struct platform_device *omap_wdt_dev;
51
50static unsigned timer_margin; 52static unsigned timer_margin;
51module_param(timer_margin, uint, 0); 53module_param(timer_margin, uint, 0);
52MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); 54MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");
53 55
54static int omap_wdt_users;
55static struct clk *armwdt_ck;
56static struct clk *mpu_wdt_ick;
57static struct clk *mpu_wdt_fck;
58
59static unsigned int wdt_trgr_pattern = 0x1234; 56static unsigned int wdt_trgr_pattern = 0x1234;
60static spinlock_t wdt_lock; 57static spinlock_t wdt_lock;
61 58
62static void omap_wdt_ping(void) 59struct omap_wdt_dev {
60 void __iomem *base; /* physical */
61 struct device *dev;
62 int omap_wdt_users;
63 struct clk *armwdt_ck;
64 struct clk *mpu_wdt_ick;
65 struct clk *mpu_wdt_fck;
66 struct resource *mem;
67 struct miscdevice omap_wdt_miscdev;
68};
69
70static void omap_wdt_ping(struct omap_wdt_dev *wdev)
63{ 71{
72 void __iomem *base = wdev->base;
64 /* wait for posted write to complete */ 73 /* wait for posted write to complete */
65 while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08) 74 while ((omap_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
66 cpu_relax(); 75 cpu_relax();
67 wdt_trgr_pattern = ~wdt_trgr_pattern; 76 wdt_trgr_pattern = ~wdt_trgr_pattern;
68 omap_writel(wdt_trgr_pattern, (OMAP_WATCHDOG_TGR)); 77 omap_writel(wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR));
69 /* wait for posted write to complete */ 78 /* wait for posted write to complete */
70 while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x08) 79 while ((omap_readl(base + OMAP_WATCHDOG_WPS)) & 0x08)
71 cpu_relax(); 80 cpu_relax();
72 /* reloaded WCRR from WLDR */ 81 /* reloaded WCRR from WLDR */
73} 82}
74 83
75static void omap_wdt_enable(void) 84static void omap_wdt_enable(struct omap_wdt_dev *wdev)
76{ 85{
86 void __iomem *base;
87 base = wdev->base;
77 /* Sequence to enable the watchdog */ 88 /* Sequence to enable the watchdog */
78 omap_writel(0xBBBB, OMAP_WATCHDOG_SPR); 89 omap_writel(0xBBBB, base + OMAP_WATCHDOG_SPR);
79 while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10) 90 while ((omap_readl(base + OMAP_WATCHDOG_WPS)) & 0x10)
80 cpu_relax(); 91 cpu_relax();
81 omap_writel(0x4444, OMAP_WATCHDOG_SPR); 92 omap_writel(0x4444, base + OMAP_WATCHDOG_SPR);
82 while ((omap_readl(OMAP_WATCHDOG_WPS)) & 0x10) 93 while ((omap_readl(base + OMAP_WATCHDOG_WPS)) & 0x10)
83 cpu_relax(); 94 cpu_relax();
84} 95}
85 96
86static void omap_wdt_disable(void) 97static void omap_wdt_disable(struct omap_wdt_dev *wdev)
87{ 98{
99 void __iomem *base;
100 base = wdev->base;
88 /* sequence required to disable watchdog */ 101 /* sequence required to disable watchdog */
89 omap_writel(0xAAAA, OMAP_WATCHDOG_SPR); /* TIMER_MODE */ 102 omap_writel(0xAAAA, base + OMAP_WATCHDOG_SPR); /* TIMER_MODE */
90 while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10) 103 while (omap_readl(base + OMAP_WATCHDOG_WPS) & 0x10)
91 cpu_relax(); 104 cpu_relax();
92 omap_writel(0x5555, OMAP_WATCHDOG_SPR); /* TIMER_MODE */ 105 omap_writel(0x5555, base + OMAP_WATCHDOG_SPR); /* TIMER_MODE */
93 while (omap_readl(OMAP_WATCHDOG_WPS) & 0x10) 106 while (omap_readl(base + OMAP_WATCHDOG_WPS) & 0x10)
94 cpu_relax(); 107 cpu_relax();
95} 108}
96 109
@@ -103,15 +116,17 @@ static void omap_wdt_adjust_timeout(unsigned new_timeout)
103 timer_margin = new_timeout; 116 timer_margin = new_timeout;
104} 117}
105 118
106static void omap_wdt_set_timeout(void) 119static void omap_wdt_set_timeout(struct omap_wdt_dev *wdev)
107{ 120{
108 u32 pre_margin = GET_WLDR_VAL(timer_margin); 121 u32 pre_margin = GET_WLDR_VAL(timer_margin);
122 void __iomem *base;
123 base = wdev->base;
109 124
110 /* just count up at 32 KHz */ 125 /* just count up at 32 KHz */
111 while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04) 126 while (omap_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
112 cpu_relax(); 127 cpu_relax();
113 omap_writel(pre_margin, OMAP_WATCHDOG_LDR); 128 omap_writel(pre_margin, base + OMAP_WATCHDOG_LDR);
114 while (omap_readl(OMAP_WATCHDOG_WPS) & 0x04) 129 while (omap_readl(base + OMAP_WATCHDOG_WPS) & 0x04)
115 cpu_relax(); 130 cpu_relax();
116} 131}
117 132
@@ -121,65 +136,69 @@ static void omap_wdt_set_timeout(void)
121 136
122static int omap_wdt_open(struct inode *inode, struct file *file) 137static int omap_wdt_open(struct inode *inode, struct file *file)
123{ 138{
124 if (test_and_set_bit(1, (unsigned long *)&omap_wdt_users)) 139 struct omap_wdt_dev *wdev;
140 void __iomem *base;
141 wdev = platform_get_drvdata(omap_wdt_dev);
142 base = wdev->base;
143 if (test_and_set_bit(1, (unsigned long *)&(wdev->omap_wdt_users)))
125 return -EBUSY; 144 return -EBUSY;
126 145
127 if (cpu_is_omap16xx()) 146 if (cpu_is_omap16xx())
128 clk_enable(armwdt_ck); /* Enable the clock */ 147 clk_enable(wdev->armwdt_ck); /* Enable the clock */
129 148
130 if (cpu_is_omap24xx()) { 149 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
131 clk_enable(mpu_wdt_ick); /* Enable the interface clock */ 150 clk_enable(wdev->mpu_wdt_ick); /* Enable the interface clock */
132 clk_enable(mpu_wdt_fck); /* Enable the functional clock */ 151 clk_enable(wdev->mpu_wdt_fck); /* Enable the functional clock */
133 } 152 }
134 153
135 /* initialize prescaler */ 154 /* initialize prescaler */
136 while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01) 155 while (omap_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
137 cpu_relax(); 156 cpu_relax();
138 omap_writel((1 << 5) | (PTV << 2), OMAP_WATCHDOG_CNTRL); 157 omap_writel((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL);
139 while (omap_readl(OMAP_WATCHDOG_WPS) & 0x01) 158 while (omap_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
140 cpu_relax(); 159 cpu_relax();
141 160
142 omap_wdt_set_timeout(); 161 file->private_data = (void *) wdev;
143 omap_wdt_enable(); 162
163 omap_wdt_set_timeout(wdev);
164 omap_wdt_enable(wdev);
144 return nonseekable_open(inode, file); 165 return nonseekable_open(inode, file);
145} 166}
146 167
147static int omap_wdt_release(struct inode *inode, struct file *file) 168static int omap_wdt_release(struct inode *inode, struct file *file)
148{ 169{
170 struct omap_wdt_dev *wdev;
171 wdev = file->private_data;
149 /* 172 /*
150 * Shut off the timer unless NOWAYOUT is defined. 173 * Shut off the timer unless NOWAYOUT is defined.
151 */ 174 */
152#ifndef CONFIG_WATCHDOG_NOWAYOUT 175#ifndef CONFIG_WATCHDOG_NOWAYOUT
153 omap_wdt_disable();
154 176
155 if (cpu_is_omap16xx()) { 177 omap_wdt_disable(wdev);
156 clk_disable(armwdt_ck); /* Disable the clock */
157 clk_put(armwdt_ck);
158 armwdt_ck = NULL;
159 }
160 178
161 if (cpu_is_omap24xx()) { 179 if (cpu_is_omap16xx())
162 clk_disable(mpu_wdt_ick); /* Disable the clock */ 180 clk_disable(wdev->armwdt_ck); /* Disable the clock */
163 clk_disable(mpu_wdt_fck); /* Disable the clock */ 181
164 clk_put(mpu_wdt_ick); 182 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
165 clk_put(mpu_wdt_fck); 183 clk_disable(wdev->mpu_wdt_ick); /* Disable the clock */
166 mpu_wdt_ick = NULL; 184 clk_disable(wdev->mpu_wdt_fck); /* Disable the clock */
167 mpu_wdt_fck = NULL;
168 } 185 }
169#else 186#else
170 printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n"); 187 printk(KERN_CRIT "omap_wdt: Unexpected close, not stopping!\n");
171#endif 188#endif
172 omap_wdt_users = 0; 189 wdev->omap_wdt_users = 0;
173 return 0; 190 return 0;
174} 191}
175 192
176static ssize_t omap_wdt_write(struct file *file, const char __user *data, 193static ssize_t omap_wdt_write(struct file *file, const char __user *data,
177 size_t len, loff_t *ppos) 194 size_t len, loff_t *ppos)
178{ 195{
196 struct omap_wdt_dev *wdev;
197 wdev = file->private_data;
179 /* Refresh LOAD_TIME. */ 198 /* Refresh LOAD_TIME. */
180 if (len) { 199 if (len) {
181 spin_lock(&wdt_lock); 200 spin_lock(&wdt_lock);
182 omap_wdt_ping(); 201 omap_wdt_ping(wdev);
183 spin_unlock(&wdt_lock); 202 spin_unlock(&wdt_lock);
184 } 203 }
185 return len; 204 return len;
@@ -188,12 +207,14 @@ static ssize_t omap_wdt_write(struct file *file, const char __user *data,
188static long omap_wdt_ioctl(struct file *file, unsigned int cmd, 207static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
189 unsigned long arg) 208 unsigned long arg)
190{ 209{
210 struct omap_wdt_dev *wdev;
191 int new_margin; 211 int new_margin;
192 static const struct watchdog_info ident = { 212 static const struct watchdog_info ident = {
193 .identity = "OMAP Watchdog", 213 .identity = "OMAP Watchdog",
194 .options = WDIOF_SETTIMEOUT, 214 .options = WDIOF_SETTIMEOUT,
195 .firmware_version = 0, 215 .firmware_version = 0,
196 }; 216 };
217 wdev = file->private_data;
197 218
198 switch (cmd) { 219 switch (cmd) {
199 case WDIOC_GETSUPPORT: 220 case WDIOC_GETSUPPORT:
@@ -210,7 +231,7 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
210 (int __user *)arg); 231 (int __user *)arg);
211 case WDIOC_KEEPALIVE: 232 case WDIOC_KEEPALIVE:
212 spin_lock(&wdt_lock); 233 spin_lock(&wdt_lock);
213 omap_wdt_ping(); 234 omap_wdt_ping(wdev);
214 spin_unlock(&wdt_lock); 235 spin_unlock(&wdt_lock);
215 return 0; 236 return 0;
216 case WDIOC_SETTIMEOUT: 237 case WDIOC_SETTIMEOUT:
@@ -219,11 +240,11 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd,
219 omap_wdt_adjust_timeout(new_margin); 240 omap_wdt_adjust_timeout(new_margin);
220 241
221 spin_lock(&wdt_lock); 242 spin_lock(&wdt_lock);
222 omap_wdt_disable(); 243 omap_wdt_disable(wdev);
223 omap_wdt_set_timeout(); 244 omap_wdt_set_timeout(wdev);
224 omap_wdt_enable(); 245 omap_wdt_enable(wdev);
225 246
226 omap_wdt_ping(); 247 omap_wdt_ping(wdev);
227 spin_unlock(&wdt_lock); 248 spin_unlock(&wdt_lock);
228 /* Fall */ 249 /* Fall */
229 case WDIOC_GETTIMEOUT: 250 case WDIOC_GETTIMEOUT:
@@ -241,96 +262,150 @@ static const struct file_operations omap_wdt_fops = {
241 .release = omap_wdt_release, 262 .release = omap_wdt_release,
242}; 263};
243 264
244static struct miscdevice omap_wdt_miscdev = {
245 .minor = WATCHDOG_MINOR,
246 .name = "watchdog",
247 .fops = &omap_wdt_fops,
248};
249 265
250static int __init omap_wdt_probe(struct platform_device *pdev) 266static int __init omap_wdt_probe(struct platform_device *pdev)
251{ 267{
252 struct resource *res, *mem; 268 struct resource *res, *mem;
253 int ret; 269 int ret;
270 struct omap_wdt_dev *wdev;
254 271
255 /* reserve static register mappings */ 272 /* reserve static register mappings */
256 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 273 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
257 if (!res) 274 if (!res)
258 return -ENOENT; 275 return -ENOENT;
259 276
277 if (omap_wdt_dev)
278 return -EBUSY;
279
260 mem = request_mem_region(res->start, res->end - res->start + 1, 280 mem = request_mem_region(res->start, res->end - res->start + 1,
261 pdev->name); 281 pdev->name);
262 if (mem == NULL) 282 if (mem == NULL)
263 return -EBUSY; 283 return -EBUSY;
264 284
265 platform_set_drvdata(pdev, mem); 285 wdev = kzalloc(sizeof(struct omap_wdt_dev), GFP_KERNEL);
266 286 if (!wdev) {
267 omap_wdt_users = 0; 287 ret = -ENOMEM;
288 goto fail;
289 }
290 wdev->omap_wdt_users = 0;
291 wdev->mem = mem;
268 292
269 if (cpu_is_omap16xx()) { 293 if (cpu_is_omap16xx()) {
270 armwdt_ck = clk_get(&pdev->dev, "armwdt_ck"); 294 wdev->armwdt_ck = clk_get(&pdev->dev, "armwdt_ck");
271 if (IS_ERR(armwdt_ck)) { 295 if (IS_ERR(wdev->armwdt_ck)) {
272 ret = PTR_ERR(armwdt_ck); 296 ret = PTR_ERR(wdev->armwdt_ck);
273 armwdt_ck = NULL; 297 wdev->armwdt_ck = NULL;
274 goto fail; 298 goto fail;
275 } 299 }
276 } 300 }
277 301
278 if (cpu_is_omap24xx()) { 302 if (cpu_is_omap24xx()) {
279 mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick"); 303 wdev->mpu_wdt_ick = clk_get(&pdev->dev, "mpu_wdt_ick");
280 if (IS_ERR(mpu_wdt_ick)) { 304 if (IS_ERR(wdev->mpu_wdt_ick)) {
281 ret = PTR_ERR(mpu_wdt_ick); 305 ret = PTR_ERR(wdev->mpu_wdt_ick);
282 mpu_wdt_ick = NULL; 306 wdev->mpu_wdt_ick = NULL;
307 goto fail;
308 }
309 wdev->mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck");
310 if (IS_ERR(wdev->mpu_wdt_fck)) {
311 ret = PTR_ERR(wdev->mpu_wdt_fck);
312 wdev->mpu_wdt_fck = NULL;
313 goto fail;
314 }
315 }
316
317 if (cpu_is_omap34xx()) {
318 wdev->mpu_wdt_ick = clk_get(&pdev->dev, "wdt2_ick");
319 if (IS_ERR(wdev->mpu_wdt_ick)) {
320 ret = PTR_ERR(wdev->mpu_wdt_ick);
321 wdev->mpu_wdt_ick = NULL;
283 goto fail; 322 goto fail;
284 } 323 }
285 mpu_wdt_fck = clk_get(&pdev->dev, "mpu_wdt_fck"); 324 wdev->mpu_wdt_fck = clk_get(&pdev->dev, "wdt2_fck");
286 if (IS_ERR(mpu_wdt_fck)) { 325 if (IS_ERR(wdev->mpu_wdt_fck)) {
287 ret = PTR_ERR(mpu_wdt_fck); 326 ret = PTR_ERR(wdev->mpu_wdt_fck);
288 mpu_wdt_fck = NULL; 327 wdev->mpu_wdt_fck = NULL;
289 goto fail; 328 goto fail;
290 } 329 }
291 } 330 }
331 wdev->base = (void __iomem *) (mem->start);
332 platform_set_drvdata(pdev, wdev);
292 333
293 omap_wdt_disable(); 334 omap_wdt_disable(wdev);
294 omap_wdt_adjust_timeout(timer_margin); 335 omap_wdt_adjust_timeout(timer_margin);
295 336
296 omap_wdt_miscdev.parent = &pdev->dev; 337 wdev->omap_wdt_miscdev.parent = &pdev->dev;
297 ret = misc_register(&omap_wdt_miscdev); 338 wdev->omap_wdt_miscdev.minor = WATCHDOG_MINOR;
339 wdev->omap_wdt_miscdev.name = "watchdog";
340 wdev->omap_wdt_miscdev.fops = &omap_wdt_fops;
341
342 ret = misc_register(&(wdev->omap_wdt_miscdev));
298 if (ret) 343 if (ret)
299 goto fail; 344 goto fail;
300 345
301 pr_info("OMAP Watchdog Timer: initial timeout %d sec\n", timer_margin); 346 pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n",
347 omap_readl(wdev->base + OMAP_WATCHDOG_REV) & 0xFF,
348 timer_margin);
302 349
303 /* autogate OCP interface clock */ 350 /* autogate OCP interface clock */
304 omap_writel(0x01, OMAP_WATCHDOG_SYS_CONFIG); 351 omap_writel(0x01, wdev->base + OMAP_WATCHDOG_SYS_CONFIG);
352
353 omap_wdt_dev = pdev;
354
305 return 0; 355 return 0;
306 356
307fail: 357fail:
308 if (armwdt_ck) 358 if (wdev) {
309 clk_put(armwdt_ck); 359 platform_set_drvdata(pdev, NULL);
310 if (mpu_wdt_ick) 360 if (wdev->armwdt_ck)
311 clk_put(mpu_wdt_ick); 361 clk_put(wdev->armwdt_ck);
312 if (mpu_wdt_fck) 362 if (wdev->mpu_wdt_ick)
313 clk_put(mpu_wdt_fck); 363 clk_put(wdev->mpu_wdt_ick);
314 release_resource(mem); 364 if (wdev->mpu_wdt_fck)
365 clk_put(wdev->mpu_wdt_fck);
366 kfree(wdev);
367 }
368 if (mem) {
369 release_mem_region(res->start, res->end - res->start + 1);
370 }
315 return ret; 371 return ret;
316} 372}
317 373
318static void omap_wdt_shutdown(struct platform_device *pdev) 374static void omap_wdt_shutdown(struct platform_device *pdev)
319{ 375{
320 omap_wdt_disable(); 376 struct omap_wdt_dev *wdev;
377 wdev = platform_get_drvdata(pdev);
378
379 if (wdev->omap_wdt_users)
380 omap_wdt_disable(wdev);
321} 381}
322 382
323static int omap_wdt_remove(struct platform_device *pdev) 383static int omap_wdt_remove(struct platform_device *pdev)
324{ 384{
325 struct resource *mem = platform_get_drvdata(pdev); 385 struct omap_wdt_dev *wdev;
326 misc_deregister(&omap_wdt_miscdev); 386 wdev = platform_get_drvdata(pdev);
327 release_resource(mem); 387 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
328 if (armwdt_ck) 388
329 clk_put(armwdt_ck); 389 if (!res)
330 if (mpu_wdt_ick) 390 return -ENOENT;
331 clk_put(mpu_wdt_ick); 391
332 if (mpu_wdt_fck) 392 misc_deregister(&(wdev->omap_wdt_miscdev));
333 clk_put(mpu_wdt_fck); 393 release_mem_region(res->start, res->end - res->start + 1);
394 platform_set_drvdata(pdev, NULL);
395 if (wdev->armwdt_ck) {
396 clk_put(wdev->armwdt_ck);
397 wdev->armwdt_ck = NULL;
398 }
399 if (wdev->mpu_wdt_ick) {
400 clk_put(wdev->mpu_wdt_ick);
401 wdev->mpu_wdt_ick = NULL;
402 }
403 if (wdev->mpu_wdt_fck) {
404 clk_put(wdev->mpu_wdt_fck);
405 wdev->mpu_wdt_fck = NULL;
406 }
407 kfree(wdev);
408 omap_wdt_dev = NULL;
334 return 0; 409 return 0;
335} 410}
336 411
@@ -344,16 +419,20 @@ static int omap_wdt_remove(struct platform_device *pdev)
344 419
345static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state) 420static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state)
346{ 421{
347 if (omap_wdt_users) 422 struct omap_wdt_dev *wdev;
348 omap_wdt_disable(); 423 wdev = platform_get_drvdata(pdev);
424 if (wdev->omap_wdt_users)
425 omap_wdt_disable(wdev);
349 return 0; 426 return 0;
350} 427}
351 428
352static int omap_wdt_resume(struct platform_device *pdev) 429static int omap_wdt_resume(struct platform_device *pdev)
353{ 430{
354 if (omap_wdt_users) { 431 struct omap_wdt_dev *wdev;
355 omap_wdt_enable(); 432 wdev = platform_get_drvdata(pdev);
356 omap_wdt_ping(); 433 if (wdev->omap_wdt_users) {
434 omap_wdt_enable(wdev);
435 omap_wdt_ping(wdev);
357 } 436 }
358 return 0; 437 return 0;
359} 438}
diff --git a/drivers/watchdog/omap_wdt.h b/drivers/watchdog/omap_wdt.h
index 52a532a5114a..fc02ec6a0386 100644
--- a/drivers/watchdog/omap_wdt.h
+++ b/drivers/watchdog/omap_wdt.h
@@ -30,25 +30,15 @@
30#ifndef _OMAP_WATCHDOG_H 30#ifndef _OMAP_WATCHDOG_H
31#define _OMAP_WATCHDOG_H 31#define _OMAP_WATCHDOG_H
32 32
33#define OMAP1610_WATCHDOG_BASE 0xfffeb000 33#define OMAP_WATCHDOG_REV (0x00)
34#define OMAP2420_WATCHDOG_BASE 0x48022000 /*WDT Timer 2 */ 34#define OMAP_WATCHDOG_SYS_CONFIG (0x10)
35 35#define OMAP_WATCHDOG_STATUS (0x14)
36#ifdef CONFIG_ARCH_OMAP24XX 36#define OMAP_WATCHDOG_CNTRL (0x24)
37#define OMAP_WATCHDOG_BASE OMAP2420_WATCHDOG_BASE 37#define OMAP_WATCHDOG_CRR (0x28)
38#else 38#define OMAP_WATCHDOG_LDR (0x2c)
39#define OMAP_WATCHDOG_BASE OMAP1610_WATCHDOG_BASE 39#define OMAP_WATCHDOG_TGR (0x30)
40#define RM_RSTST_WKUP 0 40#define OMAP_WATCHDOG_WPS (0x34)
41#endif 41#define OMAP_WATCHDOG_SPR (0x48)
42
43#define OMAP_WATCHDOG_REV (OMAP_WATCHDOG_BASE + 0x00)
44#define OMAP_WATCHDOG_SYS_CONFIG (OMAP_WATCHDOG_BASE + 0x10)
45#define OMAP_WATCHDOG_STATUS (OMAP_WATCHDOG_BASE + 0x14)
46#define OMAP_WATCHDOG_CNTRL (OMAP_WATCHDOG_BASE + 0x24)
47#define OMAP_WATCHDOG_CRR (OMAP_WATCHDOG_BASE + 0x28)
48#define OMAP_WATCHDOG_LDR (OMAP_WATCHDOG_BASE + 0x2c)
49#define OMAP_WATCHDOG_TGR (OMAP_WATCHDOG_BASE + 0x30)
50#define OMAP_WATCHDOG_WPS (OMAP_WATCHDOG_BASE + 0x34)
51#define OMAP_WATCHDOG_SPR (OMAP_WATCHDOG_BASE + 0x48)
52 42
53/* Using the prescaler, the OMAP watchdog could go for many 43/* Using the prescaler, the OMAP watchdog could go for many
54 * months before firing. These limits work without scaling, 44 * months before firing. These limits work without scaling,