[source] cns3xxx: fix mpcore watchdog

LEDE Commits lede-commits at lists.infradead.org
Wed Apr 12 03:14:09 PDT 2017


nbd pushed a commit to source.git, branch master:
https://git.lede-project.org/84acff2865660d361283eaa4d995913c955d826b

commit 84acff2865660d361283eaa4d995913c955d826b
Author: Koen Vandeputte <koen.vandeputte at ncentric.com>
AuthorDate: Wed Apr 12 11:10:59 2017 +0200

    cns3xxx: fix mpcore watchdog
    
    The original implementation loaded the count register with (wrong) semi-
    random values due to its implemenation nature.
    
    If the wrongly calulated value was below the kickrate,
    the WD was triggered and rebooted the system.
    
    Rework this, partly based on upstream patches, to dynamically fetch the
    current clockrate and calculate the proper offset for the WD countdown
    register.
    
    Before:
    
    [  143.800000] count val: 27219720
    [  148.820000] count val: 50623201
    [  153.830000] count val: 96425250
    [  158.830000] count val: 89735401
    [  163.840000] count val: 4756110
    
    After:
    
    [    0.700000] MPCore WD init. clockrate: 299984500 prescaler: 256
    countrate: 1171814 timeout: 60s
    [  358.530000] count val: 35154751
    [  363.540000] count val: 35154750
    [  368.540000] count val: 35154751
    [  373.550000] count val: 35154750
    
    Signed-off-by: Koen Vandeputte <koen.vandeputte at ncentric.com>
---
 .../cns3xxx/patches-4.9/020-watchdog_support.patch | 45 +++++++++++++++++++---
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/target/linux/cns3xxx/patches-4.9/020-watchdog_support.patch b/target/linux/cns3xxx/patches-4.9/020-watchdog_support.patch
index 8707bf9..4f9f3e6 100644
--- a/target/linux/cns3xxx/patches-4.9/020-watchdog_support.patch
+++ b/target/linux/cns3xxx/patches-4.9/020-watchdog_support.patch
@@ -30,13 +30,14 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  obj-$(CONFIG_SAMA5D4_WATCHDOG) += sama5d4_wdt.o
 --- /dev/null
 +++ b/drivers/watchdog/mpcore_wdt.c
-@@ -0,0 +1,117 @@
+@@ -0,0 +1,118 @@
 +/*
 + * Watchdog driver for ARM MPcore
 + *
 + * Copyright (C) 2017 Felix Fietkau <nbd at nbd.name>
 + */
 +
++#include <linux/export.h>
 +#include <linux/module.h>
 +#include <linux/kernel.h>
 +#include <linux/watchdog.h>
@@ -52,10 +53,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 +	static int perturb;
 +	u32 count;
 +
-+	count = ioread32(wdt_base + TWD_WDOG_COUNTER);
-+	count = (~0U - count) * HZ / 5;
-+	count /= 256; /* prescale */
-+	count *= wdt_timeout;
++	count = (twd_timer_get_rate() / 256) * wdt_timeout;
 +
 +	/* Reload register needs a different value on each refresh */
 +	count += perturb;
@@ -118,6 +116,9 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 +static int mpcore_wdt_probe(struct platform_device *pdev)
 +{
 +	struct resource *res;
++	unsigned long rate = twd_timer_get_rate();
++
++	pr_info("MPCore WD init. clockrate: %u prescaler: %u countrate: %u timeout: %us\n", rate, 256, rate / 256, wdt_timeout);
 +
 +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +	if (!res)
@@ -148,3 +149,37 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 +module_platform_driver(mpcore_wdt_driver);
 +MODULE_AUTHOR("Felix Fietkau <nbd at nbd.name>");
 +MODULE_LICENSE("GPL");
+--- a/arch/arm/include/asm/smp_twd.h
++++ b/arch/arm/include/asm/smp_twd.h
+@@ -33,5 +33,6 @@ struct twd_local_timer name __initdata =
+ };
+ 
+ int twd_local_timer_register(struct twd_local_timer *);
++unsigned long twd_timer_get_rate(void);
+ 
+ #endif
+--- a/arch/arm/kernel/smp_twd.c
++++ b/arch/arm/kernel/smp_twd.c
+@@ -15,6 +15,7 @@
+ #include <linux/delay.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
++#include <linux/export.h>
+ #include <linux/smp.h>
+ #include <linux/jiffies.h>
+ #include <linux/clockchips.h>
+@@ -380,6 +381,14 @@ int __init twd_local_timer_register(stru
+ 	return twd_local_timer_common_register(NULL);
+ }
+ 
++/* Needed by mpcore_wdt */
++unsigned long twd_timer_get_rate(void)
++{
++	return twd_timer_rate;
++}
++EXPORT_SYMBOL_GPL(twd_timer_get_rate);
++
++
+ #ifdef CONFIG_OF
+ static int __init twd_local_timer_of_register(struct device_node *np)
+ {



More information about the lede-commits mailing list