diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-01 12:48:15 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-01 12:48:15 -0700 |
commit | 9de1f9c8ca5100a02a2e271bdbde36202e251b4b (patch) | |
tree | 52337259385cbc1da4a84561e2fdc5e657c0906a /arch/loongarch/kernel | |
parent | dfea84827f7eb49ca41d837d92ac1cbd5353a742 (diff) | |
parent | 779fda86bdeb86bad6daa4f0ecf37788dfc26f6c (diff) | |
download | linux-9de1f9c8ca5100a02a2e271bdbde36202e251b4b.tar.bz2 |
Merge tag 'irq-core-2022-08-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"Updates for interrupt core and drivers:
Core:
- Fix a few inconsistencies between UP and SMP vs interrupt
affinities
- Small updates and cleanups all over the place
New drivers:
- LoongArch interrupt controller
- Renesas RZ/G2L interrupt controller
Updates:
- Hotpath optimization for SiFive PLIC
- Workaround for broken PLIC edge triggered interrupts
- Simall cleanups and improvements as usual"
* tag 'irq-core-2022-08-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (52 commits)
irqchip/mmp: Declare init functions in common header file
irqchip/mips-gic: Check the return value of ioremap() in gic_of_init()
genirq: Use for_each_action_of_desc in actions_show()
irqchip / ACPI: Introduce ACPI_IRQ_MODEL_LPIC for LoongArch
irqchip: Add LoongArch CPU interrupt controller support
irqchip: Add Loongson Extended I/O interrupt controller support
irqchip/loongson-liointc: Add ACPI init support
irqchip/loongson-pch-msi: Add ACPI init support
irqchip/loongson-pch-pic: Add ACPI init support
irqchip: Add Loongson PCH LPC controller support
LoongArch: Prepare to support multiple pch-pic and pch-msi irqdomain
LoongArch: Use ACPI_GENERIC_GSI for gsi handling
genirq/generic_chip: Export irq_unmap_generic_chip
ACPI: irq: Allow acpi_gsi_to_irq() to have an arch-specific fallback
APCI: irq: Add support for multiple GSI domains
LoongArch: Provisionally add ACPICA data structures
irqdomain: Use hwirq_max instead of revmap_size for NOMAP domains
irqdomain: Report irq number for NOMAP domains
irqchip/gic-v3: Fix comment typo
dt-bindings: interrupt-controller: renesas,rzg2l-irqc: Document RZ/V2L SoC
...
Diffstat (limited to 'arch/loongarch/kernel')
-rw-r--r-- | arch/loongarch/kernel/acpi.c | 65 | ||||
-rw-r--r-- | arch/loongarch/kernel/irq.c | 58 | ||||
-rw-r--r-- | arch/loongarch/kernel/time.c | 14 |
3 files changed, 64 insertions, 73 deletions
diff --git a/arch/loongarch/kernel/acpi.c b/arch/loongarch/kernel/acpi.c index bb729ee8a237..03aa14581d0a 100644 --- a/arch/loongarch/kernel/acpi.c +++ b/arch/loongarch/kernel/acpi.c @@ -25,7 +25,6 @@ EXPORT_SYMBOL(acpi_pci_disabled); int acpi_strict = 1; /* We have no workarounds on LoongArch */ int num_processors; int disabled_cpus; -enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM; u64 acpi_saved_sp; @@ -33,70 +32,6 @@ u64 acpi_saved_sp; #define PREFIX "ACPI: " -int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) -{ - if (irqp != NULL) - *irqp = acpi_register_gsi(NULL, gsi, -1, -1); - return (*irqp >= 0) ? 0 : -EINVAL; -} -EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); - -int acpi_isa_irq_to_gsi(unsigned int isa_irq, u32 *gsi) -{ - if (gsi) - *gsi = isa_irq; - return 0; -} - -/* - * success: return IRQ number (>=0) - * failure: return < 0 - */ -int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) -{ - struct irq_fwspec fwspec; - - switch (gsi) { - case GSI_MIN_CPU_IRQ ... GSI_MAX_CPU_IRQ: - fwspec.fwnode = liointc_domain->fwnode; - fwspec.param[0] = gsi - GSI_MIN_CPU_IRQ; - fwspec.param_count = 1; - - return irq_create_fwspec_mapping(&fwspec); - - case GSI_MIN_LPC_IRQ ... GSI_MAX_LPC_IRQ: - if (!pch_lpc_domain) - return -EINVAL; - - fwspec.fwnode = pch_lpc_domain->fwnode; - fwspec.param[0] = gsi - GSI_MIN_LPC_IRQ; - fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); - fwspec.param_count = 2; - - return irq_create_fwspec_mapping(&fwspec); - - case GSI_MIN_PCH_IRQ ... GSI_MAX_PCH_IRQ: - if (!pch_pic_domain[0]) - return -EINVAL; - - fwspec.fwnode = pch_pic_domain[0]->fwnode; - fwspec.param[0] = gsi - GSI_MIN_PCH_IRQ; - fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH; - fwspec.param_count = 2; - - return irq_create_fwspec_mapping(&fwspec); - } - - return -EINVAL; -} -EXPORT_SYMBOL_GPL(acpi_register_gsi); - -void acpi_unregister_gsi(u32 gsi) -{ - -} -EXPORT_SYMBOL_GPL(acpi_unregister_gsi); - void __init __iomem * __acpi_map_table(unsigned long phys, unsigned long size) { diff --git a/arch/loongarch/kernel/irq.c b/arch/loongarch/kernel/irq.c index b34b8d792aa4..1ba19c76563e 100644 --- a/arch/loongarch/kernel/irq.c +++ b/arch/loongarch/kernel/irq.c @@ -25,12 +25,8 @@ DEFINE_PER_CPU(unsigned long, irq_stack); DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); EXPORT_PER_CPU_SYMBOL(irq_stat); -struct irq_domain *cpu_domain; -struct irq_domain *liointc_domain; -struct irq_domain *pch_lpc_domain; -struct irq_domain *pch_msi_domain[MAX_IO_PICS]; -struct irq_domain *pch_pic_domain[MAX_IO_PICS]; - +struct acpi_vector_group pch_group[MAX_IO_PICS]; +struct acpi_vector_group msi_group[MAX_IO_PICS]; /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. @@ -56,6 +52,51 @@ int arch_show_interrupts(struct seq_file *p, int prec) return 0; } +static int __init early_pci_mcfg_parse(struct acpi_table_header *header) +{ + struct acpi_table_mcfg *mcfg; + struct acpi_mcfg_allocation *mptr; + int i, n; + + if (header->length < sizeof(struct acpi_table_mcfg)) + return -EINVAL; + + n = (header->length - sizeof(struct acpi_table_mcfg)) / + sizeof(struct acpi_mcfg_allocation); + mcfg = (struct acpi_table_mcfg *)header; + mptr = (struct acpi_mcfg_allocation *) &mcfg[1]; + + for (i = 0; i < n; i++, mptr++) { + msi_group[i].pci_segment = mptr->pci_segment; + pch_group[i].node = msi_group[i].node = (mptr->address >> 44) & 0xf; + } + + return 0; +} + +static void __init init_vec_parent_group(void) +{ + int i; + + for (i = 0; i < MAX_IO_PICS; i++) { + msi_group[i].pci_segment = -1; + msi_group[i].node = -1; + pch_group[i].node = -1; + } + + acpi_table_parse(ACPI_SIG_MCFG, early_pci_mcfg_parse); +} + +static int __init get_ipi_irq(void) +{ + struct irq_domain *d = irq_find_matching_fwnode(cpuintc_handle, DOMAIN_BUS_ANY); + + if (d) + return irq_create_mapping(d, EXCCODE_IPI - EXCCODE_INT_START); + + return -EINVAL; +} + void __init init_IRQ(void) { int i; @@ -69,9 +110,12 @@ void __init init_IRQ(void) clear_csr_ecfg(ECFG0_IM); clear_csr_estat(ESTATF_IP); + init_vec_parent_group(); irqchip_init(); #ifdef CONFIG_SMP - ipi_irq = EXCCODE_IPI - EXCCODE_INT_START; + ipi_irq = get_ipi_irq(); + if (ipi_irq < 0) + panic("IPI IRQ mapping failed\n"); irq_set_percpu_devid(ipi_irq); r = request_percpu_irq(ipi_irq, loongson3_ipi_interrupt, "IPI", &ipi_dummy_dev); if (r < 0) diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c index fe6823875895..79dc5eddf504 100644 --- a/arch/loongarch/kernel/time.c +++ b/arch/loongarch/kernel/time.c @@ -123,6 +123,16 @@ void sync_counter(void) csr_write64(-init_timeval, LOONGARCH_CSR_CNTC); } +static int get_timer_irq(void) +{ + struct irq_domain *d = irq_find_matching_fwnode(cpuintc_handle, DOMAIN_BUS_ANY); + + if (d) + return irq_create_mapping(d, EXCCODE_TIMER - EXCCODE_INT_START); + + return -EINVAL; +} + int constant_clockevent_init(void) { unsigned int irq; @@ -132,7 +142,9 @@ int constant_clockevent_init(void) struct clock_event_device *cd; static int timer_irq_installed = 0; - irq = EXCCODE_TIMER - EXCCODE_INT_START; + irq = get_timer_irq(); + if (irq < 0) + pr_err("Failed to map irq %d (timer)\n", irq); cd = &per_cpu(constant_clockevent_device, cpu); |