diff options
| author | Anoop P A <anoop.pa@gmail.com> | 2011-01-25 03:21:03 -0500 |
|---|---|---|
| committer | Ralf Baechle <ralf@linux-mips.org> | 2011-03-25 13:45:14 -0400 |
| commit | 088f3876fc9234feca0cdfdf710b8fafa87bfce1 (patch) | |
| tree | 0bacb9393936aab712dd5b41cb8821a0b00404f6 /arch/mips/pmc-sierra/msp71xx | |
| parent | 92592c9ccac9ab9c652533e08d0daad06f1dc501 (diff) | |
MIPS: MSP71xx: Add VSMP/SMTC support.
[Ralf: Fixed more checkpatch assertions and inclusion of unnecessary header
<linux/sched.h>.]
Signed-off-by: Anoop P A <anoop.pa@gmail.com>
To: linux-mips@linux-mips.org
To: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/2042/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/pmc-sierra/msp71xx')
| -rw-r--r-- | arch/mips/pmc-sierra/msp71xx/Makefile | 2 | ||||
| -rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_setup.c | 10 | ||||
| -rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_smp.c | 77 | ||||
| -rw-r--r-- | arch/mips/pmc-sierra/msp71xx/msp_smtc.c | 105 |
4 files changed, 194 insertions, 0 deletions
diff --git a/arch/mips/pmc-sierra/msp71xx/Makefile b/arch/mips/pmc-sierra/msp71xx/Makefile index b25f3542e6d1..a002fa222b25 100644 --- a/arch/mips/pmc-sierra/msp71xx/Makefile +++ b/arch/mips/pmc-sierra/msp71xx/Makefile | |||
| @@ -10,3 +10,5 @@ obj-$(CONFIG_IRQ_MSP_CIC) += msp_irq_cic.o msp_irq_per.o | |||
| 10 | obj-$(CONFIG_PCI) += msp_pci.o | 10 | obj-$(CONFIG_PCI) += msp_pci.o |
| 11 | obj-$(CONFIG_MSPETH) += msp_eth.o | 11 | obj-$(CONFIG_MSPETH) += msp_eth.o |
| 12 | obj-$(CONFIG_USB_MSP71XX) += msp_usb.o | 12 | obj-$(CONFIG_USB_MSP71XX) += msp_usb.o |
| 13 | obj-$(CONFIG_MIPS_MT_SMP) += msp_smp.o | ||
| 14 | obj-$(CONFIG_MIPS_MT_SMTC) += msp_smtc.o | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c index a54e85b3cf29..fb37a10e0309 100644 --- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c +++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c | |||
| @@ -146,6 +146,8 @@ void __init plat_mem_setup(void) | |||
| 146 | pm_power_off = msp_power_off; | 146 | pm_power_off = msp_power_off; |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | extern struct plat_smp_ops msp_smtc_smp_ops; | ||
| 150 | |||
| 149 | void __init prom_init(void) | 151 | void __init prom_init(void) |
| 150 | { | 152 | { |
| 151 | unsigned long family; | 153 | unsigned long family; |
| @@ -226,6 +228,14 @@ void __init prom_init(void) | |||
| 226 | */ | 228 | */ |
| 227 | msp_serial_setup(); | 229 | msp_serial_setup(); |
| 228 | 230 | ||
| 231 | #ifdef CONFIG_MIPS_MT_SMP | ||
| 232 | register_smp_ops(&vsmp_smp_ops); | ||
| 233 | #endif | ||
| 234 | |||
| 235 | #ifdef CONFIG_MIPS_MT_SMTC | ||
| 236 | register_smp_ops(&msp_smtc_smp_ops); | ||
| 237 | #endif | ||
| 238 | |||
| 229 | #ifdef CONFIG_PMCTWILED | 239 | #ifdef CONFIG_PMCTWILED |
| 230 | /* | 240 | /* |
| 231 | * Setup LED states before the subsys_initcall loads other | 241 | * Setup LED states before the subsys_initcall loads other |
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/arch/mips/pmc-sierra/msp71xx/msp_smp.c new file mode 100644 index 000000000000..43a9e26e1c69 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smp.c | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc. | ||
| 3 | * Copyright (C) 2001 Ralf Baechle | ||
| 4 | * Copyright (C) 2010 PMC-Sierra, Inc. | ||
| 5 | * | ||
| 6 | * VSMP support for MSP platforms . Derived from malta vsmp support. | ||
| 7 | * | ||
| 8 | * This program is free software; you can distribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License (Version 2) as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 15 | * for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License along | ||
| 18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 19 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | #include <linux/smp.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | |||
| 25 | #ifdef CONFIG_MIPS_MT_SMP | ||
| 26 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 /* SW int 0 for resched */ | ||
| 27 | #define MIPS_CPU_IPI_CALL_IRQ 1 /* SW int 1 for call */ | ||
| 28 | |||
| 29 | |||
| 30 | static void ipi_resched_dispatch(void) | ||
| 31 | { | ||
| 32 | do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ); | ||
| 33 | } | ||
| 34 | |||
| 35 | static void ipi_call_dispatch(void) | ||
| 36 | { | ||
| 37 | do_IRQ(MIPS_CPU_IPI_CALL_IRQ); | ||
| 38 | } | ||
| 39 | |||
| 40 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | ||
| 41 | { | ||
| 42 | return IRQ_HANDLED; | ||
| 43 | } | ||
| 44 | |||
| 45 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | ||
| 46 | { | ||
| 47 | smp_call_function_interrupt(); | ||
| 48 | |||
| 49 | return IRQ_HANDLED; | ||
| 50 | } | ||
| 51 | |||
| 52 | static struct irqaction irq_resched = { | ||
| 53 | .handler = ipi_resched_interrupt, | ||
| 54 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
| 55 | .name = "IPI_resched" | ||
| 56 | }; | ||
| 57 | |||
| 58 | static struct irqaction irq_call = { | ||
| 59 | .handler = ipi_call_interrupt, | ||
| 60 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
| 61 | .name = "IPI_call" | ||
| 62 | }; | ||
| 63 | |||
| 64 | void __init arch_init_ipiirq(int irq, struct irqaction *action) | ||
| 65 | { | ||
| 66 | setup_irq(irq, action); | ||
| 67 | set_irq_handler(irq, handle_percpu_irq); | ||
| 68 | } | ||
| 69 | |||
| 70 | void __init msp_vsmp_int_init(void) | ||
| 71 | { | ||
| 72 | set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); | ||
| 73 | set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); | ||
| 74 | arch_init_ipiirq(MIPS_CPU_IPI_RESCHED_IRQ, &irq_resched); | ||
| 75 | arch_init_ipiirq(MIPS_CPU_IPI_CALL_IRQ, &irq_call); | ||
| 76 | } | ||
| 77 | #endif /* CONFIG_MIPS_MT_SMP */ | ||
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smtc.c b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c new file mode 100644 index 000000000000..c8dcc1c01e18 --- /dev/null +++ b/arch/mips/pmc-sierra/msp71xx/msp_smtc.c | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* | ||
| 2 | * MSP71xx Platform-specific hooks for SMP operation | ||
| 3 | */ | ||
| 4 | #include <linux/irq.h> | ||
| 5 | #include <linux/init.h> | ||
| 6 | |||
| 7 | #include <asm/mipsmtregs.h> | ||
| 8 | #include <asm/mipsregs.h> | ||
| 9 | #include <asm/smtc.h> | ||
| 10 | #include <asm/smtc_ipi.h> | ||
| 11 | |||
| 12 | /* VPE/SMP Prototype implements platform interfaces directly */ | ||
| 13 | |||
| 14 | /* | ||
| 15 | * Cause the specified action to be performed on a targeted "CPU" | ||
| 16 | */ | ||
| 17 | |||
| 18 | static void msp_smtc_send_ipi_single(int cpu, unsigned int action) | ||
| 19 | { | ||
| 20 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | ||
| 21 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | ||
| 22 | } | ||
| 23 | |||
| 24 | static void msp_smtc_send_ipi_mask(const struct cpumask *mask, | ||
| 25 | unsigned int action) | ||
| 26 | { | ||
| 27 | unsigned int i; | ||
| 28 | |||
| 29 | for_each_cpu(i, mask) | ||
| 30 | msp_smtc_send_ipi_single(i, action); | ||
| 31 | } | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Post-config but pre-boot cleanup entry point | ||
| 35 | */ | ||
| 36 | static void __cpuinit msp_smtc_init_secondary(void) | ||
| 37 | { | ||
| 38 | int myvpe; | ||
| 39 | |||
| 40 | /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ | ||
| 41 | myvpe = read_c0_tcbind() & TCBIND_CURVPE; | ||
| 42 | if (myvpe > 0) | ||
| 43 | change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 | | ||
| 44 | STATUSF_IP6 | STATUSF_IP7); | ||
| 45 | smtc_init_secondary(); | ||
| 46 | } | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Platform "CPU" startup hook | ||
| 50 | */ | ||
| 51 | static void __cpuinit msp_smtc_boot_secondary(int cpu, | ||
| 52 | struct task_struct *idle) | ||
| 53 | { | ||
| 54 | smtc_boot_secondary(cpu, idle); | ||
| 55 | } | ||
| 56 | |||
| 57 | /* | ||
| 58 | * SMP initialization finalization entry point | ||
| 59 | */ | ||
| 60 | static void __cpuinit msp_smtc_smp_finish(void) | ||
| 61 | { | ||
| 62 | smtc_smp_finish(); | ||
| 63 | } | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Hook for after all CPUs are online | ||
| 67 | */ | ||
| 68 | |||
| 69 | static void msp_smtc_cpus_done(void) | ||
| 70 | { | ||
| 71 | } | ||
| 72 | |||
| 73 | /* | ||
| 74 | * Platform SMP pre-initialization | ||
| 75 | * | ||
| 76 | * As noted above, we can assume a single CPU for now | ||
| 77 | * but it may be multithreaded. | ||
| 78 | */ | ||
| 79 | |||
| 80 | static void __init msp_smtc_smp_setup(void) | ||
| 81 | { | ||
| 82 | /* | ||
| 83 | * we won't get the definitive value until | ||
| 84 | * we've run smtc_prepare_cpus later, but | ||
| 85 | */ | ||
| 86 | |||
| 87 | if (read_c0_config3() & (1 << 2)) | ||
| 88 | smp_num_siblings = smtc_build_cpu_map(0); | ||
| 89 | } | ||
| 90 | |||
| 91 | static void __init msp_smtc_prepare_cpus(unsigned int max_cpus) | ||
| 92 | { | ||
| 93 | smtc_prepare_cpus(max_cpus); | ||
| 94 | } | ||
| 95 | |||
| 96 | struct plat_smp_ops msp_smtc_smp_ops = { | ||
| 97 | .send_ipi_single = msp_smtc_send_ipi_single, | ||
| 98 | .send_ipi_mask = msp_smtc_send_ipi_mask, | ||
| 99 | .init_secondary = msp_smtc_init_secondary, | ||
| 100 | .smp_finish = msp_smtc_smp_finish, | ||
| 101 | .cpus_done = msp_smtc_cpus_done, | ||
| 102 | .boot_secondary = msp_smtc_boot_secondary, | ||
| 103 | .smp_setup = msp_smtc_smp_setup, | ||
| 104 | .prepare_cpus = msp_smtc_prepare_cpus, | ||
| 105 | }; | ||
