summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/85xx/smp.c
diff options
context:
space:
mode:
authorGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-09-27 11:56:14 -0300
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-09-27 11:56:14 -0300
commit1025c04cecd19882e28f16c4004034b475c372c5 (patch)
tree2b7402887e86d54bff5a123228c9059eae5e32bd /arch/powerpc/platforms/85xx/smp.c
parent4375f1037d52602413142e290608d0d84671ad36 (diff)
parent5bcecf325378218a8e248bb6bcae96ec7362f8ef (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
Conflicts: net/bluetooth/hci_core.c
Diffstat (limited to 'arch/powerpc/platforms/85xx/smp.c')
-rw-r--r--arch/powerpc/platforms/85xx/smp.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 5ced4f5bb2b..281b7f01df6 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -69,7 +69,32 @@ static void mpc85xx_give_timebase(void)
tb_req = 0;
mpc85xx_timebase_freeze(1);
+#ifdef CONFIG_PPC64
+ /*
+ * e5500/e6500 have a workaround for erratum A-006958 in place
+ * that will reread the timebase until TBL is non-zero.
+ * That would be a bad thing when the timebase is frozen.
+ *
+ * Thus, we read it manually, and instead of checking that
+ * TBL is non-zero, we ensure that TB does not change. We don't
+ * do that for the main mftb implementation, because it requires
+ * a scratch register
+ */
+ {
+ u64 prev;
+
+ asm volatile("mfspr %0, %1" : "=r" (timebase) :
+ "i" (SPRN_TBRL));
+
+ do {
+ prev = timebase;
+ asm volatile("mfspr %0, %1" : "=r" (timebase) :
+ "i" (SPRN_TBRL));
+ } while (prev != timebase);
+ }
+#else
timebase = get_tb();
+#endif
mb();
tb_valid = 1;
@@ -255,6 +280,7 @@ out:
struct smp_ops_t smp_85xx_ops = {
.kick_cpu = smp_85xx_kick_cpu,
+ .cpu_bootable = smp_generic_cpu_bootable,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_disable = generic_cpu_disable,
.cpu_die = generic_cpu_die,