2 * i6300esb 0.03: Watchdog timer driver for Intel 6300ESB chipset
4 * (c) Copyright 2004 Google Inc.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 * based on i810-tco.c which is
13 * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>
15 * Jentro AG, Haar/Munich (Germany)
17 * which is in turn based on softdog.c by Alan Cox <alan@redhat.com>
19 * The timer is implemented in the following I/O controller hubs:
20 * (See the intel documentation on http://developer.intel.com.)
21 * 6300ESB chip : document number 300641-003
24 * Initial version 0.01
27 * 20050210 David Härdeman <david@2gen.com>
28 * Ported driver to kernel 2.6
32 * Includes, defines, variables, module parameters, ...
35 #include <linux/module.h>
36 #include <linux/types.h>
37 #include <linux/kernel.h>
40 #include <linux/miscdevice.h>
41 #include <linux/watchdog.h>
42 #include <linux/reboot.h>
43 #include <linux/init.h>
44 #include <linux/pci.h>
45 #include <linux/ioport.h>
47 #include <asm/uaccess.h>
52 /* Module and version information */
53 #define ESB_VERSION "0.03"
54 #define ESB_MODULE_NAME "i6300ESB timer"
55 #define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
56 #define PFX ESB_MODULE_NAME ": "
58 /* internal variables */
59 static void __iomem *BASEADDR;
60 static spinlock_t esb_lock; /* Guards the hardware */
61 static unsigned long timer_alive;
62 static struct pci_dev *esb_pci;
63 static unsigned short triggered; /* The status of the watchdog upon boot */
64 static char esb_expect_close;
66 /* module parameters */
67 #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat (1<heartbeat<2*1023) */
68 static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
69 module_param(heartbeat, int, 0);
70 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1<heartbeat<2046, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
72 static int nowayout = WATCHDOG_NOWAYOUT;
73 module_param(nowayout, int, 0);
74 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
77 * Some i6300ESB specific functions
81 * Prepare for reloading the timer by unlocking the proper registers.
82 * This is performed by first writing 0x80 followed by 0x86 to the
83 * reload register. After this the appropriate registers can be written
84 * to once before they need to be unlocked again.
86 static inline void esb_unlock_registers(void) {
87 writeb(ESB_UNLOCK1, ESB_RELOAD_REG);
88 writeb(ESB_UNLOCK2, ESB_RELOAD_REG);
91 static void esb_timer_start(void)
95 /* Enable or Enable + Lock? */
96 val = 0x02 | (nowayout ? 0x01 : 0x00);
98 pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
101 static int esb_timer_stop(void)
105 spin_lock(&esb_lock);
106 /* First, reset timers as suggested by the docs */
107 esb_unlock_registers();
108 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
109 /* Then disable the WDT */
110 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0);
111 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val);
112 spin_unlock(&esb_lock);
114 /* Returns 0 if the timer was disabled, non-zero otherwise */
118 static void esb_timer_keepalive(void)
120 spin_lock(&esb_lock);
121 esb_unlock_registers();
122 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
123 /* FIXME: Do we need to flush anything here? */
124 spin_unlock(&esb_lock);
127 static int esb_timer_set_heartbeat(int time)
131 if (time < 0x1 || time > (2 * 0x03ff))
134 spin_lock(&esb_lock);
136 /* We shift by 9, so if we are passed a value of 1 sec,
137 * val will be 1 << 9 = 512, then write that to two
138 * timers => 2 * 512 = 1024 (which is decremented at 1KHz)
143 esb_unlock_registers();
144 writel(val, ESB_TIMER1_REG);
147 esb_unlock_registers();
148 writel(val, ESB_TIMER2_REG);
151 esb_unlock_registers();
152 writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
154 /* FIXME: Do we need to flush everything out? */
158 spin_unlock(&esb_lock);
162 static int esb_timer_read (void)
166 /* This isn't documented, and doesn't take into
167 * acount which stage is running, but it looks
168 * like a 20 bit count down, so we might as well report it.
170 pci_read_config_dword(esb_pci, 0x64, &count);
175 * /dev/watchdog handling
178 static int esb_open (struct inode *inode, struct file *file)
180 /* /dev/watchdog can only be opened once */
181 if (test_and_set_bit(0, &timer_alive))
184 /* Reload and activate timer */
185 esb_timer_keepalive ();
188 return nonseekable_open(inode, file);
191 static int esb_release (struct inode *inode, struct file *file)
193 /* Shut off the timer. */
194 if (esb_expect_close == 42) {
197 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
198 esb_timer_keepalive ();
200 clear_bit(0, &timer_alive);
201 esb_expect_close = 0;
205 static ssize_t esb_write (struct file *file, const char __user *data,
206 size_t len, loff_t * ppos)
208 /* See if we got the magic character 'V' and reload the timer */
213 /* note: just in case someone wrote the magic character
214 * five months ago... */
215 esb_expect_close = 0;
217 /* scan to see whether or not we got the magic character */
218 for (i = 0; i != len; i++) {
220 if(get_user(c, data+i))
223 esb_expect_close = 42;
227 /* someone wrote to us, we should reload the timer */
228 esb_timer_keepalive ();
233 static int esb_ioctl (struct inode *inode, struct file *file,
234 unsigned int cmd, unsigned long arg)
236 int new_options, retval = -EINVAL;
238 void __user *argp = (void __user *)arg;
239 int __user *p = argp;
240 static struct watchdog_info ident = {
241 .options = WDIOF_SETTIMEOUT |
242 WDIOF_KEEPALIVEPING |
244 .firmware_version = 0,
245 .identity = ESB_MODULE_NAME,
249 case WDIOC_GETSUPPORT:
250 return copy_to_user(argp, &ident,
251 sizeof (ident)) ? -EFAULT : 0;
253 case WDIOC_GETSTATUS:
254 return put_user (esb_timer_read(), p);
256 case WDIOC_GETBOOTSTATUS:
257 return put_user (triggered, p);
259 case WDIOC_KEEPALIVE:
260 esb_timer_keepalive ();
263 case WDIOC_SETOPTIONS:
265 if (get_user (new_options, p))
268 if (new_options & WDIOS_DISABLECARD) {
273 if (new_options & WDIOS_ENABLECARD) {
274 esb_timer_keepalive ();
282 case WDIOC_SETTIMEOUT:
284 if (get_user(new_heartbeat, p))
287 if (esb_timer_set_heartbeat(new_heartbeat))
290 esb_timer_keepalive ();
294 case WDIOC_GETTIMEOUT:
295 return put_user(heartbeat, p);
306 static int esb_notify_sys (struct notifier_block *this, unsigned long code, void *unused)
308 if (code==SYS_DOWN || code==SYS_HALT) {
309 /* Turn the WDT off */
320 static struct file_operations esb_fops = {
321 .owner = THIS_MODULE,
326 .release = esb_release,
329 static struct miscdevice esb_miscdev = {
330 .minor = WATCHDOG_MINOR,
335 static struct notifier_block esb_notifier = {
336 .notifier_call = esb_notify_sys,
340 * Data for PCI driver interface
342 * This data only exists for exporting the supported
343 * PCI ids via MODULE_DEVICE_TABLE. We do not actually
344 * register a pci_driver, because someone else might one day
345 * want to register another driver on the same PCI id.
347 static struct pci_device_id esb_pci_tbl[] = {
348 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_9), },
349 { 0, }, /* End of list */
351 MODULE_DEVICE_TABLE (pci, esb_pci_tbl);
354 * Init & exit routines
357 static unsigned char __init esb_getdevice (void)
362 struct pci_dev *dev = NULL;
364 * Find the PCI device
367 for_each_pci_dev(dev) {
368 if (pci_match_id(esb_pci_tbl, dev)) {
375 if (pci_enable_device(esb_pci)) {
376 printk (KERN_ERR PFX "failed to enable device\n");
380 if (pci_request_region(esb_pci, 0, ESB_MODULE_NAME)) {
381 printk (KERN_ERR PFX "failed to request region\n");
385 BASEADDR = ioremap(pci_resource_start(esb_pci, 0),
386 pci_resource_len(esb_pci, 0));
387 if (BASEADDR == NULL) {
388 /* Something's wrong here, BASEADDR has to be set */
389 printk (KERN_ERR PFX "failed to get BASEADDR\n");
394 * The watchdog has two timers, it can be setup so that the
395 * expiry of timer1 results in an interrupt and the expiry of
396 * timer2 results in a reboot. We set it to not generate
397 * any interrupts as there is not much we can do with it
400 * We also enable reboots and set the timer frequency to
401 * the PCI clock divided by 2^15 (approx 1KHz).
403 pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
405 /* Check that the WDT isn't already locked */
406 pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
407 if (val1 & ESB_WDT_LOCK)
408 printk (KERN_WARNING PFX "nowayout already set\n");
410 /* Set the timer to watchdog mode and disable it for now */
411 pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
413 /* Check if the watchdog was previously triggered */
414 esb_unlock_registers();
415 val2 = readw(ESB_RELOAD_REG);
416 triggered = (val2 & (0x01 << 9) >> 9);
418 /* Reset trigger flag and timers */
419 esb_unlock_registers();
420 writew((0x11 << 8), ESB_RELOAD_REG);
426 pci_release_region(esb_pci, 0);
428 pci_disable_device(esb_pci);
430 pci_dev_put(esb_pci);
435 static int __init watchdog_init (void)
439 spin_lock_init(&esb_lock);
441 /* Check whether or not the hardware watchdog is there */
442 if (!esb_getdevice () || esb_pci == NULL)
445 /* Check that the heartbeat value is within it's range ; if not reset to the default */
446 if (esb_timer_set_heartbeat (heartbeat)) {
447 esb_timer_set_heartbeat (WATCHDOG_HEARTBEAT);
448 printk(KERN_INFO PFX "heartbeat value must be 1<heartbeat<2046, using %d\n",
452 ret = register_reboot_notifier(&esb_notifier);
454 printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
459 ret = misc_register(&esb_miscdev);
461 printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
462 WATCHDOG_MINOR, ret);
468 printk (KERN_INFO PFX "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
469 BASEADDR, heartbeat, nowayout);
474 unregister_reboot_notifier(&esb_notifier);
478 pci_release_region(esb_pci, 0);
480 pci_disable_device(esb_pci);
482 pci_dev_put(esb_pci);
486 static void __exit watchdog_cleanup (void)
488 /* Stop the timer before we leave */
493 misc_deregister(&esb_miscdev);
494 unregister_reboot_notifier(&esb_notifier);
496 pci_release_region(esb_pci, 0);
497 pci_disable_device(esb_pci);
498 pci_dev_put(esb_pci);
501 module_init(watchdog_init);
502 module_exit(watchdog_cleanup);
504 MODULE_AUTHOR("Ross Biro and David Härdeman");
505 MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
506 MODULE_LICENSE("GPL");
507 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);