Lines Matching +full:reserved +full:- +full:cpu +full:- +full:vectors
6 * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
10 #define pr_fmt(fmt) "irq-mips-gic: " fmt
24 #include <asm/mips-cps.h>
28 #include <dt-bindings/interrupt-controller/mips-gic.h>
33 /* Add 2 to convert GIC CPU pin to core interrupt */
42 #define GIC_HWIRQ_TO_LOCAL(x) ((x) - GIC_LOCAL_HWIRQ_BASE)
45 #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE)
104 irq -= GIC_PIN_TO_VEC_OFFSET; in gic_bind_eic_interrupt()
110 static void gic_send_ipi(struct irq_data *d, unsigned int cpu) in gic_send_ipi() argument
130 return -1; in gic_get_c0_perfcount_int()
142 return -1; in gic_get_c0_fdc_int()
156 /* Get per-cpu bitmaps */ in gic_handle_shared_int()
180 unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); in gic_mask_irq()
188 unsigned int intr = GIC_HWIRQ_TO_SHARED(d->hwirq); in gic_unmask_irq()
189 unsigned int cpu; in gic_unmask_irq() local
194 cpu = cpumask_first(irq_data_get_effective_affinity_mask(d)); in gic_unmask_irq()
195 set_bit(intr, per_cpu_ptr(pcpu_masks, cpu)); in gic_unmask_irq()
200 unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); in gic_ack_irq()
210 irq = GIC_HWIRQ_TO_SHARED(d->hwirq); in gic_set_type()
261 unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); in gic_set_affinity()
263 unsigned int cpu; in gic_set_affinity() local
265 cpu = cpumask_first_and(cpumask, cpu_online_mask); in gic_set_affinity()
266 if (cpu >= NR_CPUS) in gic_set_affinity()
267 return -EINVAL; in gic_set_affinity()
269 /* Assumption : cpumask refers to a single CPU */ in gic_set_affinity()
272 /* Re-route this IRQ */ in gic_set_affinity()
273 write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu))); in gic_set_affinity()
278 set_bit(irq, per_cpu_ptr(pcpu_masks, cpu)); in gic_set_affinity()
280 irq_data_update_effective_affinity(d, cpumask_of(cpu)); in gic_set_affinity()
331 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); in gic_mask_local_irq()
338 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); in gic_unmask_local_irq()
353 int intr, cpu; in gic_mask_local_irq_all_vpes() local
355 intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); in gic_mask_local_irq_all_vpes()
357 cd->mask = false; in gic_mask_local_irq_all_vpes()
360 for_each_online_cpu(cpu) { in gic_mask_local_irq_all_vpes()
361 write_gic_vl_other(mips_cm_vp_id(cpu)); in gic_mask_local_irq_all_vpes()
371 int intr, cpu; in gic_unmask_local_irq_all_vpes() local
373 intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); in gic_unmask_local_irq_all_vpes()
375 cd->mask = true; in gic_unmask_local_irq_all_vpes()
378 for_each_online_cpu(cpu) { in gic_unmask_local_irq_all_vpes()
379 write_gic_vl_other(mips_cm_vp_id(cpu)); in gic_unmask_local_irq_all_vpes()
402 write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map); in gic_all_vpes_irq_cpu_online()
403 if (cd->mask) in gic_all_vpes_irq_cpu_online()
429 irq_hw_number_t hw, unsigned int cpu) in gic_shared_irq_domain_map() argument
439 write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); in gic_shared_irq_domain_map()
440 irq_data_update_effective_affinity(data, cpumask_of(cpu)); in gic_shared_irq_domain_map()
452 return -EINVAL; in gic_irq_domain_xlate()
459 return -EINVAL; in gic_irq_domain_xlate()
471 int err, cpu; in gic_irq_domain_map() local
478 return -EBUSY; in gic_irq_domain_map()
495 * If adding support for more per-cpu interrupts, keep the the in gic_irq_domain_map()
511 cd->map = map; in gic_irq_domain_map()
534 return -EPERM; in gic_irq_domain_map()
537 for_each_online_cpu(cpu) { in gic_irq_domain_map()
538 write_gic_vl_other(mips_cm_vp_id(cpu)); in gic_irq_domain_map()
552 if (fwspec->param[0] == GIC_SHARED) in gic_irq_domain_alloc()
553 hwirq = GIC_SHARED_TO_HWIRQ(fwspec->param[1]); in gic_irq_domain_alloc()
555 hwirq = GIC_LOCAL_TO_HWIRQ(fwspec->param[1]); in gic_irq_domain_alloc()
594 int cpu, ret, i; in gic_ipi_domain_alloc() local
598 return -ENOMEM; in gic_ipi_domain_alloc()
603 return -EBUSY; in gic_ipi_domain_alloc()
607 /* map the hwirq for each cpu consecutively */ in gic_ipi_domain_alloc()
609 for_each_cpu(cpu, ipimask) { in gic_ipi_domain_alloc()
618 ret = irq_domain_set_hwirq_and_chip(d->parent, virq + i, hwirq, in gic_ipi_domain_alloc()
628 ret = gic_shared_irq_domain_map(d, virq + i, hwirq, cpu); in gic_ipi_domain_alloc()
662 is_ipi = d->bus_token == bus_token; in gic_ipi_domain_match()
663 return (!node || to_of_node(d->fwnode) == node) && is_ipi; in gic_ipi_domain_match()
688 return -ENXIO; in gic_register_ipi_domain()
694 !of_property_read_u32_array(node, "mti,reserved-ipi-vectors", v, 2)) { in gic_register_ipi_domain()
698 * Reserve 2 interrupts per possible CPU/VP for use as IPIs, in gic_register_ipi_domain()
702 bitmap_set(ipi_resrv, gic_shared_intrs - num_ipis, num_ipis); in gic_register_ipi_domain()
719 static int gic_cpu_startup(unsigned int cpu) in gic_cpu_startup() argument
738 unsigned long reserved; in gic_of_init() local
744 /* Find the first available CPU vector. */ in gic_of_init()
746 reserved = (C_SW0 | C_SW1) >> __ffs(C_SW0); in gic_of_init()
747 while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", in gic_of_init()
749 reserved |= BIT(cpu_vec); in gic_of_init()
751 cpu_vec = find_first_zero_bit(&reserved, hweight_long(ST0_IM)); in gic_of_init()
753 pr_err("No CPU vectors available\n"); in gic_of_init()
754 return -ENODEV; in gic_of_init()
760 * in the device-tree. in gic_of_init()
770 return -ENODEV; in gic_of_init()
786 return -ENOMEM; in gic_of_init()
801 gic_cpu_pin = cpu_vec - GIC_CPU_PIN_OFFSET; in gic_of_init()
807 * waiting poll loop. We must not re-route those CPU's local in gic_of_init()
809 * so just handle whatever CPU interrupt it is routed to by in gic_of_init()
832 return -ENXIO; in gic_of_init()