Lines Matching +full:4 +full:- +full:cpu

1 // SPDX-License-Identifier: GPL-2.0-only
10 * o There is one CPU Interface per CPU, which sends interrupts sent
12 * associated CPU. The base address of the CPU interface is usually
14 * on the CPU it is accessed from.
16 * Note that IRQs 0-31 are special - they are local to each CPU.
18 * registers are banked per-cpu for these sources.
27 #include <linux/cpu.h>
42 #include <linux/irqchip/arm-gic.h>
50 #include "irq-gic-common.h"
80 u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
114 * The GIC mapping of CPU interfaces does not necessarily match
115 * the logical CPU numbering. Let's use a mapping as returned
140 return raw_cpu_read(*base->percpu_base); in __get_base()
142 return base->common_base; in __get_base()
145 #define gic_data_dist_base(d) __get_base(&(d)->dist_base)
146 #define gic_data_cpu_base(d) __get_base(&(d)->cpu_base)
148 #define gic_data_dist_base(d) ((d)->dist_base.common_base)
149 #define gic_data_cpu_base(d) ((d)->cpu_base.common_base)
167 return d->hwirq; in gic_irq()
187 writel_relaxed(mask, gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4); in gic_poke_irq()
193 return !!(readl_relaxed(gic_dist_base(d) + offset + (gic_irq(d) / 32) * 4) & mask); in gic_peek_irq()
264 return -EINVAL; in gic_irq_set_irqchip_state()
288 return -EINVAL; in gic_irq_get_irqchip_state()
302 return type != IRQ_TYPE_EDGE_RISING ? -EINVAL : 0; in gic_set_type()
307 return -EINVAL; in gic_set_type()
312 pr_warn("GIC: PPI%d is secure or misconfigured\n", gicirq - 16); in gic_set_type()
323 return -EINVAL; in gic_irq_set_vcpu_affinity()
355 * Ensure any shared data written by the CPU sending the IPI in gic_handle_irq()
364 * The GIC encodes the source CPU in GICC_IAR, in gic_handle_irq()
373 generic_handle_domain_irq(gic->domain, irqnr); in gic_handle_irq()
394 ret = generic_handle_domain_irq(chip_data->domain, gic_irq); in gic_handle_cascade_irq()
405 if (gic->domain->pm_dev) in gic_irq_print_chip()
406 seq_printf(p, gic->domain->pm_dev->of_node->name); in gic_irq_print_chip()
408 seq_printf(p, "GIC-%d", (int)(gic - &gic_data[0])); in gic_irq_print_chip()
423 for (i = mask = 0; i < 32; i += 4) { in gic_get_cpumask()
432 pr_crit("GIC CPU mask not found - kernel will fail to boot.\n"); in gic_get_cpumask()
454 for (i = 0; i < 4; i++) in gic_cpu_if_up()
455 writel_relaxed(0, cpu_base + GIC_CPU_ACTIVEPRIO + i * 4); in gic_cpu_if_up()
471 unsigned int gic_irqs = gic->gic_irqs; in gic_dist_init()
477 * Set all global interrupts to this CPU only. in gic_dist_init()
482 for (i = 32; i < gic_irqs; i += 4) in gic_dist_init()
483 writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); in gic_dist_init()
494 unsigned int cpu_mask, cpu = smp_processor_id(); in gic_cpu_init() local
498 * Setting up the CPU map is only relevant for the primary GIC in gic_cpu_init()
500 * with the CPU(s). in gic_cpu_init()
504 * Get what the GIC says our CPU mask is. in gic_cpu_init()
506 if (WARN_ON(cpu >= NR_GIC_CPU_IF)) in gic_cpu_init()
507 return -EINVAL; in gic_cpu_init()
511 gic_cpu_map[cpu] = cpu_mask; in gic_cpu_init()
518 if (i != cpu) in gic_cpu_init()
536 return -EINVAL; in gic_cpu_if_down()
551 * platform-specific wakeup source must be enabled.
562 gic_irqs = gic->gic_irqs; in gic_dist_save()
569 gic->saved_spi_conf[i] = in gic_dist_save()
570 readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); in gic_dist_save()
572 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) in gic_dist_save()
573 gic->saved_spi_target[i] = in gic_dist_save()
574 readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4); in gic_dist_save()
577 gic->saved_spi_enable[i] = in gic_dist_save()
578 readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); in gic_dist_save()
581 gic->saved_spi_active[i] = in gic_dist_save()
582 readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); in gic_dist_save()
590 * the GIC and need to be handled by the platform-specific wakeup source.
601 gic_irqs = gic->gic_irqs; in gic_dist_restore()
610 writel_relaxed(gic->saved_spi_conf[i], in gic_dist_restore()
611 dist_base + GIC_DIST_CONFIG + i * 4); in gic_dist_restore()
613 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) in gic_dist_restore()
615 dist_base + GIC_DIST_PRI + i * 4); in gic_dist_restore()
617 for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) in gic_dist_restore()
618 writel_relaxed(gic->saved_spi_target[i], in gic_dist_restore()
619 dist_base + GIC_DIST_TARGET + i * 4); in gic_dist_restore()
623 dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); in gic_dist_restore()
624 writel_relaxed(gic->saved_spi_enable[i], in gic_dist_restore()
625 dist_base + GIC_DIST_ENABLE_SET + i * 4); in gic_dist_restore()
630 dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); in gic_dist_restore()
631 writel_relaxed(gic->saved_spi_active[i], in gic_dist_restore()
632 dist_base + GIC_DIST_ACTIVE_SET + i * 4); in gic_dist_restore()
654 ptr = raw_cpu_ptr(gic->saved_ppi_enable); in gic_cpu_save()
656 ptr[i] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4); in gic_cpu_save()
658 ptr = raw_cpu_ptr(gic->saved_ppi_active); in gic_cpu_save()
660 ptr[i] = readl_relaxed(dist_base + GIC_DIST_ACTIVE_SET + i * 4); in gic_cpu_save()
662 ptr = raw_cpu_ptr(gic->saved_ppi_conf); in gic_cpu_save()
664 ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4); in gic_cpu_save()
684 ptr = raw_cpu_ptr(gic->saved_ppi_enable); in gic_cpu_restore()
687 dist_base + GIC_DIST_ENABLE_CLEAR + i * 4); in gic_cpu_restore()
688 writel_relaxed(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); in gic_cpu_restore()
691 ptr = raw_cpu_ptr(gic->saved_ppi_active); in gic_cpu_restore()
694 dist_base + GIC_DIST_ACTIVE_CLEAR + i * 4); in gic_cpu_restore()
695 writel_relaxed(ptr[i], dist_base + GIC_DIST_ACTIVE_SET + i * 4); in gic_cpu_restore()
698 ptr = raw_cpu_ptr(gic->saved_ppi_conf); in gic_cpu_restore()
700 writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); in gic_cpu_restore()
702 for (i = 0; i < DIV_ROUND_UP(32, 4); i++) in gic_cpu_restore()
704 dist_base + GIC_DIST_PRI + i * 4); in gic_cpu_restore()
742 gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4, in gic_pm_init()
744 if (WARN_ON(!gic->saved_ppi_enable)) in gic_pm_init()
745 return -ENOMEM; in gic_pm_init()
747 gic->saved_ppi_active = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4, in gic_pm_init()
749 if (WARN_ON(!gic->saved_ppi_active)) in gic_pm_init()
752 gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4, in gic_pm_init()
754 if (WARN_ON(!gic->saved_ppi_conf)) in gic_pm_init()
763 free_percpu(gic->saved_ppi_active); in gic_pm_init()
765 free_percpu(gic->saved_ppi_enable); in gic_pm_init()
767 return -ENOMEM; in gic_pm_init()
787 addr -= offset; in rmw_writeb()
801 unsigned int cpu; in gic_set_affinity() local
804 return -EINVAL; in gic_set_affinity()
807 cpu = cpumask_any_and(mask_val, cpu_online_mask); in gic_set_affinity()
809 cpu = cpumask_first(mask_val); in gic_set_affinity()
811 if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) in gic_set_affinity()
812 return -EINVAL; in gic_set_affinity()
815 rmw_writeb(gic_cpu_map[cpu], reg); in gic_set_affinity()
817 writeb_relaxed(gic_cpu_map[cpu], reg); in gic_set_affinity()
818 irq_data_update_effective_affinity(d, cpumask_of(cpu)); in gic_set_affinity()
825 int cpu; in gic_ipi_send_mask() local
829 /* Only one CPU? let's do a self-IPI... */ in gic_ipi_send_mask()
830 writel_relaxed(2 << 24 | d->hwirq, in gic_ipi_send_mask()
837 /* Convert our logical CPU mask into a physical one. */ in gic_ipi_send_mask()
838 for_each_cpu(cpu, mask) in gic_ipi_send_mask()
839 map |= gic_cpu_map[cpu]; in gic_ipi_send_mask()
848 writel_relaxed(map << 16 | d->hwirq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); in gic_ipi_send_mask()
853 static int gic_starting_cpu(unsigned int cpu) in gic_starting_cpu() argument
862 .fwnode = gic_data[0].domain->fwnode, in gic_smp_init()
918 * gic_send_sgi - send a SGI directly to given CPU interface number
920 * cpu_id: the ID for the destination CPU interface
932 * gic_get_cpu_id - get the CPU interface ID for the specified CPU
934 * @cpu: the logical CPU number to get the GIC ID for.
936 * Return the CPU interface ID for the given logical CPU number,
937 * or -1 if the CPU number is too large or the interface ID is
940 int gic_get_cpu_id(unsigned int cpu) in gic_get_cpu_id() argument
944 if (cpu >= NR_GIC_CPU_IF) in gic_get_cpu_id()
945 return -1; in gic_get_cpu_id()
946 cpu_bit = gic_cpu_map[cpu]; in gic_get_cpu_id()
947 if (cpu_bit & (cpu_bit - 1)) in gic_get_cpu_id()
948 return -1; in gic_get_cpu_id()
953 * gic_migrate_target - migrate IRQs to another CPU interface
955 * @new_cpu_id: the CPU target ID to migrate IRQs to
957 * Migrate all peripheral interrupts with a target matching the current CPU
958 * to the interface corresponding to @new_cpu_id. The CPU interface mapping
959 * is also updated. Targets to other CPU interfaces are unchanged.
966 int i, ror_val, cpu = smp_processor_id(); in gic_migrate_target() local
976 cur_cpu_id = __ffs(gic_cpu_map[cpu]); in gic_migrate_target()
978 ror_val = (cur_cpu_id - new_cpu_id) & 31; in gic_migrate_target()
982 /* Update the target interface for this logical CPU */ in gic_migrate_target()
983 gic_cpu_map[cpu] = 1 << new_cpu_id; in gic_migrate_target()
987 * CPU interface and migrate them to the new CPU interface. in gic_migrate_target()
988 * We skip DIST_TARGET 0 to 7 as they are read-only. in gic_migrate_target()
990 for (i = 8; i < DIV_ROUND_UP(gic_irqs, 4); i++) { in gic_migrate_target()
991 val = readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4); in gic_migrate_target()
996 writel_relaxed(val, dist_base + GIC_DIST_TARGET + i*4); in gic_migrate_target()
1012 for (i = 0; i < 16; i += 4) { in gic_migrate_target()
1018 for (j = i; j < i + 4; j++) { in gic_migrate_target()
1028 * gic_get_sgir_physaddr - get the physical address for the SGI register
1058 struct gic_chip_data *gic = d->host_data; in gic_irq_domain_map()
1068 irq_domain_set_info(d, irq, hw, chip, d->host_data, in gic_irq_domain_map()
1072 irq_domain_set_info(d, irq, hw, chip, d->host_data, in gic_irq_domain_map()
1089 if (fwspec->param_count == 1 && fwspec->param[0] < 16) { in gic_irq_domain_translate()
1090 *hwirq = fwspec->param[0]; in gic_irq_domain_translate()
1095 if (is_of_node(fwspec->fwnode)) { in gic_irq_domain_translate()
1096 if (fwspec->param_count < 3) in gic_irq_domain_translate()
1097 return -EINVAL; in gic_irq_domain_translate()
1099 switch (fwspec->param[0]) { in gic_irq_domain_translate()
1101 *hwirq = fwspec->param[1] + 32; in gic_irq_domain_translate()
1104 *hwirq = fwspec->param[1] + 16; in gic_irq_domain_translate()
1107 return -EINVAL; in gic_irq_domain_translate()
1110 *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; in gic_irq_domain_translate()
1118 if (is_fwnode_irqchip(fwspec->fwnode)) { in gic_irq_domain_translate()
1119 if(fwspec->param_count != 2) in gic_irq_domain_translate()
1120 return -EINVAL; in gic_irq_domain_translate()
1122 if (fwspec->param[0] < 16) { in gic_irq_domain_translate()
1124 fwspec->param[0]); in gic_irq_domain_translate()
1125 return -EINVAL; in gic_irq_domain_translate()
1128 *hwirq = fwspec->param[0]; in gic_irq_domain_translate()
1129 *type = fwspec->param[1]; in gic_irq_domain_translate()
1136 return -EINVAL; in gic_irq_domain_translate()
1171 if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) { in gic_init_bases()
1172 /* Frankein-GIC without banked registers... */ in gic_init_bases()
1173 unsigned int cpu; in gic_init_bases() local
1175 gic->dist_base.percpu_base = alloc_percpu(void __iomem *); in gic_init_bases()
1176 gic->cpu_base.percpu_base = alloc_percpu(void __iomem *); in gic_init_bases()
1177 if (WARN_ON(!gic->dist_base.percpu_base || in gic_init_bases()
1178 !gic->cpu_base.percpu_base)) { in gic_init_bases()
1179 ret = -ENOMEM; in gic_init_bases()
1183 for_each_possible_cpu(cpu) { in gic_init_bases()
1184 u32 mpidr = cpu_logical_map(cpu); in gic_init_bases()
1186 unsigned long offset = gic->percpu_offset * core_id; in gic_init_bases()
1187 *per_cpu_ptr(gic->dist_base.percpu_base, cpu) = in gic_init_bases()
1188 gic->raw_dist_base + offset; in gic_init_bases()
1189 *per_cpu_ptr(gic->cpu_base.percpu_base, cpu) = in gic_init_bases()
1190 gic->raw_cpu_base + offset; in gic_init_bases()
1196 WARN(gic->percpu_offset, in gic_init_bases()
1198 gic->percpu_offset); in gic_init_bases()
1199 gic->dist_base.common_base = gic->raw_dist_base; in gic_init_bases()
1200 gic->cpu_base.common_base = gic->raw_cpu_base; in gic_init_bases()
1211 gic->gic_irqs = gic_irqs; in gic_init_bases()
1213 gic->domain = irq_domain_create_linear(handle, gic_irqs, in gic_init_bases()
1216 if (WARN_ON(!gic->domain)) { in gic_init_bases()
1217 ret = -ENODEV; in gic_init_bases()
1233 if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) { in gic_init_bases()
1234 free_percpu(gic->dist_base.percpu_base); in gic_init_bases()
1235 free_percpu(gic->cpu_base.percpu_base); in gic_init_bases()
1246 if (WARN_ON(!gic || gic->domain)) in __gic_init_bases()
1247 return -EINVAL; in __gic_init_bases()
1251 * Initialize the CPU interface map to all CPUs. in __gic_init_bases()
1252 * It will be refined as each CPU probes its ID. in __gic_init_bases()
1275 if (gic->raw_dist_base) in gic_teardown()
1276 iounmap(gic->raw_dist_base); in gic_teardown()
1277 if (gic->raw_cpu_base) in gic_teardown()
1278 iounmap(gic->raw_cpu_base); in gic_teardown()
1340 cpuif_res.end = cpuif_res.start + SZ_128K -1; in gic_check_eoimode()
1346 * Verify that we have the first 4kB of a GICv2 in gic_check_eoimode()
1361 pr_warn("GIC: Adjusting CPU interface base to %pa\n", in gic_check_eoimode()
1395 return -EINVAL; in gic_of_setup()
1397 gic->raw_dist_base = of_iomap(node, 0); in gic_of_setup()
1398 if (WARN(!gic->raw_dist_base, "unable to map gic dist registers\n")) in gic_of_setup()
1401 gic->raw_cpu_base = of_iomap(node, 1); in gic_of_setup()
1402 if (WARN(!gic->raw_cpu_base, "unable to map gic cpu registers\n")) in gic_of_setup()
1405 if (of_property_read_u32(node, "cpu-offset", &gic->percpu_offset)) in gic_of_setup()
1406 gic->percpu_offset = 0; in gic_of_setup()
1415 return -ENOMEM; in gic_of_setup()
1422 if (!dev || !dev->of_node || !gic || !irq) in gic_of_init_child()
1423 return -EINVAL; in gic_of_init_child()
1427 return -ENOMEM; in gic_of_init_child()
1429 ret = gic_of_setup(*gic, dev->of_node); in gic_of_init_child()
1433 ret = gic_init_bases(*gic, &dev->of_node->fwnode); in gic_of_init_child()
1439 irq_domain_set_pm_device((*gic)->domain, dev); in gic_of_init_child()
1476 return -ENODEV; in gic_of_init()
1479 return -EINVAL; in gic_of_init()
1489 * or the CPU interface is too small. in gic_of_init()
1491 if (gic_cnt == 0 && !gic_check_eoimode(node, &gic->raw_cpu_base)) in gic_of_init()
1494 ret = __gic_init_bases(gic, &node->fwnode); in gic_of_init()
1511 gicv2m_init(&node->fwnode, gic_data[gic_cnt].domain); in gic_of_init()
1516 IRQCHIP_DECLARE(gic_400, "arm,gic-400", gic_of_init);
1517 IRQCHIP_DECLARE(arm11mp_gic, "arm,arm11mp-gic", gic_of_init);
1518 IRQCHIP_DECLARE(arm1176jzf_dc_gic, "arm,arm1176jzf-devchip-gic", gic_of_init);
1519 IRQCHIP_DECLARE(cortex_a15_gic, "arm,cortex-a15-gic", gic_of_init);
1520 IRQCHIP_DECLARE(cortex_a9_gic, "arm,cortex-a9-gic", gic_of_init);
1521 IRQCHIP_DECLARE(cortex_a7_gic, "arm,cortex-a7-gic", gic_of_init);
1522 IRQCHIP_DECLARE(msm_8660_qgic, "qcom,msm-8660-qgic", gic_of_init);
1523 IRQCHIP_DECLARE(msm_qgic2, "qcom,msm-qgic2", gic_of_init);
1547 return -EINVAL; in gic_acpi_parse_madt_cpu()
1550 * There is no support for non-banked GICv1/2 register in ACPI spec. in gic_acpi_parse_madt_cpu()
1551 * All CPU interface addresses have to be the same. in gic_acpi_parse_madt_cpu()
1553 gic_cpu_base = processor->base_address; in gic_acpi_parse_madt_cpu()
1555 return -EINVAL; in gic_acpi_parse_madt_cpu()
1558 acpi_data.maint_irq = processor->vgic_interrupt; in gic_acpi_parse_madt_cpu()
1559 acpi_data.maint_irq_mode = (processor->flags & ACPI_MADT_VGIC_IRQ_MODE) ? in gic_acpi_parse_madt_cpu()
1561 acpi_data.vctrl_base = processor->gich_base_address; in gic_acpi_parse_madt_cpu()
1562 acpi_data.vcpu_base = processor->gicv_base_address; in gic_acpi_parse_madt_cpu()
1587 return (dist->version == ape->driver_data && in gic_validate_dist()
1588 (dist->version != ACPI_MADT_GIC_VERSION_NONE || in gic_validate_dist()
1608 vctrl_res->flags = IORESOURCE_MEM; in gic_acpi_setup_kvm_info()
1609 vctrl_res->start = acpi_data.vctrl_base; in gic_acpi_setup_kvm_info()
1610 vctrl_res->end = vctrl_res->start + ACPI_GICV2_VCTRL_MEM_SIZE - 1; in gic_acpi_setup_kvm_info()
1615 vcpu_res->flags = IORESOURCE_MEM; in gic_acpi_setup_kvm_info()
1616 vcpu_res->start = acpi_data.vcpu_base; in gic_acpi_setup_kvm_info()
1617 vcpu_res->end = vcpu_res->start + ACPI_GICV2_VCPU_MEM_SIZE - 1; in gic_acpi_setup_kvm_info()
1644 /* Collect CPU base addresses */ in gic_v2_acpi_init()
1649 return -EINVAL; in gic_v2_acpi_init()
1652 gic->raw_cpu_base = ioremap(acpi_data.cpu_phys_base, ACPI_GIC_CPU_IF_MEM_SIZE); in gic_v2_acpi_init()
1653 if (!gic->raw_cpu_base) { in gic_v2_acpi_init()
1655 return -ENOMEM; in gic_v2_acpi_init()
1659 gic->raw_dist_base = ioremap(dist->base_address, in gic_v2_acpi_init()
1661 if (!gic->raw_dist_base) { in gic_v2_acpi_init()
1664 return -ENOMEM; in gic_v2_acpi_init()
1669 * guarantees that we'll always have a GICv2, so the CPU in gic_v2_acpi_init()
1676 * Initialize GIC instance zero (no multi-GIC support). in gic_v2_acpi_init()
1678 gsi_domain_handle = irq_domain_alloc_fwnode(&dist->base_address); in gic_v2_acpi_init()
1682 return -ENOMEM; in gic_v2_acpi_init()