[v3,2/4] watchdog: cadence_wdt: Calculate actual timeout limits
diff mbox series

Message ID 20190709200801.42313-3-tomas.melin@vaisala.com
State Changes Requested
Headers show
Series
  • watchdog: cadence_wdt: Support all available prescaler values
Related show

Commit Message

Melin Tomas July 9, 2019, 8:09 p.m. UTC
Maximum and minimum timeout values depend on the actual input clock
frequency and prescaler selection.

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
---
 drivers/watchdog/cadence_wdt.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

Comments

Guenter Roeck July 9, 2019, 8:14 p.m. UTC | #1
On Tue, Jul 09, 2019 at 08:09:05PM +0000, Melin Tomas wrote:
> Maximum and minimum timeout values depend on the actual input clock
> frequency and prescaler selection.
> 
> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
> ---
>  drivers/watchdog/cadence_wdt.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c
> index ddbf602bdc40..a0d7666e7d20 100644
> --- a/drivers/watchdog/cadence_wdt.c
> +++ b/drivers/watchdog/cadence_wdt.c
> @@ -18,9 +18,6 @@
>  #include <linux/watchdog.h>
>  
>  #define CDNS_WDT_DEFAULT_TIMEOUT	10
> -/* Supports 1 - 516 sec */
> -#define CDNS_WDT_MIN_TIMEOUT	1
> -#define CDNS_WDT_MAX_TIMEOUT	516
>  
>  /* Restart key */
>  #define CDNS_WDT_RESTART_KEY 0x00001999
> @@ -28,6 +25,10 @@
>  /* Counter register access key */
>  #define CDNS_WDT_REGISTER_ACCESS_KEY 0x00920000
>  
> +/* Counter control register, counter restart values */
> +#define CDNS_WDT_CCR_CRV_MIN 0xFFF
> +#define CDNS_WDT_CCR_CRV_MAX 0xFFFFFF
                               ^ Please use tabs here

> +
>  /* Counter value divisor */
>  #define CDNS_WDT_COUNTER_VALUE_DIVISOR 0x1000
>  
> @@ -317,7 +318,10 @@ static int cdns_wdt_probe(struct platform_device *pdev)
>  		return ret;
>  
>  	clock_f = clk_get_rate(wdt->clk);
> -	if (clock_f <= CDNS_WDT_CLK_75MHZ) {
> +	if (clock_f == 0) {
> +		dev_err(dev, "invalid clock frequency, (f=%lu)\n", clock_f);

We know that clock_f is 0 here. No need to use %lu.

> +		return -EINVAL;

else after return is unnecessary (and static checkers will rightfully complain).

> +	} else if (clock_f <= CDNS_WDT_CLK_75MHZ) {
>  		wdt->prescaler = CDNS_WDT_PRESCALE_512;
>  		wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512;
>  	} else {
> @@ -329,8 +333,10 @@ static int cdns_wdt_probe(struct platform_device *pdev)
>  	cdns_wdt_device->info = &cdns_wdt_info;
>  	cdns_wdt_device->ops = &cdns_wdt_ops;
>  	cdns_wdt_device->timeout = CDNS_WDT_DEFAULT_TIMEOUT;
> -	cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT;
> -	cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT;
> +	cdns_wdt_device->min_timeout =
> +		CDNS_WDT_CCR_CRV_MIN * wdt->prescaler / clock_f;
> +	cdns_wdt_device->max_timeout =
> +		CDNS_WDT_CCR_CRV_MAX * wdt->prescaler / clock_f;
>  
>  	wdt->regs = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(wdt->regs))
> -- 
> 2.17.2
>

Patch
diff mbox series

diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c
index ddbf602bdc40..a0d7666e7d20 100644
--- a/drivers/watchdog/cadence_wdt.c
+++ b/drivers/watchdog/cadence_wdt.c
@@ -18,9 +18,6 @@ 
 #include <linux/watchdog.h>
 
 #define CDNS_WDT_DEFAULT_TIMEOUT	10
-/* Supports 1 - 516 sec */
-#define CDNS_WDT_MIN_TIMEOUT	1
-#define CDNS_WDT_MAX_TIMEOUT	516
 
 /* Restart key */
 #define CDNS_WDT_RESTART_KEY 0x00001999
@@ -28,6 +25,10 @@ 
 /* Counter register access key */
 #define CDNS_WDT_REGISTER_ACCESS_KEY 0x00920000
 
+/* Counter control register, counter restart values */
+#define CDNS_WDT_CCR_CRV_MIN 0xFFF
+#define CDNS_WDT_CCR_CRV_MAX 0xFFFFFF
+
 /* Counter value divisor */
 #define CDNS_WDT_COUNTER_VALUE_DIVISOR 0x1000
 
@@ -317,7 +318,10 @@  static int cdns_wdt_probe(struct platform_device *pdev)
 		return ret;
 
 	clock_f = clk_get_rate(wdt->clk);
-	if (clock_f <= CDNS_WDT_CLK_75MHZ) {
+	if (clock_f == 0) {
+		dev_err(dev, "invalid clock frequency, (f=%lu)\n", clock_f);
+		return -EINVAL;
+	} else if (clock_f <= CDNS_WDT_CLK_75MHZ) {
 		wdt->prescaler = CDNS_WDT_PRESCALE_512;
 		wdt->ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512;
 	} else {
@@ -329,8 +333,10 @@  static int cdns_wdt_probe(struct platform_device *pdev)
 	cdns_wdt_device->info = &cdns_wdt_info;
 	cdns_wdt_device->ops = &cdns_wdt_ops;
 	cdns_wdt_device->timeout = CDNS_WDT_DEFAULT_TIMEOUT;
-	cdns_wdt_device->min_timeout = CDNS_WDT_MIN_TIMEOUT;
-	cdns_wdt_device->max_timeout = CDNS_WDT_MAX_TIMEOUT;
+	cdns_wdt_device->min_timeout =
+		CDNS_WDT_CCR_CRV_MIN * wdt->prescaler / clock_f;
+	cdns_wdt_device->max_timeout =
+		CDNS_WDT_CCR_CRV_MAX * wdt->prescaler / clock_f;
 
 	wdt->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(wdt->regs))