diff options
Diffstat (limited to 'arch/mips/loongson/loongson-3/irq.c')
-rw-r--r-- | arch/mips/loongson/loongson-3/irq.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c index f240828181ff..0f75b6b3d218 100644 --- a/arch/mips/loongson/loongson-3/irq.c +++ b/arch/mips/loongson/loongson-3/irq.c @@ -7,7 +7,9 @@ #include <asm/i8259.h> #include <asm/mipsregs.h> -unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; +#include "smp.h" + +unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; static void ht_irqdispatch(void) { @@ -42,6 +44,7 @@ void mach_irq_dispatch(unsigned int pending) static struct irqaction cascade_irqaction = { .handler = no_action, + .flags = IRQF_NO_SUSPEND, .name = "cascade", }; @@ -53,9 +56,15 @@ static inline void mask_loongson_irq(struct irq_data *d) /* Workaround: UART IRQ may deliver to any core */ if (d->irq == LOONGSON_UART_IRQ) { int cpu = smp_processor_id(); - - LOONGSON_INT_ROUTER_INTENCLR = 1 << 10; - LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu); + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; + u64 intenclr_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_INTENCLR); + u64 introuter_lpc_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_LPC); + + *(volatile u32 *)intenclr_addr = 1 << 10; + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id); } } @@ -64,9 +73,15 @@ static inline void unmask_loongson_irq(struct irq_data *d) /* Workaround: UART IRQ may deliver to any core */ if (d->irq == LOONGSON_UART_IRQ) { int cpu = smp_processor_id(); - - LOONGSON_INT_ROUTER_INTENSET = 1 << 10; - LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu); + int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; + int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; + u64 intenset_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_INTENSET); + u64 introuter_lpc_addr = smp_group[node_id] | + (u64)(&LOONGSON_INT_ROUTER_LPC); + + *(volatile u32 *)intenset_addr = 1 << 10; + *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id); } set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); @@ -88,10 +103,12 @@ void irq_router_init(void) int i; /* route LPC int to cpu core0 int 0 */ - LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0; + LOONGSON_INT_ROUTER_LPC = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); /* route HT1 int0 ~ int7 to cpu core0 INT1*/ for (i = 0; i < 8; i++) - LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1; + LOONGSON_INT_ROUTER_HT1(i) = + LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); /* enable HT1 interrupt */ LOONGSON_HT1_INTN_EN(0) = 0xffffffff; /* enable router interrupt intenset */ |