powerpc: Use one common impl. of RTAS timebase sync and use raw spinlock

Several platforms use their own copy of what is essentially the same code,
using RTAS to synchronize the timebases when bringing up new CPUs. This
moves it all into a single common implementation and additionally
turns the spinlock into a raw spinlock since the former can rely on
the timebase not being frozen when spinlock debugging is enabled, and finally
masks interrupts while the timebase is disabled.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
Benjamin Herrenschmidt
2009-06-16 16:42:50 +00:00
parent f97bb36f70
commit c4007a2fbf
5 changed files with 40 additions and 87 deletions

View File

@@ -38,6 +38,7 @@
#include <asm/syscalls.h>
#include <asm/smp.h>
#include <asm/atomic.h>
#include <asm/time.h>
struct rtas_t rtas = {
.lock = __RAW_SPIN_LOCK_UNLOCKED
@@ -971,3 +972,33 @@ int __init early_init_dt_scan_rtas(unsigned long node,
/* break now */
return 1;
}
static raw_spinlock_t timebase_lock;
static u64 timebase = 0;
void __cpuinit rtas_give_timebase(void)
{
unsigned long flags;
local_irq_save(flags);
hard_irq_disable();
__raw_spin_lock(&timebase_lock);
rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
timebase = get_tb();
__raw_spin_unlock(&timebase_lock);
while (timebase)
barrier();
rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL);
local_irq_restore(flags);
}
void __cpuinit rtas_take_timebase(void)
{
while (!timebase)
barrier();
__raw_spin_lock(&timebase_lock);
set_tb(timebase >> 32, timebase & 0xffffffff);
timebase = 0;
__raw_spin_unlock(&timebase_lock);
}