aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/watchdog/rm9k_wdt.c
diff options
context:
space:
mode:
authorWim Van Sebroeck <wim@iguana.be>2006-11-17 17:15:48 -0500
committerWim Van Sebroeck <wim@iguana.be>2006-11-17 17:15:48 -0500
commit97846e3ccbcbcc966e23a91b0d190efd1f889c9b (patch)
tree9d60f17dc7fb6e17b4e25ea9e4feeec444d1e642 /drivers/char/watchdog/rm9k_wdt.c
parentcd57eeab7c4c108ce6e84545bdf37ae91b930781 (diff)
[WATCHDOG] MIPS RM9000 on-chip watchdog device - patch 2
Reorganize source code so that it is structured as follows: - Function prototypes - Local variables - Module arguments - Interrupt handler - Watchdog functions - /dev/watchdog operations - Shutdown notifier - Kernel interfaces - Init & exit procedures - Device driver init & exit Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/char/watchdog/rm9k_wdt.c')
-rw-r--r--drivers/char/watchdog/rm9k_wdt.c216
1 files changed, 101 insertions, 115 deletions
diff --git a/drivers/char/watchdog/rm9k_wdt.c b/drivers/char/watchdog/rm9k_wdt.c
index da3fc63bca61..1aad9138f714 100644
--- a/drivers/char/watchdog/rm9k_wdt.c
+++ b/drivers/char/watchdog/rm9k_wdt.c
@@ -46,8 +46,7 @@
46 46
47 47
48/* Function prototypes */ 48/* Function prototypes */
49static int __init wdt_gpi_probe(struct device *); 49static irqreturn_t wdt_gpi_irqhdl(int, void *, struct pt_regs *);
50static int __exit wdt_gpi_remove(struct device *);
51static void wdt_gpi_set_timeout(unsigned int); 50static void wdt_gpi_set_timeout(unsigned int);
52static int wdt_gpi_open(struct inode *, struct file *); 51static int wdt_gpi_open(struct inode *, struct file *);
53static int wdt_gpi_release(struct inode *, struct file *); 52static int wdt_gpi_release(struct inode *, struct file *);
@@ -55,7 +54,8 @@ static ssize_t wdt_gpi_write(struct file *, const char __user *, size_t, loff_t
55static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); 54static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long);
56static const struct resource *wdt_gpi_get_resource(struct platform_device *, const char *, unsigned int); 55static const struct resource *wdt_gpi_get_resource(struct platform_device *, const char *, unsigned int);
57static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); 56static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *);
58static irqreturn_t wdt_gpi_irqhdl(int, void *, struct pt_regs *); 57static int __init wdt_gpi_probe(struct device *);
58static int __exit wdt_gpi_remove(struct device *);
59 59
60 60
61static const char wdt_gpi_name[] = "wdt_gpi"; 61static const char wdt_gpi_name[] = "wdt_gpi";
@@ -91,93 +91,26 @@ module_param(nowayout, bool, 0444);
91MODULE_PARM_DESC(nowayout, "Watchdog cannot be disabled once started"); 91MODULE_PARM_DESC(nowayout, "Watchdog cannot be disabled once started");
92 92
93 93
94 94/* Interrupt handler */
95static struct file_operations fops = { 95static irqreturn_t wdt_gpi_irqhdl(int irq, void *ctxt, struct pt_regs *regs)
96 .owner = THIS_MODULE,
97 .open = wdt_gpi_open,
98 .release = wdt_gpi_release,
99 .write = wdt_gpi_write,
100 .unlocked_ioctl = wdt_gpi_ioctl,
101};
102
103static struct miscdevice miscdev = {
104 .minor = WATCHDOG_MINOR,
105 .name = wdt_gpi_name,
106 .fops = &fops,
107};
108
109static struct device_driver wdt_gpi_driver = {
110 .name = (char *) wdt_gpi_name,
111 .bus = &platform_bus_type,
112 .owner = THIS_MODULE,
113 .probe = wdt_gpi_probe,
114 .remove = __exit_p(wdt_gpi_remove),
115 .shutdown = NULL,
116 .suspend = NULL,
117 .resume = NULL,
118};
119
120static struct notifier_block wdt_gpi_shutdown = {
121 .notifier_call = wdt_gpi_notify,
122};
123
124
125
126static const struct resource *
127wdt_gpi_get_resource(struct platform_device *pdv, const char *name,
128 unsigned int type)
129{
130 char buf[80];
131 if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf)
132 return NULL;
133 return platform_get_resource_byname(pdv, type, buf);
134}
135
136
137
138/* No hotplugging on the platform bus - use __init */
139static int __init wdt_gpi_probe(struct device *dev)
140{ 96{
141 int res; 97 if (!unlikely(__raw_readl(wd_regs + 0x0008) & 0x1))
142 struct platform_device * const pdv = to_platform_device(dev); 98 return IRQ_NONE;
143 const struct resource 99 __raw_writel(0x1, wd_regs + 0x0008);
144 * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS,
145 IORESOURCE_MEM),
146 * const ri = wdt_gpi_get_resource(pdv, WDT_RESOURCE_IRQ,
147 IORESOURCE_IRQ),
148 * const rc = wdt_gpi_get_resource(pdv, WDT_RESOURCE_COUNTER,
149 0);
150
151 if (unlikely(!rr || !ri || !rc))
152 return -ENXIO;
153
154 wd_regs = ioremap_nocache(rr->start, rr->end + 1 - rr->start);
155 if (unlikely(!wd_regs))
156 return -ENOMEM;
157 wd_irq = ri->start;
158 wd_ctr = rc->start;
159 res = misc_register(&miscdev);
160 if (res)
161 iounmap(wd_regs);
162 else
163 register_reboot_notifier(&wdt_gpi_shutdown);
164 return res;
165}
166
167 100
168 101
169static int __exit wdt_gpi_remove(struct device *dev) 102 printk(KERN_WARNING "%s: watchdog expired - resetting system\n",
170{ 103 wdt_gpi_name);
171 int res;
172 104
173 unregister_reboot_notifier(&wdt_gpi_shutdown); 105 *(volatile char *) flagaddr |= 0x01;
174 res = misc_deregister(&miscdev); 106 *(volatile char *) resetaddr = powercycle ? 0x01 : 0x2;
175 iounmap(wd_regs); 107 iob();
176 wd_regs = NULL; 108 while (1)
177 return res; 109 cpu_relax();
178} 110}
179 111
180 112
113/* Watchdog functions */
181static void wdt_gpi_set_timeout(unsigned int to) 114static void wdt_gpi_set_timeout(unsigned int to)
182{ 115{
183 u32 reg; 116 u32 reg;
@@ -197,7 +130,7 @@ static void wdt_gpi_set_timeout(unsigned int to)
197} 130}
198 131
199 132
200 133/* /dev/watchdog operations */
201static int wdt_gpi_open(struct inode *i, struct file *f) 134static int wdt_gpi_open(struct inode *i, struct file *f)
202{ 135{
203 int res; 136 int res;
@@ -231,8 +164,6 @@ static int wdt_gpi_open(struct inode *i, struct file *f)
231 return 0; 164 return 0;
232} 165}
233 166
234
235
236static int wdt_gpi_release(struct inode *i, struct file *f) 167static int wdt_gpi_release(struct inode *i, struct file *f)
237{ 168{
238 if (nowayout) { 169 if (nowayout) {
@@ -267,8 +198,6 @@ static int wdt_gpi_release(struct inode *i, struct file *f)
267 return 0; 198 return 0;
268} 199}
269 200
270
271
272static ssize_t 201static ssize_t
273wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o) 202wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o)
274{ 203{
@@ -279,8 +208,6 @@ wdt_gpi_write(struct file *f, const char __user *d, size_t s, loff_t *o)
279 return s ? 1 : 0; 208 return s ? 1 : 0;
280} 209}
281 210
282
283
284static long 211static long
285wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 212wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
286{ 213{
@@ -362,27 +289,7 @@ wdt_gpi_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
362} 289}
363 290
364 291
365 292/* Shutdown notifier*/
366
367static irqreturn_t wdt_gpi_irqhdl(int irq, void *ctxt, struct pt_regs *regs)
368{
369 if (!unlikely(__raw_readl(wd_regs + 0x0008) & 0x1))
370 return IRQ_NONE;
371 __raw_writel(0x1, wd_regs + 0x0008);
372
373
374 printk(KERN_WARNING "%s: watchdog expired - resetting system\n",
375 wdt_gpi_name);
376
377 *(volatile char *) flagaddr |= 0x01;
378 *(volatile char *) resetaddr = powercycle ? 0x01 : 0x2;
379 iob();
380 while (1)
381 cpu_relax();
382}
383
384
385
386static int 293static int
387wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused) 294wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused)
388{ 295{
@@ -401,6 +308,89 @@ wdt_gpi_notify(struct notifier_block *this, unsigned long code, void *unused)
401} 308}
402 309
403 310
311/* Kernel interfaces */
312static struct file_operations fops = {
313 .owner = THIS_MODULE,
314 .open = wdt_gpi_open,
315 .release = wdt_gpi_release,
316 .write = wdt_gpi_write,
317 .unlocked_ioctl = wdt_gpi_ioctl,
318};
319
320static struct miscdevice miscdev = {
321 .minor = WATCHDOG_MINOR,
322 .name = wdt_gpi_name,
323 .fops = &fops,
324};
325
326static struct notifier_block wdt_gpi_shutdown = {
327 .notifier_call = wdt_gpi_notify,
328};
329
330
331/* Init & exit procedures */
332static const struct resource *
333wdt_gpi_get_resource(struct platform_device *pdv, const char *name,
334 unsigned int type)
335{
336 char buf[80];
337 if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf)
338 return NULL;
339 return platform_get_resource_byname(pdv, type, buf);
340}
341
342/* No hotplugging on the platform bus - use __init */
343static int __init wdt_gpi_probe(struct device *dev)
344{
345 int res;
346 struct platform_device * const pdv = to_platform_device(dev);
347 const struct resource
348 * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS,
349 IORESOURCE_MEM),
350 * const ri = wdt_gpi_get_resource(pdv, WDT_RESOURCE_IRQ,
351 IORESOURCE_IRQ),
352 * const rc = wdt_gpi_get_resource(pdv, WDT_RESOURCE_COUNTER,
353 0);
354
355 if (unlikely(!rr || !ri || !rc))
356 return -ENXIO;
357
358 wd_regs = ioremap_nocache(rr->start, rr->end + 1 - rr->start);
359 if (unlikely(!wd_regs))
360 return -ENOMEM;
361 wd_irq = ri->start;
362 wd_ctr = rc->start;
363 res = misc_register(&miscdev);
364 if (res)
365 iounmap(wd_regs);
366 else
367 register_reboot_notifier(&wdt_gpi_shutdown);
368 return res;
369}
370
371static int __exit wdt_gpi_remove(struct device *dev)
372{
373 int res;
374
375 unregister_reboot_notifier(&wdt_gpi_shutdown);
376 res = misc_deregister(&miscdev);
377 iounmap(wd_regs);
378 wd_regs = NULL;
379 return res;
380}
381
382
383/* Device driver init & exit */
384static struct device_driver wdt_gpi_driver = {
385 .name = (char *) wdt_gpi_name,
386 .bus = &platform_bus_type,
387 .owner = THIS_MODULE,
388 .probe = wdt_gpi_probe,
389 .remove = __exit_p(wdt_gpi_remove),
390 .shutdown = NULL,
391 .suspend = NULL,
392 .resume = NULL,
393};
404 394
405static int __init wdt_gpi_init_module(void) 395static int __init wdt_gpi_init_module(void)
406{ 396{
@@ -410,8 +400,6 @@ static int __init wdt_gpi_init_module(void)
410 return driver_register(&wdt_gpi_driver); 400 return driver_register(&wdt_gpi_driver);
411} 401}
412 402
413
414
415static void __exit wdt_gpi_cleanup_module(void) 403static void __exit wdt_gpi_cleanup_module(void)
416{ 404{
417 driver_unregister(&wdt_gpi_driver); 405 driver_unregister(&wdt_gpi_driver);
@@ -420,8 +408,6 @@ static void __exit wdt_gpi_cleanup_module(void)
420module_init(wdt_gpi_init_module); 408module_init(wdt_gpi_init_module);
421module_exit(wdt_gpi_cleanup_module); 409module_exit(wdt_gpi_cleanup_module);
422 410
423
424
425MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>"); 411MODULE_AUTHOR("Thomas Koeller <thomas.koeller@baslerweb.com>");
426MODULE_DESCRIPTION("Basler eXcite watchdog driver for gpi devices"); 412MODULE_DESCRIPTION("Basler eXcite watchdog driver for gpi devices");
427MODULE_VERSION("0.1"); 413MODULE_VERSION("0.1");