From: Zwane Mwaikambo We've had trouble with this driver, it appears to work but the hardware never does the final reboot. I have yet to come across someone with a board which works and don't have personal access to one. So how about scrapping the whole thing. --- /dev/null | 374 --------------------------------- 25-akpm/drivers/char/watchdog/Kconfig | 13 - 25-akpm/drivers/char/watchdog/Makefile | 1 3 files changed, 388 deletions(-) diff -L drivers/char/watchdog/amd7xx_tco.c -puN drivers/char/watchdog/amd7xx_tco.c~remove-amd7saucy_tco /dev/null --- 25/drivers/char/watchdog/amd7xx_tco.c +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,374 +0,0 @@ -/* - * AMD 766/768 TCO Timer Driver - * (c) Copyright 2002 Zwane Mwaikambo - * All Rights Reserved. - * - * Parts from; - * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * The author(s) of this software shall not be held liable for damages - * of any nature resulting due to the use of this software. This - * software is provided AS-IS with no warranties. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define AMDTCO_MODULE_VER "build 20021116" -#define AMDTCO_MODULE_NAME "amd7xx_tco" -#define PFX AMDTCO_MODULE_NAME ": " - -#define MAX_TIMEOUT 38 /* max of 38 seconds, although the system will only - * reset itself after the second timeout */ - -/* pmbase registers */ -#define TCO_RELOAD_REG 0x40 /* bits 0-5 are current count, 6-7 are reserved */ -#define TCO_INITVAL_REG 0x41 /* bits 0-5 are value to load, 6-7 are reserved */ -#define TCO_TIMEOUT_MASK 0x3f -#define TCO_STATUS1_REG 0x44 -#define TCO_STATUS2_REG 0x46 -#define NDTO_STS2 (1 << 1) /* we're interested in the second timeout */ -#define BOOT_STS (1 << 2) /* will be set if NDTO_STS2 was set before reboot */ -#define TCO_CTRL1_REG 0x48 -#define TCO_HALT (1 << 11) -#define NO_REBOOT (1 << 10) /* in DevB:3x48 */ - -static char banner[] __initdata = KERN_INFO PFX AMDTCO_MODULE_VER "\n"; -static int timeout = MAX_TIMEOUT; -static u32 pmbase; /* PMxx I/O base */ -static struct pci_dev *dev; -static struct semaphore open_sem; -static spinlock_t amdtco_lock; /* only for device access */ -static char expect_close; - -module_param(timeout, int, 0); -MODULE_PARM_DESC(timeout, "range is 0-38 seconds, default is 38"); - -#ifdef CONFIG_WATCHDOG_NOWAYOUT -static int nowayout = 1; -#else -static int nowayout = 0; -#endif - -module_param(nowayout, int, 0); -MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); - -static inline u8 seconds_to_ticks(int seconds) -{ - /* the internal timer is stored as ticks which decrement - * every 0.6 seconds */ - return (seconds * 10) / 6; -} - -static inline int ticks_to_seconds(u8 ticks) -{ - return (ticks * 6) / 10; -} - -static inline int amdtco_status(void) -{ - u16 reg; - int status = 0; - - reg = inb(pmbase+TCO_CTRL1_REG); - if ((reg & TCO_HALT) == 0) - status |= WDIOF_KEEPALIVEPING; - - reg = inb(pmbase+TCO_STATUS2_REG); - if (reg & BOOT_STS) - status |= WDIOF_CARDRESET; - - return status; -} - -static inline void amdtco_ping(void) -{ - outb(1, pmbase+TCO_RELOAD_REG); -} - -static inline int amdtco_gettimeout(void) -{ - u8 reg = inb(pmbase+TCO_RELOAD_REG) & TCO_TIMEOUT_MASK; - return ticks_to_seconds(reg); -} - -static inline void amdtco_settimeout(unsigned int timeout) -{ - u8 reg = seconds_to_ticks(timeout) & TCO_TIMEOUT_MASK; - outb(reg, pmbase+TCO_INITVAL_REG); -} - -static inline void amdtco_global_enable(void) -{ - u16 reg; - - spin_lock(&amdtco_lock); - - /* clear NO_REBOOT on DevB:3x48 p97 */ - pci_read_config_word(dev, 0x48, ®); - reg &= ~NO_REBOOT; - pci_write_config_word(dev, 0x48, reg); - - spin_unlock(&amdtco_lock); -} - -static inline void amdtco_enable(void) -{ - u16 reg; - - spin_lock(&amdtco_lock); - reg = inw(pmbase+TCO_CTRL1_REG); - reg &= ~TCO_HALT; - outw(reg, pmbase+TCO_CTRL1_REG); - spin_unlock(&amdtco_lock); -} - -static inline void amdtco_disable(void) -{ - u16 reg; - - spin_lock(&amdtco_lock); - reg = inw(pmbase+TCO_CTRL1_REG); - reg |= TCO_HALT; - outw(reg, pmbase+TCO_CTRL1_REG); - spin_unlock(&amdtco_lock); -} - -static int amdtco_fop_open(struct inode *inode, struct file *file) -{ - if (down_trylock(&open_sem)) - return -EBUSY; - - if (timeout > MAX_TIMEOUT) - timeout = MAX_TIMEOUT; - - amdtco_disable(); - amdtco_settimeout(timeout); - amdtco_global_enable(); - amdtco_enable(); - amdtco_ping(); - printk(KERN_INFO PFX "Watchdog enabled, timeout = %ds of %ds\n", - amdtco_gettimeout(), timeout); - - return 0; -} - - -static int amdtco_fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - int new_timeout; - int tmp; - - static struct watchdog_info ident = { - .options = WDIOF_SETTIMEOUT | WDIOF_CARDRESET, - .identity = "AMD 766/768", - }; - - switch (cmd) { - default: - return -ENOIOCTLCMD; - - case WDIOC_GETSUPPORT: - if (copy_to_user((struct watchdog_info *)arg, &ident, sizeof ident)) - return -EFAULT; - return 0; - - case WDIOC_GETSTATUS: - return put_user(amdtco_status(), (int *)arg); - - case WDIOC_KEEPALIVE: - amdtco_ping(); - return 0; - - case WDIOC_SETTIMEOUT: - if (get_user(new_timeout, (int *)arg)) - return -EFAULT; - - if (new_timeout < 0) - return -EINVAL; - - if (new_timeout > MAX_TIMEOUT) - new_timeout = MAX_TIMEOUT; - - timeout = new_timeout; - amdtco_settimeout(timeout); - /* fall through and return the new timeout */ - - case WDIOC_GETTIMEOUT: - return put_user(amdtco_gettimeout(), (int *)arg); - - case WDIOC_SETOPTIONS: - if (copy_from_user(&tmp, (int *)arg, sizeof tmp)) - return -EFAULT; - - if (tmp & WDIOS_DISABLECARD) - amdtco_disable(); - - if (tmp & WDIOS_ENABLECARD) - amdtco_enable(); - - return 0; - } -} - - -static int amdtco_fop_release(struct inode *inode, struct file *file) -{ - if (expect_close == 42) { - amdtco_disable(); - printk(KERN_INFO PFX "Watchdog disabled\n"); - } else { - amdtco_ping(); - printk(KERN_CRIT PFX "Unexpected close!, timeout in %d seconds\n", timeout); - } - - expect_close = 0; - up(&open_sem); - return 0; -} - - -static ssize_t amdtco_fop_write(struct file *file, const char *data, size_t len, loff_t *ppos) -{ - if (ppos != &file->f_pos) - return -ESPIPE; - - if (len) { - if (!nowayout) { - size_t i; - char c; - expect_close = 0; - - for (i = 0; i != len; i++) { - if (get_user(c, data + i)) - return -EFAULT; - - if (c == 'V') - expect_close = 42; - } - } - amdtco_ping(); - } - - return len; -} - - -static int amdtco_notify_sys(struct notifier_block *this, unsigned long code, void *unused) -{ - if (code == SYS_DOWN || code == SYS_HALT) - amdtco_disable(); - - return NOTIFY_DONE; -} - - -static struct notifier_block amdtco_notifier = -{ - .notifier_call = amdtco_notify_sys, -}; - -static struct file_operations amdtco_fops = -{ - .owner = THIS_MODULE, - .write = amdtco_fop_write, - .ioctl = amdtco_fop_ioctl, - .open = amdtco_fop_open, - .release = amdtco_fop_release, -}; - -static struct miscdevice amdtco_miscdev = -{ - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &amdtco_fops, -}; - -static struct pci_device_id amdtco_pci_tbl[] = { - /* AMD 766 PCI_IDs here */ - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7443, PCI_ANY_ID, PCI_ANY_ID, }, - { 0, }, -}; - -MODULE_DEVICE_TABLE (pci, amdtco_pci_tbl); - -static int __init amdtco_init(void) -{ - int ret; - - sema_init(&open_sem, 1); - spin_lock_init(&amdtco_lock); - - dev = NULL; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (pci_match_device (amdtco_pci_tbl, dev) != NULL) - goto found_one; - } - - return -ENODEV; - -found_one: - - if ((ret = register_reboot_notifier(&amdtco_notifier))) { - printk(KERN_ERR PFX "Unable to register reboot notifier err = %d\n", ret); - goto out_clean; - } - - if ((ret = misc_register(&amdtco_miscdev))) { - printk(KERN_ERR PFX "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); - goto out_unreg_reboot; - } - - pci_read_config_dword(dev, 0x58, &pmbase); - pmbase &= 0x0000FF00; - - if (pmbase == 0) { - printk (KERN_ERR PFX "power management base not set\n"); - ret = -EIO; - goto out_unreg_misc; - } - - /* ret = 0; */ - printk(banner); - goto out_clean; - -out_unreg_misc: - misc_deregister(&amdtco_miscdev); -out_unreg_reboot: - unregister_reboot_notifier(&amdtco_notifier); -out_clean: - return ret; -} - -static void __exit amdtco_exit(void) -{ - misc_deregister(&amdtco_miscdev); - unregister_reboot_notifier(&amdtco_notifier); -} - -module_init(amdtco_init); -module_exit(amdtco_exit); - -MODULE_AUTHOR("Zwane Mwaikambo "); -MODULE_DESCRIPTION("AMD 766/768 TCO Timer Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff -puN drivers/char/watchdog/Kconfig~remove-amd7saucy_tco drivers/char/watchdog/Kconfig --- 25/drivers/char/watchdog/Kconfig~remove-amd7saucy_tco 2004-04-15 18:49:57.009626248 -0700 +++ 25-akpm/drivers/char/watchdog/Kconfig 2004-04-15 18:49:57.014625488 -0700 @@ -143,19 +143,6 @@ config ALIM7101_WDT Most people will say N. -config AMD7XX_TCO - tristate "AMD 766/768 TCO Timer/Watchdog" - depends on WATCHDOG && X86 && PCI - help - This is the driver for the hardware watchdog built in to the - AMD 766/768 chipsets. - This watchdog simply watches your kernel to make sure it doesn't - freeze, and if it does, it reboots your computer after a certain - amount of time. - - You can compile this driver directly into the kernel, or use - it as a module. The module will be called amd7xx_tco. - config SC520_WDT tristate "AMD Elan SC520 processor Watchdog" depends on WATCHDOG && X86 diff -puN drivers/char/watchdog/Makefile~remove-amd7saucy_tco drivers/char/watchdog/Makefile --- 25/drivers/char/watchdog/Makefile~remove-amd7saucy_tco 2004-04-15 18:49:57.011625944 -0700 +++ 25-akpm/drivers/char/watchdog/Makefile 2004-04-15 18:49:57.014625488 -0700 @@ -32,7 +32,6 @@ obj-$(CONFIG_ALIM1535_WDT) += alim1535_w obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o -obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o obj-$(CONFIG_INDYDOG) += indydog.o obj-$(CONFIG_PCIPCWATCHDOG) += pcwd_pci.o obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o _