Commit 3d8598fb authored by Tero Kristo's avatar Tero Kristo

clk: ti: clkctrl: use fallback udelay approach if timekeeping is suspended

In certain cases it is possible that the timekeeping has been suspended
already when attempting to disable/enable a clkctrl clock. This will
happen at least on am43xx platform when attempting to enable / disable
the clockevent source itself, burping out a warning from timekeeping core.

The sequence of events leading to this:
-> timekeeping_suspend()
 -> clockevents_suspend()
  -> omap_clkevt_idle()
   -> omap_hwmod_idle()
    -> _omap4_clkctrl_clk_disable()
     -> _omap4_is_timeout()

Avoid the issue by checking if the timekeeping is suspended and using
the fallback udelay approach for checking timeouts.
Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
Acked-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 5b385a45
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/clk/ti.h> #include <linux/clk/ti.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/timekeeping.h>
#include "clock.h" #include "clock.h"
#define NO_IDLEST 0x1 #define NO_IDLEST 0x1
...@@ -90,7 +91,18 @@ static bool _omap4_is_ready(u32 val) ...@@ -90,7 +91,18 @@ static bool _omap4_is_ready(u32 val)
static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout) static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
{ {
if (unlikely(_early_timeout)) { /*
* There are two special cases where ktime_to_ns() can't be
* used to track the timeouts. First one is during early boot
* when the timers haven't been initialized yet. The second
* one is during suspend-resume cycle while timekeeping is
* being suspended / resumed. Clocksource for the system
* can be from a timer that requires pm_runtime access, which
* will eventually bring us here with timekeeping_suspended,
* during both suspend entry and resume paths. This happens
* at least on am43xx platform.
*/
if (unlikely(_early_timeout || timekeeping_suspended)) {
if (time->cycles++ < timeout) { if (time->cycles++ < timeout) {
udelay(1); udelay(1);
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment