diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2016-07-24 09:27:20 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-08-22 15:26:51 +1000 |
commit | 610d54e7c0d9d4e1650b38ac408dc14225b57493 (patch) | |
tree | d3b5df69c4f66767fabe36f10d7c1dc02f9a7fe7 /core/timebase.c | |
parent | 36be5e0ac86e6aeb020a2e37cc146cc2ff7a6bb5 (diff) | |
download | skiboot-610d54e7c0d9d4e1650b38ac408dc14225b57493.zip skiboot-610d54e7c0d9d4e1650b38ac408dc14225b57493.tar.gz skiboot-610d54e7c0d9d4e1650b38ac408dc14225b57493.tar.bz2 |
time: Setup DEC and call cpu_idle() in time_wait_nopoll()
This will currently do nothing more than spin but will eventually
allow us to nap until the decrementer fires.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/timebase.c')
-rw-r--r-- | core/timebase.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/core/timebase.c b/core/timebase.c index 8b1c01b..a3c0fec 100644 --- a/core/timebase.c +++ b/core/timebase.c @@ -65,14 +65,27 @@ void time_wait(unsigned long duration) void time_wait_nopoll(unsigned long duration) { unsigned long end = mftb() + duration; + unsigned long min = usecs_to_tb(10); if (this_cpu()->tb_invalid) { cpu_relax(); return; } - while(tb_compare(mftb(), end) != TB_AAFTERB) - cpu_relax(); + for (;;) { + uint64_t delay, tb = mftb(); + + if (tb_compare(tb, end) == TB_AAFTERB) + break; + delay = end - tb; + if (delay >= 0x7fffffff) + delay = 0x7fffffff; + if (delay >= min) { + mtspr(SPR_DEC, delay); + cpu_idle(cpu_wake_on_dec); + } else + cpu_relax(); + } } void time_wait_ms(unsigned long ms) |