diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2023-02-23 15:49:31 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2023-02-23 15:49:31 +0100 |
commit | 5931e4eb55f904a4a221b57ff7d24afc0e463957 (patch) | |
tree | a6e51d12e3939d48470b75bc2bac28b337707076 /drivers | |
parent | genirq/irqdesc: Make kobj_type structures constant (diff) | |
parent | Merge tag 'irqchip-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/... (diff) | |
download | linux-5931e4eb55f904a4a221b57ff7d24afc0e463957.tar.xz linux-5931e4eb55f904a4a221b57ff7d24afc0e463957.zip |
Merge branch 'irq/core' into irq/urgent
Pull in the upstream changes so a fix for them can be applied.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/irqchip/Kconfig | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-alpine-msi.c | 9 | ||||
-rw-r--r-- | drivers/irqchip/irq-apple-aic.c | 161 | ||||
-rw-r--r-- | drivers/irqchip/irq-armada-370-xp.c | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-aspeed-scu-ic.c | 5 | ||||
-rw-r--r-- | drivers/irqchip/irq-bcm2836.c | 5 | ||||
-rw-r--r-- | drivers/irqchip/irq-bcm7120-l2.c | 3 | ||||
-rw-r--r-- | drivers/irqchip/irq-brcmstb-l2.c | 6 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v2m.c | 5 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 13 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-mbi.c | 5 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3.c | 4 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v4.c | 9 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic.c | 4 | ||||
-rw-r--r-- | drivers/irqchip/irq-loongson-liointc.c | 13 | ||||
-rw-r--r-- | drivers/irqchip/irq-loongson-pch-msi.c | 9 | ||||
-rw-r--r-- | drivers/irqchip/irq-mvebu-gicp.c | 1 | ||||
-rw-r--r-- | drivers/irqchip/irq-mvebu-odmi.c | 13 | ||||
-rw-r--r-- | drivers/irqchip/irq-ti-sci-intr.c | 1 | ||||
-rw-r--r-- | drivers/irqchip/irqchip.c | 8 |
20 files changed, 75 insertions, 205 deletions
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index caa952c40ff9..7abdb98f805d 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -389,7 +389,7 @@ config LS_EXTIRQ config LS_SCFG_MSI def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE - depends on PCI && PCI_MSI + depends on PCI_MSI config PARTITION_PERCPU bool @@ -658,6 +658,7 @@ config APPLE_AIC bool "Apple Interrupt Controller (AIC)" depends on ARM64 depends on ARCH_APPLE || COMPILE_TEST + select GENERIC_IRQ_IPI_MUX help Support for the Apple Interrupt Controller found on Apple Silicon SoCs, such as the M1. diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c index 5ddb8e578ac6..9c8b1349ee17 100644 --- a/drivers/irqchip/irq-alpine-msi.c +++ b/drivers/irqchip/irq-alpine-msi.c @@ -199,21 +199,20 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv, } gic_domain = irq_find_host(gic_node); + of_node_put(gic_node); if (!gic_domain) { pr_err("Failed to find the GIC domain\n"); return -ENXIO; } - middle_domain = irq_domain_add_tree(NULL, - &alpine_msix_middle_domain_ops, - priv); + middle_domain = irq_domain_add_hierarchy(gic_domain, 0, 0, NULL, + &alpine_msix_middle_domain_ops, + priv); if (!middle_domain) { pr_err("Failed to create the MSIX middle domain\n"); return -ENOMEM; } - middle_domain->parent = gic_domain; - msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node), &alpine_msix_domain_info, middle_domain); diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c index ae3437f03e6c..eabb3b92965b 100644 --- a/drivers/irqchip/irq-apple-aic.c +++ b/drivers/irqchip/irq-apple-aic.c @@ -292,7 +292,6 @@ struct aic_irq_chip { void __iomem *base; void __iomem *event; struct irq_domain *hw_domain; - struct irq_domain *ipi_domain; struct { cpumask_t aff; } *fiq_aff[AIC_NR_FIQ]; @@ -307,9 +306,6 @@ struct aic_irq_chip { static DEFINE_PER_CPU(uint32_t, aic_fiq_unmasked); -static DEFINE_PER_CPU(atomic_t, aic_vipi_flag); -static DEFINE_PER_CPU(atomic_t, aic_vipi_enable); - static struct aic_irq_chip *aic_irqc; static void aic_handle_ipi(struct pt_regs *regs); @@ -751,98 +747,8 @@ static void aic_ipi_send_fast(int cpu) isb(); } -static void aic_ipi_mask(struct irq_data *d) -{ - u32 irq_bit = BIT(irqd_to_hwirq(d)); - - /* No specific ordering requirements needed here. */ - atomic_andnot(irq_bit, this_cpu_ptr(&aic_vipi_enable)); -} - -static void aic_ipi_unmask(struct irq_data *d) -{ - struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d); - u32 irq_bit = BIT(irqd_to_hwirq(d)); - - atomic_or(irq_bit, this_cpu_ptr(&aic_vipi_enable)); - - /* - * The atomic_or() above must complete before the atomic_read() - * below to avoid racing aic_ipi_send_mask(). - */ - smp_mb__after_atomic(); - - /* - * If a pending vIPI was unmasked, raise a HW IPI to ourselves. - * No barriers needed here since this is a self-IPI. - */ - if (atomic_read(this_cpu_ptr(&aic_vipi_flag)) & irq_bit) { - if (static_branch_likely(&use_fast_ipi)) - aic_ipi_send_fast(smp_processor_id()); - else - aic_ic_write(ic, AIC_IPI_SEND, AIC_IPI_SEND_CPU(smp_processor_id())); - } -} - -static void aic_ipi_send_mask(struct irq_data *d, const struct cpumask *mask) -{ - struct aic_irq_chip *ic = irq_data_get_irq_chip_data(d); - u32 irq_bit = BIT(irqd_to_hwirq(d)); - u32 send = 0; - int cpu; - unsigned long pending; - - for_each_cpu(cpu, mask) { - /* - * This sequence is the mirror of the one in aic_ipi_unmask(); - * see the comment there. Additionally, release semantics - * ensure that the vIPI flag set is ordered after any shared - * memory accesses that precede it. This therefore also pairs - * with the atomic_fetch_andnot in aic_handle_ipi(). - */ - pending = atomic_fetch_or_release(irq_bit, per_cpu_ptr(&aic_vipi_flag, cpu)); - - /* - * The atomic_fetch_or_release() above must complete before the - * atomic_read() below to avoid racing aic_ipi_unmask(). - */ - smp_mb__after_atomic(); - - if (!(pending & irq_bit) && - (atomic_read(per_cpu_ptr(&aic_vipi_enable, cpu)) & irq_bit)) { - if (static_branch_likely(&use_fast_ipi)) - aic_ipi_send_fast(cpu); - else - send |= AIC_IPI_SEND_CPU(cpu); - } - } - - /* - * The flag writes must complete before the physical IPI is issued - * to another CPU. This is implied by the control dependency on - * the result of atomic_read_acquire() above, which is itself - * already ordered after the vIPI flag write. - */ - if (send) - aic_ic_write(ic, AIC_IPI_SEND, send); -} - -static struct irq_chip ipi_chip = { - .name = "AIC-IPI", - .irq_mask = aic_ipi_mask, - .irq_unmask = aic_ipi_unmask, - .ipi_send_mask = aic_ipi_send_mask, -}; - -/* - * IPI IRQ domain - */ - static void aic_handle_ipi(struct pt_regs *regs) { - int i; - unsigned long enabled, firing; - /* * Ack the IPI. We need to order this after the AIC event read, but * that is enforced by normal MMIO ordering guarantees. @@ -857,27 +763,7 @@ static void aic_handle_ipi(struct pt_regs *regs) aic_ic_write(aic_irqc, AIC_IPI_ACK, AIC_IPI_OTHER); } - /* - * The mask read does not need to be ordered. Only we can change - * our own mask anyway, so no races are possible here, as long as - * we are properly in the interrupt handler (which is covered by - * the barrier that is part of the top-level AIC handler's readl()). - */ - enabled = atomic_read(this_cpu_ptr(&aic_vipi_enable)); - - /* - * Clear the IPIs we are about to handle. This pairs with the - * atomic_fetch_or_release() in aic_ipi_send_mask(), and needs to be - * ordered after the aic_ic_write() above (to avoid dropping vIPIs) and - * before IPI handling code (to avoid races handling vIPIs before they - * are signaled). The former is taken care of by the release semantics - * of the write portion, while the latter is taken care of by the - * acquire semantics of the read portion. - */ - firing = atomic_fetch_andnot(enabled, this_cpu_ptr(&aic_vipi_flag)) & enabled; - - for_each_set_bit(i, &firing, AIC_NR_SWIPI) - generic_handle_domain_irq(aic_irqc->ipi_domain, i); + ipi_mux_process(); /* * No ordering needed here; at worst this just changes the timing of @@ -887,55 +773,24 @@ static void aic_handle_ipi(struct pt_regs *regs) aic_ic_write(aic_irqc, AIC_IPI_MASK_CLR, AIC_IPI_OTHER); } -static int aic_ipi_alloc(struct irq_domain *d, unsigned int virq, - unsigned int nr_irqs, void *args) +static void aic_ipi_send_single(unsigned int cpu) { - int i; - - for (i = 0; i < nr_irqs; i++) { - irq_set_percpu_devid(virq + i); - irq_domain_set_info(d, virq + i, i, &ipi_chip, d->host_data, - handle_percpu_devid_irq, NULL, NULL); - } - - return 0; -} - -static void aic_ipi_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs) -{ - /* Not freeing IPIs */ + if (static_branch_likely(&use_fast_ipi)) + aic_ipi_send_fast(cpu); + else + aic_ic_write(aic_irqc, AIC_IPI_SEND, AIC_IPI_SEND_CPU(cpu)); } -static const struct irq_domain_ops aic_ipi_domain_ops = { - .alloc = aic_ipi_alloc, - .free = aic_ipi_free, -}; - static int __init aic_init_smp(struct aic_irq_chip *irqc, struct device_node *node) { - struct irq_domain *ipi_domain; int base_ipi; - ipi_domain = irq_domain_create_linear(irqc->hw_domain->fwnode, AIC_NR_SWIPI, - &aic_ipi_domain_ops, irqc); - if (WARN_ON(!ipi_domain)) - return -ENODEV; - - ipi_domain->flags |= IRQ_DOMAIN_FLAG_IPI_SINGLE; - irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI); - - base_ipi = __irq_domain_alloc_irqs(ipi_domain, -1, AIC_NR_SWIPI, - NUMA_NO_NODE, NULL, false, NULL); - - if (WARN_ON(!base_ipi)) { - irq_domain_remove(ipi_domain); + base_ipi = ipi_mux_create(AIC_NR_SWIPI, aic_ipi_send_single); + if (WARN_ON(base_ipi <= 0)) return -ENODEV; - } set_smp_ipi_range(base_ipi, AIC_NR_SWIPI); - irqc->ipi_domain = ipi_domain; - return 0; } diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index ee18eb3e72b7..a55528469278 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -454,8 +454,7 @@ static __init void armada_xp_ipi_init(struct device_node *node) return; irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI); - base_ipi = __irq_domain_alloc_irqs(ipi_domain, -1, IPI_DOORBELL_END, - NUMA_NO_NODE, NULL, false, NULL); + base_ipi = irq_domain_alloc_irqs(ipi_domain, IPI_DOORBELL_END, NUMA_NO_NODE, NULL); if (WARN_ON(!base_ipi)) return; diff --git a/drivers/irqchip/irq-aspeed-scu-ic.c b/drivers/irqchip/irq-aspeed-scu-ic.c index 279e92cf0b16..94a7223e95df 100644 --- a/drivers/irqchip/irq-aspeed-scu-ic.c +++ b/drivers/irqchip/irq-aspeed-scu-ic.c @@ -17,8 +17,9 @@ #define ASPEED_SCU_IC_REG 0x018 #define ASPEED_SCU_IC_SHIFT 0 -#define ASPEED_SCU_IC_ENABLE GENMASK(6, ASPEED_SCU_IC_SHIFT) +#define ASPEED_SCU_IC_ENABLE GENMASK(15, ASPEED_SCU_IC_SHIFT) #define ASPEED_SCU_IC_NUM_IRQS 7 +#define ASPEED_SCU_IC_STATUS GENMASK(28, 16) #define ASPEED_SCU_IC_STATUS_SHIFT 16 #define ASPEED_AST2600_SCU_IC0_REG 0x560 @@ -155,6 +156,8 @@ static int aspeed_scu_ic_of_init_common(struct aspeed_scu_ic *scu_ic, rc = PTR_ERR(scu_ic->scu); goto err; } + regmap_write_bits(scu_ic->scu, scu_ic->reg, ASPEED_SCU_IC_STATUS, ASPEED_SCU_IC_STATUS); + regmap_write_bits(scu_ic->scu, scu_ic->reg, ASPEED_SCU_IC_ENABLE, 0); irq = irq_of_parse_and_map(node, 0); if (!irq) { diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c index 51491c3c6fdd..e5f1059b989f 100644 --- a/drivers/irqchip/irq-bcm2836.c +++ b/drivers/irqchip/irq-bcm2836.c @@ -268,10 +268,7 @@ static void __init bcm2836_arm_irqchip_smp_init(void) ipi_domain->flags |= IRQ_DOMAIN_FLAG_IPI_SINGLE; irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI); - base_ipi = __irq_domain_alloc_irqs(ipi_domain, -1, BITS_PER_MBOX, - NUMA_NO_NODE, NULL, - false, NULL); - + base_ipi = irq_domain_alloc_irqs(ipi_domain, BITS_PER_MBOX, NUMA_NO_NODE, NULL); if (WARN_ON(!base_ipi)) return; diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index bb6609cebdbc..1e9dab6e0d86 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c @@ -279,7 +279,8 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, flags |= IRQ_GC_BE_IO; ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1, - dn->full_name, handle_level_irq, clr, 0, flags); + dn->full_name, handle_level_irq, clr, + IRQ_LEVEL, flags); if (ret) { pr_err("failed to allocate generic irq chip\n"); goto out_free_domain; diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index e4efc08ac594..091b0fe7e324 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -161,6 +161,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, *init_params) { unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; struct brcmstb_l2_intc_data *data; struct irq_chip_type *ct; int ret; @@ -208,9 +209,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) flags |= IRQ_GC_BE_IO; + if (init_params->handler == handle_level_irq) + set |= IRQ_LEVEL; + /* Allocate a single Generic IRQ chip for this node */ ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, - np->full_name, init_params->handler, clr, 0, flags); + np->full_name, init_params->handler, clr, set, flags); if (ret) { pr_err("failed to allocate generic irq chip\n"); goto out_free_domain; diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index f4d7eeb13951..f1e75b35a52a 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -287,15 +287,14 @@ static __init int gicv2m_allocate_domains(struct irq_domain *parent) if (!v2m) return 0; - inner_domain = irq_domain_create_tree(v2m->fwnode, - &gicv2m_domain_ops, v2m); + inner_domain = irq_domain_create_hierarchy(parent, 0, 0, v2m->fwnode, + &gicv2m_domain_ops, v2m); if (!inner_domain) { pr_err("Failed to create GICv2m domain\n"); return -ENOMEM; } irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS); - inner_domain->parent = parent; pci_domain = pci_msi_create_irq_domain(v2m->fwnode, &gicv2m_msi_domain_info, inner_domain); diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 973ede0197e3..5634d29b644d 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -4909,18 +4909,19 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its) if (!info) return -ENOMEM; - inner_domain = irq_domain_create_tree(handle, &its_domain_ops, its); + info->ops = &its_msi_domain_ops; + info->data = its; + + inner_domain = irq_domain_create_hierarchy(its_parent, + its->msi_domain_flags, 0, + handle, &its_domain_ops, + info); if (!inner_domain) { kfree(info); return -ENOMEM; } - inner_domain->parent = its_parent; irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS); - inner_domain->flags |= its->msi_domain_flags; - info->ops = &its_msi_domain_ops; - info->data = its; - inner_domain->host_data = info; return 0; } diff --git a/drivers/irqchip/irq-gic-v3-mbi.c b/drivers/irqchip/irq-gic-v3-mbi.c index e1efdec9e9ac..dbb8b1efda44 100644 --- a/drivers/irqchip/irq-gic-v3-mbi.c +++ b/drivers/irqchip/irq-gic-v3-mbi.c @@ -233,13 +233,12 @@ static int mbi_allocate_domains(struct irq_domain *parent) struct irq_domain *nexus_domain, *pci_domain, *plat_domain; int err; - nexus_domain = irq_domain_create_tree(parent->fwnode, - &mbi_domain_ops, NULL); + nexus_domain = irq_domain_create_hierarchy(parent, 0, 0, parent->fwnode, + &mbi_domain_ops, NULL); if (!nexus_domain) return -ENOMEM; irq_domain_update_bus_token(nexus_domain, DOMAIN_BUS_NEXUS); - nexus_domain->parent = parent; err = mbi_allocate_pci_domain(nexus_domain, &pci_domain); diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 997104d4338e..bb57ab8bff6a 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1310,9 +1310,7 @@ static void __init gic_smp_init(void) gic_starting_cpu, NULL); /* Register all 8 non-secure SGIs */ - base_sgi = __irq_domain_alloc_irqs(gic_data.domain, -1, 8, - NUMA_NO_NODE, &sgi_fwspec, - false, NULL); + base_sgi = irq_domain_alloc_irqs(gic_data.domain, 8, NUMA_NO_NODE, &sgi_fwspec); if (WARN_ON(base_sgi <= 0)) return; diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c index a6277dea4c7a..94d56a03b175 100644 --- a/drivers/irqchip/irq-gic-v4.c +++ b/drivers/irqchip/irq-gic-v4.c @@ -139,9 +139,7 @@ static int its_alloc_vcpu_sgis(struct its_vpe *vpe, int idx) if (!vpe->sgi_domain) goto err; - sgi_base = __irq_domain_alloc_irqs(vpe->sgi_domain, -1, 16, - NUMA_NO_NODE, vpe, - false, NULL); + sgi_base = irq_domain_alloc_irqs(vpe->sgi_domain, 16, NUMA_NO_NODE, vpe); if (sgi_base <= 0) goto err; @@ -176,9 +174,8 @@ int its_alloc_vcpu_irqs(struct its_vm *vm) vm->vpes[i]->idai = true; } - vpe_base_irq = __irq_domain_alloc_irqs(vm->domain, -1, vm->nr_vpes, - NUMA_NO_NODE, vm, - false, NULL); + vpe_base_irq = irq_domain_alloc_irqs(vm->domain, vm->nr_vpes, + NUMA_NO_NODE, vm); if (vpe_base_irq <= 0) goto err; diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 210bc2f4d555..4fa4d8ac76d9 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -868,9 +868,7 @@ static __init void gic_smp_init(void) "irqchip/arm/gic:starting", gic_starting_cpu, NULL); - base_sgi = __irq_domain_alloc_irqs(gic_data[0].domain, -1, 8, - NUMA_NO_NODE, &sgi_fwspec, - false, NULL); + base_sgi = irq_domain_alloc_irqs(gic_data[0].domain, 8, NUMA_NO_NODE, &sgi_fwspec); if (WARN_ON(base_sgi <= 0)) return; diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c index 85b754f7f4e6..8d00a9ad5b00 100644 --- a/drivers/irqchip/irq-loongson-liointc.c +++ b/drivers/irqchip/irq-loongson-liointc.c @@ -55,6 +55,8 @@ struct liointc_priv { struct liointc_handler_data handler[LIOINTC_NUM_PARENT]; void __iomem *core_isr[LIOINTC_NUM_CORES]; u8 map_cache[LIOINTC_CHIP_IRQ]; + u32 int_pol; + u32 int_edge; bool has_lpc_irq_errata; }; @@ -138,6 +140,14 @@ static int liointc_set_type(struct irq_data *data, unsigned int type) return 0; } +static void liointc_suspend(struct irq_chip_generic *gc) +{ + struct liointc_priv *priv = gc->private; + + priv->int_pol = readl(gc->reg_base + LIOINTC_REG_INTC_POL); + priv->int_edge = readl(gc->reg_base + LIOINTC_REG_INTC_EDGE); +} + static void liointc_resume(struct irq_chip_generic *gc) { struct liointc_priv *priv = gc->private; @@ -150,6 +160,8 @@ static void liointc_resume(struct irq_chip_generic *gc) /* Restore map cache */ for (i = 0; i < LIOINTC_CHIP_IRQ; i++) writeb(priv->map_cache[i], gc->reg_base + i); + writel(priv->int_pol, gc->reg_base + LIOINTC_REG_INTC_POL); + writel(priv->int_edge, gc->reg_base + LIOINTC_REG_INTC_EDGE); /* Restore mask cache */ writel(gc->mask_cache, gc->reg_base + LIOINTC_REG_INTC_ENABLE); irq_gc_unlock_irqrestore(gc, flags); @@ -269,6 +281,7 @@ static int liointc_init(phys_addr_t addr, unsigned long size, int revision, gc->private = priv; gc->reg_base = base; gc->domain = domain; + gc->suspend = liointc_suspend; gc->resume = liointc_resume; ct = gc->chip_types; diff --git a/drivers/irqchip/irq-loongson-pch-msi.c b/drivers/irqchip/irq-loongson-pch-msi.c index a72ede90ffc6..6e1e1f011bb2 100644 --- a/drivers/irqchip/irq-loongson-pch-msi.c +++ b/drivers/irqchip/irq-loongson-pch-msi.c @@ -163,16 +163,15 @@ static int pch_msi_init_domains(struct pch_msi_data *priv, { struct irq_domain *middle_domain, *msi_domain; - middle_domain = irq_domain_create_linear(domain_handle, - priv->num_irqs, - &pch_msi_middle_domain_ops, - priv); + middle_domain = irq_domain_create_hierarchy(parent, 0, priv->num_irqs, + domain_handle, + &pch_msi_middle_domain_ops, + priv); if (!middle_domain) { pr_err("Failed to create the MSI middle domain\n"); return -ENOMEM; } - middle_domain->parent = parent; irq_domain_update_bus_token(middle_domain, DOMAIN_BUS_NEXUS); msi_domain = pci_msi_create_irq_domain(domain_handle, diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c index fe88a782173d..c43a345061d5 100644 --- a/drivers/irqchip/irq-mvebu-gicp.c +++ b/drivers/irqchip/irq-mvebu-gicp.c @@ -221,6 +221,7 @@ static int mvebu_gicp_probe(struct platform_device *pdev) } parent_domain = irq_find_host(irq_parent_dn); + of_node_put(irq_parent_dn); if (!parent_domain) { dev_err(&pdev->dev, "failed to find parent IRQ domain\n"); return -ENODEV; diff --git a/drivers/irqchip/irq-mvebu-odmi.c b/drivers/irqchip/irq-mvebu-odmi.c index dc4145abdd6f..108091533e10 100644 --- a/drivers/irqchip/irq-mvebu-odmi.c +++ b/drivers/irqchip/irq-mvebu-odmi.c @@ -161,7 +161,7 @@ static struct msi_domain_info odmi_msi_domain_info = { static int __init mvebu_odmi_init(struct device_node *node, struct device_node *parent) { - struct irq_domain *inner_domain, *plat_domain; + struct irq_domain *parent_domain, *inner_domain, *plat_domain; int ret, i; if (of_property_read_u32(node, "marvell,odmi-frames", &odmis_count)) @@ -197,16 +197,17 @@ static int __init mvebu_odmi_init(struct device_node *node, } } - inner_domain = irq_domain_create_linear(of_node_to_fwnode(node), - odmis_count * NODMIS_PER_FRAME, - &odmi_domain_ops, NULL); + parent_domain = irq_find_host(parent); + + inner_domain = irq_domain_create_hierarchy(parent_domain, 0, + odmis_count * NODMIS_PER_FRAME, + of_node_to_fwnode(node), + &odmi_domain_ops, NULL); if (!inner_domain) { ret = -ENOMEM; goto err_unmap; } - inner_domain->parent = irq_find_host(parent); - plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node), &odmi_msi_domain_info, inner_domain); diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c index fe8fad22bcf9..020ddf29efb8 100644 --- a/drivers/irqchip/irq-ti-sci-intr.c +++ b/drivers/irqchip/irq-ti-sci-intr.c @@ -236,6 +236,7 @@ static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev) } parent_domain = irq_find_host(parent_node); + of_node_put(parent_node); if (!parent_domain) { dev_err(dev, "Failed to find IRQ parent domain\n"); return -ENODEV; diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c index 3570f0a588c4..7899607fbee8 100644 --- a/drivers/irqchip/irqchip.c +++ b/drivers/irqchip/irqchip.c @@ -38,8 +38,10 @@ int platform_irqchip_probe(struct platform_device *pdev) struct device_node *par_np = of_irq_find_parent(np); of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); - if (!irq_init_cb) + if (!irq_init_cb) { + of_node_put(par_np); return -EINVAL; + } if (par_np == np) par_np = NULL; @@ -52,8 +54,10 @@ int platform_irqchip_probe(struct platform_device *pdev) * interrupt controller. The actual initialization callback of this * interrupt controller can check for specific domains as necessary. */ - if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) + if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { + of_node_put(par_np); return -EPROBE_DEFER; + } return irq_init_cb(np, par_np); } |