[openwrt/openwrt] rtl838x: Add irq settings for RTL839x SoCs

LEDE Commits lede-commits at lists.infradead.org
Thu Oct 15 02:32:35 EDT 2020


blogic pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/3c4063f715e1adcfe5710c0efe1c5f06ccd1768f

commit 3c4063f715e1adcfe5710c0efe1c5f06ccd1768f
Author: Birger Koblitz <git at birger-koblitz.de>
AuthorDate: Fri Sep 25 06:49:51 2020 +0200

    rtl838x: Add irq settings for RTL839x SoCs
    
    This adds correct interrupt routing settings for IRQs on the RTL839x SoCs.
    It also speeds up irq handling based on work by biot for all SoCs.
    
    Signed-off-by: Birger Koblitz <git at birger-koblitz.de>
---
 .../mips/include/asm/mach-rtl838x/mach-rtl838x.h   |  10 +-
 .../rtl838x/files-5.4/arch/mips/rtl838x/irq.c      | 222 ++++++++-------------
 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;
 }
 



More information about the lede-commits mailing list