Skip to content

Commit

Permalink
clk: ti: clkctrl: use fallback udelay approach if timekeeping is susp…
Browse files Browse the repository at this point in the history
…ended

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 <t-kristo@ti.com>
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
  • Loading branch information
Tero Kristo committed Dec 1, 2017
1 parent 5b385a4 commit 3d8598f
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion drivers/clk/ti/clkctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/of_address.h>
#include <linux/clk/ti.h>
#include <linux/delay.h>
#include <linux/timekeeping.h>
#include "clock.h"

#define NO_IDLEST 0x1
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 3d8598f

Please sign in to comment.