diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-01-20 14:01:31 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-01-20 14:01:31 -0300 |
commit | b4b7ff4b08e691656c9d77c758fc355833128ac0 (patch) | |
tree | 82fcb00e6b918026dc9f2d1f05ed8eee83874cc0 /arch/powerpc/platforms/85xx | |
parent | 35acfa0fc609f2a2cd95cef4a6a9c3a5c38f1778 (diff) |
Linux-libre 4.4-gnupck-4.4-gnu
Diffstat (limited to 'arch/powerpc/platforms/85xx')
-rw-r--r-- | arch/powerpc/platforms/85xx/corenet_generic.c | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_mds.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/p1022_ds.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/p1022_rdk.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/smp.c | 88 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/twr_p102x.c | 2 |
7 files changed, 95 insertions, 14 deletions
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c index b39557120..46d05c94a 100644 --- a/arch/powerpc/platforms/85xx/corenet_generic.c +++ b/arch/powerpc/platforms/85xx/corenet_generic.c @@ -161,6 +161,7 @@ static const char * const boards[] __initconst = { "fsl,T1042RDB", "fsl,T1042RDB_PI", "keymile,kmcoge4", + "varisys,CYRUS", NULL }; @@ -214,7 +215,17 @@ define_machine(corenet_generic) { .pcibios_fixup_bus = fsl_pcibios_fixup_bus, .pcibios_fixup_phb = fsl_pcibios_fixup_phb, #endif +/* + * Core reset may cause issues if using the proxy mode of MPIC. + * So, use the mixed mode of MPIC if enabling CPU hotplug. + * + * Likewise, problems have been seen with kexec when coreint is enabled. + */ +#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC) + .get_irq = mpic_get_irq, +#else .get_irq = mpic_get_coreint_irq, +#endif .restart = fsl_rstcr_restart, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index a392e94a0..f0be439ce 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -34,6 +34,7 @@ #include <linux/of_device.h> #include <linux/phy.h> #include <linux/memblock.h> +#include <linux/fsl/guts.h> #include <linux/atomic.h> #include <asm/time.h> @@ -51,7 +52,6 @@ #include <asm/qe_ic.h> #include <asm/mpic.h> #include <asm/swiotlb.h> -#include <asm/fsl_guts.h> #include "smp.h" #include "mpc85xx.h" diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index e358bed66..50dcc00a0 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c @@ -17,6 +17,7 @@ #include <linux/seq_file.h> #include <linux/interrupt.h> #include <linux/of_platform.h> +#include <linux/fsl/guts.h> #include <asm/time.h> #include <asm/machdep.h> @@ -27,7 +28,6 @@ #include <asm/mpic.h> #include <asm/qe.h> #include <asm/qe_ic.h> -#include <asm/fsl_guts.h> #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c index 6ac986d3f..371df822e 100644 --- a/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/arch/powerpc/platforms/85xx/p1022_ds.c @@ -16,6 +16,7 @@ * kind, whether express or implied. */ +#include <linux/fsl/guts.h> #include <linux/pci.h> #include <linux/of_platform.h> #include <asm/div64.h> @@ -25,7 +26,6 @@ #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> #include <asm/udbg.h> -#include <asm/fsl_guts.h> #include <asm/fsl_lbc.h> #include "smp.h" diff --git a/arch/powerpc/platforms/85xx/p1022_rdk.c b/arch/powerpc/platforms/85xx/p1022_rdk.c index 680232d6b..5087becaa 100644 --- a/arch/powerpc/platforms/85xx/p1022_rdk.c +++ b/arch/powerpc/platforms/85xx/p1022_rdk.c @@ -12,6 +12,7 @@ * kind, whether express or implied. */ +#include <linux/fsl/guts.h> #include <linux/pci.h> #include <linux/of_platform.h> #include <asm/div64.h> @@ -21,7 +22,6 @@ #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> #include <asm/udbg.h> -#include <asm/fsl_guts.h> #include "smp.h" #include "mpc85xx.h" diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index b8b821697..6b107cea1 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -19,6 +19,7 @@ #include <linux/kexec.h> #include <linux/highmem.h> #include <linux/cpu.h> +#include <linux/fsl/guts.h> #include <asm/machdep.h> #include <asm/pgtable.h> @@ -26,7 +27,6 @@ #include <asm/mpic.h> #include <asm/cacheflush.h> #include <asm/dbell.h> -#include <asm/fsl_guts.h> #include <asm/code-patching.h> #include <asm/cputhreads.h> @@ -173,15 +173,22 @@ static inline u32 read_spin_table_addr_l(void *spin_table) static void wake_hw_thread(void *info) { void fsl_secondary_thread_init(void); - unsigned long imsr1, inia1; + unsigned long imsr, inia; 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)); + imsr = MSR_KERNEL; + inia = *(unsigned long *)fsl_secondary_thread_init; + + if (cpu_thread_in_core(nr) == 0) { + /* For when we boot on a secondary thread with kdump */ + mttmr(TMRN_IMSR0, imsr); + mttmr(TMRN_INIA0, inia); + mtspr(SPRN_TENS, TEN_THREAD(0)); + } else { + mttmr(TMRN_IMSR1, imsr); + mttmr(TMRN_INIA1, inia); + mtspr(SPRN_TENS, TEN_THREAD(1)); + } smp_generic_kick_cpu(nr); } @@ -224,6 +231,12 @@ static int smp_85xx_kick_cpu(int nr) smp_call_function_single(primary, wake_hw_thread, &nr, 0); return 0; + } else if (cpu_thread_in_core(boot_cpuid) != 0 && + cpu_first_thread_sibling(boot_cpuid) == nr) { + if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) + return -ENOENT; + + smp_call_function_single(boot_cpuid, wake_hw_thread, &nr, 0); } #endif @@ -331,13 +344,14 @@ struct smp_ops_t smp_85xx_ops = { .cpu_disable = generic_cpu_disable, .cpu_die = generic_cpu_die, #endif -#ifdef CONFIG_KEXEC +#if defined(CONFIG_KEXEC) && !defined(CONFIG_PPC64) .give_timebase = smp_generic_give_timebase, .take_timebase = smp_generic_take_timebase, #endif }; #ifdef CONFIG_KEXEC +#ifdef CONFIG_PPC32 atomic_t kexec_down_cpus = ATOMIC_INIT(0); void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) @@ -357,9 +371,64 @@ static void mpc85xx_smp_kexec_down(void *arg) if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down(0,1); } +#else +void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) +{ + int cpu = smp_processor_id(); + int sibling = cpu_last_thread_sibling(cpu); + bool notified = false; + int disable_cpu; + int disable_threadbit = 0; + long start = mftb(); + long now; + + local_irq_disable(); + hard_irq_disable(); + mpic_teardown_this_cpu(secondary); + + if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) { + /* + * We enter the crash kernel on whatever cpu crashed, + * even if it's a secondary thread. If that's the case, + * disable the corresponding primary thread. + */ + disable_threadbit = 1; + disable_cpu = cpu_first_thread_sibling(cpu); + } else if (sibling != crashing_cpu && + cpu_thread_in_core(cpu) == 0 && + cpu_thread_in_core(sibling) != 0) { + disable_threadbit = 2; + disable_cpu = sibling; + } + + if (disable_threadbit) { + while (paca[disable_cpu].kexec_state < KEXEC_STATE_REAL_MODE) { + barrier(); + now = mftb(); + if (!notified && now - start > 1000000) { + pr_info("%s/%d: waiting for cpu %d to enter KEXEC_STATE_REAL_MODE (%d)\n", + __func__, smp_processor_id(), + disable_cpu, + paca[disable_cpu].kexec_state); + notified = true; + } + } + + if (notified) { + pr_info("%s: cpu %d done waiting\n", + __func__, disable_cpu); + } + + mtspr(SPRN_TENC, disable_threadbit); + while (mfspr(SPRN_TENSR) & disable_threadbit) + cpu_relax(); + } +} +#endif static void mpc85xx_smp_machine_kexec(struct kimage *image) { +#ifdef CONFIG_PPC32 int timeout = INT_MAX; int i, num_cpus = num_present_cpus(); @@ -380,6 +449,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image) if ( i == smp_processor_id() ) continue; mpic_reset_core(i); } +#endif default_machine_kexec(image); } diff --git a/arch/powerpc/platforms/85xx/twr_p102x.c b/arch/powerpc/platforms/85xx/twr_p102x.c index 30e002f46..892e61351 100644 --- a/arch/powerpc/platforms/85xx/twr_p102x.c +++ b/arch/powerpc/platforms/85xx/twr_p102x.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/errno.h> +#include <linux/fsl/guts.h> #include <linux/pci.h> #include <linux/of_platform.h> @@ -23,7 +24,6 @@ #include <asm/mpic.h> #include <asm/qe.h> #include <asm/qe_ic.h> -#include <asm/fsl_guts.h> #include <sysdev/fsl_soc.h> #include <sysdev/fsl_pci.h> |