diff options
| -rw-r--r-- | arch/powerpc/include/asm/rtas.h | 3 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rtas.c | 31 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/smp.c | 30 | ||||
| -rw-r--r-- | arch/powerpc/platforms/chrp/smp.c | 33 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/smp.c | 30 |
5 files changed, 40 insertions, 87 deletions
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 0af42d20b692..168fce726201 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
| @@ -245,5 +245,8 @@ static inline u32 rtas_config_addr(int busno, int devfn, int reg) | |||
| 245 | (devfn << 8) | (reg & 0xff); | 245 | (devfn << 8) | (reg & 0xff); |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | extern void __cpuinit rtas_give_timebase(void); | ||
| 249 | extern void __cpuinit rtas_take_timebase(void); | ||
| 250 | |||
| 248 | #endif /* __KERNEL__ */ | 251 | #endif /* __KERNEL__ */ |
| 249 | #endif /* _POWERPC_RTAS_H */ | 252 | #endif /* _POWERPC_RTAS_H */ |
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 | } | ||
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index 9046803c8276..bc97fada48c6 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c | |||
| @@ -36,7 +36,6 @@ | |||
| 36 | #include <asm/prom.h> | 36 | #include <asm/prom.h> |
| 37 | #include <asm/smp.h> | 37 | #include <asm/smp.h> |
| 38 | #include <asm/paca.h> | 38 | #include <asm/paca.h> |
| 39 | #include <asm/time.h> | ||
| 40 | #include <asm/machdep.h> | 39 | #include <asm/machdep.h> |
| 41 | #include <asm/cputable.h> | 40 | #include <asm/cputable.h> |
| 42 | #include <asm/firmware.h> | 41 | #include <asm/firmware.h> |
| @@ -140,31 +139,6 @@ static void __devinit smp_cell_setup_cpu(int cpu) | |||
| 140 | mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); | 139 | mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); |
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | static DEFINE_SPINLOCK(timebase_lock); | ||
| 144 | static unsigned long timebase = 0; | ||
| 145 | |||
| 146 | static void __devinit cell_give_timebase(void) | ||
| 147 | { | ||
| 148 | spin_lock(&timebase_lock); | ||
| 149 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
| 150 | timebase = get_tb(); | ||
| 151 | spin_unlock(&timebase_lock); | ||
| 152 | |||
| 153 | while (timebase) | ||
| 154 | barrier(); | ||
| 155 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
| 156 | } | ||
| 157 | |||
| 158 | static void __devinit cell_take_timebase(void) | ||
| 159 | { | ||
| 160 | while (!timebase) | ||
| 161 | barrier(); | ||
| 162 | spin_lock(&timebase_lock); | ||
| 163 | set_tb(timebase >> 32, timebase & 0xffffffff); | ||
| 164 | timebase = 0; | ||
| 165 | spin_unlock(&timebase_lock); | ||
| 166 | } | ||
| 167 | |||
| 168 | static void __devinit smp_cell_kick_cpu(int nr) | 142 | static void __devinit smp_cell_kick_cpu(int nr) |
| 169 | { | 143 | { |
| 170 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 144 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
| @@ -224,8 +198,8 @@ void __init smp_init_cell(void) | |||
| 224 | 198 | ||
| 225 | /* Non-lpar has additional take/give timebase */ | 199 | /* Non-lpar has additional take/give timebase */ |
| 226 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { | 200 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { |
| 227 | smp_ops->give_timebase = cell_give_timebase; | 201 | smp_ops->give_timebase = rtas_give_timebase; |
| 228 | smp_ops->take_timebase = cell_take_timebase; | 202 | smp_ops->take_timebase = rtas_take_timebase; |
| 229 | } | 203 | } |
| 230 | 204 | ||
| 231 | DBG(" <- smp_init_cell()\n"); | 205 | DBG(" <- smp_init_cell()\n"); |
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index 10a4a4d063b6..02cafecc90e3 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| 27 | #include <asm/prom.h> | 27 | #include <asm/prom.h> |
| 28 | #include <asm/smp.h> | 28 | #include <asm/smp.h> |
| 29 | #include <asm/time.h> | ||
| 30 | #include <asm/machdep.h> | 29 | #include <asm/machdep.h> |
| 31 | #include <asm/mpic.h> | 30 | #include <asm/mpic.h> |
| 32 | #include <asm/rtas.h> | 31 | #include <asm/rtas.h> |
| @@ -42,40 +41,12 @@ static void __devinit smp_chrp_setup_cpu(int cpu_nr) | |||
| 42 | mpic_setup_this_cpu(); | 41 | mpic_setup_this_cpu(); |
| 43 | } | 42 | } |
| 44 | 43 | ||
| 45 | static DEFINE_SPINLOCK(timebase_lock); | ||
| 46 | static unsigned int timebase_upper = 0, timebase_lower = 0; | ||
| 47 | |||
| 48 | void __devinit smp_chrp_give_timebase(void) | ||
| 49 | { | ||
| 50 | spin_lock(&timebase_lock); | ||
| 51 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
| 52 | timebase_upper = get_tbu(); | ||
| 53 | timebase_lower = get_tbl(); | ||
| 54 | spin_unlock(&timebase_lock); | ||
| 55 | |||
| 56 | while (timebase_upper || timebase_lower) | ||
| 57 | barrier(); | ||
| 58 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
| 59 | } | ||
| 60 | |||
| 61 | void __devinit smp_chrp_take_timebase(void) | ||
| 62 | { | ||
| 63 | while (!(timebase_upper || timebase_lower)) | ||
| 64 | barrier(); | ||
| 65 | spin_lock(&timebase_lock); | ||
| 66 | set_tb(timebase_upper, timebase_lower); | ||
| 67 | timebase_upper = 0; | ||
| 68 | timebase_lower = 0; | ||
| 69 | spin_unlock(&timebase_lock); | ||
| 70 | printk("CPU %i taken timebase\n", smp_processor_id()); | ||
| 71 | } | ||
| 72 | |||
| 73 | /* CHRP with openpic */ | 44 | /* CHRP with openpic */ |
| 74 | struct smp_ops_t chrp_smp_ops = { | 45 | struct smp_ops_t chrp_smp_ops = { |
| 75 | .message_pass = smp_mpic_message_pass, | 46 | .message_pass = smp_mpic_message_pass, |
| 76 | .probe = smp_mpic_probe, | 47 | .probe = smp_mpic_probe, |
| 77 | .kick_cpu = smp_chrp_kick_cpu, | 48 | .kick_cpu = smp_chrp_kick_cpu, |
| 78 | .setup_cpu = smp_chrp_setup_cpu, | 49 | .setup_cpu = smp_chrp_setup_cpu, |
| 79 | .give_timebase = smp_chrp_give_timebase, | 50 | .give_timebase = rtas_give_timebase, |
| 80 | .take_timebase = smp_chrp_take_timebase, | 51 | .take_timebase = rtas_take_timebase, |
| 81 | }; | 52 | }; |
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 1a231c389ba0..1f8f6cfb94f7 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include <asm/prom.h> | 35 | #include <asm/prom.h> |
| 36 | #include <asm/smp.h> | 36 | #include <asm/smp.h> |
| 37 | #include <asm/paca.h> | 37 | #include <asm/paca.h> |
| 38 | #include <asm/time.h> | ||
| 39 | #include <asm/machdep.h> | 38 | #include <asm/machdep.h> |
| 40 | #include <asm/cputable.h> | 39 | #include <asm/cputable.h> |
| 41 | #include <asm/firmware.h> | 40 | #include <asm/firmware.h> |
| @@ -118,31 +117,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
| 118 | } | 117 | } |
| 119 | #endif /* CONFIG_XICS */ | 118 | #endif /* CONFIG_XICS */ |
| 120 | 119 | ||
| 121 | static DEFINE_SPINLOCK(timebase_lock); | ||
| 122 | static unsigned long timebase = 0; | ||
| 123 | |||
| 124 | static void __devinit pSeries_give_timebase(void) | ||
| 125 | { | ||
| 126 | spin_lock(&timebase_lock); | ||
| 127 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
| 128 | timebase = get_tb(); | ||
| 129 | spin_unlock(&timebase_lock); | ||
| 130 | |||
| 131 | while (timebase) | ||
| 132 | barrier(); | ||
| 133 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
| 134 | } | ||
| 135 | |||
| 136 | static void __devinit pSeries_take_timebase(void) | ||
| 137 | { | ||
| 138 | while (!timebase) | ||
| 139 | barrier(); | ||
| 140 | spin_lock(&timebase_lock); | ||
| 141 | set_tb(timebase >> 32, timebase & 0xffffffff); | ||
| 142 | timebase = 0; | ||
| 143 | spin_unlock(&timebase_lock); | ||
| 144 | } | ||
| 145 | |||
| 146 | static void __devinit smp_pSeries_kick_cpu(int nr) | 120 | static void __devinit smp_pSeries_kick_cpu(int nr) |
| 147 | { | 121 | { |
| 148 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 122 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
| @@ -209,8 +183,8 @@ static void __init smp_init_pseries(void) | |||
| 209 | 183 | ||
| 210 | /* Non-lpar has additional take/give timebase */ | 184 | /* Non-lpar has additional take/give timebase */ |
| 211 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { | 185 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { |
| 212 | smp_ops->give_timebase = pSeries_give_timebase; | 186 | smp_ops->give_timebase = rtas_give_timebase; |
| 213 | smp_ops->take_timebase = pSeries_take_timebase; | 187 | smp_ops->take_timebase = rtas_take_timebase; |
| 214 | } | 188 | } |
| 215 | 189 | ||
| 216 | pr_debug(" <- smp_init_pSeries()\n"); | 190 | pr_debug(" <- smp_init_pSeries()\n"); |
