[WATCHDOG] i6300esb.c: convert to platform device driver
[linux-2.6] / drivers / watchdog / i6300esb.c
1 /*
2  *      i6300esb:       Watchdog timer driver for Intel 6300ESB chipset
3  *
4  *      (c) Copyright 2004 Google Inc.
5  *      (c) Copyright 2005 David Härdeman <david@2gen.com>
6  *
7  *      This program is free software; you can redistribute it and/or
8  *      modify it under the terms of the GNU General Public License
9  *      as published by the Free Software Foundation; either version
10  *      2 of the License, or (at your option) any later version.
11  *
12  *      based on i810-tco.c which is in turn based on softdog.c
13  *
14  *      The timer is implemented in the following I/O controller hubs:
15  *      (See the intel documentation on http://developer.intel.com.)
16  *      6300ESB chip : document number 300641-004
17  *
18  *  2004YYZZ Ross Biro
19  *      Initial version 0.01
20  *  2004YYZZ Ross Biro
21  *      Version 0.02
22  *  20050210 David Härdeman <david@2gen.com>
23  *      Ported driver to kernel 2.6
24  */
25
26 /*
27  *      Includes, defines, variables, module parameters, ...
28  */
29
30 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/kernel.h>
33 #include <linux/fs.h>
34 #include <linux/mm.h>
35 #include <linux/miscdevice.h>
36 #include <linux/watchdog.h>
37 #include <linux/platform_device.h>
38 #include <linux/init.h>
39 #include <linux/pci.h>
40 #include <linux/ioport.h>
41 #include <linux/uaccess.h>
42 #include <linux/io.h>
43
44 /* Module and version information */
45 #define ESB_VERSION "0.04"
46 #define ESB_MODULE_NAME "i6300ESB timer"
47 #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
48 #define PFX ESB_MODULE_NAME ": "
49
50 /* PCI configuration registers */
51 #define ESB_CONFIG_REG  0x60            /* Config register                   */
52 #define ESB_LOCK_REG    0x68            /* WDT lock register                 */
53
54 /* Memory mapped registers */
55 #define ESB_TIMER1_REG  BASEADDR + 0x00 /* Timer1 value after each reset     */
56 #define ESB_TIMER2_REG  BASEADDR + 0x04 /* Timer2 value after each reset     */
57 #define ESB_GINTSR_REG  BASEADDR + 0x08 /* General Interrupt Status Register */
58 #define ESB_RELOAD_REG  BASEADDR + 0x0c /* Reload register                   */
59
60 /* Lock register bits */
61 #define ESB_WDT_FUNC    (0x01 << 2)   /* Watchdog functionality            */
62 #define ESB_WDT_ENABLE  (0x01 << 1)   /* Enable WDT                        */
63 #define ESB_WDT_LOCK    (0x01 << 0)   /* Lock (nowayout)                   */
64
65 /* Config register bits */
66 #define ESB_WDT_REBOOT  (0x01 << 5)   /* Enable reboot on timeout          */
67 #define ESB_WDT_FREQ    (0x01 << 2)   /* Decrement frequency               */
68 #define ESB_WDT_INTTYPE (0x11 << 0)   /* Interrupt type on timer1 timeout  */
69
70 /* Reload register bits */
71 #define ESB_WDT_RELOAD  (0x01 << 8)    /* prevent timeout                   */
72
73 /* Magic constants */
74 #define ESB_UNLOCK1     0x80            /* Step 1 to unlock reset registers  */
75 #define ESB_UNLOCK2     0x86            /* Step 2 to unlock reset registers  */
76
77 /* internal variables */
78 static void __iomem *BASEADDR;
79 static DEFINE_SPINLOCK(esb_lock); /* Guards the hardware */
80 static unsigned long timer_alive;
81 static struct pci_dev *esb_pci;
82 static unsigned short triggered; /* The status of the watchdog upon boot */
83 static char esb_expect_close;
84 static struct platform_device *esb_platform_device;
85
86
87 /* module parameters */
88 /* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
89 #define WATCHDOG_HEARTBEAT 30
90 static int heartbeat = WATCHDOG_HEARTBEAT;  /* in seconds */
91
92 module_param(heartbeat, int, 0);
93 MODULE_PARM_DESC(heartbeat,
94                 "Watchdog heartbeat in seconds. (1<heartbeat<2046, default="
95                                 __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
96
97 static int nowayout = WATCHDOG_NOWAYOUT;
98 module_param(nowayout, int, 0);
99 MODULE_PARM_DESC(nowayout,
100                 "Watchdog cannot be stopped once started (default="
101                                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
102
103 /*
104  * Some i6300ESB specific functions
105  */
106
107 /*
108  * Prepare for reloading the timer by unlocking the proper registers.
109  * This is performed by first writing 0x80 followed by 0x86 to the
110  * reload register. After this the appropriate registers can be written
111  * to once before they need to be unlocked again.
112  */
113 static inline void esb_unlock_registers(void)
114 {
115         writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
116         writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
117 }
118
119 static void esb_timer_start(void)
120 {
121         u8 val;
122
123         /* Enable or Enable + Lock? */
124         val = 0x02 | (nowayout ? 0x01 : 0x00);
125         pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
126 }
127
128 static int esb_timer_stop(void)
129 {
130         u8 val;
131
132         spin_lock(&esb_lock);
133         /* First, reset timers as suggested by the docs */
134         esb_unlock_registers();
135         writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
136         /* Then disable the WDT */
137         pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0);
138         pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val);
139         spin_unlock(&esb_lock);
140
141         /* Returns 0 if the timer was disabled, non-zero otherwise */
142         return (val & 0x01);
143 }
144
145 static void esb_timer_keepalive(void)
146 {
147         spin_lock(&esb_lock);
148         esb_unlock_registers();
149         writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
150         /* FIXME: Do we need to flush anything here? */
151         spin_unlock(&esb_lock);
152 }
153
154 static int esb_timer_set_heartbeat(int time)
155 {
156         u32 val;
157
158         if (time < 0x1 || time > (2 * 0x03ff))
159                 return -EINVAL;
160
161         spin_lock(&esb_lock);
162
163         /* We shift by 9, so if we are passed a value of 1 sec,
164          * val will be 1 << 9 = 512, then write that to two
165          * timers => 2 * 512 = 1024 (which is decremented at 1KHz)
166          */
167         val = time << 9;
168
169         /* Write timer 1 */
170         esb_unlock_registers();
171         writel(val, ESB_TIMER1_REG);
172
173         /* Write timer 2 */
174         esb_unlock_registers();
175         writel(val, ESB_TIMER2_REG);
176
177         /* Reload */
178         esb_unlock_registers();
179         writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
180
181         /* FIXME: Do we need to flush everything out? */
182
183         /* Done */
184         heartbeat = time;
185         spin_unlock(&esb_lock);
186         return 0;
187 }
188
189 static int esb_timer_read(void)
190 {
191         u32 count;
192
193         /* This isn't documented, and doesn't take into
194          * acount which stage is running, but it looks
195          * like a 20 bit count down, so we might as well report it.
196          */
197         pci_read_config_dword(esb_pci, 0x64, &count);
198         return (int)count;
199 }
200
201 /*
202  *      /dev/watchdog handling
203  */
204
205 static int esb_open(struct inode *inode, struct file *file)
206 {
207         /* /dev/watchdog can only be opened once */
208         if (test_and_set_bit(0, &timer_alive))
209                 return -EBUSY;
210
211         /* Reload and activate timer */
212         esb_timer_keepalive();
213         esb_timer_start();
214
215         return nonseekable_open(inode, file);
216 }
217
218 static int esb_release(struct inode *inode, struct file *file)
219 {
220         /* Shut off the timer. */
221         if (esb_expect_close == 42)
222                 esb_timer_stop();
223         else {
224                 printk(KERN_CRIT PFX
225                                 "Unexpected close, not stopping watchdog!\n");
226                 esb_timer_keepalive();
227         }
228         clear_bit(0, &timer_alive);
229         esb_expect_close = 0;
230         return 0;
231 }
232
233 static ssize_t esb_write(struct file *file, const char __user *data,
234                           size_t len, loff_t *ppos)
235 {
236         /* See if we got the magic character 'V' and reload the timer */
237         if (len) {
238                 if (!nowayout) {
239                         size_t i;
240
241                         /* note: just in case someone wrote the magic character
242                          * five months ago... */
243                         esb_expect_close = 0;
244
245                         /* scan to see whether or not we got the
246                          * magic character */
247                         for (i = 0; i != len; i++) {
248                                 char c;
249                                 if (get_user(c, data + i))
250                                         return -EFAULT;
251                                 if (c == 'V')
252                                         esb_expect_close = 42;
253                         }
254                 }
255
256                 /* someone wrote to us, we should reload the timer */
257                 esb_timer_keepalive();
258         }
259         return len;
260 }
261
262 static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
263 {
264         int new_options, retval = -EINVAL;
265         int new_heartbeat;
266         void __user *argp = (void __user *)arg;
267         int __user *p = argp;
268         static struct watchdog_info ident = {
269                 .options =              WDIOF_SETTIMEOUT |
270                                         WDIOF_KEEPALIVEPING |
271                                         WDIOF_MAGICCLOSE,
272                 .firmware_version =     0,
273                 .identity =             ESB_MODULE_NAME,
274         };
275
276         switch (cmd) {
277         case WDIOC_GETSUPPORT:
278                 return copy_to_user(argp, &ident,
279                                         sizeof(ident)) ? -EFAULT : 0;
280
281         case WDIOC_GETSTATUS:
282                 return put_user(esb_timer_read(), p);
283
284         case WDIOC_GETBOOTSTATUS:
285                 return put_user(triggered, p);
286
287         case WDIOC_SETOPTIONS:
288         {
289                 if (get_user(new_options, p))
290                         return -EFAULT;
291
292                 if (new_options & WDIOS_DISABLECARD) {
293                         esb_timer_stop();
294                         retval = 0;
295                 }
296
297                 if (new_options & WDIOS_ENABLECARD) {
298                         esb_timer_keepalive();
299                         esb_timer_start();
300                         retval = 0;
301                 }
302                 return retval;
303         }
304         case WDIOC_KEEPALIVE:
305                 esb_timer_keepalive();
306                 return 0;
307
308         case WDIOC_SETTIMEOUT:
309         {
310                 if (get_user(new_heartbeat, p))
311                         return -EFAULT;
312                 if (esb_timer_set_heartbeat(new_heartbeat))
313                         return -EINVAL;
314                 esb_timer_keepalive();
315                 /* Fall */
316         }
317         case WDIOC_GETTIMEOUT:
318                 return put_user(heartbeat, p);
319         default:
320                 return -ENOTTY;
321         }
322 }
323
324 /*
325  *      Kernel Interfaces
326  */
327
328 static const struct file_operations esb_fops = {
329         .owner = THIS_MODULE,
330         .llseek = no_llseek,
331         .write = esb_write,
332         .unlocked_ioctl = esb_ioctl,
333         .open = esb_open,
334         .release = esb_release,
335 };
336
337 static struct miscdevice esb_miscdev = {
338         .minor = WATCHDOG_MINOR,
339         .name = "watchdog",
340         .fops = &esb_fops,
341 };
342
343 /*
344  * Data for PCI driver interface
345  *
346  * This data only exists for exporting the supported
347  * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
348  * register a pci_driver, because someone else might one day
349  * want to register another driver on the same PCI id.
350  */
351 static struct pci_device_id esb_pci_tbl[] = {
352         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
353         { 0, },                 /* End of list */
354 };
355 MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
356
357 /*
358  *      Init & exit routines
359  */
360
361 static unsigned char __devinit esb_getdevice(void)
362 {
363         u8 val1;
364         unsigned short val2;
365         /*
366          *      Find the PCI device
367          */
368
369         esb_pci = pci_get_device(PCI_VENDOR_ID_INTEL,
370                                         PCI_DEVICE_ID_INTEL_ESB_9, NULL);
371
372         if (esb_pci) {
373                 if (pci_enable_device(esb_pci)) {
374                         printk(KERN_ERR PFX "failed to enable device\n");
375                         goto err_devput;
376                 }
377
378                 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
379                         printk(KERN_ERR PFX "failed to request region\n");
380                         goto err_disable;
381                 }
382
383                 BASEADDR = pci_ioremap_bar(esb_pci, 0);
384                 if (BASEADDR == NULL) {
385                         /* Something's wrong here, BASEADDR has to be set */
386                         printk(KERN_ERR PFX "failed to get BASEADDR\n");
387                         goto err_release;
388                 }
389
390                 /*
391                  * The watchdog has two timers, it can be setup so that the
392                  * expiry of timer1 results in an interrupt and the expiry of
393                  * timer2 results in a reboot. We set it to not generate
394                  * any interrupts as there is not much we can do with it
395                  * right now.
396                  *
397                  * We also enable reboots and set the timer frequency to
398                  * the PCI clock divided by 2^15 (approx 1KHz).
399                  */
400                 pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
401
402                 /* Check that the WDT isn't already locked */
403                 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
404                 if (val1 & ESB_WDT_LOCK)
405                         printk(KERN_WARNING PFX "nowayout already set\n");
406
407                 /* Set the timer to watchdog mode and disable it for now */
408                 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
409
410                 /* Check if the watchdog was previously triggered */
411                 esb_unlock_registers();
412                 val2 = readw(ESB_RELOAD_REG);
413                 triggered = (val2 & (0x01 << 9) >> 9);
414
415                 /* Reset trigger flag and timers */
416                 esb_unlock_registers();
417                 writew((0x11 << 8), ESB_RELOAD_REG);
418
419                 /* Done */
420                 return 1;
421
422 err_release:
423                 pci_release_region(esb_pci, 0);
424 err_disable:
425                 pci_disable_device(esb_pci);
426 err_devput:
427                 pci_dev_put(esb_pci);
428         }
429         return 0;
430 }
431
432 static int __devinit esb_probe(struct platform_device *dev)
433 {
434         int ret;
435
436         /* Check whether or not the hardware watchdog is there */
437         if (!esb_getdevice() || esb_pci == NULL)
438                 return -ENODEV;
439
440         /* Check that the heartbeat value is within it's range;
441            if not reset to the default */
442         if (esb_timer_set_heartbeat(heartbeat)) {
443                 esb_timer_set_heartbeat(WATCHDOG_HEARTBEAT);
444                 printk(KERN_INFO PFX
445                         "heartbeat value must be 1<heartbeat<2046, using %d\n",
446                                                                 heartbeat);
447         }
448
449         ret = misc_register(&esb_miscdev);
450         if (ret != 0) {
451                 printk(KERN_ERR PFX
452                         "cannot register miscdev on minor=%d (err=%d)\n",
453                                                         WATCHDOG_MINOR, ret);
454                 goto err_unmap;
455         }
456         esb_timer_stop();
457         printk(KERN_INFO PFX
458                 "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
459                                                 BASEADDR, heartbeat, nowayout);
460         return 0;
461
462 err_unmap:
463         iounmap(BASEADDR);
464 /* err_release: */
465         pci_release_region(esb_pci, 0);
466 /* err_disable: */
467         pci_disable_device(esb_pci);
468 /* err_devput: */
469         pci_dev_put(esb_pci);
470         return ret;
471 }
472
473 static int __devexit esb_remove(struct platform_device *dev)
474 {
475         /* Stop the timer before we leave */
476         if (!nowayout)
477                 esb_timer_stop();
478
479         /* Deregister */
480         misc_deregister(&esb_miscdev);
481         iounmap(BASEADDR);
482         pci_release_region(esb_pci, 0);
483         pci_disable_device(esb_pci);
484         pci_dev_put(esb_pci);
485         return 0;
486 }
487
488 static void esb_shutdown(struct platform_device *dev)
489 {
490         esb_timer_stop();
491 }
492
493 static struct platform_driver esb_platform_driver = {
494         .probe          = esb_probe,
495         .remove         = __devexit_p(esb_remove),
496         .shutdown       = esb_shutdown,
497         .driver         = {
498                 .owner  = THIS_MODULE,
499                 .name   = ESB_MODULE_NAME,
500         },
501 };
502
503 static int __init watchdog_init(void)
504 {
505         int err;
506
507         printk(KERN_INFO PFX "Intel 6300ESB WatchDog Timer Driver v%s\n",
508                 ESB_VERSION);
509
510         err = platform_driver_register(&esb_platform_driver);
511         if (err)
512                 return err;
513
514         esb_platform_device = platform_device_register_simple(ESB_MODULE_NAME,
515                                                                 -1, NULL, 0);
516         if (IS_ERR(esb_platform_device)) {
517                 err = PTR_ERR(esb_platform_device);
518                 goto unreg_platform_driver;
519         }
520
521         return 0;
522
523 unreg_platform_driver:
524         platform_driver_unregister(&esb_platform_driver);
525         return err;
526 }
527
528 static void __exit watchdog_cleanup(void)
529 {
530         platform_device_unregister(esb_platform_device);
531         platform_driver_unregister(&esb_platform_driver);
532         printk(KERN_INFO PFX "Watchdog Module Unloaded.\n");
533 }
534
535 module_init(watchdog_init);
536 module_exit(watchdog_cleanup);
537
538 MODULE_AUTHOR("Ross Biro and David Härdeman");
539 MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
540 MODULE_LICENSE("GPL");
541 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);