aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/rtl838x/files-5.4/arch/mips/include/asm/mach-rtl838x/mach-rtl838x.h10
-rw-r--r--target/linux/rtl838x/files-5.4/arch/mips/rtl838x/irq.c222
2 files changed, 90 insertions, 142 deletions
diff --git a/target/linux/rtl838x/files-5.4/arch/mips/include/asm/mach-rtl838x/mach-rtl838x.h b/target/linux/rtl838x/files-5.4/arch/mips/include/asm/mach-rtl838x/mach-rtl838x.h
index cece36635c..4050661d33 100644
--- a/target/linux/rtl838x/files-5.4/arch/mips/include/asm/mach-rtl838x/mach-rtl838x.h
+++ b/target/linux/rtl838x/files-5.4/arch/mips/include/asm/mach-rtl838x/mach-rtl838x.h
@@ -16,11 +16,13 @@
#define rtl838x_w32(val, reg) __raw_writel(val, reg)
#define rtl838x_w32_mask(clear, set, reg) rtl838x_w32((rtl838x_r32(reg) & ~(clear)) | (set), reg)
+#define rtl838x_r8(reg) __raw_readb(reg)
+#define rtl838x_w8(val, reg) __raw_writeb(val, reg)
+
#define sw_r32(reg) __raw_readl(RTL838X_SW_BASE + reg)
#define sw_w32(val, reg) __raw_writel(val, RTL838X_SW_BASE + reg)
#define sw_w32_mask(clear, set, reg) \
sw_w32((sw_r32(reg) & ~(clear)) | (set), reg)
-
#define sw_r64(reg) ((((u64)__raw_readl(RTL838X_SW_BASE + reg)) << 32) | \
__raw_readl(RTL838X_SW_BASE + reg + 4))
@@ -102,11 +104,15 @@
#define IRR1 (0x0c)
-#define IRR1_SETTING ((GPIO_ABCD_RS << 28) | \
+#define IRR1_SETTING_RTL838X ((GPIO_ABCD_RS << 28) | \
(GPIO_EFGH_RS << 24) | \
(RTC_RS << 20) | \
(SWCORE_RS << 16) \
)
+#define IRR1_SETTING_RTL839X ((GPIO_ABCD_RS << 28) | \
+ (SWCORE_RS << 16) \
+ )
+
#define IRR2 (0x10)
#define IRR2_SETTING 0
diff --git a/target/linux/rtl838x/files-5.4/arch/mips/rtl838x/irq.c b/target/linux/rtl838x/files-5.4/arch/mips/rtl838x/irq.c
index 34e90982b2..0c3a311d1d 100644
--- a/target/linux/rtl838x/files-5.4/arch/mips/rtl838x/irq.c
+++ b/target/linux/rtl838x/files-5.4/arch/mips/rtl838x/irq.c
@@ -29,36 +29,7 @@ extern struct rtl838x_soc_info soc_info;
static DEFINE_RAW_SPINLOCK(irq_lock);
extern irqreturn_t c0_compare_interrupt(int irq, void *dev_id);
-unsigned int rtl838x_ictl_irq_dispatch1(void);
-unsigned int rtl838x_ictl_irq_dispatch2(void);
-unsigned int rtl838x_ictl_irq_dispatch3(void);
-unsigned int rtl838x_ictl_irq_dispatch4(void);
-unsigned int rtl838x_ictl_irq_dispatch5(void);
-
-static struct irqaction irq_cascade1 = {
- .handler = no_action,
- .name = "RTL838X IRQ cascade1",
-};
-
-static struct irqaction irq_cascade2 = {
- .handler = no_action,
- .name = "RTL838X IRQ cascade2",
-};
-
-static struct irqaction irq_cascade3 = {
- .handler = no_action,
- .name = "RTL838X IRQ cascade3",
-};
-
-static struct irqaction irq_cascade4 = {
- .handler = no_action,
- .name = "RTL838X IRQ cascade4",
-};
-static struct irqaction irq_cascade5 = {
- .handler = no_action,
- .name = "RTL838X IRQ cascade5",
-};
static void rtl838x_ictl_enable_irq(struct irq_data *i)
{
@@ -69,12 +40,6 @@ static void rtl838x_ictl_enable_irq(struct irq_data *i)
raw_spin_unlock_irqrestore(&irq_lock, flags);
}
-static unsigned int rtl838x_ictl_startup_irq(struct irq_data *i)
-{
- rtl838x_ictl_enable_irq(i);
- return 0;
-}
-
static void rtl838x_ictl_disable_irq(struct irq_data *i)
{
unsigned long flags;
@@ -94,9 +59,7 @@ static void rtl838x_ictl_eoi_irq(struct irq_data *i)
}
static struct irq_chip rtl838x_ictl_irq = {
- .name = "RTL838X",
- .irq_startup = rtl838x_ictl_startup_irq,
- .irq_shutdown = rtl838x_ictl_disable_irq,
+ .name = "RTL83xx",
.irq_enable = rtl838x_ictl_enable_irq,
.irq_disable = rtl838x_ictl_disable_irq,
.irq_ack = rtl838x_ictl_disable_irq,
@@ -106,113 +69,57 @@ static struct irq_chip rtl838x_ictl_irq = {
};
/*
- * RTL8390/80/28 Interrupt Scheme
+ * RTL8390/80/28 Interrupt Scheme
*
- * Source IRQ CPU INT
- * -------- ------- -------
- * UART0 31 IP3
- * UART1 30 IP2
- * TIMER0 29 IP6
- * TIMER1 28 IP2
- * OCPTO 27 IP2
- * HLXTO 26 IP2
- * SLXTO 25 IP2
- * NIC 24 IP5
- * GPIO_ABCD 23 IP5
- * SWCORE 20 IP4
+ * Source IRQ CPU INT
+ * -------- ------- -------
+ * UART0 31 IP3
+ * UART1 30 IP2
+ * TIMER0 29 IP6
+ * TIMER1 28 IP2
+ * OCPTO 27 IP2
+ * HLXTO 26 IP2
+ * SLXTO 25 IP2
+ * NIC 24 IP5
+ * GPIO_ABCD 23 IP5
+ * SWCORE 20 IP4
*/
-unsigned int rtl838x_ictl_irq_dispatch1(void)
-{
- /* Identify shared IRQ */
- unsigned int extint_ip = icu_r32(GIMR) & icu_r32(GISR);
-
- if (extint_ip & TC1_IP)
- do_IRQ(TC1_IRQ);
- else if (extint_ip & UART1_IP)
- do_IRQ(UART1_IRQ);
- else
- spurious_interrupt();
-
- return IRQ_HANDLED;
-}
-
-unsigned int rtl838x_ictl_irq_dispatch2(void)
-{
- do_IRQ(UART0_IRQ);
- return IRQ_HANDLED;
-}
-
-unsigned int rtl838x_ictl_irq_dispatch3(void)
-{
- do_IRQ(SWCORE_IRQ);
- return IRQ_HANDLED;
-}
-
-unsigned int rtl838x_ictl_irq_dispatch4(void)
-{
- /* Identify shared IRQ */
- unsigned int extint_ip = icu_r32(GIMR) & icu_r32(GISR);
-
- if (extint_ip & NIC_IP)
- do_IRQ(NIC_IRQ);
- else if (extint_ip & GPIO_ABCD_IP)
- do_IRQ(GPIO_ABCD_IRQ);
- else if ((extint_ip & GPIO_EFGH_IP) && (soc_info.family == RTL8328_FAMILY_ID))
- do_IRQ(GPIO_EFGH_IRQ);
- else
- spurious_interrupt();
-
- return IRQ_HANDLED;
-}
-
-unsigned int rtl838x_ictl_irq_dispatch5(void)
-{
- do_IRQ(TC0_IRQ);
- return IRQ_HANDLED;
-}
-
asmlinkage void plat_irq_dispatch(void)
{
- unsigned int pending;
+ unsigned int pending, ext_int;
- pending = read_c0_cause() & read_c0_status() & ST0_IM;
+ pending = read_c0_cause();
- if (pending & CAUSEF_IP7)
+ if (pending & CAUSEF_IP7) {
c0_compare_interrupt(7, NULL);
- else if (pending & CAUSEF_IP6)
- rtl838x_ictl_irq_dispatch5();
- else if (pending & CAUSEF_IP5)
- rtl838x_ictl_irq_dispatch4();
- else if (pending & CAUSEF_IP4)
- rtl838x_ictl_irq_dispatch3();
- else if (pending & CAUSEF_IP3)
- rtl838x_ictl_irq_dispatch2();
- else if (pending & CAUSEF_IP2)
- rtl838x_ictl_irq_dispatch1();
- else
+ } else if (pending & CAUSEF_IP6) {
+ do_IRQ(TC0_IRQ);
+ } else if (pending & CAUSEF_IP5) {
+ ext_int = icu_r32(GIMR) & icu_r32(GISR);
+ if (ext_int & NIC_IP)
+ do_IRQ(NIC_IRQ);
+ else if (ext_int & GPIO_ABCD_IP)
+ do_IRQ(GPIO_ABCD_IRQ);
+ else if ((ext_int & GPIO_EFGH_IP) && (soc_info.family == RTL8328_FAMILY_ID))
+ do_IRQ(GPIO_EFGH_IRQ);
+ else
+ spurious_interrupt();
+ } else if (pending & CAUSEF_IP4) {
+ do_IRQ(SWCORE_IRQ);
+ } else if (pending & CAUSEF_IP3) {
+ do_IRQ(UART0_IRQ);
+ } else if (pending & CAUSEF_IP2) {
+ ext_int = icu_r32(GIMR) & icu_r32(GISR);
+ if (ext_int & TC1_IP)
+ do_IRQ(TC1_IRQ);
+ else if (ext_int & UART1_IP)
+ do_IRQ(UART1_IRQ);
+ else
+ spurious_interrupt();
+ } else {
spurious_interrupt();
-}
-
-static void __init rtl838x_ictl_irq_init(unsigned int irq_base)
-{
- int i;
-
- for (i = 0; i < RTL838X_IRQ_ICTL_NUM; i++)
- irq_set_chip_and_handler(irq_base + i, &rtl838x_ictl_irq, handle_level_irq);
-
- setup_irq(RTL838X_ICTL1_IRQ, &irq_cascade1);
- setup_irq(RTL838X_ICTL2_IRQ, &irq_cascade2);
- setup_irq(RTL838X_ICTL3_IRQ, &irq_cascade3);
- setup_irq(RTL838X_ICTL4_IRQ, &irq_cascade4);
- setup_irq(RTL838X_ICTL5_IRQ, &irq_cascade5);
-
- /* Set GIMR, IRR */
- icu_w32(TC0_IE | UART0_IE, GIMR);
- icu_w32(IRR0_SETTING, IRR0);
- icu_w32(IRR1_SETTING, IRR1);
- icu_w32(IRR2_SETTING, IRR2);
- icu_w32(IRR3_SETTING, IRR3);
+ }
}
static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
@@ -234,11 +141,12 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
struct resource res;
pr_info("Found Interrupt controller: %s (%s)\n", node->name, node->full_name);
- if (of_address_to_resource(node, 0, &res)) {
+ if (of_address_to_resource(node, 0, &res))
panic("Failed to get icu memory range");
- }
+
if (!request_mem_region(res.start, resource_size(&res), res.name))
pr_err("Failed to request icu memory\n");
+
soc_info.icu_base = ioremap(res.start, resource_size(&res));
pr_info("ICU Memory: %08x\n", (u32)soc_info.icu_base);
@@ -247,10 +155,44 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
domain = irq_domain_add_simple(node, 32, 0, &irq_domain_ops, NULL);
/* Setup all external HW irqs */
- for (i = 8; i < 32; i++)
+ for (i = 8; i < RTL838X_IRQ_ICTL_NUM; i++) {
irq_domain_associate(domain, i, i);
+ irq_set_chip_and_handler(RTL838X_IRQ_ICTL_BASE + i,
+ &rtl838x_ictl_irq, handle_level_irq);
+ }
- rtl838x_ictl_irq_init(RTL838X_IRQ_ICTL_BASE);
+ if (request_irq(RTL838X_ICTL1_IRQ, no_action, IRQF_NO_THREAD,
+ "IRQ cascade 1", NULL)) {
+ pr_err("request_irq() cascade 1 for irq %d failed\n", RTL838X_ICTL1_IRQ);
+ }
+ if (request_irq(RTL838X_ICTL2_IRQ, no_action, IRQF_NO_THREAD,
+ "IRQ cascade 2", NULL)) {
+ pr_err("request_irq() cascade 2 for irq %d failed\n", RTL838X_ICTL2_IRQ);
+ }
+ if (request_irq(RTL838X_ICTL3_IRQ, no_action, IRQF_NO_THREAD,
+ "IRQ cascade 3", NULL)) {
+ pr_err("request_irq() cascade 3 for irq %d failed\n", RTL838X_ICTL3_IRQ);
+ }
+ if (request_irq(RTL838X_ICTL4_IRQ, no_action, IRQF_NO_THREAD,
+ "IRQ cascade 4", NULL)) {
+ pr_err("request_irq() cascade 4 for irq %d failed\n", RTL838X_ICTL4_IRQ);
+ }
+ if (request_irq(RTL838X_ICTL5_IRQ, no_action, IRQF_NO_THREAD,
+ "IRQ cascade 5", NULL)) {
+ pr_err("request_irq() cascade 5 for irq %d failed\n", RTL838X_ICTL5_IRQ);
+ }
+
+ /* Set up interrupt routing scheme */
+ icu_w32(IRR0_SETTING, IRR0);
+ if (soc_info.family == RTL8380_FAMILY_ID)
+ icu_w32(IRR1_SETTING_RTL838X, IRR1);
+ else
+ icu_w32(IRR1_SETTING_RTL839X, IRR1);
+ icu_w32(IRR2_SETTING, IRR2);
+ icu_w32(IRR3_SETTING, IRR3);
+
+ /* Enable timer0 and uart0 interrupts */
+ icu_w32(TC0_IE | UART0_IE, GIMR);
return 0;
}