|
@@ -28,6 +28,7 @@
|
|
#include <asm/dbell.h>
|
|
#include <asm/dbell.h>
|
|
#include <asm/fsl_guts.h>
|
|
#include <asm/fsl_guts.h>
|
|
#include <asm/code-patching.h>
|
|
#include <asm/code-patching.h>
|
|
|
|
+#include <asm/cputhreads.h>
|
|
|
|
|
|
#include <sysdev/fsl_soc.h>
|
|
#include <sysdev/fsl_soc.h>
|
|
#include <sysdev/mpic.h>
|
|
#include <sysdev/mpic.h>
|
|
@@ -168,6 +169,24 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
|
|
return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
|
|
return in_be32(&((struct epapr_spin_table *)spin_table)->addr_l);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_PPC64
|
|
|
|
+static void wake_hw_thread(void *info)
|
|
|
|
+{
|
|
|
|
+ void fsl_secondary_thread_init(void);
|
|
|
|
+ unsigned long imsr1, inia1;
|
|
|
|
+ int nr = *(const int *)info;
|
|
|
|
+
|
|
|
|
+ imsr1 = MSR_KERNEL;
|
|
|
|
+ inia1 = *(unsigned long *)fsl_secondary_thread_init;
|
|
|
|
+
|
|
|
|
+ mttmr(TMRN_IMSR1, imsr1);
|
|
|
|
+ mttmr(TMRN_INIA1, inia1);
|
|
|
|
+ mtspr(SPRN_TENS, TEN_THREAD(1));
|
|
|
|
+
|
|
|
|
+ smp_generic_kick_cpu(nr);
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
static int smp_85xx_kick_cpu(int nr)
|
|
static int smp_85xx_kick_cpu(int nr)
|
|
{
|
|
{
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
@@ -183,6 +202,31 @@ static int smp_85xx_kick_cpu(int nr)
|
|
|
|
|
|
pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
|
|
pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr);
|
|
|
|
|
|
|
|
+#ifdef CONFIG_PPC64
|
|
|
|
+ /* Threads don't use the spin table */
|
|
|
|
+ if (cpu_thread_in_core(nr) != 0) {
|
|
|
|
+ int primary = cpu_first_thread_sibling(nr);
|
|
|
|
+
|
|
|
|
+ if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
|
|
|
|
+ return -ENOENT;
|
|
|
|
+
|
|
|
|
+ if (cpu_thread_in_core(nr) != 1) {
|
|
|
|
+ pr_err("%s: cpu %d: invalid hw thread %d\n",
|
|
|
|
+ __func__, nr, cpu_thread_in_core(nr));
|
|
|
|
+ return -ENOENT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!cpu_online(primary)) {
|
|
|
|
+ pr_err("%s: cpu %d: primary %d not online\n",
|
|
|
|
+ __func__, nr, primary);
|
|
|
|
+ return -ENOENT;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ smp_call_function_single(primary, wake_hw_thread, &nr, 0);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
np = of_get_cpu_node(nr, NULL);
|
|
np = of_get_cpu_node(nr, NULL);
|
|
cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
|
|
cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL);
|
|
|
|
|