diff options
Diffstat (limited to 'arch/arc/plat-arcfpga/smp.c')
-rw-r--r-- | arch/arc/plat-arcfpga/smp.c | 186 |
1 files changed, 0 insertions, 186 deletions
diff --git a/arch/arc/plat-arcfpga/smp.c b/arch/arc/plat-arcfpga/smp.c deleted file mode 100644 index 64797ba3bbe3..000000000000 --- a/arch/arc/plat-arcfpga/smp.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * ARC700 Simulation-only Extensions for SMP - * - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Vineet Gupta - 2012 : split off arch common and plat specific SMP - * Rajeshwar Ranga - 2007 : Interrupt Distribution Unit API's - */ - -#include <linux/smp.h> -#include <linux/irq.h> -#include <plat/smp.h> - -#define IDU_INTERRUPT_0 16 - -static char smp_cpuinfo_buf[128]; - -/* - *------------------------------------------------------------------- - * Platform specific callbacks expected by arch SMP code - *------------------------------------------------------------------- - */ - -/* - * Master kick starting another CPU - */ -static void iss_model_smp_wakeup_cpu(int cpu, unsigned long pc) -{ - /* setup the start PC */ - write_aux_reg(ARC_AUX_XTL_REG_PARAM, pc); - - /* Trigger WRITE_PC cmd for this cpu */ - write_aux_reg(ARC_AUX_XTL_REG_CMD, - (ARC_XTL_CMD_WRITE_PC | (cpu << 8))); - - /* Take the cpu out of Halt */ - write_aux_reg(ARC_AUX_XTL_REG_CMD, - (ARC_XTL_CMD_CLEAR_HALT | (cpu << 8))); - -} - -static inline int get_hw_config_num_irq(void) -{ - uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR); - - switch (val & 0x03) { - case 0: - return 16; - case 1: - return 32; - case 2: - return 8; - default: - return 0; - } - - return 0; -} - -/* - * Any SMP specific init any CPU does when it comes up. - * Here we setup the CPU to enable Inter-Processor-Interrupts - * Called for each CPU - * -Master : init_IRQ() - * -Other(s) : start_kernel_secondary() - */ -void iss_model_init_smp(unsigned int cpu) -{ - /* Check if CPU is configured for more than 16 interrupts */ - if (NR_IRQS <= 16 || get_hw_config_num_irq() <= 16) - panic("[arcfpga] IRQ system can't support IDU IPI\n"); - - idu_disable(); - - /**************************************************************** - * IDU provides a set of Common IRQs, each of which can be dynamically - * attached to (1|many|all) CPUs. - * The Common IRQs [0-15] are mapped as CPU pvt [16-31] - * - * Here we use a simple 1:1 mapping: - * A CPU 'x' is wired to Common IRQ 'x'. - * So an IDU ASSERT on IRQ 'x' will trigger Interupt on CPU 'x', which - * makes up for our simple IPI plumbing. - * - * TBD: Have a dedicated multicast IRQ for sending IPIs to all CPUs - * w/o having to do one-at-a-time - ******************************************************************/ - - /* - * Claim an IRQ which would trigger IPI on this CPU. - * In IDU parlance it involves setting up a cpu bitmask for the IRQ - * The bitmap here contains only 1 CPU (self). - */ - idu_irq_set_tgtcpu(cpu, 0x1 << cpu); - - /* Set the IRQ destination to use the bitmask above */ - idu_irq_set_mode(cpu, 7, /* XXX: IDU_IRQ_MOD_TCPU_ALLRECP: ISS bug */ - IDU_IRQ_MODE_PULSE_TRIG); - - idu_enable(); - - /* Attach the arch-common IPI ISR to our IDU IRQ */ - smp_ipi_irq_setup(cpu, IDU_INTERRUPT_0 + cpu); -} - -static void iss_model_ipi_send(int cpu) -{ - idu_irq_assert(cpu); -} - -static void iss_model_ipi_clear(int irq) -{ - idu_irq_clear(IDU_INTERRUPT_0 + smp_processor_id()); -} - -void iss_model_init_early_smp(void) -{ -#define IS_AVAIL1(var, str) ((var) ? str : "") - - struct bcr_mp mp; - - READ_BCR(ARC_REG_MP_BCR, mp); - - sprintf(smp_cpuinfo_buf, "Extn [ISS-SMP]: v%d, arch(%d) %s %s %s\n", - mp.ver, mp.mp_arch, IS_AVAIL1(mp.scu, "SCU"), - IS_AVAIL1(mp.idu, "IDU"), IS_AVAIL1(mp.sdu, "SDU")); - - plat_smp_ops.info = smp_cpuinfo_buf; - - plat_smp_ops.cpu_kick = iss_model_smp_wakeup_cpu; - plat_smp_ops.ipi_send = iss_model_ipi_send; - plat_smp_ops.ipi_clear = iss_model_ipi_clear; -} - -/* - *------------------------------------------------------------------- - * Low level Platform IPI Providers - *------------------------------------------------------------------- - */ - -/* Set the Mode for the Common IRQ */ -void idu_irq_set_mode(uint8_t irq, uint8_t dest_mode, uint8_t trig_mode) -{ - uint32_t par = IDU_IRQ_MODE_PARAM(dest_mode, trig_mode); - - IDU_SET_PARAM(par); - IDU_SET_COMMAND(irq, IDU_IRQ_WMODE); -} - -/* Set the target cpu Bitmask for Common IRQ */ -void idu_irq_set_tgtcpu(uint8_t irq, uint32_t mask) -{ - IDU_SET_PARAM(mask); - IDU_SET_COMMAND(irq, IDU_IRQ_WBITMASK); -} - -/* Get the Interrupt Acknowledged status for IRQ (as CPU Bitmask) */ -bool idu_irq_get_ack(uint8_t irq) -{ - uint32_t val; - - IDU_SET_COMMAND(irq, IDU_IRQ_ACK); - val = IDU_GET_PARAM(); - - return val & (1 << irq); -} - -/* - * Get the Interrupt Pending status for IRQ (as CPU Bitmask) - * -Pending means CPU has not yet noticed the IRQ (e.g. disabled) - * -After Interrupt has been taken, the IPI expcitily needs to be - * cleared, to be acknowledged. - */ -bool idu_irq_get_pend(uint8_t irq) -{ - uint32_t val; - - IDU_SET_COMMAND(irq, IDU_IRQ_PEND); - val = IDU_GET_PARAM(); - - return val & (1 << irq); -} |