summaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/watchdog')
-rw-r--r--drivers/watchdog/efi_wdt.c1
-rw-r--r--drivers/watchdog/stm32_iwdg.c1
-rw-r--r--drivers/watchdog/stpmic1_wdt.c1
-rw-r--r--drivers/watchdog/wd_core.c73
4 files changed, 50 insertions, 26 deletions
diff --git a/drivers/watchdog/efi_wdt.c b/drivers/watchdog/efi_wdt.c
index 8e3e51b7a9..ea1ede1381 100644
--- a/drivers/watchdog/efi_wdt.c
+++ b/drivers/watchdog/efi_wdt.c
@@ -41,6 +41,7 @@ static int efi_wdt_probe(struct device_d *dev)
priv->wd.set_timeout = efi_wdt_set_timeout;
priv->wd.hwdev = dev;
priv->dev = dev;
+ priv->wd.priority = WATCHDOG_DEFAULT_PRIORITY - 50;
dev->priv = priv;
diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index 20536cb4ab..4d252e558c 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -256,7 +256,6 @@ static int stm32_iwdg_probe(struct device_d *dev)
wdd->set_timeout = stm32_iwdg_set_timeout;
wdd->timeout_max = (RLR_MAX + 1) * data->max_prescaler * 1000;
wdd->timeout_max /= wd->rate * 1000;
- wdd->timeout_cur = wdd->timeout_max;
ret = watchdog_register(wdd);
if (ret) {
diff --git a/drivers/watchdog/stpmic1_wdt.c b/drivers/watchdog/stpmic1_wdt.c
index 5d9720c230..9b7a586387 100644
--- a/drivers/watchdog/stpmic1_wdt.c
+++ b/drivers/watchdog/stpmic1_wdt.c
@@ -178,7 +178,6 @@ static int stpmic1_wdt_probe(struct device_d *dev)
wdd->hwdev = dev;
wdd->set_timeout = stpmic1_wdt_set_timeout;
wdd->timeout_max = PMIC_WDT_MAX_TIMEOUT;
- wdd->timeout_cur = PMIC_WDT_DEFAULT_TIMEOUT;
/* have the watchdog reset, not power-off the system */
regmap_write_bits(wdt->regmap, MAIN_CR, RREQ_EN, RREQ_EN);
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index e6e5ddecd2..8b13950238 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -31,8 +31,15 @@ static const char *watchdog_name(struct watchdog *wd)
return "unknown";
}
-static int _watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
+/*
+ * start, stop or retrigger the watchdog
+ * timeout in [seconds]. timeout of '0' will disable the watchdog (if possible)
+ */
+int watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
{
+ if (!wd)
+ return -ENODEV;
+
if (timeout > wd->timeout_max)
return -EINVAL;
@@ -40,12 +47,23 @@ static int _watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
return wd->set_timeout(wd, timeout);
}
+EXPORT_SYMBOL(watchdog_set_timeout);
+
+static int watchdog_set_priority(struct param_d *param, void *priv)
+{
+ struct watchdog *wd = priv;
+
+ if (wd->priority == 0)
+ return watchdog_set_timeout(wd, 0);
+
+ return 0;
+}
static int watchdog_set_cur(struct param_d *param, void *priv)
{
struct watchdog *wd = priv;
- if (wd->timeout_cur > wd->timeout_max)
+ if (wd->poller_timeout_cur > wd->timeout_max)
return -EINVAL;
return 0;
@@ -55,7 +73,7 @@ static void watchdog_poller_cb(void *priv);
static void watchdog_poller_start(struct watchdog *wd)
{
- _watchdog_set_timeout(wd, wd->timeout_cur);
+ watchdog_set_timeout(wd, wd->poller_timeout_cur);
poller_call_async(&wd->poller, 500 * MSECOND,
watchdog_poller_cb, wd);
@@ -130,24 +148,31 @@ int watchdog_register(struct watchdog *wd)
if (!wd->priority)
wd->priority = WATCHDOG_DEFAULT_PRIORITY;
+ p = dev_add_param_uint32(&wd->dev, "priority",
+ watchdog_set_priority, NULL,
+ &wd->priority, "%u", wd);
+ if (IS_ERR(p))
+ return PTR_ERR(p);
+
/* set some default sane value */
if (!wd->timeout_max)
wd->timeout_max = 60 * 60 * 24;
- if (!wd->timeout_cur || wd->timeout_cur > wd->timeout_max)
- wd->timeout_cur = wd->timeout_max;
-
p = dev_add_param_uint32_ro(&wd->dev, "timeout_max",
&wd->timeout_max, "%u");
if (IS_ERR(p))
return PTR_ERR(p);
- p = dev_add_param_uint32(&wd->dev, "timeout_cur", watchdog_set_cur, NULL,
- &wd->timeout_cur, "%u", wd);
- if (IS_ERR(p))
- return PTR_ERR(p);
-
if (IS_ENABLED(CONFIG_WATCHDOG_POLLER)) {
+ if (!wd->poller_timeout_cur ||
+ wd->poller_timeout_cur > wd->timeout_max)
+ wd->poller_timeout_cur = wd->timeout_max;
+
+ p = dev_add_param_uint32(&wd->dev, "timeout_cur", watchdog_set_cur,
+ NULL, &wd->poller_timeout_cur, "%u", wd);
+ if (IS_ERR(p))
+ return PTR_ERR(p);
+
ret = watchdog_register_poller(wd);
if (ret)
return ret;
@@ -176,7 +201,7 @@ int watchdog_deregister(struct watchdog *wd)
}
EXPORT_SYMBOL(watchdog_deregister);
-static struct watchdog *watchdog_get_default(void)
+struct watchdog *watchdog_get_default(void)
{
struct watchdog *tmp, *wd = NULL;
int priority = 0;
@@ -190,23 +215,23 @@ static struct watchdog *watchdog_get_default(void)
return wd;
}
+EXPORT_SYMBOL(watchdog_get_default);
-/*
- * start, stop or retrigger the watchdog
- * timeout in [seconds]. timeout of '0' will disable the watchdog (if possible)
- */
-int watchdog_set_timeout(unsigned timeout)
+struct watchdog *watchdog_get_by_name(const char *name)
{
- struct watchdog *wd;
+ struct watchdog *tmp;
+ struct device_d *dev = get_device_by_name(name);
+ if (!dev)
+ return NULL;
- wd = watchdog_get_default();
-
- if (!wd)
- return -ENODEV;
+ list_for_each_entry(tmp, &watchdog_list, list) {
+ if (dev == tmp->hwdev || dev == &tmp->dev)
+ return tmp;
+ }
- return _watchdog_set_timeout(wd, timeout);
+ return NULL;
}
-EXPORT_SYMBOL(watchdog_set_timeout);
+EXPORT_SYMBOL(watchdog_get_by_name);
/**
* of_get_watchdog_priority() - get the desired watchdog priority from device tree