All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] watchdog: Add support for RZ/A2 wdt
@ 2018-09-06 18:37 Chris Brandt
  2018-09-06 18:37 ` [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts Chris Brandt
  2018-09-06 18:37 ` [PATCH v2 2/2] dt-bindings: watchdog: renesas-wdt: Add support for R7S9210 Chris Brandt
  0 siblings, 2 replies; 8+ messages in thread
From: Chris Brandt @ 2018-09-06 18:37 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Mark Rutland,
	Geert Uytterhoeven
  Cc: linux-watchdog, devicetree, linux-renesas-soc, Simon Horman,
	Chris Brandt

Slightly modify the rza_wdt.c driver and update the binding docs.


Chris Brandt (2):
  watchdog: rza_wdt: Support longer timeouts
  dt-bindings: watchdog: renesas-wdt: Add support for R7S9210

 .../devicetree/bindings/watchdog/renesas-wdt.txt   |  1 +
 drivers/watchdog/rza_wdt.c                         | 81 +++++++++++++++++-----
 2 files changed, 64 insertions(+), 18 deletions(-)

-- 
2.16.1

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

* [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts
  2018-09-06 18:37 [PATCH v2 0/2] watchdog: Add support for RZ/A2 wdt Chris Brandt
@ 2018-09-06 18:37 ` Chris Brandt
  2018-09-06 18:52   ` Guenter Roeck
  2018-09-06 18:37 ` [PATCH v2 2/2] dt-bindings: watchdog: renesas-wdt: Add support for R7S9210 Chris Brandt
  1 sibling, 1 reply; 8+ messages in thread
From: Chris Brandt @ 2018-09-06 18:37 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Mark Rutland,
	Geert Uytterhoeven
  Cc: linux-watchdog, devicetree, linux-renesas-soc, Simon Horman,
	Chris Brandt

The RZ/A2 watchdog timer extends the clock source options in order to
allow for longer timeouts.

Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
v2:
* use DIV_ROUND_UP
* use %u for pr_debug
* use of_match data to determine the size of CKS register
---
 drivers/watchdog/rza_wdt.c | 81 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 63 insertions(+), 18 deletions(-)

diff --git a/drivers/watchdog/rza_wdt.c b/drivers/watchdog/rza_wdt.c
index e618218d2374..d55eb947d08c 100644
--- a/drivers/watchdog/rza_wdt.c
+++ b/drivers/watchdog/rza_wdt.c
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/watchdog.h>
 
@@ -34,12 +35,40 @@
 #define WRCSR_RSTE		BIT(6)
 #define WRCSR_CLEAR_WOVF	0xA500	/* special value */
 
+#define CKS_3BIT		0x7
+#define CKS_4BIT		0xF
+
 struct rza_wdt {
 	struct watchdog_device wdev;
 	void __iomem *base;
 	struct clk *clk;
+	u8 count;
+	u8 cks;
+	u8 timeout;
 };
 
+static void rza_wdt_calc_timeout(struct rza_wdt *priv, int timeout)
+{
+	int rate = clk_get_rate(priv->clk);
+	u16 counter;
+
+	if (priv->cks == CKS_4BIT) {
+		counter = DIV_ROUND_UP((timeout * rate),  4194304) + 1;
+		if (counter > 255)
+			counter = 0;
+
+		priv->count = 256 - counter;
+	} else {
+		/* Start timer with longest timeout */
+		priv->count = 0;
+	}
+
+	priv->timeout = timeout;
+
+	pr_debug("%s: timeout set to %u (WTCNT=%d)\n", __func__,
+		 timeout, priv->count);
+}
+
 static int rza_wdt_start(struct watchdog_device *wdev)
 {
 	struct rza_wdt *priv = watchdog_get_drvdata(wdev);
@@ -51,13 +80,12 @@ static int rza_wdt_start(struct watchdog_device *wdev)
 	readb(priv->base + WRCSR);
 	writew(WRCSR_CLEAR_WOVF, priv->base + WRCSR);
 
-	/*
-	 * Start timer with slowest clock source and reset option enabled.
-	 */
+	rza_wdt_calc_timeout(priv, wdev->timeout);
+
 	writew(WRCSR_MAGIC | WRCSR_RSTE, priv->base + WRCSR);
-	writew(WTCNT_MAGIC | 0, priv->base + WTCNT);
-	writew(WTCSR_MAGIC | WTSCR_WT | WTSCR_TME | WTSCR_CKS(7),
-	       priv->base + WTCSR);
+	writew(WTCNT_MAGIC | priv->count, priv->base + WTCNT);
+	writew(WTCSR_MAGIC | WTSCR_WT | WTSCR_TME |
+	       WTSCR_CKS(priv->cks), priv->base + WTCSR);
 
 	return 0;
 }
@@ -75,7 +103,12 @@ static int rza_wdt_ping(struct watchdog_device *wdev)
 {
 	struct rza_wdt *priv = watchdog_get_drvdata(wdev);
 
-	writew(WTCNT_MAGIC | 0, priv->base + WTCNT);
+	if (priv->timeout != wdev->timeout)
+		rza_wdt_calc_timeout(priv, wdev->timeout);
+
+	writew(WTCNT_MAGIC | priv->count, priv->base + WTCNT);
+
+	pr_debug("%s: timeout = %u\n", __func__, wdev->timeout);
 
 	return 0;
 }
@@ -150,20 +183,31 @@ static int rza_wdt_probe(struct platform_device *pdev)
 		return -ENOENT;
 	}
 
-	/* Assume slowest clock rate possible (CKS=7) */
-	rate /= 16384;
-
 	priv->wdev.info = &rza_wdt_ident,
 	priv->wdev.ops = &rza_wdt_ops,
 	priv->wdev.parent = &pdev->dev;
 
-	/*
-	 * Since the max possible timeout of our 8-bit count register is less
-	 * than a second, we must use max_hw_heartbeat_ms.
-	 */
-	priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
-	dev_dbg(&pdev->dev, "max hw timeout of %dms\n",
-		 priv->wdev.max_hw_heartbeat_ms);
+	priv->cks = (unsigned int)of_device_get_match_data(&pdev->dev);
+	if (priv->cks == CKS_4BIT) {
+		/* Assume slowest clock rate possible (CKS=0xF) */
+		priv->wdev.max_timeout = (4194304 * U8_MAX) / rate;
+
+	} else if (priv->cks == CKS_3BIT) {
+		/* Assume slowest clock rate possible (CKS=7) */
+		rate /= 16384;
+
+		/*
+		 * Since the max possible timeout of our 8-bit count
+		 * register is less than a second, we must use
+		 * max_hw_heartbeat_ms.
+		 */
+		priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
+		dev_dbg(&pdev->dev, "max hw timeout of %dms\n",
+			 priv->wdev.max_hw_heartbeat_ms);
+	} else {
+		dev_err(&pdev->dev, "invalid CKS value (%u)\n", priv->cks);
+		return -EINVAL;
+	}
 
 	priv->wdev.min_timeout = 1;
 	priv->wdev.timeout = DEFAULT_TIMEOUT;
@@ -179,7 +223,8 @@ static int rza_wdt_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id rza_wdt_of_match[] = {
-	{ .compatible = "renesas,rza-wdt", },
+	{ .compatible = "renesas,r7s9210-wdt",	.data = (void *)CKS_4BIT, },
+	{ .compatible = "renesas,rza-wdt",	.data = (void *)CKS_3BIT, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, rza_wdt_of_match);
-- 
2.16.1

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

* [PATCH v2 2/2] dt-bindings: watchdog: renesas-wdt: Add support for R7S9210
  2018-09-06 18:37 [PATCH v2 0/2] watchdog: Add support for RZ/A2 wdt Chris Brandt
  2018-09-06 18:37 ` [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts Chris Brandt
@ 2018-09-06 18:37 ` Chris Brandt
  1 sibling, 0 replies; 8+ messages in thread
From: Chris Brandt @ 2018-09-06 18:37 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Rob Herring, Mark Rutland,
	Geert Uytterhoeven
  Cc: linux-watchdog, devicetree, linux-renesas-soc, Simon Horman,
	Chris Brandt

Document support for RZ/A2

Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
---
 Documentation/devicetree/bindings/watchdog/renesas-wdt.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
index 5d47a262474c..45a709dd0345 100644
--- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
@@ -19,6 +19,7 @@ Required properties:
 	         - "renesas,r8a77990-wdt" (R-Car E3)
 	         - "renesas,r8a77995-wdt" (R-Car D3)
 	         - "renesas,r7s72100-wdt" (RZ/A1)
+	         - "renesas,r7s9210-wdt"  (RZ/A2)
 		The generic compatible string must be:
 		 - "renesas,rza-wdt" for RZ/A
 		 - "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G
-- 
2.16.1

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

* Re: [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts
  2018-09-06 18:37 ` [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts Chris Brandt
@ 2018-09-06 18:52   ` Guenter Roeck
  2018-09-06 18:56     ` Guenter Roeck
  2018-09-06 20:45     ` Chris Brandt
  0 siblings, 2 replies; 8+ messages in thread
From: Guenter Roeck @ 2018-09-06 18:52 UTC (permalink / raw)
  To: Chris Brandt
  Cc: Wim Van Sebroeck, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-watchdog, devicetree, linux-renesas-soc, Simon Horman

On Thu, Sep 06, 2018 at 01:37:37PM -0500, Chris Brandt wrote:
> The RZ/A2 watchdog timer extends the clock source options in order to
> allow for longer timeouts.
> 
> Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
> ---
> v2:
> * use DIV_ROUND_UP
> * use %u for pr_debug
> * use of_match data to determine the size of CKS register
> ---
>  drivers/watchdog/rza_wdt.c | 81 +++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 63 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/watchdog/rza_wdt.c b/drivers/watchdog/rza_wdt.c
> index e618218d2374..d55eb947d08c 100644
> --- a/drivers/watchdog/rza_wdt.c
> +++ b/drivers/watchdog/rza_wdt.c
> @@ -14,6 +14,7 @@
>  #include <linux/delay.h>
>  #include <linux/module.h>
>  #include <linux/of_address.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/watchdog.h>
>  
> @@ -34,12 +35,40 @@
>  #define WRCSR_RSTE		BIT(6)
>  #define WRCSR_CLEAR_WOVF	0xA500	/* special value */
>  
> +#define CKS_3BIT		0x7
> +#define CKS_4BIT		0xF
> +
>  struct rza_wdt {
>  	struct watchdog_device wdev;
>  	void __iomem *base;
>  	struct clk *clk;
> +	u8 count;
> +	u8 cks;
> +	u8 timeout;
>  };
>  
> +static void rza_wdt_calc_timeout(struct rza_wdt *priv, int timeout)
> +{
> +	int rate = clk_get_rate(priv->clk);

clk_get_rate() returns unsigned long.

> +	u16 counter;
> +
> +	if (priv->cks == CKS_4BIT) {
> +		counter = DIV_ROUND_UP((timeout * rate),  4194304) + 1;

two spaces ?

Also, I am not sure how this prevents overflows. Was't the concern
that timeout * rate might overflow an int ?

Also, why still "+ 1" ? Wasn't DIV_ROUND_UP() supposed to take care
of that ?

> +		if (counter > 255)
> +			counter = 0;

This is difficult to understand. 

> +
> +		priv->count = 256 - counter;

It sets priv->count to 256, meaning that 0x5B00 instead of
0x5Axx will be written into the counter register. That really
asks for some explanation.

> +	} else {
> +		/* Start timer with longest timeout */
> +		priv->count = 0;
> +	}
> +
> +	priv->timeout = timeout;
> +
> +	pr_debug("%s: timeout set to %u (WTCNT=%d)\n", __func__,
> +		 timeout, priv->count);
> +}
> +
>  static int rza_wdt_start(struct watchdog_device *wdev)
>  {
>  	struct rza_wdt *priv = watchdog_get_drvdata(wdev);
> @@ -51,13 +80,12 @@ static int rza_wdt_start(struct watchdog_device *wdev)
>  	readb(priv->base + WRCSR);
>  	writew(WRCSR_CLEAR_WOVF, priv->base + WRCSR);
>  
> -	/*
> -	 * Start timer with slowest clock source and reset option enabled.
> -	 */
> +	rza_wdt_calc_timeout(priv, wdev->timeout);
> +
>  	writew(WRCSR_MAGIC | WRCSR_RSTE, priv->base + WRCSR);
> -	writew(WTCNT_MAGIC | 0, priv->base + WTCNT);
> -	writew(WTCSR_MAGIC | WTSCR_WT | WTSCR_TME | WTSCR_CKS(7),
> -	       priv->base + WTCSR);
> +	writew(WTCNT_MAGIC | priv->count, priv->base + WTCNT);
> +	writew(WTCSR_MAGIC | WTSCR_WT | WTSCR_TME |
> +	       WTSCR_CKS(priv->cks), priv->base + WTCSR);
>  
>  	return 0;
>  }
> @@ -75,7 +103,12 @@ static int rza_wdt_ping(struct watchdog_device *wdev)
>  {
>  	struct rza_wdt *priv = watchdog_get_drvdata(wdev);
>  
> -	writew(WTCNT_MAGIC | 0, priv->base + WTCNT);
> +	if (priv->timeout != wdev->timeout)
> +		rza_wdt_calc_timeout(priv, wdev->timeout);
> +
> +	writew(WTCNT_MAGIC | priv->count, priv->base + WTCNT);
> +
> +	pr_debug("%s: timeout = %u\n", __func__, wdev->timeout);
>  
>  	return 0;
>  }
> @@ -150,20 +183,31 @@ static int rza_wdt_probe(struct platform_device *pdev)
>  		return -ENOENT;
>  	}
>  
> -	/* Assume slowest clock rate possible (CKS=7) */
> -	rate /= 16384;
> -
>  	priv->wdev.info = &rza_wdt_ident,
>  	priv->wdev.ops = &rza_wdt_ops,
>  	priv->wdev.parent = &pdev->dev;
>  
> -	/*
> -	 * Since the max possible timeout of our 8-bit count register is less
> -	 * than a second, we must use max_hw_heartbeat_ms.
> -	 */
> -	priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
> -	dev_dbg(&pdev->dev, "max hw timeout of %dms\n",
> -		 priv->wdev.max_hw_heartbeat_ms);
> +	priv->cks = (unsigned int)of_device_get_match_data(&pdev->dev);
> +	if (priv->cks == CKS_4BIT) {
> +		/* Assume slowest clock rate possible (CKS=0xF) */
> +		priv->wdev.max_timeout = (4194304 * U8_MAX) / rate;
> +
> +	} else if (priv->cks == CKS_3BIT) {
> +		/* Assume slowest clock rate possible (CKS=7) */
> +		rate /= 16384;
> +
> +		/*
> +		 * Since the max possible timeout of our 8-bit count
> +		 * register is less than a second, we must use
> +		 * max_hw_heartbeat_ms.
> +		 */
> +		priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
> +		dev_dbg(&pdev->dev, "max hw timeout of %dms\n",
> +			 priv->wdev.max_hw_heartbeat_ms);
> +	} else {
> +		dev_err(&pdev->dev, "invalid CKS value (%u)\n", priv->cks);
> +		return -EINVAL;
> +	}
>  
>  	priv->wdev.min_timeout = 1;
>  	priv->wdev.timeout = DEFAULT_TIMEOUT;
> @@ -179,7 +223,8 @@ static int rza_wdt_probe(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id rza_wdt_of_match[] = {
> -	{ .compatible = "renesas,rza-wdt", },
> +	{ .compatible = "renesas,r7s9210-wdt",	.data = (void *)CKS_4BIT, },
> +	{ .compatible = "renesas,rza-wdt",	.data = (void *)CKS_3BIT, },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, rza_wdt_of_match);
> -- 
> 2.16.1
> 

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

* Re: [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts
  2018-09-06 18:52   ` Guenter Roeck
@ 2018-09-06 18:56     ` Guenter Roeck
  2018-09-06 19:40       ` Chris Brandt
  2018-09-06 21:39       ` Chris Brandt
  2018-09-06 20:45     ` Chris Brandt
  1 sibling, 2 replies; 8+ messages in thread
From: Guenter Roeck @ 2018-09-06 18:56 UTC (permalink / raw)
  To: Chris Brandt
  Cc: Wim Van Sebroeck, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-watchdog, devicetree, linux-renesas-soc, Simon Horman

On Thu, Sep 06, 2018 at 11:52:47AM -0700, Guenter Roeck wrote:
> On Thu, Sep 06, 2018 at 01:37:37PM -0500, Chris Brandt wrote:
> > The RZ/A2 watchdog timer extends the clock source options in order to
> > allow for longer timeouts.
> > 
> > Signed-off-by: Chris Brandt <chris.brandt@renesas.com>
> > ---
> > v2:
> > * use DIV_ROUND_UP
> > * use %u for pr_debug
> > * use of_match data to determine the size of CKS register
> > ---
> >  drivers/watchdog/rza_wdt.c | 81 +++++++++++++++++++++++++++++++++++-----------
> >  1 file changed, 63 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/watchdog/rza_wdt.c b/drivers/watchdog/rza_wdt.c
> > index e618218d2374..d55eb947d08c 100644
> > --- a/drivers/watchdog/rza_wdt.c
> > +++ b/drivers/watchdog/rza_wdt.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/delay.h>
> >  #include <linux/module.h>
> >  #include <linux/of_address.h>
> > +#include <linux/of_device.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/watchdog.h>
> >  
> > @@ -34,12 +35,40 @@
> >  #define WRCSR_RSTE		BIT(6)
> >  #define WRCSR_CLEAR_WOVF	0xA500	/* special value */
> >  
> > +#define CKS_3BIT		0x7
> > +#define CKS_4BIT		0xF
> > +
> >  struct rza_wdt {
> >  	struct watchdog_device wdev;
> >  	void __iomem *base;
> >  	struct clk *clk;
> > +	u8 count;
> > +	u8 cks;
> > +	u8 timeout;
> >  };
> >  
> > +static void rza_wdt_calc_timeout(struct rza_wdt *priv, int timeout)
> > +{
> > +	int rate = clk_get_rate(priv->clk);
> 
> clk_get_rate() returns unsigned long.
> 
> > +	u16 counter;
> > +
> > +	if (priv->cks == CKS_4BIT) {
> > +		counter = DIV_ROUND_UP((timeout * rate),  4194304) + 1;
> 
> two spaces ?
> 
> Also, I am not sure how this prevents overflows. Was't the concern
> that timeout * rate might overflow an int ?
> 
> Also, why still "+ 1" ? Wasn't DIV_ROUND_UP() supposed to take care
> of that ?
> 
> > +		if (counter > 255)
> > +			counter = 0;
> 
> This is difficult to understand. 
> 
> > +
> > +		priv->count = 256 - counter;
> 
> It sets priv->count to 256, meaning that 0x5B00 instead of
> 0x5Axx will be written into the counter register. That really
> asks for some explanation.
> 

No, wait, priv->count is an 8-bit variable, so this really sets
priv->counter to 0. I am getting more and more confused. Why
not just set "counter = 256" above to make it obvious if that
is what is supposed to happen ?

Guenter

> > +	} else {
> > +		/* Start timer with longest timeout */
> > +		priv->count = 0;
> > +	}
> > +
> > +	priv->timeout = timeout;
> > +
> > +	pr_debug("%s: timeout set to %u (WTCNT=%d)\n", __func__,
> > +		 timeout, priv->count);
> > +}
> > +
> >  static int rza_wdt_start(struct watchdog_device *wdev)
> >  {
> >  	struct rza_wdt *priv = watchdog_get_drvdata(wdev);
> > @@ -51,13 +80,12 @@ static int rza_wdt_start(struct watchdog_device *wdev)
> >  	readb(priv->base + WRCSR);
> >  	writew(WRCSR_CLEAR_WOVF, priv->base + WRCSR);
> >  
> > -	/*
> > -	 * Start timer with slowest clock source and reset option enabled.
> > -	 */
> > +	rza_wdt_calc_timeout(priv, wdev->timeout);
> > +
> >  	writew(WRCSR_MAGIC | WRCSR_RSTE, priv->base + WRCSR);
> > -	writew(WTCNT_MAGIC | 0, priv->base + WTCNT);
> > -	writew(WTCSR_MAGIC | WTSCR_WT | WTSCR_TME | WTSCR_CKS(7),
> > -	       priv->base + WTCSR);
> > +	writew(WTCNT_MAGIC | priv->count, priv->base + WTCNT);
> > +	writew(WTCSR_MAGIC | WTSCR_WT | WTSCR_TME |
> > +	       WTSCR_CKS(priv->cks), priv->base + WTCSR);
> >  
> >  	return 0;
> >  }
> > @@ -75,7 +103,12 @@ static int rza_wdt_ping(struct watchdog_device *wdev)
> >  {
> >  	struct rza_wdt *priv = watchdog_get_drvdata(wdev);
> >  
> > -	writew(WTCNT_MAGIC | 0, priv->base + WTCNT);
> > +	if (priv->timeout != wdev->timeout)
> > +		rza_wdt_calc_timeout(priv, wdev->timeout);
> > +
> > +	writew(WTCNT_MAGIC | priv->count, priv->base + WTCNT);
> > +
> > +	pr_debug("%s: timeout = %u\n", __func__, wdev->timeout);
> >  
> >  	return 0;
> >  }
> > @@ -150,20 +183,31 @@ static int rza_wdt_probe(struct platform_device *pdev)
> >  		return -ENOENT;
> >  	}
> >  
> > -	/* Assume slowest clock rate possible (CKS=7) */
> > -	rate /= 16384;
> > -
> >  	priv->wdev.info = &rza_wdt_ident,
> >  	priv->wdev.ops = &rza_wdt_ops,
> >  	priv->wdev.parent = &pdev->dev;
> >  
> > -	/*
> > -	 * Since the max possible timeout of our 8-bit count register is less
> > -	 * than a second, we must use max_hw_heartbeat_ms.
> > -	 */
> > -	priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
> > -	dev_dbg(&pdev->dev, "max hw timeout of %dms\n",
> > -		 priv->wdev.max_hw_heartbeat_ms);
> > +	priv->cks = (unsigned int)of_device_get_match_data(&pdev->dev);
> > +	if (priv->cks == CKS_4BIT) {
> > +		/* Assume slowest clock rate possible (CKS=0xF) */
> > +		priv->wdev.max_timeout = (4194304 * U8_MAX) / rate;
> > +
> > +	} else if (priv->cks == CKS_3BIT) {
> > +		/* Assume slowest clock rate possible (CKS=7) */
> > +		rate /= 16384;
> > +
> > +		/*
> > +		 * Since the max possible timeout of our 8-bit count
> > +		 * register is less than a second, we must use
> > +		 * max_hw_heartbeat_ms.
> > +		 */
> > +		priv->wdev.max_hw_heartbeat_ms = (1000 * U8_MAX) / rate;
> > +		dev_dbg(&pdev->dev, "max hw timeout of %dms\n",
> > +			 priv->wdev.max_hw_heartbeat_ms);
> > +	} else {
> > +		dev_err(&pdev->dev, "invalid CKS value (%u)\n", priv->cks);
> > +		return -EINVAL;
> > +	}
> >  
> >  	priv->wdev.min_timeout = 1;
> >  	priv->wdev.timeout = DEFAULT_TIMEOUT;
> > @@ -179,7 +223,8 @@ static int rza_wdt_probe(struct platform_device *pdev)
> >  }
> >  
> >  static const struct of_device_id rza_wdt_of_match[] = {
> > -	{ .compatible = "renesas,rza-wdt", },
> > +	{ .compatible = "renesas,r7s9210-wdt",	.data = (void *)CKS_4BIT, },
> > +	{ .compatible = "renesas,rza-wdt",	.data = (void *)CKS_3BIT, },
> >  	{ /* sentinel */ }
> >  };
> >  MODULE_DEVICE_TABLE(of, rza_wdt_of_match);
> > -- 
> > 2.16.1
> > 

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

* RE: [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts
  2018-09-06 18:56     ` Guenter Roeck
@ 2018-09-06 19:40       ` Chris Brandt
  2018-09-06 21:39       ` Chris Brandt
  1 sibling, 0 replies; 8+ messages in thread
From: Chris Brandt @ 2018-09-06 19:40 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Wim Van Sebroeck, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org, Simon Horman

On Thursday, September 06, 2018, Guenter Roeck wrote:
> > > +		if (counter > 255)
> > > +			counter = 0;
> >
> > This is difficult to understand.
> >
> > > +
> > > +		priv->count = 256 - counter;
> >
> > It sets priv->count to 256, meaning that 0x5B00 instead of
> > 0x5Axx will be written into the counter register. That really
> > asks for some explanation.
> >
> 
> No, wait, priv->count is an 8-bit variable, so this really sets
> priv->counter to 0. I am getting more and more confused. Why
> not just set "counter = 256" above to make it obvious if that
> is what is supposed to happen ?

That's a good point.

The math is supposed to be:

  256 - [number of ticks you want] = [register value]

Where [number of ticks you want] must be <= 256

Of course it's 8-bit variable so it will work...but that's not obvious 
at first.

I'll change it to:

	if (counter > 256)
		counter = 256;


Chris

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

* RE: [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts
  2018-09-06 18:52   ` Guenter Roeck
  2018-09-06 18:56     ` Guenter Roeck
@ 2018-09-06 20:45     ` Chris Brandt
  1 sibling, 0 replies; 8+ messages in thread
From: Chris Brandt @ 2018-09-06 20:45 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Wim Van Sebroeck, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org, Simon Horman

On Thursday, September 06, 2018, Guenter Roeck wrote:
> > +static void rza_wdt_calc_timeout(struct rza_wdt *priv, int timeout)
> > +{
> > +	int rate = clk_get_rate(priv->clk);
> 
> clk_get_rate() returns unsigned long.

OK, I'll change it.

> > +	u16 counter;
> > +
> > +	if (priv->cks == CKS_4BIT) {
> > +		counter = DIV_ROUND_UP((timeout * rate),  4194304) + 1;
> 
> two spaces ?

Oh, did see that.

> Also, I am not sure how this prevents overflows. Was't the concern
> that timeout * rate might overflow an int ?

Actually, since 32 second is the max timeout for this WDT, I think at 
first I'll check to see if "timeout" is greater than 32. If it is, there 
is no reason to do any math. Then I won't have to worry about any 
overflows from math.

	if (timeout > 32) 
		counter = 256;
	else
		counter = DIV_ROUND_UP((timeout * rate), 4194304) + 1;


> Also, why still "+ 1" ? Wasn't DIV_ROUND_UP() supposed to take care
> of that ?

Ooops, I forgot to remove the "+ 1"

> > +		if (counter > 255)
> > +			counter = 0;
> 
> This is difficult to understand.

As you suggested, I'll change this to:
	if (counter > 256)
		counter = 256;

Chris

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

* RE: [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts
  2018-09-06 18:56     ` Guenter Roeck
  2018-09-06 19:40       ` Chris Brandt
@ 2018-09-06 21:39       ` Chris Brandt
  1 sibling, 0 replies; 8+ messages in thread
From: Chris Brandt @ 2018-09-06 21:39 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Wim Van Sebroeck, Rob Herring, Mark Rutland, Geert Uytterhoeven,
	linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org,
	linux-renesas-soc@vger.kernel.org, Simon Horman

On Thursday, September 06, 2018, Guenter Roeck wrote:
> > > +	u16 counter;
> > > +
> > > +	if (priv->cks == CKS_4BIT) {
> > > +		counter = DIV_ROUND_UP((timeout * rate),  4194304) + 1;
> >
> > two spaces ?
> >
> > Also, I am not sure how this prevents overflows. Was't the concern
> > that timeout * rate might overflow an int ?

Actually, I don't have to care about math overflows for large timeout 
values because the driver sets a max timeout value.

	if (priv->cks == CKS_4BIT) {
		/* Assume slowest clock rate possible (CKS=0xF) */
		priv->wdev.max_timeout = (4194304 * U8_MAX) / rate;


So if a user sends a timeout greater than that, the upper layer returns 
'Invalid argument' before it ever gets to the driver.

I guess that technically means I don't really have to do the
	if (counter > 256)
		counter = 256;
either because I will never get a timeout value greater than my max.

  (but, I might keep it in there anyway)

Chris

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

end of thread, other threads:[~2018-09-07  2:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-06 18:37 [PATCH v2 0/2] watchdog: Add support for RZ/A2 wdt Chris Brandt
2018-09-06 18:37 ` [PATCH v2 1/2] watchdog: rza_wdt: Support longer timeouts Chris Brandt
2018-09-06 18:52   ` Guenter Roeck
2018-09-06 18:56     ` Guenter Roeck
2018-09-06 19:40       ` Chris Brandt
2018-09-06 21:39       ` Chris Brandt
2018-09-06 20:45     ` Chris Brandt
2018-09-06 18:37 ` [PATCH v2 2/2] dt-bindings: watchdog: renesas-wdt: Add support for R7S9210 Chris Brandt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.