mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 1/6] watchdog: rename dev to hwdev
@ 2018-03-13  8:33 Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 2/6] watchdog: move max timeout test in to wd_core Oleksij Rempel
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Oleksij Rempel @ 2018-03-13  8:33 UTC (permalink / raw)
  To: barebox

From: Sascha Hauer <s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/watchdog/ar9344_wdt.c  | 2 +-
 drivers/watchdog/davinci_wdt.c | 2 +-
 drivers/watchdog/dw_wdt.c      | 4 ++--
 drivers/watchdog/im28wd.c      | 2 +-
 drivers/watchdog/imxwd.c       | 2 +-
 drivers/watchdog/orion_wdt.c   | 2 +-
 drivers/watchdog/wd_core.c     | 4 ++--
 include/watchdog.h             | 2 +-
 8 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/watchdog/ar9344_wdt.c b/drivers/watchdog/ar9344_wdt.c
index d570cb40f..c1dfc994a 100644
--- a/drivers/watchdog/ar9344_wdt.c
+++ b/drivers/watchdog/ar9344_wdt.c
@@ -95,7 +95,7 @@ static int ar9344_wdt_probe(struct device_d *dev)
 
 	priv->base = IOMEM(iores->start);
 	priv->wd.set_timeout = ar9344_watchdog_set_timeout;
-	priv->wd.dev = dev;
+	priv->wd.hwdev = dev;
 	priv->dev = dev;
 
 	dev->priv = priv;
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 03dc83408..2ac5f8b38 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -149,7 +149,7 @@ static int davinci_wdt_probe(struct device_d *dev)
 	clk_enable(davinci_wdt->clk);
 
 	davinci_wdt->wd.set_timeout = davinci_wdt_set_timeout;
-	davinci_wdt->wd.dev = dev;
+	davinci_wdt->wd.hwdev = dev;
 
 	ret = watchdog_register(&davinci_wdt->wd);
 	if (ret < 0)
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 8fd8c81e6..85e810f24 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -73,7 +73,7 @@ static int dw_wdt_stop(struct watchdog *wdd)
 	struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
 
 	if (IS_ERR(dw_wdt->rst)) {
-		dev_warn(dw_wdt->wdd.dev, "No reset line. Will not stop.\n");
+		dev_warn(dw_wdt->wdd.hwdev, "No reset line. Will not stop.\n");
 		return PTR_ERR(dw_wdt->rst);
 	}
 
@@ -157,7 +157,7 @@ static int dw_wdt_drv_probe(struct device_d *dev)
 
 	wdd = &dw_wdt->wdd;
 	wdd->name = "dw_wdt";
-	wdd->dev = dev;
+	wdd->hwdev = dev;
 	wdd->set_timeout = dw_wdt_set_timeout;
 
 	ret = watchdog_register(wdd);
diff --git a/drivers/watchdog/im28wd.c b/drivers/watchdog/im28wd.c
index 1956fdb73..43edea8d0 100644
--- a/drivers/watchdog/im28wd.c
+++ b/drivers/watchdog/im28wd.c
@@ -199,7 +199,7 @@ static int imx28_wd_probe(struct device_d *dev)
 		return PTR_ERR(iores);
 	priv->regs = IOMEM(iores->start);
 	priv->wd.set_timeout = imx28_watchdog_set_timeout;
-	priv->wd.dev = dev;
+	priv->wd.hwdev = dev;
 
 	if (!(readl(priv->regs + MXS_RTC_STAT) & MXS_RTC_STAT_WD_PRESENT)) {
 		rc = -ENODEV;
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index bd5e518bc..6b33834fe 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -218,7 +218,7 @@ static int imx_wd_probe(struct device_d *dev)
 	priv->base = IOMEM(iores->start);
 	priv->ops = ops;
 	priv->wd.set_timeout = imx_watchdog_set_timeout;
-	priv->wd.dev = dev;
+	priv->wd.hwdev = dev;
 	priv->dev = dev;
 
 	priv->ext_reset = of_property_read_bool(dev->device_node,
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 2802033f7..4fe1ac1fd 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -88,7 +88,7 @@ static int orion_wdt_probe(struct device_d *dev)
 
 	ddata->wd.set_timeout = armada_xp_set_timeout;
 	ddata->wd.name = "orion_wdt";
-	ddata->wd.dev = dev;
+	ddata->wd.hwdev = dev;
 
 	res_timer = dev_request_mem_resource(dev, 0);
 	if (IS_ERR(res_timer)) {
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 3a3f51964..56436e6f8 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -23,8 +23,8 @@ static LIST_HEAD(watchdog_list);
 
 static const char *watchdog_name(struct watchdog *wd)
 {
-	if (wd->dev)
-		return dev_name(wd->dev);
+	if (wd->hwdev)
+		return dev_name(wd->hwdev);
 	if (wd->name)
 		return wd->name;
 
diff --git a/include/watchdog.h b/include/watchdog.h
index 3e8a487a4..848981cc0 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -16,7 +16,7 @@
 struct watchdog {
 	int (*set_timeout)(struct watchdog *, unsigned);
 	const char *name;
-	struct device_d *dev;
+	struct device_d *hwdev;
 	unsigned int priority;
 	struct list_head list;
 };
-- 
2.16.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 2/6] watchdog: move max timeout test in to wd_core
  2018-03-13  8:33 [PATCH v2 1/6] watchdog: rename dev to hwdev Oleksij Rempel
@ 2018-03-13  8:33 ` Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 3/6] watchdog: register watchdog virtual device with short name wdog Oleksij Rempel
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksij Rempel @ 2018-03-13  8:33 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

From: Oleksij Rempel <linux@rempel-privat.de>

this also will be needed for watchdog poller as well

Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
---
 drivers/watchdog/ar9344_wdt.c | 15 ++++-----------
 drivers/watchdog/im28wd.c     |  4 +---
 drivers/watchdog/imxwd.c      | 10 ++++------
 drivers/watchdog/orion_wdt.c  |  4 +---
 drivers/watchdog/wd_core.c    |  6 ++++++
 include/watchdog.h            |  1 +
 6 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/drivers/watchdog/ar9344_wdt.c b/drivers/watchdog/ar9344_wdt.c
index c1dfc994a..461528863 100644
--- a/drivers/watchdog/ar9344_wdt.c
+++ b/drivers/watchdog/ar9344_wdt.c
@@ -41,20 +41,11 @@ struct ar9344_wd {
 static int ar9344_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
 {
 	struct ar9344_wd *priv = to_ar9344_wd(wd);
-	u32 val, ctrl, rate, max_timout;
-
-	rate = clk_get_rate(priv->clk);
-	max_timout = U32_MAX / rate;
-
-	if (timeout > max_timout) {
-		dev_err(priv->dev, "timeout value out of range: %d > %d\n",
-			timeout, max_timout);
-		return -EINVAL;
-	}
+	u32 val, ctrl;
 
 	if (timeout) {
 		ctrl = AR9344_WD_CTRL_ACTION_FCR;
-		val = timeout * rate;
+		val = timeout * clk_get_rate(priv->clk);
 	} else {
 		ctrl = AR9344_WD_CTRL_ACTION_NONE;
 		val = U32_MAX;
@@ -111,6 +102,8 @@ static int ar9344_wdt_probe(struct device_d *dev)
 
 	clk_enable(priv->clk);
 
+	priv->wd.timeout_max = U32_MAX / clk_get_rate(priv->clk);
+
 	ret = watchdog_register(&priv->wd);
 	if (ret)
 		goto on_error;
diff --git a/drivers/watchdog/im28wd.c b/drivers/watchdog/im28wd.c
index 43edea8d0..2b233ede2 100644
--- a/drivers/watchdog/im28wd.c
+++ b/drivers/watchdog/im28wd.c
@@ -133,9 +133,6 @@ static int imx28_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
 	struct imx28_wd *pwd = (struct imx28_wd *)to_imx28_wd(wd);
 	void __iomem *base;
 
-	if (timeout > (ULONG_MAX / WDOG_TICK_RATE))
-		return -EINVAL;
-
 	if (timeout) {
 		writel(timeout * WDOG_TICK_RATE, pwd->regs + MXS_RTC_WATCHDOG);
 		base = pwd->regs + MXS_RTC_SET_ADDR;
@@ -199,6 +196,7 @@ static int imx28_wd_probe(struct device_d *dev)
 		return PTR_ERR(iores);
 	priv->regs = IOMEM(iores->start);
 	priv->wd.set_timeout = imx28_watchdog_set_timeout;
+	priv->wd.timeout_max = ULONG_MAX / WDOG_TICK_RATE;
 	priv->wd.hwdev = dev;
 
 	if (!(readl(priv->regs + MXS_RTC_STAT) & MXS_RTC_STAT_WD_PRESENT)) {
diff --git a/drivers/watchdog/imxwd.c b/drivers/watchdog/imxwd.c
index 6b33834fe..a66fae400 100644
--- a/drivers/watchdog/imxwd.c
+++ b/drivers/watchdog/imxwd.c
@@ -28,6 +28,7 @@ struct imx_wd_ops {
 	int (*set_timeout)(struct imx_wd *, unsigned);
 	void (*soc_reset)(struct imx_wd *);
 	int (*init)(struct imx_wd *);
+	unsigned int timeout_max;
 };
 
 struct imx_wd {
@@ -71,9 +72,6 @@ static int imx1_watchdog_set_timeout(struct imx_wd *priv, unsigned timeout)
 
 	dev_dbg(priv->dev, "%s: %d\n", __func__, timeout);
 
-	if (timeout > 64)
-		return -EINVAL;
-
 	if (!timeout) {
 		writew(IMX1_WDOG_WCR_WHALT, priv->base + IMX1_WDOG_WCR);
 		return 0;
@@ -102,9 +100,6 @@ static int imx21_watchdog_set_timeout(struct imx_wd *priv, unsigned timeout)
 
 	dev_dbg(priv->dev, "%s: %d\n", __func__, timeout);
 
-	if (timeout > 128)
-		return -EINVAL;
-
 	if (timeout == 0) /* bit 2 (WDE) cannot be set to 0 again */
 		return -ENOSYS;
 
@@ -218,6 +213,7 @@ static int imx_wd_probe(struct device_d *dev)
 	priv->base = IOMEM(iores->start);
 	priv->ops = ops;
 	priv->wd.set_timeout = imx_watchdog_set_timeout;
+	priv->wd.timeout_max = priv->ops->timeout_max;
 	priv->wd.hwdev = dev;
 	priv->dev = dev;
 
@@ -259,11 +255,13 @@ static const struct imx_wd_ops imx21_wd_ops = {
 	.set_timeout = imx21_watchdog_set_timeout,
 	.soc_reset = imx21_soc_reset,
 	.init = imx21_wd_init,
+	.timeout_max = 128,
 };
 
 static const struct imx_wd_ops imx1_wd_ops = {
 	.set_timeout = imx1_watchdog_set_timeout,
 	.soc_reset = imx1_soc_reset,
+	.timeout_max = 64,
 };
 
 static __maybe_unused struct of_device_id imx_wdt_dt_ids[] = {
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 4fe1ac1fd..dd1fa3a04 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -49,9 +49,6 @@ static int armada_xp_set_timeout(struct watchdog *wd, unsigned timeout)
 		container_of(wd, struct orion_wdt_ddata, wd);
 	u32 ctrl;
 
-	if (0xffffffff / CLKRATE < timeout)
-		return -EINVAL;
-
 	ctrl = readl(ddata->timer_base + TIMER_CTRL);
 
 	if (timeout == 0) {
@@ -89,6 +86,7 @@ static int orion_wdt_probe(struct device_d *dev)
 	ddata->wd.set_timeout = armada_xp_set_timeout;
 	ddata->wd.name = "orion_wdt";
 	ddata->wd.hwdev = dev;
+	ddata->wd.timeout_max = U32_MAX / CLKRATE;
 
 	res_timer = dev_request_mem_resource(dev, 0);
 	if (IS_ERR(res_timer)) {
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 56436e6f8..1d0f0de7d 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -36,6 +36,9 @@ int watchdog_register(struct watchdog *wd)
 	if (!wd->priority)
 		wd->priority = WATCHDOG_DEFAULT_PRIORITY;
 
+	dev_add_param_uint32_ro(&wd->dev, "timeout_max",
+			&wd->timeout_max, "%u");
+
 	list_add_tail(&wd->list, &watchdog_list);
 
 	pr_debug("registering watchdog %s with priority %d\n", watchdog_name(wd),
@@ -81,6 +84,9 @@ int watchdog_set_timeout(unsigned timeout)
 	if (!wd)
 		return -ENODEV;
 
+	if (timeout > wd->timeout_max)
+		return -EINVAL;
+
 	pr_debug("setting timeout on %s to %ds\n", watchdog_name(wd), timeout);
 
 	return wd->set_timeout(wd, timeout);
diff --git a/include/watchdog.h b/include/watchdog.h
index 848981cc0..1e06fbc3f 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -18,6 +18,7 @@ struct watchdog {
 	const char *name;
 	struct device_d *hwdev;
 	unsigned int priority;
+	unsigned int timeout_max;
 	struct list_head list;
 };
 
-- 
2.16.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 3/6] watchdog: register watchdog virtual device with short name wdog
  2018-03-13  8:33 [PATCH v2 1/6] watchdog: rename dev to hwdev Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 2/6] watchdog: move max timeout test in to wd_core Oleksij Rempel
@ 2018-03-13  8:33 ` Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 4/6] watchdog: set some reasonable timeout_max value if no other is available Oleksij Rempel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksij Rempel @ 2018-03-13  8:33 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

the watchdog hwdev is usually named with devicetree schema
which is not practical for CLI.

On device registration "wdog" will be extended with some index number
extracted from devicetree (if awailable) or automatically assigned
first available number. End result will be "wdog0" .. etc.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/watchdog/wd_core.c | 24 ++++++++++++++++++++++++
 include/watchdog.h         |  1 +
 2 files changed, 25 insertions(+)

diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 1d0f0de7d..0dc7aecf3 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -31,8 +31,31 @@ static const char *watchdog_name(struct watchdog *wd)
 	return "unknown";
 }
 
+static int watchdog_register_dev(struct watchdog *wd, const char *name, int id)
+{
+	wd->dev.parent = wd->hwdev;
+	wd->dev.id = id;
+	strncpy(wd->dev.name, name, MAX_DRIVER_NAME);
+
+	return register_device(&wd->dev);
+}
+
 int watchdog_register(struct watchdog *wd)
 {
+	struct param_d *p;
+	const char *alias;
+	int ret;
+
+	alias = of_alias_get(wd->hwdev->device_node);
+	if (alias)
+		ret = watchdog_register_dev(wd, alias, DEVICE_ID_SINGLE);
+
+	if (!alias || ret)
+		ret = watchdog_register_dev(wd, "wdog", DEVICE_ID_DYNAMIC);
+
+	if (ret)
+		return ret;
+
 	if (!wd->priority)
 		wd->priority = WATCHDOG_DEFAULT_PRIORITY;
 
@@ -50,6 +73,7 @@ EXPORT_SYMBOL(watchdog_register);
 
 int watchdog_deregister(struct watchdog *wd)
 {
+	unregister_device(&wd->dev);
 	list_del(&wd->list);
 
 	return 0;
diff --git a/include/watchdog.h b/include/watchdog.h
index 1e06fbc3f..a2459d255 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -17,6 +17,7 @@ struct watchdog {
 	int (*set_timeout)(struct watchdog *, unsigned);
 	const char *name;
 	struct device_d *hwdev;
+	struct device_d dev;
 	unsigned int priority;
 	unsigned int timeout_max;
 	struct list_head list;
-- 
2.16.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 4/6] watchdog: set some reasonable timeout_max value if no other is available
  2018-03-13  8:33 [PATCH v2 1/6] watchdog: rename dev to hwdev Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 2/6] watchdog: move max timeout test in to wd_core Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 3/6] watchdog: register watchdog virtual device with short name wdog Oleksij Rempel
@ 2018-03-13  8:33 ` Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 5/6] watchdog: provide timeout_cur value Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 6/6] watchdog: add watchdog poller Oleksij Rempel
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksij Rempel @ 2018-03-13  8:33 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

Some drivers do not provide timeout_max value.
Using some value is probably better then setting timeout_max to 0.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/watchdog/wd_core.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 0dc7aecf3..31a88a377 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -59,8 +59,14 @@ int watchdog_register(struct watchdog *wd)
 	if (!wd->priority)
 		wd->priority = WATCHDOG_DEFAULT_PRIORITY;
 
-	dev_add_param_uint32_ro(&wd->dev, "timeout_max",
+	/* set some default sane value */
+	if (!wd->timeout_max)
+		wd->timeout_max = 60 * 60 * 24;
+
+	p = dev_add_param_uint32_ro(&wd->dev, "timeout_max",
 			&wd->timeout_max, "%u");
+	if (IS_ERR(p))
+		return PTR_ERR(p);
 
 	list_add_tail(&wd->list, &watchdog_list);
 
-- 
2.16.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 5/6] watchdog: provide timeout_cur value
  2018-03-13  8:33 [PATCH v2 1/6] watchdog: rename dev to hwdev Oleksij Rempel
                   ` (2 preceding siblings ...)
  2018-03-13  8:33 ` [PATCH v2 4/6] watchdog: set some reasonable timeout_max value if no other is available Oleksij Rempel
@ 2018-03-13  8:33 ` Oleksij Rempel
  2018-03-13  8:33 ` [PATCH v2 6/6] watchdog: add watchdog poller Oleksij Rempel
  4 siblings, 0 replies; 7+ messages in thread
From: Oleksij Rempel @ 2018-03-13  8:33 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

timeout_cur will be used for watchdog poller.
Provided values should be good enough for most users
and still can be changed for separate projects and
fit to needed requirements.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/watchdog/wd_core.c | 18 ++++++++++++++++++
 include/watchdog.h         |  1 +
 2 files changed, 19 insertions(+)

diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 31a88a377..69663b39c 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -31,6 +31,16 @@ static const char *watchdog_name(struct watchdog *wd)
 	return "unknown";
 }
 
+static int watchdog_set_cur(struct param_d *param, void *priv)
+{
+	struct watchdog *wd = priv;
+
+	if (wd->timeout_cur > wd->timeout_max)
+		return -EINVAL;
+
+	return 0;
+}
+
 static int watchdog_register_dev(struct watchdog *wd, const char *name, int id)
 {
 	wd->dev.parent = wd->hwdev;
@@ -63,11 +73,19 @@ int watchdog_register(struct watchdog *wd)
 	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);
+
 	list_add_tail(&wd->list, &watchdog_list);
 
 	pr_debug("registering watchdog %s with priority %d\n", watchdog_name(wd),
diff --git a/include/watchdog.h b/include/watchdog.h
index a2459d255..2f1874c19 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -20,6 +20,7 @@ struct watchdog {
 	struct device_d dev;
 	unsigned int priority;
 	unsigned int timeout_max;
+	unsigned int timeout_cur;
 	struct list_head list;
 };
 
-- 
2.16.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 6/6] watchdog: add watchdog poller
  2018-03-13  8:33 [PATCH v2 1/6] watchdog: rename dev to hwdev Oleksij Rempel
                   ` (3 preceding siblings ...)
  2018-03-13  8:33 ` [PATCH v2 5/6] watchdog: provide timeout_cur value Oleksij Rempel
@ 2018-03-13  8:33 ` Oleksij Rempel
  2018-03-19  8:01   ` Sascha Hauer
  4 siblings, 1 reply; 7+ messages in thread
From: Oleksij Rempel @ 2018-03-13  8:33 UTC (permalink / raw)
  To: barebox; +Cc: Oleksij Rempel

In some cases it is practical to supervise as much as possible of
the barebox execution with a watchdog (or multiple watchdogs). This
patch provides an async poller for watchdog core framework which can
be enabled by the user and stores this configuration to nv.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/watchdog/Kconfig   |  6 ++++
 drivers/watchdog/wd_core.c | 74 ++++++++++++++++++++++++++++++++++++++++++----
 include/watchdog.h         |  4 +++
 3 files changed, 78 insertions(+), 6 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3defb9da6..375eb248b 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -10,6 +10,12 @@ menuconfig WATCHDOG
 
 if WATCHDOG
 
+menuconfig WATCHDOG_POLLER
+	bool "Watchdog poller support"
+	select POLLER
+	help
+	  Provides periodic ping support for watchdog framework.
+
 config WATCHDOG_AR9344
 	bool "QCA AR9344"
 	depends on SOC_QCA_AR9344 || SOC_QCA_AR9331
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index 69663b39c..77827eb50 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -31,6 +31,16 @@ static const char *watchdog_name(struct watchdog *wd)
 	return "unknown";
 }
 
+static int _watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
+{
+	if (timeout > wd->timeout_max)
+		return -EINVAL;
+
+	pr_debug("setting timeout on %s to %ds\n", watchdog_name(wd), timeout);
+
+	return wd->set_timeout(wd, timeout);
+}
+
 static int watchdog_set_cur(struct param_d *param, void *priv)
 {
 	struct watchdog *wd = priv;
@@ -41,6 +51,55 @@ static int watchdog_set_cur(struct param_d *param, void *priv)
 	return 0;
 }
 
+static void watchdog_poller_cb(void *priv);
+
+static void watchdog_poller_start(struct watchdog *wd)
+{
+	_watchdog_set_timeout(wd, wd->timeout_cur);
+	poller_call_async(&wd->poller, 500 * MSECOND,
+			watchdog_poller_cb, wd);
+
+}
+
+static void watchdog_poller_cb(void *priv)
+{
+	struct watchdog *wd = priv;
+
+	if (wd->poller_enable)
+		watchdog_poller_start(wd);
+}
+
+static int watchdog_set_poller(struct param_d *param, void *priv)
+{
+	struct watchdog *wd = priv;
+
+
+	if (wd->poller_enable) {
+		dev_info(&wd->dev, "enable watchdog poller\n");
+		watchdog_poller_start(wd);
+	} else {
+		dev_info(&wd->dev, "disable watchdog poller\n");
+		poller_async_cancel(&wd->poller);
+	}
+
+	return 0;
+}
+
+static int watchdog_register_poller(struct watchdog *wd)
+{
+	struct param_d *p;
+	int ret;
+
+	ret = poller_async_register(&wd->poller);
+	if (ret)
+		return ret;
+
+	p = dev_add_param_bool(&wd->dev, "poller_enable", watchdog_set_poller,
+			NULL, &wd->poller_enable, wd);
+
+	return PTR_ERR_OR_ZERO(p);
+}
+
 static int watchdog_register_dev(struct watchdog *wd, const char *name, int id)
 {
 	wd->dev.parent = wd->hwdev;
@@ -86,6 +145,12 @@ int watchdog_register(struct watchdog *wd)
 	if (IS_ERR(p))
 		return PTR_ERR(p);
 
+	if (IS_ENABLED(CONFIG_WATCHDOG_POLLER)) {
+		ret = watchdog_register_poller(wd);
+		if (ret)
+			return ret;
+	}
+
 	list_add_tail(&wd->list, &watchdog_list);
 
 	pr_debug("registering watchdog %s with priority %d\n", watchdog_name(wd),
@@ -97,6 +162,8 @@ EXPORT_SYMBOL(watchdog_register);
 
 int watchdog_deregister(struct watchdog *wd)
 {
+	poller_async_cancel(&wd->poller);
+	poller_async_unregister(&wd->poller);
 	unregister_device(&wd->dev);
 	list_del(&wd->list);
 
@@ -132,12 +199,7 @@ int watchdog_set_timeout(unsigned timeout)
 	if (!wd)
 		return -ENODEV;
 
-	if (timeout > wd->timeout_max)
-		return -EINVAL;
-
-	pr_debug("setting timeout on %s to %ds\n", watchdog_name(wd), timeout);
-
-	return wd->set_timeout(wd, timeout);
+	return _watchdog_set_timeout(wd, timeout);
 }
 EXPORT_SYMBOL(watchdog_set_timeout);
 
diff --git a/include/watchdog.h b/include/watchdog.h
index 2f1874c19..0db4263a3 100644
--- a/include/watchdog.h
+++ b/include/watchdog.h
@@ -13,6 +13,8 @@
 #ifndef INCLUDE_WATCHDOG_H
 # define INCLUDE_WATCHDOG_H
 
+#include <poller.h>
+
 struct watchdog {
 	int (*set_timeout)(struct watchdog *, unsigned);
 	const char *name;
@@ -21,6 +23,8 @@ struct watchdog {
 	unsigned int priority;
 	unsigned int timeout_max;
 	unsigned int timeout_cur;
+	unsigned int poller_enable;
+	struct poller_async poller;
 	struct list_head list;
 };
 
-- 
2.16.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 6/6] watchdog: add watchdog poller
  2018-03-13  8:33 ` [PATCH v2 6/6] watchdog: add watchdog poller Oleksij Rempel
@ 2018-03-19  8:01   ` Sascha Hauer
  0 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-03-19  8:01 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: barebox

On Tue, Mar 13, 2018 at 09:33:28AM +0100, Oleksij Rempel wrote:
> In some cases it is practical to supervise as much as possible of
> the barebox execution with a watchdog (or multiple watchdogs). This
> patch provides an async poller for watchdog core framework which can
> be enabled by the user and stores this configuration to nv.
> 
> +static int watchdog_register_poller(struct watchdog *wd)
> +{
> +	struct param_d *p;
> +	int ret;
> +
> +	ret = poller_async_register(&wd->poller);
> +	if (ret)
> +		return ret;
> +
> +	p = dev_add_param_bool(&wd->dev, "poller_enable", watchdog_set_poller,
> +			NULL, &wd->poller_enable, wd);

The series looks mostly good and I applied 1-5. However, as Jan
mentioned we should find a better name for the variable. "poller_enable"
describes how it's internally implemented, not what this variable is
good for.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-03-19  8:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-13  8:33 [PATCH v2 1/6] watchdog: rename dev to hwdev Oleksij Rempel
2018-03-13  8:33 ` [PATCH v2 2/6] watchdog: move max timeout test in to wd_core Oleksij Rempel
2018-03-13  8:33 ` [PATCH v2 3/6] watchdog: register watchdog virtual device with short name wdog Oleksij Rempel
2018-03-13  8:33 ` [PATCH v2 4/6] watchdog: set some reasonable timeout_max value if no other is available Oleksij Rempel
2018-03-13  8:33 ` [PATCH v2 5/6] watchdog: provide timeout_cur value Oleksij Rempel
2018-03-13  8:33 ` [PATCH v2 6/6] watchdog: add watchdog poller Oleksij Rempel
2018-03-19  8:01   ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox