Merge git://www.linux-watchdog.org/linux-watchdog
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 May 2012 22:42:42 +0000 (15:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 May 2012 22:42:42 +0000 (15:42 -0700)
Pull first set of watchdog updates from Wim Van Sebroeck:
 "This pull contains:

   - The removal of ixp2000_wdt
   - The addition of ie6xx_wdt
   - Some documentation fixes
   - Small fixes and improvements

  (Note: Part 2 will contain generic watchdog core changes + conversion
  of some more drivers)"

* git://www.linux-watchdog.org/linux-watchdog:
  Documentation/watchdog: Fix the file descriptor leak when no cmdline arg given
  Documentation/watchdog: close the fd when cmdline arg given
  Documentation/watchdog: Fix a small typo
  watchdog: s3c2410_wdt: Set timeout to actually achieved timeout
  watchdog: wm831x: Convert to gpio_request_one()
  watchdog: via_wdt: depends on PCI
  watchdog: ie6xx_wdt needs io.h
  watchdog: ie6xx_wdt.c: fix printk format warning
  watchdog: Add watchdog driver for Intel Atom E6XX
  watchdog: it87_wdt: Add support for IT8728F watchdog.
  watchdog: i6300esb: don't depend on X86
  watchdog: Use module_pci_driver
  watchdog: sch311x_wdt.c: Remove RESGEN
  watchdog: s3c2410-wdt: Use of_match_ptr().
  watchdog: Device tree support for pnx4008-wdt
  watchdog: ar7_wdt.c: use devm_request_and_ioremap
  watchdog: remove ixp2000 driver
  watchdog: sp5100_tco.c: quiet sparse noise about using plain integer was NULL pointer

19 files changed:
Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt [new file with mode: 0644]
Documentation/watchdog/src/watchdog-test.c
Documentation/watchdog/watchdog-kernel-api.txt
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/ar7_wdt.c
drivers/watchdog/hpwdt.c
drivers/watchdog/i6300esb.c
drivers/watchdog/ie6xx_wdt.c [new file with mode: 0644]
drivers/watchdog/it87_wdt.c
drivers/watchdog/ixp2000_wdt.c [deleted file]
drivers/watchdog/pcwd_pci.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/s3c2410_wdt.c
drivers/watchdog/sch311x_wdt.c
drivers/watchdog/sp5100_tco.c
drivers/watchdog/via_wdt.c
drivers/watchdog/wdt_pci.c
drivers/watchdog/wm831x_wdt.c

diff --git a/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt b/Documentation/devicetree/bindings/watchdog/pnx4008-wdt.txt
new file mode 100644 (file)
index 0000000..7c7f688
--- /dev/null
@@ -0,0 +1,13 @@
+* NXP PNX watchdog timer
+
+Required properties:
+- compatible: must be "nxp,pnx4008-wdt"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+Example:
+
+       watchdog@4003C000 {
+               compatible = "nxp,pnx4008-wdt";
+               reg = <0x4003C000 0x1000>;
+       };
index 63fdc34..73ff5cc 100644 (file)
@@ -7,6 +7,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <sys/ioctl.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
@@ -29,6 +30,14 @@ static void keep_alive(void)
  * The main program.  Run the program with "-d" to disable the card,
  * or "-e" to enable the card.
  */
+
+void term(int sig)
+{
+    close(fd);
+    fprintf(stderr, "Stopping watchdog ticks...\n");
+    exit(0);
+}
+
 int main(int argc, char *argv[])
 {
     int flags;
@@ -47,26 +56,31 @@ int main(int argc, char *argv[])
            ioctl(fd, WDIOC_SETOPTIONS, &flags);
            fprintf(stderr, "Watchdog card disabled.\n");
            fflush(stderr);
-           exit(0);
+           goto end;
        } else if (!strncasecmp(argv[1], "-e", 2)) {
            flags = WDIOS_ENABLECARD;
            ioctl(fd, WDIOC_SETOPTIONS, &flags);
            fprintf(stderr, "Watchdog card enabled.\n");
            fflush(stderr);
-           exit(0);
+           goto end;
        } else {
            fprintf(stderr, "-d to disable, -e to enable.\n");
            fprintf(stderr, "run by itself to tick the card.\n");
            fflush(stderr);
-           exit(0);
+           goto end;
        }
     } else {
        fprintf(stderr, "Watchdog Ticking Away!\n");
        fflush(stderr);
     }
 
+    signal(SIGINT, term);
+
     while(1) {
        keep_alive();
        sleep(1);
     }
+end:
+    close(fd);
+    return 0;
 }
index 227f6cd..25fe430 100644 (file)
@@ -59,7 +59,7 @@ It contains following fields:
 * bootstatus: status of the device after booting (reported with watchdog
   WDIOF_* status bits).
 * driver_data: a pointer to the drivers private data of a watchdog device.
