* [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU
@ 2013-01-12 17:14 Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 1/5] watchdog: bcm47xx_wdt.c: convert to watchdog core api Hauke Mehrtens
` (6 more replies)
0 siblings, 7 replies; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-12 17:14 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips, Hauke Mehrtens
This patch series improves the functions for setting the watchdog
driver for bcm47xx based SoCs using ssb and bcma. This makes the
watchdog driver use the platform device provided by bcma or ssb.
This code is currently based on the linux-watchdog/master tree by
Wim Van Sebroeck.
v4:
* Just the parts changing the watchdog driver itself and not ssb or bcma.
v3:
* Remove changes done to the watchdog driver so John could pull this
into wireless-testing, this sill works with the old watchdog driver.
The patches changing the watchdog driver will be send later.
This was done to get this into 3.8 because Wim Van Sebroeck is
neither giving an Ack or a Nack on these patches and we want to do
more changes to bcma/ssb on top of these.
v2:
* reword some commit messages
* rebase on current wireless-testing/master with
"ssb: extif: fix compile errors" applied on top of it.
* do not change value of WDT_SOFTTIMER_MAX
* moved some small changes in the bcm47xx_wdt.c patches
Hauke Mehrtens (5):
watchdog: bcm47xx_wdt.c: convert to watchdog core api
watchdog: bcm47xx_wdt.c: use platform device
watchdog: bcm47xx_wdt.c: rename ops methods
watchdog: bcm47xx_wdt.c: rename wdt_time to timeout
watchdog: bcm47xx_wdt.c: add hard timer
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/bcm47xx_wdt.c | 339 +++++++++++++++++-----------------------
include/linux/bcm47xx_wdt.h | 9 ++
3 files changed, 154 insertions(+), 195 deletions(-)
--
1.7.10.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v4 1/5] watchdog: bcm47xx_wdt.c: convert to watchdog core api
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
@ 2013-01-12 17:14 ` Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 2/5] watchdog: bcm47xx_wdt.c: use platform device Hauke Mehrtens
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-12 17:14 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips, Hauke Mehrtens
Convert the bcm47xx_wdt.c driver to the new watchdog core api.
The nowayout parameter is now added unconditionally to the module.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/bcm47xx_wdt.c | 152 ++++++----------------------------------
2 files changed, 23 insertions(+), 130 deletions(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 7f809fd..e6eb363 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -971,6 +971,7 @@ config ATH79_WDT
config BCM47XX_WDT
tristate "Broadcom BCM47xx Watchdog Timer"
depends on BCM47XX
+ select WATCHDOG_CORE
help
Hardware driver for the Broadcom BCM47xx Watchdog Timer.
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index bc0e91e..4c520d6 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -14,15 +14,12 @@
#include <linux/bitops.h>
#include <linux/errno.h>
-#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/reboot.h>
#include <linux/types.h>
-#include <linux/uaccess.h>
#include <linux/watchdog.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
@@ -41,15 +38,11 @@ module_param(wdt_time, int, 0);
MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
__MODULE_STRING(WDT_DEFAULT_TIME) ")");
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-#endif
-static unsigned long bcm47xx_wdt_busy;
-static char expect_release;
static struct timer_list wdt_timer;
static atomic_t ticks;
@@ -97,29 +90,31 @@ static void bcm47xx_timer_tick(unsigned long unused)
}
}
-static inline void bcm47xx_wdt_pet(void)
+static int bcm47xx_wdt_keepalive(struct watchdog_device *wdd)
{
atomic_set(&ticks, wdt_time);
+
+ return 0;
}
-static void bcm47xx_wdt_start(void)
+static int bcm47xx_wdt_start(struct watchdog_device *wdd)
{
bcm47xx_wdt_pet();
bcm47xx_timer_tick(0);
+
+ return 0;
}
-static void bcm47xx_wdt_pause(void)
+static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
{
del_timer_sync(&wdt_timer);
bcm47xx_wdt_hw_stop();
-}
-static void bcm47xx_wdt_stop(void)
-{
- bcm47xx_wdt_pause();
+ return 0;
}
-static int bcm47xx_wdt_settimeout(int new_time)
+static int bcm47xx_wdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int new_time)
{
if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
return -EINVAL;
@@ -128,51 +123,6 @@ static int bcm47xx_wdt_settimeout(int new_time)
return 0;
}
-static int bcm47xx_wdt_open(struct inode *inode, struct file *file)
-{
- if (test_and_set_bit(0, &bcm47xx_wdt_busy))
- return -EBUSY;
-
- bcm47xx_wdt_start();
- return nonseekable_open(inode, file);
-}
-
-static int bcm47xx_wdt_release(struct inode *inode, struct file *file)
-{
- if (expect_release == 42) {
- bcm47xx_wdt_stop();
- } else {
- pr_crit("Unexpected close, not stopping watchdog!\n");
- bcm47xx_wdt_start();
- }
-
- clear_bit(0, &bcm47xx_wdt_busy);
- expect_release = 0;
- return 0;
-}
-
-static ssize_t bcm47xx_wdt_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
-{
- if (len) {
- if (!nowayout) {
- size_t i;
-
- expect_release = 0;
-
- for (i = 0; i != len; i++) {
- char c;
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V')
- expect_release = 42;
- }
- }
- bcm47xx_wdt_pet();
- }
- return len;
-}
-
static const struct watchdog_info bcm47xx_wdt_info = {
.identity = DRV_NAME,
.options = WDIOF_SETTIMEOUT |
@@ -180,80 +130,25 @@ static const struct watchdog_info bcm47xx_wdt_info = {
WDIOF_MAGICCLOSE,
};
-static long bcm47xx_wdt_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
- int new_value, retval = -EINVAL;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user(argp, &bcm47xx_wdt_info,
- sizeof(bcm47xx_wdt_info)) ? -EFAULT : 0;
-
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- return put_user(0, p);
-
- case WDIOC_SETOPTIONS:
- if (get_user(new_value, p))
- return -EFAULT;
-
- if (new_value & WDIOS_DISABLECARD) {
- bcm47xx_wdt_stop();
- retval = 0;
- }
-
- if (new_value & WDIOS_ENABLECARD) {
- bcm47xx_wdt_start();
- retval = 0;
- }
-
- return retval;
-
- case WDIOC_KEEPALIVE:
- bcm47xx_wdt_pet();
- return 0;
-
- case WDIOC_SETTIMEOUT:
- if (get_user(new_value, p))
- return -EFAULT;
-
- if (bcm47xx_wdt_settimeout(new_value))
- return -EINVAL;
-
- bcm47xx_wdt_pet();
-
- case WDIOC_GETTIMEOUT:
- return put_user(wdt_time, p);
-
- default:
- return -ENOTTY;
- }
-}
-
static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
- unsigned long code, void *unused)
+ unsigned long code, void *unused)
{
if (code == SYS_DOWN || code == SYS_HALT)
bcm47xx_wdt_stop();
return NOTIFY_DONE;
}
-static const struct file_operations bcm47xx_wdt_fops = {
+static struct watchdog_ops bcm47xx_wdt_ops = {
.owner = THIS_MODULE,
- .llseek = no_llseek,
- .unlocked_ioctl = bcm47xx_wdt_ioctl,
- .open = bcm47xx_wdt_open,
- .release = bcm47xx_wdt_release,
- .write = bcm47xx_wdt_write,
+ .start = bcm47xx_wdt_start,
+ .stop = bcm47xx_wdt_stop,
+ .ping = bcm47xx_wdt_keepalive,
+ .set_timeout = bcm47xx_wdt_set_timeout,
};
-static struct miscdevice bcm47xx_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &bcm47xx_wdt_fops,
+static struct watchdog_device bcm47xx_wdt_wdd = {
+ .info = &bcm47xx_wdt_info,
+ .ops = &bcm47xx_wdt_ops,
};
static struct notifier_block bcm47xx_wdt_notifier = {
@@ -274,12 +169,13 @@ static int __init bcm47xx_wdt_init(void)
pr_info("wdt_time value must be 0 < wdt_time < %d, using %d\n",
(WDT_MAX_TIME + 1), wdt_time);
}
+ watchdog_set_nowayout(&bcm47xx_wdt_wdd, nowayout);
ret = register_reboot_notifier(&bcm47xx_wdt_notifier);
if (ret)
return ret;
- ret = misc_register(&bcm47xx_wdt_miscdev);
+ ret = watchdog_register_device(&bcm47xx_wdt_wdd);
if (ret) {
unregister_reboot_notifier(&bcm47xx_wdt_notifier);
return ret;
@@ -292,10 +188,7 @@ static int __init bcm47xx_wdt_init(void)
static void __exit bcm47xx_wdt_exit(void)
{
- if (!nowayout)
- bcm47xx_wdt_stop();
-
- misc_deregister(&bcm47xx_wdt_miscdev);
+ watchdog_unregister_device(&bcm47xx_wdt_wdd);
unregister_reboot_notifier(&bcm47xx_wdt_notifier);
}
@@ -306,4 +199,3 @@ module_exit(bcm47xx_wdt_exit);
MODULE_AUTHOR("Aleksandar Radovanovic");
MODULE_DESCRIPTION("Watchdog driver for Broadcom BCM47xx");
MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 2/5] watchdog: bcm47xx_wdt.c: use platform device
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 1/5] watchdog: bcm47xx_wdt.c: convert to watchdog core api Hauke Mehrtens
@ 2013-01-12 17:14 ` Hauke Mehrtens
2013-01-24 17:13 ` [PATCH v5 " Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 3/5] watchdog: bcm47xx_wdt.c: rename ops methods Hauke Mehrtens
` (4 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-12 17:14 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips, Hauke Mehrtens
Instead of accessing the function to set the watchdog timer directly,
register a platform driver the platform could register to use this
watchdog driver.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/watchdog/bcm47xx_wdt.c | 156 ++++++++++++++++++++--------------------
include/linux/bcm47xx_wdt.h | 9 +++
2 files changed, 87 insertions(+), 78 deletions(-)
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 4c520d6..cf1191b 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2008 Aleksandar Radovanovic <biblbroks@sezampro.rs>
* Copyright (C) 2009 Matthieu CASTET <castet.matthieu@free.fr>
+ * Copyright (C) 2012 Hauke Mehrtens <hauke@hauke-m.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -12,19 +13,19 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/bcm47xx_wdt.h>
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
-#include <linux/ssb/ssb_embedded.h>
-#include <asm/mach-bcm47xx/bcm47xx.h>
#define DRV_NAME "bcm47xx_wdt"
@@ -43,48 +44,19 @@ MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-static struct timer_list wdt_timer;
-static atomic_t ticks;
-
-static inline void bcm47xx_wdt_hw_start(void)
+static inline struct bcm47xx_wdt *bcm47xx_wdt_get(struct watchdog_device *wdd)
{
- /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
- switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
- case BCM47XX_BUS_TYPE_SSB:
- ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
- break;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
- case BCM47XX_BUS_TYPE_BCMA:
- bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
- 0xfffffff);
- break;
-#endif
- }
+ return container_of(wdd, struct bcm47xx_wdt, wdd);
}
-static inline int bcm47xx_wdt_hw_stop(void)
+static void bcm47xx_timer_tick(unsigned long data)
{
- switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
- case BCM47XX_BUS_TYPE_SSB:
- return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
- case BCM47XX_BUS_TYPE_BCMA:
- bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
- return 0;
-#endif
- }
- return -EINVAL;
-}
+ struct bcm47xx_wdt *wdt = (struct bcm47xx_wdt *)data;
+ u32 next_tick = min(wdt->wdd.timeout * 1000, wdt->max_timer_ms);
-static void bcm47xx_timer_tick(unsigned long unused)
-{
- if (!atomic_dec_and_test(&ticks)) {
- bcm47xx_wdt_hw_start();
- mod_timer(&wdt_timer, jiffies + HZ);
+ if (!atomic_dec_and_test(&wdt->soft_ticks)) {
+ wdt->timer_set_ms(wdt, next_tick);
+ mod_timer(&wdt->soft_timer, jiffies + HZ);
} else {
pr_crit("Watchdog will fire soon!!!\n");
}
@@ -92,23 +64,29 @@ static void bcm47xx_timer_tick(unsigned long unused)
static int bcm47xx_wdt_keepalive(struct watchdog_device *wdd)
{
- atomic_set(&ticks, wdt_time);
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ atomic_set(&wdt->soft_ticks, wdd->timeout);
return 0;
}
static int bcm47xx_wdt_start(struct watchdog_device *wdd)
{
- bcm47xx_wdt_pet();
- bcm47xx_timer_tick(0);
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ bcm47xx_wdt_keepalive(wdd);
+ bcm47xx_timer_tick((unsigned long)wdt);
return 0;
}
static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
{
- del_timer_sync(&wdt_timer);
- bcm47xx_wdt_hw_stop();
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ del_timer_sync(&wdt->soft_timer);
+ wdt->timer_set(wdt, 0);
return 0;
}
@@ -116,10 +94,13 @@ static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
static int bcm47xx_wdt_set_timeout(struct watchdog_device *wdd,
unsigned int new_time)
{
- if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
+ if (new_time < 1 || new_time > WDT_MAX_TIME) {
+ pr_warn("timeout value must be 1<=x<=%d, using %d\n",
+ WDT_MAX_TIME, new_time);
return -EINVAL;
+ }
- wdt_time = new_time;
+ wdd->timeout = new_time;
return 0;
}
@@ -133,8 +114,11 @@ static const struct watchdog_info bcm47xx_wdt_info = {
static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
unsigned long code, void *unused)
{
+ struct bcm47xx_wdt *wdt;
+
+ wdt = container_of(this, struct bcm47xx_wdt, notifier);
if (code == SYS_DOWN || code == SYS_HALT)
- bcm47xx_wdt_stop();
+ wdt->wdd.ops->stop(&wdt->wdd);
return NOTIFY_DONE;
}
@@ -146,56 +130,72 @@ static struct watchdog_ops bcm47xx_wdt_ops = {
.set_timeout = bcm47xx_wdt_set_timeout,
};
-static struct watchdog_device bcm47xx_wdt_wdd = {
- .info = &bcm47xx_wdt_info,
- .ops = &bcm47xx_wdt_ops,
-};
-
-static struct notifier_block bcm47xx_wdt_notifier = {
- .notifier_call = bcm47xx_wdt_notify_sys,
-};
-
-static int __init bcm47xx_wdt_init(void)
+static int __devinit bcm47xx_wdt_probe(struct platform_device *pdev)
{
int ret;
+ struct bcm47xx_wdt *wdt = dev_get_platdata(&pdev->dev);
- if (bcm47xx_wdt_hw_stop() < 0)
- return -ENODEV;
+ if (!wdt)
+ return -ENXIO;
- setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
+ setup_timer(&wdt->soft_timer, bcm47xx_timer_tick,
+ (long unsigned int)wdt);
- if (bcm47xx_wdt_settimeout(wdt_time)) {
- bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME);
- pr_info("wdt_time value must be 0 < wdt_time < %d, using %d\n",
- (WDT_MAX_TIME + 1), wdt_time);
- }
- watchdog_set_nowayout(&bcm47xx_wdt_wdd, nowayout);
+ wdt->wdd.ops = &bcm47xx_wdt_ops;
+ wdt->wdd.info = &bcm47xx_wdt_info;
+ wdt->wdd.timeout = WDT_DEFAULT_TIME;
+ ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
+ if (ret)
+ goto err_timer;
+ watchdog_set_nowayout(&wdt->wdd, nowayout);
+
+ wdt->notifier.notifier_call = &bcm47xx_wdt_notify_sys;
- ret = register_reboot_notifier(&bcm47xx_wdt_notifier);
+ ret = register_reboot_notifier(&wdt->notifier);
if (ret)
- return ret;
+ goto err_timer;
- ret = watchdog_register_device(&bcm47xx_wdt_wdd);
- if (ret) {
- unregister_reboot_notifier(&bcm47xx_wdt_notifier);
- return ret;
- }
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret)
+ goto err_notifier;
pr_info("BCM47xx Watchdog Timer enabled (%d seconds%s)\n",
wdt_time, nowayout ? ", nowayout" : "");
return 0;
+
+err_notifier:
+ unregister_reboot_notifier(&wdt->notifier);
+err_timer:
+ del_timer_sync(&wdt->soft_timer);
+
+ return ret;
}
-static void __exit bcm47xx_wdt_exit(void)
+static int __devexit bcm47xx_wdt_remove(struct platform_device *pdev)
{
- watchdog_unregister_device(&bcm47xx_wdt_wdd);
+ struct bcm47xx_wdt *wdt = dev_get_platdata(&pdev->dev);
+
+ if (!wdt)
+ return -ENXIO;
+
+ watchdog_unregister_device(&wdt->wdd);
+ unregister_reboot_notifier(&wdt->notifier);
- unregister_reboot_notifier(&bcm47xx_wdt_notifier);
+ return 0;
}
-module_init(bcm47xx_wdt_init);
-module_exit(bcm47xx_wdt_exit);
+static struct platform_driver bcm47xx_wdt_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "bcm47xx-wdt",
+ },
+ .probe = bcm47xx_wdt_probe,
+ .remove = __devexit_p(bcm47xx_wdt_remove),
+};
+
+module_platform_driver(bcm47xx_wdt_driver);
MODULE_AUTHOR("Aleksandar Radovanovic");
+MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
MODULE_DESCRIPTION("Watchdog driver for Broadcom BCM47xx");
MODULE_LICENSE("GPL");
diff --git a/include/linux/bcm47xx_wdt.h b/include/linux/bcm47xx_wdt.h
index e5dfc25..b708786 100644
--- a/include/linux/bcm47xx_wdt.h
+++ b/include/linux/bcm47xx_wdt.h
@@ -1,7 +1,10 @@
#ifndef LINUX_BCM47XX_WDT_H_
#define LINUX_BCM47XX_WDT_H_
+#include <linux/notifier.h>
+#include <linux/timer.h>
#include <linux/types.h>
+#include <linux/watchdog.h>
struct bcm47xx_wdt {
@@ -10,6 +13,12 @@ struct bcm47xx_wdt {
u32 max_timer_ms;
void *driver_data;
+
+ struct watchdog_device wdd;
+ struct notifier_block notifier;
+
+ struct timer_list soft_timer;
+ atomic_t soft_ticks;
};
static inline void *bcm47xx_wdt_get_drvdata(struct bcm47xx_wdt *wdt)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 3/5] watchdog: bcm47xx_wdt.c: rename ops methods
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 1/5] watchdog: bcm47xx_wdt.c: convert to watchdog core api Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 2/5] watchdog: bcm47xx_wdt.c: use platform device Hauke Mehrtens
@ 2013-01-12 17:14 ` Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 4/5] watchdog: bcm47xx_wdt.c: rename wdt_time to timeout Hauke Mehrtens
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-12 17:14 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips, Hauke Mehrtens
Rename the methods registered to struct watchdog_ops bcm47xx_wdt_ops in
order to add an other struct watchdog_ops using different ops in the
next patch.
Also rename WDT_MAX_TIME to WDT_SOFTTIMER_MAX.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/watchdog/bcm47xx_wdt.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index cf1191b..ed10762 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -30,7 +30,7 @@
#define DRV_NAME "bcm47xx_wdt"
#define WDT_DEFAULT_TIME 30 /* seconds */
-#define WDT_MAX_TIME 255 /* seconds */
+#define WDT_SOFTTIMER_MAX 255 /* seconds */
static int wdt_time = WDT_DEFAULT_TIME;
static bool nowayout = WATCHDOG_NOWAYOUT;
@@ -49,7 +49,7 @@ static inline struct bcm47xx_wdt *bcm47xx_wdt_get(struct watchdog_device *wdd)
return container_of(wdd, struct bcm47xx_wdt, wdd);
}
-static void bcm47xx_timer_tick(unsigned long data)
+static void bcm47xx_wdt_soft_timer_tick(unsigned long data)
{
struct bcm47xx_wdt *wdt = (struct bcm47xx_wdt *)data;
u32 next_tick = min(wdt->wdd.timeout * 1000, wdt->max_timer_ms);
@@ -62,7 +62,7 @@ static void bcm47xx_timer_tick(unsigned long data)
}
}
-static int bcm47xx_wdt_keepalive(struct watchdog_device *wdd)
+static int bcm47xx_wdt_soft_keepalive(struct watchdog_device *wdd)
{
struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
@@ -71,17 +71,17 @@ static int bcm47xx_wdt_keepalive(struct watchdog_device *wdd)
return 0;
}
-static int bcm47xx_wdt_start(struct watchdog_device *wdd)
+static int bcm47xx_wdt_soft_start(struct watchdog_device *wdd)
{
struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
- bcm47xx_wdt_keepalive(wdd);
- bcm47xx_timer_tick((unsigned long)wdt);
+ bcm47xx_wdt_soft_keepalive(wdd);
+ bcm47xx_wdt_soft_timer_tick((unsigned long)wdt);
return 0;
}
-static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
+static int bcm47xx_wdt_soft_stop(struct watchdog_device *wdd)
{
struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
@@ -91,12 +91,12 @@ static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
return 0;
}
-static int bcm47xx_wdt_set_timeout(struct watchdog_device *wdd,
- unsigned int new_time)
+static int bcm47xx_wdt_soft_set_timeout(struct watchdog_device *wdd,
+ unsigned int new_time)
{
- if (new_time < 1 || new_time > WDT_MAX_TIME) {
+ if (new_time < 1 || new_time > WDT_SOFTTIMER_MAX) {
pr_warn("timeout value must be 1<=x<=%d, using %d\n",
- WDT_MAX_TIME, new_time);
+ WDT_SOFTTIMER_MAX, new_time);
return -EINVAL;
}
@@ -122,12 +122,12 @@ static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
return NOTIFY_DONE;
}
-static struct watchdog_ops bcm47xx_wdt_ops = {
+static struct watchdog_ops bcm47xx_wdt_soft_ops = {
.owner = THIS_MODULE,
- .start = bcm47xx_wdt_start,
- .stop = bcm47xx_wdt_stop,
- .ping = bcm47xx_wdt_keepalive,
- .set_timeout = bcm47xx_wdt_set_timeout,
+ .start = bcm47xx_wdt_soft_start,
+ .stop = bcm47xx_wdt_soft_stop,
+ .ping = bcm47xx_wdt_soft_keepalive,
+ .set_timeout = bcm47xx_wdt_soft_set_timeout,
};
static int __devinit bcm47xx_wdt_probe(struct platform_device *pdev)
@@ -138,10 +138,10 @@ static int __devinit bcm47xx_wdt_probe(struct platform_device *pdev)
if (!wdt)
return -ENXIO;
- setup_timer(&wdt->soft_timer, bcm47xx_timer_tick,
+ setup_timer(&wdt->soft_timer, bcm47xx_wdt_soft_timer_tick,
(long unsigned int)wdt);
- wdt->wdd.ops = &bcm47xx_wdt_ops;
+ wdt->wdd.ops = &bcm47xx_wdt_soft_ops;
wdt->wdd.info = &bcm47xx_wdt_info;
wdt->wdd.timeout = WDT_DEFAULT_TIME;
ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 4/5] watchdog: bcm47xx_wdt.c: rename wdt_time to timeout
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
` (2 preceding siblings ...)
2013-01-12 17:14 ` [PATCH v4 3/5] watchdog: bcm47xx_wdt.c: rename ops methods Hauke Mehrtens
@ 2013-01-12 17:14 ` Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 5/5] watchdog: bcm47xx_wdt.c: add hard timer Hauke Mehrtens
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-12 17:14 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips, Hauke Mehrtens
Rename wdt_time to timeout to name it like the other watchdog
driver do it.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/watchdog/bcm47xx_wdt.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index ed10762..f188097 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -32,11 +32,11 @@
#define WDT_DEFAULT_TIME 30 /* seconds */
#define WDT_SOFTTIMER_MAX 255 /* seconds */
-static int wdt_time = WDT_DEFAULT_TIME;
+static int timeout = WDT_DEFAULT_TIME;
static bool nowayout = WATCHDOG_NOWAYOUT;
-module_param(wdt_time, int, 0);
-MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout, "Watchdog time in seconds. (default="
__MODULE_STRING(WDT_DEFAULT_TIME) ")");
module_param(nowayout, bool, 0);
@@ -160,7 +160,7 @@ static int __devinit bcm47xx_wdt_probe(struct platform_device *pdev)
goto err_notifier;
pr_info("BCM47xx Watchdog Timer enabled (%d seconds%s)\n",
- wdt_time, nowayout ? ", nowayout" : "");
+ timeout, nowayout ? ", nowayout" : "");
return 0;
err_notifier:
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v4 5/5] watchdog: bcm47xx_wdt.c: add hard timer
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
` (3 preceding siblings ...)
2013-01-12 17:14 ` [PATCH v4 4/5] watchdog: bcm47xx_wdt.c: rename wdt_time to timeout Hauke Mehrtens
@ 2013-01-12 17:14 ` Hauke Mehrtens
2013-01-24 17:15 ` [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
2013-02-07 22:29 ` Wim Van Sebroeck
6 siblings, 0 replies; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-12 17:14 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips, Hauke Mehrtens
The more recent devices have a watchdog timer which could be configured
for over 2 hours and not just 2 seconds like the first generation
devices. For those devices do not use the extra software timer, but
directly program the time into the register. This will automatically be
used if the timer supports more than a minute.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
drivers/watchdog/bcm47xx_wdt.c | 69 ++++++++++++++++++++++++++++++++++++----
1 file changed, 63 insertions(+), 6 deletions(-)
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index f188097..9cb69ad 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -31,6 +31,7 @@
#define WDT_DEFAULT_TIME 30 /* seconds */
#define WDT_SOFTTIMER_MAX 255 /* seconds */
+#define WDT_SOFTTIMER_THRESHOLD 60 /* seconds */
static int timeout = WDT_DEFAULT_TIME;
static bool nowayout = WATCHDOG_NOWAYOUT;
@@ -49,6 +50,53 @@ static inline struct bcm47xx_wdt *bcm47xx_wdt_get(struct watchdog_device *wdd)
return container_of(wdd, struct bcm47xx_wdt, wdd);
}
+static int bcm47xx_wdt_hard_keepalive(struct watchdog_device *wdd)
+{
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ wdt->timer_set_ms(wdt, wdd->timeout * 1000);
+
+ return 0;
+}
+
+static int bcm47xx_wdt_hard_start(struct watchdog_device *wdd)
+{
+ return 0;
+}
+
+static int bcm47xx_wdt_hard_stop(struct watchdog_device *wdd)
+{
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ wdt->timer_set(wdt, 0);
+
+ return 0;
+}
+
+static int bcm47xx_wdt_hard_set_timeout(struct watchdog_device *wdd,
+ unsigned int new_time)
+{
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+ u32 max_timer = wdt->max_timer_ms;
+
+ if (new_time < 1 || new_time > max_timer / 1000) {
+ pr_warn("timeout value must be 1<=x<=%d, using %d\n",
+ max_timer / 1000, new_time);
+ return -EINVAL;
+ }
+
+ wdd->timeout = new_time;
+ return 0;
+}
+
+static struct watchdog_ops bcm47xx_wdt_hard_ops = {
+ .owner = THIS_MODULE,
+ .start = bcm47xx_wdt_hard_start,
+ .stop = bcm47xx_wdt_hard_stop,
+ .ping = bcm47xx_wdt_hard_keepalive,
+ .set_timeout = bcm47xx_wdt_hard_set_timeout,
+};
+
static void bcm47xx_wdt_soft_timer_tick(unsigned long data)
{
struct bcm47xx_wdt *wdt = (struct bcm47xx_wdt *)data;
@@ -133,15 +181,22 @@ static struct watchdog_ops bcm47xx_wdt_soft_ops = {
static int __devinit bcm47xx_wdt_probe(struct platform_device *pdev)
{
int ret;
+ bool soft;
struct bcm47xx_wdt *wdt = dev_get_platdata(&pdev->dev);
if (!wdt)
return -ENXIO;
- setup_timer(&wdt->soft_timer, bcm47xx_wdt_soft_timer_tick,
- (long unsigned int)wdt);
+ soft = wdt->max_timer_ms < WDT_SOFTTIMER_THRESHOLD * 1000;
+
+ if (soft) {
+ wdt->wdd.ops = &bcm47xx_wdt_soft_ops;
+ setup_timer(&wdt->soft_timer, bcm47xx_wdt_soft_timer_tick,
+ (long unsigned int)wdt);
+ } else {
+ wdt->wdd.ops = &bcm47xx_wdt_hard_ops;
+ }
- wdt->wdd.ops = &bcm47xx_wdt_soft_ops;
wdt->wdd.info = &bcm47xx_wdt_info;
wdt->wdd.timeout = WDT_DEFAULT_TIME;
ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
@@ -159,14 +214,16 @@ static int __devinit bcm47xx_wdt_probe(struct platform_device *pdev)
if (ret)
goto err_notifier;
- pr_info("BCM47xx Watchdog Timer enabled (%d seconds%s)\n",
- timeout, nowayout ? ", nowayout" : "");
+ dev_info(&pdev->dev, "BCM47xx Watchdog Timer enabled (%d seconds%s%s)\n",
+ timeout, nowayout ? ", nowayout" : "",
+ soft ? ", Software Timer" : "");
return 0;
err_notifier:
unregister_reboot_notifier(&wdt->notifier);
err_timer:
- del_timer_sync(&wdt->soft_timer);
+ if (soft)
+ del_timer_sync(&wdt->soft_timer);
return ret;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 2/5] watchdog: bcm47xx_wdt.c: use platform device
2013-01-12 17:14 ` [PATCH v4 2/5] watchdog: bcm47xx_wdt.c: use platform device Hauke Mehrtens
@ 2013-01-24 17:13 ` Hauke Mehrtens
0 siblings, 0 replies; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-24 17:13 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips, Hauke Mehrtens
Instead of accessing the function to set the watchdog timer directly,
register a platform driver the platform could register to use this
watchdog driver.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
v5:
* remove usage of __devinit __devexit and __devexit_p, usage will
cause build errors when merged with 3.8-rc4.
drivers/watchdog/bcm47xx_wdt.c | 156 ++++++++++++++++++++--------------------
include/linux/bcm47xx_wdt.h | 9 +++
2 files changed, 87 insertions(+), 78 deletions(-)
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index 4c520d6..97ccfce 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2008 Aleksandar Radovanovic <biblbroks@sezampro.rs>
* Copyright (C) 2009 Matthieu CASTET <castet.matthieu@free.fr>
+ * Copyright (C) 2012-2013 Hauke Mehrtens <hauke@hauke-m.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -12,19 +13,19 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/bcm47xx_wdt.h>
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/types.h>
#include <linux/watchdog.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
-#include <linux/ssb/ssb_embedded.h>
-#include <asm/mach-bcm47xx/bcm47xx.h>
#define DRV_NAME "bcm47xx_wdt"
@@ -43,48 +44,19 @@ MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-static struct timer_list wdt_timer;
-static atomic_t ticks;
-
-static inline void bcm47xx_wdt_hw_start(void)
+static inline struct bcm47xx_wdt *bcm47xx_wdt_get(struct watchdog_device *wdd)
{
- /* this is 2,5s on 100Mhz clock and 2s on 133 Mhz */
- switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
- case BCM47XX_BUS_TYPE_SSB:
- ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
- break;
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
- case BCM47XX_BUS_TYPE_BCMA:
- bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
- 0xfffffff);
- break;
-#endif
- }
+ return container_of(wdd, struct bcm47xx_wdt, wdd);
}
-static inline int bcm47xx_wdt_hw_stop(void)
+static void bcm47xx_timer_tick(unsigned long data)
{
- switch (bcm47xx_bus_type) {
-#ifdef CONFIG_BCM47XX_SSB
- case BCM47XX_BUS_TYPE_SSB:
- return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
-#endif
-#ifdef CONFIG_BCM47XX_BCMA
- case BCM47XX_BUS_TYPE_BCMA:
- bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
- return 0;
-#endif
- }
- return -EINVAL;
-}
+ struct bcm47xx_wdt *wdt = (struct bcm47xx_wdt *)data;
+ u32 next_tick = min(wdt->wdd.timeout * 1000, wdt->max_timer_ms);
-static void bcm47xx_timer_tick(unsigned long unused)
-{
- if (!atomic_dec_and_test(&ticks)) {
- bcm47xx_wdt_hw_start();
- mod_timer(&wdt_timer, jiffies + HZ);
+ if (!atomic_dec_and_test(&wdt->soft_ticks)) {
+ wdt->timer_set_ms(wdt, next_tick);
+ mod_timer(&wdt->soft_timer, jiffies + HZ);
} else {
pr_crit("Watchdog will fire soon!!!\n");
}
@@ -92,23 +64,29 @@ static void bcm47xx_timer_tick(unsigned long unused)
static int bcm47xx_wdt_keepalive(struct watchdog_device *wdd)
{
- atomic_set(&ticks, wdt_time);
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ atomic_set(&wdt->soft_ticks, wdd->timeout);
return 0;
}
static int bcm47xx_wdt_start(struct watchdog_device *wdd)
{
- bcm47xx_wdt_pet();
- bcm47xx_timer_tick(0);
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ bcm47xx_wdt_keepalive(wdd);
+ bcm47xx_timer_tick((unsigned long)wdt);
return 0;
}
static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
{
- del_timer_sync(&wdt_timer);
- bcm47xx_wdt_hw_stop();
+ struct bcm47xx_wdt *wdt = bcm47xx_wdt_get(wdd);
+
+ del_timer_sync(&wdt->soft_timer);
+ wdt->timer_set(wdt, 0);
return 0;
}
@@ -116,10 +94,13 @@ static int bcm47xx_wdt_stop(struct watchdog_device *wdd)
static int bcm47xx_wdt_set_timeout(struct watchdog_device *wdd,
unsigned int new_time)
{
- if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
+ if (new_time < 1 || new_time > WDT_MAX_TIME) {
+ pr_warn("timeout value must be 1<=x<=%d, using %d\n",
+ WDT_MAX_TIME, new_time);
return -EINVAL;
+ }
- wdt_time = new_time;
+ wdd->timeout = new_time;
return 0;
}
@@ -133,8 +114,11 @@ static const struct watchdog_info bcm47xx_wdt_info = {
static int bcm47xx_wdt_notify_sys(struct notifier_block *this,
unsigned long code, void *unused)
{
+ struct bcm47xx_wdt *wdt;
+
+ wdt = container_of(this, struct bcm47xx_wdt, notifier);
if (code == SYS_DOWN || code == SYS_HALT)
- bcm47xx_wdt_stop();
+ wdt->wdd.ops->stop(&wdt->wdd);
return NOTIFY_DONE;
}
@@ -146,56 +130,72 @@ static struct watchdog_ops bcm47xx_wdt_ops = {
.set_timeout = bcm47xx_wdt_set_timeout,
};
-static struct watchdog_device bcm47xx_wdt_wdd = {
- .info = &bcm47xx_wdt_info,
- .ops = &bcm47xx_wdt_ops,
-};
-
-static struct notifier_block bcm47xx_wdt_notifier = {
- .notifier_call = bcm47xx_wdt_notify_sys,
-};
-
-static int __init bcm47xx_wdt_init(void)
+static int bcm47xx_wdt_probe(struct platform_device *pdev)
{
int ret;
+ struct bcm47xx_wdt *wdt = dev_get_platdata(&pdev->dev);
- if (bcm47xx_wdt_hw_stop() < 0)
- return -ENODEV;
+ if (!wdt)
+ return -ENXIO;
- setup_timer(&wdt_timer, bcm47xx_timer_tick, 0L);
+ setup_timer(&wdt->soft_timer, bcm47xx_timer_tick,
+ (long unsigned int)wdt);
- if (bcm47xx_wdt_settimeout(wdt_time)) {
- bcm47xx_wdt_settimeout(WDT_DEFAULT_TIME);
- pr_info("wdt_time value must be 0 < wdt_time < %d, using %d\n",
- (WDT_MAX_TIME + 1), wdt_time);
- }
- watchdog_set_nowayout(&bcm47xx_wdt_wdd, nowayout);
+ wdt->wdd.ops = &bcm47xx_wdt_ops;
+ wdt->wdd.info = &bcm47xx_wdt_info;
+ wdt->wdd.timeout = WDT_DEFAULT_TIME;
+ ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
+ if (ret)
+ goto err_timer;
+ watchdog_set_nowayout(&wdt->wdd, nowayout);
+
+ wdt->notifier.notifier_call = &bcm47xx_wdt_notify_sys;
- ret = register_reboot_notifier(&bcm47xx_wdt_notifier);
+ ret = register_reboot_notifier(&wdt->notifier);
if (ret)
- return ret;
+ goto err_timer;
- ret = watchdog_register_device(&bcm47xx_wdt_wdd);
- if (ret) {
- unregister_reboot_notifier(&bcm47xx_wdt_notifier);
- return ret;
- }
+ ret = watchdog_register_device(&wdt->wdd);
+ if (ret)
+ goto err_notifier;
pr_info("BCM47xx Watchdog Timer enabled (%d seconds%s)\n",
wdt_time, nowayout ? ", nowayout" : "");
return 0;
+
+err_notifier:
+ unregister_reboot_notifier(&wdt->notifier);
+err_timer:
+ del_timer_sync(&wdt->soft_timer);
+
+ return ret;
}
-static void __exit bcm47xx_wdt_exit(void)
+static int bcm47xx_wdt_remove(struct platform_device *pdev)
{
- watchdog_unregister_device(&bcm47xx_wdt_wdd);
+ struct bcm47xx_wdt *wdt = dev_get_platdata(&pdev->dev);
+
+ if (!wdt)
+ return -ENXIO;
+
+ watchdog_unregister_device(&wdt->wdd);
+ unregister_reboot_notifier(&wdt->notifier);
- unregister_reboot_notifier(&bcm47xx_wdt_notifier);
+ return 0;
}
-module_init(bcm47xx_wdt_init);
-module_exit(bcm47xx_wdt_exit);
+static struct platform_driver bcm47xx_wdt_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "bcm47xx-wdt",
+ },
+ .probe = bcm47xx_wdt_probe,
+ .remove = bcm47xx_wdt_remove,
+};
+
+module_platform_driver(bcm47xx_wdt_driver);
MODULE_AUTHOR("Aleksandar Radovanovic");
+MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
MODULE_DESCRIPTION("Watchdog driver for Broadcom BCM47xx");
MODULE_LICENSE("GPL");
diff --git a/include/linux/bcm47xx_wdt.h b/include/linux/bcm47xx_wdt.h
index e5dfc25..b708786 100644
--- a/include/linux/bcm47xx_wdt.h
+++ b/include/linux/bcm47xx_wdt.h
@@ -1,7 +1,10 @@
#ifndef LINUX_BCM47XX_WDT_H_
#define LINUX_BCM47XX_WDT_H_
+#include <linux/notifier.h>
+#include <linux/timer.h>
#include <linux/types.h>
+#include <linux/watchdog.h>
struct bcm47xx_wdt {
@@ -10,6 +13,12 @@ struct bcm47xx_wdt {
u32 max_timer_ms;
void *driver_data;
+
+ struct watchdog_device wdd;
+ struct notifier_block notifier;
+
+ struct timer_list soft_timer;
+ atomic_t soft_ticks;
};
static inline void *bcm47xx_wdt_get_drvdata(struct bcm47xx_wdt *wdt)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
` (4 preceding siblings ...)
2013-01-12 17:14 ` [PATCH v4 5/5] watchdog: bcm47xx_wdt.c: add hard timer Hauke Mehrtens
@ 2013-01-24 17:15 ` Hauke Mehrtens
2013-01-28 21:35 ` Wim Van Sebroeck
2013-02-07 22:29 ` Wim Van Sebroeck
6 siblings, 1 reply; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-24 17:15 UTC (permalink / raw)
To: wim; +Cc: linux-watchdog, zajec5, linux-mips
On 01/12/2013 06:14 PM, Hauke Mehrtens wrote:
> This patch series improves the functions for setting the watchdog
> driver for bcm47xx based SoCs using ssb and bcma. This makes the
> watchdog driver use the platform device provided by bcma or ssb.
>
> This code is currently based on the linux-watchdog/master tree by
> Wim Van Sebroeck.
>
> v4:
> * Just the parts changing the watchdog driver itself and not ssb or bcma.
>
> v3:
> * Remove changes done to the watchdog driver so John could pull this
> into wireless-testing, this sill works with the old watchdog driver.
> The patches changing the watchdog driver will be send later.
> This was done to get this into 3.8 because Wim Van Sebroeck is
> neither giving an Ack or a Nack on these patches and we want to do
> more changes to bcma/ssb on top of these.
>
> v2:
> * reword some commit messages
> * rebase on current wireless-testing/master with
> "ssb: extif: fix compile errors" applied on top of it.
> * do not change value of WDT_SOFTTIMER_MAX
> * moved some small changes in the bcm47xx_wdt.c patches
>
> Hauke Mehrtens (5):
> watchdog: bcm47xx_wdt.c: convert to watchdog core api
> watchdog: bcm47xx_wdt.c: use platform device
> watchdog: bcm47xx_wdt.c: rename ops methods
> watchdog: bcm47xx_wdt.c: rename wdt_time to timeout
> watchdog: bcm47xx_wdt.c: add hard timer
>
> drivers/watchdog/Kconfig | 1 +
> drivers/watchdog/bcm47xx_wdt.c | 339 +++++++++++++++++-----------------------
> include/linux/bcm47xx_wdt.h | 9 ++
> 3 files changed, 154 insertions(+), 195 deletions(-)
>
Hi Wim,
what is the status of these patches?
Hauke
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU
2013-01-24 17:15 ` [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
@ 2013-01-28 21:35 ` Wim Van Sebroeck
2013-01-28 22:06 ` Hauke Mehrtens
0 siblings, 1 reply; 11+ messages in thread
From: Wim Van Sebroeck @ 2013-01-28 21:35 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linux-watchdog, zajec5, linux-mips
Hi Hauke,
> what is the status of these patches?
First reading/checking (v4+v5) seems OK.
1 small remark allready: the settimeout functions seem to check the min and max timeout values.
Can't you use the min and max values of the watchdog structure for this?
Kind regards,
Wim.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU
2013-01-28 21:35 ` Wim Van Sebroeck
@ 2013-01-28 22:06 ` Hauke Mehrtens
0 siblings, 0 replies; 11+ messages in thread
From: Hauke Mehrtens @ 2013-01-28 22:06 UTC (permalink / raw)
To: Wim Van Sebroeck; +Cc: linux-watchdog, zajec5, linux-mips
On 01/28/2013 10:35 PM, Wim Van Sebroeck wrote:
> Hi Hauke,
>
>> what is the status of these patches?
>
> First reading/checking (v4+v5) seems OK.
> 1 small remark allready: the settimeout functions seem to check the min and max timeout values.
> Can't you use the min and max values of the watchdog structure for this?
>
> Kind regards,
> Wim.
>
Hi Wim,
The max_timer_ms attribute in struct bcm47xx_wdt contains the maximum
value the hardware is capable of, the watchdog driver uses a softtimer
if this value is too low and in that case it is no problem if a
userspace application sets the timeout to some value higher than
max_timer_ms.
If I would use max_timeout from struct watchdog_device I would have to
change that values when softtimer is selected.
The best solution would be if the softtimer choice and implementation
would go to watchdog_dev.c as some more watchdog driver do something
similar.
Hauke
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
` (5 preceding siblings ...)
2013-01-24 17:15 ` [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
@ 2013-02-07 22:29 ` Wim Van Sebroeck
6 siblings, 0 replies; 11+ messages in thread
From: Wim Van Sebroeck @ 2013-02-07 22:29 UTC (permalink / raw)
To: Hauke Mehrtens; +Cc: linux-watchdog, zajec5, linux-mips
Hi Hauke
> This patch series improves the functions for setting the watchdog
> driver for bcm47xx based SoCs using ssb and bcma. This makes the
> watchdog driver use the platform device provided by bcma or ssb.
>
> This code is currently based on the linux-watchdog/master tree by
> Wim Van Sebroeck.
V5 patches have been added to linux-watchdog-next.
Kind regards,
Wim.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2013-02-07 22:29 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-12 17:14 [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 1/5] watchdog: bcm47xx_wdt.c: convert to watchdog core api Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 2/5] watchdog: bcm47xx_wdt.c: use platform device Hauke Mehrtens
2013-01-24 17:13 ` [PATCH v5 " Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 3/5] watchdog: bcm47xx_wdt.c: rename ops methods Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 4/5] watchdog: bcm47xx_wdt.c: rename wdt_time to timeout Hauke Mehrtens
2013-01-12 17:14 ` [PATCH v4 5/5] watchdog: bcm47xx_wdt.c: add hard timer Hauke Mehrtens
2013-01-24 17:15 ` [PATCH v4 0/5] watchdog: bcm47xx_wdt.c: add support for SoCs with PMU Hauke Mehrtens
2013-01-28 21:35 ` Wim Van Sebroeck
2013-01-28 22:06 ` Hauke Mehrtens
2013-02-07 22:29 ` Wim Van Sebroeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox