diff options
Diffstat (limited to 'target/linux/rtl838x')
-rw-r--r-- | target/linux/rtl838x/files-5.4/arch/mips/include/asm/mach-rtl838x/mach-rtl838x.h | 10 | ||||
-rw-r--r-- | target/linux/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; } |