-  This data should only be accessed via the watchdog_set_drvadata and
+  This data should only be accessed via the watchdog_set_drvdata and
   watchdog_get_drvdata routines.
 * status: this field contains a number of status bits that give extra
   information about the status of the device (Like: is the watchdog timer
index edebaf7..a18bf63 100644 (file)
@@ -129,17 +129,6 @@ config 977_WATCHDOG
 
          Not sure? It's safe to say N.
 
-config IXP2000_WATCHDOG
-       tristate "IXP2000 Watchdog"
-       depends on ARCH_IXP2000
-       help
-         Say Y here if to include support for the watchdog timer
-         in the Intel IXP2000(2400, 2800, 2850) network processors.
-         This driver can be built as a module by choosing M. The module
-         will be called ixp2000_wdt.
-
-         Say N if you are unsure.
-
 config IXP4XX_WATCHDOG
        tristate "IXP4xx Watchdog"
        depends on ARCH_IXP4XX
@@ -543,7 +532,7 @@ config WAFER_WDT
 
 config I6300ESB_WDT
        tristate "Intel 6300ESB Timer/Watchdog"
-       depends on X86 && PCI
+       depends on PCI
        ---help---
          Hardware driver for the watchdog timer built into the Intel
          6300ESB controller hub.
@@ -551,6 +540,19 @@ config I6300ESB_WDT
          To compile this driver as a module, choose M here: the
          module will be called i6300esb.
 
+config IE6XX_WDT
+       tristate "Intel Atom E6xx Watchdog"
+       depends on X86 && PCI
+       select WATCHDOG_CORE
+       select MFD_CORE
+       select LPC_SCH
+       ---help---
+         Hardware driver for the watchdog timer built into the Intel
+         Atom E6XX (TunnelCreek) processor.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ie6xx_wdt.
+
 config INTEL_SCU_WATCHDOG
        bool "Intel SCU Watchdog for Mobile Platforms"
        depends on X86_MRST
@@ -607,7 +609,12 @@ config IT87_WDT
        depends on X86 && EXPERIMENTAL
        ---help---
          This is the driver for the hardware watchdog on the ITE IT8702,
-         IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 Super I/O chips.
+         IT8712, IT8716, IT8718, IT8720, IT8721, IT8726 and IT8728
+         Super I/O chips.
+
+         If the driver does not work, then make sure that the game port in
+         the BIOS is enabled.
+
          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.
@@ -780,7 +787,7 @@ config SMSC37B787_WDT
 
 config VIA_WDT
        tristate "VIA Watchdog Timer"
-       depends on X86
+       depends on X86 && PCI
        select WATCHDOG_CORE
        ---help---
        This is the driver for the hardware watchdog timer on VIA
index e8f479a..442bfbe 100644 (file)
@@ -36,7 +36,6 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o
 obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
 obj-$(CONFIG_977_WATCHDOG) += wdt977.o
-obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
 obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
 obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
 obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
@@ -81,6 +80,7 @@ obj-$(CONFIG_IB700_WDT) += ib700wdt.o
 obj-$(CONFIG_IBMASR) += ibmasr.o
 obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
 obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
+obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o
 obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o
 ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y)
 obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o
index 639ae9a..dc30dbd 100644 (file)
@@ -282,29 +282,19 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
                platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
        if (!ar7_regs_wdt) {
                pr_err("could not get registers resource\n");
-               rc = -ENODEV;
-               goto out;
-       }
-
-       if (!request_mem_region(ar7_regs_wdt->start,
-                               resource_size(ar7_regs_wdt), LONGNAME)) {
-               pr_warn("watchdog I/O region busy\n");
-               rc = -EBUSY;
-               goto out;
+               return -ENODEV;
        }
 
-       ar7_wdt = ioremap(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
+       ar7_wdt = devm_request_and_ioremap(&pdev->dev, ar7_regs_wdt);
        if (!ar7_wdt) {
                pr_err("could not ioremap registers\n");
-               rc = -ENXIO;
-               goto out_mem_region;
+               return -ENXIO;
        }
 
        vbus_clk = clk_get(NULL, "vbus");
        if (IS_ERR(vbus_clk)) {
                pr_err("could not get vbus clock\n");
-               rc = PTR_ERR(vbus_clk);
-               goto out_mem_region;
+               return PTR_ERR(vbus_clk);
        }
 
        ar7_wdt_disable_wdt();
@@ -314,24 +304,21 @@ static int __devinit ar7_wdt_probe(struct platform_device *pdev)
        rc = misc_register(&ar7_wdt_miscdev);
        if (rc) {
                pr_err("unable to register misc device\n");
-               goto out_alloc;
+               goto out;
        }
-       goto out;
+       return 0;
 
-out_alloc:
-       iounmap(ar7_wdt);
-out_mem_region:
-       release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
 out:
+       clk_put(vbus_clk);
+       vbus_clk = NULL;
        return rc;
 }
 
 static int __devexit ar7_wdt_remove(struct platform_device *pdev)
 {
        misc_deregister(&ar7_wdt_miscdev);
-       iounmap(ar7_wdt);
-       release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
-
+       clk_put(vbus_clk);
+       vbus_clk = NULL;
        return 0;
 }
 
index 23885f2..2b76381 100644 (file)
@@ -861,16 +861,6 @@ static struct pci_driver hpwdt_driver = {
        .remove = __devexit_p(hpwdt_exit),
 };
 
-static void __exit hpwdt_cleanup(void)
-{
-       pci_unregister_driver(&hpwdt_driver);
-}
-
-static int __init hpwdt_init(void)
-{
-       return pci_register_driver(&hpwdt_driver);
-}
-
 MODULE_AUTHOR("Tom Mingarelli");
 MODULE_DESCRIPTION("hp watchdog driver");
 MODULE_LICENSE("GPL");
@@ -889,5 +879,4 @@ module_param(allow_kdump, int, 0);
 MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
 #endif /* !CONFIG_HPWDT_NMI_DECODING */
 
-module_init(hpwdt_init);
-module_exit(hpwdt_cleanup);
+module_pci_driver(hpwdt_driver);
index 738032a..276877d 100644 (file)
@@ -492,19 +492,7 @@ static struct pci_driver esb_driver = {
        .shutdown       = esb_shutdown,
 };
 
-static int __init watchdog_init(void)
-{
-       return pci_register_driver(&esb_driver);
-}
-
-static void __exit watchdog_cleanup(void)
-{
-       pci_unregister_driver(&esb_driver);
-       pr_info("Watchdog Module Unloaded\n");
-}
-
-module_init(watchdog_init);
-module_exit(watchdog_cleanup);
+module_pci_driver(esb_driver);
 
 MODULE_AUTHOR("Ross Biro and David Härdeman");
 MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
