diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-02-11 16:37:34 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2009-02-11 16:37:34 +1100 |
commit | 4cb847bb4ac2cb849f7412d00893e9d2e0c44600 (patch) | |
tree | 23402125c9a7b480f664b455362e03ac15cdb2bf | |
parent | d803fdca515bdd7c3a64ad599ee73adcb9d2291e (diff) | |
parent | d3e2000d218824ca49efa6c5c427ee7b0ea77a78 (diff) |
Merge commit 'watchdog/master'
-rw-r--r-- | drivers/watchdog/Kconfig | 2 | ||||
-rw-r--r-- | drivers/watchdog/cpwd.c | 20 | ||||
-rw-r--r-- | drivers/watchdog/davinci_wdt.c | 45 | ||||
-rw-r--r-- | drivers/watchdog/iTCO_vendor_support.c | 32 | ||||
-rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 35 | ||||
-rw-r--r-- | drivers/watchdog/pcwd_usb.c | 4 | ||||
-rw-r--r-- | drivers/watchdog/riowd.c | 15 | ||||
-rw-r--r-- | drivers/watchdog/w83697ug_wdt.c | 21 |
8 files changed, 101 insertions, 73 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 316ee964b945..c7352f7195ee 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -406,7 +406,7 @@ config ITCO_WDT ---help--- Hardware driver for the intel TCO timer based watchdog devices. These drivers are included in the Intel 82801 I/O Controller - Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB + Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB controller hub. The TCO (Total Cost of Ownership) timer is a watchdog timer diff --git a/drivers/watchdog/cpwd.c b/drivers/watchdog/cpwd.c index 084dfe9cecfb..261790afd65b 100644 --- a/drivers/watchdog/cpwd.c +++ b/drivers/watchdog/cpwd.c @@ -400,8 +400,7 @@ static int cpwd_release(struct inode *inode, struct file *file) return 0; } -static int cpwd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long cpwd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { static struct watchdog_info info = { .options = WDIOF_SETTIMEOUT, @@ -409,6 +408,7 @@ static int cpwd_ioctl(struct inode *inode, struct file *file, .identity = DRIVER_NAME, }; void __user *argp = (void __user *)arg; + struct inode *inode = file->f_path.dentry->d_inode; int index = iminor(inode) - WD0_MINOR; struct cpwd *p = cpwd_device; int setopt = 0; @@ -481,7 +481,7 @@ static long cpwd_compat_ioctl(struct file *file, unsigned int cmd, case WIOCSTOP: case WIOCGSTAT: lock_kernel(); - rval = cpwd_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); + rval = cpwd_ioctl(file, cmd, arg); unlock_kernel(); break; @@ -515,13 +515,13 @@ static ssize_t cpwd_read(struct file * file, char __user *buffer, } static const struct file_operations cpwd_fops = { - .owner = THIS_MODULE, - .ioctl = cpwd_ioctl, - .compat_ioctl = cpwd_compat_ioctl, - .open = cpwd_open, - .write = cpwd_write, - .read = cpwd_read, - .release = cpwd_release, + .owner = THIS_MODULE, + .unlocked_ioctl = cpwd_ioctl, + .compat_ioctl = cpwd_compat_ioctl, + .open = cpwd_open, + .write = cpwd_write, + .read = cpwd_read, + .release = cpwd_release, }; static int __devinit cpwd_probe(struct of_device *op, diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 2e1360286732..c51d0b0ea0c4 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c @@ -24,7 +24,7 @@ #include <linux/spinlock.h> #include <linux/uaccess.h> #include <linux/io.h> -#include <mach/hardware.h> +#include <linux/device.h> #define MODULE_NAME "DAVINCI-WDT: " @@ -75,9 +75,9 @@ static void wdt_service(void) spin_lock(&io_lock); /* put watchdog in service state */ - davinci_writel(WDKEY_SEQ0, wdt_base + WDTCR); + iowrite32(WDKEY_SEQ0, wdt_base + WDTCR); /* put watchdog in active state */ - davinci_writel(WDKEY_SEQ1, wdt_base + WDTCR); + iowrite32(WDKEY_SEQ1, wdt_base + WDTCR); spin_unlock(&io_lock); } @@ -90,29 +90,29 @@ static void wdt_enable(void) spin_lock(&io_lock); /* disable, internal clock source */ - davinci_writel(0, wdt_base + TCR); + iowrite32(0, wdt_base + TCR); /* reset timer, set mode to 64-bit watchdog, and unreset */ - davinci_writel(0, wdt_base + TGCR); + iowrite32(0, wdt_base + TGCR); tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET; - davinci_writel(tgcr, wdt_base + TGCR); + iowrite32(tgcr, wdt_base + TGCR); /* clear counter regs */ - davinci_writel(0, wdt_base + TIM12); - davinci_writel(0, wdt_base + TIM34); + iowrite32(0, wdt_base + TIM12); + iowrite32(0, wdt_base + TIM34); /* set timeout period */ timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) & 0xffffffff); - davinci_writel(timer_margin, wdt_base + PRD12); + iowrite32(timer_margin, wdt_base + PRD12); timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) >> 32); - davinci_writel(timer_margin, wdt_base + PRD34); + iowrite32(timer_margin, wdt_base + PRD34); /* enable run continuously */ - davinci_writel(ENAMODE12_PERIODIC, wdt_base + TCR); + iowrite32(ENAMODE12_PERIODIC, wdt_base + TCR); /* Once the WDT is in pre-active state write to * TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are * write protected (except for the WDKEY field) */ /* put watchdog in pre-active state */ - davinci_writel(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR); + iowrite32(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR); /* put watchdog in active state */ - davinci_writel(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR); + iowrite32(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR); spin_unlock(&io_lock); } @@ -197,17 +197,16 @@ static int davinci_wdt_probe(struct platform_device *pdev) { int ret = 0, size; struct resource *res; + struct device *dev = &pdev->dev; if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) heartbeat = DEFAULT_HEARTBEAT; - printk(KERN_INFO MODULE_NAME - "DaVinci Watchdog Timer: heartbeat %d sec\n", heartbeat); + dev_info(dev, "heartbeat %d sec\n", heartbeat); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { - printk(KERN_INFO MODULE_NAME - "failed to get memory region resource\n"); + dev_err(dev, "failed to get memory region resource\n"); return -ENOENT; } @@ -215,20 +214,26 @@ static int davinci_wdt_probe(struct platform_device *pdev) wdt_mem = request_mem_region(res->start, size, pdev->name); if (wdt_mem == NULL) { - printk(KERN_INFO MODULE_NAME "failed to get memory region\n"); + dev_err(dev, "failed to get memory region\n"); return -ENOENT; } - wdt_base = (void __iomem *)(res->start); + + wdt_base = ioremap(res->start, size); + if (!wdt_base) { + dev_err(dev, "failed to map memory region\n"); + return -ENOMEM; + } ret = misc_register(&davinci_wdt_miscdev); if (ret < 0) { - printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); + dev_err(dev, "cannot register misc device\n"); release_resource(wdt_mem); kfree(wdt_mem); } else { set_bit(WDT_DEVICE_INITED, &wdt_status); } + iounmap(wdt_base); return ret; } diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c index 2474ebca88f6..d8264ad0be41 100644 --- a/drivers/watchdog/iTCO_vendor_support.c +++ b/drivers/watchdog/iTCO_vendor_support.c @@ -1,7 +1,7 @@ /* * intel TCO vendor specific watchdog driver support * - * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>. + * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_vendor_support" -#define DRV_VERSION "1.02" +#define DRV_VERSION "1.03" #define PFX DRV_NAME ": " /* Includes */ @@ -77,6 +77,26 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=0 (n * 20.6 seconds. */ +static void supermicro_old_pre_start(unsigned long acpibase) +{ + unsigned long val32; + + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); /* Needed to activate watchdog */ +} + +static void supermicro_old_pre_stop(unsigned long acpibase) +{ + unsigned long val32; + + /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ + val32 = inl(SMI_EN); + val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ + outl(val32, SMI_EN); /* Needed to deactivate watchdog */ +} + static void supermicro_old_pre_keepalive(unsigned long acpibase) { /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ @@ -228,14 +248,18 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) void iTCO_vendor_pre_start(unsigned long acpibase, unsigned int heartbeat) { - if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_OLD_BOARD) + supermicro_old_pre_start(acpibase); + else if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_start(heartbeat); } EXPORT_SYMBOL(iTCO_vendor_pre_start); void iTCO_vendor_pre_stop(unsigned long acpibase) { - if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_OLD_BOARD) + supermicro_old_pre_stop(acpibase); + else if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_stop(); } EXPORT_SYMBOL(iTCO_vendor_pre_stop); diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 5b395a4ddfdf..352334947ea3 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -1,7 +1,7 @@ /* - * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) + * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) * - * (c) Copyright 2006-2008 Wim Van Sebroeck <wim@iguana.be>. + * (c) Copyright 2006-2009 Wim Van Sebroeck <wim@iguana.be>. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -63,7 +63,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_wdt" -#define DRV_VERSION "1.04" +#define DRV_VERSION "1.05" #define PFX DRV_NAME ": " /* Includes */ @@ -236,16 +236,16 @@ MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); /* Address definitions for the TCO */ /* TCO base address */ -#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 +#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* SMI Control and Enable Register */ -#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 +#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ -#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ -#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ -#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ -#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ +#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ +#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ +#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ +#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ #define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ #define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ #define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ @@ -338,7 +338,6 @@ static int iTCO_wdt_unset_NO_REBOOT_bit(void) static int iTCO_wdt_start(void) { unsigned int val; - unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -351,11 +350,6 @@ static int iTCO_wdt_start(void) return -EIO; } - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); - /* Force the timer to its reload value by writing to the TCO_RLD register */ if (iTCO_wdt_private.iTCO_version == 2) @@ -378,7 +372,6 @@ static int iTCO_wdt_start(void) static int iTCO_wdt_stop(void) { unsigned int val; - unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -390,11 +383,6 @@ static int iTCO_wdt_stop(void) outw(val, TCO1_CNT); val = inw(TCO1_CNT); - /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ - val32 = inl(SMI_EN); - val32 |= 0x00002000; - outl(val32, SMI_EN); - /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ iTCO_wdt_set_NO_REBOOT_bit(); @@ -649,6 +637,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, int ret; u32 base_address; unsigned long RCBA; + unsigned long val32; /* * Find the ACPI/PM base I/O address which is the base @@ -695,6 +684,10 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, ret = -EIO; goto out; } + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index afb089695da8..b5320a8e7451 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -609,9 +609,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi /* check out the endpoint: it has to be Interrupt & IN */ endpoint = &iface_desc->endpoint[0].desc; - if (!((endpoint->bEndpointAddress & USB_DIR_IN) && - ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_INT))) { + if (!usb_endpoint_is_int_in(endpoint)) { /* we didn't find a Interrupt endpoint with direction IN */ printk(KERN_ERR PFX "Couldn't find an INTR & IN endpoint\n"); return -ENODEV; diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c index 09cb1833ea27..01cc7e39d92f 100644 --- a/drivers/watchdog/riowd.c +++ b/drivers/watchdog/riowd.c @@ -86,8 +86,7 @@ static int riowd_release(struct inode *inode, struct file *filp) return 0; } -static int riowd_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long riowd_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { static struct watchdog_info info = { .options = WDIOF_SETTIMEOUT, @@ -160,12 +159,12 @@ static ssize_t riowd_write(struct file *file, const char __user *buf, size_t cou } static const struct file_operations riowd_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .ioctl = riowd_ioctl, - .open = riowd_open, - .write = riowd_write, - .release = riowd_release, + .owner = THIS_MODULE, + .llseek = no_llseek, + .unlocked_ioctl = riowd_ioctl, + .open = riowd_open, + .write = riowd_write, + .release = riowd_release, }; static struct miscdevice riowd_miscdev = { diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c index ada8ad82d993..6972c0a1e4d6 100644 --- a/drivers/watchdog/w83697ug_wdt.c +++ b/drivers/watchdog/w83697ug_wdt.c @@ -79,7 +79,7 @@ MODULE_PARM_DESC(nowayout, (same as EFER) */ #define WDT_EFDR (WDT_EFIR+1) /* Extended Function Data Register */ -static void w83697ug_select_wd_register(void) +static int w83697ug_select_wd_register(void) { unsigned char c; unsigned char version; @@ -102,7 +102,7 @@ static void w83697ug_select_wd_register(void) } else { printk(KERN_ERR PFX "No W83697UG/UF could be found\n"); - return; + return -ENODEV; } outb_p(0x07, WDT_EFER); /* point to logical device number reg */ @@ -110,6 +110,8 @@ static void w83697ug_select_wd_register(void) outb_p(0x30, WDT_EFER); /* select CR30 */ c = inb_p(WDT_EFDR); outb_p(c || 0x01, WDT_EFDR); /* set bit 0 to activate GPIO2 */ + + return 0; } static void w83697ug_unselect_wd_register(void) @@ -117,11 +119,14 @@ static void w83697ug_unselect_wd_register(void) outb_p(0xAA, WDT_EFER); /* Leave extended function mode */ } -static void w83697ug_init(void) +static int w83697ug_init(void) { + int ret; unsigned char t; - w83697ug_select_wd_register(); + ret = w83697ug_select_wd_register(); + if (ret != 0) + return ret; outb_p(0xF6, WDT_EFER); /* Select CRF6 */ t = inb_p(WDT_EFDR); /* read CRF6 */ @@ -137,13 +142,15 @@ static void w83697ug_init(void) outb_p(t, WDT_EFDR); /* Write back to CRF5 */ w83697ug_unselect_wd_register(); + return 0; } static void wdt_ctrl(int timeout) { spin_lock(&io_lock); - w83697ug_select_wd_register(); + if (w83697ug_select_wd_register() < 0) + return; outb_p(0xF4, WDT_EFER); /* Select CRF4 */ outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ @@ -347,7 +354,9 @@ static int __init wdt_init(void) goto out; } - w83697ug_init(); + ret = w83697ug_init(); + if (ret != 0) + goto unreg_regions; ret = register_reboot_notifier(&wdt_notifier); if (ret != 0) { |