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. * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
* http://www.kernelconcepts.de * http://www.kernelconcepts.de
...@@ -17,12 +17,14 @@ ...@@ -17,12 +17,14 @@
* developed for * developed for
* Jentro AG, Haar/Munich (Germany) * 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> * based on softdog.c by Alan Cox <alan@redhat.com>
* *
* The TCO timer is implemented in the 82801AA (82801AB) chip, * The TCO timer is implemented in the following I/O controller hubs:
* see intel documentation from http://developer.intel.com, * (See the intel documentation on http://developer.intel.com.)
* order number 290655-003 * 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 * 20000710 Nils Faerber
* Initial Version 0.01 * Initial Version 0.01
...@@ -31,6 +33,9 @@ ...@@ -31,6 +33,9 @@
* 20011214 Matt Domsch <Matt_Domsch@dell.com> * 20011214 Matt Domsch <Matt_Domsch@dell.com>
* 0.03 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT * 0.03 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
* Didn't add timeout option as i810_margin already exists. * 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> #include <linux/module.h>
...@@ -49,13 +54,13 @@ ...@@ -49,13 +54,13 @@
#include "i810-tco.h" #include "i810-tco.h"
/* Just in case that the PCI vendor and device IDs are not yet defined */ /* Module and version information */
#ifndef PCI_DEVICE_ID_INTEL_82801AA_0 #define TCO_VERSION "0.04"
#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define TCO_MODULE_NAME "i810 TCO timer"
#endif #define TCO_DRIVER_NAME TCO_MODULE_NAME " , " TCO_VERSION
/* Default expire timeout */ /* 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 unsigned int ACPIBASE;
static spinlock_t tco_lock; /* Guards the hardware */ static spinlock_t tco_lock; /* Guards the hardware */
...@@ -63,7 +68,7 @@ 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 */ static int i810_margin = TIMER_MARGIN; /* steps of 0.6sec */
MODULE_PARM (i810_margin, "i"); 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 #ifdef CONFIG_WATCHDOG_NOWAYOUT
...@@ -84,7 +89,7 @@ static int timer_alive; ...@@ -84,7 +89,7 @@ static int timer_alive;
static int boot_status; static int boot_status;
/* /*
* Some i810 specific functions * Some TCO specific functions
*/ */
...@@ -135,7 +140,7 @@ static int tco_timer_settimer (unsigned char tmrval) ...@@ -135,7 +140,7 @@ static int tco_timer_settimer (unsigned char tmrval)
/* from the specs: */ /* from the specs: */
/* "Values of 0h-3h are ignored and should not be attempted" */ /* "Values of 0h-3h are ignored and should not be attempted" */
if (tmrval > 0x3f || tmrval < 0x03) if (tmrval > 0x3f || tmrval < 0x04)
return -1; return -1;
spin_lock(&tco_lock); spin_lock(&tco_lock);
...@@ -226,8 +231,10 @@ static ssize_t i810tco_write (struct file *file, const char *data, ...@@ -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, static int i810tco_ioctl (struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
int new_margin, u_margin;
static struct watchdog_info ident = { static struct watchdog_info ident = {
0, WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
0, 0,
"i810 TCO timer" "i810 TCO timer"
}; };
...@@ -247,6 +254,19 @@ static int i810tco_ioctl (struct inode *inode, struct file *file, ...@@ -247,6 +254,19 @@ static int i810tco_ioctl (struct inode *inode, struct file *file,
case WDIOC_KEEPALIVE: case WDIOC_KEEPALIVE:
tco_timer_reload (); tco_timer_reload ();
return 0; 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 = { ...@@ -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_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_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_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, }, { 0, },
}; };
MODULE_DEVICE_TABLE (pci, i810tco_pci_tbl); MODULE_DEVICE_TABLE (pci, i810tco_pci_tbl);
...@@ -297,7 +319,7 @@ static unsigned char i810tco_getdevice (void) ...@@ -297,7 +319,7 @@ static unsigned char i810tco_getdevice (void)
ACPIBASE = badr; ACPIBASE = badr;
/* Something's wrong here, ACPIBASE has to be set */ /* Something's wrong here, ACPIBASE has to be set */
if (badr == 0x0001 || badr == 0x0000) { 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; return 0;
} }
/* /*
...@@ -309,7 +331,7 @@ static unsigned char i810tco_getdevice (void) ...@@ -309,7 +331,7 @@ static unsigned char i810tco_getdevice (void)
pci_write_config_byte (i810tco_pci, 0xd4, val1); pci_write_config_byte (i810tco_pci, 0xd4, val1);
pci_read_config_byte (i810tco_pci, 0xd4, &val1); pci_read_config_byte (i810tco_pci, 0xd4, &val1);
if (val1 & 0x02) { 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 */ return 0; /* Cannot reset NO_REBOOT bit */
} }
} }
...@@ -346,22 +368,22 @@ static int __init watchdog_init (void) ...@@ -346,22 +368,22 @@ static int __init watchdog_init (void)
if (!i810tco_getdevice () || i810tco_pci == NULL) if (!i810tco_getdevice () || i810tco_pci == NULL)
return -ENODEV; return -ENODEV;
if (!request_region (TCOBASE, 0x10, "i810 TCO")) { if (!request_region (TCOBASE, 0x10, "i810 TCO")) {
printk (KERN_ERR printk (KERN_ERR TCO_MODULE_NAME
"i810 TCO timer: I/O address 0x%04x already in use\n", ": I/O address 0x%04x already in use\n",
TCOBASE); TCOBASE);
return -EIO; return -EIO;
} }
if (misc_register (&i810tco_miscdev) != 0) { if (misc_register (&i810tco_miscdev) != 0) {
release_region (TCOBASE, 0x10); 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; return -EIO;
} }
tco_timer_settimer ((unsigned char) i810_margin); tco_timer_settimer ((unsigned char) i810_margin);
tco_timer_reload (); tco_timer_reload ();
printk (KERN_INFO printk (KERN_INFO TCO_DRIVER_NAME
"i810 TCO timer: V0.03, timer margin: %d sec (0x%04x), nowayout: %d\n", ": timer margin: %d sec (0x%04x)\n",
(int) (i810_margin * 6 / 10), TCOBASE, nowayout); (int) (i810_margin * 6 / 10), TCOBASE);
return 0; 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. * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
* http://www.kernelconcepts.de * http://www.kernelconcepts.de
...@@ -17,12 +17,14 @@ ...@@ -17,12 +17,14 @@
* developed for * developed for
* Jentro AG, Haar/Munich (Germany) * 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> * based on softdog.c by Alan Cox <alan@redhat.com>
* *
* The TCO timer is implemented in the 82801AA (82801AB) chip, * The TCO timer is implemented in the following I/O controller hubs:
* see intel documentation from http://developer.intel.com, * (See the intel documentation on http://developer.intel.com.)
* order number 290655-003 * 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 * 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