From: Tero Kristo Date: Tue, 15 Aug 2017 08:42:17 +0000 (+0300) Subject: clk: ti: clkctrl: use fallback udelay approach if timekeeping is suspended X-Git-Tag: v4.19~1676^2~7^2~24 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3d8598fb9c5a77837d9c0951efc5c36fdf91d87c;p=platform%2Fkernel%2Flinux-rpi.git 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: Tero Kristo Acked-by: Stephen Boyd --- diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 284ba449..38dbcc1 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "clock.h" #define NO_IDLEST 0x1 @@ -90,7 +91,18 @@ static bool _omap4_is_ready(u32 val) 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) { udelay(1); return false;