new file mode 100644 (file)
index 0000000..5f0d776
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ *      Intel Atom E6xx Watchdog driver
+ *
+ *      Copyright (C) 2011 Alexander Stein
+ *                <alexander.stein@systec-electronic.com>
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of version 2 of the GNU General
+ *      Public License as published by the Free Software Foundation.
+ *
+ *      This program is distributed in the hope that it will be
+ *      useful, but WITHOUT ANY WARRANTY; without even the implied
+ *      warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ *      PURPOSE.  See the GNU General Public License for more details.
+ *      You should have received a copy of the GNU General Public
+ *      License along with this program; if not, write to the Free
+ *      Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *      Boston, MA  02111-1307, USA.
+ *      The full GNU General Public License is included in this
+ *      distribution in the file called COPYING.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/miscdevice.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/spinlock.h>
+
+#define DRIVER_NAME "ie6xx_wdt"
+
+#define PV1    0x00
+#define PV2    0x04
+
+#define RR0    0x0c
+#define RR1    0x0d
+#define WDT_RELOAD     0x01
+#define WDT_TOUT       0x02
+
+#define WDTCR  0x10
+#define WDT_PRE_SEL    0x04
+#define WDT_RESET_SEL  0x08
+#define WDT_RESET_EN   0x10
+#define WDT_TOUT_EN    0x20
+
+#define DCR    0x14
+
+#define WDTLR  0x18
+#define WDT_LOCK       0x01
+#define WDT_ENABLE     0x02
+#define WDT_TOUT_CNF   0x03
+
+#define MIN_TIME       1
+#define MAX_TIME       (10 * 60) /* 10 minutes */
+#define DEFAULT_TIME   60
+
+static unsigned int timeout = DEFAULT_TIME;
+module_param(timeout, uint, 0);
+MODULE_PARM_DESC(timeout,
+               "Default Watchdog timer setting ("
+               __MODULE_STRING(DEFAULT_TIME) "s)."
+               "The range is from 1 to 600");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+       "Watchdog cannot be stopped once started (default="
+               __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static u8 resetmode = 0x10;
+module_param(resetmode, byte, 0);
+MODULE_PARM_DESC(resetmode,
+       "Resetmode bits: 0x08 warm reset (cold reset otherwise), "
+       "0x10 reset enable, 0x20 disable toggle GPIO[4] (default=0x10)");
+
+static struct {
+       unsigned short sch_wdtba;
+       struct spinlock unlock_sequence;
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *debugfs;
+#endif
+} ie6xx_wdt_data;
+
+/*
+ * This is needed to write to preload and reload registers
+ * struct ie6xx_wdt_data.unlock_sequence must be used
+ * to prevent sequence interrupts
+ */
+static void ie6xx_wdt_unlock_registers(void)
+{
+       outb(0x80, ie6xx_wdt_data.sch_wdtba + RR0);
+       outb(0x86, ie6xx_wdt_data.sch_wdtba + RR0);
+}
+
+static int ie6xx_wdt_ping(struct watchdog_device *wdd)
+{
+       spin_lock(&ie6xx_wdt_data.unlock_sequence);
+       ie6xx_wdt_unlock_registers();
+       outb(WDT_RELOAD, ie6xx_wdt_data.sch_wdtba + RR1);
+       spin_unlock(&ie6xx_wdt_data.unlock_sequence);
+       return 0;
+}
+
+static int ie6xx_wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
+{
+       u32 preload;
+       u64 clock;
+       u8 wdtcr;
+
+       /* Watchdog clock is PCI Clock (33MHz) */
+       clock = 33000000;
+       /* and the preload value is loaded into [34:15] of the down counter */
+       preload = (t * clock) >> 15;
+       /*
+        * Manual states preload must be one less.
+        * Does not wrap as t is at least 1
+        */
+       preload -= 1;
+
+       spin_lock(&ie6xx_wdt_data.unlock_sequence);
+
+       /* Set ResetMode & Enable prescaler for range 10ms to 10 min */
+       wdtcr = resetmode & 0x38;
+       outb(wdtcr, ie6xx_wdt_data.sch_wdtba + WDTCR);
+
+       ie6xx_wdt_unlock_registers();
+       outl(0, ie6xx_wdt_data.sch_wdtba + PV1);
+
+       ie6xx_wdt_unlock_registers();
+       outl(preload, ie6xx_wdt_data.sch_wdtba + PV2);
+
+       ie6xx_wdt_unlock_registers();
+       outb(WDT_RELOAD | WDT_TOUT, ie6xx_wdt_data.sch_wdtba + RR1);
+
+       spin_unlock(&ie6xx_wdt_data.unlock_sequence);
+
+       wdd->timeout = t;
+       return 0;
+}
+
+static int ie6xx_wdt_start(struct watchdog_device *wdd)
+{
+       ie6xx_wdt_set_timeout(wdd, wdd->timeout);
+
+       /* Enable the watchdog timer */
+       spin_lock(&ie6xx_wdt_data.unlock_sequence);
+       outb(WDT_ENABLE, ie6xx_wdt_data.sch_wdtba + WDTLR);
+       spin_unlock(&ie6xx_wdt_data.unlock_sequence);
+
+       return 0;
+}
+
+static int ie6xx_wdt_stop(struct watchdog_device *wdd)
+{
+       if (inb(ie6xx_wdt_data.sch_wdtba + WDTLR) & WDT_LOCK)
+               return -1;
+
+       /* Disable the watchdog timer */
+       spin_lock(&ie6xx_wdt_data.unlock_sequence);
+       outb(0, ie6xx_wdt_data.sch_wdtba + WDTLR);
+       spin_unlock(&ie6xx_wdt_data.unlock_sequence);
+
+       return 0;
+}
+
+static const struct watchdog_info ie6xx_wdt_info = {
+       .identity =     "Intel Atom E6xx Watchdog",
+       .options =      WDIOF_SETTIMEOUT |
+                       WDIOF_MAGICCLOSE |
+                       WDIOF_KEEPALIVEPING,
+};
+
+static const struct watchdog_ops ie6xx_wdt_ops = {
+       .owner =        THIS_MODULE,
+       .start =        ie6xx_wdt_start,
+       .stop =         ie6xx_wdt_stop,
+       .ping =         ie6xx_wdt_ping,
+       .set_timeout =  ie6xx_wdt_set_timeout,
+};
+
+static struct watchdog_device ie6xx_wdt_dev = {
+       .info =         &ie6xx_wdt_info,
+       .ops =          &ie6xx_wdt_ops,
+       .min_timeout =  MIN_TIME,
+       .max_timeout =  MAX_TIME,
+};
+
+#ifdef CONFIG_DEBUG_FS
+
+static int ie6xx_wdt_dbg_show(struct seq_file *s, void *unused)
+{
+       seq_printf(s, "PV1   = 0x%08x\n",
+               inl(ie6xx_wdt_data.sch_wdtba + PV1));
+       seq_printf(s, "PV2   = 0x%08x\n",
+               inl(ie6xx_wdt_data.sch_wdtba + PV2));
+       seq_printf(s, "RR    = 0x%08x\n",
+               inw(ie6xx_wdt_data.sch_wdtba + RR0));
+       seq_printf(s, "WDTCR = 0x%08x\n",
+               inw(ie6xx_wdt_data.sch_wdtba + WDTCR));
+       seq_printf(s, "DCR   = 0x%08x\n",
+               inl(ie6xx_wdt_data.sch_wdtba + DCR));
+       seq_printf(s, "WDTLR = 0x%08x\n",
+               inw(ie6xx_wdt_data.sch_wdtba + WDTLR));
+
+       seq_printf(s, "\n");
+       return 0;
+}
+
+static int ie6xx_wdt_dbg_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, ie6xx_wdt_dbg_show, NULL);
+}
+
+static const struct file_operations ie6xx_wdt_dbg_operations = {
+       .open           = ie6xx_wdt_dbg_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static void __devinit ie6xx_wdt_debugfs_init(void)
+{
+       /* /sys/kernel/debug/ie6xx_wdt */
+       ie6xx_wdt_data.debugfs = debugfs_create_file("ie6xx_wdt",
+               S_IFREG | S_IRUGO, NULL, NULL, &ie6xx_wdt_dbg_operations);
+}
+
+static void __devexit ie6xx_wdt_debugfs_exit(void)
+{
+       debugfs_remove(ie6xx_wdt_data.debugfs);
+}
+
+#else
+static void __devinit ie6xx_wdt_debugfs_init(void)
+{
+}
+
+static void __devexit ie6xx_wdt_debugfs_exit(void)
+{
+}
+#endif
+
+static int __devinit ie6xx_wdt_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       u8 wdtlr;
+       int ret;
+
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (!res)
+               return -ENODEV;
+
+       if (!request_region(res->start, resource_size(res), pdev->name)) {
+               dev_err(&pdev->dev, "Watchdog region 0x%llx already in use!\n",
+                       (u64)res->start);
+               return -EBUSY;
+       }
+
+       ie6xx_wdt_data.sch_wdtba = res->start;
+       dev_dbg(&pdev->dev, "WDT = 0x%X\n", ie6xx_wdt_data.sch_wdtba);
+
+       ie6xx_wdt_dev.timeout = timeout;
+       watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
+
+       spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
+
+       wdtlr = inb(ie6xx_wdt_data.sch_wdtba + WDTLR);
+       if (wdtlr & WDT_LOCK)
+               dev_warn(&pdev->dev,
+                       "Watchdog Timer is Locked (Reg=0x%x)\n", wdtlr);
+
+       ie6xx_wdt_debugfs_init();
+
+       ret = watchdog_register_device(&ie6xx_wdt_dev);
+       if (ret) {
+               dev_err(&pdev->dev,
+                       "Watchdog timer: cannot register device (err =%d)\n",
+                                                                       ret);
+               goto misc_register_error;
+       }
+
+       return 0;
+
+misc_register_error:
+       ie6xx_wdt_debugfs_exit();
+       release_region(res->start, resource_size(res));
+       ie6xx_wdt_data.sch_wdtba = 0;
+       return ret;
+}
+
+static int __devexit ie6xx_wdt_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       ie6xx_wdt_stop(NULL);
+       watchdog_unregister_device(&ie6xx_wdt_dev);
+       ie6xx_wdt_debugfs_exit();
+       release_region(res->start, resource_size(res));
+       ie6xx_wdt_data.sch_wdtba = 0;
+
+       return 0;
+}
+
+static struct platform_driver ie6xx_wdt_driver = {
+       .probe          = ie6xx_wdt_probe,
+       .remove         = __devexit_p(ie6xx_wdt_remove),
+       .driver         = {
+               .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init ie6xx_wdt_init(void)
+{
+       /* Check boot parameters to verify that their initial values */
+       /* are in range. */
+       if ((timeout < MIN_TIME) ||
+           (timeout > MAX_TIME)) {
+               pr_err("Watchdog timer: value of timeout %d (dec) "
+                 "is out of range from %d to %d (dec)\n",
+                 timeout, MIN_TIME, MAX_TIME);
+               return -EINVAL;
+       }
+
+       return platform_driver_register(&ie6xx_wdt_driver);
+}
+
+static void __exit ie6xx_wdt_exit(void)
+{
+       platform_driver_unregister(&ie6xx_wdt_driver);
+}
+
+late_initcall(ie6xx_wdt_init);
+module_exit(ie6xx_wdt_exit);
+
+MODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>");
+MODULE_DESCRIPTION("Intel Atom E6xx Watchdog Device Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:" DRIVER_NAME);
index 8a741bc..d3dcc69 100644 (file)
@@ -12,7 +12,8 @@
  *                 http://www.ite.com.tw/
  *
  *     Support of the watchdog timers, which are available on
- *     IT8702, IT8712, IT8716, IT8718, IT8720, IT8721 and IT8726.
+ *     IT8702, IT8712, IT8716, IT8718, IT8720, IT8721, IT8726
+ *     and IT8728.
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -84,6 +85,7 @@
 #define IT8720_ID      0x8720
 #define IT8721_ID      0x8721
 #define IT8726_ID      0x8726  /* the data sheet suggest wrongly 0x8716 */
+#define IT8728_ID      0x8728
 
 /* GPIO Configuration Registers LDN=0x07 */
 #define WDTCTRL                0x71
@@ -95,7 +97,7 @@
 #define WDT_CIRINT     0x80
 #define WDT_MOUSEINT   0x40
 #define WDT_KYBINT     0x20
-#define WDT_GAMEPORT   0x10 /* not in it8718, it8720, it8721 */
+#define WDT_GAMEPORT   0x10 /* not in it8718, it8720, it8721, it8728 */
 #define WDT_FORCE      0x02
 #define WDT_ZERO       0x01
 
@@ -616,6 +618,7 @@ static int __init it87_wdt_init(void)
        case IT8718_ID:
        case IT8720_ID:
        case IT8721_ID:
+       case IT8728_ID:
                max_units = 65535;
                try_gameport = 0;
                break;
diff --git a/drivers/watchdog/ixp2000_wdt.c b/drivers/watchdog/ixp2000_wdt.c
deleted file mode 100644 (file)
index 3f047a5..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * drivers/char/watchdog/ixp2000_wdt.c
- *
- * Watchdog driver for Intel IXP2000 network processors
- *
- * Adapted from the IXP4xx watchdog driver by Lennert Buytenhek.
- * The original version carries these notices:
- *
- * Author: Deepak Saxena <dsaxena@plexity.net>
- *
- * Copyright 2004 (c) MontaVista, Software, Inc.
- * Based on sa1100 driver, Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/timer.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <linux/uaccess.h>
-#include <mach/hardware.h>
-
-static bool nowayout = WATCHDOG_NOWAYOUT;
-static unsigned int heartbeat = 60;    /* (secs) Default is 1 minute */
-static unsigned long wdt_status;
-static DEFINE_SPINLOCK(wdt_lock);
-
-#define        WDT_IN_USE              0
-#define        WDT_OK_TO_CLOSE         1
-
-static unsigned long wdt_tick_rate;
-
-static void wdt_enable(void)
-{
-       spin_lock(&wdt_lock);
-       ixp2000_reg_write(IXP2000_RESET0, *(IXP2000_RESET0) | WDT_RESET_ENABLE);
-       ixp2000_reg_write(IXP2000_TWDE, WDT_ENABLE);
-       ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
-       ixp2000_reg_write(IXP2000_T4_CTL, TIMER_DIVIDER_256 | TIMER_ENABLE);
-       spin_unlock(&wdt_lock);
-}
-
-static void wdt_disable(void)
-{
-       spin_lock(&wdt_lock);
-       ixp2000_reg_write(IXP2000_T4_CTL, 0);
-       spin_unlock(&wdt_lock);
-}
-
-static void wdt_keepalive(void)
-{
-       spin_lock(&wdt_lock);
-       ixp2000_reg_write(IXP2000_T4_CLD, heartbeat * wdt_tick_rate);
-       spin_unlock(&wdt_lock);
-}
-
-static int ixp2000_wdt_open(struct inode *inode, struct file *file)
-{
-       if (test_and_set_bit(WDT_IN_USE, &wdt_status))
-               return -EBUSY;
-
-       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
-
-       wdt_enable();
-
-       return nonseekable_open(inode, file);
-}
-
-static ssize_t ixp2000_wdt_write(struct file *file, const char *data,
-                                               size_t len, loff_t *ppos)
-{
-       if (len) {
-               if (!nowayout) {
-                       size_t i;
-
-                       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
-
-                       for (i = 0; i != len; i++) {
-                               char c;
-
-                               if (get_user(c, data + i))
-                                       return -EFAULT;
-                               if (c == 'V')
-                                       set_bit(WDT_OK_TO_CLOSE, &wdt_status);
-                       }
-               }
-               wdt_keepalive();
-       }
-
-       return len;
-}
-
-
-static const struct watchdog_info ident = {
-       .options        = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
-                               WDIOF_KEEPALIVEPING,
-       .identity       = "IXP2000 Watchdog",
-};
-
-static long ixp2000_wdt_ioctl(struct file *file, unsigned int cmd,
-                                                       unsigned long arg)
-{
-       int ret = -ENOTTY;
-       int time;
-
-       switch (cmd) {
-       case WDIOC_GETSUPPORT:
-               ret = copy_to_user((struct watchdog_info *)arg, &ident,
-                                  sizeof(ident)) ? -EFAULT : 0;
-               break;
-
-       case WDIOC_GETSTATUS:
-               ret = put_user(0, (int *)arg);
-               break;
-
-       case WDIOC_GETBOOTSTATUS:
-               ret = put_user(0, (int *)arg);
-               break;
-
-       case WDIOC_KEEPALIVE:
-               wdt_enable();
-               ret = 0;
-               break;
-
-       case WDIOC_SETTIMEOUT:
-               ret = get_user(time, (int *)arg);
-               if (ret)
-                       break;
-
-               if (time <= 0 || time > 60) {
-                       ret = -EINVAL;
-                       break;
-               }
-
-               heartbeat = time;
-               wdt_keepalive();
-               /* Fall through */
-
-       case WDIOC_GETTIMEOUT:
-               ret = put_user(heartbeat, (int *)arg);
-               break;
-       }
-
-       return ret;
-}
-
-static int ixp2000_wdt_release(struct inode *inode, struct file *file)
-{
-       if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
-               wdt_disable();
-       else
-               pr_crit("Device closed unexpectedly - timer will not stop\n");
-       clear_bit(WDT_IN_USE, &wdt_status);
-       clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
-
-       return 0;
-}
-
-
-static const struct file_operations ixp2000_wdt_fops = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .write          = ixp2000_wdt_write,
-       .unlocked_ioctl = ixp2000_wdt_ioctl,
-       .open           = ixp2000_wdt_open,
-       .release        = ixp2000_wdt_release,
-};
-
-static struct miscdevice ixp2000_wdt_miscdev = {
-       .minor          = WATCHDOG_MINOR,
-       .name           = "watchdog",
-       .fops           = &ixp2000_wdt_fops,
-};
-
-static int __init ixp2000_wdt_init(void)
-{
-       if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
-               pr_info("Unable to use IXP2000 watchdog due to IXP2800 erratum #25\n");
-               return -EIO;
-       }
-       wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
-       return misc_register(&ixp2000_wdt_miscdev);
-}
-
-static void __exit ixp2000_wdt_exit(void)
-{
-       misc_deregister(&ixp2000_wdt_miscdev);
-}
-
-module_init(ixp2000_wdt_init);
-module_exit(ixp2000_wdt_exit);
-
-MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
-MODULE_DESCRIPTION("IXP2000 Network Processor Watchdog");
-
-module_param(heartbeat, int, 0);
-MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 60s)");
-
-module_param(nowayout, bool, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-
index c891399..ee6900d 100644 (file)
@@ -707,6 +707,7 @@ static int __devinit pcipcwd_card_init(struct pci_dev *pdev,
                goto err_out_disable_device;
        }
 
+       spin_lock_init(&pcipcwd_private.io_lock);
        pcipcwd_private.pdev = pdev;
        pcipcwd_private.io_addr = pci_resource_start(pdev, 0);
 
@@ -814,22 +815,7 @@ static struct pci_driver pcipcwd_driver = {
        .remove         = __devexit_p(pcipcwd_card_exit),
 };
 
-static int __init pcipcwd_init_module(void)
-{
-       spin_lock_init(&pcipcwd_private.io_lock);
-
-       return pci_register_driver(&pcipcwd_driver);
-}
-
-static void __exit pcipcwd_cleanup_module(void)
-{
-       pci_unregister_driver(&pcipcwd_driver);
-
-       pr_info("Watchdog Module Unloaded\n");
-}
-
-module_init(pcipcwd_init_module);
-module_exit(pcipcwd_cleanup_module);
+module_pci_driver(pcipcwd_driver);
 
 MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
 MODULE_DESCRIPTION("Berkshire PCI-PC Watchdog driver");
index 6b8432f..87722e1 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <mach/hardware.h>
 
 /* WatchDog Timer - Chapter 23 Page 207 */
@@ -201,10 +202,19 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id pnx4008_wdt_match[] = {
+       { .compatible = "nxp,pnx4008-wdt" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, pnx4008_wdt_match);
+#endif
+
 static struct platform_driver platform_wdt_driver = {
        .driver = {
                .name = "pnx4008-watchdog",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(pnx4008_wdt_match),
        },
        .probe = pnx4008_wdt_probe,
        .remove = __devexit_p(pnx4008_wdt_remove),
index 04e5a6d..200ece5 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include <mach/map.h>
 
@@ -201,7 +202,7 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou
        writel(count, wdt_base + S3C2410_WTDAT);
        writel(wtcon, wdt_base + S3C2410_WTCON);
 
-       wdd->timeout = timeout;
+       wdd->timeout = (count * divisor) / freq;
 
        return 0;
 }
@@ -503,8 +504,6 @@ static const struct of_device_id s3c2410_wdt_match[] = {
        {},
 };
 MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
-#else
-#define s3c2410_wdt_match NULL
 #endif
 
 static struct platform_driver s3c2410wdt_driver = {
@@ -516,7 +515,7 @@ static struct platform_driver s3c2410wdt_driver = {
        .driver         = {
                .owner  = THIS_MODULE,
                .name   = "s3c2410-wdt",
-               .of_match_table = s3c2410_wdt_match,
+               .of_match_table = of_match_ptr(s3c2410_wdt_match),
        },
 };
 
index bd86f32..f847700 100644 (file)
@@ -41,7 +41,6 @@
 #define DRV_NAME       "sch311x_wdt"
 
 /* Runtime registers */
-#define RESGEN                 0x1d
 #define GP60                   0x47
 #define WDT_TIME_OUT           0x65
 #define WDT_VAL                        0x66
@@ -69,10 +68,6 @@ static unsigned short force_id;
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-static unsigned short therm_trip;
-module_param(therm_trip, ushort, 0);
-MODULE_PARM_DESC(therm_trip, "Should a ThermTrip trigger the reset generator");
-
 #define WATCHDOG_TIMEOUT 60            /* 60 sec default timeout */
 static int timeout = WATCHDOG_TIMEOUT; /* in seconds */
 module_param(timeout, int, 0);
@@ -358,26 +353,16 @@ static struct miscdevice sch311x_wdt_miscdev = {
 static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       unsigned char val;
        int err;
 
        spin_lock_init(&sch311x_wdt_data.io_lock);
 
-       if (!request_region(sch311x_wdt_data.runtime_reg + RESGEN, 1,
-                                                               DRV_NAME)) {
-               dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
-                       sch311x_wdt_data.runtime_reg + RESGEN,
-                       sch311x_wdt_data.runtime_reg + RESGEN);
-               err = -EBUSY;
-               goto exit;
-       }
-
        if (!request_region(sch311x_wdt_data.runtime_reg + GP60, 1, DRV_NAME)) {
                dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
                        sch311x_wdt_data.runtime_reg + GP60,
                        sch311x_wdt_data.runtime_reg + GP60);
                err = -EBUSY;
-               goto exit_release_region;
+               goto exit;
        }
 
        if (!request_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4,
@@ -386,7 +371,7 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
                        sch311x_wdt_data.runtime_reg + WDT_TIME_OUT,
                        sch311x_wdt_data.runtime_reg + WDT_CTRL);
                err = -EBUSY;
-               goto exit_release_region2;
+               goto exit_release_region;
        }
 
        /* Make sure that the watchdog is not running */
@@ -414,24 +399,13 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
        /* Get status at boot */
        sch311x_wdt_get_status(&sch311x_wdt_data.boot_status);
 
-       /* enable watchdog */
-       /* -- Reset Generator --
-        * Bit 0   Enable Watchdog Timer Generation: 0* = Enabled, 1 = Disabled
-        * Bit 1   Thermtrip Source Select: O* = No Source, 1 = Source
-        * Bit 2   WDT2_CTL: WDT input bit
-        * Bit 3-7 Reserved
-        */
-       outb(0, sch311x_wdt_data.runtime_reg + RESGEN);
-       val = therm_trip ? 0x06 : 0x04;
-       outb(val, sch311x_wdt_data.runtime_reg + RESGEN);
-
        sch311x_wdt_miscdev.parent = dev;
 
        err = misc_register(&sch311x_wdt_miscdev);
        if (err != 0) {
                dev_err(dev, "cannot register miscdev on minor=%d (err=%d)\n",
                                                        WATCHDOG_MINOR, err);
-               goto exit_release_region3;
+               goto exit_release_region2;
        }
 
        dev_info(dev,
@@ -440,12 +414,10 @@ static int __devinit sch311x_wdt_probe(struct platform_device *pdev)
 
        return 0;
 
-exit_release_region3:
-       release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
 exit_release_region2:
-       release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
+       release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
 exit_release_region:
-       release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1);
+       release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
        sch311x_wdt_data.runtime_reg = 0;
 exit:
        return err;
@@ -461,7 +433,6 @@ static int __devexit sch311x_wdt_remove(struct platform_device *pdev)
        misc_deregister(&sch311x_wdt_miscdev);
        release_region(sch311x_wdt_data.runtime_reg + WDT_TIME_OUT, 4);
        release_region(sch311x_wdt_data.runtime_reg + GP60, 1);
-       release_region(sch311x_wdt_data.runtime_reg + RESGEN, 1);
        sch311x_wdt_data.runtime_reg = 0;
        return 0;
 }
