]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
Merge branches 'sh/wdt', 'sh/pci-express-async' and 'common/serial-rework' into sh...
authorPaul Mundt <lethal@linux-sh.org>
Wed, 26 Jan 2011 09:24:18 +0000 (18:24 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 26 Jan 2011 09:24:18 +0000 (18:24 +0900)
1  2  3 
drivers/watchdog/Kconfig
drivers/watchdog/shwdt.c

diff --combined drivers/watchdog/Kconfig
index 8828d8ffd35310d0877dfce6c936e55f30852096,2e2400e7322e8b0520c570b0920b19a6bb0c6c53,2e2400e7322e8b0520c570b0920b19a6bb0c6c53..faa9127aecaad347712449ed5d784b57255b22c1
@@@@ -73,6 -73,13 -73,13 +73,13 @@@@ config WM8350_WATCHDO
   
   # ARM Architecture
   
+  config ARM_SP805_WATCHDOG
+       tristate "ARM SP805 Watchdog"
+       depends on ARM_AMBA
+       help
+         ARM Primecell SP805 Watchdog timer. This will reboot your system when
+         the timeout is reached.
+  
   config AT91RM9200_WATCHDOG
        tristate "AT91RM9200 watchdog"
        depends on ARCH_AT91RM9200
@@@@ -145,13 -152,19 -152,19 +152,19 @@@@ config KS8695_WATCHDO
          Watchdog timer embedded into KS8695 processor. This will reboot your
          system when the timeout is reached.
   
+  config HAVE_S3C2410_WATCHDOG
+       bool
+       help
+         This will include watchdog timer support for Samsung SoCs. If
+         you want to include watchdog support for any machine, kindly
+         select this in the respective mach-XXXX/Kconfig file.
+  
   config S3C2410_WATCHDOG
        tristate "S3C2410 Watchdog"
-       depends on ARCH_S3C2410
+       depends on ARCH_S3C2410 || HAVE_S3C2410_WATCHDOG
        help
-         Watchdog timer block in the Samsung S3C2410 chips. This will
-         reboot the system when the timer expires with the watchdog
-         enabled.
+         Watchdog timer block in the Samsung SoCs. This will reboot
+         the system when the timer expires with the watchdog enabled.
   
          The driver is limited by the speed of the system's PCLK
          signal, so with reasonably fast systems (PCLK around 50-66MHz)
@@@@ -200,11 -213,11 -213,11 +213,11 @@@@ config OMAP_WATCHDO
          here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
   
   config PNX4008_WATCHDOG
-       tristate "PNX4008 Watchdog"
-       depends on ARCH_PNX4008
+       tristate "PNX4008 and LPC32XX Watchdog"
+       depends on ARCH_PNX4008 || ARCH_LPC32XX
        help
          Say Y here if to include support for the watchdog timer
-         in the PNX4008 processor.
+         in the PNX4008 or LPC32XX processor.
          This driver can be built as a module by choosing M. The module
          will be called pnx4008_wdt.
   
@@@@ -306,6 -319,18 -319,18 +319,18 @@@@ config MAX63XX_WATCHDO
        help
          Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
   
+  config IMX2_WDT
+       tristate "IMX2+ Watchdog"
+       depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX5
+       help
+         This is the driver for the hardware watchdog
+         on the Freescale IMX2 and later processors.
+         If you have one of these processors and wish to have
+         watchdog support enabled, say Y, otherwise say N.
+  
+         To compile this driver as a module, choose M here: the
+         module will be called imx2_wdt.
+  
   # AVR32 Architecture
   
   config AT32AP700X_WDT
@@@@ -383,6 -408,28 -408,28 +408,28 @@@@ config ALIM7101_WD
   
          Most people will say N.
   
+  config F71808E_WDT
+       tristate "Fintek F71808E, F71862FG, F71869, F71882FG and F71889FG Watchdog"
+       depends on X86 && EXPERIMENTAL
+       help
+         This is the driver for the hardware watchdog on the Fintek
+         F71808E, F71862FG, F71869, F71882FG and F71889FG Super I/O controllers.
+  
+         You can compile this driver directly into the kernel, or use
+         it as a module.  The module will be called f71808e_wdt.
+  
+  config SP5100_TCO
+       tristate "AMD/ATI SP5100 TCO Timer/Watchdog"
+       depends on X86 && PCI
+       ---help---
+         Hardware watchdog driver for the AMD/ATI SP5100 chipset. The TCO
+         (Total Cost of Ownership) timer is a watchdog timer that will reboot
+         the machine after its expiration. The expiration time can be
+         configured with the "heartbeat" parameter.
+  
+         To compile this driver as a module, choose M here: the
+         module will be called sp5100_tco.
+  
   config GEODE_WDT
        tristate "AMD Geode CS5535/CS5536 Watchdog"
        depends on CS5535_MFGPT
@@@@ -522,6 -569,9 -569,9 +569,9 @@@@ config IT8712F_WD
          This is the driver for the built-in watchdog timer on the IT8712F
          Super I/0 chipset used on many motherboards.
   
+         If the driver does not work, then make sure that the game port in
+         the BIOS is enabled.
+  
          To compile this driver as a module, choose M here: the
          module will be called it8712f_wdt.
   
@@@@ -529,25 -579,31 -579,31 +579,31 @@@@ config IT87_WD
        tristate "IT87 Watchdog Timer"
        depends on X86 && EXPERIMENTAL
        ---help---
-         This is the driver for the hardware watchdog on the ITE IT8716,
-         IT8718, IT8726, IT8712(Version J,K) Super I/O chips. 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.
+         This is the driver for the hardware watchdog on the ITE IT8702,
+         IT8712, IT8716, IT8718, IT8720, IT8726, IT8712 Super I/O chips.
+         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.
   
          To compile this driver as a module, choose M here: the module will
          be called it87_wdt.
   
   config HP_WATCHDOG
-       tristate "HP Proliant iLO 2 Hardware Watchdog Timer"
+       tristate "HP Proliant iLO2+ Hardware Watchdog Timer"
        depends on X86
        help
          A software monitoring watchdog and NMI sourcing driver. This driver
-         will detect lockups and provide stack trace. Also, when an NMI
-         occurs this driver will make the necessary BIOS calls to log
-         the cause of the NMI. This is a driver that will only load on a
-         HP ProLiant system with a minimum of iLO2 support.
-         To compile this driver as a module, choose M here: the
-         module will be called hpwdt.
+         will detect lockups and provide a stack trace. This is a driver that
+         will only load on a HP ProLiant system with a minimum of iLO2 support.
+         To compile this driver as a module, choose M here: the module will be
+         called hpwdt.
+  
+  config HPWDT_NMI_DECODING
+       bool "NMI decoding support for the HP ProLiant iLO2+ Hardware Watchdog Timer"
+       depends on HP_WATCHDOG
+       help
+         When an NMI occurs this feature will make the necessary BIOS calls to
+         log the cause of the NMI.
   
   config SC1200_WDT
        tristate "National Semiconductor PC87307/PC97307 (ala SC1200) Watchdog"
@@@@ -586,6 -642,24 -642,24 +642,24 @@@@ config PC87413_WD
   
          Most people will say N.
   
+  config NV_TCO
+       tristate "nVidia TCO Timer/Watchdog"
+       depends on X86 && PCI
+       ---help---
+         Hardware driver for the TCO timer built into the nVidia Hub family
+         (such as the MCP51).  The TCO (Total Cost of Ownership) timer is a
+         watchdog timer that will reboot the machine after its second
+         expiration. The expiration time can be configured with the
+         "heartbeat" parameter.
+  
+         On some motherboards the driver may fail to reset the chipset's
+         NO_REBOOT flag which prevents the watchdog from rebooting the
+         machine. If this is the case you will get a kernel message like
+         "failed to reset NO_REBOOT flag, reboot disabled by hardware".
+  
+         To compile this driver as a module, choose M here: the
+         module will be called nv_tco.
+  
   config RDC321X_WDT
        tristate "RDC R-321x SoC watchdog"
        depends on X86_RDC321X
@@@@ -677,14 -751,15 -751,15 +751,15 @@@@ config SMSC37B787_WD
          Most people will say N.
   
   config W83627HF_WDT
-       tristate "W83627HF Watchdog Timer"
+       tristate "W83627HF/W83627DHG Watchdog Timer"
        depends on X86
        ---help---
          This is the driver for the hardware watchdog on the W83627HF chipset
          as used in Advantech PC-9578 and Tyan S2721-533 motherboards
-         (and likely others).  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.
+         (and likely others). The driver also supports the W83627DHG chip.
+         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.
   
          To compile this driver as a module, choose M here: the
          module will be called w83627hf_wdt.
@@@@ -787,10 -862,22 -862,22 +862,22 @@@@ config SBC_EPX_C3_WATCHDO
   
   # M68K Architecture
   
-  # M68KNOMMU Architecture
+  config M548x_WATCHDOG
+       tristate "MCF548x watchdog support"
+       depends on M548x
+       help
+         To compile this driver as a module, choose M here: the
+         module will be called m548x_wdt.
   
   # MIPS Architecture
   
+  config ATH79_WDT
+       tristate "Atheros AR71XX/AR724X/AR913X hardware watchdog"
+       depends on ATH79
+       help
+         Hardware driver for the built-in watchdog timer on the Atheros
+         AR71XX/AR724X/AR913X SoCs.
+  
   config BCM47XX_WDT
        tristate "Broadcom BCM47xx Watchdog Timer"
        depends on BCM47XX
@@@@ -857,6 -944,34 -944,34 +944,34 @@@@ config TXX9_WD
        help
          Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
   
+  config OCTEON_WDT
+       tristate "Cavium OCTEON SOC family Watchdog Timer"
+       depends on CPU_CAVIUM_OCTEON
+       default y
+       select EXPORT_UASM if OCTEON_WDT = m
+       help
+         Hardware driver for OCTEON's on chip watchdog timer.
+         Enables the watchdog for all cores running Linux. It
+         installs a NMI handler and pokes the watchdog based on an
+         interrupt.  On first expiration of the watchdog, the
+         interrupt handler pokes it.  The second expiration causes an
+         NMI that prints a message. The third expiration causes a
+         global soft reset.
+  
+         When userspace has /dev/watchdog open, no poking is done
+         from the first interrupt, it is then only poked when the
+         device is written.
+  
+  config BCM63XX_WDT
+       tristate "Broadcom BCM63xx hardware watchdog"
+       depends on BCM63XX
+       help
+         Watchdog driver for the built in watchdog hardware in Broadcom
+         BCM63xx SoC.
+  
+         To compile this driver as a loadable module, choose M here.
+         The module will be called bcm63xx_wdt.
+  
   # PARISC Architecture
   
   # POWERPC Architecture
@@@@ -898,12 -1013,32 -1013,32 +1013,32 @@@@ config PIKA_WD
          the Warp platform.
   
   config BOOKE_WDT
-       bool "PowerPC Book-E Watchdog Timer"
+       tristate "PowerPC Book-E Watchdog Timer"
        depends on BOOKE || 4xx
        ---help---
+         Watchdog driver for PowerPC Book-E chips, such as the Freescale
+         MPC85xx SOCs and the IBM PowerPC 440.
+  
          Please see Documentation/watchdog/watchdog-api.txt for
          more information.
   
+  config BOOKE_WDT_DEFAULT_TIMEOUT
+       int "PowerPC Book-E Watchdog Timer Default Timeout"
+       depends on BOOKE_WDT
+       default 38 if FSL_BOOKE
+       range 0 63 if FSL_BOOKE
+       default 3 if !FSL_BOOKE
+       range 0 3 if !FSL_BOOKE
+       help
+         Select the default watchdog timer period to be used by the PowerPC
+         Book-E watchdog driver.  A watchdog "event" occurs when the bit
+         position represented by this number transitions from zero to one.
+  
+         For Freescale Book-E processors, this is a number between 0 and 63.
+         For other Book-E processors, this is a number between 0 and 3.
+  
+         The value can be overidden by the wdt_period command-line parameter.
+  
   # PPC64 Architecture
   
   config WATCHDOG_RTAS
@@@@ -948,6 -1083,14 -1083,14 +1083,6 @@@@ config SH_WD
          To compile this driver as a module, choose M here: the
          module will be called shwdt.
   
 --config SH_WDT_MMAP
 --     bool "Allow mmap of SH WDT"
 --     default n
 --     depends on SH_WDT
 --     help
 --       If you say Y here, user applications will be able to mmap the
 --       WDT/CPG registers.
 --
   # SPARC Architecture
   
   # SPARC64 Architecture
diff --combined drivers/watchdog/shwdt.c
index b7d2f8a0422bb54eef40d0b12a45125bacd37815,6fc74065abee9bef283fc0da35e870f707d38a33,6fc74065abee9bef283fc0da35e870f707d38a33..4e3e7eb5919c95b1ddf9327dfab21b5fc9d61b90
@@@@ -1,9 -1,9 -1,9 +1,9 @@@@
   /*
 -- * drivers/char/watchdog/shwdt.c
 ++ * drivers/watchdog/shwdt.c
    *
    * Watchdog driver for integrated watchdog in the SuperH processors.
    *
 -- * Copyright (C) 2001, 2002, 2003 Paul Mundt <lethal@linux-sh.org>
 ++ * Copyright (C) 2001 - 2010  Paul Mundt <lethal@linux-sh.org>
    *
    * This program is free software; you can redistribute it and/or modify it
    * under the terms of the GNU General Public License as published by the
    */
   #include <linux/module.h>
   #include <linux/moduleparam.h>
 ++#include <linux/platform_device.h>
   #include <linux/init.h>
   #include <linux/types.h>
   #include <linux/miscdevice.h>
   #include <linux/ioport.h>
   #include <linux/fs.h>
   #include <linux/mm.h>
 ++#include <linux/slab.h>
   #include <linux/io.h>
   #include <linux/uaccess.h>
   #include <asm/watchdog.h>
   
 --#define PFX "shwdt: "
 ++#define DRV_NAME "sh-wdt"
   
   /*
    * Default clock division ratio is 5.25 msecs. For an additional table of
    * misses its deadline, the kernel timer will allow the WDT to overflow.
    */
   static int clock_division_ratio = WTCSR_CKS_4096;
 --
   #define next_ping_period(cks)        msecs_to_jiffies(cks - 4)
   
 --static void sh_wdt_ping(unsigned long data);
 --
 --static unsigned long shwdt_is_open;
   static const struct watchdog_info sh_wdt_info;
 --static char shwdt_expect_close;
 --static DEFINE_TIMER(timer, sh_wdt_ping, 0, 0);
 --static unsigned long next_heartbeat;
 ++static struct platform_device *sh_wdt_dev;
   static DEFINE_SPINLOCK(shwdt_lock);
   
   #define WATCHDOG_HEARTBEAT 30                        /* 30 sec default heartbeat */
   static int heartbeat = WATCHDOG_HEARTBEAT;   /* in seconds */
 --
   static int nowayout = WATCHDOG_NOWAYOUT;
 ++static unsigned long next_heartbeat;
   
 --/**
 -- *   sh_wdt_start - Start the Watchdog
 -- *
 -- *   Starts the watchdog.
 -- */
 --static void sh_wdt_start(void)
 ++struct sh_wdt {
 ++     void __iomem            *base;
 ++     struct device           *dev;
 ++
 ++     struct timer_list       timer;
 ++
 ++     unsigned long           enabled;
 ++     char                    expect_close;
 ++};
 ++
 ++static void sh_wdt_start(struct sh_wdt *wdt)
   {
 --     __u8 csr;
        unsigned long flags;
 ++     u8 csr;
   
        spin_lock_irqsave(&shwdt_lock, flags);
   
        next_heartbeat = jiffies + (heartbeat * HZ);
 --     mod_timer(&timer, next_ping_period(clock_division_ratio));
 ++     mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
   
        csr = sh_wdt_read_csr();
        csr |= WTCSR_WT | clock_division_ratio;
        sh_wdt_write_csr(csr);
   
   #ifdef CONFIG_CPU_SH2
 --     /*
 --      * Whoever came up with the RSTCSR semantics must've been smoking
 --      * some of the good stuff, since in addition to the WTCSR/WTCNT write
 --      * brain-damage, it's managed to fuck things up one step further..
 --      *
 --      * If we need to clear the WOVF bit, the upper byte has to be 0xa5..
 --      * but if we want to touch RSTE or RSTS, the upper byte has to be
 --      * 0x5a..
 --      */
        csr = sh_wdt_read_rstcsr();
        csr &= ~RSTCSR_RSTS;
        sh_wdt_write_rstcsr(csr);
        spin_unlock_irqrestore(&shwdt_lock, flags);
   }
   
 --/**
 -- *   sh_wdt_stop - Stop the Watchdog
 -- *   Stops the watchdog.
 -- */
 --static void sh_wdt_stop(void)
 ++static void sh_wdt_stop(struct sh_wdt *wdt)
   {
 --     __u8 csr;
        unsigned long flags;
 ++     u8 csr;
   
        spin_lock_irqsave(&shwdt_lock, flags);
   
 --     del_timer(&timer);
 ++     del_timer(&wdt->timer);
   
        csr = sh_wdt_read_csr();
        csr &= ~WTCSR_TME;
        sh_wdt_write_csr(csr);
 ++
        spin_unlock_irqrestore(&shwdt_lock, flags);
   }
   
 --/**
 -- *   sh_wdt_keepalive - Keep the Userspace Watchdog Alive
 -- *   The Userspace watchdog got a KeepAlive: schedule the next heartbeat.
 -- */
 --static inline void sh_wdt_keepalive(void)
 ++static inline void sh_wdt_keepalive(struct sh_wdt *wdt)
   {
        unsigned long flags;
   
        spin_unlock_irqrestore(&shwdt_lock, flags);
   }
   
 --/**
 -- *   sh_wdt_set_heartbeat - Set the Userspace Watchdog heartbeat
 -- *   Set the Userspace Watchdog heartbeat
 -- */
   static int sh_wdt_set_heartbeat(int t)
   {
        unsigned long flags;
        return 0;
   }
   
 --/**
 -- *   sh_wdt_ping - Ping the Watchdog
 -- *   @data: Unused
 -- *
 -- *   Clears overflow bit, resets timer counter.
 -- */
   static void sh_wdt_ping(unsigned long data)
   {
 ++     struct sh_wdt *wdt = (struct sh_wdt *)data;
        unsigned long flags;
   
        spin_lock_irqsave(&shwdt_lock, flags);
        if (time_before(jiffies, next_heartbeat)) {
 --             __u8 csr;
 ++             u8 csr;
   
                csr = sh_wdt_read_csr();
                csr &= ~WTCSR_IOVF;
   
                sh_wdt_write_cnt(0);
   
 --             mod_timer(&timer, next_ping_period(clock_division_ratio));
 ++             mod_timer(&wdt->timer, next_ping_period(clock_division_ratio));
        } else
 --             printk(KERN_WARNING PFX "Heartbeat lost! Will not ping "
 --                    "the watchdog\n");
 ++             dev_warn(wdt->dev, "Heartbeat lost! Will not ping "
 ++                      "the watchdog\n");
        spin_unlock_irqrestore(&shwdt_lock, flags);
   }
   
 --/**
 -- *   sh_wdt_open - Open the Device
 -- *   @inode: inode of device
 -- *   @file: file handle of device
 -- *
 -- *   Watchdog device is opened and started.
 -- */
   static int sh_wdt_open(struct inode *inode, struct file *file)
   {
 --     if (test_and_set_bit(0, &shwdt_is_open))
 ++     struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev);
 ++
 ++     if (test_and_set_bit(0, &wdt->enabled))
                return -EBUSY;
        if (nowayout)
                __module_get(THIS_MODULE);
   
 --     sh_wdt_start();
 ++     file->private_data = wdt;
 ++
 ++     sh_wdt_start(wdt);
   
        return nonseekable_open(inode, file);
   }
   
 --/**
 -- *   sh_wdt_close - Close the Device
 -- *   @inode: inode of device
 -- *   @file: file handle of device
 -- *
 -- *   Watchdog device is closed and stopped.
 -- */
   static int sh_wdt_close(struct inode *inode, struct file *file)
   {
 --     if (shwdt_expect_close == 42) {
 --             sh_wdt_stop();
 ++     struct sh_wdt *wdt = file->private_data;
 ++
 ++     if (wdt->expect_close == 42) {
 ++             sh_wdt_stop(wdt);
        } else {
 --             printk(KERN_CRIT PFX "Unexpected close, not "
 --                    "stopping watchdog!\n");
 --             sh_wdt_keepalive();
 ++             dev_crit(wdt->dev, "Unexpected close, not "
 ++                      "stopping watchdog!\n");
 ++             sh_wdt_keepalive(wdt);
        }
   
 --     clear_bit(0, &shwdt_is_open);
 --     shwdt_expect_close = 0;
 ++     clear_bit(0, &wdt->enabled);
 ++     wdt->expect_close = 0;
   
        return 0;
   }
   
 --/**
 -- *   sh_wdt_write - Write to Device
 -- *   @file: file handle of device
 -- *   @buf: buffer to write
 -- *   @count: length of buffer
 -- *   @ppos: offset
 -- *
 -- *   Pings the watchdog on write.
 -- */
   static ssize_t sh_wdt_write(struct file *file, const char *buf,
                            size_t count, loff_t *ppos)
   {
 ++     struct sh_wdt *wdt = file->private_data;
 ++
        if (count) {
                if (!nowayout) {
                        size_t i;
   
 --                     shwdt_expect_close = 0;
 ++                     wdt->expect_close = 0;
   
                        for (i = 0; i != count; i++) {
                                char c;
                                if (get_user(c, buf + i))
                                        return -EFAULT;
                                if (c == 'V')
 --                                     shwdt_expect_close = 42;
 ++                                     wdt->expect_close = 42;
                        }
                }
 --             sh_wdt_keepalive();
 ++             sh_wdt_keepalive(wdt);
        }
   
        return count;
   }
   
 --/**
 -- *   sh_wdt_mmap - map WDT/CPG registers into userspace
 -- *   @file: file structure for the device
 -- *   @vma: VMA to map the registers into
 -- *
 -- *   A simple mmap() implementation for the corner cases where the counter
 -- *   needs to be mapped in userspace directly. Due to the relatively small
 -- *   size of the area, neighbouring registers not necessarily tied to the
 -- *   CPG will also be accessible through the register page, so this remains
 -- *   configurable for users that really know what they're doing.
 -- *
 -- *   Additionaly, the register page maps in the CPG register base relative
 -- *   to the nearest page-aligned boundary, which requires that userspace do
 -- *   the appropriate CPU subtype math for calculating the page offset for
 -- *   the counter value.
 -- */
 --static int sh_wdt_mmap(struct file *file, struct vm_area_struct *vma)
 --{
 --     int ret = -ENOSYS;
 --
 --#ifdef CONFIG_SH_WDT_MMAP
 --     unsigned long addr;
 --
 --     /* Only support the simple cases where we map in a register page. */
 --     if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
 --             return -EINVAL;
 --
 --     /*
 --      * Pick WTCNT as the start, it's usually the first register after the
 --      * FRQCR, and neither one are generally page-aligned out of the box.
 --      */
 --     addr = WTCNT & ~(PAGE_SIZE - 1);
 --
 --     vma->vm_flags |= VM_IO;
 --     vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 --
 --     if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
 --                            PAGE_SIZE, vma->vm_page_prot)) {
 --             printk(KERN_ERR PFX "%s: io_remap_pfn_range failed\n",
 --                    __func__);
 --             return -EAGAIN;
 --     }
 --
 --     ret = 0;
 --#endif
 --
 --     return ret;
 --}
 --
 --/**
 -- *   sh_wdt_ioctl - Query Device
 -- *   @file: file handle of device
 -- *   @cmd: watchdog command
 -- *   @arg: argument
 -- *
 -- *   Query basic information from the device or ping it, as outlined by the
 -- *   watchdog API.
 -- */
   static long sh_wdt_ioctl(struct file *file, unsigned int cmd,
                                                        unsigned long arg)
   {
 ++     struct sh_wdt *wdt = file->private_data;
        int new_heartbeat;
        int options, retval = -EINVAL;
   
                        return -EFAULT;
   
                if (options & WDIOS_DISABLECARD) {
 --                     sh_wdt_stop();
 ++                     sh_wdt_stop(wdt);
                        retval = 0;
                }
   
                if (options & WDIOS_ENABLECARD) {
 --                     sh_wdt_start();
 ++                     sh_wdt_start(wdt);
                        retval = 0;
                }
   
                return retval;
        case WDIOC_KEEPALIVE:
 --             sh_wdt_keepalive();
 ++             sh_wdt_keepalive(wdt);
                return 0;
        case WDIOC_SETTIMEOUT:
                if (get_user(new_heartbeat, (int *)arg))
                if (sh_wdt_set_heartbeat(new_heartbeat))
                        return -EINVAL;
   
 --             sh_wdt_keepalive();
 ++             sh_wdt_keepalive(wdt);
                /* Fall */
        case WDIOC_GETTIMEOUT:
                return put_user(heartbeat, (int *)arg);
        return 0;
   }
   
 --/**
 -- *   sh_wdt_notify_sys - Notifier Handler
 -- *   @this: notifier block
 -- *   @code: notifier event
 -- *   @unused: unused
 -- *
 -- *   Handles specific events, such as turning off the watchdog during a
 -- *   shutdown event.
 -- */
   static int sh_wdt_notify_sys(struct notifier_block *this,
                             unsigned long code, void *unused)
   {
 ++     struct sh_wdt *wdt = platform_get_drvdata(sh_wdt_dev);
 ++
        if (code == SYS_DOWN || code == SYS_HALT)
 --             sh_wdt_stop();
 ++             sh_wdt_stop(wdt);
   
        return NOTIFY_DONE;
   }
