hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/irqchip/irq-sun4i.c
....@@ -28,11 +28,21 @@
2828 #define SUN4I_IRQ_NMI_CTRL_REG 0x0c
2929 #define SUN4I_IRQ_PENDING_REG(x) (0x10 + 0x4 * x)
3030 #define SUN4I_IRQ_FIQ_PENDING_REG(x) (0x20 + 0x4 * x)
31
-#define SUN4I_IRQ_ENABLE_REG(x) (0x40 + 0x4 * x)
32
-#define SUN4I_IRQ_MASK_REG(x) (0x50 + 0x4 * x)
31
+#define SUN4I_IRQ_ENABLE_REG(data, x) ((data)->enable_reg_offset + 0x4 * x)
32
+#define SUN4I_IRQ_MASK_REG(data, x) ((data)->mask_reg_offset + 0x4 * x)
33
+#define SUN4I_IRQ_ENABLE_REG_OFFSET 0x40
34
+#define SUN4I_IRQ_MASK_REG_OFFSET 0x50
35
+#define SUNIV_IRQ_ENABLE_REG_OFFSET 0x20
36
+#define SUNIV_IRQ_MASK_REG_OFFSET 0x30
3337
34
-static void __iomem *sun4i_irq_base;
35
-static struct irq_domain *sun4i_irq_domain;
38
+struct sun4i_irq_chip_data {
39
+ void __iomem *irq_base;
40
+ struct irq_domain *irq_domain;
41
+ u32 enable_reg_offset;
42
+ u32 mask_reg_offset;
43
+};
44
+
45
+static struct sun4i_irq_chip_data *irq_ic_data;
3646
3747 static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs);
3848
....@@ -43,7 +53,7 @@
4353 if (irq != 0)
4454 return; /* Only IRQ 0 / the ENMI needs to be acked */
4555
46
- writel(BIT(0), sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0));
56
+ writel(BIT(0), irq_ic_data->irq_base + SUN4I_IRQ_PENDING_REG(0));
4757 }
4858
4959 static void sun4i_irq_mask(struct irq_data *irqd)
....@@ -53,9 +63,10 @@
5363 int reg = irq / 32;
5464 u32 val;
5565
56
- val = readl(sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg));
66
+ val = readl(irq_ic_data->irq_base +
67
+ SUN4I_IRQ_ENABLE_REG(irq_ic_data, reg));
5768 writel(val & ~(1 << irq_off),
58
- sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg));
69
+ irq_ic_data->irq_base + SUN4I_IRQ_ENABLE_REG(irq_ic_data, reg));
5970 }
6071
6172 static void sun4i_irq_unmask(struct irq_data *irqd)
....@@ -65,9 +76,10 @@
6576 int reg = irq / 32;
6677 u32 val;
6778
68
- val = readl(sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg));
79
+ val = readl(irq_ic_data->irq_base +
80
+ SUN4I_IRQ_ENABLE_REG(irq_ic_data, reg));
6981 writel(val | (1 << irq_off),
70
- sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(reg));
82
+ irq_ic_data->irq_base + SUN4I_IRQ_ENABLE_REG(irq_ic_data, reg));
7183 }
7284
7385 static struct irq_chip sun4i_irq_chip = {
....@@ -95,42 +107,76 @@
95107 static int __init sun4i_of_init(struct device_node *node,
96108 struct device_node *parent)
97109 {
98
- sun4i_irq_base = of_iomap(node, 0);
99
- if (!sun4i_irq_base)
110
+ irq_ic_data->irq_base = of_iomap(node, 0);
111
+ if (!irq_ic_data->irq_base)
100112 panic("%pOF: unable to map IC registers\n",
101113 node);
102114
103115 /* Disable all interrupts */
104
- writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(0));
105
- writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(1));
106
- writel(0, sun4i_irq_base + SUN4I_IRQ_ENABLE_REG(2));
116
+ writel(0, irq_ic_data->irq_base + SUN4I_IRQ_ENABLE_REG(irq_ic_data, 0));
117
+ writel(0, irq_ic_data->irq_base + SUN4I_IRQ_ENABLE_REG(irq_ic_data, 1));
118
+ writel(0, irq_ic_data->irq_base + SUN4I_IRQ_ENABLE_REG(irq_ic_data, 2));
107119
108120 /* Unmask all the interrupts, ENABLE_REG(x) is used for masking */
109
- writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(0));
110
- writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(1));
111
- writel(0, sun4i_irq_base + SUN4I_IRQ_MASK_REG(2));
121
+ writel(0, irq_ic_data->irq_base + SUN4I_IRQ_MASK_REG(irq_ic_data, 0));
122
+ writel(0, irq_ic_data->irq_base + SUN4I_IRQ_MASK_REG(irq_ic_data, 1));
123
+ writel(0, irq_ic_data->irq_base + SUN4I_IRQ_MASK_REG(irq_ic_data, 2));
112124
113125 /* Clear all the pending interrupts */
114
- writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0));
115
- writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(1));
116
- writel(0xffffffff, sun4i_irq_base + SUN4I_IRQ_PENDING_REG(2));
126
+ writel(0xffffffff, irq_ic_data->irq_base + SUN4I_IRQ_PENDING_REG(0));
127
+ writel(0xffffffff, irq_ic_data->irq_base + SUN4I_IRQ_PENDING_REG(1));
128
+ writel(0xffffffff, irq_ic_data->irq_base + SUN4I_IRQ_PENDING_REG(2));
117129
118130 /* Enable protection mode */
119
- writel(0x01, sun4i_irq_base + SUN4I_IRQ_PROTECTION_REG);
131
+ writel(0x01, irq_ic_data->irq_base + SUN4I_IRQ_PROTECTION_REG);
120132
121133 /* Configure the external interrupt source type */
122
- writel(0x00, sun4i_irq_base + SUN4I_IRQ_NMI_CTRL_REG);
134
+ writel(0x00, irq_ic_data->irq_base + SUN4I_IRQ_NMI_CTRL_REG);
123135
124
- sun4i_irq_domain = irq_domain_add_linear(node, 3 * 32,
136
+ irq_ic_data->irq_domain = irq_domain_add_linear(node, 3 * 32,
125137 &sun4i_irq_ops, NULL);
126
- if (!sun4i_irq_domain)
138
+ if (!irq_ic_data->irq_domain)
127139 panic("%pOF: unable to create IRQ domain\n", node);
128140
129141 set_handle_irq(sun4i_handle_irq);
130142
131143 return 0;
132144 }
133
-IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-a10-ic", sun4i_of_init);
145
+
146
+static int __init sun4i_ic_of_init(struct device_node *node,
147
+ struct device_node *parent)
148
+{
149
+ irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL);
150
+ if (!irq_ic_data) {
151
+ pr_err("kzalloc failed!\n");
152
+ return -ENOMEM;
153
+ }
154
+
155
+ irq_ic_data->enable_reg_offset = SUN4I_IRQ_ENABLE_REG_OFFSET;
156
+ irq_ic_data->mask_reg_offset = SUN4I_IRQ_MASK_REG_OFFSET;
157
+
158
+ return sun4i_of_init(node, parent);
159
+}
160
+
161
+IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-a10-ic", sun4i_ic_of_init);
162
+
163
+static int __init suniv_ic_of_init(struct device_node *node,
164
+ struct device_node *parent)
165
+{
166
+ irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL);
167
+ if (!irq_ic_data) {
168
+ pr_err("kzalloc failed!\n");
169
+ return -ENOMEM;
170
+ }
171
+
172
+ irq_ic_data->enable_reg_offset = SUNIV_IRQ_ENABLE_REG_OFFSET;
173
+ irq_ic_data->mask_reg_offset = SUNIV_IRQ_MASK_REG_OFFSET;
174
+
175
+ return sun4i_of_init(node, parent);
176
+}
177
+
178
+IRQCHIP_DECLARE(allwinner_sunvi_ic, "allwinner,suniv-f1c100s-ic",
179
+ suniv_ic_of_init);
134180
135181 static void __exception_irq_entry sun4i_handle_irq(struct pt_regs *regs)
136182 {
....@@ -143,16 +189,18 @@
143189 * 3) spurious irq
144190 * So if we immediately get a reading of 0, check the irq-pending reg
145191 * to differentiate between 2 and 3. We only do this once to avoid
146
- * the extra check in the common case of 1 hapening after having
192
+ * the extra check in the common case of 1 happening after having
147193 * read the vector-reg once.
148194 */
149
- hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2;
195
+ hwirq = readl(irq_ic_data->irq_base + SUN4I_IRQ_VECTOR_REG) >> 2;
150196 if (hwirq == 0 &&
151
- !(readl(sun4i_irq_base + SUN4I_IRQ_PENDING_REG(0)) & BIT(0)))
197
+ !(readl(irq_ic_data->irq_base + SUN4I_IRQ_PENDING_REG(0)) &
198
+ BIT(0)))
152199 return;
153200
154201 do {
155
- handle_domain_irq(sun4i_irq_domain, hwirq, regs);
156
- hwirq = readl(sun4i_irq_base + SUN4I_IRQ_VECTOR_REG) >> 2;
202
+ handle_domain_irq(irq_ic_data->irq_domain, hwirq, regs);
203
+ hwirq = readl(irq_ic_data->irq_base +
204
+ SUN4I_IRQ_VECTOR_REG) >> 2;
157205 } while (hwirq != 0);
158206 }