-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MIPS: Loongson 3: Add IRQ init and dispatch support
IRQ routing path of Loongson-3: Devices(most) --> I8259 --> HT Controller --> IRQ Routing Table --> CPU ^ | Device(legacy devices such as UART) --> Bonito ---| IRQ Routing Table route 32 INTs to CPU's INT0~INT3(IP2~IP5 of CP0), 32 INTs include 16 HT INTs(mostly), 4 PCI INTs, 1 LPC INT, etc. IP6 is used for IPI and IP7 is used for internal MIPS timer. LOONGSON_INT_ROUTER_* are IRQ Routing Table registers. I8259 IRQs are 1:1 mapped to HT1 INTs. LOONGSON_HT1_* are configuration registers of HT1 controller. Signed-off-by: Huacai Chen <chenhc@lemote.com> Signed-off-by: Hongliang Tao <taohl@lemote.com> Signed-off-by: Hua Yan <yanh@lemote.com> Tested-by: Alex Smith <alex.smith@imgtec.com> Reviewed-by: Alex Smith <alex.smith@imgtec.com> Cc: John Crispin <john@phrozen.org> Cc: Steven J. Hill <Steven.Hill@imgtec.com> Cc: Aurelien Jarno <aurelien@aurel32.net> Cc: linux-mips@linux-mips.org Cc: Fuxin Zhang <zhangfx@lemote.com> Cc: Zhangjin Wu <wuzhangjin@gmail.com> Patchwork: https://patchwork.linux-mips.org/patch/6634 Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
- Loading branch information
Huacai Chen
authored and
Ralf Baechle
committed
Mar 31, 2014
1 parent
c7d3555
commit d788bfa
Showing
5 changed files
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef __ASM_MACH_LOONGSON_IRQ_H_ | ||
#define __ASM_MACH_LOONGSON_IRQ_H_ | ||
|
||
#include <boot_param.h> | ||
|
||
#ifdef CONFIG_CPU_LOONGSON3 | ||
|
||
/* cpu core interrupt numbers */ | ||
#define MIPS_CPU_IRQ_BASE 56 | ||
|
||
#define LOONGSON_UART_IRQ (MIPS_CPU_IRQ_BASE + 2) /* UART */ | ||
#define LOONGSON_HT1_IRQ (MIPS_CPU_IRQ_BASE + 3) /* HT1 */ | ||
#define LOONGSON_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */ | ||
|
||
#define LOONGSON_HT1_CFG_BASE loongson_sysconf.ht_control_base | ||
#define LOONGSON_HT1_INT_VECTOR_BASE (LOONGSON_HT1_CFG_BASE + 0x80) | ||
#define LOONGSON_HT1_INT_EN_BASE (LOONGSON_HT1_CFG_BASE + 0xa0) | ||
#define LOONGSON_HT1_INT_VECTOR(n) \ | ||
LOONGSON3_REG32(LOONGSON_HT1_INT_VECTOR_BASE, 4 * (n)) | ||
#define LOONGSON_HT1_INTN_EN(n) \ | ||
LOONGSON3_REG32(LOONGSON_HT1_INT_EN_BASE, 4 * (n)) | ||
|
||
#define LOONGSON_INT_ROUTER_OFFSET 0x1400 | ||
#define LOONGSON_INT_ROUTER_INTEN \ | ||
LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x24) | ||
#define LOONGSON_INT_ROUTER_INTENSET \ | ||
LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x28) | ||
#define LOONGSON_INT_ROUTER_INTENCLR \ | ||
LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x2c) | ||
#define LOONGSON_INT_ROUTER_ENTRY(n) \ | ||
LOONGSON3_REG8(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + n) | ||
#define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) | ||
#define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) | ||
|
||
#define LOONGSON_INT_CORE0_INT0 0x11 /* route to int 0 of core 0 */ | ||
#define LOONGSON_INT_CORE0_INT1 0x21 /* route to int 1 of core 0 */ | ||
|
||
#endif | ||
|
||
#include_next <irq.h> | ||
#endif /* __ASM_MACH_LOONGSON_IRQ_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# | ||
# Makefile for Loongson-3 family machines | ||
# | ||
obj-y += irq.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#include <loongson.h> | ||
#include <irq.h> | ||
#include <linux/interrupt.h> | ||
#include <linux/module.h> | ||
|
||
#include <asm/irq_cpu.h> | ||
#include <asm/i8259.h> | ||
#include <asm/mipsregs.h> | ||
|
||
unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; | ||
|
||
static void ht_irqdispatch(void) | ||
{ | ||
unsigned int i, irq; | ||
|
||
irq = LOONGSON_HT1_INT_VECTOR(0); | ||
LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */ | ||
|
||
for (i = 0; i < ARRAY_SIZE(ht_irq); i++) { | ||
if (irq & (0x1 << ht_irq[i])) | ||
do_IRQ(ht_irq[i]); | ||
} | ||
} | ||
|
||
void mach_irq_dispatch(unsigned int pending) | ||
{ | ||
if (pending & CAUSEF_IP7) | ||
do_IRQ(LOONGSON_TIMER_IRQ); | ||
else if (pending & CAUSEF_IP3) | ||
ht_irqdispatch(); | ||
else if (pending & CAUSEF_IP2) | ||
do_IRQ(LOONGSON_UART_IRQ); | ||
else { | ||
pr_err("%s : spurious interrupt\n", __func__); | ||
spurious_interrupt(); | ||
} | ||
} | ||
|
||
static struct irqaction cascade_irqaction = { | ||
.handler = no_action, | ||
.name = "cascade", | ||
}; | ||
|
||
static inline void mask_loongson_irq(struct irq_data *d) | ||
{ | ||
clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); | ||
irq_disable_hazard(); | ||
} | ||
|
||
static inline void unmask_loongson_irq(struct irq_data *d) | ||
{ | ||
set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); | ||
irq_enable_hazard(); | ||
} | ||
|
||
/* For MIPS IRQs which shared by all cores */ | ||
static struct irq_chip loongson_irq_chip = { | ||
.name = "Loongson", | ||
.irq_ack = mask_loongson_irq, | ||
.irq_mask = mask_loongson_irq, | ||
.irq_mask_ack = mask_loongson_irq, | ||
.irq_unmask = unmask_loongson_irq, | ||
.irq_eoi = unmask_loongson_irq, | ||
}; | ||
|
||
void irq_router_init(void) | ||
{ | ||
int i; | ||
|
||
/* route LPC int to cpu core0 int 0 */ | ||
LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0; | ||
/* route HT1 int0 ~ int7 to cpu core0 INT1*/ | ||
for (i = 0; i < 8; i++) | ||
LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1; | ||
/* enable HT1 interrupt */ | ||
LOONGSON_HT1_INTN_EN(0) = 0xffffffff; | ||
/* enable router interrupt intenset */ | ||
LOONGSON_INT_ROUTER_INTENSET = | ||
LOONGSON_INT_ROUTER_INTEN | (0xffff << 16) | 0x1 << 10; | ||
} | ||
|
||
void __init mach_init_irq(void) | ||
{ | ||
clear_c0_status(ST0_IM | ST0_BEV); | ||
|
||
irq_router_init(); | ||
mips_cpu_irq_init(); | ||
init_i8259_irqs(); | ||
irq_set_chip_and_handler(LOONGSON_UART_IRQ, | ||
&loongson_irq_chip, handle_level_irq); | ||
|
||
/* setup HT1 irq */ | ||
setup_irq(LOONGSON_HT1_IRQ, &cascade_irqaction); | ||
|
||
set_c0_status(STATUSF_IP2 | STATUSF_IP6); | ||
} |