@@@@ -308,6 -411,7 -411,7 +308,6 @@@@ static const struct file_operations sh_
        .unlocked_ioctl = sh_wdt_ioctl,
        .open           = sh_wdt_open,
        .release        = sh_wdt_close,
 --     .mmap           = sh_wdt_mmap,
   };
   
   static const struct watchdog_info sh_wdt_info = {
@@@@ -327,154 -431,72 -431,72 +327,154 @@@@ static struct miscdevice sh_wdt_miscde
        .fops           = &sh_wdt_fops,
   };
   
 --/**
 -- *   sh_wdt_init - Initialize module
 -- *   Registers the device and notifier handler. Actual device
 -- *   initialization is handled by sh_wdt_open().
 -- */
 --static int __init sh_wdt_init(void)
 ++static int __devinit sh_wdt_probe(struct platform_device *pdev)
   {
 ++     struct sh_wdt *wdt;
 ++     struct resource *res;
        int rc;
   
 --     if (clock_division_ratio < 0x5 || clock_division_ratio > 0x7) {
 --             clock_division_ratio = WTCSR_CKS_4096;
 --             printk(KERN_INFO PFX
 --               "clock_division_ratio value must be 0x5<=x<=0x7, using %d\n",
 --                             clock_division_ratio);
 ++     /*
 ++      * As this driver only covers the global watchdog case, reject
 ++      * any attempts to register per-CPU watchdogs.
 ++      */
 ++     if (pdev->id != -1)
 ++             return -EINVAL;
 ++
 ++     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 ++     if (unlikely(!res))
 ++             return -EINVAL;
 ++
 ++     if (!devm_request_mem_region(&pdev->dev, res->start,
 ++                                  resource_size(res), DRV_NAME))
 ++             return -EBUSY;
 ++
 ++     wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL);
 ++     if (unlikely(!wdt)) {
 ++             rc = -ENOMEM;
 ++             goto out_release;
        }
   
 --     rc = sh_wdt_set_heartbeat(heartbeat);
 --     if (unlikely(rc)) {
 --             heartbeat = WATCHDOG_HEARTBEAT;
 --             printk(KERN_INFO PFX
 --                     "heartbeat value must be 1<=x<=3600, using %d\n",
 --                                                             heartbeat);
 ++     wdt->dev = &pdev->dev;
 ++
 ++     wdt->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
 ++     if (unlikely(!wdt->base)) {
 ++             rc = -ENXIO;
 ++             goto out_err;
        }
   
        rc = register_reboot_notifier(&sh_wdt_notifier);
        if (unlikely(rc)) {
 --             printk(KERN_ERR PFX
 ++             dev_err(&pdev->dev,
                        "Can't register reboot notifier (err=%d)\n", rc);
 --             return rc;
 ++             goto out_unmap;
        }
   
 ++     sh_wdt_miscdev.parent = wdt->dev;
 ++
        rc = misc_register(&sh_wdt_miscdev);
        if (unlikely(rc)) {
 --             printk(KERN_ERR PFX
 ++             dev_err(&pdev->dev,
                        "Can't register miscdev on minor=%d (err=%d)\n",
                                                sh_wdt_miscdev.minor, rc);
 --             unregister_reboot_notifier(&sh_wdt_notifier);
 --             return rc;
 ++             goto out_unreg;
        }
   
 --     printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
 --             heartbeat, nowayout);
 ++     init_timer(&wdt->timer);
 ++     wdt->timer.function     = sh_wdt_ping;
 ++     wdt->timer.data         = (unsigned long)wdt;
 ++     wdt->timer.expires      = next_ping_period(clock_division_ratio);
 ++
 ++     platform_set_drvdata(pdev, wdt);
 ++     sh_wdt_dev = pdev;
 ++
 ++     dev_info(&pdev->dev, "initialized.\n");
   
        return 0;
 ++
 ++out_unreg:
 ++     unregister_reboot_notifier(&sh_wdt_notifier);
 ++out_unmap:
 ++     devm_iounmap(&pdev->dev, wdt->base);
 ++out_err:
 ++     devm_kfree(&pdev->dev, wdt);
 ++out_release:
 ++     devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
 ++
 ++     return rc;
   }
   
 --/**
 -- *   sh_wdt_exit - Deinitialize module
 -- *   Unregisters the device and notifier handler. Actual device
 -- *   deinitialization is handled by sh_wdt_close().
 -- */
 --static void __exit sh_wdt_exit(void)
 ++static int __devexit sh_wdt_remove(struct platform_device *pdev)
   {
 ++     struct sh_wdt *wdt = platform_get_drvdata(pdev);
 ++     struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 ++
 ++     platform_set_drvdata(pdev, NULL);
 ++
        misc_deregister(&sh_wdt_miscdev);
 ++
 ++     sh_wdt_dev = NULL;
 ++
        unregister_reboot_notifier(&sh_wdt_notifier);
 ++     devm_release_mem_region(&pdev->dev, res->start, resource_size(res));
 ++     devm_iounmap(&pdev->dev, wdt->base);
 ++     devm_kfree(&pdev->dev, wdt);
 ++
 ++     return 0;
   }
   
 ++static struct platform_driver sh_wdt_driver = {
 ++     .driver         = {
 ++             .name   = DRV_NAME,
 ++             .owner  = THIS_MODULE,
 ++     },
 ++
 ++     .probe  = sh_wdt_probe,
 ++     .remove = __devexit_p(sh_wdt_remove),
 ++};
 ++
 ++static int __init sh_wdt_init(void)
 ++{
 ++     int rc;
 ++
 ++     if (unlikely(clock_division_ratio < 0x5 ||
 ++                  clock_division_ratio > 0x7)) {
 ++             clock_division_ratio = WTCSR_CKS_4096;
 ++
 ++             pr_info("%s: divisor must be 0x5<=x<=0x7, using %d\n",
 ++                      DRV_NAME, clock_division_ratio);
 ++     }
 ++
 ++     rc = sh_wdt_set_heartbeat(heartbeat);
 ++     if (unlikely(rc)) {
 ++             heartbeat = WATCHDOG_HEARTBEAT;
 ++
 ++             pr_info("%s: heartbeat value must be 1<=x<=3600, using %d\n",
 ++                     DRV_NAME, heartbeat);
 ++     }
 ++
 ++     pr_info("%s: configured with heartbeat=%d sec (nowayout=%d)\n",
 ++             DRV_NAME, heartbeat, nowayout);
 ++
 ++     return platform_driver_register(&sh_wdt_driver);
 ++}
 ++
 ++static void __exit sh_wdt_exit(void)
 ++{
 ++     platform_driver_unregister(&sh_wdt_driver);
 ++}
 ++module_init(sh_wdt_init);
 ++module_exit(sh_wdt_exit);
 ++
   MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
   MODULE_DESCRIPTION("SuperH watchdog driver");
   MODULE_LICENSE("GPL");
 ++MODULE_ALIAS("platform:" DRV_NAME);
   MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
   
   module_param(clock_division_ratio, int, 0);
   MODULE_PARM_DESC(clock_division_ratio,
        "Clock division ratio. Valid ranges are from 0x5 (1.31ms) "
-       "to 0x7 (5.25ms). (default=" __MODULE_STRING(clock_division_ratio) ")");
+       "to 0x7 (5.25ms). (default=" __MODULE_STRING(WTCSR_CKS_4096) ")");
   
   module_param(heartbeat, int, 0);
   MODULE_PARM_DESC(heartbeat,
@@@@ -485,3 -507,6 -507,6 +485,3 @@@@ module_param(nowayout, int, 0)
   MODULE_PARM_DESC(nowayout,
        "Watchdog cannot be stopped once started (default="
                                __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 --
 --module_init(sh_wdt_init);
 --module_exit(sh_wdt_exit);