From nobody Mon Dec 1 21:31:51 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD84A286D60 for ; Mon, 1 Dec 2025 06:51:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764571893; cv=none; b=KlvrGFP8yx639MtnPlSzcpOu0YRtc6IZ9EwybFCnE6KVWTNOFE6WUv7wm2MCrD0H859lZc6r7Rp29v+CVHzaVP0pa87/X6bUpqz/xYHF8afn9AgmTeg/RQ84u33mi7ANxiWmXQfeUWZzMEmnnjgoGbQ4en9Gpxb+bYVTXOTuAow= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764571893; c=relaxed/simple; bh=0+A2jWtH9lLsUSAQ2zNv6LrefVmpFHKXoA1grZC/SkY=; h=From:To:Cc:Subject:References:Message-ID:Content-Type: MIME-Version:Date; b=eJEBlMJjsqd+w5cDxm9/yoAEyoEm0OS14F7zhC6fKMc6MHPJO/HJe8y1aSEFjePZOegf24uPUFM3jfLhO+jOQfxIsfB5U4a4m62UOHfZPRUTyYabyslKhhd4ABiv+E+J19NGXN0g03MAIJ+hzF+b5iCwcmPoxBuubht2crqJD8g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=wBdfAc12; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=3th3paVZ; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="wBdfAc12"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="3th3paVZ" From: Thomas Gleixner DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1764571888; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=e7iIp6J8xSFOTbVDBpQdP7vxoOeZ7F24E9t6zXXItRY=; b=wBdfAc12WzVx/ir+lBtnKiEZYwz7lhuTo9jLDQLcuLdqvDtqxCib8m68DQc65tDKfKOTxN CrVdDhWhXnTFmwNCSclX6t+nP1pfpRWYczBtoU1V5i1iYuQBQNyjO++x2FqoTZ0OEYIJ45 vlClfONBq839u4SjFsvSkVZr6lACJr+38k4BXgH2/dC51NF8XcC6GvV9SRK0ULdn9GRHlv OrM3hq7sijwJBTodHe4Y5UwrTIwqpZXbtvlyk5B2ZoV2DH9ItMkJqHYozYxLQrhzZJWyjK X7enL/dbnxo4D8nErmtBc/fQ+akosWQwe9k3L1BqGzCLvnNozrp2UP6uKM3SYg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1764571888; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: references:references; bh=e7iIp6J8xSFOTbVDBpQdP7vxoOeZ7F24E9t6zXXItRY=; b=3th3paVZJykghIeHD9puwh3V1t+JkkZXuvyeKg0cYPv9EaGOhZtcsm1r0yUHXM1ehq3EQ0 hqcsZGvbdRyLatBg== To: Linus Torvalds Cc: linux-kernel@vger.kernel.org, x86@kernel.org Subject: [GIT pull] irq/drivers for v6.19-rc1 References: <176457119565.1888260.10012195384143368631.tglx@xen13> Message-ID: <176457121064.1888260.17471146987184773476.tglx@xen13> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Mon, 1 Dec 2025 07:51:21 +0100 (CET) Linus, please pull the latest irq/drivers branch from: git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-drivers-20= 25-11-30 up to: fc584d871c16: irqchip/meson-gpio: Add support for Amlogic S6 S7 and= S7D SoCs Boring updates for interrupt drivers: - Support for a couple of new ARM64 and RISCV SoC variants and their magic interrupt controllers which either can reuse existing code or require quirks due to a botched hardware implementation. - More section mismatch fixes. - The usual cleanups and fixes all over the place. Thanks, tglx ------------------> Charles Mirabile (4): dt-bindings: interrupt-controller: Add UltraRISC DP1000 PLIC irqchip/sifive-plic: Cache the interrupt enable state irqchip/sifive-plic: Add support for UltraRISC DP1000 PLIC irqchip/sifive-plic: Fix call to __plic_toggle() in M-Mode code path Johan Hovold (16): irqchip/bcm2712-mip: Fix OF node reference imbalance irqchip/bcm2712-mip: Fix section mismatch irqchip/irq-bcm7038-l1: Fix section mismatch irqchip/irq-bcm7120-l2: Fix section mismatch irqchip/irq-brcmstb-l2: Fix section mismatch irqchip/imx-mu-msi: Fix section mismatch irqchip/renesas-rzg2l: Fix section mismatch irqchip/starfive-jh8100: Fix section mismatch irqchip/qcom-irq-combiner: Fix section mismatch irqchip: Drop leftover brackets irqchip: Pass platform device to platform drivers irqchip: Enable compile testing of Broadcom drivers irqchip/meson-gpio: Drop unused module alias irqchip/mvebu-pic: Drop unused module alias irqchip/ts4800: Drop unused module alias irqchip/qcom-irq-combiner: Rename driver structure Junhui Liu (4): dt-bindings: interrupt-controller: Add Anlogic DR1V90 PLIC dt-bindings: interrupt-controller: Add Anlogic DR1V90 ACLINT MSWI dt-bindings: interrupt-controller: Add Anlogic DR1V90 ACLINT SSWI irqchip/aclint-sswi: Add Nuclei UX900 support Krzysztof Kozlowski (1): irqchip/irq-bcm7038-l1: Remove unused reg_mask_status() Lucas Zampieri (1): dt-bindings: vendor-prefixes: Add UltraRISC Ryan Chen (1): dt-bindings: interrupt-controller: aspeed,ast2700: Correct #interrupt= -cells and interrupts count Samuel Holland (3): irqchip/riscv-imsic: Remove redundant irq_data lookups irqchip/riscv-imsic: Embed the vector array in lpriv irqchip/riscv-imsic: Inline imsic_vector_from_local_id() Xianwei Zhao (2): dt-bindings: interrupt-controller: Add support for Amlogic S6 S7 and = S7D SoCs irqchip/meson-gpio: Add support for Amlogic S6 S7 and S7D SoCs .../amlogic,meson-gpio-intc.yaml | 3 + .../interrupt-controller/aspeed,ast2700-intc.yaml | 13 +- .../interrupt-controller/sifive,plic-1.0.0.yaml | 4 + .../thead,c900-aclint-mswi.yaml | 17 ++- .../thead,c900-aclint-sswi.yaml | 4 + .../devicetree/bindings/vendor-prefixes.yaml | 2 + drivers/irqchip/Kconfig | 6 +- drivers/irqchip/irq-aclint-sswi.c | 3 +- drivers/irqchip/irq-bcm2712-mip.c | 11 +- drivers/irqchip/irq-bcm7038-l1.c | 17 +-- drivers/irqchip/irq-bcm7120-l2.c | 31 ++--- drivers/irqchip/irq-brcmstb-l2.c | 25 ++-- drivers/irqchip/irq-imx-mu-msi.c | 28 ++-- drivers/irqchip/irq-mchp-eic.c | 5 +- drivers/irqchip/irq-meson-gpio.c | 17 ++- drivers/irqchip/irq-mvebu-pic.c | 2 - drivers/irqchip/irq-qcom-mpm.c | 6 +- drivers/irqchip/irq-renesas-rzg2l.c | 37 ++--- drivers/irqchip/irq-renesas-rzv2h.c | 32 ++--- drivers/irqchip/irq-riscv-imsic-early.c | 11 +- drivers/irqchip/irq-riscv-imsic-platform.c | 4 +- drivers/irqchip/irq-riscv-imsic-state.c | 20 +-- drivers/irqchip/irq-riscv-imsic-state.h | 4 +- drivers/irqchip/irq-sifive-plic.c | 149 +++++++++++++++++= ---- drivers/irqchip/irq-starfive-jh8100-intc.c | 6 +- drivers/irqchip/irq-ts4800.c | 1 - drivers/irqchip/irqchip.c | 10 +- drivers/irqchip/qcom-irq-combiner.c | 6 +- drivers/irqchip/qcom-pdc.c | 5 +- include/linux/irqchip.h | 8 +- 30 files changed, 264 insertions(+), 223 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic= ,meson-gpio-intc.yaml b/Documentation/devicetree/bindings/interrupt-control= ler/amlogic,meson-gpio-intc.yaml index 3d60d9e9e208..d0fad930de9d 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-= gpio-intc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-= gpio-intc.yaml @@ -39,6 +39,9 @@ properties: - amlogic,a4-gpio-ao-intc - amlogic,a5-gpio-intc - amlogic,c3-gpio-intc + - amlogic,s6-gpio-intc + - amlogic,s7-gpio-intc + - amlogic,s7d-gpio-intc - amlogic,t7-gpio-intc - const: amlogic,meson-gpio-intc =20 diff --git a/Documentation/devicetree/bindings/interrupt-controller/aspeed,= ast2700-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/= aspeed,ast2700-intc.yaml index 55636d06a674..999df5b905c5 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700= -intc.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2700= -intc.yaml @@ -25,13 +25,14 @@ properties: interrupt-controller: true =20 '#interrupt-cells': - const: 2 + const: 1 description: The first cell is the IRQ number, the second cell is the trigger type as defined in interrupt.txt in this directory. =20 interrupts: - maxItems: 6 + minItems: 1 + maxItems: 10 description: | Depend to which INTC0 or INTC1 used. INTC0 and INTC1 are two kinds of interrupt controller with enable an= d raw @@ -74,13 +75,17 @@ examples: interrupt-controller@12101b00 { compatible =3D "aspeed,ast2700-intc-ic"; reg =3D <0 0x12101b00 0 0x10>; - #interrupt-cells =3D <2>; + #interrupt-cells =3D <1>; interrupt-controller; interrupts =3D , , , , , - ; + , + , + , + , + ; }; }; diff --git a/Documentation/devicetree/bindings/interrupt-controller/sifive,= plic-1.0.0.yaml b/Documentation/devicetree/bindings/interrupt-controller/si= five,plic-1.0.0.yaml index f683d696909b..6fdb7ae9e85a 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.= 0.0.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/sifive,plic-1.= 0.0.yaml @@ -58,6 +58,7 @@ properties: - const: andestech,nceplic100 - items: - enum: + - anlogic,dr1v90-plic - canaan,k210-plic - eswin,eic7700-plic - sifive,fu540-c000-plic @@ -75,6 +76,9 @@ properties: - sophgo,sg2044-plic - thead,th1520-plic - const: thead,c900-plic + - items: + - const: ultrarisc,dp1000-plic + - const: ultrarisc,cp100-plic - items: - const: sifive,plic-1.0.0 - const: riscv,plic0 diff --git a/Documentation/devicetree/bindings/interrupt-controller/thead,c= 900-aclint-mswi.yaml b/Documentation/devicetree/bindings/interrupt-controll= er/thead,c900-aclint-mswi.yaml index d6fb08a54167..62fd220e126e 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/thead,c900-acl= int-mswi.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-acl= int-mswi.yaml @@ -4,18 +4,23 @@ $id: http://devicetree.org/schemas/interrupt-controller/thead,c900-aclint-= mswi.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# =20 -title: Sophgo sg2042 CLINT Machine-level Software Interrupt Device +title: ACLINT Machine-level Software Interrupt Device =20 maintainers: - Inochi Amaoto =20 properties: compatible: - items: - - enum: - - sophgo,sg2042-aclint-mswi - - sophgo,sg2044-aclint-mswi - - const: thead,c900-aclint-mswi + oneOf: + - items: + - enum: + - sophgo,sg2042-aclint-mswi + - sophgo,sg2044-aclint-mswi + - const: thead,c900-aclint-mswi + - items: + - enum: + - anlogic,dr1v90-aclint-mswi + - const: nuclei,ux900-aclint-mswi =20 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/interrupt-controller/thead,c= 900-aclint-sswi.yaml b/Documentation/devicetree/bindings/interrupt-controll= er/thead,c900-aclint-sswi.yaml index c1ab865fcd64..d02c6886283a 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/thead,c900-acl= int-sswi.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-acl= int-sswi.yaml @@ -30,6 +30,10 @@ properties: - const: thead,c900-aclint-sswi - items: - const: mips,p8700-aclint-sswi + - items: + - enum: + - anlogic,dr1v90-aclint-sswi + - const: nuclei,ux900-aclint-sswi =20 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Docum= entation/devicetree/bindings/vendor-prefixes.yaml index f1d1882009ba..647746e6f75f 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1705,6 +1705,8 @@ patternProperties: description: Universal Scientific Industrial Co., Ltd. "^usr,.*": description: U.S. Robotics Corporation + "^ultrarisc,.*": + description: UltraRISC Technology Co., Ltd. "^ultratronik,.*": description: Ultratronik GmbH "^utoo,.*": diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index a61c6dc63c29..9b7153777688 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -151,7 +151,7 @@ config BCM6345_L1_IRQ =20 config BCM7038_L1_IRQ tristate "Broadcom STB 7038-style L1/L2 interrupt controller driver" - depends on ARCH_BRCMSTB || BMIPS_GENERIC + depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST default ARCH_BRCMSTB || BMIPS_GENERIC select GENERIC_IRQ_CHIP select IRQ_DOMAIN @@ -159,14 +159,14 @@ config BCM7038_L1_IRQ =20 config BCM7120_L2_IRQ tristate "Broadcom STB 7120-style L2 interrupt controller driver" - depends on ARCH_BRCMSTB || BMIPS_GENERIC + depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST default ARCH_BRCMSTB || BMIPS_GENERIC select GENERIC_IRQ_CHIP select IRQ_DOMAIN =20 config BRCMSTB_L2_IRQ tristate "Broadcom STB generic L2 interrupt controller driver" - depends on ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC + depends on ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST default ARCH_BCM2835 || ARCH_BRCMSTB || BMIPS_GENERIC select GENERIC_IRQ_CHIP select IRQ_DOMAIN diff --git a/drivers/irqchip/irq-aclint-sswi.c b/drivers/irqchip/irq-aclint= -sswi.c index 93e28e9f281f..fee30f3bc5ac 100644 --- a/drivers/irqchip/irq-aclint-sswi.c +++ b/drivers/irqchip/irq-aclint-sswi.c @@ -175,7 +175,8 @@ static int __init generic_aclint_sswi_early_probe(struc= t device_node *node, { return generic_aclint_sswi_probe(&node->fwnode); } -IRQCHIP_DECLARE(generic_aclint_sswi, "mips,p8700-aclint-sswi", generic_acl= int_sswi_early_probe); +IRQCHIP_DECLARE(mips_p8700_sswi, "mips,p8700-aclint-sswi", generic_aclint_= sswi_early_probe); +IRQCHIP_DECLARE(nuclei_ux900_sswi, "nuclei,ux900-aclint-sswi", generic_acl= int_sswi_early_probe); =20 /* THEAD variant */ #define THEAD_C9XX_CSR_SXSTATUS 0x5c0 diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm271= 2-mip.c index 9bd7bc0bf6d5..4761974ad650 100644 --- a/drivers/irqchip/irq-bcm2712-mip.c +++ b/drivers/irqchip/irq-bcm2712-mip.c @@ -232,17 +232,12 @@ static int mip_parse_dt(struct mip_priv *mip, struct = device_node *np) return ret; } =20 -static int __init mip_of_msi_init(struct device_node *node, struct device_= node *parent) +static int mip_msi_probe(struct platform_device *pdev, struct device_node = *parent) { - struct platform_device *pdev; + struct device_node *node =3D pdev->dev.of_node; struct mip_priv *mip; int ret; =20 - pdev =3D of_find_device_by_node(node); - of_node_put(node); - if (!pdev) - return -EPROBE_DEFER; - mip =3D kzalloc(sizeof(*mip), GFP_KERNEL); if (!mip) return -ENOMEM; @@ -285,7 +280,7 @@ static int __init mip_of_msi_init(struct device_node *n= ode, struct device_node * } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(mip_msi) -IRQCHIP_MATCH("brcm,bcm2712-mip", mip_of_msi_init) +IRQCHIP_MATCH("brcm,bcm2712-mip", mip_msi_probe) IRQCHIP_PLATFORM_DRIVER_END(mip_msi) MODULE_DESCRIPTION("Broadcom BCM2712 MSI-X interrupt controller"); MODULE_AUTHOR("Phil Elwell "); diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038= -l1.c index 04fac0cc857f..ea1446c0a09c 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c @@ -82,12 +82,6 @@ static inline unsigned int reg_status(struct bcm7038_l1_= chip *intc, return (0 * intc->n_words + word) * sizeof(u32); } =20 -static inline unsigned int reg_mask_status(struct bcm7038_l1_chip *intc, - unsigned int word) -{ - return (1 * intc->n_words + word) * sizeof(u32); -} - static inline unsigned int reg_mask_set(struct bcm7038_l1_chip *intc, unsigned int word) { @@ -219,9 +213,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, } #endif =20 -static int __init bcm7038_l1_init_one(struct device_node *dn, - unsigned int idx, - struct bcm7038_l1_chip *intc) +static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, + struct bcm7038_l1_chip *intc) { struct resource res; resource_size_t sz; @@ -395,9 +388,9 @@ static const struct irq_domain_ops bcm7038_l1_domain_op= s =3D { .map =3D bcm7038_l1_map, }; =20 -static int __init bcm7038_l1_of_init(struct device_node *dn, - struct device_node *parent) +static int bcm7038_l1_probe(struct platform_device *pdev, struct device_no= de *parent) { + struct device_node *dn =3D pdev->dev.of_node; struct bcm7038_l1_chip *intc; int idx, ret; =20 @@ -455,7 +448,7 @@ static int __init bcm7038_l1_of_init(struct device_node= *dn, } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(bcm7038_l1) -IRQCHIP_MATCH("brcm,bcm7038-l1-intc", bcm7038_l1_of_init) +IRQCHIP_MATCH("brcm,bcm7038-l1-intc", bcm7038_l1_probe) IRQCHIP_PLATFORM_DRIVER_END(bcm7038_l1) MODULE_DESCRIPTION("Broadcom STB 7038-style L1/L2 interrupt controller"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120= -l2.c index ff22c3104401..518c9d4366a5 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c @@ -143,8 +143,7 @@ static int bcm7120_l2_intc_init_one(struct device_node = *dn, return 0; } =20 -static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, - struct bcm7120_l2_intc_data *data) +static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm71= 20_l2_intc_data *data) { int ret; =20 @@ -177,8 +176,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct dev= ice_node *dn, return 0; } =20 -static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, - struct bcm7120_l2_intc_data *data) +static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm71= 20_l2_intc_data *data) { unsigned int gc_idx; =20 @@ -208,15 +206,14 @@ static int __init bcm7120_l2_intc_iomap_3380(struct d= evice_node *dn, return 0; } =20 -static int __init bcm7120_l2_intc_probe(struct device_node *dn, - struct device_node *parent, +static int bcm7120_l2_intc_probe(struct platform_device *pdev, struct devi= ce_node *parent, int (*iomap_regs_fn)(struct device_node *, - struct bcm7120_l2_intc_data *), + struct bcm7120_l2_intc_data *), const char *intc_name) { unsigned int clr =3D IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + struct device_node *dn =3D pdev->dev.of_node; struct bcm7120_l2_intc_data *data; - struct platform_device *pdev; struct irq_chip_generic *gc; struct irq_chip_type *ct; int ret =3D 0; @@ -227,14 +224,7 @@ static int __init bcm7120_l2_intc_probe(struct device_= node *dn, if (!data) return -ENOMEM; =20 - pdev =3D of_find_device_by_node(dn); - if (!pdev) { - ret =3D -ENODEV; - goto out_free_data; - } - data->num_parent_irqs =3D platform_irq_count(pdev); - put_device(&pdev->dev); if (data->num_parent_irqs <=3D 0) { pr_err("invalid number of parent interrupts\n"); ret =3D -ENOMEM; @@ -334,22 +324,19 @@ static int __init bcm7120_l2_intc_probe(struct device= _node *dn, if (data->map_base[idx]) iounmap(data->map_base[idx]); } -out_free_data: kfree(data); return ret; } =20 -static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn, - struct device_node *parent) +static int bcm7120_l2_intc_probe_7120(struct platform_device *pdev, struct= device_node *parent) { - return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, + return bcm7120_l2_intc_probe(pdev, parent, bcm7120_l2_intc_iomap_7120, "BCM7120 L2"); } =20 -static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn, - struct device_node *parent) +static int bcm7120_l2_intc_probe_3380(struct platform_device *pdev, struct= device_node *parent) { - return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, + return bcm7120_l2_intc_probe(pdev, parent, bcm7120_l2_intc_iomap_3380, "BCM3380 L2"); } =20 diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb= -l2.c index 1bec5b2cd3f0..bb7078d6524f 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -138,13 +138,12 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable); } =20 -static int __init brcmstb_l2_intc_of_init(struct device_node *np, - struct device_node *parent, - const struct brcmstb_intc_init_params - *init_params) +static int brcmstb_l2_intc_probe(struct platform_device *pdev, struct devi= ce_node *parent, + const struct brcmstb_intc_init_params *init_params) { unsigned int clr =3D IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; unsigned int set =3D 0; + struct device_node *np =3D pdev->dev.of_node; struct brcmstb_l2_intc_data *data; struct irq_chip_type *ct; int ret; @@ -257,23 +256,21 @@ static int __init brcmstb_l2_intc_of_init(struct devi= ce_node *np, return ret; } =20 -static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np, - struct device_node *parent) +static int brcmstb_l2_edge_intc_probe(struct platform_device *pdev, struct= device_node *parent) { - return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); + return brcmstb_l2_intc_probe(pdev, parent, &l2_edge_intc_init); } =20 -static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, - struct device_node *parent) +static int brcmstb_l2_lvl_intc_probe(struct platform_device *pdev, struct = device_node *parent) { - return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); + return brcmstb_l2_intc_probe(pdev, parent, &l2_lvl_intc_init); } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(brcmstb_l2) -IRQCHIP_MATCH("brcm,l2-intc", brcmstb_l2_edge_intc_of_init) -IRQCHIP_MATCH("brcm,hif-spi-l2-intc", brcmstb_l2_edge_intc_of_init) -IRQCHIP_MATCH("brcm,upg-aux-aon-l2-intc", brcmstb_l2_edge_intc_of_init) -IRQCHIP_MATCH("brcm,bcm7271-l2-intc", brcmstb_l2_lvl_intc_of_init) +IRQCHIP_MATCH("brcm,l2-intc", brcmstb_l2_edge_intc_probe) +IRQCHIP_MATCH("brcm,hif-spi-l2-intc", brcmstb_l2_edge_intc_probe) +IRQCHIP_MATCH("brcm,upg-aux-aon-l2-intc", brcmstb_l2_edge_intc_probe) +IRQCHIP_MATCH("brcm,bcm7271-l2-intc", brcmstb_l2_lvl_intc_probe) IRQCHIP_PLATFORM_DRIVER_END(brcmstb_l2) MODULE_DESCRIPTION("Broadcom STB generic L2 interrupt controller"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-= msi.c index d2a4e8a61a42..c598f2f52fc6 100644 --- a/drivers/irqchip/irq-imx-mu-msi.c +++ b/drivers/irqchip/irq-imx-mu-msi.c @@ -296,11 +296,9 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp =3D= { }, }; =20 -static int __init imx_mu_of_init(struct device_node *dn, - struct device_node *parent, - const struct imx_mu_dcfg *cfg) +static int imx_mu_probe(struct platform_device *pdev, struct device_node *= parent, + const struct imx_mu_dcfg *cfg) { - struct platform_device *pdev =3D of_find_device_by_node(dn); struct device_link *pd_link_a; struct device_link *pd_link_b; struct imx_mu_msi *msi_data; @@ -416,31 +414,27 @@ static const struct dev_pm_ops imx_mu_pm_ops =3D { imx_mu_runtime_resume, NULL) }; =20 -static int __init imx_mu_imx7ulp_of_init(struct device_node *dn, - struct device_node *parent) +static int imx_mu_imx7ulp_probe(struct platform_device *pdev, struct devic= e_node *parent) { - return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); + return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx7ulp); } =20 -static int __init imx_mu_imx6sx_of_init(struct device_node *dn, - struct device_node *parent) +static int imx_mu_imx6sx_probe(struct platform_device *pdev, struct device= _node *parent) { - return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); + return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx6sx); } =20 -static int __init imx_mu_imx8ulp_of_init(struct device_node *dn, - struct device_node *parent) +static int imx_mu_imx8ulp_probe(struct platform_device *pdev, struct devic= e_node *parent) { - return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); + return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx8ulp); } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(imx_mu_msi) -IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init) -IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_of_init) -IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_of_init) +IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_probe) +IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_probe) +IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_probe) IRQCHIP_PLATFORM_DRIVER_END(imx_mu_msi, .pm =3D &imx_mu_pm_ops) =20 - MODULE_AUTHOR("Frank Li "); MODULE_DESCRIPTION("Freescale MU MSI controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/irqchip/irq-mchp-eic.c b/drivers/irqchip/irq-mchp-eic.c index 516a3a0e359c..b513a899c085 100644 --- a/drivers/irqchip/irq-mchp-eic.c +++ b/drivers/irqchip/irq-mchp-eic.c @@ -199,8 +199,9 @@ static const struct irq_domain_ops mchp_eic_domain_ops = =3D { .free =3D irq_domain_free_irqs_common, }; =20 -static int mchp_eic_init(struct device_node *node, struct device_node *par= ent) +static int mchp_eic_probe(struct platform_device *pdev, struct device_node= *parent) { + struct device_node *node =3D pdev->dev.of_node; struct irq_domain *parent_domain =3D NULL; int ret, i; =20 @@ -273,7 +274,7 @@ static int mchp_eic_init(struct device_node *node, stru= ct device_node *parent) } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(mchp_eic) -IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_init) +IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_probe) IRQCHIP_PLATFORM_DRIVER_END(mchp_eic) =20 MODULE_DESCRIPTION("Microchip External Interrupt Controller"); diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-g= pio.c index 7d177626d64b..3fcbb044ae60 100644 --- a/drivers/irqchip/irq-meson-gpio.c +++ b/drivers/irqchip/irq-meson-gpio.c @@ -174,6 +174,14 @@ static const struct meson_gpio_irq_params s4_params = =3D { INIT_MESON_S4_COMMON_DATA(82) }; =20 +static const struct meson_gpio_irq_params s6_params =3D { + INIT_MESON_S4_COMMON_DATA(100) +}; + +static const struct meson_gpio_irq_params s7_params =3D { + INIT_MESON_S4_COMMON_DATA(84) +}; + static const struct meson_gpio_irq_params c3_params =3D { INIT_MESON_S4_COMMON_DATA(55) }; @@ -195,6 +203,9 @@ static const struct of_device_id meson_irq_gpio_matches= [] __maybe_unused =3D { { .compatible =3D "amlogic,a4-gpio-ao-intc", .data =3D &a4_ao_params }, { .compatible =3D "amlogic,a4-gpio-intc", .data =3D &a4_params }, { .compatible =3D "amlogic,a5-gpio-intc", .data =3D &a5_params }, + { .compatible =3D "amlogic,s6-gpio-intc", .data =3D &s6_params }, + { .compatible =3D "amlogic,s7-gpio-intc", .data =3D &s7_params }, + { .compatible =3D "amlogic,s7d-gpio-intc", .data =3D &s7_params }, { .compatible =3D "amlogic,c3-gpio-intc", .data =3D &c3_params }, { .compatible =3D "amlogic,t7-gpio-intc", .data =3D &t7_params }, { } @@ -572,8 +583,9 @@ static int meson_gpio_irq_parse_dt(struct device_node *= node, struct meson_gpio_i return 0; } =20 -static int meson_gpio_irq_of_init(struct device_node *node, struct device_= node *parent) +static int meson_gpio_irq_probe(struct platform_device *pdev, struct devic= e_node *parent) { + struct device_node *node =3D pdev->dev.of_node; struct irq_domain *domain, *parent_domain; struct meson_gpio_irq_controller *ctl; int ret; @@ -630,10 +642,9 @@ static int meson_gpio_irq_of_init(struct device_node *= node, struct device_node * } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(meson_gpio_intc) -IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init) +IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_probe) IRQCHIP_PLATFORM_DRIVER_END(meson_gpio_intc) =20 MODULE_AUTHOR("Jerome Brunet "); MODULE_DESCRIPTION("Meson GPIO Interrupt Multiplexer driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:meson-gpio-intc"); diff --git a/drivers/irqchip/irq-mvebu-pic.c b/drivers/irqchip/irq-mvebu-pi= c.c index cd8b73482b9f..10b85128183a 100644 --- a/drivers/irqchip/irq-mvebu-pic.c +++ b/drivers/irqchip/irq-mvebu-pic.c @@ -195,5 +195,3 @@ MODULE_AUTHOR("Yehuda Yitschak "); MODULE_AUTHOR("Thomas Petazzoni "); MODULE_DESCRIPTION("Marvell Armada 7K/8K PIC driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:mvebu_pic"); - diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c index 8d569f7c5a7a..83f31ea657b7 100644 --- a/drivers/irqchip/irq-qcom-mpm.c +++ b/drivers/irqchip/irq-qcom-mpm.c @@ -320,9 +320,9 @@ static bool gic_hwirq_is_mapped(struct mpm_gic_map *map= s, int cnt, u32 hwirq) return false; } =20 -static int qcom_mpm_init(struct device_node *np, struct device_node *paren= t) +static int qcom_mpm_probe(struct platform_device *pdev, struct device_node= *parent) { - struct platform_device *pdev =3D of_find_device_by_node(np); + struct device_node *np =3D pdev->dev.of_node; struct device *dev =3D &pdev->dev; struct irq_domain *parent_domain; struct generic_pm_domain *genpd; @@ -478,7 +478,7 @@ static int qcom_mpm_init(struct device_node *np, struct= device_node *parent) } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_mpm) -IRQCHIP_MATCH("qcom,mpm", qcom_mpm_init) +IRQCHIP_MATCH("qcom,mpm", qcom_mpm_probe) IRQCHIP_PLATFORM_DRIVER_END(qcom_mpm) MODULE_DESCRIPTION("Qualcomm Technologies, Inc. MSM Power Manager"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-rene= sas-rzg2l.c index 2a54adeb4cc7..1bf19deb02c4 100644 --- a/drivers/irqchip/irq-renesas-rzg2l.c +++ b/drivers/irqchip/irq-renesas-rzg2l.c @@ -8,7 +8,6 @@ */ =20 #include -#include #include #include #include @@ -528,18 +527,15 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_i= rqc_priv *priv, return 0; } =20 -static int rzg2l_irqc_common_init(struct device_node *node, struct device_= node *parent, - const struct irq_chip *irq_chip) +static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct de= vice_node *parent, + const struct irq_chip *irq_chip) { - struct platform_device *pdev =3D of_find_device_by_node(node); - struct device *dev __free(put_device) =3D pdev ? &pdev->dev : NULL; struct irq_domain *irq_domain, *parent_domain; + struct device_node *node =3D pdev->dev.of_node; + struct device *dev =3D &pdev->dev; struct reset_control *resetn; int ret; =20 - if (!pdev) - return -ENODEV; - parent_domain =3D irq_find_host(parent); if (!parent_domain) return dev_err_probe(dev, -ENODEV, "cannot find parent domain\n"); @@ -583,35 +579,22 @@ static int rzg2l_irqc_common_init(struct device_node = *node, struct device_node * =20 register_syscore_ops(&rzg2l_irqc_syscore_ops); =20 - /* - * Prevent the cleanup function from invoking put_device by assigning - * NULL to dev. - * - * make coccicheck will complain about missing put_device calls, but - * those are false positives, as dev will be automatically "put" via - * __free_put_device on the failing path. - * On the successful path we don't actually want to "put" dev. - */ - dev =3D NULL; - return 0; } =20 -static int __init rzg2l_irqc_init(struct device_node *node, - struct device_node *parent) +static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_no= de *parent) { - return rzg2l_irqc_common_init(node, parent, &rzg2l_irqc_chip); + return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_chip); } =20 -static int __init rzfive_irqc_init(struct device_node *node, - struct device_node *parent) +static int rzfive_irqc_probe(struct platform_device *pdev, struct device_n= ode *parent) { - return rzg2l_irqc_common_init(node, parent, &rzfive_irqc_chip); + return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_chip); } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc) -IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init) -IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_init) +IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_probe) +IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_probe) IRQCHIP_PLATFORM_DRIVER_END(rzg2l_irqc) MODULE_AUTHOR("Lad Prabhakar "); MODULE_DESCRIPTION("Renesas RZ/G2L IRQC Driver"); diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-rene= sas-rzv2h.c index 9018d9c3911e..899a423b5da8 100644 --- a/drivers/irqchip/irq-renesas-rzv2h.c +++ b/drivers/irqchip/irq-renesas-rzv2h.c @@ -490,29 +490,15 @@ static int rzv2h_icu_parse_interrupts(struct rzv2h_ic= u_priv *priv, struct device return 0; } =20 -static void rzv2h_icu_put_device(void *data) -{ - put_device(data); -} - -static int rzv2h_icu_init_common(struct device_node *node, struct device_n= ode *parent, - const struct rzv2h_hw_info *hw_info) +static int rzv2h_icu_probe_common(struct platform_device *pdev, struct dev= ice_node *parent, + const struct rzv2h_hw_info *hw_info) { struct irq_domain *irq_domain, *parent_domain; + struct device_node *node =3D pdev->dev.of_node; struct rzv2h_icu_priv *rzv2h_icu_data; - struct platform_device *pdev; struct reset_control *resetn; int ret; =20 - pdev =3D of_find_device_by_node(node); - if (!pdev) - return -ENODEV; - - ret =3D devm_add_action_or_reset(&pdev->dev, rzv2h_icu_put_device, - &pdev->dev); - if (ret < 0) - return ret; - parent_domain =3D irq_find_host(parent); if (!parent_domain) { dev_err(&pdev->dev, "cannot find parent domain\n"); @@ -618,19 +604,19 @@ static const struct rzv2h_hw_info rzv2h_hw_params =3D= { .field_width =3D 8, }; =20 -static int rzg3e_icu_init(struct device_node *node, struct device_node *pa= rent) +static int rzg3e_icu_probe(struct platform_device *pdev, struct device_nod= e *parent) { - return rzv2h_icu_init_common(node, parent, &rzg3e_hw_params); + return rzv2h_icu_probe_common(pdev, parent, &rzg3e_hw_params); } =20 -static int rzv2h_icu_init(struct device_node *node, struct device_node *pa= rent) +static int rzv2h_icu_probe(struct platform_device *pdev, struct device_nod= e *parent) { - return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params); + return rzv2h_icu_probe_common(pdev, parent, &rzv2h_hw_params); } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu) -IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_init) -IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init) +IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_probe) +IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_probe) IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu) MODULE_AUTHOR("Fabrizio Castro "); MODULE_DESCRIPTION("Renesas RZ/V2H(P) ICU Driver"); diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-= riscv-imsic-early.c index 2c4c682627b8..6bac67cc0b6d 100644 --- a/drivers/irqchip/irq-riscv-imsic-early.c +++ b/drivers/irqchip/irq-riscv-imsic-early.c @@ -91,9 +91,8 @@ static int __init imsic_ipi_domain_init(void) { return 0;= } */ static void imsic_handle_irq(struct irq_desc *desc) { + struct imsic_local_priv *lpriv =3D this_cpu_ptr(imsic->lpriv); struct irq_chip *chip =3D irq_desc_get_chip(desc); - int cpu =3D smp_processor_id(); - struct imsic_vector *vec; unsigned long local_id; =20 /* @@ -113,16 +112,12 @@ static void imsic_handle_irq(struct irq_desc *desc) continue; } =20 - if (unlikely(!imsic->base_domain)) - continue; - - vec =3D imsic_vector_from_local_id(cpu, local_id); - if (!vec) { + if (unlikely(local_id > imsic->global.nr_ids)) { pr_warn_ratelimited("vector not found for local ID 0x%lx\n", local_id); continue; } =20 - generic_handle_irq(vec->irq); + generic_handle_irq(lpriv->vectors[local_id].irq); } =20 chained_irq_exit(chip, desc); diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/i= rq-riscv-imsic-platform.c index 643c8e459611..7228a33f6c37 100644 --- a/drivers/irqchip/irq-riscv-imsic-platform.c +++ b/drivers/irqchip/irq-riscv-imsic-platform.c @@ -158,11 +158,11 @@ static int imsic_irq_set_affinity(struct irq_data *d,= const struct cpumask *mask tmp_vec.local_id =3D new_vec->local_id; =20 /* Point device to the temporary vector */ - imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec); + imsic_msi_update_msg(d, &tmp_vec); } =20 /* Point device to the new vector */ - imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec); + imsic_msi_update_msg(d, new_vec); =20 /* Update irq descriptors with the new vector */ d->chip_data =3D new_vec; diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-= riscv-imsic-state.c index dc95ad856d80..385368052d5c 100644 --- a/drivers/irqchip/irq-riscv-imsic-state.c +++ b/drivers/irqchip/irq-riscv-imsic-state.c @@ -434,16 +434,6 @@ void imsic_vector_debug_show_summary(struct seq_file *= m, int ind) } #endif =20 -struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned= int local_id) -{ - struct imsic_local_priv *lpriv =3D per_cpu_ptr(imsic->lpriv, cpu); - - if (!lpriv || imsic->global.nr_ids < local_id) - return NULL; - - return &lpriv->vectors[local_id]; -} - struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpu= mask *mask) { struct imsic_vector *vec =3D NULL; @@ -487,7 +477,6 @@ static void __init imsic_local_cleanup(void) lpriv =3D per_cpu_ptr(imsic->lpriv, cpu); =20 bitmap_free(lpriv->dirty_bitmap); - kfree(lpriv->vectors); } =20 free_percpu(imsic->lpriv); @@ -501,7 +490,8 @@ static int __init imsic_local_init(void) int cpu, i; =20 /* Allocate per-CPU private state */ - imsic->lpriv =3D alloc_percpu(typeof(*imsic->lpriv)); + imsic->lpriv =3D __alloc_percpu(struct_size(imsic->lpriv, vectors, global= ->nr_ids + 1), + __alignof__(*imsic->lpriv)); if (!imsic->lpriv) return -ENOMEM; =20 @@ -521,12 +511,6 @@ static int __init imsic_local_init(void) timer_setup(&lpriv->timer, imsic_local_timer_callback, TIMER_PINNED); #endif =20 - /* Allocate vector array */ - lpriv->vectors =3D kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors), - GFP_KERNEL); - if (!lpriv->vectors) - goto fail_local_cleanup; - /* Setup vector array */ for (i =3D 0; i <=3D global->nr_ids; i++) { vec =3D &lpriv->vectors[i]; diff --git a/drivers/irqchip/irq-riscv-imsic-state.h b/drivers/irqchip/irq-= riscv-imsic-state.h index 57f951952b0c..6332501dcbd8 100644 --- a/drivers/irqchip/irq-riscv-imsic-state.h +++ b/drivers/irqchip/irq-riscv-imsic-state.h @@ -40,7 +40,7 @@ struct imsic_local_priv { #endif =20 /* Local vector table */ - struct imsic_vector *vectors; + struct imsic_vector vectors[]; }; =20 struct imsic_priv { @@ -95,8 +95,6 @@ static inline struct imsic_vector *imsic_vector_get_move(= struct imsic_vector *ve void imsic_vector_force_move_cleanup(struct imsic_vector *vec); void imsic_vector_move(struct imsic_vector *old_vec, struct imsic_vector *= new_vec); =20 -struct imsic_vector *imsic_vector_from_local_id(unsigned int cpu, unsigned= int local_id); - struct imsic_vector *imsic_vector_alloc(unsigned int irq, const struct cpu= mask *mask); void imsic_vector_free(struct imsic_vector *vector); =20 diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive= -plic.c index cbd7697bc148..c5db7d6e3f7c 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -49,6 +49,8 @@ #define CONTEXT_ENABLE_BASE 0x2000 #define CONTEXT_ENABLE_SIZE 0x80 =20 +#define PENDING_BASE 0x1000 + /* * Each hart context has a set of control registers associated with it. R= ight * now there's only two: a source priority threshold over which the hart w= ill @@ -63,6 +65,7 @@ #define PLIC_ENABLE_THRESHOLD 0 =20 #define PLIC_QUIRK_EDGE_INTERRUPT 0 +#define PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM 1 =20 struct plic_priv { struct fwnode_handle *fwnode; @@ -94,15 +97,22 @@ static DEFINE_PER_CPU(struct plic_handler, plic_handler= s); =20 static int plic_irq_set_type(struct irq_data *d, unsigned int type); =20 -static void __plic_toggle(void __iomem *enable_base, int hwirq, int enable) +static void __plic_toggle(struct plic_handler *handler, int hwirq, int ena= ble) { - u32 __iomem *reg =3D enable_base + (hwirq / 32) * sizeof(u32); + u32 __iomem *base =3D handler->enable_base; u32 hwirq_mask =3D 1 << (hwirq % 32); + int group =3D hwirq / 32; + u32 value; + + value =3D readl(base + group); =20 if (enable) - writel(readl(reg) | hwirq_mask, reg); + value |=3D hwirq_mask; else - writel(readl(reg) & ~hwirq_mask, reg); + value &=3D ~hwirq_mask; + + handler->enable_save[group] =3D value; + writel(value, base + group); } =20 static void plic_toggle(struct plic_handler *handler, int hwirq, int enabl= e) @@ -110,7 +120,7 @@ static void plic_toggle(struct plic_handler *handler, i= nt hwirq, int enable) unsigned long flags; =20 raw_spin_lock_irqsave(&handler->enable_lock, flags); - __plic_toggle(handler->enable_base, hwirq, enable); + __plic_toggle(handler, hwirq, enable); raw_spin_unlock_irqrestore(&handler->enable_lock, flags); } =20 @@ -247,33 +257,16 @@ static int plic_irq_set_type(struct irq_data *d, unsi= gned int type) =20 static int plic_irq_suspend(void) { - unsigned int i, cpu; - unsigned long flags; - u32 __iomem *reg; struct plic_priv *priv; =20 priv =3D per_cpu_ptr(&plic_handlers, smp_processor_id())->priv; =20 /* irq ID 0 is reserved */ - for (i =3D 1; i < priv->nr_irqs; i++) { + for (unsigned int i =3D 1; i < priv->nr_irqs; i++) { __assign_bit(i, priv->prio_save, readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)); } =20 - for_each_present_cpu(cpu) { - struct plic_handler *handler =3D per_cpu_ptr(&plic_handlers, cpu); - - if (!handler->present) - continue; - - raw_spin_lock_irqsave(&handler->enable_lock, flags); - for (i =3D 0; i < DIV_ROUND_UP(priv->nr_irqs, 32); i++) { - reg =3D handler->enable_base + i * sizeof(u32); - handler->enable_save[i] =3D readl(reg); - } - raw_spin_unlock_irqrestore(&handler->enable_lock, flags); - } - return 0; } =20 @@ -398,6 +391,98 @@ static void plic_handle_irq(struct irq_desc *desc) chained_irq_exit(chip, desc); } =20 +static u32 cp100_isolate_pending_irq(int nr_irq_groups, struct plic_handle= r *handler) +{ + u32 __iomem *pending =3D handler->priv->regs + PENDING_BASE; + u32 __iomem *enable =3D handler->enable_base; + u32 pending_irqs =3D 0; + int i, j; + + /* Look for first pending interrupt */ + for (i =3D 0; i < nr_irq_groups; i++) { + /* Any pending interrupts would be annihilated, so skip checking them */ + if (!handler->enable_save[i]) + continue; + + pending_irqs =3D handler->enable_save[i] & readl_relaxed(pending + i); + if (pending_irqs) + break; + } + + if (!pending_irqs) + return 0; + + /* Isolate lowest set bit */ + pending_irqs &=3D -pending_irqs; + + /* Disable all interrupts but the first pending one */ + for (j =3D 0; j < nr_irq_groups; j++) { + u32 new_mask =3D j =3D=3D i ? pending_irqs : 0; + + if (new_mask !=3D handler->enable_save[j]) + writel_relaxed(new_mask, enable + j); + } + return pending_irqs; +} + +static irq_hw_number_t cp100_get_hwirq(struct plic_handler *handler, void = __iomem *claim) +{ + int nr_irq_groups =3D DIV_ROUND_UP(handler->priv->nr_irqs, 32); + u32 __iomem *enable =3D handler->enable_base; + irq_hw_number_t hwirq =3D 0; + u32 iso_mask; + int i; + + guard(raw_spinlock)(&handler->enable_lock); + + /* Existing enable state is already cached in enable_save */ + iso_mask =3D cp100_isolate_pending_irq(nr_irq_groups, handler); + if (!iso_mask) + return 0; + + /* + * Interrupts delievered to hardware still become pending, but only + * interrupts that are both pending and enabled can be claimed. + * Clearing the enable bit for all interrupts but the first pending + * one avoids a hardware bug that occurs during read from the claim + * register with more than one eligible interrupt. + */ + hwirq =3D readl(claim); + + /* Restore previous state */ + for (i =3D 0; i < nr_irq_groups; i++) { + u32 written =3D i =3D=3D hwirq / 32 ? iso_mask : 0; + u32 stored =3D handler->enable_save[i]; + + if (stored !=3D written) + writel_relaxed(stored, enable + i); + } + return hwirq; +} + +static void plic_handle_irq_cp100(struct irq_desc *desc) +{ + struct plic_handler *handler =3D this_cpu_ptr(&plic_handlers); + struct irq_chip *chip =3D irq_desc_get_chip(desc); + void __iomem *claim =3D handler->hart_base + CONTEXT_CLAIM; + irq_hw_number_t hwirq; + + WARN_ON_ONCE(!handler->present); + + chained_irq_enter(chip, desc); + + while ((hwirq =3D cp100_get_hwirq(handler, claim))) { + int err =3D generic_handle_domain_irq(handler->priv->irqdomain, hwirq); + + if (unlikely(err)) { + pr_warn_ratelimited("%pfwP: can't find mapping for hwirq %lu\n", + handler->priv->fwnode, hwirq); + } + } + + chained_irq_exit(chip, desc); +} + static void plic_set_threshold(struct plic_handler *handler, u32 threshold) { /* priority must be > threshold to trigger an interrupt */ @@ -434,6 +519,8 @@ static const struct of_device_id plic_match[] =3D { .data =3D (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) }, { .compatible =3D "thead,c900-plic", .data =3D (const void *)BIT(PLIC_QUIRK_EDGE_INTERRUPT) }, + { .compatible =3D "ultrarisc,cp100-plic", + .data =3D (const void *)BIT(PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM) }, {} }; =20 @@ -592,12 +679,11 @@ static int plic_probe(struct fwnode_handle *fwnode) if (parent_hwirq !=3D RV_IRQ_EXT) { /* Disable S-mode enable bits if running in M-mode. */ if (IS_ENABLED(CONFIG_RISCV_M_MODE)) { - void __iomem *enable_base =3D priv->regs + - CONTEXT_ENABLE_BASE + - i * CONTEXT_ENABLE_SIZE; + u32 __iomem *enable_base =3D priv->regs + CONTEXT_ENABLE_BASE + + i * CONTEXT_ENABLE_SIZE; =20 - for (hwirq =3D 1; hwirq <=3D nr_irqs; hwirq++) - __plic_toggle(enable_base, hwirq, 0); + for (int j =3D 0; j <=3D nr_irqs / 32; j++) + writel(0, enable_base + j); } continue; } @@ -668,12 +754,17 @@ static int plic_probe(struct fwnode_handle *fwnode) } =20 if (global_setup) { + void (*handler_fn)(struct irq_desc *) =3D plic_handle_irq; + + if (test_bit(PLIC_QUIRK_CP100_CLAIM_REGISTER_ERRATUM, &handler->priv->p= lic_quirks)) + handler_fn =3D plic_handle_irq_cp100; + /* Find parent domain and register chained handler */ domain =3D irq_find_matching_fwnode(riscv_get_intc_hwnode(), DOMAIN_BUS= _ANY); if (domain) plic_parent_irq =3D irq_create_mapping(domain, RV_IRQ_EXT); if (plic_parent_irq) - irq_set_chained_handler(plic_parent_irq, plic_handle_irq); + irq_set_chained_handler(plic_parent_irq, handler_fn); =20 cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING, "irqchip/sifive/plic:starting", diff --git a/drivers/irqchip/irq-starfive-jh8100-intc.c b/drivers/irqchip/i= rq-starfive-jh8100-intc.c index 2460798ec158..705361b4ebe0 100644 --- a/drivers/irqchip/irq-starfive-jh8100-intc.c +++ b/drivers/irqchip/irq-starfive-jh8100-intc.c @@ -114,9 +114,9 @@ static void starfive_intc_irq_handler(struct irq_desc *= desc) chained_irq_exit(chip, desc); } =20 -static int __init starfive_intc_init(struct device_node *intc, - struct device_node *parent) +static int starfive_intc_probe(struct platform_device *pdev, struct device= _node *parent) { + struct device_node *intc =3D pdev->dev.of_node; struct starfive_irq_chip *irqc; struct reset_control *rst; struct clk *clk; @@ -199,7 +199,7 @@ static int __init starfive_intc_init(struct device_node= *intc, } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(starfive_intc) -IRQCHIP_MATCH("starfive,jh8100-intc", starfive_intc_init) +IRQCHIP_MATCH("starfive,jh8100-intc", starfive_intc_probe) IRQCHIP_PLATFORM_DRIVER_END(starfive_intc) =20 MODULE_DESCRIPTION("StarFive JH8100 External Interrupt Controller"); diff --git a/drivers/irqchip/irq-ts4800.c b/drivers/irqchip/irq-ts4800.c index 1e236d5b7516..2e4013c6834d 100644 --- a/drivers/irqchip/irq-ts4800.c +++ b/drivers/irqchip/irq-ts4800.c @@ -165,4 +165,3 @@ module_platform_driver(ts4800_ic_driver); MODULE_AUTHOR("Damien Riegel "); MODULE_DESCRIPTION("Multiplexed-IRQs driver for TS-4800's FPGA"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:ts4800_irqc"); diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c index 0ee7b6b71f5f..689c8e448901 100644 --- a/drivers/irqchip/irqchip.c +++ b/drivers/irqchip/irqchip.c @@ -36,11 +36,10 @@ int platform_irqchip_probe(struct platform_device *pdev) { struct device_node *np =3D pdev->dev.of_node; struct device_node *par_np __free(device_node) =3D of_irq_find_parent(np); - of_irq_init_cb_t irq_init_cb =3D of_device_get_match_data(&pdev->dev); + platform_irq_probe_t irq_probe =3D of_device_get_match_data(&pdev->dev); =20 - if (!irq_init_cb) { + if (!irq_probe) return -EINVAL; - } =20 if (par_np =3D=3D np) par_np =3D NULL; @@ -53,10 +52,9 @@ int platform_irqchip_probe(struct platform_device *pdev) * interrupt controller. The actual initialization callback of this * interrupt controller can check for specific domains as necessary. */ - if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { + if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) return -EPROBE_DEFER; - } =20 - return irq_init_cb(np, par_np); + return irq_probe(pdev, par_np); } EXPORT_SYMBOL_GPL(platform_irqchip_probe); diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq= -combiner.c index 18e696dc7f4d..09819007d08e 100644 --- a/drivers/irqchip/qcom-irq-combiner.c +++ b/drivers/irqchip/qcom-irq-combiner.c @@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, = struct combiner *comb) return 0; } =20 -static int __init combiner_probe(struct platform_device *pdev) +static int combiner_probe(struct platform_device *pdev) { struct combiner *combiner; int nregs; @@ -266,11 +266,11 @@ static const struct acpi_device_id qcom_irq_combiner_= ids[] =3D { { } }; =20 -static struct platform_driver qcom_irq_combiner_probe =3D { +static struct platform_driver qcom_irq_combiner_driver =3D { .driver =3D { .name =3D "qcom-irq-combiner", .acpi_match_table =3D ACPI_PTR(qcom_irq_combiner_ids), }, .probe =3D combiner_probe, }; -builtin_platform_driver(qcom_irq_combiner_probe); +builtin_platform_driver(qcom_irq_combiner_driver); diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 52d77546aacb..518f7f0f3dab 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -350,9 +350,10 @@ static int pdc_setup_pin_mapping(struct device_node *n= p) =20 #define QCOM_PDC_SIZE 0x30000 =20 -static int qcom_pdc_init(struct device_node *node, struct device_node *par= ent) +static int qcom_pdc_probe(struct platform_device *pdev, struct device_node= *parent) { struct irq_domain *parent_domain, *pdc_domain; + struct device_node *node =3D pdev->dev.of_node; resource_size_t res_size; struct resource res; int ret; @@ -428,7 +429,7 @@ static int qcom_pdc_init(struct device_node *node, stru= ct device_node *parent) } =20 IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_pdc) -IRQCHIP_MATCH("qcom,pdc", qcom_pdc_init) +IRQCHIP_MATCH("qcom,pdc", qcom_pdc_probe) IRQCHIP_PLATFORM_DRIVER_END(qcom_pdc) MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Power Domain Controller"); MODULE_LICENSE("GPL v2"); diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h index d5e6024cb2a8..bc4ddacd6ddc 100644 --- a/include/linux/irqchip.h +++ b/include/linux/irqchip.h @@ -17,12 +17,18 @@ #include #include =20 +typedef int (*platform_irq_probe_t)(struct platform_device *, struct devic= e_node *); + /* Undefined on purpose */ extern of_irq_init_cb_t typecheck_irq_init_cb; +extern platform_irq_probe_t typecheck_irq_probe; =20 #define typecheck_irq_init_cb(fn) \ (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn) =20 +#define typecheck_irq_probe(fn) \ + (__typecheck(typecheck_irq_probe, &fn) ? fn : fn) + /* * This macro must be used by the different irqchip drivers to declare * the association between their DT compatible string and their @@ -42,7 +48,7 @@ extern int platform_irqchip_probe(struct platform_device = *pdev); static const struct of_device_id drv_name##_irqchip_match_table[] =3D { =20 #define IRQCHIP_MATCH(compat, fn) { .compatible =3D compat, \ - .data =3D typecheck_irq_init_cb(fn), }, + .data =3D typecheck_irq_probe(fn), }, =20 =20 #define IRQCHIP_PLATFORM_DRIVER_END(drv_name, ...) \