realtek: update the tree to the latest refactored version
[openwrt/openwrt.git] / target / linux / realtek / files-5.4 / arch / mips / rtl838x / irq.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Realtek RTL83XX architecture specific IRQ handling
4 *
5 * based on the original BSP
6 * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com)
7 * Copyright (C) 2020 B. Koblitz
8 * Copyright (C) 2020 Bert Vermeulen <bert@biot.com>
9 * Copyright (C) 2020 John Crispin <john@phrozen.org>
10 */
11
12 #include <linux/irqchip.h>
13 #include <linux/spinlock.h>
14 #include <linux/of_address.h>
15 #include <asm/irq_cpu.h>
16 #include <linux/of_irq.h>
17 #include <asm/cevt-r4k.h>
18
19 #include <mach-rtl83xx.h>
20 #include "irq.h"
21
22 #define REALTEK_CPU_IRQ_SHARED0 (MIPS_CPU_IRQ_BASE + 2)
23 #define REALTEK_CPU_IRQ_UART (MIPS_CPU_IRQ_BASE + 3)
24 #define REALTEK_CPU_IRQ_SWITCH (MIPS_CPU_IRQ_BASE + 4)
25 #define REALTEK_CPU_IRQ_SHARED1 (MIPS_CPU_IRQ_BASE + 5)
26 #define REALTEK_CPU_IRQ_EXTERNAL (MIPS_CPU_IRQ_BASE + 6)
27 #define REALTEK_CPU_IRQ_COUNTER (MIPS_CPU_IRQ_BASE + 7)
28
29 #define REG(x) (rtl83xx_ictl_base + x)
30
31 extern struct rtl83xx_soc_info soc_info;
32
33 static DEFINE_RAW_SPINLOCK(irq_lock);
34 static void __iomem *rtl83xx_ictl_base;
35
36 static void rtl83xx_ictl_enable_irq(struct irq_data *i)
37 {
38 unsigned long flags;
39 u32 value;
40
41 raw_spin_lock_irqsave(&irq_lock, flags);
42
43 value = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR));
44 value |= BIT(i->hwirq);
45 rtl83xx_w32(value, REG(RTL83XX_ICTL_GIMR));
46
47 raw_spin_unlock_irqrestore(&irq_lock, flags);
48 }
49
50 static void rtl83xx_ictl_disable_irq(struct irq_data *i)
51 {
52 unsigned long flags;
53 u32 value;
54
55 raw_spin_lock_irqsave(&irq_lock, flags);
56
57 value = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR));
58 value &= ~BIT(i->hwirq);
59 rtl83xx_w32(value, REG(RTL83XX_ICTL_GIMR));
60
61 raw_spin_unlock_irqrestore(&irq_lock, flags);
62 }
63
64 static struct irq_chip rtl83xx_ictl_irq = {
65 .name = "RTL83xx",
66 .irq_enable = rtl83xx_ictl_enable_irq,
67 .irq_disable = rtl83xx_ictl_disable_irq,
68 .irq_ack = rtl83xx_ictl_disable_irq,
69 .irq_mask = rtl83xx_ictl_disable_irq,
70 .irq_unmask = rtl83xx_ictl_enable_irq,
71 .irq_eoi = rtl83xx_ictl_enable_irq,
72 };
73
74 static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
75 {
76 irq_set_chip_and_handler(hw, &rtl83xx_ictl_irq, handle_level_irq);
77
78 return 0;
79 }
80
81 static const struct irq_domain_ops irq_domain_ops = {
82 .map = intc_map,
83 .xlate = irq_domain_xlate_onecell,
84 };
85
86 static void rtl838x_irq_dispatch(struct irq_desc *desc)
87 {
88 unsigned int pending = rtl83xx_r32(REG(RTL83XX_ICTL_GIMR)) & rtl83xx_r32(REG(RTL83XX_ICTL_GISR));
89
90 if (pending) {
91 struct irq_domain *domain = irq_desc_get_handler_data(desc);
92 generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
93 } else {
94 spurious_interrupt();
95 }
96 }
97
98 asmlinkage void plat_irq_dispatch(void)
99 {
100 unsigned int pending;
101
102 pending = read_c0_cause() & read_c0_status() & ST0_IM;
103
104 if (pending & CAUSEF_IP7)
105 do_IRQ(REALTEK_CPU_IRQ_COUNTER);
106
107 else if (pending & CAUSEF_IP6)
108 do_IRQ(REALTEK_CPU_IRQ_EXTERNAL);
109
110 else if (pending & CAUSEF_IP5)
111 do_IRQ(REALTEK_CPU_IRQ_SHARED1);
112
113 else if (pending & CAUSEF_IP4)
114 do_IRQ(REALTEK_CPU_IRQ_SWITCH);
115
116 else if (pending & CAUSEF_IP3)
117 do_IRQ(REALTEK_CPU_IRQ_UART);
118
119 else if (pending & CAUSEF_IP2)
120 do_IRQ(REALTEK_CPU_IRQ_SHARED0);
121
122 else
123 spurious_interrupt();
124 }
125
126 static void __init icu_of_init(struct device_node *node, struct device_node *parent)
127 {
128 struct irq_domain *domain;
129
130 domain = irq_domain_add_simple(node, 32, 0,
131 &irq_domain_ops, NULL);
132 irq_set_chained_handler_and_data(2, rtl838x_irq_dispatch, domain);
133 irq_set_chained_handler_and_data(5, rtl838x_irq_dispatch, domain);
134
135 rtl83xx_ictl_base = of_iomap(node, 0);
136 if (!rtl83xx_ictl_base)
137 return;
138
139 /* Disable all cascaded interrupts */
140 rtl83xx_w32(0, REG(RTL83XX_ICTL_GIMR));
141
142 /* Set up interrupt routing */
143 rtl83xx_w32(RTL83XX_IRR0_SETTING, REG(RTL83XX_IRR0));
144 rtl83xx_w32(RTL83XX_IRR1_SETTING, REG(RTL83XX_IRR1));
145 rtl83xx_w32(RTL83XX_IRR2_SETTING, REG(RTL83XX_IRR2));
146 rtl83xx_w32(RTL83XX_IRR3_SETTING, REG(RTL83XX_IRR3));
147
148 /* Clear timer interrupt */
149 write_c0_compare(0);
150
151 /* Enable all CPU interrupts */
152 write_c0_status(read_c0_status() | ST0_IM);
153
154 /* Enable timer0 and uart0 interrupts */
155 rtl83xx_w32(BIT(RTL83XX_IRQ_TC0) | BIT(RTL83XX_IRQ_UART0), REG(RTL83XX_ICTL_GIMR));
156 }
157
158 static struct of_device_id __initdata of_irq_ids[] = {
159 { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init },
160 { .compatible = "realtek,rt8380-intc", .data = icu_of_init },
161 {},
162 };
163
164 void __init arch_init_irq(void)
165 {
166 of_irq_init(of_irq_ids);
167 }