diff options
Diffstat (limited to 'arch/powerpc/kernel/rtas.c')
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index d9a9974c6938..c434823b8c83 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/syscalls.h> | 38 | #include <asm/syscalls.h> |
39 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
40 | #include <asm/atomic.h> | 40 | #include <asm/atomic.h> |
41 | #include <asm/time.h> | ||
41 | 42 | ||
42 | struct rtas_t rtas = { | 43 | struct rtas_t rtas = { |
43 | .lock = __RAW_SPIN_LOCK_UNLOCKED | 44 | .lock = __RAW_SPIN_LOCK_UNLOCKED |
@@ -971,3 +972,33 @@ int __init early_init_dt_scan_rtas(unsigned long node, | |||
971 | /* break now */ | 972 | /* break now */ |
972 | return 1; | 973 | return 1; |
973 | } | 974 | } |
975 | |||
976 | static raw_spinlock_t timebase_lock; | ||
977 | static u64 timebase = 0; | ||
978 | |||
979 | void __cpuinit rtas_give_timebase(void) | ||
980 | { | ||
981 | unsigned long flags; | ||
982 | |||
983 | local_irq_save(flags); | ||
984 | hard_irq_disable(); | ||
985 | __raw_spin_lock(&timebase_lock); | ||
986 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
987 | timebase = get_tb(); | ||
988 | __raw_spin_unlock(&timebase_lock); | ||
989 | |||
990 | while (timebase) | ||
991 | barrier(); | ||
992 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
993 | local_irq_restore(flags); | ||
994 | } | ||
995 | |||
996 | void __cpuinit rtas_take_timebase(void) | ||
997 | { | ||
998 | while (!timebase) | ||
999 | barrier(); | ||
1000 | __raw_spin_lock(&timebase_lock); | ||
1001 | set_tb(timebase >> 32, timebase & 0xffffffff); | ||
1002 | timebase = 0; | ||
1003 | __raw_spin_unlock(&timebase_lock); | ||
1004 | } | ||