kernel: bump 5.4 to 5.4.80
[openwrt/openwrt.git] / target / linux / rtl838x / files-5.4 / arch / mips / rtl838x / irq.c
index 34e90982b2d1d8b4b512efe6d44fa149bc061f69..40e1269c921bc54d392931e214aac5de28238e6f 100644 (file)
@@ -20,8 +20,6 @@
 #include <asm/mipsregs.h>
 #include <mach-rtl838x.h>
 
-extern struct rtl838x_soc_info soc_info;
-
 #define icu_r32(reg)                   rtl838x_r32(soc_info.icu_base + reg)
 #define icu_w32(val, reg)              rtl838x_w32(val, soc_info.icu_base + reg)
 #define icu_w32_mask(clear, set, reg)  rtl838x_w32_mask(clear, set, soc_info.icu_base + reg)
@@ -29,36 +27,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 +38,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 +57,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 +67,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 +139,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 +153,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);
+       }
+
+       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);
 
-       rtl838x_ictl_irq_init(RTL838X_IRQ_ICTL_BASE);
+       /* Enable timer0 and uart0 interrupts */
+       icu_w32(TC0_IE | UART0_IE, GIMR);
        return 0;
 }