index 59108e4..ae5e82c 100644 (file)
@@ -313,7 +313,7 @@ static unsigned char __devinit sp5100_tco_setupdevice(void)
        tcobase_phys = val;
 
        tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
-       if (tcobase == 0) {
+       if (!tcobase) {
                pr_err("failed to get tcobase address\n");
                goto unreg_mem_region;
        }
index 465e082..5603e31 100644 (file)
@@ -202,6 +202,9 @@ static int __devinit wdt_probe(struct pci_dev *pdev,
                goto err_out_release;
        }
 
+       if (timeout < 1 || timeout > WDT_TIMEOUT_MAX)
+               timeout = WDT_TIMEOUT;
+
        wdt_dev.timeout = timeout;
        watchdog_set_nowayout(&wdt_dev, nowayout);
        if (readl(wdt_mem) & VIA_WDT_FIRED)
@@ -250,20 +253,7 @@ static struct pci_driver wdt_driver = {
        .remove         = __devexit_p(wdt_remove),
 };
 
-static int __init wdt_init(void)
-{
-       if (timeout < 1 || timeout > WDT_TIMEOUT_MAX)
-               timeout = WDT_TIMEOUT;
-       return pci_register_driver(&wdt_driver);
-}
-
-static void __exit wdt_exit(void)
-{
-       pci_unregister_driver(&wdt_driver);
-}
-
-module_init(wdt_init);
-module_exit(wdt_exit);
+module_pci_driver(wdt_driver);
 
 MODULE_AUTHOR("Marc Vertes");
 MODULE_DESCRIPTION("Driver for watchdog timer on VIA chipset");
index 1c888c7..e32654e 100644 (file)
@@ -739,39 +739,7 @@ static struct pci_driver wdtpci_driver = {
        .remove         = __devexit_p(wdtpci_remove_one),
 };
 
-
-/**
- *     wdtpci_cleanup:
- *
- *     Unload the watchdog. You cannot do this with any file handles open.
- *     If your watchdog is set to continue ticking on close and you unload
- *     it, well it keeps ticking. We won't get the interrupt but the board
- *     will not touch PC memory so all is fine. You just have to load a new
- *     module in xx seconds or reboot.
- */
-
-static void __exit wdtpci_cleanup(void)
-{
-       pci_unregister_driver(&wdtpci_driver);
-}
-
-
-/**
- *     wdtpci_init:
- *
- *     Set up the WDT watchdog board. All we have to do is grab the
- *     resources we require and bitch if anyone beat us to them.
- *     The open() function will actually kick the board off.
- */
-
-static int __init wdtpci_init(void)
-{
-       return pci_register_driver(&wdtpci_driver);
-}
-
-
-module_init(wdtpci_init);
-module_exit(wdtpci_cleanup);
+module_pci_driver(wdtpci_driver);
 
 MODULE_AUTHOR("JP Nollmann, Alan Cox");
 MODULE_DESCRIPTION("Driver for the ICS PCI-WDT500/501 watchdog cards");
index b1815c5..87d66d2 100644 (file)
@@ -247,8 +247,9 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
                reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
 
                if (pdata->update_gpio) {
-                       ret = gpio_request(pdata->update_gpio,
-                                          "Watchdog update");
+                       ret = gpio_request_one(pdata->update_gpio,
+                                              GPIOF_DIR_OUT | GPIOF_INIT_LOW,
+                                              "Watchdog update");
                        if (ret < 0) {
                                dev_err(wm831x->dev,
                                        "Failed to request update GPIO: %d\n",
@@ -256,14 +257,6 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
                                goto err;
                        }
 
-                       ret = gpio_direction_output(pdata->update_gpio, 0);
-                       if (ret != 0) {
-                               dev_err(wm831x->dev,
-                                       "gpio_direction_output returned: %d\n",
-                                       ret);
-                               goto err_gpio;
-                       }
-
                        driver_data->update_gpio = pdata->update_gpio;
 
                        /* Make sure the watchdog takes hardware updates */