Lines Matching +full:cpu +full:- +full:intc
2 * Hisilicon HiP04 INTC
4 * Copyright (C) 2002-2014 ARM Limited.
5 * Copyright (c) 2013-2014 Hisilicon Ltd.
6 * Copyright (c) 2013-2014 Linaro Ltd.
12 * Interrupt architecture for the HIP04 INTC:
17 * o There is one CPU Interface per CPU, which sends interrupts sent
19 * associated CPU. The base address of the CPU interface is usually
21 * on the CPU it is accessed from.
23 * Note that IRQs 0-31 are special - they are local to each CPU.
25 * registers are banked per-cpu for these sources.
34 #include <linux/cpu.h>
45 #include <linux/irqchip/arm-gic.h>
51 #include "irq-gic-common.h"
65 * The GIC mapping of CPU interfaces does not necessarily match
66 * the logical CPU numbering. Let's use a mapping as returned
77 return hip04_data->dist_base; in hip04_dist_base()
83 return hip04_data->cpu_base; in hip04_cpu_base()
88 return d->hwirq; in hip04_irq()
127 return -EINVAL; in hip04_irq_set_type()
132 return -EINVAL; in hip04_irq_set_type()
149 unsigned int cpu, shift = (hip04_irq(d) % 2) * 16; in hip04_irq_set_affinity() local
153 cpu = cpumask_any_and(mask_val, cpu_online_mask); in hip04_irq_set_affinity()
155 cpu = cpumask_first(mask_val); in hip04_irq_set_affinity()
157 if (cpu >= NR_HIP04_CPU_IF || cpu >= nr_cpu_ids) in hip04_irq_set_affinity()
158 return -EINVAL; in hip04_irq_set_affinity()
163 bit = hip04_cpu_map[cpu] << shift; in hip04_irq_set_affinity()
168 irq_data_update_effective_affinity(d, cpumask_of(cpu)); in hip04_irq_set_affinity()
199 .name = "HIP04 INTC",
212 static u16 hip04_get_cpumask(struct hip04_irq_data *intc) in hip04_get_cpumask() argument
214 void __iomem *base = intc->dist_base; in hip04_get_cpumask()
225 pr_crit("GIC CPU mask not found - kernel will fail to boot.\n"); in hip04_get_cpumask()
230 static void __init hip04_irq_dist_init(struct hip04_irq_data *intc) in hip04_irq_dist_init() argument
234 unsigned int nr_irqs = intc->nr_irqs; in hip04_irq_dist_init()
235 void __iomem *base = intc->dist_base; in hip04_irq_dist_init()
240 * Set all global interrupts to this CPU only. in hip04_irq_dist_init()
242 cpumask = hip04_get_cpumask(intc); in hip04_irq_dist_init()
252 static void hip04_irq_cpu_init(struct hip04_irq_data *intc) in hip04_irq_cpu_init() argument
254 void __iomem *dist_base = intc->dist_base; in hip04_irq_cpu_init()
255 void __iomem *base = intc->cpu_base; in hip04_irq_cpu_init()
256 unsigned int cpu_mask, cpu = smp_processor_id(); in hip04_irq_cpu_init() local
260 * Get what the GIC says our CPU mask is. in hip04_irq_cpu_init()
262 BUG_ON(cpu >= NR_HIP04_CPU_IF); in hip04_irq_cpu_init()
263 cpu_mask = hip04_get_cpumask(intc); in hip04_irq_cpu_init()
264 hip04_cpu_map[cpu] = cpu_mask; in hip04_irq_cpu_init()
271 if (i != cpu) in hip04_irq_cpu_init()
283 int cpu; in hip04_raise_softirq() local
288 /* Convert our logical CPU mask into a physical one. */ in hip04_raise_softirq()
289 for_each_cpu(cpu, mask) in hip04_raise_softirq()
290 map |= hip04_cpu_map[cpu]; in hip04_raise_softirq()
319 irq_set_chip_data(irq, d->host_data); in hip04_irq_domain_map()
332 return -EINVAL; in hip04_irq_domain_xlate()
334 return -EINVAL; in hip04_irq_domain_xlate()
348 static int hip04_irq_starting_cpu(unsigned int cpu) in hip04_irq_starting_cpu() argument
366 return -ENODEV; in hip04_of_init()
369 WARN(!hip04_data.dist_base, "fail to map hip04 intc dist registers\n"); in hip04_of_init()
372 WARN(!hip04_data.cpu_base, "unable to map hip04 intc cpu registers\n"); in hip04_of_init()
375 * Initialize the CPU interface map to all CPUs. in hip04_of_init()
376 * It will be refined as each CPU probes its ID. in hip04_of_init()
383 * The HIP04 INTC only supports up to 510 interrupt sources. in hip04_of_init()
391 nr_irqs -= hwirq_base; /* calculate # of irqs to allocate */ in hip04_of_init()
393 irq_base = irq_alloc_descs(-1, hwirq_base, nr_irqs, numa_node_id()); in hip04_of_init()
396 return -EINVAL; in hip04_of_init()
405 return -EINVAL; in hip04_of_init()
417 IRQCHIP_DECLARE(hip04_intc, "hisilicon,hip04-intc", hip04_of_init);