summaryrefslogtreecommitdiff
path: root/drivers/irqchip
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/Kconfig9
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/exynos-combiner.c2
-rw-r--r--drivers/irqchip/irq-al-fic.c20
-rw-r--r--drivers/irqchip/irq-alpine-msi.c7
-rw-r--r--drivers/irqchip/irq-apple-aic.c4
-rw-r--r--drivers/irqchip/irq-armada-370-xp.c12
-rw-r--r--drivers/irqchip/irq-aspeed-i2c-ic.c2
-rw-r--r--drivers/irqchip/irq-aspeed-intc.c2
-rw-r--r--drivers/irqchip/irq-aspeed-scu-ic.c2
-rw-r--r--drivers/irqchip/irq-aspeed-vic.c4
-rw-r--r--drivers/irqchip/irq-ath79-misc.c4
-rw-r--r--drivers/irqchip/irq-atmel-aic-common.c2
-rw-r--r--drivers/irqchip/irq-atmel-aic.c19
-rw-r--r--drivers/irqchip/irq-atmel-aic5.c28
-rw-r--r--drivers/irqchip/irq-bcm2712-mip.c7
-rw-r--r--drivers/irqchip/irq-bcm2835.c2
-rw-r--r--drivers/irqchip/irq-bcm2836.c2
-rw-r--r--drivers/irqchip/irq-bcm6345-l1.c2
-rw-r--r--drivers/irqchip/irq-bcm7038-l1.c2
-rw-r--r--drivers/irqchip/irq-bcm7120-l2.c24
-rw-r--r--drivers/irqchip/irq-brcmstb-l2.c10
-rw-r--r--drivers/irqchip/irq-clps711x.c4
-rw-r--r--drivers/irqchip/irq-crossbar.c6
-rw-r--r--drivers/irqchip/irq-csky-apb-intc.c5
-rw-r--r--drivers/irqchip/irq-csky-mpintc.c2
-rw-r--r--drivers/irqchip/irq-davinci-cp-intc.c6
-rw-r--r--drivers/irqchip/irq-digicolor.c2
-rw-r--r--drivers/irqchip/irq-dw-apb-ictl.c5
-rw-r--r--drivers/irqchip/irq-econet-en751221.c310
-rw-r--r--drivers/irqchip/irq-ftintc010.c5
-rw-r--r--drivers/irqchip/irq-gic-v2m.c22
-rw-r--r--drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c2
-rw-r--r--drivers/irqchip/irq-gic-v3-its-msi-parent.c41
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c76
-rw-r--r--drivers/irqchip/irq-gic-v3-mbi.c20
-rw-r--r--drivers/irqchip/irq-gic-v3.c4
-rw-r--r--drivers/irqchip/irq-goldfish-pic.c7
-rw-r--r--drivers/irqchip/irq-hip04.c6
-rw-r--r--drivers/irqchip/irq-i8259.c4
-rw-r--r--drivers/irqchip/irq-idt3243x.c2
-rw-r--r--drivers/irqchip/irq-imgpdc.c2
-rw-r--r--drivers/irqchip/irq-imx-gpcv2.c4
-rw-r--r--drivers/irqchip/irq-imx-intmux.c2
-rw-r--r--drivers/irqchip/irq-imx-irqsteer.c2
-rw-r--r--drivers/irqchip/irq-imx-mu-msi.c2
-rw-r--r--drivers/irqchip/irq-ingenic-tcu.c13
-rw-r--r--drivers/irqchip/irq-ingenic.c4
-rw-r--r--drivers/irqchip/irq-ixp4xx.c2
-rw-r--r--drivers/irqchip/irq-jcore-aic.c5
-rw-r--r--drivers/irqchip/irq-keystone.c4
-rw-r--r--drivers/irqchip/irq-lan966x-oic.c20
-rw-r--r--drivers/irqchip/irq-loongarch-avec.c2
-rw-r--r--drivers/irqchip/irq-loongarch-cpu.c2
-rw-r--r--drivers/irqchip/irq-loongson-eiointc.c2
-rw-r--r--drivers/irqchip/irq-loongson-htvec.c2
-rw-r--r--drivers/irqchip/irq-loongson-liointc.c11
-rw-r--r--drivers/irqchip/irq-loongson-pch-msi.c4
-rw-r--r--drivers/irqchip/irq-loongson-pch-pic.c2
-rw-r--r--drivers/irqchip/irq-lpc32xx.c4
-rw-r--r--drivers/irqchip/irq-ls-extirq.c4
-rw-r--r--drivers/irqchip/irq-ls-scfg-msi.c10
-rw-r--r--drivers/irqchip/irq-ls1x.c4
-rw-r--r--drivers/irqchip/irq-mchp-eic.c5
-rw-r--r--drivers/irqchip/irq-meson-gpio.c2
-rw-r--r--drivers/irqchip/irq-mips-cpu.c13
-rw-r--r--drivers/irqchip/irq-mips-gic.c15
-rw-r--r--drivers/irqchip/irq-mmp.c12
-rw-r--r--drivers/irqchip/irq-mscc-ocelot.c7
-rw-r--r--drivers/irqchip/irq-msi-lib.c9
-rw-r--r--drivers/irqchip/irq-msi-lib.h27
-rw-r--r--drivers/irqchip/irq-mst-intc.c4
-rw-r--r--drivers/irqchip/irq-mtk-cirq.c5
-rw-r--r--drivers/irqchip/irq-mtk-sysirq.c4
-rw-r--r--drivers/irqchip/irq-mvebu-gicp.c28
-rw-r--r--drivers/irqchip/irq-mvebu-icu.c2
-rw-r--r--drivers/irqchip/irq-mvebu-odmi.c29
-rw-r--r--drivers/irqchip/irq-mvebu-pic.c4
-rw-r--r--drivers/irqchip/irq-mvebu-sei.c24
-rw-r--r--drivers/irqchip/irq-mxs.c4
-rw-r--r--drivers/irqchip/irq-nvic.c2
-rw-r--r--drivers/irqchip/irq-omap-intc.c4
-rw-r--r--drivers/irqchip/irq-or1k-pic.c4
-rw-r--r--drivers/irqchip/irq-orion.c6
-rw-r--r--drivers/irqchip/irq-owl-sirq.c4
-rw-r--r--drivers/irqchip/irq-pic32-evic.c6
-rw-r--r--drivers/irqchip/irq-pruss-intc.c7
-rw-r--r--drivers/irqchip/irq-qcom-mpm.c5
-rw-r--r--drivers/irqchip/irq-realtek-rtl.c2
-rw-r--r--drivers/irqchip/irq-renesas-intc-irqpin.c6
-rw-r--r--drivers/irqchip/irq-renesas-irqc.c4
-rw-r--r--drivers/irqchip/irq-renesas-rza1.c6
-rw-r--r--drivers/irqchip/irq-renesas-rzg2l.c6
-rw-r--r--drivers/irqchip/irq-renesas-rzv2h.c13
-rw-r--r--drivers/irqchip/irq-riscv-imsic-platform.c2
-rw-r--r--drivers/irqchip/irq-riscv-imsic-state.c10
-rw-r--r--drivers/irqchip/irq-riscv-intc.c2
-rw-r--r--drivers/irqchip/irq-sa11x0.c2
-rw-r--r--drivers/irqchip/irq-sg2042-msi.c155
-rw-r--r--drivers/irqchip/irq-sni-exiu.c6
-rw-r--r--drivers/irqchip/irq-sp7021-intc.c4
-rw-r--r--drivers/irqchip/irq-starfive-jh8100-intc.c4
-rw-r--r--drivers/irqchip/irq-stm32-exti.c25
-rw-r--r--drivers/irqchip/irq-stm32mp-exti.c9
-rw-r--r--drivers/irqchip/irq-sun4i.c2
-rw-r--r--drivers/irqchip/irq-sun6i-r.c4
-rw-r--r--drivers/irqchip/irq-sunxi-nmi.c11
-rw-r--r--drivers/irqchip/irq-tb10x.c21
-rw-r--r--drivers/irqchip/irq-tegra.c5
-rw-r--r--drivers/irqchip/irq-ti-sci-inta.c10
-rw-r--r--drivers/irqchip/irq-ti-sci-intr.c7
-rw-r--r--drivers/irqchip/irq-ts4800.c2
-rw-r--r--drivers/irqchip/irq-uniphier-aidet.c2
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c4
-rw-r--r--drivers/irqchip/irq-vf610-mscm-ir.c6
-rw-r--r--drivers/irqchip/irq-vic.c5
-rw-r--r--drivers/irqchip/irq-vt8500.c153
-rw-r--r--drivers/irqchip/irq-wpcm450-aic.c2
-rw-r--r--drivers/irqchip/irq-xilinx-intc.c4
-rw-r--r--drivers/irqchip/irq-xtensa-mx.c5
-rw-r--r--drivers/irqchip/irq-xtensa-pic.c4
-rw-r--r--drivers/irqchip/irq-zevio.c4
-rw-r--r--drivers/irqchip/spear-shirq.c2
123 files changed, 925 insertions, 619 deletions
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index cec05e443083..0d196e447142 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -114,8 +114,8 @@ config I8259
config BCM2712_MIP
tristate "Broadcom BCM2712 MSI-X Interrupt Peripheral support"
- depends on ARCH_BRCMSTB || COMPILE_TEST
- default m if ARCH_BRCMSTB
+ depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
+ default m if ARCH_BRCMSTB || ARCH_BCM2835
depends on ARM_GIC
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN_HIERARCHY
@@ -166,6 +166,11 @@ config DW_APB_ICTL
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN_HIERARCHY
+config ECONET_EN751221_INTC
+ bool
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+
config FARADAY_FTINTC010
bool
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 365bcea9a61f..23ca4959e6ce 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
obj-$(CONFIG_ARCH_ACTIONS) += irq-owl-sirq.o
obj-$(CONFIG_DAVINCI_CP_INTC) += irq-davinci-cp-intc.o
obj-$(CONFIG_EXYNOS_IRQ_COMBINER) += exynos-combiner.o
+obj-$(CONFIG_ECONET_EN751221_INTC) += irq-econet-en751221.o
obj-$(CONFIG_FARADAY_FTINTC010) += irq-ftintc010.o
obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o
obj-$(CONFIG_ARCH_LPC32XX) += irq-lpc32xx.o
diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index 552aa04ff063..e7dfcf0cda43 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -180,7 +180,7 @@ static void __init combiner_init(void __iomem *combiner_base,
if (!combiner_data)
return;
- combiner_irq_domain = irq_domain_add_linear(np, nr_irq,
+ combiner_irq_domain = irq_domain_create_linear(of_fwnode_handle(np), nr_irq,
&combiner_irq_domain_ops, combiner_data);
if (WARN_ON(!combiner_irq_domain)) {
pr_warn("%s: irq domain init failed\n", __func__);
diff --git a/drivers/irqchip/irq-al-fic.c b/drivers/irqchip/irq-al-fic.c
index dfb761e86c9c..8f300843bbca 100644
--- a/drivers/irqchip/irq-al-fic.c
+++ b/drivers/irqchip/irq-al-fic.c
@@ -65,15 +65,13 @@ static int al_fic_irq_set_type(struct irq_data *data, unsigned int flow_type)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
struct al_fic *fic = gc->private;
enum al_fic_state new_state;
- int ret = 0;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
if (((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_HIGH) &&
((flow_type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_EDGE_RISING)) {
pr_debug("fic doesn't support flow type %d\n", flow_type);
- ret = -EINVAL;
- goto err;
+ return -EINVAL;
}
new_state = (flow_type & IRQ_TYPE_LEVEL_HIGH) ?
@@ -91,16 +89,10 @@ static int al_fic_irq_set_type(struct irq_data *data, unsigned int flow_type)
if (fic->state == AL_FIC_UNCONFIGURED) {
al_fic_set_trigger(fic, gc, new_state);
} else if (fic->state != new_state) {
- pr_debug("fic %s state already configured to %d\n",
- fic->name, fic->state);
- ret = -EINVAL;
- goto err;
+ pr_debug("fic %s state already configured to %d\n", fic->name, fic->state);
+ return -EINVAL;
}
-
-err:
- irq_gc_unlock(gc);
-
- return ret;
+ return 0;
}
static void al_fic_irq_handler(struct irq_desc *desc)
@@ -139,7 +131,7 @@ static int al_fic_register(struct device_node *node,
struct irq_chip_generic *gc;
int ret;
- fic->domain = irq_domain_add_linear(node,
+ fic->domain = irq_domain_create_linear(of_fwnode_handle(node),
NR_FIC_IRQS,
&irq_generic_chip_ops,
fic);
diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c
index a1430ab60a8a..a5289dc26dca 100644
--- a/drivers/irqchip/irq-alpine-msi.c
+++ b/drivers/irqchip/irq-alpine-msi.c
@@ -205,15 +205,14 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv,
return -ENXIO;
}
- middle_domain = irq_domain_add_hierarchy(gic_domain, 0, 0, NULL,
- &alpine_msix_middle_domain_ops,
- priv);
+ middle_domain = irq_domain_create_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;
}
- msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node),
+ msi_domain = pci_msi_create_irq_domain(of_fwnode_handle(node),
&alpine_msix_domain_info,
middle_domain);
if (!msi_domain) {
diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
index 974dc088c853..032d66dceb8e 100644
--- a/drivers/irqchip/irq-apple-aic.c
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -1014,7 +1014,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
irqc->info.die_stride = off - start_off;
- irqc->hw_domain = irq_domain_create_tree(of_node_to_fwnode(node),
+ irqc->hw_domain = irq_domain_create_tree(of_fwnode_handle(node),
&aic_irq_domain_ops, irqc);
if (WARN_ON(!irqc->hw_domain))
goto err_unmap;
@@ -1067,7 +1067,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
if (is_kernel_in_hyp_mode()) {
struct irq_fwspec mi = {
- .fwnode = of_node_to_fwnode(node),
+ .fwnode = of_fwnode_handle(node),
.param_count = 3,
.param = {
[0] = AIC_FIQ, /* This is a lie */
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 2aa6a51e05d0..67b672a78862 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -348,12 +348,12 @@ static int __init mpic_msi_init(struct mpic *mpic, struct device_node *node,
mpic->msi_doorbell_mask = PCI_MSI_FULL_DOORBELL_MASK;
}
- mpic->msi_inner_domain = irq_domain_add_linear(NULL, mpic->msi_doorbell_size,
+ mpic->msi_inner_domain = irq_domain_create_linear(NULL, mpic->msi_doorbell_size,
&mpic_msi_domain_ops, mpic);
if (!mpic->msi_inner_domain)
return -ENOMEM;
- mpic->msi_domain = pci_msi_create_irq_domain(of_node_to_fwnode(node), &mpic_msi_domain_info,
+ mpic->msi_domain = pci_msi_create_irq_domain(of_fwnode_handle(node), &mpic_msi_domain_info,
mpic->msi_inner_domain);
if (!mpic->msi_domain) {
irq_domain_remove(mpic->msi_inner_domain);
@@ -492,7 +492,7 @@ static int __init mpic_ipi_init(struct mpic *mpic, struct device_node *node)
{
int base_ipi;
- mpic->ipi_domain = irq_domain_create_linear(of_node_to_fwnode(node), IPI_DOORBELL_NR,
+ mpic->ipi_domain = irq_domain_create_linear(of_fwnode_handle(node), IPI_DOORBELL_NR,
&mpic_ipi_domain_ops, mpic);
if (WARN_ON(!mpic->ipi_domain))
return -ENOMEM;
@@ -546,7 +546,7 @@ static void mpic_reenable_percpu(struct mpic *mpic)
{
/* Re-enable per-CPU interrupts that were enabled before suspend */
for (irq_hw_number_t i = 0; i < MPIC_PER_CPU_IRQS_NR; i++) {
- unsigned int virq = irq_linear_revmap(mpic->domain, i);
+ unsigned int virq = irq_find_mapping(mpic->domain, i);
struct irq_data *d;
if (!virq || !irq_percpu_is_enabled(virq))
@@ -740,7 +740,7 @@ static void mpic_resume(void)
/* Re-enable interrupts */
for (irq_hw_number_t i = 0; i < mpic->domain->hwirq_max; i++) {
- unsigned int virq = irq_linear_revmap(mpic->domain, i);
+ unsigned int virq = irq_find_mapping(mpic->domain, i);
struct irq_data *d;
if (!virq)
@@ -861,7 +861,7 @@ static int __init mpic_of_init(struct device_node *node, struct device_node *par
if (!mpic_is_ipi_available(mpic))
nr_irqs = MPIC_PER_CPU_IRQS_NR;
- mpic->domain = irq_domain_add_linear(node, nr_irqs, &mpic_irq_ops, mpic);
+ mpic->domain = irq_domain_create_linear(of_fwnode_handle(node), nr_irqs, &mpic_irq_ops, mpic);
if (!mpic->domain) {
pr_err("%pOF: Unable to add IRQ domain\n", node);
return -ENOMEM;
diff --git a/drivers/irqchip/irq-aspeed-i2c-ic.c b/drivers/irqchip/irq-aspeed-i2c-ic.c
index 9c9fc3e2967e..87c1feb999ff 100644
--- a/drivers/irqchip/irq-aspeed-i2c-ic.c
+++ b/drivers/irqchip/irq-aspeed-i2c-ic.c
@@ -82,7 +82,7 @@ static int __init aspeed_i2c_ic_of_init(struct device_node *node,
goto err_iounmap;
}
- i2c_ic->irq_domain = irq_domain_add_linear(node, ASPEED_I2C_IC_NUM_BUS,
+ i2c_ic->irq_domain = irq_domain_create_linear(of_fwnode_handle(node), ASPEED_I2C_IC_NUM_BUS,
&aspeed_i2c_ic_irq_domain_ops,
NULL);
if (!i2c_ic->irq_domain) {
diff --git a/drivers/irqchip/irq-aspeed-intc.c b/drivers/irqchip/irq-aspeed-intc.c
index bd3b759b4b2c..8330221799a0 100644
--- a/drivers/irqchip/irq-aspeed-intc.c
+++ b/drivers/irqchip/irq-aspeed-intc.c
@@ -102,7 +102,7 @@ static int __init aspeed_intc_ic_of_init(struct device_node *node,
writel(0xffffffff, intc_ic->base + INTC_INT_STATUS_REG);
writel(0x0, intc_ic->base + INTC_INT_ENABLE_REG);
- intc_ic->irq_domain = irq_domain_add_linear(node, INTC_IRQS_PER_WORD,
+ intc_ic->irq_domain = irq_domain_create_linear(of_fwnode_handle(node), INTC_IRQS_PER_WORD,
&aspeed_intc_ic_irq_domain_ops, intc_ic);
if (!intc_ic->irq_domain) {
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-aspeed-scu-ic.c b/drivers/irqchip/irq-aspeed-scu-ic.c
index 94a7223e95df..1c7045467c48 100644
--- a/drivers/irqchip/irq-aspeed-scu-ic.c
+++ b/drivers/irqchip/irq-aspeed-scu-ic.c
@@ -165,7 +165,7 @@ static int aspeed_scu_ic_of_init_common(struct aspeed_scu_ic *scu_ic,
goto err;
}
- scu_ic->irq_domain = irq_domain_add_linear(node, scu_ic->num_irqs,
+ scu_ic->irq_domain = irq_domain_create_linear(of_fwnode_handle(node), scu_ic->num_irqs,
&aspeed_scu_ic_domain_ops,
scu_ic);
if (!scu_ic->irq_domain) {
diff --git a/drivers/irqchip/irq-aspeed-vic.c b/drivers/irqchip/irq-aspeed-vic.c
index 62ccf2c0c414..9b665b5bb531 100644
--- a/drivers/irqchip/irq-aspeed-vic.c
+++ b/drivers/irqchip/irq-aspeed-vic.c
@@ -211,8 +211,8 @@ static int __init avic_of_init(struct device_node *node,
set_handle_irq(avic_handle_irq);
/* Register our domain */
- vic->dom = irq_domain_add_simple(node, NUM_IRQS, 0,
- &avic_dom_ops, vic);
+ vic->dom = irq_domain_create_simple(of_fwnode_handle(node), NUM_IRQS, 0,
+ &avic_dom_ops, vic);
return 0;
}
diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
index 92f001a5ff8d..268cc18b781f 100644
--- a/drivers/irqchip/irq-ath79-misc.c
+++ b/drivers/irqchip/irq-ath79-misc.c
@@ -147,7 +147,7 @@ static int __init ath79_misc_intc_of_init(
return -ENOMEM;
}
- domain = irq_domain_add_linear(node, ATH79_MISC_IRQ_COUNT,
+ domain = irq_domain_create_linear(of_fwnode_handle(node), ATH79_MISC_IRQ_COUNT,
&misc_irq_domain_ops, base);
if (!domain) {
pr_err("Failed to add MISC irqdomain\n");
@@ -188,7 +188,7 @@ void __init ath79_misc_irq_init(void __iomem *regs, int irq,
else
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
- domain = irq_domain_add_legacy(NULL, ATH79_MISC_IRQ_COUNT,
+ domain = irq_domain_create_legacy(NULL, ATH79_MISC_IRQ_COUNT,
irq_base, 0, &misc_irq_domain_ops, regs);
if (!domain)
panic("Failed to create MISC irqdomain");
diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c
index 4525366d16d6..3cad30a40c19 100644
--- a/drivers/irqchip/irq-atmel-aic-common.c
+++ b/drivers/irqchip/irq-atmel-aic-common.c
@@ -228,7 +228,7 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node,
goto err_iounmap;
}
- domain = irq_domain_add_linear(node, nchips * 32, ops, aic);
+ domain = irq_domain_create_linear(of_fwnode_handle(node), nchips * 32, ops, aic);
if (!domain) {
ret = -ENOMEM;
goto err_free_aic;
diff --git a/drivers/irqchip/irq-atmel-aic.c b/drivers/irqchip/irq-atmel-aic.c
index 3839ad79ad31..03aeed39a4d2 100644
--- a/drivers/irqchip/irq-atmel-aic.c
+++ b/drivers/irqchip/irq-atmel-aic.c
@@ -78,9 +78,8 @@ static int aic_retrigger(struct irq_data *d)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
/* Enable interrupt on AIC5 */
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
irq_reg_writel(gc, d->mask, AT91_AIC_ISCR);
- irq_gc_unlock(gc);
return 1;
}
@@ -106,30 +105,27 @@ static void aic_suspend(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IDCR);
irq_reg_writel(gc, gc->wake_active, AT91_AIC_IECR);
- irq_gc_unlock(gc);
}
static void aic_resume(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
irq_reg_writel(gc, gc->wake_active, AT91_AIC_IDCR);
irq_reg_writel(gc, gc->mask_cache, AT91_AIC_IECR);
- irq_gc_unlock(gc);
}
static void aic_pm_shutdown(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
irq_reg_writel(gc, 0xffffffff, AT91_AIC_IDCR);
irq_reg_writel(gc, 0xffffffff, AT91_AIC_ICCR);
- irq_gc_unlock(gc);
}
#else
#define aic_suspend NULL
@@ -175,10 +171,8 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
{
struct irq_domain_chip_generic *dgc = d->gc;
struct irq_chip_generic *gc;
- unsigned long flags;
unsigned smr;
- int idx;
- int ret;
+ int idx, ret;
if (!dgc)
return -EINVAL;
@@ -194,11 +188,10 @@ static int aic_irq_domain_xlate(struct irq_domain *d,
gc = dgc->gc[idx];
- irq_gc_lock_irqsave(gc, flags);
+ guard(raw_spinlock_irq)(&gc->lock);
smr = irq_reg_readl(gc, AT91_AIC_SMR(*out_hwirq));
aic_common_set_priority(intspec[2], &smr);
irq_reg_writel(gc, smr, AT91_AIC_SMR(*out_hwirq));
- irq_gc_unlock_irqrestore(gc, flags);
return ret;
}
diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c
index e98c2875af9e..60b00d2c3d7a 100644
--- a/drivers/irqchip/irq-atmel-aic5.c
+++ b/drivers/irqchip/irq-atmel-aic5.c
@@ -92,11 +92,10 @@ static void aic5_mask(struct irq_data *d)
* Disable interrupt on AIC5. We always take the lock of the
* first irq chip as all chips share the same registers.
*/
- irq_gc_lock(bgc);
+ guard(raw_spinlock)(&bgc->lock);
irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
irq_reg_writel(gc, 1, AT91_AIC5_IDCR);
gc->mask_cache &= ~d->mask;
- irq_gc_unlock(bgc);
}
static void aic5_unmask(struct irq_data *d)
@@ -109,11 +108,10 @@ static void aic5_unmask(struct irq_data *d)
* Enable interrupt on AIC5. We always take the lock of the
* first irq chip as all chips share the same registers.
*/
- irq_gc_lock(bgc);
+ guard(raw_spinlock)(&bgc->lock);
irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR);
irq_reg_writel(gc, 1, AT91_AIC5_IECR);
gc->mask_cache |= d->mask;
- irq_gc_unlock(bgc);
}
static int aic5_retrigger(struct irq_data *d)
@@ -122,11 +120,9 @@ static int aic5_retrigger(struct irq_data *d)
struct irq_chip_generic *bgc = irq_get_domain_generic_chip(domain, 0);
/* Enable interrupt on AIC5 */
- irq_gc_lock(bgc);
+ guard(raw_spinlock)(&bgc->lock);
irq_reg_writel(bgc, d->hwirq, AT91_AIC5_SSR);
irq_reg_writel(bgc, 1, AT91_AIC5_ISCR);
- irq_gc_unlock(bgc);
-
return 1;
}
@@ -137,14 +133,12 @@ static int aic5_set_type(struct irq_data *d, unsigned type)
unsigned int smr;
int ret;
- irq_gc_lock(bgc);
+ guard(raw_spinlock)(&bgc->lock);
irq_reg_writel(bgc, d->hwirq, AT91_AIC5_SSR);
smr = irq_reg_readl(bgc, AT91_AIC5_SMR);
ret = aic_common_set_type(d, type, &smr);
if (!ret)
irq_reg_writel(bgc, smr, AT91_AIC5_SMR);
- irq_gc_unlock(bgc);
-
return ret;
}
@@ -166,7 +160,7 @@ static void aic5_suspend(struct irq_data *d)
smr_cache[i] = irq_reg_readl(bgc, AT91_AIC5_SMR);
}
- irq_gc_lock(bgc);
+ guard(raw_spinlock)(&bgc->lock);
for (i = 0; i < dgc->irqs_per_chip; i++) {
mask = 1 << i;
if ((mask & gc->mask_cache) == (mask & gc->wake_active))
@@ -178,7 +172,6 @@ static void aic5_suspend(struct irq_data *d)
else
irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
}
- irq_gc_unlock(bgc);
}
static void aic5_resume(struct irq_data *d)
@@ -190,7 +183,7 @@ static void aic5_resume(struct irq_data *d)
int i;
u32 mask;
- irq_gc_lock(bgc);
+ guard(raw_spinlock)(&bgc->lock);
if (smr_cache) {
irq_reg_writel(bgc, 0xffffffff, AT91_AIC5_SPU);
@@ -214,7 +207,6 @@ static void aic5_resume(struct irq_data *d)
else
irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
}
- irq_gc_unlock(bgc);
}
static void aic5_pm_shutdown(struct irq_data *d)
@@ -225,13 +217,12 @@ static void aic5_pm_shutdown(struct irq_data *d)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
int i;
- irq_gc_lock(bgc);
+ guard(raw_spinlock)(&bgc->lock);
for (i = 0; i < dgc->irqs_per_chip; i++) {
irq_reg_writel(bgc, i + gc->irq_base, AT91_AIC5_SSR);
irq_reg_writel(bgc, 1, AT91_AIC5_IDCR);
irq_reg_writel(bgc, 1, AT91_AIC5_ICCR);
}
- irq_gc_unlock(bgc);
}
#else
#define aic5_suspend NULL
@@ -277,7 +268,6 @@ static int aic5_irq_domain_xlate(struct irq_domain *d,
unsigned int *out_type)
{
struct irq_chip_generic *bgc = irq_get_domain_generic_chip(d, 0);
- unsigned long flags;
unsigned smr;
int ret;
@@ -289,13 +279,11 @@ static int aic5_irq_domain_xlate(struct irq_domain *d,
if (ret)
return ret;
- irq_gc_lock_irqsave(bgc, flags);
+ guard(raw_spinlock_irq)(&bgc->lock);
irq_reg_writel(bgc, *out_hwirq, AT91_AIC5_SSR);
smr = irq_reg_readl(bgc, AT91_AIC5_SMR);
aic_common_set_priority(intspec[2], &smr);
irq_reg_writel(bgc, smr, AT91_AIC5_SMR);
- irq_gc_unlock_irqrestore(bgc, flags);
-
return ret;
}
diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c
index 49a19db2d1e1..63de5ef6cf2d 100644
--- a/drivers/irqchip/irq-bcm2712-mip.c
+++ b/drivers/irqchip/irq-bcm2712-mip.c
@@ -11,7 +11,7 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#define MIP_INT_RAISE 0x00
#define MIP_INT_CLEAR 0x10
@@ -163,6 +163,7 @@ static const struct irq_domain_ops mip_middle_domain_ops = {
static const struct msi_parent_ops mip_msi_parent_ops = {
.supported_flags = MIP_MSI_FLAGS_SUPPORTED,
.required_flags = MIP_MSI_FLAGS_REQUIRED,
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
.bus_select_token = DOMAIN_BUS_GENERIC_MSI,
.bus_select_mask = MATCH_PCI_MSI,
.prefix = "MIP-MSI-",
@@ -173,8 +174,8 @@ static int mip_init_domains(struct mip_priv *mip, struct device_node *np)
{
struct irq_domain *middle;
- middle = irq_domain_add_hierarchy(mip->parent, 0, mip->num_msis, np,
- &mip_middle_domain_ops, mip);
+ middle = irq_domain_create_hierarchy(mip->parent, 0, mip->num_msis, of_fwnode_handle(np),
+ &mip_middle_domain_ops, mip);
if (!middle)
return -ENOMEM;
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index 6c20604c2242..1e384c870350 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -144,7 +144,7 @@ static int __init armctrl_of_init(struct device_node *node,
if (!base)
panic("%pOF: unable to map IC registers\n", node);
- intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
+ intc.domain = irq_domain_create_linear(of_fwnode_handle(node), MAKE_HWIRQ(NR_BANKS, 0),
&armctrl_ops, NULL);
if (!intc.domain)
panic("%pOF: unable to create IRQ domain\n", node);
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index e366257684b5..fafd1f71348e 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -325,7 +325,7 @@ static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
bcm2835_init_local_timer_frequency();
- intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1,
+ intc.domain = irq_domain_create_linear(of_fwnode_handle(node), LAST_IRQ + 1,
&bcm2836_arm_irqchip_intc_ops,
NULL);
if (!intc.domain)
diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c
index 90daa274ef23..ca4e141c5bc2 100644
--- a/drivers/irqchip/irq-bcm6345-l1.c
+++ b/drivers/irqchip/irq-bcm6345-l1.c
@@ -316,7 +316,7 @@ static int __init bcm6345_l1_of_init(struct device_node *dn,
raw_spin_lock_init(&intc->lock);
- intc->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * intc->n_words,
+ intc->domain = irq_domain_create_linear(of_fwnode_handle(dn), IRQS_PER_WORD * intc->n_words,
&bcm6345_l1_domain_ops,
intc);
if (!intc->domain) {
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 36e71af054e9..04fac0cc857f 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -416,7 +416,7 @@ static int __init bcm7038_l1_of_init(struct device_node *dn,
}
}
- intc->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * intc->n_words,
+ intc->domain = irq_domain_create_linear(of_fwnode_handle(dn), IRQS_PER_WORD * intc->n_words,
&bcm7038_l1_domain_ops,
intc);
if (!intc->domain) {
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
index 1e9dab6e0d86..ff22c3104401 100644
--- a/drivers/irqchip/irq-bcm7120-l2.c
+++ b/drivers/irqchip/irq-bcm7120-l2.c
@@ -63,16 +63,15 @@ static void bcm7120_l2_intc_irq_handle(struct irq_desc *desc)
for (idx = 0; idx < b->n_words; idx++) {
int base = idx * IRQS_PER_WORD;
- struct irq_chip_generic *gc =
- irq_get_domain_generic_chip(b->domain, base);
+ struct irq_chip_generic *gc;
unsigned long pending;
int hwirq;
- irq_gc_lock(gc);
- pending = irq_reg_readl(gc, b->stat_offset[idx]) &
- gc->mask_cache &
- data->irq_map_mask[idx];
- irq_gc_unlock(gc);
+ gc = irq_get_domain_generic_chip(b->domain, base);
+ scoped_guard (raw_spinlock, &gc->lock) {
+ pending = irq_reg_readl(gc, b->stat_offset[idx]) & gc->mask_cache &
+ data->irq_map_mask[idx];
+ }
for_each_set_bit(hwirq, &pending, IRQS_PER_WORD)
generic_handle_domain_irq(b->domain, base + hwirq);
@@ -86,11 +85,9 @@ static void bcm7120_l2_intc_suspend(struct irq_chip_generic *gc)
struct bcm7120_l2_intc_data *b = gc->private;
struct irq_chip_type *ct = gc->chip_types;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
if (b->can_wake)
- irq_reg_writel(gc, gc->mask_cache | gc->wake_active,
- ct->regs.mask);
- irq_gc_unlock(gc);
+ irq_reg_writel(gc, gc->mask_cache | gc->wake_active, ct->regs.mask);
}
static void bcm7120_l2_intc_resume(struct irq_chip_generic *gc)
@@ -98,9 +95,8 @@ static void bcm7120_l2_intc_resume(struct irq_chip_generic *gc)
struct irq_chip_type *ct = gc->chip_types;
/* Restore the saved mask */
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
irq_reg_writel(gc, gc->mask_cache, ct->regs.mask);
- irq_gc_unlock(gc);
}
static int bcm7120_l2_intc_init_one(struct device_node *dn,
@@ -264,7 +260,7 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn,
goto out_free_l1_data;
}
- data->domain = irq_domain_add_linear(dn, IRQS_PER_WORD * data->n_words,
+ data->domain = irq_domain_create_linear(of_fwnode_handle(dn), IRQS_PER_WORD * data->n_words,
&irq_generic_chip_ops, NULL);
if (!data->domain) {
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
index db4c9721fcf2..1bec5b2cd3f0 100644
--- a/drivers/irqchip/irq-brcmstb-l2.c
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -97,9 +97,8 @@ static void __brcmstb_l2_intc_suspend(struct irq_data *d, bool save)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d);
struct brcmstb_l2_intc_data *b = gc->private;
- unsigned long flags;
- irq_gc_lock_irqsave(gc, flags);
+ guard(raw_spinlock_irqsave)(&gc->lock);
/* Save the current mask */
if (save)
b->saved_mask = irq_reg_readl(gc, ct->regs.mask);
@@ -109,7 +108,6 @@ static void __brcmstb_l2_intc_suspend(struct irq_data *d, bool save)
irq_reg_writel(gc, ~gc->wake_active, ct->regs.disable);
irq_reg_writel(gc, gc->wake_active, ct->regs.enable);
}
- irq_gc_unlock_irqrestore(gc, flags);
}
static void brcmstb_l2_intc_shutdown(struct irq_data *d)
@@ -127,9 +125,8 @@ static void brcmstb_l2_intc_resume(struct irq_data *d)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d);
struct brcmstb_l2_intc_data *b = gc->private;
- unsigned long flags;
- irq_gc_lock_irqsave(gc, flags);
+ guard(raw_spinlock_irqsave)(&gc->lock);
if (ct->chip.irq_ack) {
/* Clear unmasked non-wakeup interrupts */
irq_reg_writel(gc, ~b->saved_mask & ~gc->wake_active,
@@ -139,7 +136,6 @@ static void brcmstb_l2_intc_resume(struct irq_data *d)
/* Restore the saved mask */
irq_reg_writel(gc, b->saved_mask, ct->regs.disable);
irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable);
- irq_gc_unlock_irqrestore(gc, flags);
}
static int __init brcmstb_l2_intc_of_init(struct device_node *np,
@@ -182,7 +178,7 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np,
goto out_unmap;
}
- data->domain = irq_domain_add_linear(np, 32,
+ data->domain = irq_domain_create_linear(of_fwnode_handle(np), 32,
&irq_generic_chip_ops, NULL);
if (!data->domain) {
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c
index 48c73c948ddf..c4b73ba2323b 100644
--- a/drivers/irqchip/irq-clps711x.c
+++ b/drivers/irqchip/irq-clps711x.c
@@ -184,8 +184,8 @@ static int __init _clps711x_intc_init(struct device_node *np,
clps711x_intc->ops.map = clps711x_intc_irq_map;
clps711x_intc->ops.xlate = irq_domain_xlate_onecell;
clps711x_intc->domain =
- irq_domain_add_legacy(np, ARRAY_SIZE(clps711x_irqs),
- 0, 0, &clps711x_intc->ops, NULL);
+ irq_domain_create_legacy(of_fwnode_handle(np), ARRAY_SIZE(clps711x_irqs), 0, 0,
+ &clps711x_intc->ops, NULL);
if (!clps711x_intc->domain) {
err = -ENOMEM;
goto out_irqfree;
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index a05a7501e107..66bb39e24a52 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -351,10 +351,8 @@ static int __init irqcrossbar_init(struct device_node *node,
if (err)
return err;
- domain = irq_domain_add_hierarchy(parent_domain, 0,
- cb->max_crossbar_sources,
- node, &crossbar_domain_ops,
- NULL);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, cb->max_crossbar_sources,
+ of_fwnode_handle(node), &crossbar_domain_ops, NULL);
if (!domain) {
pr_err("%pOF: failed to allocated domain\n", node);
return -ENOMEM;
diff --git a/drivers/irqchip/irq-csky-apb-intc.c b/drivers/irqchip/irq-csky-apb-intc.c
index 6710691e4c25..5b7150705d29 100644
--- a/drivers/irqchip/irq-csky-apb-intc.c
+++ b/drivers/irqchip/irq-csky-apb-intc.c
@@ -50,11 +50,10 @@ static void irq_ck_mask_set_bit(struct irq_data *d)
unsigned long ifr = ct->regs.mask - 8;
u32 mask = d->mask;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
*ct->mask_cache |= mask;
irq_reg_writel(gc, *ct->mask_cache, ct->regs.mask);
irq_reg_writel(gc, irq_reg_readl(gc, ifr) & ~mask, ifr);
- irq_gc_unlock(gc);
}
static void __init ck_set_gc(struct device_node *node, void __iomem *reg_base,
@@ -114,7 +113,7 @@ ck_intc_init_comm(struct device_node *node, struct device_node *parent)
return -EINVAL;
}
- root_domain = irq_domain_add_linear(node, nr_irq,
+ root_domain = irq_domain_create_linear(of_fwnode_handle(node), nr_irq,
&irq_generic_chip_ops, NULL);
if (!root_domain) {
pr_err("C-SKY Intc irq_domain_add failed.\n");
diff --git a/drivers/irqchip/irq-csky-mpintc.c b/drivers/irqchip/irq-csky-mpintc.c
index 4aebd67d4f8f..1d1f5091f26f 100644
--- a/drivers/irqchip/irq-csky-mpintc.c
+++ b/drivers/irqchip/irq-csky-mpintc.c
@@ -255,7 +255,7 @@ csky_mpintc_init(struct device_node *node, struct device_node *parent)
writel_relaxed(BIT(0), INTCG_base + INTCG_ICTLR);
}
- root_domain = irq_domain_add_linear(node, nr_irq, &csky_irqdomain_ops,
+ root_domain = irq_domain_create_linear(of_fwnode_handle(node), nr_irq, &csky_irqdomain_ops,
NULL);
if (!root_domain)
return -ENXIO;
diff --git a/drivers/irqchip/irq-davinci-cp-intc.c b/drivers/irqchip/irq-davinci-cp-intc.c
index d7948c55f542..00cdcc90f614 100644
--- a/drivers/irqchip/irq-davinci-cp-intc.c
+++ b/drivers/irqchip/irq-davinci-cp-intc.c
@@ -204,8 +204,10 @@ static int __init davinci_cp_intc_do_init(struct resource *res, unsigned int num
return irq_base;
}
- davinci_cp_intc_irq_domain = irq_domain_add_legacy(node, num_irqs, irq_base, 0,
- &davinci_cp_intc_irq_domain_ops, NULL);
+ davinci_cp_intc_irq_domain = irq_domain_create_legacy(of_fwnode_handle(node), num_irqs,
+ irq_base, 0,
+ &davinci_cp_intc_irq_domain_ops,
+ NULL);
if (!davinci_cp_intc_irq_domain) {
pr_err("%s: unable to create an interrupt domain\n", __func__);
diff --git a/drivers/irqchip/irq-digicolor.c b/drivers/irqchip/irq-digicolor.c
index 3b0d78aac13b..eb5a8de82751 100644
--- a/drivers/irqchip/irq-digicolor.c
+++ b/drivers/irqchip/irq-digicolor.c
@@ -95,7 +95,7 @@ static int __init digicolor_of_init(struct device_node *node,
regmap_write(ucregs, UC_IRQ_CONTROL, 1);
digicolor_irq_domain =
- irq_domain_add_linear(node, 64, &irq_generic_chip_ops, NULL);
+ irq_domain_create_linear(of_fwnode_handle(node), 64, &irq_generic_chip_ops, NULL);
if (!digicolor_irq_domain) {
pr_err("%pOF: unable to create IRQ domain\n", node);
return -ENOMEM;
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c
index d5c1c750c8d2..4240a0dbf627 100644
--- a/drivers/irqchip/irq-dw-apb-ictl.c
+++ b/drivers/irqchip/irq-dw-apb-ictl.c
@@ -101,10 +101,9 @@ static void dw_apb_ictl_resume(struct irq_data *d)
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d);
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
writel_relaxed(~0, gc->reg_base + ct->regs.enable);
writel_relaxed(*ct->mask_cache, gc->reg_base + ct->regs.mask);
- irq_gc_unlock(gc);
}
#else
#define dw_apb_ictl_resume NULL
@@ -173,7 +172,7 @@ static int __init dw_apb_ictl_init(struct device_node *np,
else
nrirqs = fls(readl_relaxed(iobase + APB_INT_ENABLE_L));
- domain = irq_domain_add_linear(np, nrirqs, domain_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(np), nrirqs, domain_ops, NULL);
if (!domain) {
pr_err("%pOF: unable to add irq domain\n", np);
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-econet-en751221.c b/drivers/irqchip/irq-econet-en751221.c
new file mode 100644
index 000000000000..d83d5eb12795
--- /dev/null
+++ b/drivers/irqchip/irq-econet-en751221.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * EN751221 Interrupt Controller Driver.
+ *
+ * The EcoNet EN751221 Interrupt Controller is a simple interrupt controller
+ * designed for the MIPS 34Kc MT SMP processor with 2 VPEs. Each interrupt can
+ * be routed to either VPE but not both, so to support per-CPU interrupts, a
+ * secondary IRQ number is allocated to control masking/unmasking on VPE#1. In
+ * this driver, these are called "shadow interrupts". The assignment of shadow
+ * interrupts is defined by the SoC integrator when wiring the interrupt lines,
+ * so they are configurable in the device tree.
+ *
+ * If an interrupt (say 30) needs per-CPU capability, the SoC integrator
+ * allocates another IRQ number (say 29) to be its shadow. The device tree
+ * reflects this by adding the pair <30 29> to the "econet,shadow-interrupts"
+ * property.
+ *
+ * When VPE#1 requests IRQ 30, the driver manipulates the mask bit for IRQ 29,
+ * telling the hardware to mask VPE#1's view of IRQ 30.
+ *
+ * Copyright (C) 2025 Caleb James DeLisle <cjd@cjdns.fr>
+ */
+
+#include <linux/cleanup.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+
+#define IRQ_COUNT 40
+
+#define NOT_PERCPU 0xff
+#define IS_SHADOW 0xfe
+
+#define REG_MASK0 0x04
+#define REG_MASK1 0x50
+#define REG_PENDING0 0x08
+#define REG_PENDING1 0x54
+
+/**
+ * @membase: Base address of the interrupt controller registers
+ * @interrupt_shadows: Array of all interrupts, for each value,
+ * - NOT_PERCPU: This interrupt is not per-cpu, so it has no shadow
+ * - IS_SHADOW: This interrupt is a shadow of another per-cpu interrupt
+ * - else: This is a per-cpu interrupt whose shadow is the value
+ */
+static struct {
+ void __iomem *membase;
+ u8 interrupt_shadows[IRQ_COUNT];
+} econet_intc __ro_after_init;
+
+static DEFINE_RAW_SPINLOCK(irq_lock);
+
+/* IRQs must be disabled */
+static void econet_wreg(u32 reg, u32 val, u32 mask)
+{
+ u32 v;
+
+ guard(raw_spinlock)(&irq_lock);
+
+ v = ioread32(econet_intc.membase + reg);
+ v &= ~mask;
+ v |= val & mask;
+ iowrite32(v, econet_intc.membase + reg);
+}
+
+/* IRQs must be disabled */
+static void econet_chmask(u32 hwirq, bool unmask)
+{
+ u32 reg, mask;
+ u8 shadow;
+
+ /*
+ * If the IRQ is a shadow, it should never be manipulated directly.
+ * It should only be masked/unmasked as a result of the "real" per-cpu
+ * irq being manipulated by a thread running on VPE#1.
+ * If it is per-cpu (has a shadow), and we're on VPE#1, the shadow is what we mask.
+ * This is single processor only, so smp_processor_id() never exceeds 1.
+ */
+ shadow = econet_intc.interrupt_shadows[hwirq];
+ if (WARN_ON_ONCE(shadow == IS_SHADOW))
+ return;
+ else if (shadow != NOT_PERCPU && smp_processor_id() == 1)
+ hwirq = shadow;
+
+ if (hwirq >= 32) {
+ reg = REG_MASK1;
+ mask = BIT(hwirq - 32);
+ } else {
+ reg = REG_MASK0;
+ mask = BIT(hwirq);
+ }
+
+ econet_wreg(reg, unmask ? mask : 0, mask);
+}
+
+/* IRQs must be disabled */
+static void econet_intc_mask(struct irq_data *d)
+{
+ econet_chmask(d->hwirq, false);
+}
+
+/* IRQs must be disabled */
+static void econet_intc_unmask(struct irq_data *d)
+{
+ econet_chmask(d->hwirq, true);
+}
+
+static void econet_mask_all(void)
+{
+ /* IRQs are generally disabled during init, but guarding here makes it non-obligatory. */
+ guard(irqsave)();
+ econet_wreg(REG_MASK0, 0, ~0);
+ econet_wreg(REG_MASK1, 0, ~0);
+}
+
+static void econet_intc_handle_pending(struct irq_domain *d, u32 pending, u32 offset)
+{
+ int hwirq;
+
+ while (pending) {
+ hwirq = fls(pending) - 1;
+ generic_handle_domain_irq(d, hwirq + offset);
+ pending &= ~BIT(hwirq);
+ }
+}
+
+static void econet_intc_from_parent(struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct irq_domain *domain;
+ u32 pending0, pending1;
+
+ chained_irq_enter(chip, desc);
+
+ pending0 = ioread32(econet_intc.membase + REG_PENDING0);
+ pending1 = ioread32(econet_intc.membase + REG_PENDING1);
+
+ if (unlikely(!(pending0 | pending1))) {
+ spurious_interrupt();
+ } else {
+ domain = irq_desc_get_handler_data(desc);
+ econet_intc_handle_pending(domain, pending0, 0);
+ econet_intc_handle_pending(domain, pending1, 32);
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static const struct irq_chip econet_irq_chip;
+
+static int econet_intc_map(struct irq_domain *d, u32 irq, irq_hw_number_t hwirq)
+{
+ int ret;
+
+ if (hwirq >= IRQ_COUNT) {
+ pr_err("%s: hwirq %lu out of range\n", __func__, hwirq);
+ return -EINVAL;
+ } else if (econet_intc.interrupt_shadows[hwirq] == IS_SHADOW) {
+ pr_err("%s: can't map hwirq %lu, it is a shadow interrupt\n", __func__, hwirq);
+ return -EINVAL;
+ }
+
+ if (econet_intc.interrupt_shadows[hwirq] == NOT_PERCPU) {
+ irq_set_chip_and_handler(irq, &econet_irq_chip, handle_level_irq);
+ } else {
+ irq_set_chip_and_handler(irq, &econet_irq_chip, handle_percpu_devid_irq);
+ ret = irq_set_percpu_devid(irq);
+ if (ret)
+ pr_warn("%s: Failed irq_set_percpu_devid for %u: %d\n", d->name, irq, ret);
+ }
+
+ irq_set_chip_data(irq, NULL);
+ return 0;
+}
+
+static const struct irq_chip econet_irq_chip = {
+ .name = "en751221-intc",
+ .irq_unmask = econet_intc_unmask,
+ .irq_mask = econet_intc_mask,
+ .irq_mask_ack = econet_intc_mask,
+};
+
+static const struct irq_domain_ops econet_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = econet_intc_map
+};
+
+static int __init get_shadow_interrupts(struct device_node *node)
+{
+ const char *field = "econet,shadow-interrupts";
+ int num_shadows;
+
+ num_shadows = of_property_count_u32_elems(node, field);
+
+ memset(econet_intc.interrupt_shadows, NOT_PERCPU,
+ sizeof(econet_intc.interrupt_shadows));
+
+ if (num_shadows <= 0) {
+ return 0;
+ } else if (num_shadows % 2) {
+ pr_err("%pOF: %s count is odd, ignoring\n", node, field);
+ return 0;
+ }
+
+ u32 *shadows __free(kfree) = kmalloc_array(num_shadows, sizeof(u32), GFP_KERNEL);
+ if (!shadows)
+ return -ENOMEM;
+
+ if (of_property_read_u32_array(node, field, shadows, num_shadows)) {
+ pr_err("%pOF: Failed to read %s\n", node, field);
+ return -EINVAL;
+ }
+
+ for (int i = 0; i < num_shadows; i += 2) {
+ u32 shadow = shadows[i + 1];
+ u32 target = shadows[i];
+
+ if (shadow > IRQ_COUNT) {
+ pr_err("%pOF: %s[%d] shadow(%d) out of range\n",
+ node, field, i + 1, shadow);
+ continue;
+ }
+
+ if (target >= IRQ_COUNT) {
+ pr_err("%pOF: %s[%d] target(%d) out of range\n", node, field, i, target);
+ continue;
+ }
+
+ if (econet_intc.interrupt_shadows[target] != NOT_PERCPU) {
+ pr_err("%pOF: %s[%d] target(%d) already has a shadow\n",
+ node, field, i, target);
+ continue;
+ }
+
+ if (econet_intc.interrupt_shadows[shadow] != NOT_PERCPU) {
+ pr_err("%pOF: %s[%d] shadow(%d) already has a target\n",
+ node, field, i + 1, shadow);
+ continue;
+ }
+
+ econet_intc.interrupt_shadows[target] = shadow;
+ econet_intc.interrupt_shadows[shadow] = IS_SHADOW;
+ }
+
+ return 0;
+}
+
+static int __init econet_intc_of_init(struct device_node *node, struct device_node *parent)
+{
+ struct irq_domain *domain;
+ struct resource res;
+ int ret, irq;
+
+ ret = get_shadow_interrupts(node);
+ if (ret)
+ return ret;
+
+ irq = irq_of_parse_and_map(node, 0);
+ if (!irq) {
+ pr_err("%pOF: DT: Failed to get IRQ from 'interrupts'\n", node);
+ return -EINVAL;
+ }
+
+ if (of_address_to_resource(node, 0, &res)) {
+ pr_err("%pOF: DT: Failed to get 'reg'\n", node);
+ ret = -EINVAL;
+ goto err_dispose_mapping;
+ }
+
+ if (!request_mem_region(res.start, resource_size(&res), res.name)) {
+ pr_err("%pOF: Failed to request memory\n", node);
+ ret = -EBUSY;
+ goto err_dispose_mapping;
+ }
+
+ econet_intc.membase = ioremap(res.start, resource_size(&res));
+ if (!econet_intc.membase) {
+ pr_err("%pOF: Failed to remap membase\n", node);
+ ret = -ENOMEM;
+ goto err_release;
+ }
+
+ econet_mask_all();
+
+ domain = irq_domain_create_linear(of_fwnode_handle(node), IRQ_COUNT,
+ &econet_domain_ops, NULL);
+ if (!domain) {
+ pr_err("%pOF: Failed to add irqdomain\n", node);
+ ret = -ENOMEM;
+ goto err_unmap;
+ }
+
+ irq_set_chained_handler_and_data(irq, econet_intc_from_parent, domain);
+
+ return 0;
+
+err_unmap:
+ iounmap(econet_intc.membase);
+err_release:
+ release_mem_region(res.start, resource_size(&res));
+err_dispose_mapping:
+ irq_dispose_mapping(irq);
+ return ret;
+}
+
+IRQCHIP_DECLARE(econet_en751221_intc, "econet,en751221-intc", econet_intc_of_init);
diff --git a/drivers/irqchip/irq-ftintc010.c b/drivers/irqchip/irq-ftintc010.c
index b91c358ea6db..a59a66d79da6 100644
--- a/drivers/irqchip/irq-ftintc010.c
+++ b/drivers/irqchip/irq-ftintc010.c
@@ -180,8 +180,9 @@ static int __init ft010_of_init_irq(struct device_node *node,
writel(0, FT010_IRQ_MASK(f->base));
writel(0, FT010_FIQ_MASK(f->base));
- f->domain = irq_domain_add_simple(node, FT010_NUM_IRQS, 0,
- &ft010_irqdomain_ops, f);
+ f->domain = irq_domain_create_simple(of_fwnode_handle(node),
+ FT010_NUM_IRQS, 0,
+ &ft010_irqdomain_ops, f);
set_handle_irq(ft010_irqchip_handle_irq);
return 0;
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index c69894861866..24ef5af569fe 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -26,7 +26,7 @@
#include <linux/irqchip/arm-gic.h>
#include <linux/irqchip/arm-gic-common.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
/*
* MSI_TYPER:
@@ -252,7 +252,7 @@ static void __init gicv2m_teardown(void)
static struct msi_parent_ops gicv2m_msi_parent_ops = {
.supported_flags = GICV2M_MSI_FLAGS_SUPPORTED,
.required_flags = GICV2M_MSI_FLAGS_REQUIRED,
- .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI,
.bus_select_token = DOMAIN_BUS_NEXUS,
.bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
.prefix = "GICv2m-",
@@ -261,23 +261,23 @@ static struct msi_parent_ops gicv2m_msi_parent_ops = {
static __init int gicv2m_allocate_domains(struct irq_domain *parent)
{
- struct irq_domain *inner_domain;
+ struct irq_domain_info info = {
+ .ops = &gicv2m_domain_ops,
+ .parent = parent,
+ };
struct v2m_data *v2m;
v2m = list_first_entry_or_null(&v2m_nodes, struct v2m_data, entry);
if (!v2m)
return 0;
- inner_domain = irq_domain_create_hierarchy(parent, 0, 0, v2m->fwnode,
- &gicv2m_domain_ops, v2m);
- if (!inner_domain) {
+ info.host_data = v2m;
+ info.fwnode = v2m->fwnode;
+
+ if (!msi_create_parent_irq_domain(&info, &gicv2m_msi_parent_ops)) {
pr_err("Failed to create GICv2m domain\n");
return -ENOMEM;
}
-
- irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
- inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
- inner_domain->msi_parent_ops = &gicv2m_msi_parent_ops;
return 0;
}
@@ -421,7 +421,7 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle,
#ifdef CONFIG_ACPI
static int acpi_num_msi;
-static __init struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
+static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev)
{
struct v2m_data *data;
diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
index 8e87fc35f8aa..11549d85f23b 100644
--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
@@ -152,7 +152,7 @@ static void __init its_fsl_mc_of_msi_init(void)
if (!of_property_read_bool(np, "msi-controller"))
continue;
- its_fsl_mc_msi_init_one(of_node_to_fwnode(np),
+ its_fsl_mc_msi_init_one(of_fwnode_handle(np),
np->full_name);
}
}
diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
index bdb04c808148..a5e110ffdd88 100644
--- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c
+++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c
@@ -8,7 +8,7 @@
#include <linux/pci.h>
#include "irq-gic-common.h"
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#define ITS_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
MSI_FLAG_USE_DEF_CHIP_OPS | \
@@ -68,17 +68,6 @@ static int its_pci_msi_prepare(struct irq_domain *domain, struct device *dev,
info->scratchpad[0].ul = pci_msi_domain_get_msi_rid(domain->parent, pdev);
/*
- * @domain->msi_domain_info->hwsize contains the size of the
- * MSI[-X] domain, but vector allocation happens one by one. This
- * needs some thought when MSI comes into play as the size of MSI
- * might be unknown at domain creation time and therefore set to
- * MSI_MAX_INDEX.
- */
- msi_info = msi_get_domain_info(domain);
- if (msi_info->hwsize > nvec)
- nvec = msi_info->hwsize;
-
- /*
* Always allocate a power of 2, and special case device 0 for
* broken systems where the DevID is not wired (and all devices
* appear as DevID 0). For that reason, we generously allocate a
@@ -118,6 +107,14 @@ static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev,
index++;
} while (!ret);
+ if (ret) {
+ struct device_node *np = NULL;
+
+ ret = of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &np, dev_id);
+ if (np)
+ of_node_put(np);
+ }
+
return ret;
}
@@ -143,14 +140,6 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
/* ITS specific DeviceID, as the core ITS ignores dev. */
info->scratchpad[0].ul = dev_id;
- /*
- * @domain->msi_domain_info->hwsize contains the size of the device
- * domain, but vector allocation happens one by one.
- */
- msi_info = msi_get_domain_info(domain);
- if (msi_info->hwsize > nvec)
- nvec = msi_info->hwsize;
-
/* Allocate at least 32 MSIs, and always as a power of 2 */
nvec = max_t(int, 32, roundup_pow_of_two(nvec));
@@ -159,6 +148,14 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev,
dev, nvec, info);
}
+static void its_msi_teardown(struct irq_domain *domain, msi_alloc_info_t *info)
+{
+ struct msi_domain_info *msi_info;
+
+ msi_info = msi_get_domain_info(domain->parent);
+ msi_info->ops->msi_teardown(domain->parent, info);
+}
+
static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
struct irq_domain *real_parent, struct msi_domain_info *info)
{
@@ -182,6 +179,7 @@ static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
* %MSI_MAX_INDEX.
*/
info->ops->msi_prepare = its_pci_msi_prepare;
+ info->ops->msi_teardown = its_msi_teardown;
break;
case DOMAIN_BUS_DEVICE_MSI:
case DOMAIN_BUS_WIRED_TO_MSI:
@@ -190,6 +188,7 @@ static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
* size is also known at domain creation time.
*/
info->ops->msi_prepare = its_pmsi_prepare;
+ info->ops->msi_teardown = its_msi_teardown;
break;
default:
/* Confused. How did the lib return true? */
@@ -203,7 +202,7 @@ static bool its_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
const struct msi_parent_ops gic_v3_its_msi_parent_ops = {
.supported_flags = ITS_MSI_FLAGS_SUPPORTED,
.required_flags = ITS_MSI_FLAGS_REQUIRED,
- .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI,
.bus_select_token = DOMAIN_BUS_NEXUS,
.bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
.prefix = "ITS-",
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 0115ad6c8259..d54fa0638dc4 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -41,7 +41,7 @@
#include <asm/exception.h>
#include "irq-gic-common.h"
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0)
#define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1)
@@ -125,6 +125,8 @@ struct its_node {
int vlpi_redist_offset;
};
+static DEFINE_PER_CPU(struct its_node *, local_4_1_its);
+
#define is_v4(its) (!!((its)->typer & GITS_TYPER_VLPIS))
#define is_v4_1(its) (!!((its)->typer & GITS_TYPER_VMAPP))
#define device_ids(its) (FIELD_GET(GITS_TYPER_DEVBITS, (its)->typer) + 1)
@@ -2778,6 +2780,7 @@ static u64 inherit_vpe_l1_table_from_its(void)
}
val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, GITS_BASER_NR_PAGES(baser) - 1);
+ *this_cpu_ptr(&local_4_1_its) = its;
return val;
}
@@ -2815,6 +2818,7 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
gic_data_rdist()->vpe_l1_base = gic_data_rdist_cpu(cpu)->vpe_l1_base;
*mask = gic_data_rdist_cpu(cpu)->vpe_table_mask;
+ *this_cpu_ptr(&local_4_1_its) = *per_cpu_ptr(&local_4_1_its, cpu);
return val;
}
@@ -3620,8 +3624,33 @@ out:
return err;
}
+static void its_msi_teardown(struct irq_domain *domain, msi_alloc_info_t *info)
+{
+ struct its_device *its_dev = info->scratchpad[0].ptr;
+
+ guard(mutex)(&its_dev->its->dev_alloc_lock);
+
+ /* If the device is shared, keep everything around */
+ if (its_dev->shared)
+ return;
+
+ /* LPIs should have been already unmapped at this stage */
+ if (WARN_ON_ONCE(!bitmap_empty(its_dev->event_map.lpi_map,
+ its_dev->event_map.nr_lpis)))
+ return;
+
+ its_lpi_free(its_dev->event_map.lpi_map,
+ its_dev->event_map.lpi_base,
+ its_dev->event_map.nr_lpis);
+
+ /* Unmap device/itt, and get rid of the tracking */
+ its_send_mapd(its_dev, 0);
+ its_free_device(its_dev);
+}
+
static struct msi_domain_ops its_msi_domain_ops = {
.msi_prepare = its_msi_prepare,
+ .msi_teardown = its_msi_teardown,
};
static int its_irq_gic_domain_alloc(struct irq_domain *domain,
@@ -3722,7 +3751,6 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
{
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
struct its_device *its_dev = irq_data_get_irq_chip_data(d);
- struct its_node *its = its_dev->its;
int i;
bitmap_release_region(its_dev->event_map.lpi_map,
@@ -3736,26 +3764,6 @@ static void its_irq_domain_free(struct irq_domain *domain, unsigned int virq,
irq_domain_reset_irq_data(data);
}
- mutex_lock(&its->dev_alloc_lock);
-
- /*
- * If all interrupts have been freed, start mopping the
- * floor. This is conditioned on the device not being shared.
- */
- if (!its_dev->shared &&
- bitmap_empty(its_dev->event_map.lpi_map,
- its_dev->event_map.nr_lpis)) {
- its_lpi_free(its_dev->event_map.lpi_map,
- its_dev->event_map.lpi_base,
- its_dev->event_map.nr_lpis);
-
- /* Unmap device/itt */
- its_send_mapd(its_dev, 0);
- its_free_device(its_dev);
- }
-
- mutex_unlock(&its->dev_alloc_lock);
-
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
}
@@ -4180,7 +4188,7 @@ static struct irq_chip its_vpe_irq_chip = {
static struct its_node *find_4_1_its(void)
{
- static struct its_node *its = NULL;
+ struct its_node *its = *this_cpu_ptr(&local_4_1_its);
if (!its) {
list_for_each_entry(its, &its_nodes, entry) {
@@ -5118,7 +5126,12 @@ out_unmap:
static int its_init_domain(struct its_node *its)
{
- struct irq_domain *inner_domain;
+ struct irq_domain_info dom_info = {
+ .fwnode = its->fwnode_handle,
+ .ops = &its_domain_ops,
+ .domain_flags = its->msi_domain_flags,
+ .parent = its_parent,
+ };
struct msi_domain_info *info;
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -5127,21 +5140,12 @@ static int its_init_domain(struct its_node *its)
info->ops = &its_msi_domain_ops;
info->data = its;
+ dom_info.host_data = info;
- inner_domain = irq_domain_create_hierarchy(its_parent,
- its->msi_domain_flags, 0,
- its->fwnode_handle, &its_domain_ops,
- info);
- if (!inner_domain) {
+ if (!msi_create_parent_irq_domain(&dom_info, &gic_v3_its_msi_parent_ops)) {
kfree(info);
return -ENOMEM;
}
-
- irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS);
-
- inner_domain->msi_parent_ops = &gic_v3_its_msi_parent_ops;
- inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
-
return 0;
}
@@ -5518,7 +5522,7 @@ static struct its_node __init *its_node_init(struct resource *res,
its->base = its_base;
its->phys_base = res->start;
its->get_msi_base = its_irq_get_msi_base;
- its->msi_domain_flags = IRQ_DOMAIN_FLAG_ISOLATED_MSI;
+ its->msi_domain_flags = IRQ_DOMAIN_FLAG_ISOLATED_MSI | IRQ_DOMAIN_FLAG_MSI_IMMUTABLE;
its->numa_node = numa_node;
its->fwnode_handle = handle;
diff --git a/drivers/irqchip/irq-gic-v3-mbi.c b/drivers/irqchip/irq-gic-v3-mbi.c
index 34e9ca77a8c3..aa11bbe8026a 100644
--- a/drivers/irqchip/irq-gic-v3-mbi.c
+++ b/drivers/irqchip/irq-gic-v3-mbi.c
@@ -18,7 +18,7 @@
#include <linux/irqchip/arm-gic-v3.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
struct mbi_range {
u32 spi_start;
@@ -197,7 +197,7 @@ static bool mbi_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
static const struct msi_parent_ops gic_v3_mbi_msi_parent_ops = {
.supported_flags = MBI_MSI_FLAGS_SUPPORTED,
.required_flags = MBI_MSI_FLAGS_REQUIRED,
- .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI,
.bus_select_token = DOMAIN_BUS_NEXUS,
.bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI,
.prefix = "MBI-",
@@ -206,17 +206,13 @@ static const struct msi_parent_ops gic_v3_mbi_msi_parent_ops = {
static int mbi_allocate_domain(struct irq_domain *parent)
{
- struct irq_domain *nexus_domain;
+ struct irq_domain_info info = {
+ .fwnode = parent->fwnode,
+ .ops = &mbi_domain_ops,
+ .parent = parent,
+ };
- 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->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
- nexus_domain->msi_parent_ops = &gic_v3_mbi_msi_parent_ops;
- return 0;
+ return msi_create_parent_irq_domain(&info, &gic_v3_mbi_msi_parent_ops) ? 0 : -ENOMEM;
}
int __init mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 270d7a4d85a6..efc791c43d44 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1826,7 +1826,7 @@ static int partition_domain_translate(struct irq_domain *d,
ppi_idx = __gic_get_ppi_index(ppi_intid);
ret = partition_translate_id(gic_data.ppi_descs[ppi_idx],
- of_node_to_fwnode(np));
+ of_fwnode_handle(np));
if (ret < 0)
return ret;
@@ -2192,7 +2192,7 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
part = &parts[part_idx];
- part->partition_id = of_node_to_fwnode(child_part);
+ part->partition_id = of_fwnode_handle(child_part);
pr_info("GIC: PPI partition %pOFn[%d] { ",
child_part, part_idx);
diff --git a/drivers/irqchip/irq-goldfish-pic.c b/drivers/irqchip/irq-goldfish-pic.c
index 513f6edbbe95..a8b23b507ecd 100644
--- a/drivers/irqchip/irq-goldfish-pic.c
+++ b/drivers/irqchip/irq-goldfish-pic.c
@@ -101,10 +101,9 @@ static int __init goldfish_pic_of_init(struct device_node *of_node,
irq_setup_generic_chip(gc, IRQ_MSK(GFPIC_NR_IRQS), 0,
IRQ_NOPROBE | IRQ_LEVEL, 0);
- gfpic->irq_domain = irq_domain_add_legacy(of_node, GFPIC_NR_IRQS,
- GFPIC_IRQ_BASE, 0,
- &goldfish_irq_domain_ops,
- NULL);
+ gfpic->irq_domain = irq_domain_create_legacy(of_fwnode_handle(of_node), GFPIC_NR_IRQS,
+ GFPIC_IRQ_BASE, 0, &goldfish_irq_domain_ops,
+ NULL);
if (!gfpic->irq_domain) {
pr_err("Failed to add irqdomain!\n");
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index 31c3f70a5d5e..b7958c5a1221 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -386,10 +386,8 @@ hip04_of_init(struct device_node *node, struct device_node *parent)
return -EINVAL;
}
- hip04_data.domain = irq_domain_add_legacy(node, nr_irqs, irq_base,
- 0,
- &hip04_irq_domain_ops,
- &hip04_data);
+ hip04_data.domain = irq_domain_create_legacy(of_fwnode_handle(node), nr_irqs, irq_base, 0,
+ &hip04_irq_domain_ops, &hip04_data);
if (WARN_ON(!hip04_data.domain))
return -EINVAL;
diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c
index 115bdcffab24..91b2f587119c 100644
--- a/drivers/irqchip/irq-i8259.c
+++ b/drivers/irqchip/irq-i8259.c
@@ -313,8 +313,8 @@ struct irq_domain * __init __init_i8259_irqs(struct device_node *node)
init_8259A(0);
- domain = irq_domain_add_legacy(node, 16, I8259A_IRQ_BASE, 0,
- &i8259A_ops, NULL);
+ domain = irq_domain_create_legacy(of_fwnode_handle(node), 16, I8259A_IRQ_BASE, 0,
+ &i8259A_ops, NULL);
if (!domain)
panic("Failed to add i8259 IRQ domain");
diff --git a/drivers/irqchip/irq-idt3243x.c b/drivers/irqchip/irq-idt3243x.c
index 0732a0e9af62..f8324fb1fe8f 100644
--- a/drivers/irqchip/irq-idt3243x.c
+++ b/drivers/irqchip/irq-idt3243x.c
@@ -72,7 +72,7 @@ static int idt_pic_init(struct device_node *of_node, struct device_node *parent)
goto out_unmap_irq;
}
- domain = irq_domain_add_linear(of_node, IDT_PIC_NR_IRQS,
+ domain = irq_domain_create_linear(of_fwnode_handle(of_node), IDT_PIC_NR_IRQS,
&irq_generic_chip_ops, NULL);
if (!domain) {
pr_err("Failed to add irqdomain!\n");
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c
index 85f80bac0961..f0410d5d7315 100644
--- a/drivers/irqchip/irq-imgpdc.c
+++ b/drivers/irqchip/irq-imgpdc.c
@@ -372,7 +372,7 @@ static int pdc_intc_probe(struct platform_device *pdev)
priv->syswake_irq = irq;
/* Set up an IRQ domain */
- priv->domain = irq_domain_add_linear(node, 16, &irq_generic_chip_ops,
+ priv->domain = irq_domain_create_linear(of_fwnode_handle(node), 16, &irq_generic_chip_ops,
priv);
if (unlikely(!priv->domain)) {
dev_err(&pdev->dev, "cannot add IRQ domain\n");
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
index 095ae8e3217e..b91f5c14b405 100644
--- a/drivers/irqchip/irq-imx-gpcv2.c
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -240,8 +240,8 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
return -ENOMEM;
}
- domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
- node, &gpcv2_irqchip_data_domain_ops, cd);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
+ of_fwnode_handle(node), &gpcv2_irqchip_data_domain_ops, cd);
if (!domain) {
iounmap(cd->gpc_base);
kfree(cd);
diff --git a/drivers/irqchip/irq-imx-intmux.c b/drivers/irqchip/irq-imx-intmux.c
index 787543d07565..5f9b204d350b 100644
--- a/drivers/irqchip/irq-imx-intmux.c
+++ b/drivers/irqchip/irq-imx-intmux.c
@@ -254,7 +254,7 @@ static int imx_intmux_probe(struct platform_device *pdev)
goto out;
}
- domain = irq_domain_add_linear(np, 32, &imx_intmux_domain_ops,
+ domain = irq_domain_create_linear(of_fwnode_handle(np), 32, &imx_intmux_domain_ops,
&data->irqchip_data[i]);
if (!domain) {
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index afbfcce3b1e3..6dc9ac48fee5 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -212,7 +212,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
/* steer all IRQs into configured channel */
writel_relaxed(BIT(data->channel), data->regs + CHANCTRL);
- data->domain = irq_domain_add_linear(np, data->reg_num * 32,
+ data->domain = irq_domain_create_linear(of_fwnode_handle(np), data->reg_num * 32,
&imx_irqsteer_domain_ops, data);
if (!data->domain) {
dev_err(&pdev->dev, "failed to create IRQ domain\n");
diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
index 69aacdfc8bef..137da1927d14 100644
--- a/drivers/irqchip/irq-imx-mu-msi.c
+++ b/drivers/irqchip/irq-imx-mu-msi.c
@@ -24,7 +24,7 @@
#include <linux/pm_domain.h>
#include <linux/spinlock.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#define IMX_MU_CHANS 4
diff --git a/drivers/irqchip/irq-ingenic-tcu.c b/drivers/irqchip/irq-ingenic-tcu.c
index 3363f83bd7e9..794ecba717c9 100644
--- a/drivers/irqchip/irq-ingenic-tcu.c
+++ b/drivers/irqchip/irq-ingenic-tcu.c
@@ -52,11 +52,10 @@ static void ingenic_tcu_gc_unmask_enable_reg(struct irq_data *d)
struct regmap *map = gc->private;
u32 mask = d->mask;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
regmap_write(map, ct->regs.ack, mask);
regmap_write(map, ct->regs.enable, mask);
*ct->mask_cache |= mask;
- irq_gc_unlock(gc);
}
static void ingenic_tcu_gc_mask_disable_reg(struct irq_data *d)
@@ -66,10 +65,9 @@ static void ingenic_tcu_gc_mask_disable_reg(struct irq_data *d)
struct regmap *map = gc->private;
u32 mask = d->mask;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
regmap_write(map, ct->regs.disable, mask);
*ct->mask_cache &= ~mask;
- irq_gc_unlock(gc);
}
static void ingenic_tcu_gc_mask_disable_reg_and_ack(struct irq_data *d)
@@ -79,10 +77,9 @@ static void ingenic_tcu_gc_mask_disable_reg_and_ack(struct irq_data *d)
struct regmap *map = gc->private;
u32 mask = d->mask;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
regmap_write(map, ct->regs.ack, mask);
regmap_write(map, ct->regs.disable, mask);
- irq_gc_unlock(gc);
}
static int __init ingenic_tcu_irq_init(struct device_node *np,
@@ -114,8 +111,8 @@ static int __init ingenic_tcu_irq_init(struct device_node *np,
tcu->nb_parent_irqs = irqs;
- tcu->domain = irq_domain_add_linear(np, 32, &irq_generic_chip_ops,
- NULL);
+ tcu->domain = irq_domain_create_linear(of_fwnode_handle(np), 32, &irq_generic_chip_ops,
+ NULL);
if (!tcu->domain) {
ret = -ENOMEM;
goto err_free_tcu;
diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c
index cee839ca627e..52393724f213 100644
--- a/drivers/irqchip/irq-ingenic.c
+++ b/drivers/irqchip/irq-ingenic.c
@@ -90,8 +90,8 @@ static int __init ingenic_intc_of_init(struct device_node *node,
goto out_unmap_irq;
}
- domain = irq_domain_add_linear(node, num_chips * 32,
- &irq_generic_chip_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(node), num_chips * 32,
+ &irq_generic_chip_ops, NULL);
if (!domain) {
err = -ENOMEM;
goto out_unmap_base;
diff --git a/drivers/irqchip/irq-ixp4xx.c b/drivers/irqchip/irq-ixp4xx.c
index f23b02f62a5c..a9a5a52b818a 100644
--- a/drivers/irqchip/irq-ixp4xx.c
+++ b/drivers/irqchip/irq-ixp4xx.c
@@ -261,7 +261,7 @@ static int __init ixp4xx_of_init_irq(struct device_node *np,
pr_crit("IXP4XX: could not ioremap interrupt controller\n");
return -ENODEV;
}
- fwnode = of_node_to_fwnode(np);
+ fwnode = of_fwnode_handle(np);
/* These chip variants have 64 interrupts */
is_356 = of_device_is_compatible(np, "intel,ixp43x-interrupt") ||
diff --git a/drivers/irqchip/irq-jcore-aic.c b/drivers/irqchip/irq-jcore-aic.c
index 1f613eb7b7f0..94c05cf974be 100644
--- a/drivers/irqchip/irq-jcore-aic.c
+++ b/drivers/irqchip/irq-jcore-aic.c
@@ -107,9 +107,8 @@ static int __init aic_irq_of_init(struct device_node *node,
if (ret < 0)
return ret;
- domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq,
- &jcore_aic_irqdomain_ops,
- &jcore_aic);
+ domain = irq_domain_create_legacy(of_fwnode_handle(node), dom_sz - min_irq, min_irq,
+ min_irq, &jcore_aic_irqdomain_ops, &jcore_aic);
if (!domain)
return -ENOMEM;
diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c
index 37e1a03fcbb4..c9e902b7bf48 100644
--- a/drivers/irqchip/irq-keystone.c
+++ b/drivers/irqchip/irq-keystone.c
@@ -157,8 +157,8 @@ static int keystone_irq_probe(struct platform_device *pdev)
kirq->chip.irq_mask = keystone_irq_setmask;
kirq->chip.irq_unmask = keystone_irq_unmask;
- kirq->irqd = irq_domain_add_linear(np, KEYSTONE_N_IRQ,
- &keystone_irq_ops, kirq);
+ kirq->irqd = irq_domain_create_linear(of_fwnode_handle(np), KEYSTONE_N_IRQ,
+ &keystone_irq_ops, kirq);
if (!kirq->irqd) {
dev_err(dev, "IRQ domain registration failed\n");
return -ENODEV;
diff --git a/drivers/irqchip/irq-lan966x-oic.c b/drivers/irqchip/irq-lan966x-oic.c
index 41ac880e3b87..11d3a0ffa261 100644
--- a/drivers/irqchip/irq-lan966x-oic.c
+++ b/drivers/irqchip/irq-lan966x-oic.c
@@ -71,14 +71,12 @@ static unsigned int lan966x_oic_irq_startup(struct irq_data *data)
struct lan966x_oic_chip_regs *chip_regs = gc->private;
u32 map;
- irq_gc_lock(gc);
-
- /* Map the source interrupt to the destination */
- map = irq_reg_readl(gc, chip_regs->reg_off_map);
- map |= data->mask;
- irq_reg_writel(gc, map, chip_regs->reg_off_map);
-
- irq_gc_unlock(gc);
+ scoped_guard (raw_spinlock, &gc->lock) {
+ /* Map the source interrupt to the destination */
+ map = irq_reg_readl(gc, chip_regs->reg_off_map);
+ map |= data->mask;
+ irq_reg_writel(gc, map, chip_regs->reg_off_map);
+ }
ct->chip.irq_ack(data);
ct->chip.irq_unmask(data);
@@ -95,14 +93,12 @@ static void lan966x_oic_irq_shutdown(struct irq_data *data)
ct->chip.irq_mask(data);
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
/* Unmap the interrupt */
map = irq_reg_readl(gc, chip_regs->reg_off_map);
map &= ~data->mask;
irq_reg_writel(gc, map, chip_regs->reg_off_map);
-
- irq_gc_unlock(gc);
}
static int lan966x_oic_irq_set_type(struct irq_data *data,
@@ -224,7 +220,7 @@ static int lan966x_oic_probe(struct platform_device *pdev)
.exit = lan966x_oic_chip_exit,
};
struct irq_domain_info d_info = {
- .fwnode = of_node_to_fwnode(pdev->dev.of_node),
+ .fwnode = of_fwnode_handle(pdev->dev.of_node),
.domain_flags = IRQ_DOMAIN_FLAG_DESTROY_GC,
.size = LAN966X_OIC_NR_IRQ,
.hwirq_max = LAN966X_OIC_NR_IRQ,
diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c
index 80e55955a29f..bf52dc8345f5 100644
--- a/drivers/irqchip/irq-loongarch-avec.c
+++ b/drivers/irqchip/irq-loongarch-avec.c
@@ -18,7 +18,7 @@
#include <asm/loongarch.h>
#include <asm/setup.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#include "irq-loongson.h"
#define VECTORS_PER_REG 64
diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c
index e62dab4c97fc..950bc087e388 100644
--- a/drivers/irqchip/irq-loongarch-cpu.c
+++ b/drivers/irqchip/irq-loongarch-cpu.c
@@ -100,7 +100,7 @@ static const struct irq_domain_ops loongarch_cpu_intc_irq_domain_ops = {
static int __init cpuintc_of_init(struct device_node *of_node,
struct device_node *parent)
{
- cpuintc_handle = of_node_to_fwnode(of_node);
+ cpuintc_handle = of_fwnode_handle(of_node);
irq_domain = irq_domain_create_linear(cpuintc_handle, EXCCODE_INT_NUM,
&loongarch_cpu_intc_irq_domain_ops, NULL);
diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
index bb79e19dfb59..b2860eb2d32c 100644
--- a/drivers/irqchip/irq-loongson-eiointc.c
+++ b/drivers/irqchip/irq-loongson-eiointc.c
@@ -554,7 +554,7 @@ static int __init eiointc_of_init(struct device_node *of_node,
priv->vec_count = VEC_COUNT;
priv->node = 0;
- priv->domain_handle = of_node_to_fwnode(of_node);
+ priv->domain_handle = of_fwnode_handle(of_node);
ret = eiointc_init(priv, parent_irq, 0);
if (ret < 0)
diff --git a/drivers/irqchip/irq-loongson-htvec.c b/drivers/irqchip/irq-loongson-htvec.c
index 5da02c7ad0b3..d8558eb35044 100644
--- a/drivers/irqchip/irq-loongson-htvec.c
+++ b/drivers/irqchip/irq-loongson-htvec.c
@@ -248,7 +248,7 @@ static int htvec_of_init(struct device_node *node,
}
err = htvec_init(res.start, resource_size(&res),
- num_parents, parent_irq, of_node_to_fwnode(node));
+ num_parents, parent_irq, of_fwnode_handle(node));
if (err < 0)
return err;
diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c
index 2b1bd4a96665..0033c2188abc 100644
--- a/drivers/irqchip/irq-loongson-liointc.c
+++ b/drivers/irqchip/irq-loongson-liointc.c
@@ -116,9 +116,8 @@ static int liointc_set_type(struct irq_data *data, unsigned int type)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
u32 mask = data->mask;
- unsigned long flags;
- irq_gc_lock_irqsave(gc, flags);
+ guard(raw_spinlock)(&gc->lock);
switch (type) {
case IRQ_TYPE_LEVEL_HIGH:
liointc_set_bit(gc, LIOINTC_REG_INTC_EDGE, mask, false);
@@ -137,10 +136,8 @@ static int liointc_set_type(struct irq_data *data, unsigned int type)
liointc_set_bit(gc, LIOINTC_REG_INTC_POL, mask, true);
break;
default:
- irq_gc_unlock_irqrestore(gc, flags);
return -EINVAL;
}
- irq_gc_unlock_irqrestore(gc, flags);
irqd_set_trigger_type(data, type);
return 0;
@@ -157,10 +154,9 @@ static void liointc_suspend(struct irq_chip_generic *gc)
static void liointc_resume(struct irq_chip_generic *gc)
{
struct liointc_priv *priv = gc->private;
- unsigned long flags;
int i;
- irq_gc_lock_irqsave(gc, flags);
+ guard(raw_spinlock_irqsave)(&gc->lock);
/* Disable all at first */
writel(0xffffffff, gc->reg_base + LIOINTC_REG_INTC_DISABLE);
/* Restore map cache */
@@ -170,7 +166,6 @@ static void liointc_resume(struct irq_chip_generic *gc)
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);
}
static int parent_irq[LIOINTC_NUM_PARENT];
@@ -363,7 +358,7 @@ static int __init liointc_of_init(struct device_node *node,
}
err = liointc_init(res.start, resource_size(&res),
- revision, of_node_to_fwnode(node), node);
+ revision, of_fwnode_handle(node), node);
if (err < 0)
return err;
diff --git a/drivers/irqchip/irq-loongson-pch-msi.c b/drivers/irqchip/irq-loongson-pch-msi.c
index 9c62108b3ad5..a0257c7bef10 100644
--- a/drivers/irqchip/irq-loongson-pch-msi.c
+++ b/drivers/irqchip/irq-loongson-pch-msi.c
@@ -15,7 +15,7 @@
#include <linux/pci.h>
#include <linux/slab.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#include "irq-loongson.h"
static int nr_pics;
@@ -243,7 +243,7 @@ static int pch_msi_of_init(struct device_node *node, struct device_node *parent)
return -EINVAL;
}
- err = pch_msi_init(res.start, irq_base, irq_count, parent_domain, of_node_to_fwnode(node));
+ err = pch_msi_init(res.start, irq_base, irq_count, parent_domain, of_fwnode_handle(node));
if (err < 0)
return err;
diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c
index 69efda35a8e7..62e6bf3a0611 100644
--- a/drivers/irqchip/irq-loongson-pch-pic.c
+++ b/drivers/irqchip/irq-loongson-pch-pic.c
@@ -392,7 +392,7 @@ static int pch_pic_of_init(struct device_node *node,
}
err = pch_pic_init(res.start, resource_size(&res), vec_base,
- parent_domain, of_node_to_fwnode(node), 0);
+ parent_domain, of_fwnode_handle(node), 0);
if (err < 0)
return err;
diff --git a/drivers/irqchip/irq-lpc32xx.c b/drivers/irqchip/irq-lpc32xx.c
index 4d70a857133f..14cca44baa14 100644
--- a/drivers/irqchip/irq-lpc32xx.c
+++ b/drivers/irqchip/irq-lpc32xx.c
@@ -210,8 +210,8 @@ static int __init lpc32xx_of_ic_init(struct device_node *node,
return -EINVAL;
}
- irqc->domain = irq_domain_add_linear(node, NR_LPC32XX_IC_IRQS,
- &lpc32xx_irq_domain_ops, irqc);
+ irqc->domain = irq_domain_create_linear(of_fwnode_handle(node), NR_LPC32XX_IC_IRQS,
+ &lpc32xx_irq_domain_ops, irqc);
if (!irqc->domain) {
pr_err("unable to add irq domain\n");
iounmap(irqc->base);
diff --git a/drivers/irqchip/irq-ls-extirq.c b/drivers/irqchip/irq-ls-extirq.c
index 139f26b0a6ef..50a7b38381b9 100644
--- a/drivers/irqchip/irq-ls-extirq.c
+++ b/drivers/irqchip/irq-ls-extirq.c
@@ -208,8 +208,8 @@ ls_extirq_of_init(struct device_node *node, struct device_node *parent)
of_device_is_compatible(node, "fsl,ls1043a-extirq");
raw_spin_lock_init(&priv->lock);
- domain = irq_domain_add_hierarchy(parent_domain, 0, priv->nirq, node,
- &extirq_domain_ops, priv);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, priv->nirq, of_fwnode_handle(node),
+ &extirq_domain_ops, priv);
if (!domain) {
ret = -ENOMEM;
goto err_add_hierarchy;
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 3cb80796cc7c..84bc5e4b47cf 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -215,17 +215,17 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
static int ls_scfg_msi_domains_init(struct ls_scfg_msi *msi_data)
{
/* Initialize MSI domain parent */
- msi_data->parent = irq_domain_add_linear(NULL,
- msi_data->irqs_num,
- &ls_scfg_msi_domain_ops,
- msi_data);
+ msi_data->parent = irq_domain_create_linear(NULL,
+ msi_data->irqs_num,
+ &ls_scfg_msi_domain_ops,
+ msi_data);
if (!msi_data->parent) {
dev_err(&msi_data->pdev->dev, "failed to create IRQ domain\n");
return -ENOMEM;
}
msi_data->msi_domain = pci_msi_create_irq_domain(
- of_node_to_fwnode(msi_data->pdev->dev.of_node),
+ of_fwnode_handle(msi_data->pdev->dev.of_node),
&ls_scfg_msi_domain_info,
msi_data->parent);
if (!msi_data->msi_domain) {
diff --git a/drivers/irqchip/irq-ls1x.c b/drivers/irqchip/irq-ls1x.c
index 77a3f7dfaaf0..589d32007fca 100644
--- a/drivers/irqchip/irq-ls1x.c
+++ b/drivers/irqchip/irq-ls1x.c
@@ -126,8 +126,8 @@ static int __init ls1x_intc_of_init(struct device_node *node,
}
/* Set up an IRQ domain */
- priv->domain = irq_domain_add_linear(node, 32, &irq_generic_chip_ops,
- NULL);
+ priv->domain = irq_domain_create_linear(of_fwnode_handle(node), 32, &irq_generic_chip_ops,
+ NULL);
if (!priv->domain) {
pr_err("ls1x-irq: cannot add IRQ domain\n");
err = -ENOMEM;
diff --git a/drivers/irqchip/irq-mchp-eic.c b/drivers/irqchip/irq-mchp-eic.c
index 5dcd94c000a2..516a3a0e359c 100644
--- a/drivers/irqchip/irq-mchp-eic.c
+++ b/drivers/irqchip/irq-mchp-eic.c
@@ -248,8 +248,9 @@ static int mchp_eic_init(struct device_node *node, struct device_node *parent)
eic->irqs[i] = irq.args[1];
}
- eic->domain = irq_domain_add_hierarchy(parent_domain, 0, MCHP_EIC_NIRQ,
- node, &mchp_eic_domain_ops, eic);
+ eic->domain = irq_domain_create_hierarchy(parent_domain, 0, MCHP_EIC_NIRQ,
+ of_fwnode_handle(node), &mchp_eic_domain_ops,
+ eic);
if (!eic->domain) {
pr_err("%pOF: Failed to add domain\n", node);
ret = -ENODEV;
diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index 0a25536a5d07..7d177626d64b 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -607,7 +607,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
domain = irq_domain_create_hierarchy(parent_domain, 0,
ctl->params->nr_hwirq,
- of_node_to_fwnode(node),
+ of_fwnode_handle(node),
&meson_gpio_irq_domain_ops,
ctl);
if (!domain) {
diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c
index 0c7ae71a0af0..ac784ef3ed4b 100644
--- a/drivers/irqchip/irq-mips-cpu.c
+++ b/drivers/irqchip/irq-mips-cpu.c
@@ -238,11 +238,9 @@ static void mips_cpu_register_ipi_domain(struct device_node *of_node)
struct cpu_ipi_domain_state *ipi_domain_state;
ipi_domain_state = kzalloc(sizeof(*ipi_domain_state), GFP_KERNEL);
- ipi_domain = irq_domain_add_hierarchy(irq_domain,
- IRQ_DOMAIN_FLAG_IPI_SINGLE,
- 2, of_node,
- &mips_cpu_ipi_chip_ops,
- ipi_domain_state);
+ ipi_domain = irq_domain_create_hierarchy(irq_domain, IRQ_DOMAIN_FLAG_IPI_SINGLE, 2,
+ of_fwnode_handle(of_node),
+ &mips_cpu_ipi_chip_ops, ipi_domain_state);
if (!ipi_domain)
panic("Failed to add MIPS CPU IPI domain");
irq_domain_update_bus_token(ipi_domain, DOMAIN_BUS_IPI);
@@ -260,9 +258,8 @@ static void __init __mips_cpu_irq_init(struct device_node *of_node)
clear_c0_status(ST0_IM);
clear_c0_cause(CAUSEF_IP);
- irq_domain = irq_domain_add_legacy(of_node, 8, MIPS_CPU_IRQ_BASE, 0,
- &mips_cpu_intc_irq_domain_ops,
- NULL);
+ irq_domain = irq_domain_create_legacy(of_fwnode_handle(of_node), 8, MIPS_CPU_IRQ_BASE, 0,
+ &mips_cpu_intc_irq_domain_ops, NULL);
if (!irq_domain)
panic("Failed to add irqdomain for MIPS CPU");
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index bca8053864b2..34e8d09c12a0 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -841,10 +841,10 @@ static int gic_register_ipi_domain(struct device_node *node)
struct irq_domain *gic_ipi_domain;
unsigned int v[2], num_ipis;
- gic_ipi_domain = irq_domain_add_hierarchy(gic_irq_domain,
- IRQ_DOMAIN_FLAG_IPI_PER_CPU,
- GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
- node, &gic_ipi_domain_ops, NULL);
+ gic_ipi_domain = irq_domain_create_hierarchy(gic_irq_domain, IRQ_DOMAIN_FLAG_IPI_PER_CPU,
+ GIC_NUM_LOCAL_INTRS + gic_shared_intrs,
+ of_fwnode_handle(node), &gic_ipi_domain_ops,
+ NULL);
if (!gic_ipi_domain) {
pr_err("Failed to add IPI domain");
return -ENXIO;
@@ -963,9 +963,10 @@ static int __init gic_of_init(struct device_node *node,
gic_irq_dispatch);
}
- gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS +
- gic_shared_intrs, 0,
- &gic_irq_domain_ops, NULL);
+ gic_irq_domain = irq_domain_create_simple(of_fwnode_handle(node),
+ GIC_NUM_LOCAL_INTRS +
+ gic_shared_intrs, 0,
+ &gic_irq_domain_ops, NULL);
if (!gic_irq_domain) {
pr_err("Failed to add IRQ domain");
return -ENXIO;
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index 25cf4f80e767..09e640430208 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -261,9 +261,9 @@ static int __init mmp_init_bases(struct device_node *node)
}
icu_data[0].virq_base = 0;
- icu_data[0].domain = irq_domain_add_linear(node, nr_irqs,
- &mmp_irq_domain_ops,
- &icu_data[0]);
+ icu_data[0].domain = irq_domain_create_linear(of_fwnode_handle(node), nr_irqs,
+ &mmp_irq_domain_ops,
+ &icu_data[0]);
for (irq = 0; irq < nr_irqs; irq++) {
ret = irq_create_mapping(icu_data[0].domain, irq);
if (!ret) {
@@ -391,9 +391,9 @@ static int __init mmp2_mux_of_init(struct device_node *node,
return -EINVAL;
icu_data[i].virq_base = 0;
- icu_data[i].domain = irq_domain_add_linear(node, nr_irqs,
- &mmp_irq_domain_ops,
- &icu_data[i]);
+ icu_data[i].domain = irq_domain_create_linear(of_fwnode_handle(node), nr_irqs,
+ &mmp_irq_domain_ops,
+ &icu_data[i]);
for (irq = 0; irq < nr_irqs; irq++) {
ret = irq_create_mapping(icu_data[i].domain, irq);
if (!ret) {
diff --git a/drivers/irqchip/irq-mscc-ocelot.c b/drivers/irqchip/irq-mscc-ocelot.c
index 3dc745b14caf..8cbc191f750b 100644
--- a/drivers/irqchip/irq-mscc-ocelot.c
+++ b/drivers/irqchip/irq-mscc-ocelot.c
@@ -83,7 +83,7 @@ static void ocelot_irq_unmask(struct irq_data *data)
unsigned int mask = data->mask;
u32 val;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
/*
* Clear sticky bits for edge mode interrupts.
* Serval has only one trigger register replication, but the adjacent
@@ -97,7 +97,6 @@ static void ocelot_irq_unmask(struct irq_data *data)
*ct->mask_cache &= ~mask;
irq_reg_writel(gc, mask, p->reg_off_ena_set);
- irq_gc_unlock(gc);
}
static void ocelot_irq_handler(struct irq_desc *desc)
@@ -132,8 +131,8 @@ static int __init vcoreiii_irq_init(struct device_node *node,
if (!parent_irq)
return -EINVAL;
- domain = irq_domain_add_linear(node, p->n_irq,
- &irq_generic_chip_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(node), p->n_irq,
+ &irq_generic_chip_ops, NULL);
if (!domain) {
pr_err("%pOFn: unable to add irq domain\n", node);
return -ENOMEM;
diff --git a/drivers/irqchip/irq-msi-lib.c b/drivers/irqchip/irq-msi-lib.c
index 51464c6257f3..246c30205af4 100644
--- a/drivers/irqchip/irq-msi-lib.c
+++ b/drivers/irqchip/irq-msi-lib.c
@@ -4,7 +4,7 @@
#include <linux/export.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
/**
* msi_lib_init_dev_msi_info - Domain info setup for MSI domains
@@ -105,8 +105,13 @@ bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
* MSI message into the hardware which is the whole purpose of the
* device MSI domain aside of mask/unmask which is provided e.g. by
* PCI/MSI device domains.
+ *
+ * The exception to the rule is when the underlying domain
+ * tells you that affinity is not a thing -- for example when
+ * everything is muxed behind a single interrupt.
*/
- chip->irq_set_affinity = msi_domain_set_affinity;
+ if (!chip->irq_set_affinity && !(info->flags & MSI_FLAG_NO_AFFINITY))
+ chip->irq_set_affinity = msi_domain_set_affinity;
return true;
}
EXPORT_SYMBOL_GPL(msi_lib_init_dev_msi_info);
diff --git a/drivers/irqchip/irq-msi-lib.h b/drivers/irqchip/irq-msi-lib.h
deleted file mode 100644
index 681ceabb7bc7..000000000000
--- a/drivers/irqchip/irq-msi-lib.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-// Copyright (C) 2022 Linutronix GmbH
-// Copyright (C) 2022 Intel
-
-#ifndef _DRIVERS_IRQCHIP_IRQ_MSI_LIB_H
-#define _DRIVERS_IRQCHIP_IRQ_MSI_LIB_H
-
-#include <linux/bits.h>
-#include <linux/irqdomain.h>
-#include <linux/msi.h>
-
-#ifdef CONFIG_PCI_MSI
-#define MATCH_PCI_MSI BIT(DOMAIN_BUS_PCI_MSI)
-#else
-#define MATCH_PCI_MSI (0)
-#endif
-
-#define MATCH_PLATFORM_MSI BIT(DOMAIN_BUS_PLATFORM_MSI)
-
-int msi_lib_irq_domain_select(struct irq_domain *d, struct irq_fwspec *fwspec,
- enum irq_domain_bus_token bus_token);
-
-bool msi_lib_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
- struct irq_domain *real_parent,
- struct msi_domain_info *info);
-
-#endif /* _DRIVERS_IRQCHIP_IRQ_MSI_LIB_H */
diff --git a/drivers/irqchip/irq-mst-intc.c b/drivers/irqchip/irq-mst-intc.c
index f6133ae28155..9643cc3a77d7 100644
--- a/drivers/irqchip/irq-mst-intc.c
+++ b/drivers/irqchip/irq-mst-intc.c
@@ -273,8 +273,8 @@ static int __init mst_intc_of_init(struct device_node *dn,
raw_spin_lock_init(&cd->lock);
cd->irq_start = irq_start;
cd->nr_irqs = irq_end - irq_start + 1;
- domain = irq_domain_add_hierarchy(domain_parent, 0, cd->nr_irqs, dn,
- &mst_intc_domain_ops, cd);
+ domain = irq_domain_create_hierarchy(domain_parent, 0, cd->nr_irqs, of_fwnode_handle(dn),
+ &mst_intc_domain_ops, cd);
if (!domain) {
iounmap(cd->base);
kfree(cd);
diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c
index 76bc0283e3b9..de481ba340f8 100644
--- a/drivers/irqchip/irq-mtk-cirq.c
+++ b/drivers/irqchip/irq-mtk-cirq.c
@@ -336,9 +336,8 @@ static int __init mtk_cirq_of_init(struct device_node *node,
cirq_data->offsets = match->data;
irq_num = cirq_data->ext_irq_end - cirq_data->ext_irq_start + 1;
- domain = irq_domain_add_hierarchy(domain_parent, 0,
- irq_num, node,
- &cirq_domain_ops, cirq_data);
+ domain = irq_domain_create_hierarchy(domain_parent, 0, irq_num, of_fwnode_handle(node),
+ &cirq_domain_ops, cirq_data);
if (!domain) {
ret = -ENOMEM;
goto out_unmap;
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c
index 586e52d5442b..6895e7096b27 100644
--- a/drivers/irqchip/irq-mtk-sysirq.c
+++ b/drivers/irqchip/irq-mtk-sysirq.c
@@ -207,8 +207,8 @@ static int __init mtk_sysirq_of_init(struct device_node *node,
chip_data->which_word[i] = word;
}
- domain = irq_domain_add_hierarchy(domain_parent, 0, intpol_num, node,
- &sysirq_domain_ops, chip_data);
+ domain = irq_domain_create_hierarchy(domain_parent, 0, intpol_num, of_fwnode_handle(node),
+ &sysirq_domain_ops, chip_data);
if (!domain) {
ret = -ENOMEM;
goto out_free_which_word;
diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c
index d67f93f6d750..d3232d6d8dce 100644
--- a/drivers/irqchip/irq-mvebu-gicp.c
+++ b/drivers/irqchip/irq-mvebu-gicp.c
@@ -17,7 +17,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -161,7 +161,7 @@ static const struct irq_domain_ops gicp_domain_ops = {
static const struct msi_parent_ops gicp_msi_parent_ops = {
.supported_flags = GICP_MSI_FLAGS_SUPPORTED,
.required_flags = GICP_MSI_FLAGS_REQUIRED,
- .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI,
.bus_select_token = DOMAIN_BUS_GENERIC_MSI,
.bus_select_mask = MATCH_PLATFORM_MSI,
.prefix = "GICP-",
@@ -170,9 +170,12 @@ static const struct msi_parent_ops gicp_msi_parent_ops = {
static int mvebu_gicp_probe(struct platform_device *pdev)
{
- struct irq_domain *inner_domain, *parent_domain;
struct device_node *node = pdev->dev.of_node;
struct device_node *irq_parent_dn;
+ struct irq_domain_info info = {
+ .fwnode = of_fwnode_handle(node),
+ .ops = &gicp_domain_ops,
+ };
struct mvebu_gicp *gicp;
int ret, i;
@@ -217,30 +220,23 @@ static int mvebu_gicp_probe(struct platform_device *pdev)
if (!gicp->spi_bitmap)
return -ENOMEM;
+ info.size = gicp->spi_cnt;
+ info.host_data = gicp;
+
irq_parent_dn = of_irq_find_parent(node);
if (!irq_parent_dn) {
dev_err(&pdev->dev, "failed to find parent IRQ node\n");
return -ENODEV;
}
- parent_domain = irq_find_host(irq_parent_dn);
+ info.parent = irq_find_host(irq_parent_dn);
of_node_put(irq_parent_dn);
- if (!parent_domain) {
+ if (!info.parent) {
dev_err(&pdev->dev, "failed to find parent IRQ domain\n");
return -ENODEV;
}
- inner_domain = irq_domain_create_hierarchy(parent_domain, 0,
- gicp->spi_cnt,
- of_node_to_fwnode(node),
- &gicp_domain_ops, gicp);
- if (!inner_domain)
- return -ENOMEM;
-
- irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_GENERIC_MSI);
- inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
- inner_domain->msi_parent_ops = &gicp_msi_parent_ops;
- return 0;
+ return msi_create_parent_irq_domain(&info, &gicp_msi_parent_ops) ? 0 : -ENOMEM;
}
static const struct of_device_id mvebu_gicp_of_match[] = {
diff --git a/drivers/irqchip/irq-mvebu-icu.c b/drivers/irqchip/irq-mvebu-icu.c
index 4eebed39880a..db5dbc6e88b0 100644
--- a/drivers/irqchip/irq-mvebu-icu.c
+++ b/drivers/irqchip/irq-mvebu-icu.c
@@ -20,7 +20,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#include <dt-bindings/interrupt-controller/mvebu-icu.h>
diff --git a/drivers/irqchip/irq-mvebu-odmi.c b/drivers/irqchip/irq-mvebu-odmi.c
index 28f7e81df94f..e5b2bde3d933 100644
--- a/drivers/irqchip/irq-mvebu-odmi.c
+++ b/drivers/irqchip/irq-mvebu-odmi.c
@@ -18,7 +18,7 @@
#include <linux/of_address.h>
#include <linux/slab.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -157,7 +157,7 @@ static const struct irq_domain_ops odmi_domain_ops = {
static const struct msi_parent_ops odmi_msi_parent_ops = {
.supported_flags = ODMI_MSI_FLAGS_SUPPORTED,
.required_flags = ODMI_MSI_FLAGS_REQUIRED,
- .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI,
.bus_select_token = DOMAIN_BUS_GENERIC_MSI,
.bus_select_mask = MATCH_PLATFORM_MSI,
.prefix = "ODMI-",
@@ -167,7 +167,12 @@ static const struct msi_parent_ops odmi_msi_parent_ops = {
static int __init mvebu_odmi_init(struct device_node *node,
struct device_node *parent)
{
- struct irq_domain *parent_domain, *inner_domain;
+ struct irq_domain_info info = {
+ .fwnode = of_fwnode_handle(node),
+ .ops = &odmi_domain_ops,
+ .size = odmis_count * NODMIS_PER_FRAME,
+ .parent = irq_find_host(parent),
+ };
int ret, i;
if (of_property_read_u32(node, "marvell,odmi-frames", &odmis_count))
@@ -203,22 +208,10 @@ static int __init mvebu_odmi_init(struct device_node *node,
}
}
- parent_domain = irq_find_host(parent);
+ if (msi_create_parent_irq_domain(&info, &odmi_msi_parent_ops))
+ return 0;
- 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;
- }
-
- irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_GENERIC_MSI);
- inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
- inner_domain->msi_parent_ops = &odmi_msi_parent_ops;
-
- return 0;
+ ret = -ENOMEM;
err_unmap:
for (i = 0; i < odmis_count; i++) {
diff --git a/drivers/irqchip/irq-mvebu-pic.c b/drivers/irqchip/irq-mvebu-pic.c
index 3888b7585981..8db638aa21d2 100644
--- a/drivers/irqchip/irq-mvebu-pic.c
+++ b/drivers/irqchip/irq-mvebu-pic.c
@@ -150,8 +150,8 @@ static int mvebu_pic_probe(struct platform_device *pdev)
return -EINVAL;
}
- pic->domain = irq_domain_add_linear(node, PIC_MAX_IRQS,
- &mvebu_pic_domain_ops, pic);
+ pic->domain = irq_domain_create_linear(of_fwnode_handle(node), PIC_MAX_IRQS,
+ &mvebu_pic_domain_ops, pic);
if (!pic->domain) {
dev_err(&pdev->dev, "Failed to allocate irq domain\n");
return -ENOMEM;
diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
index ebd4a9014e8d..5822ea864765 100644
--- a/drivers/irqchip/irq-mvebu-sei.c
+++ b/drivers/irqchip/irq-mvebu-sei.c
@@ -14,7 +14,7 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
/* Cause register */
#define GICP_SECR(idx) (0x0 + ((idx) * 0x4))
@@ -366,6 +366,10 @@ static const struct msi_parent_ops sei_msi_parent_ops = {
static int mvebu_sei_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
+ struct irq_domain_info info = {
+ .fwnode = of_fwnode_handle(node),
+ .ops = &mvebu_sei_cp_domain_ops,
+ };
struct mvebu_sei *sei;
u32 parent_irq;
int ret;
@@ -402,7 +406,7 @@ static int mvebu_sei_probe(struct platform_device *pdev)
}
/* Create the root SEI domain */
- sei->sei_domain = irq_domain_create_linear(of_node_to_fwnode(node),
+ sei->sei_domain = irq_domain_create_linear(of_fwnode_handle(node),
(sei->caps->ap_range.size +
sei->caps->cp_range.size),
&mvebu_sei_domain_ops,
@@ -418,7 +422,7 @@ static int mvebu_sei_probe(struct platform_device *pdev)
/* Create the 'wired' domain */
sei->ap_domain = irq_domain_create_hierarchy(sei->sei_domain, 0,
sei->caps->ap_range.size,
- of_node_to_fwnode(node),
+ of_fwnode_handle(node),
&mvebu_sei_ap_domain_ops,
sei);
if (!sei->ap_domain) {
@@ -430,21 +434,17 @@ static int mvebu_sei_probe(struct platform_device *pdev)
irq_domain_update_bus_token(sei->ap_domain, DOMAIN_BUS_WIRED);
/* Create the 'MSI' domain */
- sei->cp_domain = irq_domain_create_hierarchy(sei->sei_domain, 0,
- sei->caps->cp_range.size,
- of_node_to_fwnode(node),
- &mvebu_sei_cp_domain_ops,
- sei);
+ info.size = sei->caps->cp_range.size;
+ info.host_data = sei;
+ info.parent = sei->sei_domain;
+
+ sei->cp_domain = msi_create_parent_irq_domain(&info, &sei_msi_parent_ops);
if (!sei->cp_domain) {
pr_err("Failed to create CPs IRQ domain\n");
ret = -ENOMEM;
goto remove_ap_domain;
}
- irq_domain_update_bus_token(sei->cp_domain, DOMAIN_BUS_GENERIC_MSI);
- sei->cp_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
- sei->cp_domain->msi_parent_ops = &sei_msi_parent_ops;
-
mvebu_sei_reset(sei);
irq_set_chained_handler_and_data(parent_irq, mvebu_sei_handle_cascade_irq, sei);
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index d67b5da38982..0bb423dd5280 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -162,8 +162,8 @@ static const struct irq_domain_ops icoll_irq_domain_ops = {
static void __init icoll_add_domain(struct device_node *np,
int num)
{
- icoll_domain = irq_domain_add_linear(np, num,
- &icoll_irq_domain_ops, NULL);
+ icoll_domain = irq_domain_create_linear(of_fwnode_handle(np), num,
+ &icoll_irq_domain_ops, NULL);
if (!icoll_domain)
panic("%pOF: unable to create irq domain", np);
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index ba6332b00a0a..76e11cac9631 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -90,7 +90,7 @@ static int __init nvic_of_init(struct device_node *node,
irqs = NVIC_MAX_IRQ;
nvic_irq_domain =
- irq_domain_add_linear(node, irqs, &nvic_irq_domain_ops, NULL);
+ irq_domain_create_linear(of_fwnode_handle(node), irqs, &nvic_irq_domain_ops, NULL);
if (!nvic_irq_domain) {
pr_warn("Failed to allocate irq domain\n");
diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c
index ad84a2f03368..16f00db570e7 100644
--- a/drivers/irqchip/irq-omap-intc.c
+++ b/drivers/irqchip/irq-omap-intc.c
@@ -248,7 +248,7 @@ static int __init omap_init_irq_of(struct device_node *node)
if (WARN_ON(!omap_irq_base))
return -ENOMEM;
- domain = irq_domain_add_linear(node, omap_nr_irqs,
+ domain = irq_domain_create_linear(of_fwnode_handle(node), omap_nr_irqs,
&irq_generic_chip_ops, NULL);
omap_irq_soft_reset();
@@ -274,7 +274,7 @@ static int __init omap_init_irq_legacy(u32 base, struct device_node *node)
irq_base = 0;
}
- domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0,
+ domain = irq_domain_create_legacy(of_fwnode_handle(node), omap_nr_irqs, irq_base, 0,
&irq_domain_simple_ops, NULL);
omap_irq_soft_reset();
diff --git a/drivers/irqchip/irq-or1k-pic.c b/drivers/irqchip/irq-or1k-pic.c
index f289ccd95291..48126067c54b 100644
--- a/drivers/irqchip/irq-or1k-pic.c
+++ b/drivers/irqchip/irq-or1k-pic.c
@@ -144,8 +144,8 @@ static int __init or1k_pic_init(struct device_node *node,
/* Disable all interrupts until explicitly requested */
mtspr(SPR_PICMR, (0UL));
- root_domain = irq_domain_add_linear(node, 32, &or1k_irq_domain_ops,
- pic);
+ root_domain = irq_domain_create_linear(of_fwnode_handle(node), 32, &or1k_irq_domain_ops,
+ pic);
set_handle_irq(or1k_pic_handle_irq);
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c
index 4e4e874e09a8..dddbc05917c0 100644
--- a/drivers/irqchip/irq-orion.c
+++ b/drivers/irqchip/irq-orion.c
@@ -59,7 +59,7 @@ static int __init orion_irq_init(struct device_node *np,
/* count number of irq chips by valid reg addresses */
num_chips = of_address_count(np);
- orion_irq_domain = irq_domain_add_linear(np,
+ orion_irq_domain = irq_domain_create_linear(of_fwnode_handle(np),
num_chips * ORION_IRQS_PER_CHIP,
&irq_generic_chip_ops, NULL);
if (!orion_irq_domain)
@@ -146,8 +146,8 @@ static int __init orion_bridge_irq_init(struct device_node *np,
/* get optional number of interrupts provided */
of_property_read_u32(np, "marvell,#interrupts", &nrirqs);
- domain = irq_domain_add_linear(np, nrirqs,
- &irq_generic_chip_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(np), nrirqs,
+ &irq_generic_chip_ops, NULL);
if (!domain) {
pr_err("%pOFn: unable to add irq domain\n", np);
return -ENOMEM;
diff --git a/drivers/irqchip/irq-owl-sirq.c b/drivers/irqchip/irq-owl-sirq.c
index 6e4127465094..3d93d21f6732 100644
--- a/drivers/irqchip/irq-owl-sirq.c
+++ b/drivers/irqchip/irq-owl-sirq.c
@@ -323,8 +323,8 @@ static int __init owl_sirq_init(const struct owl_sirq_params *params,
owl_sirq_clear_set_extctl(chip_data, 0, INTC_EXTCTL_CLK_SEL, i);
}
- domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_SIRQ, node,
- &owl_sirq_domain_ops, chip_data);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, NUM_SIRQ, of_fwnode_handle(node),
+ &owl_sirq_domain_ops, chip_data);
if (!domain) {
pr_err("%pOF: failed to add domain\n", node);
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-pic32-evic.c b/drivers/irqchip/irq-pic32-evic.c
index b546b1036e12..5dfda8e8df10 100644
--- a/drivers/irqchip/irq-pic32-evic.c
+++ b/drivers/irqchip/irq-pic32-evic.c
@@ -227,9 +227,9 @@ static int __init pic32_of_init(struct device_node *node,
goto err_iounmap;
}
- evic_irq_domain = irq_domain_add_linear(node, nchips * 32,
- &pic32_irq_domain_ops,
- priv);
+ evic_irq_domain = irq_domain_create_linear(of_fwnode_handle(node), nchips * 32,
+ &pic32_irq_domain_ops,
+ priv);
if (!evic_irq_domain) {
ret = -ENOMEM;
goto err_free_priv;
diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index bee01980b463..87a5813fd835 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -555,8 +555,8 @@ static int pruss_intc_probe(struct platform_device *pdev)
mutex_init(&intc->lock);
- intc->domain = irq_domain_add_linear(dev->of_node, max_system_events,
- &pruss_intc_irq_domain_ops, intc);
+ intc->domain = irq_domain_create_linear(of_fwnode_handle(dev->of_node), max_system_events,
+ &pruss_intc_irq_domain_ops, intc);
if (!intc->domain)
return -ENOMEM;
@@ -581,8 +581,7 @@ static int pruss_intc_probe(struct platform_device *pdev)
host_data->intc = intc;
host_data->host_irq = i;
- irq_set_handler_data(irq, host_data);
- irq_set_chained_handler(irq, pruss_intc_irq_handler);
+ irq_set_chained_handler_and_data(irq, pruss_intc_irq_handler, host_data);
}
return 0;
diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c
index 7942d8eb3d00..8d569f7c5a7a 100644
--- a/drivers/irqchip/irq-qcom-mpm.c
+++ b/drivers/irqchip/irq-qcom-mpm.c
@@ -227,6 +227,9 @@ static int qcom_mpm_alloc(struct irq_domain *domain, unsigned int virq,
if (ret)
return ret;
+ if (pin == GPIO_NO_WAKE_IRQ)
+ return irq_domain_disconnect_hierarchy(domain, virq);
+
ret = irq_domain_set_hwirq_and_chip(domain, virq, pin,
&qcom_mpm_chip, priv);
if (ret)
@@ -447,7 +450,7 @@ static int qcom_mpm_init(struct device_node *np, struct device_node *parent)
priv->domain = irq_domain_create_hierarchy(parent_domain,
IRQ_DOMAIN_FLAG_QCOM_MPM_WAKEUP, pin_cnt,
- of_node_to_fwnode(np), &qcom_mpm_ops, priv);
+ of_fwnode_handle(np), &qcom_mpm_ops, priv);
if (!priv->domain) {
dev_err(dev, "failed to create MPM domain\n");
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c
index 2a349082af81..942c1f8c363d 100644
--- a/drivers/irqchip/irq-realtek-rtl.c
+++ b/drivers/irqchip/irq-realtek-rtl.c
@@ -162,7 +162,7 @@ static int __init realtek_rtl_of_init(struct device_node *node, struct device_no
else if (!parent_irq)
return -ENODEV;
- domain = irq_domain_add_linear(node, RTL_ICTL_NUM_INPUTS, &irq_domain_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(node), RTL_ICTL_NUM_INPUTS, &irq_domain_ops, NULL);
if (!domain)
return -ENOMEM;
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 954419f2460d..0959ed43b1a9 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -513,8 +513,10 @@ static int intc_irqpin_probe(struct platform_device *pdev)
irq_chip->irq_set_wake = intc_irqpin_irq_set_wake;
irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND;
- p->irq_domain = irq_domain_add_simple(dev->of_node, nirqs, 0,
- &intc_irqpin_irq_domain_ops, p);
+ p->irq_domain = irq_domain_create_simple(of_fwnode_handle(dev->of_node),
+ nirqs, 0,
+ &intc_irqpin_irq_domain_ops,
+ p);
if (!p->irq_domain) {
ret = -ENXIO;
dev_err(dev, "cannot initialize irq domain\n");
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index cbce8ffc7de4..5c3196e5a437 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -168,8 +168,8 @@ static int irqc_probe(struct platform_device *pdev)
p->cpu_int_base = p->iomem + IRQC_INT_CPU_BASE(0); /* SYS-SPI */
- p->irq_domain = irq_domain_add_linear(dev->of_node, p->number_of_irqs,
- &irq_generic_chip_ops, p);
+ p->irq_domain = irq_domain_create_linear(of_fwnode_handle(dev->of_node), p->number_of_irqs,
+ &irq_generic_chip_ops, p);
if (!p->irq_domain) {
ret = -ENXIO;
dev_err(dev, "cannot initialize irq domain\n");
diff --git a/drivers/irqchip/irq-renesas-rza1.c b/drivers/irqchip/irq-renesas-rza1.c
index d4e6a68889ec..0a9640ba0adb 100644
--- a/drivers/irqchip/irq-renesas-rza1.c
+++ b/drivers/irqchip/irq-renesas-rza1.c
@@ -231,9 +231,9 @@ static int rza1_irqc_probe(struct platform_device *pdev)
priv->chip.irq_set_type = rza1_irqc_set_type;
priv->chip.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE;
- priv->irq_domain = irq_domain_add_hierarchy(parent, 0, IRQC_NUM_IRQ,
- np, &rza1_irqc_domain_ops,
- priv);
+ priv->irq_domain = irq_domain_create_hierarchy(parent, 0, IRQC_NUM_IRQ,
+ of_fwnode_handle(np), &rza1_irqc_domain_ops,
+ priv);
if (!priv->irq_domain) {
dev_err(dev, "cannot initialize irq domain\n");
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c
index 6a2e41f02446..1e861bd64f97 100644
--- a/drivers/irqchip/irq-renesas-rzg2l.c
+++ b/drivers/irqchip/irq-renesas-rzg2l.c
@@ -574,9 +574,9 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *
raw_spin_lock_init(&rzg2l_irqc_data->lock);
- irq_domain = irq_domain_add_hierarchy(parent_domain, 0, IRQC_NUM_IRQ,
- node, &rzg2l_irqc_domain_ops,
- rzg2l_irqc_data);
+ irq_domain = irq_domain_create_hierarchy(parent_domain, 0, IRQC_NUM_IRQ,
+ of_fwnode_handle(node), &rzg2l_irqc_domain_ops,
+ rzg2l_irqc_data);
if (!irq_domain) {
pm_runtime_put(dev);
return dev_err_probe(dev, -ENOMEM, "failed to add irq domain\n");
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 3d5b5fdf9bde..1c12e6ec1370 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -170,6 +170,14 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
else
tssr &= ~ICU_TSSR_TIEN(tssel_n, priv->info->field_width);
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k));
+
+ /*
+ * A glitch in the edge detection circuit can cause a spurious
+ * interrupt. Clear the status flag after setting the ICU_TSSRk
+ * registers, which is recommended by the hardware manual as a
+ * countermeasure.
+ */
+ writel_relaxed(BIT(tint_nr), priv->base + priv->info->t_offs + ICU_TSCLR);
}
static void rzv2h_icu_irq_disable(struct irq_data *d)
@@ -514,8 +522,9 @@ static int rzv2h_icu_init_common(struct device_node *node, struct device_node *p
raw_spin_lock_init(&rzv2h_icu_data->lock);
- irq_domain = irq_domain_add_hierarchy(parent_domain, 0, ICU_NUM_IRQ, node,
- &rzv2h_icu_domain_ops, rzv2h_icu_data);
+ irq_domain = irq_domain_create_hierarchy(parent_domain, 0, ICU_NUM_IRQ,
+ of_fwnode_handle(node), &rzv2h_icu_domain_ops,
+ rzv2h_icu_data);
if (!irq_domain) {
dev_err(&pdev->dev, "failed to add irq domain\n");
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/irq-riscv-imsic-platform.c
index b8ae67c25b37..1b9fbfce9581 100644
--- a/drivers/irqchip/irq-riscv-imsic-platform.c
+++ b/drivers/irqchip/irq-riscv-imsic-platform.c
@@ -20,7 +20,7 @@
#include <linux/spinlock.h>
#include <linux/smp.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
#include "irq-riscv-imsic-state.h"
static bool imsic_cpu_page_phys(unsigned int cpu, unsigned int guest_index,
diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c
index bdf5cd2037f2..62f76950a113 100644
--- a/drivers/irqchip/irq-riscv-imsic-state.c
+++ b/drivers/irqchip/irq-riscv-imsic-state.c
@@ -208,17 +208,17 @@ skip:
}
#ifdef CONFIG_SMP
-static void __imsic_local_timer_start(struct imsic_local_priv *lpriv)
+static void __imsic_local_timer_start(struct imsic_local_priv *lpriv, unsigned int cpu)
{
lockdep_assert_held(&lpriv->lock);
if (!timer_pending(&lpriv->timer)) {
lpriv->timer.expires = jiffies + 1;
- add_timer_on(&lpriv->timer, smp_processor_id());
+ add_timer_on(&lpriv->timer, cpu);
}
}
#else
-static inline void __imsic_local_timer_start(struct imsic_local_priv *lpriv)
+static inline void __imsic_local_timer_start(struct imsic_local_priv *lpriv, unsigned int cpu)
{
}
#endif
@@ -233,7 +233,7 @@ void imsic_local_sync_all(bool force_all)
if (force_all)
bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1);
if (!__imsic_local_sync(lpriv))
- __imsic_local_timer_start(lpriv);
+ __imsic_local_timer_start(lpriv, smp_processor_id());
raw_spin_unlock_irqrestore(&lpriv->lock, flags);
}
@@ -278,7 +278,7 @@ static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsigned int cpu
return;
}
- __imsic_local_timer_start(lpriv);
+ __imsic_local_timer_start(lpriv, cpu);
}
}
#else
diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
index f653c13de62b..e5805885394e 100644
--- a/drivers/irqchip/irq-riscv-intc.c
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -242,7 +242,7 @@ static int __init riscv_intc_init(struct device_node *node,
chip = &andes_intc_chip;
}
- return riscv_intc_init_common(of_node_to_fwnode(node), chip);
+ return riscv_intc_init_common(of_fwnode_handle(node), chip);
}
IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
diff --git a/drivers/irqchip/irq-sa11x0.c b/drivers/irqchip/irq-sa11x0.c
index 9d0b80271949..d8d4dff16276 100644
--- a/drivers/irqchip/irq-sa11x0.c
+++ b/drivers/irqchip/irq-sa11x0.c
@@ -162,7 +162,7 @@ void __init sa11x0_init_irq_nodt(int irq_start, resource_size_t io_start)
*/
writel_relaxed(1, iobase + ICCR);
- sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
+ sa1100_normal_irqdomain = irq_domain_create_simple(NULL,
32, irq_start,
&sa1100_normal_irqdomain_ops, NULL);
diff --git a/drivers/irqchip/irq-sg2042-msi.c b/drivers/irqchip/irq-sg2042-msi.c
index ee682e87eb8b..af16bc5a3c8b 100644
--- a/drivers/irqchip/irq-sg2042-msi.c
+++ b/drivers/irqchip/irq-sg2042-msi.c
@@ -17,23 +17,38 @@
#include <linux/property.h>
#include <linux/slab.h>
-#include "irq-msi-lib.h"
+#include <linux/irqchip/irq-msi-lib.h>
-#define SG2042_MAX_MSI_VECTOR 32
+struct sg204x_msi_chip_info {
+ const struct irq_chip *irqchip;
+ const struct msi_parent_ops *parent_ops;
+};
+
+/**
+ * struct sg204x_msi_chipdata - chip data for the SG204x MSI IRQ controller
+ * @reg_clr: clear reg, see TRM, 10.1.33, GP_INTR0_CLR
+ * @doorbell_addr: see TRM, 10.1.32, GP_INTR0_SET
+ * @irq_first: First vectors number that MSIs starts
+ * @num_irqs: Number of vectors for MSIs
+ * @msi_map: mapping for allocated MSI vectors.
+ * @msi_map_lock: Lock for msi_map
+ * @chip_info: chip specific infomations
+ */
+struct sg204x_msi_chipdata {
+ void __iomem *reg_clr;
-struct sg2042_msi_chipdata {
- void __iomem *reg_clr; // clear reg, see TRM, 10.1.33, GP_INTR0_CLR
+ phys_addr_t doorbell_addr;
- phys_addr_t doorbell_addr; // see TRM, 10.1.32, GP_INTR0_SET
+ u32 irq_first;
+ u32 num_irqs;
- u32 irq_first; // The vector number that MSIs starts
- u32 num_irqs; // The number of vectors for MSIs
+ unsigned long *msi_map;
+ struct mutex msi_map_lock;
- DECLARE_BITMAP(msi_map, SG2042_MAX_MSI_VECTOR);
- struct mutex msi_map_lock; // lock for msi_map
+ const struct sg204x_msi_chip_info *chip_info;
};
-static int sg2042_msi_allocate_hwirq(struct sg2042_msi_chipdata *data, int num_req)
+static int sg204x_msi_allocate_hwirq(struct sg204x_msi_chipdata *data, int num_req)
{
int first;
@@ -43,7 +58,7 @@ static int sg2042_msi_allocate_hwirq(struct sg2042_msi_chipdata *data, int num_r
return first >= 0 ? first : -ENOSPC;
}
-static void sg2042_msi_free_hwirq(struct sg2042_msi_chipdata *data, int hwirq, int num_req)
+static void sg204x_msi_free_hwirq(struct sg204x_msi_chipdata *data, int hwirq, int num_req)
{
guard(mutex)(&data->msi_map_lock);
bitmap_release_region(data->msi_map, hwirq, get_count_order(num_req));
@@ -51,7 +66,7 @@ static void sg2042_msi_free_hwirq(struct sg2042_msi_chipdata *data, int hwirq, i
static void sg2042_msi_irq_ack(struct irq_data *d)
{
- struct sg2042_msi_chipdata *data = irq_data_get_irq_chip_data(d);
+ struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
int bit_off = d->hwirq;
writel(1 << bit_off, data->reg_clr);
@@ -61,7 +76,7 @@ static void sg2042_msi_irq_ack(struct irq_data *d)
static void sg2042_msi_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
{
- struct sg2042_msi_chipdata *data = irq_data_get_irq_chip_data(d);
+ struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
msg->address_hi = upper_32_bits(data->doorbell_addr);
msg->address_lo = lower_32_bits(data->doorbell_addr);
@@ -79,9 +94,38 @@ static const struct irq_chip sg2042_msi_middle_irq_chip = {
.irq_compose_msi_msg = sg2042_msi_irq_compose_msi_msg,
};
-static int sg2042_msi_parent_domain_alloc(struct irq_domain *domain, unsigned int virq, int hwirq)
+static void sg2044_msi_irq_ack(struct irq_data *d)
+{
+ struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
+
+ writel(0, (u32 __iomem *)data->reg_clr + d->hwirq);
+ irq_chip_ack_parent(d);
+}
+
+static void sg2044_msi_irq_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)
+{
+ struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
+ phys_addr_t doorbell = data->doorbell_addr + 4 * (d->hwirq / 32);
+
+ msg->address_lo = lower_32_bits(doorbell);
+ msg->address_hi = upper_32_bits(doorbell);
+ msg->data = d->hwirq % 32;
+}
+
+static struct irq_chip sg2044_msi_middle_irq_chip = {
+ .name = "SG2044 MSI",
+ .irq_ack = sg2044_msi_irq_ack,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+#endif
+ .irq_compose_msi_msg = sg2044_msi_irq_compose_msi_msg,
+};
+
+static int sg204x_msi_parent_domain_alloc(struct irq_domain *domain, unsigned int virq, int hwirq)
{
- struct sg2042_msi_chipdata *data = domain->host_data;
+ struct sg204x_msi_chipdata *data = domain->host_data;
struct irq_fwspec fwspec;
struct irq_data *d;
int ret;
@@ -99,47 +143,45 @@ static int sg2042_msi_parent_domain_alloc(struct irq_domain *domain, unsigned in
return d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING);
}
-static int sg2042_msi_middle_domain_alloc(struct irq_domain *domain, unsigned int virq,
+static int sg204x_msi_middle_domain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *args)
{
- struct sg2042_msi_chipdata *data = domain->host_data;
+ struct sg204x_msi_chipdata *data = domain->host_data;
int hwirq, err, i;
- hwirq = sg2042_msi_allocate_hwirq(data, nr_irqs);
+ hwirq = sg204x_msi_allocate_hwirq(data, nr_irqs);
if (hwirq < 0)
return hwirq;
for (i = 0; i < nr_irqs; i++) {
- err = sg2042_msi_parent_domain_alloc(domain, virq + i, hwirq + i);
+ err = sg204x_msi_parent_domain_alloc(domain, virq + i, hwirq + i);
if (err)
goto err_hwirq;
irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
- &sg2042_msi_middle_irq_chip, data);
+ data->chip_info->irqchip, data);
}
-
return 0;
err_hwirq:
- sg2042_msi_free_hwirq(data, hwirq, nr_irqs);
+ sg204x_msi_free_hwirq(data, hwirq, nr_irqs);
irq_domain_free_irqs_parent(domain, virq, i);
-
return err;
}
-static void sg2042_msi_middle_domain_free(struct irq_domain *domain, unsigned int virq,
+static void sg204x_msi_middle_domain_free(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs)
{
struct irq_data *d = irq_domain_get_irq_data(domain, virq);
- struct sg2042_msi_chipdata *data = irq_data_get_irq_chip_data(d);
+ struct sg204x_msi_chipdata *data = irq_data_get_irq_chip_data(d);
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
- sg2042_msi_free_hwirq(data, d->hwirq, nr_irqs);
+ sg204x_msi_free_hwirq(data, d->hwirq, nr_irqs);
}
-static const struct irq_domain_ops sg2042_msi_middle_domain_ops = {
- .alloc = sg2042_msi_middle_domain_alloc,
- .free = sg2042_msi_middle_domain_free,
+static const struct irq_domain_ops sg204x_msi_middle_domain_ops = {
+ .alloc = sg204x_msi_middle_domain_alloc,
+ .free = sg204x_msi_middle_domain_free,
.select = msi_lib_irq_domain_select,
};
@@ -151,20 +193,37 @@ static const struct irq_domain_ops sg2042_msi_middle_domain_ops = {
static const struct msi_parent_ops sg2042_msi_parent_ops = {
.required_flags = SG2042_MSI_FLAGS_REQUIRED,
.supported_flags = SG2042_MSI_FLAGS_SUPPORTED,
+ .chip_flags = MSI_CHIP_FLAG_SET_ACK,
.bus_select_mask = MATCH_PCI_MSI,
.bus_select_token = DOMAIN_BUS_NEXUS,
.prefix = "SG2042-",
.init_dev_msi_info = msi_lib_init_dev_msi_info,
};
-static int sg2042_msi_init_domains(struct sg2042_msi_chipdata *data,
+#define SG2044_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
+ MSI_FLAG_USE_DEF_CHIP_OPS)
+
+#define SG2044_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
+ MSI_FLAG_PCI_MSIX)
+
+static const struct msi_parent_ops sg2044_msi_parent_ops = {
+ .required_flags = SG2044_MSI_FLAGS_REQUIRED,
+ .supported_flags = SG2044_MSI_FLAGS_SUPPORTED,
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK,
+ .bus_select_mask = MATCH_PCI_MSI,
+ .bus_select_token = DOMAIN_BUS_NEXUS,
+ .prefix = "SG2044-",
+ .init_dev_msi_info = msi_lib_init_dev_msi_info,
+};
+
+static int sg204x_msi_init_domains(struct sg204x_msi_chipdata *data,
struct irq_domain *plic_domain, struct device *dev)
{
struct fwnode_handle *fwnode = dev_fwnode(dev);
struct irq_domain *middle_domain;
middle_domain = irq_domain_create_hierarchy(plic_domain, 0, data->num_irqs, fwnode,
- &sg2042_msi_middle_domain_ops, data);
+ &sg204x_msi_middle_domain_ops, data);
if (!middle_domain) {
pr_err("Failed to create the MSI middle domain\n");
return -ENOMEM;
@@ -173,24 +232,29 @@ static int sg2042_msi_init_domains(struct sg2042_msi_chipdata *data,
irq_domain_update_bus_token(middle_domain, DOMAIN_BUS_NEXUS);
middle_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
- middle_domain->msi_parent_ops = &sg2042_msi_parent_ops;
-
+ middle_domain->msi_parent_ops = data->chip_info->parent_ops;
return 0;
}
static int sg2042_msi_probe(struct platform_device *pdev)
{
struct fwnode_reference_args args = { };
- struct sg2042_msi_chipdata *data;
+ struct sg204x_msi_chipdata *data;
struct device *dev = &pdev->dev;
struct irq_domain *plic_domain;
struct resource *res;
int ret;
- data = devm_kzalloc(dev, sizeof(struct sg2042_msi_chipdata), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(struct sg204x_msi_chipdata), GFP_KERNEL);
if (!data)
return -ENOMEM;
+ data->chip_info = device_get_match_data(&pdev->dev);
+ if (!data->chip_info) {
+ dev_err(&pdev->dev, "Failed to get irqchip\n");
+ return -EINVAL;
+ }
+
data->reg_clr = devm_platform_ioremap_resource_byname(pdev, "clr");
if (IS_ERR(data->reg_clr)) {
dev_err(dev, "Failed to map clear register\n");
@@ -231,11 +295,28 @@ static int sg2042_msi_probe(struct platform_device *pdev)
mutex_init(&data->msi_map_lock);
- return sg2042_msi_init_domains(data, plic_domain, dev);
+ data->msi_map = devm_bitmap_zalloc(&pdev->dev, data->num_irqs, GFP_KERNEL);
+ if (!data->msi_map) {
+ dev_err(&pdev->dev, "Unable to allocate msi mapping\n");
+ return -ENOMEM;
+ }
+
+ return sg204x_msi_init_domains(data, plic_domain, dev);
}
+static const struct sg204x_msi_chip_info sg2042_chip_info = {
+ .irqchip = &sg2042_msi_middle_irq_chip,
+ .parent_ops = &sg2042_msi_parent_ops,
+};
+
+static const struct sg204x_msi_chip_info sg2044_chip_info = {
+ .irqchip = &sg2044_msi_middle_irq_chip,
+ .parent_ops = &sg2044_msi_parent_ops,
+};
+
static const struct of_device_id sg2042_msi_of_match[] = {
- { .compatible = "sophgo,sg2042-msi" },
+ { .compatible = "sophgo,sg2042-msi", .data = &sg2042_chip_info },
+ { .compatible = "sophgo,sg2044-msi", .data = &sg2044_chip_info },
{ }
};
diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c
index c7db617e1a2f..0cad68aa8388 100644
--- a/drivers/irqchip/irq-sni-exiu.c
+++ b/drivers/irqchip/irq-sni-exiu.c
@@ -249,12 +249,12 @@ static int __init exiu_dt_init(struct device_node *node,
return -ENXIO;
}
- data = exiu_init(of_node_to_fwnode(node), &res);
+ data = exiu_init(of_fwnode_handle(node), &res);
if (IS_ERR(data))
return PTR_ERR(data);
- domain = irq_domain_add_hierarchy(parent_domain, 0, NUM_IRQS, node,
- &exiu_domain_ops, data);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, NUM_IRQS, of_fwnode_handle(node),
+ &exiu_domain_ops, data);
if (!domain) {
pr_err("%pOF: failed to allocate domain\n", node);
goto out_unmap;
diff --git a/drivers/irqchip/irq-sp7021-intc.c b/drivers/irqchip/irq-sp7021-intc.c
index bed78d1def3d..2a6eda9ab62e 100644
--- a/drivers/irqchip/irq-sp7021-intc.c
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -256,8 +256,8 @@ static int __init sp_intc_init_dt(struct device_node *node, struct device_node *
writel_relaxed(~0, REG_INTR_CLEAR + i * 4);
}
- sp_intc.domain = irq_domain_add_linear(node, SP_INTC_NR_IRQS,
- &sp_intc_dm_ops, &sp_intc);
+ sp_intc.domain = irq_domain_create_linear(of_fwnode_handle(node), SP_INTC_NR_IRQS,
+ &sp_intc_dm_ops, &sp_intc);
if (!sp_intc.domain) {
ret = -ENOMEM;
goto out_unmap1;
diff --git a/drivers/irqchip/irq-starfive-jh8100-intc.c b/drivers/irqchip/irq-starfive-jh8100-intc.c
index 0f5837176e53..2460798ec158 100644
--- a/drivers/irqchip/irq-starfive-jh8100-intc.c
+++ b/drivers/irqchip/irq-starfive-jh8100-intc.c
@@ -158,8 +158,8 @@ static int __init starfive_intc_init(struct device_node *intc,
raw_spin_lock_init(&irqc->lock);
- irqc->domain = irq_domain_add_linear(intc, STARFIVE_INTC_SRC_IRQ_NUM,
- &starfive_intc_domain_ops, irqc);
+ irqc->domain = irq_domain_create_linear(of_fwnode_handle(intc), STARFIVE_INTC_SRC_IRQ_NUM,
+ &starfive_intc_domain_ops, irqc);
if (!irqc->domain) {
pr_err("Unable to create IRQ domain\n");
ret = -EINVAL;
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index 7c6a0080c330..978811f2abe8 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -169,22 +169,18 @@ static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
u32 rtsr, ftsr;
int err;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
err = stm32_exti_set_type(d, type, &rtsr, &ftsr);
if (err)
- goto unlock;
+ return err;
irq_reg_writel(gc, rtsr, stm32_bank->rtsr_ofst);
irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst);
-
-unlock:
- irq_gc_unlock(gc);
-
- return err;
+ return 0;
}
static void stm32_chip_suspend(struct stm32_exti_chip_data *chip_data,
@@ -217,18 +213,16 @@ static void stm32_irq_suspend(struct irq_chip_generic *gc)
{
struct stm32_exti_chip_data *chip_data = gc->private;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
stm32_chip_suspend(chip_data, gc->wake_active);
- irq_gc_unlock(gc);
}
static void stm32_irq_resume(struct irq_chip_generic *gc)
{
struct stm32_exti_chip_data *chip_data = gc->private;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
stm32_chip_resume(chip_data, gc->mask_cache);
- irq_gc_unlock(gc);
}
static int stm32_exti_alloc(struct irq_domain *d, unsigned int virq,
@@ -265,11 +259,8 @@ static void stm32_irq_ack(struct irq_data *d)
struct stm32_exti_chip_data *chip_data = gc->private;
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
- irq_gc_lock(gc);
-
+ guard(raw_spinlock)(&gc->lock);
irq_reg_writel(gc, d->mask, stm32_bank->rpr_ofst);
-
- irq_gc_unlock(gc);
}
static struct
@@ -344,8 +335,8 @@ static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
if (!host_data)
return -ENOMEM;
- domain = irq_domain_add_linear(node, drv_data->bank_nr * IRQS_PER_BANK,
- &irq_exti_domain_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(node), drv_data->bank_nr * IRQS_PER_BANK,
+ &irq_exti_domain_ops, NULL);
if (!domain) {
pr_err("%pOFn: Could not register interrupt domain.\n",
node);
diff --git a/drivers/irqchip/irq-stm32mp-exti.c b/drivers/irqchip/irq-stm32mp-exti.c
index cb83d6cc6113..c6b4407d05f9 100644
--- a/drivers/irqchip/irq-stm32mp-exti.c
+++ b/drivers/irqchip/irq-stm32mp-exti.c
@@ -531,7 +531,7 @@ static int stm32mp_exti_domain_alloc(struct irq_domain *dm,
if (ret)
return ret;
/* we only support one parent, so far */
- if (of_node_to_fwnode(out_irq.np) != dm->parent->fwnode)
+ if (of_fwnode_handle(out_irq.np) != dm->parent->fwnode)
return -EINVAL;
of_phandle_args_to_fwspec(out_irq.np, out_irq.args,
@@ -682,10 +682,9 @@ static int stm32mp_exti_probe(struct platform_device *pdev)
return -EINVAL;
}
- domain = irq_domain_add_hierarchy(parent_domain, 0,
- drv_data->bank_nr * IRQS_PER_BANK,
- np, &stm32mp_exti_domain_ops,
- host_data);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, drv_data->bank_nr * IRQS_PER_BANK,
+ of_fwnode_handle(np), &stm32mp_exti_domain_ops,
+ host_data);
if (!domain) {
dev_err(dev, "Could not register exti domain\n");
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c
index dd506ebfdacb..9c2c9caeca2a 100644
--- a/drivers/irqchip/irq-sun4i.c
+++ b/drivers/irqchip/irq-sun4i.c
@@ -133,7 +133,7 @@ static int __init sun4i_of_init(struct device_node *node,
/* Configure the external interrupt source type */
writel(0x00, irq_ic_data->irq_base + SUN4I_IRQ_NMI_CTRL_REG);
- irq_ic_data->irq_domain = irq_domain_add_linear(node, 3 * 32,
+ irq_ic_data->irq_domain = irq_domain_create_linear(of_fwnode_handle(node), 3 * 32,
&sun4i_irq_ops, NULL);
if (!irq_ic_data->irq_domain)
panic("%pOF: unable to create IRQ domain\n", node);
diff --git a/drivers/irqchip/irq-sun6i-r.c b/drivers/irqchip/irq-sun6i-r.c
index 99958d470d62..37d4b29763bc 100644
--- a/drivers/irqchip/irq-sun6i-r.c
+++ b/drivers/irqchip/irq-sun6i-r.c
@@ -338,8 +338,8 @@ static int __init sun6i_r_intc_init(struct device_node *node,
return PTR_ERR(base);
}
- domain = irq_domain_add_hierarchy(parent_domain, 0, 0, node,
- &sun6i_r_intc_domain_ops, NULL);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, 0, of_fwnode_handle(node),
+ &sun6i_r_intc_domain_ops, NULL);
if (!domain) {
pr_err("%pOF: Failed to allocate domain\n", node);
iounmap(base);
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c
index 01b0d8321728..fe32dfdc2dd0 100644
--- a/drivers/irqchip/irq-sunxi-nmi.c
+++ b/drivers/irqchip/irq-sunxi-nmi.c
@@ -111,7 +111,7 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type)
unsigned int src_type;
unsigned int i;
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
switch (flow_type & IRQF_TRIGGER_MASK) {
case IRQ_TYPE_EDGE_FALLING:
@@ -128,9 +128,7 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type)
src_type = SUNXI_SRC_TYPE_LEVEL_LOW;
break;
default:
- irq_gc_unlock(gc);
- pr_err("Cannot assign multiple trigger modes to IRQ %d.\n",
- data->irq);
+ pr_err("Cannot assign multiple trigger modes to IRQ %d.\n", data->irq);
return -EBADR;
}
@@ -145,9 +143,6 @@ static int sunxi_sc_nmi_set_type(struct irq_data *data, unsigned int flow_type)
src_type_reg &= ~SUNXI_NMI_SRC_TYPE_MASK;
src_type_reg |= src_type;
sunxi_sc_nmi_write(gc, ctrl_off, src_type_reg);
-
- irq_gc_unlock(gc);
-
return IRQ_SET_MASK_OK;
}
@@ -159,7 +154,7 @@ static int __init sunxi_sc_nmi_irq_init(struct device_node *node,
struct irq_domain *domain;
int ret;
- domain = irq_domain_add_linear(node, 1, &irq_generic_chip_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(node), 1, &irq_generic_chip_ops, NULL);
if (!domain) {
pr_err("Could not register interrupt domain.\n");
return -ENOMEM;
diff --git a/drivers/irqchip/irq-tb10x.c b/drivers/irqchip/irq-tb10x.c
index d59bfbe8c6d0..94cbc5111d7e 100644
--- a/drivers/irqchip/irq-tb10x.c
+++ b/drivers/irqchip/irq-tb10x.c
@@ -41,11 +41,9 @@ static inline u32 ab_irqctl_readreg(struct irq_chip_generic *gc, u32 reg)
static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
- uint32_t im, mod, pol;
+ uint32_t mod, pol, im = data->mask;
- im = data->mask;
-
- irq_gc_lock(gc);
+ guard(raw_spinlock)(&gc->lock);
mod = ab_irqctl_readreg(gc, AB_IRQCTL_SRC_MODE) | im;
pol = ab_irqctl_readreg(gc, AB_IRQCTL_SRC_POLARITY) | im;
@@ -67,9 +65,7 @@ static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type)
case IRQ_TYPE_EDGE_RISING:
break;
default:
- irq_gc_unlock(gc);
- pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n",
- __func__, data->irq);
+ pr_err("%s: Cannot assign multiple trigger modes to IRQ %d.\n", __func__, data->irq);
return -EBADR;
}
@@ -79,9 +75,6 @@ static int tb10x_irq_set_type(struct irq_data *data, unsigned int flow_type)
ab_irqctl_writereg(gc, AB_IRQCTL_SRC_MODE, mod);
ab_irqctl_writereg(gc, AB_IRQCTL_SRC_POLARITY, pol);
ab_irqctl_writereg(gc, AB_IRQCTL_INT_STATUS, im);
-
- irq_gc_unlock(gc);
-
return IRQ_SET_MASK_OK;
}
@@ -121,13 +114,13 @@ static int __init of_tb10x_init_irq(struct device_node *ictl,
goto ioremap_fail;
}
- domain = irq_domain_add_linear(ictl, AB_IRQCTL_MAXIRQ,
- &irq_generic_chip_ops, NULL);
+ domain = irq_domain_create_linear(of_fwnode_handle(ictl), AB_IRQCTL_MAXIRQ,
+ &irq_generic_chip_ops, NULL);
if (!domain) {
ret = -ENOMEM;
pr_err("%pOFn: Could not register interrupt domain.\n",
ictl);
- goto irq_domain_add_fail;
+ goto irq_domain_create_fail;
}
ret = irq_alloc_domain_generic_chips(domain, AB_IRQCTL_MAXIRQ,
@@ -174,7 +167,7 @@ static int __init of_tb10x_init_irq(struct device_node *ictl,
gc_alloc_fail:
irq_domain_remove(domain);
-irq_domain_add_fail:
+irq_domain_create_fail:
iounmap(reg_base);
ioremap_fail:
release_mem_region(mem.start, resource_size(&mem));
diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
index ad3e2c1b3c87..66cbb9f77ff3 100644
--- a/drivers/irqchip/irq-tegra.c
+++ b/drivers/irqchip/irq-tegra.c
@@ -330,9 +330,8 @@ static int __init tegra_ictlr_init(struct device_node *node,
node, num_ictlrs, soc->num_ictlrs);
- domain = irq_domain_add_hierarchy(parent_domain, 0, num_ictlrs * 32,
- node, &tegra_ictlr_domain_ops,
- lic);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, num_ictlrs * 32,
+ of_fwnode_handle(node), &tegra_ictlr_domain_ops, lic);
if (!domain) {
pr_err("%pOF: failed to allocated domain\n", node);
err = -ENOMEM;
diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
index a887efba262c..7de59238e6b0 100644
--- a/drivers/irqchip/irq-ti-sci-inta.c
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -233,7 +233,7 @@ static struct ti_sci_inta_vint_desc *ti_sci_inta_alloc_parent_irq(struct irq_dom
INIT_LIST_HEAD(&vint_desc->list);
parent_node = of_irq_find_parent(dev_of_node(&inta->pdev->dev));
- parent_fwspec.fwnode = of_node_to_fwnode(parent_node);
+ parent_fwspec.fwnode = of_fwnode_handle(parent_node);
if (of_device_is_compatible(parent_node, "arm,gic-v3")) {
/* Parent is GIC */
@@ -701,15 +701,15 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
if (ret)
return ret;
- domain = irq_domain_add_linear(dev_of_node(dev),
- ti_sci_get_num_resources(inta->vint),
- &ti_sci_inta_irq_domain_ops, inta);
+ domain = irq_domain_create_linear(of_fwnode_handle(dev_of_node(dev)),
+ ti_sci_get_num_resources(inta->vint),
+ &ti_sci_inta_irq_domain_ops, inta);
if (!domain) {
dev_err(dev, "Failed to allocate IRQ domain\n");
return -ENOMEM;
}
- msi_domain = ti_sci_inta_msi_create_irq_domain(of_node_to_fwnode(node),
+ msi_domain = ti_sci_inta_msi_create_irq_domain(of_fwnode_handle(node),
&ti_sci_inta_msi_domain_info,
domain);
if (!msi_domain) {
diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
index b49a73106c69..07fff5ae5ce0 100644
--- a/drivers/irqchip/irq-ti-sci-intr.c
+++ b/drivers/irqchip/irq-ti-sci-intr.c
@@ -149,7 +149,7 @@ static int ti_sci_intr_alloc_parent_irq(struct irq_domain *domain,
goto err_irqs;
parent_node = of_irq_find_parent(dev_of_node(intr->dev));
- fwspec.fwnode = of_node_to_fwnode(parent_node);
+ fwspec.fwnode = of_fwnode_handle(parent_node);
if (of_device_is_compatible(parent_node, "arm,gic-v3")) {
/* Parent is GIC */
@@ -274,8 +274,9 @@ static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev)
return PTR_ERR(intr->out_irqs);
}
- domain = irq_domain_add_hierarchy(parent_domain, 0, 0, dev_of_node(dev),
- &ti_sci_intr_irq_domain_ops, intr);
+ domain = irq_domain_create_hierarchy(parent_domain, 0, 0,
+ of_fwnode_handle(dev_of_node(dev)),
+ &ti_sci_intr_irq_domain_ops, intr);
if (!domain) {
dev_err(dev, "Failed to allocate IRQ domain\n");
return -ENOMEM;
diff --git a/drivers/irqchip/irq-ts4800.c b/drivers/irqchip/irq-ts4800.c
index 960c343d5781..e625f4fb2bb8 100644
--- a/drivers/irqchip/irq-ts4800.c
+++ b/drivers/irqchip/irq-ts4800.c
@@ -125,7 +125,7 @@ static int ts4800_ic_probe(struct platform_device *pdev)
return -EINVAL;
}
- data->domain = irq_domain_add_linear(node, 8, &ts4800_ic_ops, data);
+ data->domain = irq_domain_create_linear(of_fwnode_handle(node), 8, &ts4800_ic_ops, data);
if (!data->domain) {
dev_err(&pdev->dev, "cannot add IRQ domain\n");
return -ENOMEM;
diff --git a/drivers/irqchip/irq-uniphier-aidet.c b/drivers/irqchip/irq-uniphier-aidet.c
index 601f9343d5b3..6005c2d28dd9 100644
--- a/drivers/irqchip/irq-uniphier-aidet.c
+++ b/drivers/irqchip/irq-uniphier-aidet.c
@@ -188,7 +188,7 @@ static int uniphier_aidet_probe(struct platform_device *pdev)
priv->domain = irq_domain_create_hierarchy(
parent_domain, 0,
UNIPHIER_AIDET_NR_IRQS,
- of_node_to_fwnode(dev->of_node),
+ of_fwnode_handle(dev->of_node),
&uniphier_aidet_domain_ops, priv);
if (!priv->domain)
return -ENOMEM;
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index 0abc8934c2ee..034ce6afe170 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -176,8 +176,8 @@ static void __init fpga_irq_init(void __iomem *base, int parent_irq,
f);
}
- f->domain = irq_domain_add_linear(node, fls(valid),
- &fpga_irqdomain_ops, f);
+ f->domain = irq_domain_create_linear(of_fwnode_handle(node), fls(valid),
+ &fpga_irqdomain_ops, f);
/* This will allocate all valid descriptors in the linear case */
for (i = 0; i < fls(valid); i++)
diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c
index 2b9a8ba58e26..5d9c7503aa7f 100644
--- a/drivers/irqchip/irq-vf610-mscm-ir.c
+++ b/drivers/irqchip/irq-vf610-mscm-ir.c
@@ -209,9 +209,9 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node,
regmap_read(mscm_cp_regmap, MSCM_CPxNUM, &cpuid);
mscm_ir_data->cpu_mask = 0x1 << cpuid;
- domain = irq_domain_add_hierarchy(domain_parent, 0,
- MSCM_IRSPRC_NUM, node,
- &mscm_irq_domain_ops, mscm_ir_data);
+ domain = irq_domain_create_hierarchy(domain_parent, 0, MSCM_IRSPRC_NUM,
+ of_fwnode_handle(node), &mscm_irq_domain_ops,
+ mscm_ir_data);
if (!domain) {
ret = -ENOMEM;
goto out_unmap;
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index ea93e7236c4a..2bcdf216a000 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -289,8 +289,9 @@ static void __init vic_register(void __iomem *base, unsigned int parent_irq,
vic_handle_irq_cascaded, v);
}
- v->domain = irq_domain_add_simple(node, fls(valid_sources), irq,
- &vic_irqdomain_ops, v);
+ v->domain = irq_domain_create_simple(of_fwnode_handle(node),
+ fls(valid_sources), irq,
+ &vic_irqdomain_ops, v);
/* create an IRQ mapping for each valid IRQ */
for (i = 0; i < fls(valid_sources); i++)
if (valid_sources & (1 << i))
diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c
index e17dd3a8c2d5..3b742590aec8 100644
--- a/drivers/irqchip/irq-vt8500.c
+++ b/drivers/irqchip/irq-vt8500.c
@@ -15,6 +15,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
@@ -63,29 +64,28 @@ struct vt8500_irq_data {
struct irq_domain *domain; /* Domain for this controller */
};
-/* Global variable for accessing io-mem addresses */
-static struct vt8500_irq_data intc[VT8500_INTC_MAX];
-static u32 active_cnt = 0;
+/* Primary interrupt controller data */
+static struct vt8500_irq_data *primary_intc;
-static void vt8500_irq_mask(struct irq_data *d)
+static void vt8500_irq_ack(struct irq_data *d)
{
struct vt8500_irq_data *priv = d->domain->host_data;
void __iomem *base = priv->base;
void __iomem *stat_reg = base + VT8500_ICIS + (d->hwirq < 32 ? 0 : 4);
- u8 edge, dctr;
- u32 status;
+ u32 status = (1 << (d->hwirq & 0x1f));
- edge = readb(base + VT8500_ICDC + d->hwirq) & VT8500_EDGE;
- if (edge) {
- status = readl(stat_reg);
+ writel(status, stat_reg);
+}
- status |= (1 << (d->hwirq & 0x1f));
- writel(status, stat_reg);
- } else {
- dctr = readb(base + VT8500_ICDC + d->hwirq);
- dctr &= ~VT8500_INT_ENABLE;
- writeb(dctr, base + VT8500_ICDC + d->hwirq);
- }
+static void vt8500_irq_mask(struct irq_data *d)
+{
+ struct vt8500_irq_data *priv = d->domain->host_data;
+ void __iomem *base = priv->base;
+ u8 dctr;
+
+ dctr = readb(base + VT8500_ICDC + d->hwirq);
+ dctr &= ~VT8500_INT_ENABLE;
+ writeb(dctr, base + VT8500_ICDC + d->hwirq);
}
static void vt8500_irq_unmask(struct irq_data *d)
@@ -130,11 +130,11 @@ static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
}
static struct irq_chip vt8500_irq_chip = {
- .name = "vt8500",
- .irq_ack = vt8500_irq_mask,
- .irq_mask = vt8500_irq_mask,
- .irq_unmask = vt8500_irq_unmask,
- .irq_set_type = vt8500_irq_set_type,
+ .name = "vt8500",
+ .irq_ack = vt8500_irq_ack,
+ .irq_mask = vt8500_irq_mask,
+ .irq_unmask = vt8500_irq_unmask,
+ .irq_set_type = vt8500_irq_set_type,
};
static void __init vt8500_init_irq_hw(void __iomem *base)
@@ -163,82 +163,89 @@ static const struct irq_domain_ops vt8500_irq_domain_ops = {
.xlate = irq_domain_xlate_onecell,
};
+static inline void vt8500_handle_irq_common(struct vt8500_irq_data *intc)
+{
+ unsigned long irqnr = readl_relaxed(intc->base) & 0x3F;
+ unsigned long stat;
+
+ /*
+ * Highest Priority register default = 63, so check that this
+ * is a real interrupt by checking the status register
+ */
+ if (irqnr == 63) {
+ stat = readl_relaxed(intc->base + VT8500_ICIS + 4);
+ if (!(stat & BIT(31)))
+ return;
+ }
+
+ generic_handle_domain_irq(intc->domain, irqnr);
+}
+
static void __exception_irq_entry vt8500_handle_irq(struct pt_regs *regs)
{
- u32 stat, i;
- int irqnr;
- void __iomem *base;
-
- /* Loop through each active controller */
- for (i=0; i<active_cnt; i++) {
- base = intc[i].base;
- irqnr = readl_relaxed(base) & 0x3F;
- /*
- Highest Priority register default = 63, so check that this
- is a real interrupt by checking the status register
- */
- if (irqnr == 63) {
- stat = readl_relaxed(base + VT8500_ICIS + 4);
- if (!(stat & BIT(31)))
- continue;
- }
+ vt8500_handle_irq_common(primary_intc);
+}
- generic_handle_domain_irq(intc[i].domain, irqnr);
- }
+static void vt8500_handle_irq_chained(struct irq_desc *desc)
+{
+ struct irq_domain *d = irq_desc_get_handler_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct vt8500_irq_data *intc = d->host_data;
+
+ chained_irq_enter(chip, desc);
+ vt8500_handle_irq_common(intc);
+ chained_irq_exit(chip, desc);
}
static int __init vt8500_irq_init(struct device_node *node,
struct device_node *parent)
{
- int irq, i;
- struct device_node *np = node;
+ struct vt8500_irq_data *intc;
+ int irq, i, ret = 0;
- if (active_cnt == VT8500_INTC_MAX) {
- pr_err("%s: Interrupt controllers > VT8500_INTC_MAX\n",
- __func__);
- goto out;
- }
+ intc = kzalloc(sizeof(*intc), GFP_KERNEL);
+ if (!intc)
+ return -ENOMEM;
- intc[active_cnt].base = of_iomap(np, 0);
- intc[active_cnt].domain = irq_domain_add_linear(node, 64,
- &vt8500_irq_domain_ops, &intc[active_cnt]);
-
- if (!intc[active_cnt].base) {
+ intc->base = of_iomap(node, 0);
+ if (!intc->base) {
pr_err("%s: Unable to map IO memory\n", __func__);
- goto out;
+ ret = -ENOMEM;
+ goto err_free;
}
- if (!intc[active_cnt].domain) {
+ intc->domain = irq_domain_create_linear(of_fwnode_handle(node), 64,
+ &vt8500_irq_domain_ops, intc);
+ if (!intc->domain) {
pr_err("%s: Unable to add irq domain!\n", __func__);
- goto out;
+ ret = -ENOMEM;
+ goto err_unmap;
}
- set_handle_irq(vt8500_handle_irq);
-
- vt8500_init_irq_hw(intc[active_cnt].base);
+ vt8500_init_irq_hw(intc->base);
pr_info("vt8500-irq: Added interrupt controller\n");
- active_cnt++;
-
- /* check if this is a slaved controller */
- if (of_irq_count(np) != 0) {
- /* check that we have the correct number of interrupts */
- if (of_irq_count(np) != 8) {
- pr_err("%s: Incorrect IRQ map for slaved controller\n",
- __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < 8; i++) {
- irq = irq_of_parse_and_map(np, i);
- enable_irq(irq);
+ /* check if this is a chained controller */
+ if (of_irq_count(node) != 0) {
+ for (i = 0; i < of_irq_count(node); i++) {
+ irq = irq_of_parse_and_map(node, i);
+ irq_set_chained_handler_and_data(irq, vt8500_handle_irq_chained,
+ intc);
}
pr_info("vt8500-irq: Enabled slave->parent interrupts\n");
+ } else {
+ primary_intc = intc;
+ set_handle_irq(vt8500_handle_irq);
}
-out:
return 0;
+
+err_unmap:
+ iounmap(intc->base);
+err_free:
+ kfree(intc);
+ return ret;
}
IRQCHIP_DECLARE(vt8500_irq, "via,vt8500-intc", vt8500_irq_init);
diff --git a/drivers/irqchip/irq-wpcm450-aic.c b/drivers/irqchip/irq-wpcm450-aic.c
index 91df62a64cd9..a8ed4894d29e 100644
--- a/drivers/irqchip/irq-wpcm450-aic.c
+++ b/drivers/irqchip/irq-wpcm450-aic.c
@@ -154,7 +154,7 @@ static int __init wpcm450_aic_of_init(struct device_node *node,
set_handle_irq(wpcm450_aic_handle_irq);
- aic->domain = irq_domain_add_linear(node, AIC_NUM_IRQS, &wpcm450_aic_ops, aic);
+ aic->domain = irq_domain_create_linear(of_fwnode_handle(node), AIC_NUM_IRQS, &wpcm450_aic_ops, aic);
return 0;
}
diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c
index 38727e9cc713..92dcb9fdcb25 100644
--- a/drivers/irqchip/irq-xilinx-intc.c
+++ b/drivers/irqchip/irq-xilinx-intc.c
@@ -212,8 +212,8 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
xintc_write(irqc, MER, MER_HIE | MER_ME);
}
- irqc->root_domain = irq_domain_add_linear(intc, irqc->nr_irq,
- &xintc_irq_domain_ops, irqc);
+ irqc->root_domain = irq_domain_create_linear(of_fwnode_handle(intc), irqc->nr_irq,
+ &xintc_irq_domain_ops, irqc);
if (!irqc->root_domain) {
pr_err("irq-xilinx: Unable to create IRQ domain\n");
ret = -EINVAL;
diff --git a/drivers/irqchip/irq-xtensa-mx.c b/drivers/irqchip/irq-xtensa-mx.c
index 9b441d180299..9fdacbd89a63 100644
--- a/drivers/irqchip/irq-xtensa-mx.c
+++ b/drivers/irqchip/irq-xtensa-mx.c
@@ -167,8 +167,7 @@ static void __init xtensa_mx_init_common(struct irq_domain *root_domain)
int __init xtensa_mx_init_legacy(struct device_node *interrupt_parent)
{
struct irq_domain *root_domain =
- irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,
- &xtensa_mx_irq_domain_ops,
+ irq_domain_create_legacy(NULL, NR_IRQS - 1, 1, 0, &xtensa_mx_irq_domain_ops,
&xtensa_mx_irq_chip);
xtensa_mx_init_common(root_domain);
return 0;
@@ -178,7 +177,7 @@ static int __init xtensa_mx_init(struct device_node *np,
struct device_node *interrupt_parent)
{
struct irq_domain *root_domain =
- irq_domain_add_linear(np, NR_IRQS, &xtensa_mx_irq_domain_ops,
+ irq_domain_create_linear(of_fwnode_handle(np), NR_IRQS, &xtensa_mx_irq_domain_ops,
&xtensa_mx_irq_chip);
xtensa_mx_init_common(root_domain);
return 0;
diff --git a/drivers/irqchip/irq-xtensa-pic.c b/drivers/irqchip/irq-xtensa-pic.c
index 9be7b7c5cd23..44e7be051a2e 100644
--- a/drivers/irqchip/irq-xtensa-pic.c
+++ b/drivers/irqchip/irq-xtensa-pic.c
@@ -85,7 +85,7 @@ static struct irq_chip xtensa_irq_chip = {
int __init xtensa_pic_init_legacy(struct device_node *interrupt_parent)
{
struct irq_domain *root_domain =
- irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,
+ irq_domain_create_legacy(NULL, NR_IRQS - 1, 1, 0,
&xtensa_irq_domain_ops, &xtensa_irq_chip);
irq_set_default_domain(root_domain);
return 0;
@@ -95,7 +95,7 @@ static int __init xtensa_pic_init(struct device_node *np,
struct device_node *interrupt_parent)
{
struct irq_domain *root_domain =
- irq_domain_add_linear(np, NR_IRQS, &xtensa_irq_domain_ops,
+ irq_domain_create_linear(of_fwnode_handle(np), NR_IRQS, &xtensa_irq_domain_ops,
&xtensa_irq_chip);
irq_set_default_domain(root_domain);
return 0;
diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c
index 7a72620fc478..22d46c246594 100644
--- a/drivers/irqchip/irq-zevio.c
+++ b/drivers/irqchip/irq-zevio.c
@@ -92,8 +92,8 @@ static int __init zevio_of_init(struct device_node *node,
zevio_init_irq_base(zevio_irq_io + IO_IRQ_BASE);
zevio_init_irq_base(zevio_irq_io + IO_FIQ_BASE);
- zevio_irq_domain = irq_domain_add_linear(node, MAX_INTRS,
- &irq_generic_chip_ops, NULL);
+ zevio_irq_domain = irq_domain_create_linear(of_fwnode_handle(node), MAX_INTRS,
+ &irq_generic_chip_ops, NULL);
BUG_ON(!zevio_irq_domain);
ret = irq_alloc_domain_generic_chips(zevio_irq_domain, MAX_INTRS, 1,
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
index 7c17a6f643ef..576e55569d77 100644
--- a/drivers/irqchip/spear-shirq.c
+++ b/drivers/irqchip/spear-shirq.c
@@ -239,7 +239,7 @@ static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
goto err_unmap;
}
- shirq_domain = irq_domain_add_legacy(np, nr_irqs, virq_base, 0,
+ shirq_domain = irq_domain_create_legacy(of_fwnode_handle(np), nr_irqs, virq_base, 0,
&irq_domain_simple_ops, NULL);
if (WARN_ON(!shirq_domain)) {
pr_warn("%s: irq domain init failed\n", __func__);