hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/irqchip/irq-hip04.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Hisilicon HiP04 INTC
34 *
45 * Copyright (C) 2002-2014 ARM Limited.
56 * Copyright (c) 2013-2014 Hisilicon Ltd.
67 * Copyright (c) 2013-2014 Linaro Ltd.
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
118 *
129 * Interrupt architecture for the HIP04 INTC:
1310 *
....@@ -133,7 +130,12 @@
133130
134131 raw_spin_lock(&irq_controller_lock);
135132
136
- ret = gic_configure_irq(irq, type, base, NULL);
133
+ ret = gic_configure_irq(irq, type, base + GIC_DIST_CONFIG, NULL);
134
+ if (ret && irq < 32) {
135
+ /* Misconfigured PPIs are usually not fatal */
136
+ pr_warn("GIC: PPI%d is secure or misconfigured\n", irq - 16);
137
+ ret = 0;
138
+ }
137139
138140 raw_spin_unlock(&irq_controller_lock);
139141
....@@ -169,6 +171,29 @@
169171
170172 return IRQ_SET_MASK_OK;
171173 }
174
+
175
+static void hip04_ipi_send_mask(struct irq_data *d, const struct cpumask *mask)
176
+{
177
+ int cpu;
178
+ unsigned long flags, map = 0;
179
+
180
+ raw_spin_lock_irqsave(&irq_controller_lock, flags);
181
+
182
+ /* Convert our logical CPU mask into a physical one. */
183
+ for_each_cpu(cpu, mask)
184
+ map |= hip04_cpu_map[cpu];
185
+
186
+ /*
187
+ * Ensure that stores to Normal memory are visible to the
188
+ * other CPUs before they observe us issuing the IPI.
189
+ */
190
+ dmb(ishst);
191
+
192
+ /* this always happens on GIC0 */
193
+ writel_relaxed(map << 8 | d->hwirq, hip04_data.dist_base + GIC_DIST_SOFTINT);
194
+
195
+ raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
196
+}
172197 #endif
173198
174199 static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs)
....@@ -180,19 +205,9 @@
180205 irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
181206 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
182207
183
- if (likely(irqnr > 15 && irqnr <= HIP04_MAX_IRQS)) {
208
+ if (irqnr <= HIP04_MAX_IRQS)
184209 handle_domain_irq(hip04_data.domain, irqnr, regs);
185
- continue;
186
- }
187
- if (irqnr < 16) {
188
- writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
189
-#ifdef CONFIG_SMP
190
- handle_IPI(irqnr, regs);
191
-#endif
192
- continue;
193
- }
194
- break;
195
- } while (1);
210
+ } while (irqnr > HIP04_MAX_IRQS);
196211 }
197212
198213 static struct irq_chip hip04_irq_chip = {
....@@ -203,6 +218,7 @@
203218 .irq_set_type = hip04_irq_set_type,
204219 #ifdef CONFIG_SMP
205220 .irq_set_affinity = hip04_irq_set_affinity,
221
+ .ipi_send_mask = hip04_ipi_send_mask,
206222 #endif
207223 .flags = IRQCHIP_SET_TYPE_MASKED |
208224 IRQCHIP_SKIP_SET_WAKE |
....@@ -271,45 +287,23 @@
271287 if (i != cpu)
272288 hip04_cpu_map[i] &= ~cpu_mask;
273289
274
- gic_cpu_config(dist_base, NULL);
290
+ gic_cpu_config(dist_base, 32, NULL);
275291
276292 writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
277293 writel_relaxed(1, base + GIC_CPU_CTRL);
278294 }
279295
280
-#ifdef CONFIG_SMP
281
-static void hip04_raise_softirq(const struct cpumask *mask, unsigned int irq)
282
-{
283
- int cpu;
284
- unsigned long flags, map = 0;
285
-
286
- raw_spin_lock_irqsave(&irq_controller_lock, flags);
287
-
288
- /* Convert our logical CPU mask into a physical one. */
289
- for_each_cpu(cpu, mask)
290
- map |= hip04_cpu_map[cpu];
291
-
292
- /*
293
- * Ensure that stores to Normal memory are visible to the
294
- * other CPUs before they observe us issuing the IPI.
295
- */
296
- dmb(ishst);
297
-
298
- /* this always happens on GIC0 */
299
- writel_relaxed(map << 8 | irq, hip04_data.dist_base + GIC_DIST_SOFTINT);
300
-
301
- raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
302
-}
303
-#endif
304
-
305296 static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq,
306297 irq_hw_number_t hw)
307298 {
308
- if (hw < 32) {
299
+ if (hw < 16) {
300
+ irq_set_percpu_devid(irq);
301
+ irq_set_chip_and_handler(irq, &hip04_irq_chip,
302
+ handle_percpu_devid_fasteoi_ipi);
303
+ } else if (hw < 32) {
309304 irq_set_percpu_devid(irq);
310305 irq_set_chip_and_handler(irq, &hip04_irq_chip,
311306 handle_percpu_devid_irq);
312
- irq_set_status_flags(irq, IRQ_NOAUTOEN);
313307 } else {
314308 irq_set_chip_and_handler(irq, &hip04_irq_chip,
315309 handle_fasteoi_irq);
....@@ -326,10 +320,13 @@
326320 unsigned long *out_hwirq,
327321 unsigned int *out_type)
328322 {
329
- unsigned long ret = 0;
330
-
331323 if (irq_domain_get_of_node(d) != controller)
332324 return -EINVAL;
325
+ if (intsize == 1 && intspec[0] < 16) {
326
+ *out_hwirq = intspec[0];
327
+ *out_type = IRQ_TYPE_EDGE_RISING;
328
+ return 0;
329
+ }
333330 if (intsize < 3)
334331 return -EINVAL;
335332
....@@ -342,7 +339,7 @@
342339
343340 *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
344341
345
- return ret;
342
+ return 0;
346343 }
347344
348345 static int hip04_irq_starting_cpu(unsigned int cpu)
....@@ -359,7 +356,6 @@
359356 static int __init
360357 hip04_of_init(struct device_node *node, struct device_node *parent)
361358 {
362
- irq_hw_number_t hwirq_base = 16;
363359 int nr_irqs, irq_base, i;
364360
365361 if (WARN_ON(!node))
....@@ -388,24 +384,21 @@
388384 nr_irqs = HIP04_MAX_IRQS;
389385 hip04_data.nr_irqs = nr_irqs;
390386
391
- nr_irqs -= hwirq_base; /* calculate # of irqs to allocate */
392
-
393
- irq_base = irq_alloc_descs(-1, hwirq_base, nr_irqs, numa_node_id());
387
+ irq_base = irq_alloc_descs(-1, 0, nr_irqs, numa_node_id());
394388 if (irq_base < 0) {
395389 pr_err("failed to allocate IRQ numbers\n");
396390 return -EINVAL;
397391 }
398392
399393 hip04_data.domain = irq_domain_add_legacy(node, nr_irqs, irq_base,
400
- hwirq_base,
394
+ 0,
401395 &hip04_irq_domain_ops,
402396 &hip04_data);
403
-
404397 if (WARN_ON(!hip04_data.domain))
405398 return -EINVAL;
406399
407400 #ifdef CONFIG_SMP
408
- set_smp_cross_call(hip04_raise_softirq);
401
+ set_smp_ipi_range(irq_base, 16);
409402 #endif
410403 set_handle_irq(hip04_handle_irq);
411404