Commit 39c84c66 authored by Wim Van Sebroeck's avatar Wim Van Sebroeck

[PATCH] 2.5.13 - i8xx series chipsets patches

i810-tco: Merge changes of the 2.4 kernel into the i810-tco module. Changes included are:
Support for 82801CA(M) chipset, timer margin needs to be > 3, support for WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT.
parent 9c8471d5
/*
* i810-tco 0.03: TCO timer driver for i810 chipsets
* i810-tco 0.04: TCO timer driver for i8xx chipsets
*
* (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
* http://www.kernelconcepts.de
......@@ -17,12 +17,14 @@
* developed for
* Jentro AG, Haar/Munich (Germany)
*
* TCO timer driver for i810/i815 chipsets
* TCO timer driver for i8xx chipsets
* based on softdog.c by Alan Cox <alan@redhat.com>
*
* The TCO timer is implemented in the 82801AA (82801AB) chip,
* see intel documentation from http://developer.intel.com,
* order number 290655-003
* The TCO timer is implemented in the following I/O controller hubs:
* (See the intel documentation on http://developer.intel.com.)
* 82801AA & 82801AB chip : document number 290655-003, 290677-004,
* 82801BA & 82801BAM chip : document number 290687-002, 298242-005,
* 82801CA & 82801CAM chip : document number 290716-001, 290718-001
*
* 20000710 Nils Faerber
* Initial Version 0.01
......@@ -31,6 +33,9 @@
* 20011214 Matt Domsch <Matt_Domsch@dell.com>
* 0.03 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
* Didn't add timeout option as i810_margin already exists.
* 20020224 Joel Becker, Wim Van Sebroeck
* 0.04 Support for 82801CA(M) chipset, timer margin needs to be > 3,
* add support for WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT.
*/
#include <linux/module.h>
......@@ -49,13 +54,13 @@
#include "i810-tco.h"
/* Just in case that the PCI vendor and device IDs are not yet defined */
#ifndef PCI_DEVICE_ID_INTEL_82801AA_0
#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
#endif
/* Module and version information */
#define TCO_VERSION "0.04"
#define TCO_MODULE_NAME "i810 TCO timer"
#define TCO_DRIVER_NAME TCO_MODULE_NAME " , " TCO_VERSION
/* Default expire timeout */
#define TIMER_MARGIN 50 /* steps of 0.6sec, 2<n<64. Default is 30 seconds */
#define TIMER_MARGIN 50 /* steps of 0.6sec, 3<n<64. Default is 30 seconds */
static unsigned int ACPIBASE;
static spinlock_t tco_lock; /* Guards the hardware */
......@@ -63,7 +68,7 @@ static spinlock_t tco_lock; /* Guards the hardware */
static int i810_margin = TIMER_MARGIN; /* steps of 0.6sec */
MODULE_PARM (i810_margin, "i");
MODULE_PARM_DESC(i810_margin, "Watchdog timeout in steps of 0.6sec, 2<n<64. Default = 50 (30 seconds)");
MODULE_PARM_DESC(i810_margin, "Watchdog timeout in steps of 0.6sec, 3<n<64. Default = 50 (30 seconds)");
#ifdef CONFIG_WATCHDOG_NOWAYOUT
......@@ -84,7 +89,7 @@ static int timer_alive;
static int boot_status;
/*
* Some i810 specific functions
* Some TCO specific functions
*/
......@@ -135,7 +140,7 @@ static int tco_timer_settimer (unsigned char tmrval)
/* from the specs: */
/* "Values of 0h-3h are ignored and should not be attempted" */
if (tmrval > 0x3f || tmrval < 0x03)
if (tmrval > 0x3f || tmrval < 0x04)
return -1;
spin_lock(&tco_lock);
......@@ -226,8 +231,10 @@ static ssize_t i810tco_write (struct file *file, const char *data,
static int i810tco_ioctl (struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int new_margin, u_margin;
static struct watchdog_info ident = {
0,
WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
0,
"i810 TCO timer"
};
......@@ -247,6 +254,19 @@ static int i810tco_ioctl (struct inode *inode, struct file *file,
case WDIOC_KEEPALIVE:
tco_timer_reload ();
return 0;
case WDIOC_SETTIMEOUT:
if (get_user(u_margin, (int *) arg))
return -EFAULT;
new_margin = (u_margin * 10 + 5) / 6;
if ((new_margin < 4) || (new_margin > 63))
return -EINVAL;
if (tco_timer_settimer((unsigned char)new_margin))
return -EINVAL;
i810_margin = new_margin;
tco_timer_reload();
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user((int)(i810_margin * 6 / 10), (int *) arg);
}
}
......@@ -263,6 +283,8 @@ static struct pci_device_id i810tco_pci_tbl[] __initdata = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, },
};
MODULE_DEVICE_TABLE (pci, i810tco_pci_tbl);
......@@ -297,7 +319,7 @@ static unsigned char i810tco_getdevice (void)
ACPIBASE = badr;
/* Something's wrong here, ACPIBASE has to be set */
if (badr == 0x0001 || badr == 0x0000) {
printk (KERN_ERR "i810tco init: failed to get TCOBASE address\n");
printk (KERN_ERR TCO_MODULE_NAME " init: failed to get TCOBASE address\n");
return 0;
}
/*
......@@ -309,7 +331,7 @@ static unsigned char i810tco_getdevice (void)
pci_write_config_byte (i810tco_pci, 0xd4, val1);
pci_read_config_byte (i810tco_pci, 0xd4, &val1);
if (val1 & 0x02) {
printk (KERN_ERR "i810tco init: failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
printk (KERN_ERR TCO_MODULE_NAME " init: failed to reset NO_REBOOT flag, reboot disabled by hardware\n");
return 0; /* Cannot reset NO_REBOOT bit */
}
}
......@@ -346,22 +368,22 @@ static int __init watchdog_init (void)
if (!i810tco_getdevice () || i810tco_pci == NULL)
return -ENODEV;
if (!request_region (TCOBASE, 0x10, "i810 TCO")) {
printk (KERN_ERR
"i810 TCO timer: I/O address 0x%04x already in use\n",
printk (KERN_ERR TCO_MODULE_NAME
": I/O address 0x%04x already in use\n",
TCOBASE);
return -EIO;
}
if (misc_register (&i810tco_miscdev) != 0) {
release_region (TCOBASE, 0x10);
printk (KERN_ERR "i810 TCO timer: cannot register miscdev\n");
printk (KERN_ERR TCO_MODULE_NAME ": cannot register miscdev\n");
return -EIO;
}
tco_timer_settimer ((unsigned char) i810_margin);
tco_timer_reload ();
printk (KERN_INFO
"i810 TCO timer: V0.03, timer margin: %d sec (0x%04x), nowayout: %d\n",
(int) (i810_margin * 6 / 10), TCOBASE, nowayout);
printk (KERN_INFO TCO_DRIVER_NAME
": timer margin: %d sec (0x%04x)\n",
(int) (i810_margin * 6 / 10), TCOBASE);
return 0;
}
......
/*
* i810-tco 0.02: TCO timer driver for i810 chipsets
* i810-tco 0.04: TCO timer driver for i8xx chipsets
*
* (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
* http://www.kernelconcepts.de
......@@ -17,12 +17,14 @@
* developed for
* Jentro AG, Haar/Munich (Germany)
*
* TCO timer driver for i810 chipsets
* TCO timer driver for i8xx chipsets
* based on softdog.c by Alan Cox <alan@redhat.com>
*
* The TCO timer is implemented in the 82801AA (82801AB) chip,
* see intel documentation from http://developer.intel.com,
* order number 290655-003
* The TCO timer is implemented in the following I/O controller hubs:
* (See the intel documentation on http://developer.intel.com.)
* 82801AA & 82801AB chip : document number 290655-003, 290677-004,
* 82801BA & 82801BAM chip : document number 290687-002, 298242-005,
* 82801CA & 82801CAM chip : document number 290716-001, 290718-001
*
* For history see i810-tco.c
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment