summaryrefslogtreecommitdiff
path: root/target/linux/rdc/patches-2.6.32/110-rdc321x_watchdog_fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/rdc/patches-2.6.32/110-rdc321x_watchdog_fix.patch')
-rw-r--r--target/linux/rdc/patches-2.6.32/110-rdc321x_watchdog_fix.patch313
1 files changed, 0 insertions, 313 deletions
diff --git a/target/linux/rdc/patches-2.6.32/110-rdc321x_watchdog_fix.patch b/target/linux/rdc/patches-2.6.32/110-rdc321x_watchdog_fix.patch
deleted file mode 100644
index fe7969e..0000000
--- a/target/linux/rdc/patches-2.6.32/110-rdc321x_watchdog_fix.patch
+++ /dev/null
@@ -1,313 +0,0 @@
---- a/drivers/watchdog/rdc321x_wdt.c
-+++ b/drivers/watchdog/rdc321x_wdt.c
-@@ -36,111 +36,99 @@
- #include <linux/watchdog.h>
- #include <linux/io.h>
- #include <linux/uaccess.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
- #include <linux/mfd/rdc321x.h>
-
--#define RDC_WDT_MASK 0x80000000 /* Mask */
-+#define RDC321X_WDT_REG 0x00000044
-+
- #define RDC_WDT_EN 0x00800000 /* Enable bit */
--#define RDC_WDT_WTI 0x00200000 /* Generate CPU reset/NMI/WDT on timeout */
--#define RDC_WDT_RST 0x00100000 /* Reset bit */
--#define RDC_WDT_WIF 0x00040000 /* WDT IRQ Flag */
--#define RDC_WDT_IRT 0x00000100 /* IRQ Routing table */
--#define RDC_WDT_CNT 0x00000001 /* WDT count */
-+#define RDC_WDT_WDTIRQ 0x00400000 /* Create WDT IRQ before CPU reset */
-+#define RDC_WDT_NMIIRQ 0x00200000 /* Create NMI IRQ before CPU reset */
-+#define RDC_WDT_RST 0x00100000 /* Reset wdt */
-+#define RDC_WDT_NIF 0x00080000 /* NMI interrupt occured */
-+#define RDC_WDT_WIF 0x00040000 /* WDT interrupt occured */
-+#define RDC_WDT_IRT 0x00000700 /* IRQ Routing table */
-+#define RDC_WDT_CNT 0x0000007F /* WDT count */
-
--#define RDC_CLS_TMR 0x80003844 /* Clear timer */
-+/* default counter value (2.34 s) */
-+#define RDC_WDT_DFLT_CNT 0x00000040
-
--#define RDC_WDT_INTERVAL (HZ/10+1)
-+#define RDC_WDT_SETUP (RDC_WDT_EN | RDC_WDT_NMIIRQ | RDC_WDT_RST | RDC_WDT_DFLT_CNT)
-
- static int ticks = 1000;
-
- /* some device data */
-
- static struct {
-- struct completion stop;
-- int running;
- struct timer_list timer;
-- int queue;
-- int default_ticks;
-- unsigned long inuse;
-- spinlock_t lock;
-+ int seconds_left;
-+ int total_seconds;
-+ bool inuse;
-+ bool running;
-+ bool close_expected;
-+
- struct pci_dev *sb_pdev;
- int base_reg;
- } rdc321x_wdt_device;
-
--/* generic helper functions */
-+static struct watchdog_info ident = {
-+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
-+ .identity = "RDC321x WDT",
-+};
-
--static void rdc321x_wdt_trigger(unsigned long unused)
-+
-+/* generic helper functions */
-+static void rdc321x_wdt_timer(unsigned long unused)
- {
-- unsigned long flags;
-- u32 val;
-+ if (!rdc321x_wdt_device.running) {
-+ pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
-+ rdc321x_wdt_device.base_reg, 0);
-+ return;
-+ }
-
-- if (rdc321x_wdt_device.running)
-- ticks--;
-+ rdc321x_wdt_device.seconds_left--;
-
-- /* keep watchdog alive */
-- spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
-- pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
-- rdc321x_wdt_device.base_reg, &val);
-- val |= RDC_WDT_EN;
-- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
-- rdc321x_wdt_device.base_reg, val);
-- spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
-+ if (rdc321x_wdt_device.seconds_left < 1)
-+ return;
-
-- /* requeue?? */
-- if (rdc321x_wdt_device.queue && ticks)
-- mod_timer(&rdc321x_wdt_device.timer,
-- jiffies + RDC_WDT_INTERVAL);
-- else {
-- /* ticks doesn't matter anyway */
-- complete(&rdc321x_wdt_device.stop);
-- }
-+ pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
-+ rdc321x_wdt_device.base_reg, RDC_WDT_SETUP);
-
-+ mod_timer(&rdc321x_wdt_device.timer, HZ * 2 + jiffies);
- }
-
- static void rdc321x_wdt_reset(void)
- {
-- ticks = rdc321x_wdt_device.default_ticks;
-+ rdc321x_wdt_device.seconds_left = rdc321x_wdt_device.total_seconds;
- }
-
- static void rdc321x_wdt_start(void)
- {
-- unsigned long flags;
--
-- if (!rdc321x_wdt_device.queue) {
-- rdc321x_wdt_device.queue = 1;
--
-- /* Clear the timer */
-- spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
-- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
-- rdc321x_wdt_device.base_reg, RDC_CLS_TMR);
--
-- /* Enable watchdog and set the timeout to 81.92 us */
-- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
-- rdc321x_wdt_device.base_reg,
-- RDC_WDT_EN | RDC_WDT_CNT);
-- spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
-+ if (rdc321x_wdt_device.running)
-+ return;
-
-- mod_timer(&rdc321x_wdt_device.timer,
-- jiffies + RDC_WDT_INTERVAL);
-- }
-+ rdc321x_wdt_device.seconds_left = rdc321x_wdt_device.total_seconds;
-+ rdc321x_wdt_device.running = true;
-+ rdc321x_wdt_timer(0);
-
-- /* if process dies, counter is not decremented */
-- rdc321x_wdt_device.running++;
-+ return;
- }
-
- static int rdc321x_wdt_stop(void)
- {
-- if (rdc321x_wdt_device.running)
-- rdc321x_wdt_device.running = 0;
-+ if (WATCHDOG_NOWAYOUT)
-+ return -ENOSYS;
-
-- ticks = rdc321x_wdt_device.default_ticks;
-+ rdc321x_wdt_device.running = false;
-
-- return -EIO;
-+ return 0;
- }
-
- /* filesystem operations */
- static int rdc321x_wdt_open(struct inode *inode, struct file *file)
- {
-- if (test_and_set_bit(0, &rdc321x_wdt_device.inuse))
-+ if (xchg(&rdc321x_wdt_device.inuse, true))
- return -EBUSY;
-
- return nonseekable_open(inode, file);
-@@ -148,7 +136,16 @@ static int rdc321x_wdt_open(struct inode
-
- static int rdc321x_wdt_release(struct inode *inode, struct file *file)
- {
-- clear_bit(0, &rdc321x_wdt_device.inuse);
-+ int ret;
-+
-+ if (rdc321x_wdt_device.close_expected) {
-+ ret = rdc321x_wdt_stop();
-+ if (ret)
-+ return ret;
-+ }
-+
-+ rdc321x_wdt_device.inuse = false;
-+
- return 0;
- }
-
-@@ -156,30 +153,29 @@ static long rdc321x_wdt_ioctl(struct fil
- unsigned long arg)
- {
- void __user *argp = (void __user *)arg;
-- u32 value;
-- static struct watchdog_info ident = {
-- .options = WDIOF_CARDRESET,
-- .identity = "RDC321x WDT",
-- };
-- unsigned long flags;
-+ int value;
-
- switch (cmd) {
- case WDIOC_KEEPALIVE:
- rdc321x_wdt_reset();
- break;
-- case WDIOC_GETSTATUS:
-- /* Read the value from the DATA register */
-- spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
-- pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
-- rdc321x_wdt_device.base_reg, &value);
-- spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
-- if (copy_to_user(argp, &value, sizeof(u32)))
-- return -EFAULT;
-- break;
- case WDIOC_GETSUPPORT:
- if (copy_to_user(argp, &ident, sizeof(ident)))
- return -EFAULT;
- break;
-+ case WDIOC_SETTIMEOUT:
-+ if (copy_from_user(&rdc321x_wdt_device.total_seconds, argp, sizeof(int)))
-+ return -EFAULT;
-+ rdc321x_wdt_device.seconds_left = rdc321x_wdt_device.total_seconds;
-+ break;
-+ case WDIOC_GETTIMEOUT:
-+ if (copy_to_user(argp, &rdc321x_wdt_device.total_seconds, sizeof(int)))
-+ return -EFAULT;
-+ break;
-+ case WDIOC_GETTIMELEFT:
-+ if (copy_to_user(argp, &rdc321x_wdt_device.seconds_left, sizeof(int)))
-+ return -EFAULT;
-+ break;
- case WDIOC_SETOPTIONS:
- if (copy_from_user(&value, argp, sizeof(int)))
- return -EFAULT;
-@@ -194,17 +190,34 @@ static long rdc321x_wdt_ioctl(struct fil
- }
- break;
- default:
-- return -ENOTTY;
-+ return -EINVAL;
- }
-+
- return 0;
- }
-
- static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
- {
-+ size_t i;
-+
- if (!count)
- return -EIO;
-
-+ rdc321x_wdt_device.close_expected = false;
-+
-+ for (i = 0; i != count; i++) {
-+ char c;
-+
-+ if (get_user(c, buf + i))
-+ return -EFAULT;
-+
-+ if (c == 'V') {
-+ rdc321x_wdt_device.close_expected = true;
-+ break;
-+ }
-+ }
-+
- rdc321x_wdt_reset();
-
- return count;
-@@ -246,27 +259,18 @@ static int __devinit rdc321x_wdt_probe(s
- rdc321x_wdt_device.sb_pdev = pdata->sb_pdev;
- rdc321x_wdt_device.base_reg = r->start;
-
-+ rdc321x_wdt_device.running = false;
-+ rdc321x_wdt_device.close_expected = false;
-+ rdc321x_wdt_device.inuse = 0;
-+ setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_timer, 0);
-+ rdc321x_wdt_device.total_seconds = 100;
-+
- err = misc_register(&rdc321x_wdt_misc);
- if (err < 0) {
- dev_err(&pdev->dev, "misc_register failed\n");
- return err;
- }
-
-- spin_lock_init(&rdc321x_wdt_device.lock);
--
-- /* Reset the watchdog */
-- pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
-- rdc321x_wdt_device.base_reg, RDC_WDT_RST);
--
-- init_completion(&rdc321x_wdt_device.stop);
-- rdc321x_wdt_device.queue = 0;
--
-- clear_bit(0, &rdc321x_wdt_device.inuse);
--
-- setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0);
--
-- rdc321x_wdt_device.default_ticks = ticks;
--
- dev_info(&pdev->dev, "watchdog init success\n");
-
- return 0;
-@@ -274,10 +278,11 @@ static int __devinit rdc321x_wdt_probe(s
-
- static int __devexit rdc321x_wdt_remove(struct platform_device *pdev)
- {
-- if (rdc321x_wdt_device.queue) {
-- rdc321x_wdt_device.queue = 0;
-- wait_for_completion(&rdc321x_wdt_device.stop);
-- }
-+ if (rdc321x_wdt_device.inuse)
-+ rdc321x_wdt_device.inuse = 0;
-+
-+ while (timer_pending(&rdc321x_wdt_device.timer))
-+ msleep(100);
-
- misc_deregister(&rdc321x_wdt_misc);
-