ARCv2: intc: untangle SMP, MCIP and IDU

The IDU intc is technically part of MCIP (Multi-core IP) hence
historically was only available in a SMP hardware build (and thus only
in a SMP kernel build). Now that hardware restriction has been lifted,
so a UP kernel needs to support it.

This requires breaking mcip.c into parts which are strictly SMP
(inter-core interrupts) and IDU which in reality is just another
intc and thus has no bearing on SMP.

This change allows IDU in UP builds and with a suitable device tree, we
can have the cascaded intc system

    ARCv2 core intc <---> ARCv2 IDU intc <---> periperals

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
Vineet Gupta 2016-09-29 10:00:14 -07:00
parent 1001354ca3
commit 3ce0fefc51
3 changed files with 36 additions and 28 deletions

View File

@ -186,14 +186,6 @@ if SMP
config ARC_HAS_COH_CACHES config ARC_HAS_COH_CACHES
def_bool n def_bool n
config ARC_MCIP
bool "ARConnect Multicore IP (MCIP) Support "
depends on ISA_ARCV2
help
This IP block enables SMP in ARC-HS38 cores.
It provides for cross-core interrupts, multi-core debug
hardware semaphores, shared memory,....
config NR_CPUS config NR_CPUS
int "Maximum number of CPUs (2-4096)" int "Maximum number of CPUs (2-4096)"
range 2 4096 range 2 4096
@ -211,6 +203,15 @@ config ARC_SMP_HALT_ON_RESET
endif #SMP endif #SMP
config ARC_MCIP
bool "ARConnect Multicore IP (MCIP) Support "
depends on ISA_ARCV2
default y if SMP
help
This IP block enables SMP in ARC-HS38 cores.
It provides for cross-core interrupts, multi-core debug
hardware semaphores, shared memory,....
menuconfig ARC_CACHE menuconfig ARC_CACHE
bool "Enable Cache Support" bool "Enable Cache Support"
default y default y

View File

@ -55,6 +55,22 @@ struct mcip_cmd {
#define IDU_M_DISTRI_DEST 0x2 #define IDU_M_DISTRI_DEST 0x2
}; };
struct mcip_bcr {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad3:8,
idu:1, llm:1, num_cores:6,
iocoh:1, gfrc:1, dbg:1, pad2:1,
msg:1, sem:1, ipi:1, pad:1,
ver:8;
#else
unsigned int ver:8,
pad:1, ipi:1, sem:1, msg:1,
pad2:1, dbg:1, gfrc:1, iocoh:1,
num_cores:6, llm:1, idu:1,
pad3:8;
#endif
};
/* /*
* MCIP programming model * MCIP programming model
* *

View File

@ -15,11 +15,12 @@
#include <asm/mcip.h> #include <asm/mcip.h>
#include <asm/setup.h> #include <asm/setup.h>
static char smp_cpuinfo_buf[128];
static int idu_detected;
static DEFINE_RAW_SPINLOCK(mcip_lock); static DEFINE_RAW_SPINLOCK(mcip_lock);
#ifdef CONFIG_SMP
static char smp_cpuinfo_buf[128];
static void mcip_setup_per_cpu(int cpu) static void mcip_setup_per_cpu(int cpu)
{ {
smp_ipi_irq_setup(cpu, IPI_IRQ); smp_ipi_irq_setup(cpu, IPI_IRQ);
@ -86,21 +87,7 @@ static void mcip_ipi_clear(int irq)
static void mcip_probe_n_setup(void) static void mcip_probe_n_setup(void)
{ {
struct mcip_bcr { struct mcip_bcr mp;
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad3:8,
idu:1, llm:1, num_cores:6,
iocoh:1, gfrc:1, dbg:1, pad2:1,
msg:1, sem:1, ipi:1, pad:1,
ver:8;
#else
unsigned int ver:8,
pad:1, ipi:1, sem:1, msg:1,
pad2:1, dbg:1, gfrc:1, iocoh:1,
num_cores:6, llm:1, idu:1,
pad3:8;
#endif
} mp;
READ_BCR(ARC_REG_MCIP_BCR, mp); READ_BCR(ARC_REG_MCIP_BCR, mp);
@ -114,7 +101,6 @@ static void mcip_probe_n_setup(void)
IS_AVAIL1(mp.gfrc, "GFRC")); IS_AVAIL1(mp.gfrc, "GFRC"));
cpuinfo_arc700[0].extn.gfrc = mp.gfrc; cpuinfo_arc700[0].extn.gfrc = mp.gfrc;
idu_detected = mp.idu;
if (mp.dbg) { if (mp.dbg) {
__mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf); __mcip_cmd_data(CMD_DEBUG_SET_SELECT, 0, 0xf);
@ -130,6 +116,8 @@ struct plat_smp_ops plat_smp_ops = {
.ipi_clear = mcip_ipi_clear, .ipi_clear = mcip_ipi_clear,
}; };
#endif
/*************************************************************************** /***************************************************************************
* ARCv2 Interrupt Distribution Unit (IDU) * ARCv2 Interrupt Distribution Unit (IDU)
* *
@ -295,8 +283,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
/* Read IDU BCR to confirm nr_irqs */ /* Read IDU BCR to confirm nr_irqs */
int nr_irqs = of_irq_count(intc); int nr_irqs = of_irq_count(intc);
int i, irq; int i, irq;
struct mcip_bcr mp;
if (!idu_detected) READ_BCR(ARC_REG_MCIP_BCR, mp);
if (!mp.idu)
panic("IDU not detected, but DeviceTree using it"); panic("IDU not detected, but DeviceTree using it");
pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs); pr_info("MCIP: IDU referenced from Devicetree %d irqs\n", nr_irqs);