rtl83xx: update the irq code rt83xx
authorJohn Crispin <john@phrozen.org>
Wed, 25 Nov 2020 10:51:16 +0000 (11:51 +0100)
committerJohn Crispin <john@phrozen.org>
Wed, 25 Nov 2020 10:55:04 +0000 (11:55 +0100)
Signed-off-by: John Crispin <john@phrozen.org>
target/linux/rtl838x/dts/rtl838x.dtsi
target/linux/rtl838x/files-5.4/arch/mips/rtl838x/irq.c
target/linux/rtl838x/files-5.4/arch/mips/rtl838x/serial.c
target/linux/rtl838x/files-5.4/drivers/net/dsa/rtl83xx/common.c

index ec4a523c14f40a6f01f190563305bd7725a2d1fa..ac40e3f430f021161b26a2aab294bf78daba926b 100644 (file)
                #address-cells = <0>;
                #interrupt-cells = <1>;
                interrupt-controller;
-               compatible = "rtl83xx,icu";
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       intc: rtlintc {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "realtek,rt8380-intc";
                reg = <0xb8003000 0x20>;
        };
 
@@ -88,7 +95,7 @@
                clock-frequency = <200000000>;
 
                interrupt-parent = <&cpuintc>;
-               interrupts = <31>;
+               interrupts = <3>;
 
                reg-io-width = <1>;
                reg-shift = <2>;
 
                clock-frequency = <200000000>;
 
-               interrupt-parent = <&cpuintc>;
+               interrupt-parent = <&intc>;
                interrupts = <30>;
 
                reg-io-width = <1>;
                reg = <0xb8003500 0x20>;
                gpio-controller;
                #gpio-cells = <2>;
-               interrupt-parent = <&cpuintc>;
+               interrupt-parent = <&intc>;
                interrupts = <23>;
        };
 
 
                compatible = "realtek,rtl838x-eth";
                reg = <0xbb00a300 0x100>;
-               interrupt-parent = <&cpuintc>;
+               interrupt-parent = <&intc>;
                interrupts = <24>;
                #interrupt-cells = <1>;
                phy-mode = "internal";
        switch0: switch@bb000000 {
                status = "okay";
 
+               interrupt-parent = <&cpuintc>;
+               interrupts = <4>;
+
+
                compatible = "realtek,rtl83xx-switch";
        };
 };
index 8e19b090105418de34644778cc81d606bfbde189..9057d485437952861fda294fa49da010b930b22e 100644 (file)
@@ -2,30 +2,37 @@
 /*
  * Realtek RTL83XX architecture specific IRQ handling
  *
- * Copyright  (C) 2020 B. Koblitz
  * based on the original BSP
  * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com)
- *
+ * Copyright (C) 2020 B. Koblitz
+ * Copyright (C) 2020 Bert Vermeulen <bert@biot.com>
+ * Copyright (C) 2020 John Crispin <john@phrozen.org>
  */
 
 #include <linux/irqchip.h>
 #include <linux/spinlock.h>
 #include <linux/of_address.h>
 #include <asm/irq_cpu.h>
+#include <linux/of_irq.h>
 #include <asm/cevt-r4k.h>
 
 #include <mach-rtl83xx.h>
 #include "irq.h"
 
+#define REALTEK_CPU_IRQ_SHARED0                (MIPS_CPU_IRQ_BASE + 2)
+#define REALTEK_CPU_IRQ_UART           (MIPS_CPU_IRQ_BASE + 3)
+#define REALTEK_CPU_IRQ_SWITCH         (MIPS_CPU_IRQ_BASE + 4)
+#define REALTEK_CPU_IRQ_SHARED1                (MIPS_CPU_IRQ_BASE + 5)
+#define REALTEK_CPU_IRQ_EXTERNAL       (MIPS_CPU_IRQ_BASE + 6)
+#define REALTEK_CPU_IRQ_COUNTER                (MIPS_CPU_IRQ_BASE + 7)
 
-#define REG(x)         (rtl83xx_ictl_base + x)
+#define REG(x)                         (rtl83xx_ictl_base + x)
 
 extern struct rtl83xx_soc_info soc_info;
 
 static DEFINE_RAW_SPINLOCK(irq_lock);
 static void __iomem *rtl83xx_ictl_base;
 
-
 static void rtl83xx_ictl_enable_irq(struct irq_data *i)
 {
        unsigned long flags;
@@ -34,7 +41,7 @@ static void rtl83xx_ictl_enable_irq(struct irq_data *i)
        raw_spin_lock_irqsave(&irq_lock, flags);
 
        value = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR));
-       value |= BIT(i->irq);
+       value |= BIT(i->hwirq);
        rtl83xx_w32(value, REG(RTL83XX_ICTL_GIMR));
 
        raw_spin_unlock_irqrestore(&irq_lock, flags);
@@ -48,7 +55,7 @@ static void rtl83xx_ictl_disable_irq(struct irq_data *i)
        raw_spin_lock_irqsave(&irq_lock, flags);
 
        value = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR));
-       value &= ~BIT(i->irq);
+       value &= ~BIT(i->hwirq);
        rtl83xx_w32(value, REG(RTL83XX_ICTL_GIMR));
 
        raw_spin_unlock_irqrestore(&irq_lock, flags);
@@ -64,100 +71,70 @@ static struct irq_chip rtl83xx_ictl_irq = {
        .irq_eoi = rtl83xx_ictl_enable_irq,
 };
 
-asmlinkage void plat_irq_dispatch(void)
+static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 {
-       unsigned int pending, ext_int;
+       irq_set_chip_and_handler(hw, &rtl83xx_ictl_irq, handle_level_irq);
 
-       pending =  read_c0_cause() & read_c0_status() & ST0_IM;
+       return 0;
+}
 
-       if (pending & CAUSEF_IP7) {
-               c0_compare_interrupt(7, NULL);
-
-       } else if (pending & CAUSEF_IP6) {
-               do_IRQ(RTL83XX_IRQ_TC0);
-
-       } else if (pending & CAUSEF_IP5) {
-               ext_int = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR)) & rtl83xx_r32(REG(RTL83XX_ICTL_GISR));
-               if (ext_int & BIT(RTL83XX_IRQ_NIC))
-                       do_IRQ(RTL83XX_IRQ_NIC);
-               else if (ext_int & BIT(RTL83XX_IRQ_GPIO_ABCD))
-                       do_IRQ(RTL83XX_IRQ_GPIO_ABCD);
-               else if ((ext_int & BIT(RTL83XX_IRQ_GPIO_EFGH)) && (soc_info.family == RTL8328_FAMILY_ID))
-                       do_IRQ(RTL83XX_IRQ_GPIO_EFGH);
-               else
-                       spurious_interrupt();
-
-       } else if (pending & CAUSEF_IP4) {
-               do_IRQ(RTL83XX_IRQ_SWCORE);
-
-       } else if (pending & CAUSEF_IP3) {
-               do_IRQ(RTL83XX_IRQ_UART0);
-
-       } else if (pending & CAUSEF_IP2) {
-               ext_int = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR)) & rtl83xx_r32(REG(RTL83XX_ICTL_GISR));
-               if (ext_int & BIT(RTL83XX_IRQ_TC1))
-                       do_IRQ(RTL83XX_IRQ_TC1);
-               else if (ext_int & BIT(RTL83XX_IRQ_UART1))
-                       do_IRQ(RTL83XX_IRQ_UART1);
-               else
-                       spurious_interrupt();
+static const struct irq_domain_ops irq_domain_ops = {
+       .map = intc_map,
+       .xlate = irq_domain_xlate_onecell,
+};
 
+static void rtl838x_irq_dispatch(struct irq_desc *desc)
+{
+       unsigned int pending = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR)) & rtl83xx_r32(REG(RTL83XX_ICTL_GISR));
+
+       if (pending) {
+               struct irq_domain *domain = irq_desc_get_handler_data(desc);
+               generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
        } else {
                spurious_interrupt();
        }
 }
 
-static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+asmlinkage void plat_irq_dispatch(void)
 {
-       irq_set_chip_and_handler(hw, &rtl83xx_ictl_irq, handle_level_irq);
+       unsigned int pending;
 
-       return 0;
-}
+       pending =  read_c0_cause() & read_c0_status() & ST0_IM;
 
-static const struct irq_domain_ops irq_domain_ops = {
-       .map = intc_map,
-       .xlate = irq_domain_xlate_onecell,
-};
+       if (pending & CAUSEF_IP7)
+               do_IRQ(REALTEK_CPU_IRQ_COUNTER);
+
+       else if (pending & CAUSEF_IP6)
+               do_IRQ(REALTEK_CPU_IRQ_EXTERNAL);
+
+       else if (pending & CAUSEF_IP5)
+               do_IRQ(REALTEK_CPU_IRQ_SHARED1);
+
+       else if (pending & CAUSEF_IP4)
+               do_IRQ(REALTEK_CPU_IRQ_SWITCH);
+
+       else if (pending & CAUSEF_IP3)
+               do_IRQ(REALTEK_CPU_IRQ_UART);
+
+       else if (pending & CAUSEF_IP2)
+               do_IRQ(REALTEK_CPU_IRQ_SHARED0);
 
