aboutsummaryrefslogtreecommitdiff
path: root/core/timebase.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2016-07-24 09:27:20 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-08-22 15:26:51 +1000
commit610d54e7c0d9d4e1650b38ac408dc14225b57493 (patch)
treed3b5df69c4f66767fabe36f10d7c1dc02f9a7fe7 /core/timebase.c
parent36be5e0ac86e6aeb020a2e37cc146cc2ff7a6bb5 (diff)
downloadskiboot-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.c17
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)