aboutsummaryrefslogtreecommitdiff
path: root/drivers/char/watchdog/ep93xx_wdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/watchdog/ep93xx_wdt.c')
-rw-r--r--drivers/char/watchdog/ep93xx_wdt.c253
1 files changed, 0 insertions, 253 deletions
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c
deleted file mode 100644
index 0e4787a0bb8..00000000000
--- a/drivers/char/watchdog/ep93xx_wdt.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Watchdog driver for Cirrus Logic EP93xx family of devices.
- *
- * Copyright (c) 2004 Ray Lehtiniemi
- * Copyright (c) 2006 Tower Technologies
- * Based on ep93xx driver, bits from alim7101_wdt.c
- *
- * Authors: Ray Lehtiniemi <rayl@mail.com>,
- * Alessandro Zummo <a.zummo@towertech.it>
- *
- * 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.
- *
- * This watchdog fires after 250msec, which is a too short interval
- * for us to rely on the user space daemon alone. So we ping the
- * wdt each ~200msec and eventually stop doing it if the user space
- * daemon dies.
- *
- * TODO:
- *
- * - Test last reset from watchdog status
- * - Add a few missing ioctls
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/timer.h>
-
-#include <asm/hardware.h>
-#include <asm/uaccess.h>
-
-#define WDT_VERSION "0.3"
-#define PFX "ep93xx_wdt: "
-
-/* default timeout (secs) */
-#define WDT_TIMEOUT 30
-
-static int nowayout = WATCHDOG_NOWAYOUT;
-static int timeout = WDT_TIMEOUT;
-
-static struct timer_list timer;
-static unsigned long next_heartbeat;
-static unsigned long wdt_status;
-static unsigned long boot_status;
-
-#define WDT_IN_USE 0
-#define WDT_OK_TO_CLOSE 1
-
-#define EP93XX_WDT_REG(x) (EP93XX_WATCHDOG_BASE + (x))
-#define EP93XX_WDT_WATCHDOG EP93XX_WDT_REG(0x00)
-#define EP93XX_WDT_WDSTATUS EP93XX_WDT_REG(0x04)
-
-/* reset the wdt every ~200ms */
-#define WDT_INTERVAL (HZ/5)
-
-static void wdt_enable(void)
-{
- __raw_writew(0xaaaa, EP93XX_WDT_WATCHDOG);
-}
-
-static void wdt_disable(void)
-{
- __raw_writew(0xaa55, EP93XX_WDT_WATCHDOG);
-}
-
-static inline void wdt_ping(void)
-{
- __raw_writew(0x5555, EP93XX_WDT_WATCHDOG);
-}
-
-static void wdt_startup(void)
-{
- next_heartbeat = jiffies + (timeout * HZ);
-
- wdt_enable();
- mod_timer(&timer, jiffies + WDT_INTERVAL);
-}
-
-static void wdt_shutdown(void)
-{
- del_timer_sync(&timer);
- wdt_disable();
-}
-
-static void wdt_keepalive(void)
-{
- /* user land ping */
- next_heartbeat = jiffies + (timeout * HZ);
-}
-
-static int ep93xx_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_startup();
-
- return nonseekable_open(inode, file);
-}
-
-static ssize_t
-ep93xx_wdt_write(struct file *file, const char __user *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);
- else
- clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
- }
- }
- wdt_keepalive();
- }
-
- return len;
-}
-
-static struct watchdog_info ident = {
- .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE,
- .identity = "EP93xx Watchdog",
-};
-
-static int
-ep93xx_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- int ret = -ENOTTY;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- ret = copy_to_user((struct watchdog_info __user *)arg, &ident,
- sizeof(ident)) ? -EFAULT : 0;
- break;
-
- case WDIOC_GETSTATUS:
- ret = put_user(0, (int __user *)arg);
- break;
-
- case WDIOC_GETBOOTSTATUS:
- ret = put_user(boot_status, (int __user *)arg);
- break;
-
- case WDIOC_GETTIMEOUT:
- /* actually, it is 0.250 seconds.... */
- ret = put_user(1, (int __user *)arg);
- break;
-
- case WDIOC_KEEPALIVE:
- wdt_keepalive();
- ret = 0;
- break;
- }
- return ret;
-}
-
-static int ep93xx_wdt_release(struct inode *inode, struct file *file)
-{
- if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
- wdt_shutdown();
- else
- printk(KERN_CRIT PFX "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 ep93xx_wdt_fops = {
- .owner = THIS_MODULE,
- .write = ep93xx_wdt_write,
- .ioctl = ep93xx_wdt_ioctl,
- .open = ep93xx_wdt_open,
- .release = ep93xx_wdt_release,
-};
-
-static struct miscdevice ep93xx_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &ep93xx_wdt_fops,
-};
-
-static void ep93xx_timer_ping(unsigned long data)
-{
- if (time_before(jiffies, next_heartbeat))
- wdt_ping();
-
- /* Re-set the timer interval */
- mod_timer(&timer, jiffies + WDT_INTERVAL);
-}
-
-static int __init ep93xx_wdt_init(void)
-{
- int err;
-
- err = misc_register(&ep93xx_wdt_miscdev);
-
- boot_status = __raw_readl(EP93XX_WDT_WATCHDOG) & 0x01 ? 1 : 0;
-
- printk(KERN_INFO PFX "EP93XX watchdog, driver version "
- WDT_VERSION "%s\n",
- (__raw_readl(EP93XX_WDT_WATCHDOG) & 0x08)
- ? " (nCS1 disable detected)" : "");
-
- if (timeout < 1 || timeout > 3600) {
- timeout = WDT_TIMEOUT;
- printk(KERN_INFO PFX
- "timeout value must be 1<=x<=3600, using %d\n",
- timeout);
- }
-
- setup_timer(&timer, ep93xx_timer_ping, 1);
- return err;
-}
-
-static void __exit ep93xx_wdt_exit(void)
-{
- wdt_shutdown();
- misc_deregister(&ep93xx_wdt_miscdev);
-}
-
-module_init(ep93xx_wdt_init);
-module_exit(ep93xx_wdt_exit);
-
-module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
-
-module_param(timeout, int, 0);
-MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
-
-MODULE_AUTHOR("Ray Lehtiniemi <rayl@mail.com>,"
- "Alessandro Zummo <a.zummo@towertech.it>");
-MODULE_DESCRIPTION("EP93xx Watchdog");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(WDT_VERSION);
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);