From d5d6811ac49b533e7fb996b513c406d8fe75a85e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=BCsch?= Date: Wed, 2 Mar 2011 16:20:58 +0000 Subject: cbus-retu-wdt: Some fixes SVN-Revision: 25832 --- .../530-cbus-retu-wdt-preemptible.patch | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 target/linux/omap24xx/patches-2.6.38/530-cbus-retu-wdt-preemptible.patch (limited to 'target/linux/omap24xx/patches-2.6.38/530-cbus-retu-wdt-preemptible.patch') diff --git a/target/linux/omap24xx/patches-2.6.38/530-cbus-retu-wdt-preemptible.patch b/target/linux/omap24xx/patches-2.6.38/530-cbus-retu-wdt-preemptible.patch new file mode 100644 index 0000000000..fecbd09a76 --- /dev/null +++ b/target/linux/omap24xx/patches-2.6.38/530-cbus-retu-wdt-preemptible.patch @@ -0,0 +1,127 @@ +Index: linux-2.6.38-rc6/drivers/cbus/retu-wdt.c +=================================================================== +--- linux-2.6.38-rc6.orig/drivers/cbus/retu-wdt.c 2011-03-02 16:08:59.022211654 +0100 ++++ linux-2.6.38-rc6/drivers/cbus/retu-wdt.c 2011-03-02 16:29:43.215284501 +0100 +@@ -58,13 +58,11 @@ struct retu_wdt_dev { + struct device *dev; + int users; + struct miscdevice retu_wdt_miscdev; +- struct timer_list ping_timer; ++ struct delayed_work ping_work; + }; + + static struct retu_wdt_dev *retu_wdt; + +-static void retu_wdt_set_ping_timer(unsigned long enable); +- + static int _retu_modify_counter(unsigned int new) + { + if (retu_wdt) +@@ -86,6 +84,31 @@ static int retu_modify_counter(unsigned + return 0; + } + ++/* ++ * Since retu watchdog cannot be disabled in hardware, we must kick it ++ * with a timer until userspace watchdog software takes over. Do this ++ * unless /dev/watchdog is open or CONFIG_WATCHDOG_NOWAYOUT is set. ++ */ ++static void retu_wdt_ping_enable(struct retu_wdt_dev *wdev) ++{ ++ _retu_modify_counter(RETU_WDT_MAX_TIMER); ++ schedule_delayed_work(&wdev->ping_work, ++ round_jiffies_relative(RETU_WDT_DEFAULT_TIMER * HZ)); ++} ++ ++static void retu_wdt_ping_disable(struct retu_wdt_dev *wdev) ++{ ++ _retu_modify_counter(RETU_WDT_MAX_TIMER); ++ cancel_delayed_work_sync(&wdev->ping_work); ++} ++ ++static void retu_wdt_ping_work(struct work_struct *work) ++{ ++ struct retu_wdt_dev *wdev = container_of(to_delayed_work(work), ++ struct retu_wdt_dev, ping_work); ++ retu_wdt_ping_enable(wdev); ++} ++ + static ssize_t retu_wdt_period_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -105,7 +128,7 @@ static ssize_t retu_wdt_period_store(str + int ret; + + #ifdef CONFIG_WATCHDOG_NOWAYOUT +- retu_wdt_set_ping_timer(0); ++ retu_wdt_ping_disable(retu_wdt); + #endif + + if (sscanf(buf, "%u", &new_period) != 1) { +@@ -136,30 +159,13 @@ static DEVICE_ATTR(period, S_IRUGO | S_I + retu_wdt_period_store); + static DEVICE_ATTR(counter, S_IRUGO, retu_wdt_counter_show, NULL); + +-/*----------------------------------------------------------------------------*/ +- +-/* +- * Since retu watchdog cannot be disabled in hardware, we must kick it +- * with a timer until userspace watchdog software takes over. Do this +- * unless /dev/watchdog is open or CONFIG_WATCHDOG_NOWAYOUT is set. +- */ +-static void retu_wdt_set_ping_timer(unsigned long enable) +-{ +- _retu_modify_counter(RETU_WDT_MAX_TIMER); +- if (enable) +- mod_timer(&retu_wdt->ping_timer, +- jiffies + RETU_WDT_DEFAULT_TIMER * HZ); +- else +- del_timer_sync(&retu_wdt->ping_timer); +-} +- + static int retu_wdt_open(struct inode *inode, struct file *file) + { + if (test_and_set_bit(1, (unsigned long *)&(retu_wdt->users))) + return -EBUSY; + + file->private_data = (void *)retu_wdt; +- retu_wdt_set_ping_timer(0); ++ retu_wdt_ping_disable(retu_wdt); + + return nonseekable_open(inode, file); + } +@@ -169,7 +175,7 @@ static int retu_wdt_release(struct inode + struct retu_wdt_dev *wdev = file->private_data; + + #ifndef CONFIG_WATCHDOG_NOWAYOUT +- retu_wdt_set_ping_timer(1); ++ retu_wdt_ping_enable(retu_wdt); + #endif + wdev->users = 0; + +@@ -232,7 +238,7 @@ static int __devinit retu_wdt_ping(void) + #ifdef CONFIG_WATCHDOG_NOWAYOUT + retu_modify_counter(RETU_WDT_MAX_TIMER); + #else +- retu_wdt_set_ping_timer(1); ++ retu_wdt_ping_enable(retu_wdt); + #endif + + return 0; +@@ -283,7 +289,7 @@ static int __init retu_wdt_probe(struct + if (ret) + goto free3; + +- setup_timer(&wdev->ping_timer, retu_wdt_set_ping_timer, 1); ++ INIT_DELAYED_WORK(&wdev->ping_work, retu_wdt_ping_work); + + /* passed as module parameter? */ + ret = retu_modify_counter(counter_param); +@@ -326,6 +332,7 @@ static int __devexit retu_wdt_remove(str + misc_deregister(&wdev->retu_wdt_miscdev); + device_remove_file(&pdev->dev, &dev_attr_period); + device_remove_file(&pdev->dev, &dev_attr_counter); ++ cancel_delayed_work_sync(&wdev->ping_work); + kfree(wdev); + + return 0; -- cgit v1.2.3