-int __init icu_of_init(struct device_node *node, struct device_node *parent)
+       else
+               spurious_interrupt();
+}
+
+static void __init icu_of_init(struct device_node *node, struct device_node *parent)
 {
        struct irq_domain *domain;
-       int i;
 
-       mips_cpu_irq_init();
-
-       domain = irq_domain_add_simple(node, 32, 0, &irq_domain_ops, NULL);
+       domain = irq_domain_add_simple(node, 32, 0,
+                                      &irq_domain_ops, NULL);
+        irq_set_chained_handler_and_data(2, rtl838x_irq_dispatch, domain);
+        irq_set_chained_handler_and_data(5, rtl838x_irq_dispatch, domain);
 
        rtl83xx_ictl_base = of_iomap(node, 0);
        if (!rtl83xx_ictl_base)
-               return -EIO;
-
-       for (i = 8; i < RTL83XX_IRQ_ICTL_NUM; i++) {
-               irq_domain_associate(domain, i, i);
-               irq_set_chip_and_handler(RTL83XX_IRQ_ICTL_BASE + i,
-                                        &rtl83xx_ictl_irq, handle_level_irq);
-       }
-
-       if (request_irq(RTL83XX_ICTL1_IRQ, no_action, IRQF_NO_THREAD,
-                       "IRQ cascade 1", NULL)) {
-               pr_err("request_irq() cascade 1 for irq %d failed\n", RTL83XX_ICTL1_IRQ);
-       }
-       if (request_irq(RTL83XX_ICTL2_IRQ, no_action, IRQF_NO_THREAD,
-                       "IRQ cascade 2", NULL)) {
-               pr_err("request_irq() cascade 2 for irq %d failed\n", RTL83XX_ICTL2_IRQ);
-       }
-       if (request_irq(RTL83XX_ICTL3_IRQ, no_action, IRQF_NO_THREAD,
-                       "IRQ cascade 3", NULL)) {
-               pr_err("request_irq() cascade 3 for irq %d failed\n", RTL83XX_ICTL3_IRQ);
-       }
-       if (request_irq(RTL83XX_ICTL4_IRQ, no_action, IRQF_NO_THREAD,
-                       "IRQ cascade 4", NULL)) {
-               pr_err("request_irq() cascade 4 for irq %d failed\n", RTL83XX_ICTL4_IRQ);
-       }
-       if (request_irq(RTL83XX_ICTL5_IRQ, no_action, IRQF_NO_THREAD,
-                       "IRQ cascade 5", NULL)) {
-               pr_err("request_irq() cascade 5 for irq %d failed\n", RTL83XX_ICTL5_IRQ);
-       }
+               return;
 
        /* Disable all cascaded interrupts */
        rtl83xx_w32(0, REG(RTL83XX_ICTL_GIMR));
@@ -176,13 +153,15 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
 
        /* Enable timer0 and uart0 interrupts */
        rtl83xx_w32(BIT(RTL83XX_IRQ_TC0) | BIT(RTL83XX_IRQ_UART0), REG(RTL83XX_ICTL_GIMR));
-
-       return 0;
 }
 
+static struct of_device_id __initdata of_irq_ids[] = {
+       { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
+       { .compatible = "realtek,rt8380-intc", .data = icu_of_init },
+       {},
+};
+
 void __init arch_init_irq(void)
 {
-       irqchip_init();
+       of_irq_init(of_irq_ids);
 }
-
-IRQCHIP_DECLARE(mips_cpu_intc, "rtl83xx,icu", icu_of_init);
index 22834f41342857390e8e01a72eeebce46a35a3c4..f741ee45fdd2e4bd1ad6644ce9205e86332996cd 100644 (file)
@@ -86,7 +86,7 @@ int __init rtl838x_serial_init(void)
 
        p.type = PORT_16550A;
        p.membase = (unsigned char *) RTL838X_UART0_BASE;
-       p.irq = RTL838X_UART0_IRQ;
+       p.irq = 3;
        p.uartclk = SYSTEM_FREQ - (24 * baud);
        p.flags = UPF_SKIP_TEST | UPF_LOW_LATENCY | UPF_FIXED_TYPE;
        p.iotype = UPIO_MEM;
index 6d99a8d53d1a5f0150e013b956a63c9a2a88f226..1b57ddc92c866f9676e0881837d04cee84bbbcd9 100644 (file)
@@ -343,7 +343,7 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev)
        priv->r->set_port_reg_le(irq_mask, priv->r->isr_port_link_sts_chg);
        priv->r->set_port_reg_le(irq_mask, priv->r->imr_port_link_sts_chg);
 
-       priv->link_state_irq = 20;
+       priv->link_state_irq = platform_get_irq(pdev, 0);;
        if (priv->family_id == RTL8380_FAMILY_ID) {
                err = request_irq(priv->link_state_irq, rtl838x_switch_irq,
                                IRQF_SHARED, "rtl838x-link-state", priv->ds);