]> xenbits.xensource.com Git - people/aperard/linux-chromebook.git/commitdiff
watchdog: s3c2410: Avoid excessive petting during cpufreq
authorDoug Anderson <dianders@chromium.org>
Fri, 7 Sep 2012 18:12:01 +0000 (11:12 -0700)
committerGerrit <chrome-bot@google.com>
Thu, 22 Nov 2012 02:57:01 +0000 (18:57 -0800)
On more modern Samsung SoCs (like exynos5) the watchdog is
parented on a clock that doesn't change.  Avoid all of the extra
petting, disabling, and re-enabling of the watchdog in the case
that the clock never changes.

NOTE: As pointed out in
  <https://gerrit.chromium.org/gerrit/#/c/31465/>

...the proper way would be to register a notifier for the clock
directly, but CONFIG_COMMON_CLK isn't enabled.

BUG=chrome-os-partner:9403
TEST=If I open /dev/watchdog now it eventually dies.

Change-Id: I4f982dc85caf091444633aff94b90d524bdfe829
Signed-off-by: Doug Anderson <dianders@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/32566
Reviewed-by: Olof Johansson <olofj@chromium.org>
Commit-Ready: Grant Grundler <grundler@chromium.org>
Reviewed-by: Grant Grundler <grundler@chromium.org>
Tested-by: Grant Grundler <grundler@chromium.org>
drivers/watchdog/s3c2410_wdt.c

index 04e5a6de47d72743b7010758f1c78230d416f221..1789d5597a3a926103f90ae847513565b2dd4b09 100644 (file)
@@ -78,6 +78,7 @@ static struct device    *wdt_dev;     /* platform device attached to */
 static struct resource *wdt_mem;
 static struct resource *wdt_irq;
 static struct clk      *wdt_clock;
+static unsigned long    wdt_clockrate;
 static void __iomem    *wdt_base;
 static unsigned int     wdt_count;
 static DEFINE_SPINLOCK(wdt_lock);
@@ -156,15 +157,17 @@ static inline int s3c2410wdt_is_running(void)
 
 static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeout)
 {
-       unsigned long freq = clk_get_rate(wdt_clock);
+       unsigned long freq;
        unsigned int count;
        unsigned int divisor = 1;
        unsigned long wtcon;
 
+       wdt_clockrate = clk_get_rate(wdt_clock);
+
        if (timeout < 1)
                return -EINVAL;
 
-       freq /= 128;
+       freq = wdt_clockrate / 128;
        count = timeout * freq;
 
        DBG("%s: count=%d, timeout=%d, freq=%lu\n",
@@ -248,6 +251,14 @@ static int s3c2410wdt_cpufreq_transition(struct notifier_block *nb,
        if (!s3c2410wdt_is_running())
                goto done;
 
+       /*
+        * Avoid excessive petting and disabling/enabling if the clock rate
+        * isn't actually changing.  In modern SoCs the watchdog is parented
+        * on a clock that never adjusts
+        */
+       if (clk_get_rate(wdt_clock) == wdt_clockrate)
+               goto done;
+
        if (val == CPUFREQ_PRECHANGE) {
                /* To ensure that over the change we don't cause the
                 * watchdog to trigger, we perform an keep-alive if