linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/39] irqdomain: Simplify interrupt handling
@ 2021-05-20 16:37 Marc Zyngier
  2021-05-20 16:37 ` [PATCH 01/39] nios2: Do not include linux/irqdomain.h from asm/irq.h Marc Zyngier
                   ` (40 more replies)
  0 siblings, 41 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Although most device drivers only deal with an interrupt number, the
core IRQ code is mostly concerned with the irq_desc structure that
describes the full interrupt context (hierarchy, handlers, state).

However, the low-level interrupt handling code that relies on the
irqdomain abstraction has to perform an annoying dance to eventually
get the core code to invoke interrupt handlers: the irqdomain code
converts a low-level identifier to the unique Linux interrupt number,
and the core code resolves this into an irq_desc pointer.

Each of these two lookups ends-up parsing a radix tree (although the
irqdomain code can use a linear mapping for the smallest domains),
which is obviously one too many. Wouldn't it be nice if the irqdomain
would cache the irq_desc instead of forcing the core code to look it
up on each and every interrupt? This is what this long series is all
about.

There is roughly 3 parts here:

- a substantial amount of massaging for some architectures (nios, mips
  and powerpc) to disentangle weird include constructs (asm/irq.h
  including linux/irqdomain.h is pretty bad...) and simplify bits of
  the irqdomain code

- some rework of the irqdomain code to allow the caching of a irq_data
  pointer, unify the RCU behaviour and offer new APIs.

- Perform a bulk of conversions that turn constructs similar to
  generic_handle_irq(irq_find_mapping(domain, hwirq)) into a simpler
  call to generic_handle_domain_irq(domain, hwirq). Yes, this is a
  mouthful.

I've kept most of the conversions per-subsystem/per-arch in order to
keep the number of patches low (though it is debatable whether I have
succeeded).

This ends up with a negative diffstat, so it can't be completely bad!
Given the breadth of the changes, I do expect some breakage, although
I've extensively compile-tested it and the kbuild robot has been
invaluable in helping with the coverage.

Thanks,

	M.

Marc Zyngier (39):
  nios2: Do not include linux/irqdomain.h from asm/irq.h
  staging: octeon-hcd: Directly include linux/of.h
  mfd: ioc3: Directly include linux/irqdomain.h
  watchdog/octeon-wdt: Directly include linux/irqdomain.h
  irqchip/mips-gic: Directly include linux/irqdomain.h
  MIPS: lantiq: Directly include linux/of.h in xway/dma.c
  MIPS: Add missing linux/irqdomain.h includes
  MIPS: Do not include linux/irqdomain.h from asm/irq.h
  powerpc: Add missing linux/{of.h,irqdomain.h} include directives
  scsi/ibmvscsi: Directly include linux/{of.h,irqdomain.h}
  powerpc: Convert irq_domain_add_legacy_isa use to
    irq_domain_add_legacy
  powerpc: Drop dependency between asm/irq.h and linux/irqdomain.h
  irqdomain: Kill irq_domain_add_legacy_isa
  irqdomain: Reimplement irq_linear_revmap() with irq_find_mapping()
  powerpc: Move the use of irq_domain_add_nomap() behind a config option
  irqdomain: Make normal and nomap irqdomains exclusive
  irqdomain: Use struct_size() helper when allocating irqdomain
  irqdomain: Cache irq_data instead of a virq number in the revmap
  irqdomain: Implement irq_domain_clear_mapping() with
    irq_domain_set_mapping()
  irqdomain: Protect the linear revmap with RCU
  irqdomain: Introduce irq_resolve_mapping()
  genirq: Use irq_resolve_mapping() to implement __handle_domain_irq()
    and co
  irqdesc: Fix __handle_domain_irq() comment
  irqchip/nvic: Convert from handle_IRQ() to handle_domain_irq()
  genirq: Add generic_handle_domain_irq() helper
  genirq: Move non-irqdomain handle_domain_irq() handling into ARM's
    handle_IRQ()
  irqchip: Bulk conversion to generic_handle_domain_irq()
  gpio: Bulk conversion to generic_handle_domain_irq()
  pinctrl: Bulk conversion to generic_handle_domain_irq()
  PCI: Bulk conversion to generic_handle_domain_irq()
  mfd: Bulk conversion to generic_handle_domain_irq()
  gpu: Bulk conversion to generic_handle_domain_irq()
  SH: Bulk conversion to generic_handle_domain_irq()
  ARM: Bulk conversion to generic_handle_domain_irq()
  mips: Bulk conversion to generic_handle_domain_irq()
  arc: Bulk conversion to generic_handle_domain_irq()
  xtensa: Bulk conversion to generic_handle_domain_irq()
  nios2: Bulk conversion to generic_handle_domain_irq()
  powerpc: Bulk conversion to generic_handle_domain_irq()

 Documentation/core-api/irq/irq-domain.rst     |   1 -
 arch/arc/kernel/mcip.c                        |   2 +-
 arch/arm/kernel/irq.c                         |  22 +++-
 arch/arm/mach-pxa/pxa_cplds_irqs.c            |   6 +-
 arch/arm/mach-s3c/irq-s3c24xx.c               |   5 +-
 arch/mips/ath25/ar2315.c                      |  14 +--
 arch/mips/ath25/ar5312.c                      |  13 +-
 arch/mips/include/asm/irq.h                   |   1 -
 arch/mips/lantiq/irq.c                        |   2 +-
 arch/mips/lantiq/xway/dma.c                   |   1 +
 arch/mips/pci/pci-ar2315.c                    |   8 +-
 arch/mips/pci/pci-rt3883.c                    |   6 +-
 arch/mips/pci/pci-xtalk-bridge.c              |   1 +
 arch/mips/ralink/irq.c                        |   2 +-
 arch/mips/sgi-ip27/ip27-irq.c                 |  17 ++-
 arch/mips/sgi-ip30/ip30-irq.c                 |   9 +-
 arch/nios2/include/asm/irq.h                  |   1 -
 arch/nios2/kernel/irq.c                       |   5 +-
 arch/powerpc/include/asm/irq.h                |   5 +-
 arch/powerpc/kernel/mce.c                     |   1 +
 arch/powerpc/kvm/book3s_hv_uvmem.c            |   1 +
 arch/powerpc/kvm/book3s_xive.c                |   1 +
 arch/powerpc/kvm/book3s_xive_native.c         |   1 +
 arch/powerpc/mm/book3s64/radix_pgtable.c      |   1 +
 arch/powerpc/platforms/4xx/uic.c              |   4 +-
 .../powerpc/platforms/512x/mpc5121_ads_cpld.c |  23 ++--
 arch/powerpc/platforms/52xx/media5200.c       |   9 +-
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c     |   7 +-
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c  |   6 +-
 arch/powerpc/platforms/cell/Kconfig           |   1 +
 arch/powerpc/platforms/cell/interrupt.c       |   8 +-
 arch/powerpc/platforms/cell/pmu.c             |   1 +
 arch/powerpc/platforms/cell/spider-pic.c      |  11 +-
 .../platforms/embedded6xx/flipper-pic.c       |   1 +
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c |  15 ++-
 arch/powerpc/platforms/powermac/Kconfig       |   1 +
 arch/powerpc/platforms/powernv/opal-irqchip.c |  11 +-
 arch/powerpc/platforms/ps3/Kconfig            |   1 +
 arch/powerpc/platforms/ps3/interrupt.c        |   5 +-
 arch/powerpc/platforms/pseries/ibmebus.c      |   1 +
 arch/powerpc/sysdev/ehv_pic.c                 |   1 +
 arch/powerpc/sysdev/fsl_mpic_err.c            |  12 +-
 arch/powerpc/sysdev/fsl_msi.c                 |   8 +-
 arch/powerpc/sysdev/i8259.c                   |   3 +-
 arch/powerpc/sysdev/mpic.c                    |   2 +-
 arch/powerpc/sysdev/tsi108_pci.c              |   3 +-
 arch/powerpc/sysdev/xics/icp-hv.c             |   1 +
 arch/powerpc/sysdev/xics/icp-opal.c           |   1 +
 arch/powerpc/sysdev/xics/xics-common.c        |   2 +-
 arch/powerpc/sysdev/xive/Kconfig              |   1 +
 arch/sh/boards/mach-se/7343/irq.c             |   2 +-
 arch/sh/boards/mach-se/7722/irq.c             |   2 +-
 arch/sh/boards/mach-x3proto/gpio.c            |   2 +-
 arch/xtensa/kernel/irq.c                      |   4 +-
 drivers/gpio/gpio-104-dio-48e.c               |   4 +-
 drivers/gpio/gpio-104-idi-48.c                |   4 +-
 drivers/gpio/gpio-104-idio-16.c               |   2 +-
 drivers/gpio/gpio-altera.c                    |  11 +-
 drivers/gpio/gpio-aspeed-sgpio.c              |   9 +-
 drivers/gpio/gpio-aspeed.c                    |   9 +-
 drivers/gpio/gpio-ath79.c                     |   7 +-
 drivers/gpio/gpio-bcm-kona.c                  |   6 +-
 drivers/gpio/gpio-brcmstb.c                   |   5 +-
 drivers/gpio/gpio-cadence.c                   |   2 +-
 drivers/gpio/gpio-davinci.c                   |   3 +-
 drivers/gpio/gpio-dln2.c                      |  22 ++--
 drivers/gpio/gpio-em.c                        |   2 +-
 drivers/gpio/gpio-ep93xx.c                    |   8 +-
 drivers/gpio/gpio-ftgpio010.c                 |   3 +-
 drivers/gpio/gpio-hisi.c                      |   4 +-
 drivers/gpio/gpio-hlwd.c                      |   7 +-
 drivers/gpio/gpio-merrifield.c                |   8 +-
 drivers/gpio/gpio-mpc8xxx.c                   |   2 +-
 drivers/gpio/gpio-mt7621.c                    |   4 +-
 drivers/gpio/gpio-mxc.c                       |   2 +-
 drivers/gpio/gpio-mxs.c                       |   2 +-
 drivers/gpio/gpio-omap.c                      |   3 +-
 drivers/gpio/gpio-pci-idio-16.c               |   2 +-
 drivers/gpio/gpio-pcie-idio-24.c              |   3 +-
 drivers/gpio/gpio-pl061.c                     |   4 +-
 drivers/gpio/gpio-pxa.c                       |   9 +-
 drivers/gpio/gpio-rcar.c                      |   4 +-
 drivers/gpio/gpio-rda.c                       |   8 +-
 drivers/gpio/gpio-realtek-otto.c              |   7 +-
 drivers/gpio/gpio-sch.c                       |   2 +-
 drivers/gpio/gpio-sodaville.c                 |   2 +-
 drivers/gpio/gpio-sprd.c                      |  12 +-
 drivers/gpio/gpio-tb10x.c                     |   2 +-
 drivers/gpio/gpio-tegra.c                     |   9 +-
 drivers/gpio/gpio-tegra186.c                  |   9 +-
 drivers/gpio/gpio-tqmx86.c                    |  10 +-
 drivers/gpio/gpio-vf610.c                     |   2 +-
 drivers/gpio/gpio-ws16c48.c                   |   4 +-
 drivers/gpio/gpio-xgs-iproc.c                 |   2 +-
 drivers/gpio/gpio-xilinx.c                    |   9 +-
 drivers/gpio/gpio-xlp.c                       |   3 +-
 drivers/gpio/gpio-zynq.c                      |   8 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c       |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c      |  15 +--
 drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c     |   3 +-
 drivers/gpu/ipu-v3/ipu-common.c               |  11 +-
 drivers/irqchip/exynos-combiner.c             |  10 +-
 drivers/irqchip/irq-al-fic.c                  |   7 +-
 drivers/irqchip/irq-armada-370-xp.c           |  19 ++-
 drivers/irqchip/irq-aspeed-i2c-ic.c           |   8 +-
 drivers/irqchip/irq-aspeed-scu-ic.c           |   6 +-
 drivers/irqchip/irq-ath79-misc.c              |   2 +-
 drivers/irqchip/irq-bcm2835.c                 |   2 +-
 drivers/irqchip/irq-bcm2836.c                 |   2 +-
 drivers/irqchip/irq-bcm7038-l1.c              |   6 +-
 drivers/irqchip/irq-bcm7120-l2.c              |   6 +-
 drivers/irqchip/irq-brcmstb-l2.c              |   2 +-
 drivers/irqchip/irq-dw-apb-ictl.c             |   3 +-
 drivers/irqchip/irq-gic.c                     |  13 +-
 drivers/irqchip/irq-goldfish-pic.c            |   5 +-
 drivers/irqchip/irq-i8259.c                   |   4 +-
 drivers/irqchip/irq-idt3243x.c                |   6 +-
 drivers/irqchip/irq-imgpdc.c                  |  11 +-
 drivers/irqchip/irq-imx-intmux.c              |   9 +-
 drivers/irqchip/irq-imx-irqsteer.c            |   9 +-
 drivers/irqchip/irq-ingenic-tcu.c             |   2 +-
 drivers/irqchip/irq-ingenic.c                 |   3 +-
 drivers/irqchip/irq-keystone.c                |  14 +--
 drivers/irqchip/irq-loongson-htpic.c          |   2 +-
 drivers/irqchip/irq-loongson-htvec.c          |   4 +-
 drivers/irqchip/irq-loongson-liointc.c        |   2 +-
 drivers/irqchip/irq-lpc32xx.c                 |   2 +-
 drivers/irqchip/irq-ls-scfg-msi.c             |   6 +-
 drivers/irqchip/irq-ls1x.c                    |   2 +-
 drivers/irqchip/irq-mips-gic.c                |  21 ++--
 drivers/irqchip/irq-mscc-ocelot.c             |   2 +-
 drivers/irqchip/irq-mvebu-pic.c               |   7 +-
 drivers/irqchip/irq-mvebu-sei.c               |  13 +-
 drivers/irqchip/irq-nvic.c                    |   4 +-
 drivers/irqchip/irq-orion.c                   |   2 +-
 drivers/irqchip/irq-partition-percpu.c        |   9 +-
 drivers/irqchip/irq-pruss-intc.c              |   9 +-
 drivers/irqchip/irq-realtek-rtl.c             |   2 +-
 drivers/irqchip/irq-renesas-irqc.c            |   2 +-
 drivers/irqchip/irq-sifive-plic.c             |   8 +-
 drivers/irqchip/irq-stm32-exti.c              |  10 +-
 drivers/irqchip/irq-sunxi-nmi.c               |   3 +-
 drivers/irqchip/irq-tb10x.c                   |   2 +-
 drivers/irqchip/irq-ti-sci-inta.c             |   9 +-
 drivers/irqchip/irq-ts4800.c                  |   3 +-
 drivers/irqchip/irq-versatile-fpga.c          |   2 +-
 drivers/irqchip/irq-vic.c                     |   2 +-
 drivers/irqchip/irq-xilinx-intc.c             |  22 +---
 drivers/irqchip/qcom-irq-combiner.c           |   6 +-
 drivers/mfd/db8500-prcmu.c                    |   2 +-
 drivers/mfd/fsl-imx25-tsadc.c                 |   4 +-
 drivers/mfd/ioc3.c                            |  11 +-
 drivers/mfd/qcom-pm8xxx.c                     |  10 +-
 drivers/pci/controller/dwc/pci-dra7xx.c       |  14 +--
 drivers/pci/controller/dwc/pci-keystone.c     |   5 +-
 .../pci/controller/dwc/pcie-designware-host.c |   9 +-
 drivers/pci/controller/dwc/pcie-uniphier.c    |   6 +-
 .../controller/mobiveil/pcie-mobiveil-host.c  |  15 +--
 drivers/pci/controller/pci-aardvark.c         |   5 +-
 drivers/pci/controller/pci-ftpci100.c         |   2 +-
 drivers/pci/controller/pci-tegra.c            |   8 +-
 drivers/pci/controller/pci-xgene-msi.c        |   9 +-
 drivers/pci/controller/pcie-altera-msi.c      |  10 +-
 drivers/pci/controller/pcie-altera.c          |  10 +-
 drivers/pci/controller/pcie-brcmstb.c         |   9 +-
 drivers/pci/controller/pcie-iproc-msi.c       |   4 +-
 drivers/pci/controller/pcie-mediatek-gen3.c   |  13 +-
 drivers/pci/controller/pcie-mediatek.c        |  12 +-
 drivers/pci/controller/pcie-microchip-host.c  |  18 ++-
 drivers/pci/controller/pcie-rcar-host.c       |   8 +-
 drivers/pci/controller/pcie-rockchip-host.c   |   8 +-
 drivers/pci/controller/pcie-xilinx-cpm.c      |   4 +-
 drivers/pci/controller/pcie-xilinx-nwl.c      |  13 +-
 drivers/pci/controller/pcie-xilinx.c          |   9 +-
 drivers/pinctrl/actions/pinctrl-owl.c         |   5 +-
 drivers/pinctrl/bcm/pinctrl-bcm2835.c         |   4 +-
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c      |   3 +-
 drivers/pinctrl/bcm/pinctrl-nsp-gpio.c        |   3 +-
 drivers/pinctrl/intel/pinctrl-baytrail.c      |   7 +-
 drivers/pinctrl/intel/pinctrl-cherryview.c    |   5 +-
 drivers/pinctrl/intel/pinctrl-lynxpoint.c     |   8 +-
 drivers/pinctrl/mediatek/mtk-eint.c           |   5 +-
 drivers/pinctrl/nomadik/pinctrl-nomadik.c     |   2 +-
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c     |   2 +-
 drivers/pinctrl/pinctrl-amd.c                 |   6 +-
 drivers/pinctrl/pinctrl-at91.c                |   6 +-
 drivers/pinctrl/pinctrl-equilibrium.c         |   2 +-
 drivers/pinctrl/pinctrl-ingenic.c             |   2 +-
 drivers/pinctrl/pinctrl-microchip-sgpio.c     |   2 +-
 drivers/pinctrl/pinctrl-ocelot.c              |   3 +-
 drivers/pinctrl/pinctrl-oxnas.c               |   2 +-
 drivers/pinctrl/pinctrl-pic32.c               |   2 +-
 drivers/pinctrl/pinctrl-pistachio.c           |   2 +-
 drivers/pinctrl/pinctrl-rockchip.c            |  15 +--
 drivers/pinctrl/pinctrl-single.c              |   4 +-
 drivers/pinctrl/pinctrl-st.c                  |   2 +-
 drivers/pinctrl/qcom/pinctrl-msm.c            |   4 +-
 drivers/pinctrl/samsung/pinctrl-exynos.c      |  15 ++-
 drivers/pinctrl/samsung/pinctrl-s3c24xx.c     |  25 ++--
 drivers/pinctrl/samsung/pinctrl-s3c64xx.c     |  17 ++-
 drivers/pinctrl/spear/pinctrl-plgpio.c        |   3 +-
 drivers/pinctrl/sunxi/pinctrl-sunxi.c         |   8 +-
 drivers/scsi/ibmvscsi/ibmvfc.c                |   1 +
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c      |   1 +
 drivers/staging/octeon-usb/octeon-hcd.c       |   1 +
 drivers/watchdog/octeon-wdt-main.c            |   1 +
 include/linux/irqdesc.h                       |  18 ++-
 include/linux/irqdomain.h                     |  60 +++++-----
 kernel/irq/Kconfig                            |   5 +
 kernel/irq/irqdesc.c                          |  73 +++++++-----
 kernel/irq/irqdomain.c                        | 112 +++++++++++-------
 211 files changed, 658 insertions(+), 847 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 01/39] nios2: Do not include linux/irqdomain.h from asm/irq.h
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 02/39] staging: octeon-hcd: Directly include linux/of.h Marc Zyngier
                   ` (39 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Including linux/irqdomain.h from asm/irq.h is going to break
as soon as linux/irqdomain.h will include linux/irq.h, so
let's fix this. Code relying on linux/irqomain.h should include
it directly.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/nios2/include/asm/irq.h | 1 -
 arch/nios2/kernel/irq.c      | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/nios2/include/asm/irq.h b/arch/nios2/include/asm/irq.h
index 13ce37272279..c52c94884e93 100644
--- a/arch/nios2/include/asm/irq.h
+++ b/arch/nios2/include/asm/irq.h
@@ -10,6 +10,5 @@
 #define NIOS2_CPU_NR_IRQS	32
 
 #include <asm-generic/irq.h>
-#include <linux/irqdomain.h>
 
 #endif
diff --git a/arch/nios2/kernel/irq.c b/arch/nios2/kernel/irq.c
index 5f3555ce4865..c6a1a9f6ac42 100644
--- a/arch/nios2/kernel/irq.c
+++ b/arch/nios2/kernel/irq.c
@@ -11,6 +11,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/of.h>
 
 static u32 ienable;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 02/39] staging: octeon-hcd: Directly include linux/of.h
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
  2021-05-20 16:37 ` [PATCH 01/39] nios2: Do not include linux/irqdomain.h from asm/irq.h Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 03/39] mfd: ioc3: Directly include linux/irqdomain.h Marc Zyngier
                   ` (38 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

This drivers currently obtains linux/of.h by luck and a chain of
bizarre inclusions, which we're about to fix.

Let's include the required file directly.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/staging/octeon-usb/octeon-hcd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index f27f20a4aa2d..a079bd0f5b61 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -52,6 +52,7 @@
 #include <linux/prefetch.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <asm/octeon/octeon.h>
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 03/39] mfd: ioc3: Directly include linux/irqdomain.h
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
  2021-05-20 16:37 ` [PATCH 01/39] nios2: Do not include linux/irqdomain.h from asm/irq.h Marc Zyngier
  2021-05-20 16:37 ` [PATCH 02/39] staging: octeon-hcd: Directly include linux/of.h Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-21  7:07   ` Lee Jones
  2021-05-20 16:37 ` [PATCH 04/39] watchdog/octeon-wdt: " Marc Zyngier
                   ` (37 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

This driver include linux/irqdomain.h via a bizarre set of
indirection, which we are about to break.

Directly include the required file.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/mfd/ioc3.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mfd/ioc3.c b/drivers/mfd/ioc3.c
index c73ec78f255b..99b9c113f964 100644
--- a/drivers/mfd/ioc3.c
+++ b/drivers/mfd/ioc3.c
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 04/39] watchdog/octeon-wdt: Directly include linux/irqdomain.h
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (2 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 03/39] mfd: ioc3: Directly include linux/irqdomain.h Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 05/39] irqchip/mips-gic: " Marc Zyngier
                   ` (36 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

This drivers currently obtains linux/irqdomain.h by luck and
a chain of bizarre inclusions, which we're about to fix.

Let's include the required file directly.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/watchdog/octeon-wdt-main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c
index fde9e739b436..391c774a1f67 100644
--- a/drivers/watchdog/octeon-wdt-main.c
+++ b/drivers/watchdog/octeon-wdt-main.c
@@ -54,6 +54,7 @@
 #include <linux/delay.h>
 #include <linux/cpu.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 
 #include <asm/mipsregs.h>
 #include <asm/uasm.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 05/39] irqchip/mips-gic: Directly include linux/irqdomain.h
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (3 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 04/39] watchdog/octeon-wdt: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 06/39] MIPS: lantiq: Directly include linux/of.h in xway/dma.c Marc Zyngier
                   ` (35 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

This drivers currently obtains linux/irqdomain.h by luck and
a chain of bizarre inclusions, which we're about to fix.

Let's include the required file directly.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-mips-gic.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index 215885962bb0..a2cbf0acff1c 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
+#include <linux/irqdomain.h>
 #include <linux/of_address.h>
 #include <linux/percpu.h>
 #include <linux/sched.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 06/39] MIPS: lantiq: Directly include linux/of.h in xway/dma.c
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (4 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 05/39] irqchip/mips-gic: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 07/39] MIPS: Add missing linux/irqdomain.h includes Marc Zyngier
                   ` (34 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

This drivers currently obtains linux/of.h by luck and a chain of
bizarre inclusions, which we're about to fix.

Let's include the required file directly.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/mips/lantiq/xway/dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
index aeb1b989cd4e..63dccb2ed08b 100644
--- a/arch/mips/lantiq/xway/dma.c
+++ b/arch/mips/lantiq/xway/dma.c
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/of.h>
 
 #include <lantiq_soc.h>
 #include <xway_dma.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 07/39] MIPS: Add missing linux/irqdomain.h includes
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (5 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 06/39] MIPS: lantiq: Directly include linux/of.h in xway/dma.c Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 08/39] MIPS: Do not include linux/irqdomain.h from asm/irq.h Marc Zyngier
                   ` (33 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

A number of MIPS platforms are failing to directly include
irqdomain.h. Fix this so that we can drop unnecessary dependencies

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/mips/pci/pci-rt3883.c       | 1 +
 arch/mips/pci/pci-xtalk-bridge.c | 1 +
 arch/mips/sgi-ip27/ip27-irq.c    | 1 +
 arch/mips/sgi-ip30/ip30-irq.c    | 1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index aebd4964ea34..c48e23cf5b5e 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/of_pci.h>
diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c
index d2216942af18..ab9bedb82b28 100644
--- a/arch/mips/pci/pci-xtalk-bridge.c
+++ b/arch/mips/pci/pci-xtalk-bridge.c
@@ -13,6 +13,7 @@
 #include <linux/platform_data/xtalk-bridge.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/crc16.h>
+#include <linux/irqdomain.h>
 
 #include <asm/pci/bridge.h>
 #include <asm/paccess.h>
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 42df9fafa943..95c1bff1ab9f 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -9,6 +9,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
diff --git a/arch/mips/sgi-ip30/ip30-irq.c b/arch/mips/sgi-ip30/ip30-irq.c
index e8374e4c705b..ba87704073c8 100644
--- a/arch/mips/sgi-ip30/ip30-irq.c
+++ b/arch/mips/sgi-ip30/ip30-irq.c
@@ -6,6 +6,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/percpu.h>
 #include <linux/spinlock.h>
 #include <linux/tick.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 08/39] MIPS: Do not include linux/irqdomain.h from asm/irq.h
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (6 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 07/39] MIPS: Add missing linux/irqdomain.h includes Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 09/39] powerpc: Add missing linux/{of.h,irqdomain.h} include directives Marc Zyngier
                   ` (32 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Including linux/irqdomain.h from asm/irq.h is going to break
as soon as linux/irqdomain.h will include linux/irq.h, so
let's fix this. Code relying on linux/irqomain.h should include
it directly.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/mips/include/asm/irq.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index f021de661c3a..d1477ecb1af9 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -11,7 +11,6 @@
 
 #include <linux/linkage.h>
 #include <linux/smp.h>
-#include <linux/irqdomain.h>
 
 #include <asm/mipsmtregs.h>
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 09/39] powerpc: Add missing linux/{of.h,irqdomain.h} include directives
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (7 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 08/39] MIPS: Do not include linux/irqdomain.h from asm/irq.h Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 10/39] scsi/ibmvscsi: Directly include linux/{of.h,irqdomain.h} Marc Zyngier
                   ` (31 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

A bunch of PPC files are missing the inclusion of linux/of.h and
linux/irqdomain.h, relying on transitive inclusion from another
file.

As we are about to break this dependency, make sure these dependencies
are explicit.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/powerpc/kernel/mce.c                        | 1 +
 arch/powerpc/kvm/book3s_hv_uvmem.c               | 1 +
 arch/powerpc/kvm/book3s_xive.c                   | 1 +
 arch/powerpc/kvm/book3s_xive_native.c            | 1 +
 arch/powerpc/mm/book3s64/radix_pgtable.c         | 1 +
 arch/powerpc/platforms/cell/pmu.c                | 1 +
 arch/powerpc/platforms/embedded6xx/flipper-pic.c | 1 +
 arch/powerpc/platforms/ps3/interrupt.c           | 1 +
 arch/powerpc/platforms/pseries/ibmebus.c         | 1 +
 arch/powerpc/sysdev/ehv_pic.c                    | 1 +
 arch/powerpc/sysdev/fsl_mpic_err.c               | 1 +
 arch/powerpc/sysdev/xics/icp-hv.c                | 1 +
 arch/powerpc/sysdev/xics/icp-opal.c              | 1 +
 13 files changed, 13 insertions(+)

diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index 9a3c2a84a2ac..15e7b4900689 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -18,6 +18,7 @@
 #include <linux/extable.h>
 #include <linux/ftrace.h>
 #include <linux/memblock.h>
+#include <linux/of.h>
 
 #include <asm/interrupt.h>
 #include <asm/machdep.h>
diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 84e5a2dc8be5..b898a596db42 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -90,6 +90,7 @@
 #include <linux/migrate.h>
 #include <linux/kvm_host.h>
 #include <linux/ksm.h>
+#include <linux/of.h>
 #include <asm/ultravisor.h>
 #include <asm/mman.h>
 #include <asm/kvm_ppc.h>
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index e7219b6f5f9a..08910d44d2cb 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -14,6 +14,7 @@
 #include <linux/percpu.h>
 #include <linux/cpumask.h>
 #include <linux/uaccess.h>
+#include <linux/irqdomain.h>
 #include <asm/kvm_book3s.h>
 #include <asm/kvm_ppc.h>
 #include <asm/hvcall.h>
diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c
index 76800c84f2a3..30bacf6dd53d 100644
--- a/arch/powerpc/kvm/book3s_xive_native.c
+++ b/arch/powerpc/kvm/book3s_xive_native.c
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/delay.h>
 #include <linux/file.h>
+#include <linux/irqdomain.h>
 #include <asm/uaccess.h>
 #include <asm/kvm_book3s.h>
 #include <asm/kvm_ppc.h>
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 5fef8db3b463..edadb9e9c9c0 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/sched/mm.h>
 #include <linux/memblock.h>
+#include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
index 35bbd15582af..b207a7f99be5 100644
--- a/arch/powerpc/platforms/cell/pmu.c
+++ b/arch/powerpc/platforms/cell/pmu.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/types.h>
 #include <linux/export.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index d39a9213a3e6..609bda2ad5dd 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <asm/io.h>
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 78f2339ed5cb..e68f4fb1c1f4 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/export.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 
 #include <asm/machdep.h>
 #include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/pseries/ibmebus.c b/arch/powerpc/platforms/pseries/ibmebus.c
index a15ab33646b3..c6c79ef55e13 100644
--- a/arch/powerpc/platforms/pseries/ibmebus.c
+++ b/arch/powerpc/platforms/pseries/ibmebus.c
@@ -42,6 +42,7 @@
 #include <linux/kobject.h>
 #include <linux/dma-map-ops.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index 48866e6c1efb..00705258ecf9 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
diff --git a/arch/powerpc/sysdev/fsl_mpic_err.c b/arch/powerpc/sysdev/fsl_mpic_err.c
index 13583bbc3e8e..5fa5fa215541 100644
--- a/arch/powerpc/sysdev/fsl_mpic_err.c
+++ b/arch/powerpc/sysdev/fsl_mpic_err.c
@@ -8,6 +8,7 @@
 #include <linux/irq.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c
index 21b9d1bf39ff..6765d9e264a3 100644
--- a/arch/powerpc/sysdev/xics/icp-hv.c
+++ b/arch/powerpc/sysdev/xics/icp-hv.c
@@ -7,6 +7,7 @@
 #include <linux/irq.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/cpu.h>
 #include <linux/of.h>
 
diff --git a/arch/powerpc/sysdev/xics/icp-opal.c b/arch/powerpc/sysdev/xics/icp-opal.c
index 68fd2540b093..675d708863d5 100644
--- a/arch/powerpc/sysdev/xics/icp-opal.c
+++ b/arch/powerpc/sysdev/xics/icp-opal.c
@@ -7,6 +7,7 @@
 #include <linux/irq.h>
 #include <linux/smp.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/cpu.h>
 #include <linux/of.h>
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 10/39] scsi/ibmvscsi: Directly include linux/{of.h,irqdomain.h}
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (8 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 09/39] powerpc: Add missing linux/{of.h,irqdomain.h} include directives Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 11/39] powerpc: Convert irq_domain_add_legacy_isa use to irq_domain_add_legacy Marc Zyngier
                   ` (30 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

A couple of ibmvscsi files are missing the inclusion of linux/of.h
and linux/irqdomain.h, relying on transitive inclusion from another
file.

As we are about to break this dependency, make sure these dependencies
are explicit.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/scsi/ibmvscsi/ibmvfc.c           | 1 +
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 6540d48eb0e8..715c34904e3e 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -13,6 +13,7 @@
 #include <linux/dmapool.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/kthread.h>
 #include <linux/slab.h>
 #include <linux/of.h>
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index 41ac9477df7a..10b6c6daaacd 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -22,6 +22,7 @@
 #include <linux/list.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_fabric.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 11/39] powerpc: Convert irq_domain_add_legacy_isa use to irq_domain_add_legacy
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (9 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 10/39] scsi/ibmvscsi: Directly include linux/{of.h,irqdomain.h} Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 12/39] powerpc: Drop dependency between asm/irq.h and linux/irqdomain.h Marc Zyngier
                   ` (29 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

irq_domain_add_legacy_isa is a pain. It only exists for the benefit of
two PPC-specific drivers, and creates an ugly dependency between asm/irq.h
and linux/irqdomain.h

Instead, let's convert these two drivers to irq_domain_add_legacy(),
stop using NUM_ISA_INTERRUPTS by directly setting NR_IRQS_LEGACY.

The dependency cannot be broken yet as there is a lot of PPC-related
code that depends on it, but that's the first step towards it.

A followup patch will remove irq_domain_add_legacy_isa.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/powerpc/include/asm/irq.h         | 4 ++--
 arch/powerpc/platforms/ps3/interrupt.c | 4 ++--
 arch/powerpc/sysdev/i8259.c            | 3 ++-
 arch/powerpc/sysdev/mpic.c             | 2 +-
 arch/powerpc/sysdev/tsi108_pci.c       | 3 ++-
 arch/powerpc/sysdev/xics/xics-common.c | 2 +-
 6 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index b2bd58830430..c1eda9199214 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -23,8 +23,8 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Total number of virq in the platform */
 #define NR_IRQS		CONFIG_NR_IRQS
 
-/* Same thing, used by the generic IRQ code */
-#define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
+/* Number of irqs reserved for a legacy isa controller */
+#define NR_IRQS_LEGACY		16
 
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
 
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index e68f4fb1c1f4..49871427f599 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -46,7 +46,7 @@
  * implementation equates HV plug value to Linux virq value, constrains each
  * interrupt to have a system wide unique plug number, and limits the range
  * of the plug values to map into the first dword of the bitmaps.  This
- * gives a usable range of plug values of  {NUM_ISA_INTERRUPTS..63}.  Note
+ * gives a usable range of plug values of  {NR_IRQS_LEGACY..63}.  Note
  * that there is no constraint on how many in this set an individual thread
  * can acquire.
  *
@@ -722,7 +722,7 @@ static unsigned int ps3_get_irq(void)
 	}
 
 #if defined(DEBUG)
-	if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) {
+	if (unlikely(plug < NR_IRQS_LEGACY || plug > PS3_PLUG_MAX)) {
 		dump_bmp(&per_cpu(ps3_private, 0));
 		dump_bmp(&per_cpu(ps3_private, 1));
 		BUG();
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index c1d76c344351..dc1a151c63d7 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -260,7 +260,8 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
 	raw_spin_unlock_irqrestore(&i8259_lock, flags);
 
 	/* create a legacy host */
-	i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL);
+	i8259_host = irq_domain_add_legacy(node, NR_IRQS_LEGACY, 0, 0,
+					   &i8259_host_ops, NULL);
 	if (i8259_host == NULL) {
 		printk(KERN_ERR "i8259: failed to allocate irq host !\n");
 		return;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index b0426f28946a..995fb2ada507 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -602,7 +602,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
 /* Find an mpic associated with a given linux interrupt */
 static struct mpic *mpic_find(unsigned int irq)
 {
-	if (irq < NUM_ISA_INTERRUPTS)
+	if (irq < NR_IRQS_LEGACY)
 		return NULL;
 
 	return irq_get_chip_data(irq);
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 49f9541954f8..042bb38fa5c2 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -404,7 +404,8 @@ void __init tsi108_pci_int_init(struct device_node *node)
 {
 	DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
 
-	pci_irq_host = irq_domain_add_legacy_isa(node, &pci_irq_domain_ops, NULL);
+	pci_irq_host = irq_domain_add_legacy(node, NR_IRQS_LEGACY, 0, 0,
+					     &pci_irq_domain_ops, NULL);
 	if (pci_irq_host == NULL) {
 		printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
 		return;
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index 7e4305c01bac..fdf8db4444b6 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -201,7 +201,7 @@ void xics_migrate_irqs_away(void)
 		struct ics *ics;
 
 		/* We can't set affinity on ISA interrupts */
-		if (virq < NUM_ISA_INTERRUPTS)
+		if (virq < NR_IRQS_LEGACY)
 			continue;
 		/* We only need to migrate enabled IRQS */
 		if (!desc->action)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 12/39] powerpc: Drop dependency between asm/irq.h and linux/irqdomain.h
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (10 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 11/39] powerpc: Convert irq_domain_add_legacy_isa use to irq_domain_add_legacy Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 13/39] irqdomain: Kill irq_domain_add_legacy_isa Marc Zyngier
                   ` (28 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Directly including linux/irqdomain.h was hiding all sort of sins,
which have now been fixed. Drop the spurious include.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/powerpc/include/asm/irq.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index c1eda9199214..4982f3711fc3 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -6,7 +6,6 @@
 /*
  */
 
-#include <linux/irqdomain.h>
 #include <linux/threads.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 13/39] irqdomain: Kill irq_domain_add_legacy_isa
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (11 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 12/39] powerpc: Drop dependency between asm/irq.h and linux/irqdomain.h Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 14/39] irqdomain: Reimplement irq_linear_revmap() with irq_find_mapping() Marc Zyngier
                   ` (27 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

This helper doesn't have a user anymore, let's remove it.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 Documentation/core-api/irq/irq-domain.rst |  1 -
 include/linux/irqdomain.h                 | 11 -----------
 2 files changed, 12 deletions(-)

diff --git a/Documentation/core-api/irq/irq-domain.rst b/Documentation/core-api/irq/irq-domain.rst
index 8214e215a8bf..53283b3729a1 100644
--- a/Documentation/core-api/irq/irq-domain.rst
+++ b/Documentation/core-api/irq/irq-domain.rst
@@ -146,7 +146,6 @@ Legacy
 
 	irq_domain_add_simple()
 	irq_domain_add_legacy()
-	irq_domain_add_legacy_isa()
 	irq_domain_create_simple()
 	irq_domain_create_legacy()
 
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 62a8e3d23829..9f884c948739 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -45,9 +45,6 @@ struct cpumask;
 struct seq_file;
 struct irq_affinity_desc;
 
-/* Number of irqs reserved for a legacy isa controller */
-#define NUM_ISA_INTERRUPTS	16
-
 #define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16
 
 /**
@@ -355,14 +352,6 @@ static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_nod
 {
 	return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
 }
-static inline struct irq_domain *irq_domain_add_legacy_isa(
-				struct device_node *of_node,
-				const struct irq_domain_ops *ops,
-				void *host_data)
-{
-	return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
-				     host_data);
-}
 static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
 					 const struct irq_domain_ops *ops,
 					 void *host_data)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 14/39] irqdomain: Reimplement irq_linear_revmap() with irq_find_mapping()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (12 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 13/39] irqdomain: Kill irq_domain_add_legacy_isa Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 15/39] powerpc: Move the use of irq_domain_add_nomap() behind a config option Marc Zyngier
                   ` (26 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

irq_linear_revmap() is supposed to be a fast path for domain
lookups, but it only exposes low-level details of the irqdomain
implementation, details which are better kept private.

The *overhead* between the two is only a function call and
a couple of tests, so it is likely that noone can show any
meaningful difference compared to the cost of taking an
interrupt.

Reimplement irq_linear_revmap() with irq_find_mapping()
in order to preserve source code compatibility, and
rename the internal field for a measure.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdomain.h | 22 +++++++++-------------
 kernel/irq/irqdomain.c    |  6 +++---
 2 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 9f884c948739..42b3f7d03a32 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -151,9 +151,9 @@ struct irq_domain_chip_generic;
  * Revmap data, used internally by irq_domain
  * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
  *                         support direct mapping
- * @revmap_size: Size of the linear map table @linear_revmap[]
+ * @revmap_size: Size of the linear map table @revmap[]
  * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
- * @linear_revmap: Linear table of hwirq->virq reverse mappings
+ * @revmap: Linear table of hwirq->virq reverse mappings
  */
 struct irq_domain {
 	struct list_head link;
@@ -177,7 +177,7 @@ struct irq_domain {
 	unsigned int revmap_size;
 	struct radix_tree_root revmap_tree;
 	struct mutex revmap_tree_mutex;
-	unsigned int linear_revmap[];
+	unsigned int revmap[];
 };
 
 /* Irq domain flags */
@@ -394,24 +394,20 @@ static inline unsigned int irq_create_mapping(struct irq_domain *host,
 	return irq_create_mapping_affinity(host, hwirq, NULL);
 }
 
-
 /**
- * irq_linear_revmap() - Find a linux irq from a hw irq number.
+ * irq_find_mapping() - Find a linux irq from a hw irq number.
  * @domain: domain owning this hardware interrupt
  * @hwirq: hardware irq number in that domain space
- *
- * This is a fast path alternative to irq_find_mapping() that can be
- * called directly by irq controller code to save a handful of
- * instructions. It is always safe to call, but won't find irqs mapped
- * using the radix tree.
  */
+extern unsigned int irq_find_mapping(struct irq_domain *host,
+				     irq_hw_number_t hwirq);
+
 static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
 					     irq_hw_number_t hwirq)
 {
-	return hwirq < domain->revmap_size ? domain->linear_revmap[hwirq] : 0;
+	return irq_find_mapping(domain, hwirq);
 }
-extern unsigned int irq_find_mapping(struct irq_domain *host,
-				     irq_hw_number_t hwirq);
+
 extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
 
 extern const struct irq_domain_ops irq_domain_simple_ops;
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 6284443b87ec..8bd012253989 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -486,7 +486,7 @@ static void irq_domain_clear_mapping(struct irq_domain *domain,
 				     irq_hw_number_t hwirq)
 {
 	if (hwirq < domain->revmap_size) {
-		domain->linear_revmap[hwirq] = 0;
+		domain->revmap[hwirq] = 0;
 	} else {
 		mutex_lock(&domain->revmap_tree_mutex);
 		radix_tree_delete(&domain->revmap_tree, hwirq);
@@ -499,7 +499,7 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
 				   struct irq_data *irq_data)
 {
 	if (hwirq < domain->revmap_size) {
-		domain->linear_revmap[hwirq] = irq_data->irq;
+		domain->revmap[hwirq] = irq_data->irq;
 	} else {
 		mutex_lock(&domain->revmap_tree_mutex);
 		radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);
@@ -885,7 +885,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 
 	/* Check if the hwirq is in the linear revmap. */
 	if (hwirq < domain->revmap_size)
-		return domain->linear_revmap[hwirq];
+		return domain->revmap[hwirq];
 
 	rcu_read_lock();
 	data = radix_tree_lookup(&domain->revmap_tree, hwirq);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 15/39] powerpc: Move the use of irq_domain_add_nomap() behind a config option
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (13 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 14/39] irqdomain: Reimplement irq_linear_revmap() with irq_find_mapping() Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive Marc Zyngier
                   ` (25 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Only a handful of old PPC systems are still using the old 'nomap'
variant of the irqdomain library. Move the associated definitions
behind a configuration option, which will allow us to make some
more radical changes.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/powerpc/platforms/cell/Kconfig     | 1 +
 arch/powerpc/platforms/powermac/Kconfig | 1 +
 arch/powerpc/platforms/ps3/Kconfig      | 1 +
 arch/powerpc/sysdev/xive/Kconfig        | 1 +
 include/linux/irqdomain.h               | 8 ++++++--
 kernel/irq/Kconfig                      | 5 +++++
 kernel/irq/irqdomain.c                  | 2 ++
 7 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index e7c976bcadff..cb70c5f25bc6 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -35,6 +35,7 @@ config PPC_IBM_CELL_BLADE
 config AXON_MSI
 	bool
 	depends on PPC_IBM_CELL_BLADE && PCI_MSI
+	select IRQ_DOMAIN_NOMAP
 	default y
 
 menu "Cell Broadband Engine options"
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index c02d8c503b29..b97bf12801eb 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -24,6 +24,7 @@ config PPC_PMAC32_PSURGE
 	bool "Support for powersurge upgrade cards" if EXPERT
 	depends on SMP && PPC32 && PPC_PMAC
 	select PPC_SMP_MUXED_IPI
+	select IRQ_DOMAIN_NOMAP
 	default y
 	help
 	  The powersurge cpu boards can be used in the generation
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index e32406e918d0..4d0535cc7946 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -7,6 +7,7 @@ config PPC_PS3
 	select USB_OHCI_BIG_ENDIAN_MMIO
 	select USB_EHCI_BIG_ENDIAN_MMIO
 	select HAVE_PCI
+	select IRQ_DOMAIN_NOMAP
 	help
 	  This option enables support for the Sony PS3 game console
 	  and other platforms using the PS3 hypervisor.  Enabling this
diff --git a/arch/powerpc/sysdev/xive/Kconfig b/arch/powerpc/sysdev/xive/Kconfig
index 785c292d104b..97796c6b63f0 100644
--- a/arch/powerpc/sysdev/xive/Kconfig
+++ b/arch/powerpc/sysdev/xive/Kconfig
@@ -3,6 +3,7 @@ config PPC_XIVE
 	bool
 	select PPC_SMP_MUXED_IPI
 	select HARDIRQS_SW_RESEND
+	select IRQ_DOMAIN_NOMAP
 
 config PPC_XIVE_NATIVE
 	bool
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 42b3f7d03a32..723495ec5a2f 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -345,6 +345,8 @@ static inline struct irq_domain *irq_domain_add_linear(struct device_node *of_no
 {
 	return __irq_domain_add(of_node_to_fwnode(of_node), size, size, 0, ops, host_data);
 }
+
+#ifdef CONFIG_IRQ_DOMAIN_NOMAP
 static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
 					 unsigned int max_irq,
 					 const struct irq_domain_ops *ops,
@@ -352,6 +354,10 @@ static inline struct irq_domain *irq_domain_add_nomap(struct device_node *of_nod
 {
 	return __irq_domain_add(of_node_to_fwnode(of_node), 0, max_irq, max_irq, ops, host_data);
 }
+
+extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
+#endif
+
 static inline struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
 					 const struct irq_domain_ops *ops,
 					 void *host_data)
@@ -408,8 +414,6 @@ static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
 	return irq_find_mapping(domain, hwirq);
 }
 
-extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
-
 extern const struct irq_domain_ops irq_domain_simple_ops;
 
 /* stock xlate functions */
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index d79ef2493a28..fbc54c2a7f23 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -70,6 +70,11 @@ config IRQ_DOMAIN_HIERARCHY
 	bool
 	select IRQ_DOMAIN
 
+# Support for obsolete non-mapping irq domains
+config IRQ_DOMAIN_NOMAP
+	bool
+	select IRQ_DOMAIN
+
 # Support for hierarchical fasteoi+edge and fasteoi+level handlers
 config IRQ_FASTEOI_HIERARCHY_HANDLERS
 	bool
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8bd012253989..e0143e640683 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -604,6 +604,7 @@ void irq_domain_associate_many(struct irq_domain *domain, unsigned int irq_base,
 }
 EXPORT_SYMBOL_GPL(irq_domain_associate_many);
 
+#ifdef CONFIG_IRQ_DOMAIN_NOMAP
 /**
  * irq_create_direct_mapping() - Allocate an irq for direct mapping
  * @domain: domain to allocate the irq for or NULL for default domain
@@ -644,6 +645,7 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
 	return virq;
 }
 EXPORT_SYMBOL_GPL(irq_create_direct_mapping);
+#endif
 
 /**
  * irq_create_mapping_affinity() - Map a hardware interrupt into linux irq space
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (14 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 15/39] powerpc: Move the use of irq_domain_add_nomap() behind a config option Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-11-15 19:05   ` Cédric Le Goater
  2021-05-20 16:37 ` [PATCH 17/39] irqdomain: Use struct_size() helper when allocating irqdomain Marc Zyngier
                   ` (24 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Direct mappings are completely exclusive of normal mappings, meaning
that we can refactor the code slightly so that we can get rid of
the revmap_direct_max_irq field and use the revmap_size field
instead, reducing the size of the irqdomain structure.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdomain.h |  6 +++---
 kernel/irq/irqdomain.c    | 45 ++++++++++++++++++++++++++++++---------
 2 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 723495ec5a2f..0916cf9c6e20 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -149,8 +149,6 @@ struct irq_domain_chip_generic;
  * @parent: Pointer to parent irq_domain to support hierarchy irq_domains
  *
  * Revmap data, used internally by irq_domain
- * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
- *                         support direct mapping
  * @revmap_size: Size of the linear map table @revmap[]
  * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
  * @revmap: Linear table of hwirq->virq reverse mappings
@@ -173,7 +171,6 @@ struct irq_domain {
 
 	/* reverse map data. The linear map gets appended to the irq_domain */
 	irq_hw_number_t hwirq_max;
-	unsigned int revmap_direct_max_irq;
 	unsigned int revmap_size;
 	struct radix_tree_root revmap_tree;
 	struct mutex revmap_tree_mutex;
@@ -207,6 +204,9 @@ enum {
 	 */
 	IRQ_DOMAIN_MSI_NOMASK_QUIRK	= (1 << 6),
 
+	/* Irq domain doesn't translate anything */
+	IRQ_DOMAIN_FLAG_NO_MAP		= (1 << 7),
+
 	/*
 	 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
 	 * for implementation specific purposes and ignored by the
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index e0143e640683..fa94c86e47d4 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -146,6 +146,10 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
 
 	static atomic_t unknown_domains;
 
+	if (WARN_ON((size && direct_max) ||
+		    (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max)))
+		return NULL;
+
 	domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
 			      GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
 	if (!domain)
@@ -213,8 +217,14 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
 	domain->ops = ops;
 	domain->host_data = host_data;
 	domain->hwirq_max = hwirq_max;
+
+	if (direct_max) {
+		size = direct_max;
+		domain->flags |= IRQ_DOMAIN_FLAG_NO_MAP;
+	}
+
 	domain->revmap_size = size;
-	domain->revmap_direct_max_irq = direct_max;
+
 	irq_domain_check_hierarchy(domain);
 
 	mutex_lock(&irq_domain_mutex);
@@ -482,9 +492,18 @@ struct irq_domain *irq_get_default_host(void)
 	return irq_default_domain;
 }
 
+static bool irq_domain_is_nomap(struct irq_domain *domain)
+{
+	return IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) &&
+	       (domain->flags & IRQ_DOMAIN_FLAG_NO_MAP);
+}
+
 static void irq_domain_clear_mapping(struct irq_domain *domain,
 				     irq_hw_number_t hwirq)
 {
+	if (irq_domain_is_nomap(domain))
+		return;
+
 	if (hwirq < domain->revmap_size) {
 		domain->revmap[hwirq] = 0;
 	} else {
@@ -498,6 +517,9 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
 				   irq_hw_number_t hwirq,
 				   struct irq_data *irq_data)
 {
+	if (irq_domain_is_nomap(domain))
+		return;
+
 	if (hwirq < domain->revmap_size) {
 		domain->revmap[hwirq] = irq_data->irq;
 	} else {
@@ -629,9 +651,9 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
 		pr_debug("create_direct virq allocation failed\n");
 		return 0;
 	}
-	if (virq >= domain->revmap_direct_max_irq) {
+	if (virq >= domain->revmap_size) {
 		pr_err("ERROR: no free irqs available below %i maximum\n",
-			domain->revmap_direct_max_irq);
+			domain->revmap_size);
 		irq_free_desc(virq);
 		return 0;
 	}
@@ -879,10 +901,14 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 	if (domain == NULL)
 		return 0;
 
-	if (hwirq < domain->revmap_direct_max_irq) {
-		data = irq_domain_get_irq_data(domain, hwirq);
-		if (data && data->hwirq == hwirq)
-			return hwirq;
+	if (irq_domain_is_nomap(domain)) {
+		if (hwirq < domain->revmap_size) {
+			data = irq_domain_get_irq_data(domain, hwirq);
+			if (data && data->hwirq == hwirq)
+				return hwirq;
+		}
+
+		return 0;
 	}
 
 	/* Check if the hwirq is in the linear revmap. */
@@ -1470,7 +1496,7 @@ static void irq_domain_fix_revmap(struct irq_data *d)
 {
 	void __rcu **slot;
 
-	if (d->hwirq < d->domain->revmap_size)
+	if (irq_domain_is_nomap(d->domain) || d->hwirq < d->domain->revmap_size)
 		return; /* Not using radix tree. */
 
 	/* Fix up the revmap. */
@@ -1830,8 +1856,7 @@ static void
 irq_domain_debug_show_one(struct seq_file *m, struct irq_domain *d, int ind)
 {
 	seq_printf(m, "%*sname:   %s\n", ind, "", d->name);
-	seq_printf(m, "%*ssize:   %u\n", ind + 1, "",
-		   d->revmap_size + d->revmap_direct_max_irq);
+	seq_printf(m, "%*ssize:   %u\n", ind + 1, "", d->revmap_size);
 	seq_printf(m, "%*smapped: %u\n", ind + 1, "", d->mapcount);
 	seq_printf(m, "%*sflags:  0x%08x\n", ind +1 , "", d->flags);
 	if (d->ops && d->ops->debug_show)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 17/39] irqdomain: Use struct_size() helper when allocating irqdomain
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (15 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 18/39] irqdomain: Cache irq_data instead of a virq number in the revmap Marc Zyngier
                   ` (23 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Instead of open-coding the size computation of struct irqdomain,
use the struct_size() helper instead.

This is going to be handy as we change the type of the revmap
array.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 kernel/irq/irqdomain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index fa94c86e47d4..cdcb1989cd20 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -150,7 +150,7 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
 		    (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max)))
 		return NULL;
 
-	domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
+	domain = kzalloc_node(struct_size(domain, revmap, size),
 			      GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
 	if (!domain)
 		return NULL;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 18/39] irqdomain: Cache irq_data instead of a virq number in the revmap
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (16 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 17/39] irqdomain: Use struct_size() helper when allocating irqdomain Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 19/39] irqdomain: Implement irq_domain_clear_mapping() with irq_domain_set_mapping() Marc Zyngier
                   ` (22 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Caching a virq number in the revmap is pretty inefficient, as
it means we will need to convert it back to either an irq_data
or irq_desc to do anything with it.

It is also a bit odd, as the radix tree does cache irq_data
pointers.

Change the revmap type to be an irq_data pointer instead of
an unsigned int, and preserve the current API for now.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdomain.h |  4 ++--
 kernel/irq/irqdomain.c    | 16 +++++++++++-----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 0916cf9c6e20..340cc04611dd 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -151,7 +151,7 @@ struct irq_domain_chip_generic;
  * Revmap data, used internally by irq_domain
  * @revmap_size: Size of the linear map table @revmap[]
  * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
- * @revmap: Linear table of hwirq->virq reverse mappings
+ * @revmap: Linear table of irq_data pointers
  */
 struct irq_domain {
 	struct list_head link;
@@ -174,7 +174,7 @@ struct irq_domain {
 	unsigned int revmap_size;
 	struct radix_tree_root revmap_tree;
 	struct mutex revmap_tree_mutex;
-	unsigned int revmap[];
+	struct irq_data *revmap[];
 };
 
 /* Irq domain flags */
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index cdcb1989cd20..7a4e38804487 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -505,7 +505,7 @@ static void irq_domain_clear_mapping(struct irq_domain *domain,
 		return;
 
 	if (hwirq < domain->revmap_size) {
-		domain->revmap[hwirq] = 0;
+		domain->revmap[hwirq] = NULL;
 	} else {
 		mutex_lock(&domain->revmap_tree_mutex);
 		radix_tree_delete(&domain->revmap_tree, hwirq);
@@ -521,7 +521,7 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
 		return;
 
 	if (hwirq < domain->revmap_size) {
-		domain->revmap[hwirq] = irq_data->irq;
+		domain->revmap[hwirq] = irq_data;
 	} else {
 		mutex_lock(&domain->revmap_tree_mutex);
 		radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);
@@ -913,7 +913,7 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 
 	/* Check if the hwirq is in the linear revmap. */
 	if (hwirq < domain->revmap_size)
-		return domain->revmap[hwirq];
+		return domain->revmap[hwirq]->irq;
 
 	rcu_read_lock();
 	data = radix_tree_lookup(&domain->revmap_tree, hwirq);
@@ -1496,8 +1496,14 @@ static void irq_domain_fix_revmap(struct irq_data *d)
 {
 	void __rcu **slot;
 
-	if (irq_domain_is_nomap(d->domain) || d->hwirq < d->domain->revmap_size)
-		return; /* Not using radix tree. */
+	if (irq_domain_is_nomap(d->domain))
+		return;
+
+	if (d->hwirq < d->domain->revmap_size) {
+		/* Not using radix tree */
+		d->domain->revmap[d->hwirq] = d;
+		return;
+	}
 
 	/* Fix up the revmap. */
 	mutex_lock(&d->domain->revmap_tree_mutex);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 19/39] irqdomain: Implement irq_domain_clear_mapping() with irq_domain_set_mapping()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (17 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 18/39] irqdomain: Cache irq_data instead of a virq number in the revmap Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 20/39] irqdomain: Protect the linear revmap with RCU Marc Zyngier
                   ` (21 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Now that we only deal with irq_data pointers, it is pretty obvious
that irq_domain_clear_mapping() and irq_domain_set_mapping() are
almost the exact same thing.

Implement one it terms of the other.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 kernel/irq/irqdomain.c | 21 ++++++---------------
 1 file changed, 6 insertions(+), 15 deletions(-)

diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 7a4e38804487..ed2ffffc6fc6 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -498,21 +498,6 @@ static bool irq_domain_is_nomap(struct irq_domain *domain)
 	       (domain->flags & IRQ_DOMAIN_FLAG_NO_MAP);
 }
 
-static void irq_domain_clear_mapping(struct irq_domain *domain,
-				     irq_hw_number_t hwirq)
-{
-	if (irq_domain_is_nomap(domain))
-		return;
-
-	if (hwirq < domain->revmap_size) {
-		domain->revmap[hwirq] = NULL;
-	} else {
-		mutex_lock(&domain->revmap_tree_mutex);
-		radix_tree_delete(&domain->revmap_tree, hwirq);
-		mutex_unlock(&domain->revmap_tree_mutex);
-	}
-}
-
 static void irq_domain_set_mapping(struct irq_domain *domain,
 				   irq_hw_number_t hwirq,
 				   struct irq_data *irq_data)
@@ -529,6 +514,12 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
 	}
 }
 
+static void irq_domain_clear_mapping(struct irq_domain *domain,
+				     irq_hw_number_t hwirq)
+{
+	irq_domain_set_mapping(domain, hwirq, NULL);
+}
+
 static void irq_domain_disassociate(struct irq_domain *domain, unsigned int irq)
 {
 	struct irq_data *irq_data = irq_get_irq_data(irq);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 20/39] irqdomain: Protect the linear revmap with RCU
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (18 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 19/39] irqdomain: Implement irq_domain_clear_mapping() with irq_domain_set_mapping() Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-06-19 11:37   ` Thomas Gleixner
  2021-05-20 16:37 ` [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping() Marc Zyngier
                   ` (20 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

It is pretty odd that the radix tree uses RCU while the linear
portion doesn't, leading to potential surprises for the users,
depending on how the irqdomain has been created.

Fix this by moving the update of the linear revmap under
the mutex, and the lookup under the RCU read-side lock.

The mutex name is updated to reflect that it doesn't only
cover the radix-tree anymore.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdomain.h |  5 +++--
 kernel/irq/irqdomain.c    | 38 ++++++++++++++++++--------------------
 2 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 340cc04611dd..2b696c9bcaaf 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -151,6 +151,7 @@ struct irq_domain_chip_generic;
  * Revmap data, used internally by irq_domain
  * @revmap_size: Size of the linear map table @revmap[]
  * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
+ * @revmap_mutex: Lock for the revmap
  * @revmap: Linear table of irq_data pointers
  */
 struct irq_domain {
@@ -173,8 +174,8 @@ struct irq_domain {
 	irq_hw_number_t hwirq_max;
 	unsigned int revmap_size;
 	struct radix_tree_root revmap_tree;
-	struct mutex revmap_tree_mutex;
-	struct irq_data *revmap[];
+	struct mutex revmap_mutex;
+	struct irq_data __rcu *revmap[];
 };
 
 /* Irq domain flags */
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index ed2ffffc6fc6..8e55bb8c3073 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -213,7 +213,7 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
 
 	/* Fill structure */
 	INIT_RADIX_TREE(&domain->revmap_tree, GFP_KERNEL);
-	mutex_init(&domain->revmap_tree_mutex);
+	mutex_init(&domain->revmap_mutex);
 	domain->ops = ops;
 	domain->host_data = host_data;
 	domain->hwirq_max = hwirq_max;
@@ -505,13 +505,12 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
 	if (irq_domain_is_nomap(domain))
 		return;
 
-	if (hwirq < domain->revmap_size) {
-		domain->revmap[hwirq] = irq_data;
-	} else {
-		mutex_lock(&domain->revmap_tree_mutex);
+	mutex_lock(&domain->revmap_mutex);
+	if (hwirq < domain->revmap_size)
+		rcu_assign_pointer(domain->revmap[hwirq], irq_data);
+	else
 		radix_tree_insert(&domain->revmap_tree, hwirq, irq_data);
-		mutex_unlock(&domain->revmap_tree_mutex);
-	}
+	mutex_unlock(&domain->revmap_mutex);
 }
 
 static void irq_domain_clear_mapping(struct irq_domain *domain,
@@ -902,12 +901,12 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 		return 0;
 	}
 
+	rcu_read_lock();
 	/* Check if the hwirq is in the linear revmap. */
 	if (hwirq < domain->revmap_size)
-		return domain->revmap[hwirq]->irq;
-
-	rcu_read_lock();
-	data = radix_tree_lookup(&domain->revmap_tree, hwirq);
+		data = rcu_dereference(domain->revmap[hwirq]);
+	else
+		data = radix_tree_lookup(&domain->revmap_tree, hwirq);
 	rcu_read_unlock();
 	return data ? data->irq : 0;
 }
@@ -1490,18 +1489,17 @@ static void irq_domain_fix_revmap(struct irq_data *d)
 	if (irq_domain_is_nomap(d->domain))
 		return;
 
+	/* Fix up the revmap. */
+	mutex_lock(&d->domain->revmap_mutex);
 	if (d->hwirq < d->domain->revmap_size) {
 		/* Not using radix tree */
-		d->domain->revmap[d->hwirq] = d;
-		return;
+		rcu_assign_pointer(d->domain->revmap[d->hwirq], d);
+	} else {
+		slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq);
+		if (slot)
+			radix_tree_replace_slot(&d->domain->revmap_tree, slot, d);
 	}
-
-	/* Fix up the revmap. */
-	mutex_lock(&d->domain->revmap_tree_mutex);
-	slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq);
-	if (slot)
-		radix_tree_replace_slot(&d->domain->revmap_tree, slot, d);
-	mutex_unlock(&d->domain->revmap_tree_mutex);
+	mutex_unlock(&d->domain->revmap_mutex);
 }
 
 /**
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (19 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 20/39] irqdomain: Protect the linear revmap with RCU Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-06-10  2:22   ` Qian Cai
  2021-05-20 16:37 ` [PATCH 22/39] genirq: Use irq_resolve_mapping() to implement __handle_domain_irq() and co Marc Zyngier
                   ` (19 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Rework irq_find_mapping() to return an irq_desc pointer, and
rename the result to irq_resolve_mapping().

irq_find_mapping() is then rewritten in terms of ir_resolve_mapping().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdomain.h | 18 +++++++++++++++---
 kernel/irq/irqdomain.c    | 22 ++++++++++++++--------
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 2b696c9bcaaf..189f559fb26c 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -31,7 +31,8 @@
 #define _LINUX_IRQDOMAIN_H
 
 #include <linux/types.h>
-#include <linux/irqhandler.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
 #include <linux/of.h>
 #include <linux/mutex.h>
 #include <linux/radix-tree.h>
@@ -401,13 +402,24 @@ static inline unsigned int irq_create_mapping(struct irq_domain *host,
 	return irq_create_mapping_affinity(host, hwirq, NULL);
 }
 
+extern struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
+					    irq_hw_number_t hwirq);
+
 /**
  * irq_find_mapping() - Find a linux irq from a hw irq number.
  * @domain: domain owning this hardware interrupt
  * @hwirq: hardware irq number in that domain space
  */
-extern unsigned int irq_find_mapping(struct irq_domain *host,
-				     irq_hw_number_t hwirq);
+static inline unsigned int irq_find_mapping(struct irq_domain *domain,
+					    irq_hw_number_t hwirq)
+{
+	struct irq_desc *desc = irq_resolve_mapping(domain, hwirq);
+
+	if (unlikely(!desc))
+		return 0;
+
+	return irq_desc_get_irq(desc);
+}
 
 static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
 					     irq_hw_number_t hwirq)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 8e55bb8c3073..13a3021e9370 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -876,29 +876,32 @@ void irq_dispose_mapping(unsigned int virq)
 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
 /**
- * irq_find_mapping() - Find a linux irq from a hw irq number.
+ * irq_resolve_mapping() - Find a linux irq from a hw irq number.
  * @domain: domain owning this hardware interrupt
  * @hwirq: hardware irq number in that domain space
+ *
+ * Returns the interrupt descriptor.
  */
-unsigned int irq_find_mapping(struct irq_domain *domain,
-			      irq_hw_number_t hwirq)
+struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
+				     irq_hw_number_t hwirq)
 {
+	struct irq_desc *desc = NULL;
 	struct irq_data *data;
 
 	/* Look for default domain if necessary */
 	if (domain == NULL)
 		domain = irq_default_domain;
 	if (domain == NULL)
-		return 0;
+		return desc;
 
 	if (irq_domain_is_nomap(domain)) {
 		if (hwirq < domain->revmap_size) {
 			data = irq_domain_get_irq_data(domain, hwirq);
 			if (data && data->hwirq == hwirq)
-				return hwirq;
+				desc = irq_data_to_desc(data);
 		}
 
-		return 0;
+		return desc;
 	}
 
 	rcu_read_lock();
@@ -907,10 +910,13 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
 		data = rcu_dereference(domain->revmap[hwirq]);
 	else
 		data = radix_tree_lookup(&domain->revmap_tree, hwirq);
+
+	if (likely(data))
+		desc = irq_data_to_desc(data);
 	rcu_read_unlock();
-	return data ? data->irq : 0;
+	return desc;
 }
-EXPORT_SYMBOL_GPL(irq_find_mapping);
+EXPORT_SYMBOL_GPL(irq_resolve_mapping);
 
 /**
  * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 22/39] genirq: Use irq_resolve_mapping() to implement __handle_domain_irq() and co
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (20 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping() Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 23/39] irqdesc: Fix __handle_domain_irq() comment Marc Zyngier
                   ` (18 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

In order to start reaping the benefits of irq_resolve_mapping(),
start using it in __handle_domain_irq() and handle_domain_nmi().

This involves splitting generic_handle_irq() to be able to directly
provide the irq_desc.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdesc.h |  1 +
 kernel/irq/irqdesc.c    | 60 ++++++++++++++++++++++++-----------------
 2 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index df4651250785..cdd1cf8207f6 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -158,6 +158,7 @@ static inline void generic_handle_irq_desc(struct irq_desc *desc)
 	desc->handle_irq(desc);
 }
 
+int handle_irq_desc(struct irq_desc *desc);
 int generic_handle_irq(unsigned int irq);
 
 #ifdef CONFIG_HANDLE_DOMAIN_IRQ
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 4a617d7312a4..684c5b7b7832 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -632,14 +632,8 @@ void irq_init_desc(unsigned int irq)
 
 #endif /* !CONFIG_SPARSE_IRQ */
 
-/**
- * generic_handle_irq - Invoke the handler for a particular irq
- * @irq:	The irq number to handle
- *
- */
-int generic_handle_irq(unsigned int irq)
+int handle_irq_desc(struct irq_desc *desc)
 {
-	struct irq_desc *desc = irq_to_desc(irq);
 	struct irq_data *data;
 
 	if (!desc)
@@ -652,6 +646,17 @@ int generic_handle_irq(unsigned int irq)
 	generic_handle_irq_desc(desc);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(handle_irq_desc);
+
+/**
+ * generic_handle_irq - Invoke the handler for a particular irq
+ * @irq:	The irq number to handle
+ *
+ */
+int generic_handle_irq(unsigned int irq)
+{
+	return handle_irq_desc(irq_to_desc(irq));
+}
 EXPORT_SYMBOL_GPL(generic_handle_irq);
 
 #ifdef CONFIG_HANDLE_DOMAIN_IRQ
@@ -668,27 +673,32 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
 			bool lookup, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-	unsigned int irq = hwirq;
+	struct irq_desc *desc;
 	int ret = 0;
 
 	irq_enter();
 
-#ifdef CONFIG_IRQ_DOMAIN
-	if (lookup)
-		irq = irq_find_mapping(domain, hwirq);
-#endif
-
-	/*
-	 * Some hardware gives randomly wrong interrupts.  Rather
-	 * than crashing, do something sensible.
-	 */
-	if (unlikely(!irq || irq >= nr_irqs)) {
-		ack_bad_irq(irq);
-		ret = -EINVAL;
+	if (likely(IS_ENABLED(CONFIG_IRQ_DOMAIN) && lookup)) {
+		/* The irqdomain code provides boundary checks */
+		desc = irq_resolve_mapping(domain, hwirq);
 	} else {
-		generic_handle_irq(irq);
+		/*
+		 * Some hardware gives randomly wrong interrupts.  Rather
+		 * than crashing, do something sensible.
+		 */
+		if (unlikely(!hwirq || hwirq >= nr_irqs)) {
+			ack_bad_irq(hwirq);
+			desc = NULL;
+		} else {
+			desc = irq_to_desc(hwirq);
+		}
 	}
 
+	if (likely(desc))
+		handle_irq_desc(desc);
+	else
+		ret = -EINVAL;
+
 	irq_exit();
 	set_irq_regs(old_regs);
 	return ret;
@@ -709,7 +719,7 @@ int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
 		      struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-	unsigned int irq;
+	struct irq_desc *desc;
 	int ret = 0;
 
 	/*
@@ -717,14 +727,14 @@ int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
 	 */
 	WARN_ON(!in_nmi());
 
-	irq = irq_find_mapping(domain, hwirq);
+	desc = irq_resolve_mapping(domain, hwirq);
 
 	/*
 	 * ack_bad_irq is not NMI-safe, just report
 	 * an invalid interrupt.
 	 */
-	if (likely(irq))
-		generic_handle_irq(irq);
+	if (likely(desc))
+		handle_irq_desc(desc);
 	else
 		ret = -EINVAL;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 23/39] irqdesc: Fix __handle_domain_irq() comment
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (21 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 22/39] genirq: Use irq_resolve_mapping() to implement __handle_domain_irq() and co Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 24/39] irqchip/nvic: Convert from handle_IRQ() to handle_domain_irq() Marc Zyngier
                   ` (17 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

It appears that the comment about a NULL domain meaning anything
has always been wrong. Fix it.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdesc.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index cdd1cf8207f6..2971eb7e65f1 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -165,8 +165,7 @@ int generic_handle_irq(unsigned int irq);
 /*
  * Convert a HW interrupt number to a logical one using a IRQ domain,
  * and handle the result interrupt number. Return -EINVAL if
- * conversion failed. Providing a NULL domain indicates that the
- * conversion has already been done.
+ * conversion failed.
  */
 int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
 			bool lookup, struct pt_regs *regs);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 24/39] irqchip/nvic: Convert from handle_IRQ() to handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (22 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 23/39] irqdesc: Fix __handle_domain_irq() comment Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 25/39] genirq: Add generic_handle_domain_irq() helper Marc Zyngier
                   ` (16 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Given that the nvic driver is fully irqdomain aware, there is no
reason for it to use the arch-specific handle_IRQ(), and it can
be moved over to handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/irq-nvic.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index f747e2209ea9..b31c4cff4d3a 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -40,9 +40,7 @@ static struct irq_domain *nvic_irq_domain;
 asmlinkage void __exception_irq_entry
 nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
 {
-	unsigned int irq = irq_linear_revmap(nvic_irq_domain, hwirq);
-
-	handle_IRQ(irq, regs);
+	handle_domain_irq(nvic_irq_domain, hwirq, regs);
 }
 
 static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 25/39] genirq: Add generic_handle_domain_irq() helper
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (23 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 24/39] irqchip/nvic: Convert from handle_IRQ() to handle_domain_irq() Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 26/39] genirq: Move non-irqdomain handle_domain_irq() handling into ARM's handle_IRQ() Marc Zyngier
                   ` (15 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Provide generic_handle_domain_irq() as a pendent to handle_domain_irq()
for non-root interrupt controllers

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 include/linux/irqdesc.h |  2 ++
 kernel/irq/irqdesc.c    | 19 ++++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 2971eb7e65f1..0f226c6b0c70 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -170,6 +170,8 @@ int generic_handle_irq(unsigned int irq);
 int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
 			bool lookup, struct pt_regs *regs);
 
+int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq);
+
 static inline int handle_domain_irq(struct irq_domain *domain,
 				    unsigned int hwirq, struct pt_regs *regs)
 {
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 684c5b7b7832..6179d5bde88e 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -661,7 +661,24 @@ EXPORT_SYMBOL_GPL(generic_handle_irq);
 
 #ifdef CONFIG_HANDLE_DOMAIN_IRQ
 /**
- * __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain
+ * generic_handle_domain_irq - Invoke the handler for a HW irq belonging
+ *                             to a domain, usually for a non-root interrupt
+ *                             controller
+ * @domain:	The domain where to perform the lookup
+ * @hwirq:	The HW irq number to convert to a logical one
+ *
+ * Returns:	0 on success, or -EINVAL if conversion has failed
+ *
+ */
+int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq)
+{
+	return handle_irq_desc(irq_resolve_mapping(domain, hwirq));
+}
+EXPORT_SYMBOL_GPL(generic_handle_domain_irq);
+
+/**
+ * __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain,
+ *                       usually for a root interrupt controller
  * @domain:	The domain where to perform the lookup
  * @hwirq:	The HW irq number to convert to a logical one
  * @lookup:	Whether to perform the domain lookup or not
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 26/39] genirq: Move non-irqdomain handle_domain_irq() handling into ARM's handle_IRQ()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (24 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 25/39] genirq: Add generic_handle_domain_irq() helper Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq() Marc Zyngier
                   ` (14 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Despite the name, handle_domain_irq() deals with non-irqdomain
handling for the sake of a handful of legacy ARM platforms.

Move such handling into ARM's handle_IRQ(), allowing for better
code generation for everyone else. This allows us get rid of
some complexity, and to rearrange the guards on the various helpers
in a more logical way.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm/kernel/irq.c   | 22 +++++++++++++++++++++-
 include/linux/irqdesc.h | 14 ++++----------
 kernel/irq/irqdesc.c    | 30 ++++++++----------------------
 3 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 698b6f636156..20ab1e607522 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -63,7 +63,27 @@ int arch_show_interrupts(struct seq_file *p, int prec)
  */
 void handle_IRQ(unsigned int irq, struct pt_regs *regs)
 {
-	__handle_domain_irq(NULL, irq, false, regs);
+	struct pt_regs *old_regs = set_irq_regs(regs);
+	struct irq_desc *desc;
+
+	irq_enter();
+
+	/*
+	 * Some hardware gives randomly wrong interrupts.  Rather
+	 * than crashing, do something sensible.
+	 */
+	if (unlikely(!irq || irq >= nr_irqs))
+		desc = NULL;
+	else
+		desc = irq_to_desc(irq);
+
+	if (likely(desc))
+		handle_irq_desc(desc);
+	else
+		ack_bad_irq(irq);
+
+	irq_exit();
+	set_irq_regs(old_regs);
 }
 
 /*
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 0f226c6b0c70..59aea39785bf 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -161,24 +161,18 @@ static inline void generic_handle_irq_desc(struct irq_desc *desc)
 int handle_irq_desc(struct irq_desc *desc);
 int generic_handle_irq(unsigned int irq);
 
-#ifdef CONFIG_HANDLE_DOMAIN_IRQ
+#ifdef CONFIG_IRQ_DOMAIN
 /*
  * Convert a HW interrupt number to a logical one using a IRQ domain,
  * and handle the result interrupt number. Return -EINVAL if
  * conversion failed.
  */
-int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
-			bool lookup, struct pt_regs *regs);
-
 int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq);
 
-static inline int handle_domain_irq(struct irq_domain *domain,
-				    unsigned int hwirq, struct pt_regs *regs)
-{
-	return __handle_domain_irq(domain, hwirq, true, regs);
-}
+#ifdef CONFIG_HANDLE_DOMAIN_IRQ
+int handle_domain_irq(struct irq_domain *domain,
+		      unsigned int hwirq, struct pt_regs *regs);
 
-#ifdef CONFIG_IRQ_DOMAIN
 int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
 		      struct pt_regs *regs);
 #endif
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 6179d5bde88e..f4dd5186858a 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -659,7 +659,7 @@ int generic_handle_irq(unsigned int irq)
 }
 EXPORT_SYMBOL_GPL(generic_handle_irq);
 
-#ifdef CONFIG_HANDLE_DOMAIN_IRQ
+#ifdef CONFIG_IRQ_DOMAIN
 /**
  * generic_handle_domain_irq - Invoke the handler for a HW irq belonging
  *                             to a domain, usually for a non-root interrupt
@@ -676,9 +676,10 @@ int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq)
 }
 EXPORT_SYMBOL_GPL(generic_handle_domain_irq);
 
+#ifdef CONFIG_HANDLE_DOMAIN_IRQ
 /**
- * __handle_domain_irq - Invoke the handler for a HW irq belonging to a domain,
- *                       usually for a root interrupt controller
+ * handle_domain_irq - Invoke the handler for a HW irq belonging to a domain,
+ *                     usually for a root interrupt controller
  * @domain:	The domain where to perform the lookup
  * @hwirq:	The HW irq number to convert to a logical one
  * @lookup:	Whether to perform the domain lookup or not
@@ -686,8 +687,8 @@ EXPORT_SYMBOL_GPL(generic_handle_domain_irq);
  *
  * Returns:	0 on success, or -EINVAL if conversion has failed
  */
-int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
-			bool lookup, struct pt_regs *regs)
+int handle_domain_irq(struct irq_domain *domain,
+		      unsigned int hwirq, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
 	struct irq_desc *desc;
@@ -695,22 +696,8 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
 
 	irq_enter();
 
-	if (likely(IS_ENABLED(CONFIG_IRQ_DOMAIN) && lookup)) {
-		/* The irqdomain code provides boundary checks */
-		desc = irq_resolve_mapping(domain, hwirq);
-	} else {
-		/*
-		 * Some hardware gives randomly wrong interrupts.  Rather
-		 * than crashing, do something sensible.
-		 */
-		if (unlikely(!hwirq || hwirq >= nr_irqs)) {
-			ack_bad_irq(hwirq);
-			desc = NULL;
-		} else {
-			desc = irq_to_desc(hwirq);
-		}
-	}
-
+	/* The irqdomain code provides boundary checks */
+	desc = irq_resolve_mapping(domain, hwirq);
 	if (likely(desc))
 		handle_irq_desc(desc);
 	else
@@ -721,7 +708,6 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
 	return ret;
 }
 
-#ifdef CONFIG_IRQ_DOMAIN
 /**
  * handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain
  * @domain:	The domain where to perform the lookup
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (25 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 26/39] genirq: Move non-irqdomain handle_domain_irq() handling into ARM's handle_IRQ() Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-21  8:54   ` Geert Uytterhoeven
  2021-05-21 21:10   ` Krzysztof Kozlowski
  2021-05-20 16:37 ` [PATCH 28/39] gpio: " Marc Zyngier
                   ` (13 subsequent siblings)
  40 siblings, 2 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/irqchip/exynos-combiner.c      | 10 ++++------
 drivers/irqchip/irq-al-fic.c           |  7 ++-----
 drivers/irqchip/irq-armada-370-xp.c    | 19 ++++++++-----------
 drivers/irqchip/irq-aspeed-i2c-ic.c    |  8 +++-----
 drivers/irqchip/irq-aspeed-scu-ic.c    |  6 ++----
 drivers/irqchip/irq-ath79-misc.c       |  2 +-
 drivers/irqchip/irq-bcm2835.c          |  2 +-
 drivers/irqchip/irq-bcm2836.c          |  2 +-
 drivers/irqchip/irq-bcm7038-l1.c       |  6 ++----
 drivers/irqchip/irq-bcm7120-l2.c       |  6 ++----
 drivers/irqchip/irq-brcmstb-l2.c       |  2 +-
 drivers/irqchip/irq-dw-apb-ictl.c      |  3 +--
 drivers/irqchip/irq-gic.c              | 13 +++++--------
 drivers/irqchip/irq-goldfish-pic.c     |  5 ++---
 drivers/irqchip/irq-i8259.c            |  4 +---
 drivers/irqchip/irq-idt3243x.c         |  6 ++----
 drivers/irqchip/irq-imgpdc.c           | 11 ++++-------
 drivers/irqchip/irq-imx-intmux.c       |  9 +++------
 drivers/irqchip/irq-imx-irqsteer.c     |  9 +++------
 drivers/irqchip/irq-ingenic-tcu.c      |  2 +-
 drivers/irqchip/irq-ingenic.c          |  3 +--
 drivers/irqchip/irq-keystone.c         | 14 ++++++--------
 drivers/irqchip/irq-loongson-htpic.c   |  2 +-
 drivers/irqchip/irq-loongson-htvec.c   |  4 ++--
 drivers/irqchip/irq-loongson-liointc.c |  2 +-
 drivers/irqchip/irq-lpc32xx.c          |  2 +-
 drivers/irqchip/irq-ls-scfg-msi.c      |  6 ++----
 drivers/irqchip/irq-ls1x.c             |  2 +-
 drivers/irqchip/irq-mips-gic.c         | 20 ++++++++++----------
 drivers/irqchip/irq-mscc-ocelot.c      |  2 +-
 drivers/irqchip/irq-mvebu-pic.c        |  7 ++-----
 drivers/irqchip/irq-mvebu-sei.c        | 13 ++++---------
 drivers/irqchip/irq-orion.c            |  2 +-
 drivers/irqchip/irq-partition-percpu.c |  9 +++------
 drivers/irqchip/irq-pruss-intc.c       |  9 +++------
 drivers/irqchip/irq-realtek-rtl.c      |  2 +-
 drivers/irqchip/irq-renesas-irqc.c     |  2 +-
 drivers/irqchip/irq-sifive-plic.c      |  8 +++-----
 drivers/irqchip/irq-stm32-exti.c       | 10 ++++------
 drivers/irqchip/irq-sunxi-nmi.c        |  3 +--
 drivers/irqchip/irq-tb10x.c            |  2 +-
 drivers/irqchip/irq-ti-sci-inta.c      |  9 +++------
 drivers/irqchip/irq-ts4800.c           |  3 +--
 drivers/irqchip/irq-versatile-fpga.c   |  2 +-
 drivers/irqchip/irq-vic.c              |  2 +-
 drivers/irqchip/irq-xilinx-intc.c      | 22 +++++-----------------
 drivers/irqchip/qcom-irq-combiner.c    |  6 +-----
 47 files changed, 111 insertions(+), 189 deletions(-)

diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index 0b85d9a3fbff..14106126cbf3 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -66,8 +66,9 @@ static void combiner_handle_cascade_irq(struct irq_desc *desc)
 {
 	struct combiner_chip_data *chip_data = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	unsigned int cascade_irq, combiner_irq;
+	unsigned int combiner_irq;
 	unsigned long status;
+	int ret;
 
 	chained_irq_enter(chip, desc);
 
@@ -80,12 +81,9 @@ static void combiner_handle_cascade_irq(struct irq_desc *desc)
 		goto out;
 
 	combiner_irq = chip_data->hwirq_offset + __ffs(status);
-	cascade_irq = irq_find_mapping(combiner_irq_domain, combiner_irq);
-
-	if (unlikely(!cascade_irq))
+	ret = generic_handle_domain_irq(combiner_irq_domain, combiner_irq);
+	if (unlikely(ret))
 		handle_bad_irq(desc);
-	else
-		generic_handle_irq(cascade_irq);
 
  out:
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-al-fic.c b/drivers/irqchip/irq-al-fic.c
index 0b0a73739756..886de028a901 100644
--- a/drivers/irqchip/irq-al-fic.c
+++ b/drivers/irqchip/irq-al-fic.c
@@ -111,7 +111,6 @@ static void al_fic_irq_handler(struct irq_desc *desc)
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
 	unsigned long pending;
-	unsigned int irq;
 	u32 hwirq;
 
 	chained_irq_enter(irqchip, desc);
@@ -119,10 +118,8 @@ static void al_fic_irq_handler(struct irq_desc *desc)
 	pending = readl_relaxed(fic->base + AL_FIC_CAUSE);
 	pending &= ~gc->mask_cache;
 
-	for_each_set_bit(hwirq, &pending, NR_FIC_IRQS) {
-		irq = irq_find_mapping(domain, hwirq);
-		generic_handle_irq(irq);
-	}
+	for_each_set_bit(hwirq, &pending, NR_FIC_IRQS)
+		generic_handle_domain_irq(domain, hwirq);
 
 	chained_irq_exit(irqchip, desc);
 }
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 32938dfc0e46..7557ab551295 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -582,20 +582,19 @@ static void armada_370_xp_handle_msi_irq(struct pt_regs *regs, bool is_chained)
 
 	for (msinr = PCI_MSI_DOORBELL_START;
 	     msinr < PCI_MSI_DOORBELL_END; msinr++) {
-		int irq;
+		unsigned int irq;
 
 		if (!(msimask & BIT(msinr)))
 			continue;
 
-		if (is_chained) {
-			irq = irq_find_mapping(armada_370_xp_msi_inner_domain,
-					       msinr - PCI_MSI_DOORBELL_START);
-			generic_handle_irq(irq);
-		} else {
-			irq = msinr - PCI_MSI_DOORBELL_START;
+		irq = msinr - PCI_MSI_DOORBELL_START;
+
+		if (is_chained)
+			generic_handle_domain_irq(armada_370_xp_msi_inner_domain,
+						  irq);
+		else
 			handle_domain_irq(armada_370_xp_msi_inner_domain,
 					  irq, regs);
-		}
 	}
 }
 #else
@@ -606,7 +605,6 @@ static void armada_370_xp_mpic_handle_cascade_irq(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	unsigned long irqmap, irqn, irqsrc, cpuid;
-	unsigned int cascade_irq;
 
 	chained_irq_enter(chip, desc);
 
@@ -628,8 +626,7 @@ static void armada_370_xp_mpic_handle_cascade_irq(struct irq_desc *desc)
 			continue;
 		}
 
-		cascade_irq = irq_find_mapping(armada_370_xp_mpic_domain, irqn);
-		generic_handle_irq(cascade_irq);
+		generic_handle_domain_irq(armada_370_xp_mpic_domain, irqn);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-aspeed-i2c-ic.c b/drivers/irqchip/irq-aspeed-i2c-ic.c
index 8d591c179f81..a47db16ff960 100644
--- a/drivers/irqchip/irq-aspeed-i2c-ic.c
+++ b/drivers/irqchip/irq-aspeed-i2c-ic.c
@@ -34,14 +34,12 @@ static void aspeed_i2c_ic_irq_handler(struct irq_desc *desc)
 	struct aspeed_i2c_ic *i2c_ic = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	unsigned long bit, status;
-	unsigned int bus_irq;
 
 	chained_irq_enter(chip, desc);
 	status = readl(i2c_ic->base);
-	for_each_set_bit(bit, &status, ASPEED_I2C_IC_NUM_BUS) {
-		bus_irq = irq_find_mapping(i2c_ic->irq_domain, bit);
-		generic_handle_irq(bus_irq);
-	}
+	for_each_set_bit(bit, &status, ASPEED_I2C_IC_NUM_BUS)
+		generic_handle_domain_irq(i2c_ic->irq_domain, bit);
+
 	chained_irq_exit(chip, desc);
 }
 
diff --git a/drivers/irqchip/irq-aspeed-scu-ic.c b/drivers/irqchip/irq-aspeed-scu-ic.c
index c90a3346b985..f3c6855a4cef 100644
--- a/drivers/irqchip/irq-aspeed-scu-ic.c
+++ b/drivers/irqchip/irq-aspeed-scu-ic.c
@@ -44,7 +44,6 @@ struct aspeed_scu_ic {
 
 static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
 {
-	unsigned int irq;
 	unsigned int sts;
 	unsigned long bit;
 	unsigned long enabled;
@@ -74,9 +73,8 @@ static void aspeed_scu_ic_irq_handler(struct irq_desc *desc)
 	max = scu_ic->num_irqs + bit;
 
 	for_each_set_bit_from(bit, &status, max) {
-		irq = irq_find_mapping(scu_ic->irq_domain,
-				       bit - scu_ic->irq_shift);
-		generic_handle_irq(irq);
+		generic_handle_domain_irq(scu_ic->irq_domain,
+					  bit - scu_ic->irq_shift);
 
 		regmap_update_bits(scu_ic->scu, scu_ic->reg, mask,
 				   BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT));
diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
index 3d641bb6f3f1..92f001a5ff8d 100644
--- a/drivers/irqchip/irq-ath79-misc.c
+++ b/drivers/irqchip/irq-ath79-misc.c
@@ -50,7 +50,7 @@ static void ath79_misc_irq_handler(struct irq_desc *desc)
 	while (pending) {
 		int bit = __ffs(pending);
 
-		generic_handle_irq(irq_linear_revmap(domain, bit));
+		generic_handle_domain_irq(domain, bit);
 		pending &= ~BIT(bit);
 	}
 
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index a1e004af23e7..adc1556ed332 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -254,7 +254,7 @@ static void bcm2836_chained_handle_irq(struct irq_desc *desc)
 	u32 hwirq;
 
 	while ((hwirq = get_next_armctrl_hwirq()) != ~0)
-		generic_handle_irq(irq_linear_revmap(intc.domain, hwirq));
+		generic_handle_domain_irq(intc.domain, hwirq);
 }
 
 IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic",
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index 25c9a9c06e41..501facdb4570 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -161,7 +161,7 @@ static void bcm2836_arm_irqchip_handle_ipi(struct irq_desc *desc)
 	mbox_val = readl_relaxed(intc.base + LOCAL_MAILBOX0_CLR0 + 16 * cpu);
 	if (mbox_val) {
 		int hwirq = ffs(mbox_val) - 1;
-		generic_handle_irq(irq_find_mapping(ipi_domain, hwirq));
+		generic_handle_domain_irq(ipi_domain, hwirq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c
index 9dc9bf8cdcc4..a035c385ca7a 100644
--- a/drivers/irqchip/irq-bcm7038-l1.c
+++ b/drivers/irqchip/irq-bcm7038-l1.c
@@ -145,10 +145,8 @@ static void bcm7038_l1_irq_handle(struct irq_desc *desc)
 			  ~cpu->mask_cache[idx];
 		raw_spin_unlock_irqrestore(&intc->lock, flags);
 
-		for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
-			generic_handle_irq(irq_find_mapping(intc->domain,
-							    base + hwirq));
-		}
+		for_each_set_bit(hwirq, &pending, IRQS_PER_WORD)
+			generic_handle_domain_irq(intc->domain, base + hwirq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c
index ad59656ccc28..f23d7651ea84 100644
--- a/drivers/irqchip/irq-bcm7120-l2.c
+++ b/drivers/irqchip/irq-bcm7120-l2.c
@@ -74,10 +74,8 @@ static void bcm7120_l2_intc_irq_handle(struct irq_desc *desc)
 					    data->irq_map_mask[idx];
 		irq_gc_unlock(gc);
 
-		for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) {
-			generic_handle_irq(irq_find_mapping(b->domain,
-					   base + hwirq));
-		}
+		for_each_set_bit(hwirq, &pending, IRQS_PER_WORD)
+			generic_handle_domain_irq(b->domain, base + hwirq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c
index cdd6a42d4efa..8e0911561f2d 100644
--- a/drivers/irqchip/irq-brcmstb-l2.c
+++ b/drivers/irqchip/irq-brcmstb-l2.c
@@ -110,7 +110,7 @@ static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc)
 	do {
 		irq = ffs(status) - 1;
 		status &= ~(1 << irq);
-		generic_handle_irq(irq_linear_revmap(b->domain, irq));
+		generic_handle_domain_irq(b->domain, irq);
 	} while (status);
 out:
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c
index 54b09d6c407c..a67266e44491 100644
--- a/drivers/irqchip/irq-dw-apb-ictl.c
+++ b/drivers/irqchip/irq-dw-apb-ictl.c
@@ -62,9 +62,8 @@ static void dw_apb_ictl_handle_irq_cascaded(struct irq_desc *desc)
 
 		while (stat) {
 			u32 hwirq = ffs(stat) - 1;
-			u32 virq = irq_find_mapping(d, gc->irq_base + hwirq);
+			generic_handle_domain_irq(d, gc->irq_base + hwirq);
 
-			generic_handle_irq(virq);
 			stat &= ~BIT(hwirq);
 		}
 	}
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index b1d9c22caf2e..46c9c5fafdbc 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -375,8 +375,9 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
 {
 	struct gic_chip_data *chip_data = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	unsigned int cascade_irq, gic_irq;
+	unsigned int gic_irq;
 	unsigned long status;
+	int ret;
 
 	chained_irq_enter(chip, desc);
 
@@ -386,14 +387,10 @@ static void gic_handle_cascade_irq(struct irq_desc *desc)
 	if (gic_irq == GICC_INT_SPURIOUS)
 		goto out;
 
-	cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
-	if (unlikely(gic_irq < 32 || gic_irq > 1020)) {
+	isb();
+	ret = generic_handle_domain_irq(chip_data->domain, gic_irq);
+	if (unlikely(ret))
 		handle_bad_irq(desc);
-	} else {
-		isb();
-		generic_handle_irq(cascade_irq);
-	}
-
  out:
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/irqchip/irq-goldfish-pic.c b/drivers/irqchip/irq-goldfish-pic.c
index 4f021530e7f3..513f6edbbe95 100644
--- a/drivers/irqchip/irq-goldfish-pic.c
+++ b/drivers/irqchip/irq-goldfish-pic.c
@@ -34,15 +34,14 @@ static void goldfish_pic_cascade(struct irq_desc *desc)
 {
 	struct goldfish_pic_data *gfpic = irq_desc_get_handler_data(desc);
 	struct irq_chip *host_chip = irq_desc_get_chip(desc);
-	u32 pending, hwirq, virq;
+	u32 pending, hwirq;
 
 	chained_irq_enter(host_chip, desc);
 
 	pending = readl(gfpic->base + GFPIC_REG_IRQ_PENDING);
 	while (pending) {
 		hwirq = __fls(pending);
-		virq = irq_linear_revmap(gfpic->irq_domain, hwirq);
-		generic_handle_irq(virq);
+		generic_handle_domain_irq(gfpic->irq_domain, hwirq);
 		pending &= ~(1 << hwirq);
 	}
 
diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c
index b6f6aa7b2862..b70ce0d3c092 100644
--- a/drivers/irqchip/irq-i8259.c
+++ b/drivers/irqchip/irq-i8259.c
@@ -333,13 +333,11 @@ static void i8259_irq_dispatch(struct irq_desc *desc)
 {
 	struct irq_domain *domain = irq_desc_get_handler_data(desc);
 	int hwirq = i8259_poll();
-	unsigned int irq;
 
 	if (hwirq < 0)
 		return;
 
-	irq = irq_linear_revmap(domain, hwirq);
-	generic_handle_irq(irq);
+	generic_handle_domain_irq(domain, hwirq);
 }
 
 int __init i8259_of_init(struct device_node *node, struct device_node *parent)
diff --git a/drivers/irqchip/irq-idt3243x.c b/drivers/irqchip/irq-idt3243x.c
index f0996820077a..0732a0e9af62 100644
--- a/drivers/irqchip/irq-idt3243x.c
+++ b/drivers/irqchip/irq-idt3243x.c
@@ -28,7 +28,7 @@ static void idt_irq_dispatch(struct irq_desc *desc)
 {
 	struct idt_pic_data *idtpic = irq_desc_get_handler_data(desc);
 	struct irq_chip *host_chip = irq_desc_get_chip(desc);
-	u32 pending, hwirq, virq;
+	u32 pending, hwirq;
 
 	chained_irq_enter(host_chip, desc);
 
@@ -36,9 +36,7 @@ static void idt_irq_dispatch(struct irq_desc *desc)
 	pending &= ~idtpic->gc->mask_cache;
 	while (pending) {
 		hwirq = __fls(pending);
-		virq = irq_linear_revmap(idtpic->irq_domain, hwirq);
-		if (virq)
-			generic_handle_irq(virq);
+		generic_handle_domain_irq(idtpic->irq_domain, hwirq);
 		pending &= ~(1 << hwirq);
 	}
 
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c
index 698d07f48fed..646dfbf4890b 100644
--- a/drivers/irqchip/irq-imgpdc.c
+++ b/drivers/irqchip/irq-imgpdc.c
@@ -223,7 +223,7 @@ static void pdc_intc_perip_isr(struct irq_desc *desc)
 {
 	unsigned int irq = irq_desc_get_irq(desc);
 	struct pdc_intc_priv *priv;
-	unsigned int i, irq_no;
+	unsigned int i;
 
 	priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
 
@@ -237,14 +237,13 @@ static void pdc_intc_perip_isr(struct irq_desc *desc)
 found:
 
 	/* pass on the interrupt */
-	irq_no = irq_linear_revmap(priv->domain, i);
-	generic_handle_irq(irq_no);
+	generic_handle_domain_irq(priv->domain, i);
 }
 
 static void pdc_intc_syswake_isr(struct irq_desc *desc)
 {
 	struct pdc_intc_priv *priv;
-	unsigned int syswake, irq_no;
+	unsigned int syswake;
 	unsigned int status;
 
 	priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
@@ -258,9 +257,7 @@ static void pdc_intc_syswake_isr(struct irq_desc *desc)
 		if (!(status & 1))
 			continue;
 
-		irq_no = irq_linear_revmap(priv->domain,
-					   syswake_to_hwirq(syswake));
-		generic_handle_irq(irq_no);
+		generic_handle_domain_irq(priv->domain, syswake_to_hwirq(syswake));
 	}
 }
 
diff --git a/drivers/irqchip/irq-imx-intmux.c b/drivers/irqchip/irq-imx-intmux.c
index 7709f9712cb3..e86ff743e98c 100644
--- a/drivers/irqchip/irq-imx-intmux.c
+++ b/drivers/irqchip/irq-imx-intmux.c
@@ -182,18 +182,15 @@ static void imx_intmux_irq_handler(struct irq_desc *desc)
 	struct intmux_data *data = container_of(irqchip_data, struct intmux_data,
 						irqchip_data[idx]);
 	unsigned long irqstat;
-	int pos, virq;
+	int pos;
 
 	chained_irq_enter(irq_desc_get_chip(desc), desc);
 
 	/* read the interrupt source pending status of this channel */
 	irqstat = readl_relaxed(data->regs + CHANIPR(idx));
 
-	for_each_set_bit(pos, &irqstat, 32) {
-		virq = irq_find_mapping(irqchip_data->domain, pos);
-		if (virq)
-			generic_handle_irq(virq);
-	}
+	for_each_set_bit(pos, &irqstat, 32)
+		generic_handle_domain_irq(irqchip_data->domain, pos);
 
 	chained_irq_exit(irq_desc_get_chip(desc), desc);
 }
diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index 1edf7692a790..8d91a02593fc 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -122,7 +122,7 @@ static void imx_irqsteer_irq_handler(struct irq_desc *desc)
 	for (i = 0; i < 2; i++, hwirq += 32) {
 		int idx = imx_irqsteer_get_reg_index(data, hwirq);
 		unsigned long irqmap;
-		int pos, virq;
+		int pos;
 
 		if (hwirq >= data->reg_num * 32)
 			break;
@@ -130,11 +130,8 @@ static void imx_irqsteer_irq_handler(struct irq_desc *desc)
 		irqmap = readl_relaxed(data->regs +
 				       CHANSTATUS(idx, data->reg_num));
 
-		for_each_set_bit(pos, &irqmap, 32) {
-			virq = irq_find_mapping(data->domain, pos + hwirq);
-			if (virq)
-				generic_handle_irq(virq);
-		}
+		for_each_set_bit(pos, &irqmap, 32)
+			generic_handle_domain_irq(data->domain, pos + hwirq);
 	}
 
 	chained_irq_exit(irq_desc_get_chip(desc), desc);
diff --git a/drivers/irqchip/irq-ingenic-tcu.c b/drivers/irqchip/irq-ingenic-tcu.c
index b938d1d04d96..34a7d261b710 100644
--- a/drivers/irqchip/irq-ingenic-tcu.c
+++ b/drivers/irqchip/irq-ingenic-tcu.c
@@ -38,7 +38,7 @@ static void ingenic_tcu_intc_cascade(struct irq_desc *desc)
 	irq_reg &= ~irq_mask;
 
 	for_each_set_bit(i, (unsigned long *)&irq_reg, 32)
-		generic_handle_irq(irq_linear_revmap(domain, i));
+		generic_handle_domain_irq(domain, i);
 
 	chained_irq_exit(irq_chip, desc);
 }
diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c
index ea36bb00be80..cee839ca627e 100644
--- a/drivers/irqchip/irq-ingenic.c
+++ b/drivers/irqchip/irq-ingenic.c
@@ -49,8 +49,7 @@ static irqreturn_t intc_cascade(int irq, void *data)
 		while (pending) {
 			int bit = __fls(pending);
 
-			irq = irq_linear_revmap(domain, bit + (i * 32));
-			generic_handle_irq(irq);
+			generic_handle_domain_irq(domain, bit + (i * 32));
 			pending &= ~BIT(bit);
 		}
 	}
diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c
index 8118ebe80b09..d47c8041e5bc 100644
--- a/drivers/irqchip/irq-keystone.c
+++ b/drivers/irqchip/irq-keystone.c
@@ -89,7 +89,7 @@ static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq)
 	struct keystone_irq_device *kirq = keystone_irq;
 	unsigned long wa_lock_flags;
 	unsigned long pending;
-	int src, virq;
+	int src, err;
 
 	dev_dbg(kirq->dev, "start irq %d\n", irq);
 
@@ -104,16 +104,14 @@ static irqreturn_t keystone_irq_handler(int irq, void *keystone_irq)
 
 	for (src = 0; src < KEYSTONE_N_IRQ; src++) {
 		if (BIT(src) & pending) {
-			virq = irq_find_mapping(kirq->irqd, src);
-			dev_dbg(kirq->dev, "dispatch bit %d, virq %d\n",
-				src, virq);
-			if (!virq)
-				dev_warn(kirq->dev, "spurious irq detected hwirq %d, virq %d\n",
-					 src, virq);
 			raw_spin_lock_irqsave(&kirq->wa_lock, wa_lock_flags);
-			generic_handle_irq(virq);
+			err = generic_handle_domain_irq(kirq->irqd, src);
 			raw_spin_unlock_irqrestore(&kirq->wa_lock,
 						   wa_lock_flags);
+
+			if (err)
+				dev_warn_ratelimited(kirq->dev, "spurious irq detected hwirq %d\n",
+						     src);
 		}
 	}
 
diff --git a/drivers/irqchip/irq-loongson-htpic.c b/drivers/irqchip/irq-loongson-htpic.c
index 1b801c4fb026..f4abdf156de7 100644
--- a/drivers/irqchip/irq-loongson-htpic.c
+++ b/drivers/irqchip/irq-loongson-htpic.c
@@ -48,7 +48,7 @@ static void htpic_irq_dispatch(struct irq_desc *desc)
 			break;
 		}
 
-		generic_handle_irq(irq_linear_revmap(priv->domain, bit));
+		generic_handle_domain_irq(priv->domain, bit);
 		pending &= ~BIT(bit);
 	}
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-loongson-htvec.c b/drivers/irqchip/irq-loongson-htvec.c
index 6392aafb9a63..60a335d7e64e 100644
--- a/drivers/irqchip/irq-loongson-htvec.c
+++ b/drivers/irqchip/irq-loongson-htvec.c
@@ -47,8 +47,8 @@ static void htvec_irq_dispatch(struct irq_desc *desc)
 		while (pending) {
 			int bit = __ffs(pending);
 
-			generic_handle_irq(irq_linear_revmap(priv->htvec_domain, bit +
-							     VEC_COUNT_PER_REG * i));
+			generic_handle_domain_irq(priv->htvec_domain,
+						  bit + VEC_COUNT_PER_REG * i);
 			pending &= ~BIT(bit);
 			handled = true;
 		}
diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c
index 8ccb30421806..649c58391618 100644
--- a/drivers/irqchip/irq-loongson-liointc.c
+++ b/drivers/irqchip/irq-loongson-liointc.c
@@ -73,7 +73,7 @@ static void liointc_chained_handle_irq(struct irq_desc *desc)
 	while (pending) {
 		int bit = __ffs(pending);
 
-		generic_handle_irq(irq_find_mapping(gc->domain, bit));
+		generic_handle_domain_irq(gc->domain, bit);
 		pending &= ~BIT(bit);
 	}
 
diff --git a/drivers/irqchip/irq-lpc32xx.c b/drivers/irqchip/irq-lpc32xx.c
index 7d9b388afe64..5e6f6e25f2ae 100644
--- a/drivers/irqchip/irq-lpc32xx.c
+++ b/drivers/irqchip/irq-lpc32xx.c
@@ -141,7 +141,7 @@ static void lpc32xx_sic_handler(struct irq_desc *desc)
 	while (hwirq) {
 		irq = __ffs(hwirq);
 		hwirq &= ~BIT(irq);
-		generic_handle_irq(irq_find_mapping(ic->domain, irq));
+		generic_handle_domain_irq(ic->domain, irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 61dbfda08527..55322da51c56 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -194,7 +194,7 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
 	struct ls_scfg_msir *msir = irq_desc_get_handler_data(desc);
 	struct ls_scfg_msi *msi_data = msir->msi_data;
 	unsigned long val;
-	int pos, size, virq, hwirq;
+	int pos, size, hwirq;
 
 	chained_irq_enter(irq_desc_get_chip(desc), desc);
 
@@ -206,9 +206,7 @@ static void ls_scfg_msi_irq_handler(struct irq_desc *desc)
 	for_each_set_bit_from(pos, &val, size) {
 		hwirq = ((msir->bit_end - pos) << msi_data->cfg->ibs_shift) |
 			msir->srs;
-		virq = irq_find_mapping(msi_data->parent, hwirq);
-		if (virq)
-			generic_handle_irq(virq);
+		generic_handle_domain_irq(msi_data->parent, hwirq);
 	}
 
 	chained_irq_exit(irq_desc_get_chip(desc), desc);
diff --git a/drivers/irqchip/irq-ls1x.c b/drivers/irqchip/irq-ls1x.c
index 353111a10413..77a3f7dfaaf0 100644
--- a/drivers/irqchip/irq-ls1x.c
+++ b/drivers/irqchip/irq-ls1x.c
@@ -50,7 +50,7 @@ static void ls1x_chained_handle_irq(struct irq_desc *desc)
 	while (pending) {
 		int bit = __ffs(pending);
 
-		generic_handle_irq(irq_find_mapping(priv->domain, bit));
+		generic_handle_domain_irq(priv->domain, bit);
 		pending &= ~BIT(bit);
 	}
 
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
index a2cbf0acff1c..b146e069bf5b 100644
--- a/drivers/irqchip/irq-mips-gic.c
+++ b/drivers/irqchip/irq-mips-gic.c
@@ -148,7 +148,7 @@ int gic_get_c0_fdc_int(void)
 
 static void gic_handle_shared_int(bool chained)
 {
-	unsigned int intr, virq;
+	unsigned int intr;
 	unsigned long *pcpu_mask;
 	DECLARE_BITMAP(pending, GIC_MAX_INTRS);
 
@@ -165,12 +165,12 @@ static void gic_handle_shared_int(bool chained)
 	bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs);
 
 	for_each_set_bit(intr, pending, gic_shared_intrs) {
-		virq = irq_linear_revmap(gic_irq_domain,
-					 GIC_SHARED_TO_HWIRQ(intr));
 		if (chained)
-			generic_handle_irq(virq);
+			generic_handle_domain_irq(gic_irq_domain,
+						  GIC_SHARED_TO_HWIRQ(intr));
 		else
-			do_IRQ(virq);
+			do_IRQ(irq_find_mapping(gic_irq_domain,
+						GIC_SHARED_TO_HWIRQ(intr)));
 	}
 }
 
@@ -308,7 +308,7 @@ static struct irq_chip gic_edge_irq_controller = {
 static void gic_handle_local_int(bool chained)
 {
 	unsigned long pending, masked;
-	unsigned int intr, virq;
+	unsigned int intr;
 
 	pending = read_gic_vl_pend();
 	masked = read_gic_vl_mask();
@@ -316,12 +316,12 @@ static void gic_handle_local_int(bool chained)
 	bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
 
 	for_each_set_bit(intr, &pending, GIC_NUM_LOCAL_INTRS) {
-		virq = irq_linear_revmap(gic_irq_domain,
-					 GIC_LOCAL_TO_HWIRQ(intr));
 		if (chained)
-			generic_handle_irq(virq);
+			generic_handle_domain_irq(gic_irq_domain,
+						  GIC_LOCAL_TO_HWIRQ(intr));
 		else
-			do_IRQ(virq);
+			do_IRQ(irq_find_mapping(gic_irq_domain,
+						GIC_LOCAL_TO_HWIRQ(intr)));
 	}
 }
 
diff --git a/drivers/irqchip/irq-mscc-ocelot.c b/drivers/irqchip/irq-mscc-ocelot.c
index 8235d98650c1..4d0c3532dbe7 100644
--- a/drivers/irqchip/irq-mscc-ocelot.c
+++ b/drivers/irqchip/irq-mscc-ocelot.c
@@ -107,7 +107,7 @@ static void ocelot_irq_handler(struct irq_desc *desc)
 	while (reg) {
 		u32 hwirq = __fls(reg);
 
-		generic_handle_irq(irq_find_mapping(d, hwirq));
+		generic_handle_domain_irq(d, hwirq);
 		reg &= ~(BIT(hwirq));
 	}
 
diff --git a/drivers/irqchip/irq-mvebu-pic.c b/drivers/irqchip/irq-mvebu-pic.c
index eec63951129a..dc1cee4b0fe1 100644
--- a/drivers/irqchip/irq-mvebu-pic.c
+++ b/drivers/irqchip/irq-mvebu-pic.c
@@ -91,15 +91,12 @@ static void mvebu_pic_handle_cascade_irq(struct irq_desc *desc)
 	struct mvebu_pic *pic = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	unsigned long irqmap, irqn;
-	unsigned int cascade_irq;
 
 	irqmap = readl_relaxed(pic->base + PIC_CAUSE);
 	chained_irq_enter(chip, desc);
 
-	for_each_set_bit(irqn, &irqmap, BITS_PER_LONG) {
-		cascade_irq = irq_find_mapping(pic->domain, irqn);
-		generic_handle_irq(cascade_irq);
-	}
+	for_each_set_bit(irqn, &irqmap, BITS_PER_LONG)
+		generic_handle_domain_irq(pic->domain, irqn);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/irqchip/irq-mvebu-sei.c b/drivers/irqchip/irq-mvebu-sei.c
index 18832ccc8ff8..9a75b999eda3 100644
--- a/drivers/irqchip/irq-mvebu-sei.c
+++ b/drivers/irqchip/irq-mvebu-sei.c
@@ -337,17 +337,12 @@ static void mvebu_sei_handle_cascade_irq(struct irq_desc *desc)
 		irqmap = readl_relaxed(sei->base + GICP_SECR(idx));
 		for_each_set_bit(bit, &irqmap, SEI_IRQ_COUNT_PER_REG) {
 			unsigned long hwirq;
-			unsigned int virq;
+			int err;
 
 			hwirq = idx * SEI_IRQ_COUNT_PER_REG + bit;
-			virq = irq_find_mapping(sei->sei_domain, hwirq);
-			if (likely(virq)) {
-				generic_handle_irq(virq);
-				continue;
-			}
-
-			dev_warn(sei->dev,
-				 "Spurious IRQ detected (hwirq %lu)\n", hwirq);
+			err = generic_handle_domain_irq(sei->sei_domain, hwirq);
+			if (unlikely(err))
+				dev_warn(sei->dev, "Spurious IRQ detected (hwirq %lu)\n", hwirq);
 		}
 	}
 
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c
index c4b5ffb61954..b6868f7b805a 100644
--- a/drivers/irqchip/irq-orion.c
+++ b/drivers/irqchip/irq-orion.c
@@ -117,7 +117,7 @@ static void orion_bridge_irq_handler(struct irq_desc *desc)
 	while (stat) {
 		u32 hwirq = __fls(stat);
 
-		generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq));
+		generic_handle_domain_irq(d, gc->irq_base + hwirq);
 		stat &= ~(1 << hwirq);
 	}
 }
diff --git a/drivers/irqchip/irq-partition-percpu.c b/drivers/irqchip/irq-partition-percpu.c
index 0c4c8ed7064e..89c23a1566dc 100644
--- a/drivers/irqchip/irq-partition-percpu.c
+++ b/drivers/irqchip/irq-partition-percpu.c
@@ -124,13 +124,10 @@ static void partition_handle_irq(struct irq_desc *desc)
 			break;
 	}
 
-	if (unlikely(hwirq == part->nr_parts)) {
+	if (unlikely(hwirq == part->nr_parts))
 		handle_bad_irq(desc);
-	} else {
-		unsigned int irq;
-		irq = irq_find_mapping(part->domain, hwirq);
-		generic_handle_irq(irq);
-	}
+	else
+		generic_handle_domain_irq(part->domain, hwirq);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/irqchip/irq-pruss-intc.c b/drivers/irqchip/irq-pruss-intc.c
index 92fb5780dc10..fa8d89b02ec0 100644
--- a/drivers/irqchip/irq-pruss-intc.c
+++ b/drivers/irqchip/irq-pruss-intc.c
@@ -488,8 +488,7 @@ static void pruss_intc_irq_handler(struct irq_desc *desc)
 
 	while (true) {
 		u32 hipir;
-		unsigned int virq;
-		int hwirq;
+		int hwirq, err;
 
 		/* get highest priority pending PRUSS system event */
 		hipir = pruss_intc_read_reg(intc, PRU_INTC_HIPIR(host_irq));
@@ -497,16 +496,14 @@ static void pruss_intc_irq_handler(struct irq_desc *desc)
 			break;
 
 		hwirq = hipir & GENMASK(9, 0);
-		virq = irq_find_mapping(intc->domain, hwirq);
+		err = generic_handle_domain_irq(intc->domain, hwirq);
 
 		/*
 		 * NOTE: manually ACK any system events that do not have a
 		 * handler mapped yet
 		 */
-		if (WARN_ON_ONCE(!virq))
+		if (WARN_ON_ONCE(err))
 			pruss_intc_write_reg(intc, PRU_INTC_SICR, hwirq);
-		else
-			generic_handle_irq(virq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-realtek-rtl.c b/drivers/irqchip/irq-realtek-rtl.c
index b57c67dfab5b..fd9f275592d2 100644
--- a/drivers/irqchip/irq-realtek-rtl.c
+++ b/drivers/irqchip/irq-realtek-rtl.c
@@ -85,7 +85,7 @@ static void realtek_irq_dispatch(struct irq_desc *desc)
 		goto out;
 	}
 	domain = irq_desc_get_handler_data(desc);
-	generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
+	generic_handle_domain_irq(domain, __ffs(pending));
 
 out:
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index 11abc09ef76c..07a6d8b42b63 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -115,7 +115,7 @@ static irqreturn_t irqc_irq_handler(int irq, void *dev_id)
 	if (ioread32(p->iomem + DETECT_STATUS) & bit) {
 		iowrite32(bit, p->iomem + DETECT_STATUS);
 		irqc_dbg(i, "demux2");
-		generic_handle_irq(irq_find_mapping(p->irq_domain, i->hw_irq));
+		generic_handle_domain_irq(p->irq_domain, i->hw_irq);
 		return IRQ_HANDLED;
 	}
 	return IRQ_NONE;
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 97d4d04b0a80..cf74cfa82045 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -233,13 +233,11 @@ static void plic_handle_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	while ((hwirq = readl(claim))) {
-		int irq = irq_find_mapping(handler->priv->irqdomain, hwirq);
-
-		if (unlikely(irq <= 0))
+		int err = generic_handle_domain_irq(handler->priv->irqdomain,
+						    hwirq);
+		if (unlikely(err))
 			pr_warn_ratelimited("can't find mapping for hwirq %lu\n",
 					hwirq);
-		else
-			generic_handle_irq(irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c
index b9db90c4aa56..7f55496dce66 100644
--- a/drivers/irqchip/irq-stm32-exti.c
+++ b/drivers/irqchip/irq-stm32-exti.c
@@ -257,7 +257,7 @@ static void stm32_irq_handler(struct irq_desc *desc)
 {
 	struct irq_domain *domain = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	unsigned int virq, nbanks = domain->gc->num_chips;
+	unsigned int nbanks = domain->gc->num_chips;
 	struct irq_chip_generic *gc;
 	unsigned long pending;
 	int n, i, irq_base = 0;
@@ -268,11 +268,9 @@ static void stm32_irq_handler(struct irq_desc *desc)
 		gc = irq_get_domain_generic_chip(domain, irq_base);
 
 		while ((pending = stm32_exti_pending(gc))) {
-			for_each_set_bit(n, &pending, IRQS_PER_BANK) {
-				virq = irq_find_mapping(domain, irq_base + n);
-				generic_handle_irq(virq);
-			}
-		}
+			for_each_set_bit(n, &pending, IRQS_PER_BANK)
+				generic_handle_domain_irq(domain, irq_base + n);
+ 		}
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c
index 9f2bd0c5d289..21d49791f855 100644
--- a/drivers/irqchip/irq-sunxi-nmi.c
+++ b/drivers/irqchip/irq-sunxi-nmi.c
@@ -88,10 +88,9 @@ static void sunxi_sc_nmi_handle_irq(struct irq_desc *desc)
 {
 	struct irq_domain *domain = irq_desc_get_handler_data(desc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	unsigned int virq = irq_find_mapping(domain, 0);
 
 	chained_irq_enter(chip, desc);
-	generic_handle_irq(virq);
+	generic_handle_domain_irq(domain, 0);
 	chained_irq_exit(chip, desc);
 }
 
diff --git a/drivers/irqchip/irq-tb10x.c b/drivers/irqchip/irq-tb10x.c
index 9a63b02b8176..8a0e69298e83 100644
--- a/drivers/irqchip/irq-tb10x.c
+++ b/drivers/irqchip/irq-tb10x.c
@@ -91,7 +91,7 @@ static void tb10x_irq_cascade(struct irq_desc *desc)
 	struct irq_domain *domain = irq_desc_get_handler_data(desc);
 	unsigned int irq = irq_desc_get_irq(desc);
 
-	generic_handle_irq(irq_find_mapping(domain, irq));
+	generic_handle_domain_irq(domain, irq);
 }
 
 static int __init of_tb10x_init_irq(struct device_node *ictl,
diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
index ca1f593f4d13..97f454ec376b 100644
--- a/drivers/irqchip/irq-ti-sci-inta.c
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -147,7 +147,7 @@ static void ti_sci_inta_irq_handler(struct irq_desc *desc)
 	struct ti_sci_inta_vint_desc *vint_desc;
 	struct ti_sci_inta_irq_domain *inta;
 	struct irq_domain *domain;
-	unsigned int virq, bit;
+	unsigned int bit;
 	unsigned long val;
 
 	vint_desc = irq_desc_get_handler_data(desc);
@@ -159,11 +159,8 @@ static void ti_sci_inta_irq_handler(struct irq_desc *desc)
 	val = readq_relaxed(inta->base + vint_desc->vint_id * 0x1000 +
 			    VINT_STATUS_MASKED_OFFSET);
 
-	for_each_set_bit(bit, &val, MAX_EVENTS_PER_VINT) {
-		virq = irq_find_mapping(domain, vint_desc->events[bit].hwirq);
-		if (virq)
-			generic_handle_irq(virq);
-	}
+	for_each_set_bit(bit, &val, MAX_EVENTS_PER_VINT)
+		generic_handle_domain_irq(domain, vint_desc->events[bit].hwirq);
 
 	chained_irq_exit(irq_desc_get_chip(desc), desc);
 }
diff --git a/drivers/irqchip/irq-ts4800.c b/drivers/irqchip/irq-ts4800.c
index 2325fb3c482b..34337a61b1ef 100644
--- a/drivers/irqchip/irq-ts4800.c
+++ b/drivers/irqchip/irq-ts4800.c
@@ -79,10 +79,9 @@ static void ts4800_ic_chained_handle_irq(struct irq_desc *desc)
 
 	do {
 		unsigned int bit = __ffs(status);
-		int irq = irq_find_mapping(data->domain, bit);
 
+		generic_handle_domain_irq(data->domain, bit);
 		status &= ~(1 << bit);
-		generic_handle_irq(irq);
 	} while (status);
 
 out:
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index f1386733d3bc..75be350cf82f 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -85,7 +85,7 @@ static void fpga_irq_handle(struct irq_desc *desc)
 		unsigned int irq = ffs(status) - 1;
 
 		status &= ~(1 << irq);
-		generic_handle_irq(irq_find_mapping(f->domain, irq));
+		generic_handle_domain_irq(f->domain, irq);
 	} while (status);
 
 out:
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index 62f3d29f9042..1e1f2d115257 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -225,7 +225,7 @@ static void vic_handle_irq_cascaded(struct irq_desc *desc)
 
 	while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
 		hwirq = ffs(stat) - 1;
-		generic_handle_irq(irq_find_mapping(vic->domain, hwirq));
+		generic_handle_domain_irq(vic->domain, hwirq);
 	}
 
 	chained_irq_exit(host_chip, desc);
diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c
index 8cd1bfc73057..875ff52deda9 100644
--- a/drivers/irqchip/irq-xilinx-intc.c
+++ b/drivers/irqchip/irq-xilinx-intc.c
@@ -110,20 +110,6 @@ static struct irq_chip intc_dev = {
 	.irq_mask_ack = intc_mask_ack,
 };
 
-static unsigned int xintc_get_irq_local(struct xintc_irq_chip *irqc)
-{
-	unsigned int irq = 0;
-	u32 hwirq;
-
-	hwirq = xintc_read(irqc, IVR);
-	if (hwirq != -1U)
-		irq = irq_find_mapping(irqc->root_domain, hwirq);
-
-	pr_debug("irq-xilinx: hwirq=%d, irq=%d\n", hwirq, irq);
-
-	return irq;
-}
-
 unsigned int xintc_get_irq(void)
 {
 	unsigned int irq = -1;
@@ -169,10 +155,12 @@ static void xil_intc_irq_handler(struct irq_desc *desc)
 	irqc = irq_data_get_irq_handler_data(&desc->irq_data);
 	chained_irq_enter(chip, desc);
 	do {
-		pending = xintc_get_irq_local(irqc);
-		if (pending == 0)
+		u32 hwirq = xintc_read(irqc, IVR);
+
+		if (hwirq == -1U)
 			break;
-		generic_handle_irq(pending);
+
+		generic_handle_domain_irq(irqc->root_domain, hwirq);
 	} while (true);
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c
index aa54bfcb0433..18e696dc7f4d 100644
--- a/drivers/irqchip/qcom-irq-combiner.c
+++ b/drivers/irqchip/qcom-irq-combiner.c
@@ -53,7 +53,6 @@ static void combiner_handle_irq(struct irq_desc *desc)
 	chained_irq_enter(chip, desc);
 
 	for (reg = 0; reg < combiner->nregs; reg++) {
-		int virq;
 		int hwirq;
 		u32 bit;
 		u32 status;
@@ -70,10 +69,7 @@ static void combiner_handle_irq(struct irq_desc *desc)
 			bit = __ffs(status);
 			status &= ~(1 << bit);
 			hwirq = irq_nr(reg, bit);
-			virq = irq_find_mapping(combiner->domain, hwirq);
-			if (virq > 0)
-				generic_handle_irq(virq);
-
+			generic_handle_domain_irq(combiner->domain, hwirq);
 		}
 	}
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 28/39] gpio: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (26 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq() Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-21  8:59   ` Geert Uytterhoeven
  2021-05-20 16:37 ` [PATCH 29/39] pinctrl: " Marc Zyngier
                   ` (12 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/gpio/gpio-104-dio-48e.c  |  4 ++--
 drivers/gpio/gpio-104-idi-48.c   |  4 ++--
 drivers/gpio/gpio-104-idio-16.c  |  2 +-
 drivers/gpio/gpio-altera.c       | 11 +++++------
 drivers/gpio/gpio-aspeed-sgpio.c |  9 +++------
 drivers/gpio/gpio-aspeed.c       |  9 +++------
 drivers/gpio/gpio-ath79.c        |  7 ++-----
 drivers/gpio/gpio-bcm-kona.c     |  6 ++----
 drivers/gpio/gpio-brcmstb.c      |  5 ++---
 drivers/gpio/gpio-cadence.c      |  2 +-
 drivers/gpio/gpio-davinci.c      |  3 +--
 drivers/gpio/gpio-dln2.c         | 22 +++++++++-------------
 drivers/gpio/gpio-em.c           |  2 +-
 drivers/gpio/gpio-ep93xx.c       |  8 ++++----
 drivers/gpio/gpio-ftgpio010.c    |  3 +--
 drivers/gpio/gpio-hisi.c         |  4 ++--
 drivers/gpio/gpio-hlwd.c         |  7 ++-----
 drivers/gpio/gpio-merrifield.c   |  8 ++------
 drivers/gpio/gpio-mpc8xxx.c      |  2 +-
 drivers/gpio/gpio-mt7621.c       |  4 +---
 drivers/gpio/gpio-mxc.c          |  2 +-
 drivers/gpio/gpio-mxs.c          |  2 +-
 drivers/gpio/gpio-omap.c         |  3 +--
 drivers/gpio/gpio-pci-idio-16.c  |  2 +-
 drivers/gpio/gpio-pcie-idio-24.c |  3 +--
 drivers/gpio/gpio-pl061.c        |  4 ++--
 drivers/gpio/gpio-pxa.c          |  9 ++++-----
 drivers/gpio/gpio-rcar.c         |  4 ++--
 drivers/gpio/gpio-rda.c          |  8 +++-----
 drivers/gpio/gpio-realtek-otto.c |  7 ++-----
 drivers/gpio/gpio-sch.c          |  2 +-
 drivers/gpio/gpio-sodaville.c    |  2 +-
 drivers/gpio/gpio-sprd.c         | 12 ++++--------
 drivers/gpio/gpio-tb10x.c        |  2 +-
 drivers/gpio/gpio-tegra.c        |  9 ++++-----
 drivers/gpio/gpio-tegra186.c     |  9 +++------
 drivers/gpio/gpio-tqmx86.c       | 10 ++++------
 drivers/gpio/gpio-vf610.c        |  2 +-
 drivers/gpio/gpio-ws16c48.c      |  4 ++--
 drivers/gpio/gpio-xgs-iproc.c    |  2 +-
 drivers/gpio/gpio-xilinx.c       |  9 +++------
 drivers/gpio/gpio-xlp.c          |  3 +--
 drivers/gpio/gpio-zynq.c         |  8 ++------
 43 files changed, 93 insertions(+), 147 deletions(-)

diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c
index 71c0bea34d7b..6bf41040c41f 100644
--- a/drivers/gpio/gpio-104-dio-48e.c
+++ b/drivers/gpio/gpio-104-dio-48e.c
@@ -336,8 +336,8 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
 	unsigned long gpio;
 
 	for_each_set_bit(gpio, &irq_mask, 2)
-		generic_handle_irq(irq_find_mapping(chip->irq.domain,
-			19 + gpio*24));
+		generic_handle_domain_irq(chip->irq.domain,
+					  19 + gpio*24);
 
 	raw_spin_lock(&dio48egpio->lock);
 
diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c
index b132afaf7d99..34be7dd9f5b9 100644
--- a/drivers/gpio/gpio-104-idi-48.c
+++ b/drivers/gpio/gpio-104-idi-48.c
@@ -223,8 +223,8 @@ static irqreturn_t idi_48_irq_handler(int irq, void *dev_id)
 		for_each_set_bit(bit_num, &irq_mask, 8) {
 			gpio = bit_num + boundary * 8;
 
-			generic_handle_irq(irq_find_mapping(chip->irq.domain,
-				gpio));
+			generic_handle_domain_irq(chip->irq.domain,
+						  gpio);
 		}
 	}
 
diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c
index 50ad0280fd78..bd36459464a4 100644
--- a/drivers/gpio/gpio-104-idio-16.c
+++ b/drivers/gpio/gpio-104-idio-16.c
@@ -205,7 +205,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
 	int gpio;
 
 	for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
-		generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio));
+		generic_handle_domain_irq(chip->irq.domain, gpio);
 
 	raw_spin_lock(&idio16gpio->lock);
 
diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c
index b7932ecc3b61..b59fae993626 100644
--- a/drivers/gpio/gpio-altera.c
+++ b/drivers/gpio/gpio-altera.c
@@ -201,9 +201,8 @@ static void altera_gpio_irq_edge_handler(struct irq_desc *desc)
 	      (readl(mm_gc->regs + ALTERA_GPIO_EDGE_CAP) &
 	      readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK)))) {
 		writel(status, mm_gc->regs + ALTERA_GPIO_EDGE_CAP);
-		for_each_set_bit(i, &status, mm_gc->gc.ngpio) {
-			generic_handle_irq(irq_find_mapping(irqdomain, i));
-		}
+		for_each_set_bit(i, &status, mm_gc->gc.ngpio)
+			generic_handle_domain_irq(irqdomain, i);
 	}
 
 	chained_irq_exit(chip, desc);
@@ -228,9 +227,9 @@ static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc)
 	status = readl(mm_gc->regs + ALTERA_GPIO_DATA);
 	status &= readl(mm_gc->regs + ALTERA_GPIO_IRQ_MASK);
 
-	for_each_set_bit(i, &status, mm_gc->gc.ngpio) {
-		generic_handle_irq(irq_find_mapping(irqdomain, i));
-	}
+	for_each_set_bit(i, &status, mm_gc->gc.ngpio)
+		generic_handle_domain_irq(irqdomain, i);
+
 	chained_irq_exit(chip, desc);
 }
 
diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c
index 64e54f8c30d2..a99ece15db95 100644
--- a/drivers/gpio/gpio-aspeed-sgpio.c
+++ b/drivers/gpio/gpio-aspeed-sgpio.c
@@ -392,7 +392,7 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct irq_chip *ic = irq_desc_get_chip(desc);
 	struct aspeed_sgpio *data = gpiochip_get_data(gc);
-	unsigned int i, p, girq;
+	unsigned int i, p;
 	unsigned long reg;
 
 	chained_irq_enter(ic, desc);
@@ -402,11 +402,8 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
 
 		reg = ioread32(bank_reg(data, bank, reg_irq_status));
 
-		for_each_set_bit(p, &reg, 32) {
-			girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
-			generic_handle_irq(girq);
-		}
-
+		for_each_set_bit(p, &reg, 32)
+			generic_handle_domain_irq(gc->irq.domain, i * 32 + p);
 	}
 
 	chained_irq_exit(ic, desc);
diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index b966f5e28ebf..3c8f20c57695 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -661,7 +661,7 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc)
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct irq_chip *ic = irq_desc_get_chip(desc);
 	struct aspeed_gpio *data = gpiochip_get_data(gc);
-	unsigned int i, p, girq, banks;
+	unsigned int i, p, banks;
 	unsigned long reg;
 	struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 
@@ -673,11 +673,8 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc)
 
 		reg = ioread32(bank_reg(data, bank, reg_irq_status));
 
-		for_each_set_bit(p, &reg, 32) {
-			girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
-			generic_handle_irq(girq);
-		}
-
+		for_each_set_bit(p, &reg, 32)
+			generic_handle_domain_irq(gc->irq.domain, i * 32 + p);
 	}
 
 	chained_irq_exit(ic, desc);
diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c
index 678ddd375891..1c32d7f3159d 100644
--- a/drivers/gpio/gpio-ath79.c
+++ b/drivers/gpio/gpio-ath79.c
@@ -204,11 +204,8 @@ static void ath79_gpio_irq_handler(struct irq_desc *desc)
 
 	raw_spin_unlock_irqrestore(&ctrl->lock, flags);
 
-	if (pending) {
-		for_each_set_bit(irq, &pending, gc->ngpio)
-			generic_handle_irq(
-				irq_linear_revmap(gc->irq.domain, irq));
-	}
+	for_each_set_bit(irq, &pending, gc->ngpio)
+		generic_handle_domain_irq(gc->irq.domain, irq);
 
 	chained_irq_exit(irqchip, desc);
 }
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
index 1e6b427f2c4a..d329a143f5ec 100644
--- a/drivers/gpio/gpio-bcm-kona.c
+++ b/drivers/gpio/gpio-bcm-kona.c
@@ -466,9 +466,6 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc)
 		    (~(readl(reg_base + GPIO_INT_MASK(bank_id)))))) {
 		for_each_set_bit(bit, &sta, 32) {
 			int hwirq = GPIO_PER_BANK * bank_id + bit;
-			int child_irq =
-				irq_find_mapping(bank->kona_gpio->irq_domain,
-						 hwirq);
 			/*
 			 * Clear interrupt before handler is called so we don't
 			 * miss any interrupt occurred during executing them.
@@ -476,7 +473,8 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc)
 			writel(readl(reg_base + GPIO_INT_STATUS(bank_id)) |
 			       BIT(bit), reg_base + GPIO_INT_STATUS(bank_id));
 			/* Invoke interrupt handler */
-			generic_handle_irq(child_irq);
+			generic_handle_domain_irq(bank->kona_gpio->irq_domain,
+						  hwirq);
 		}
 	}
 
diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c
index fcfc1a1f1a5c..74b7c91c3d1a 100644
--- a/drivers/gpio/gpio-brcmstb.c
+++ b/drivers/gpio/gpio-brcmstb.c
@@ -277,15 +277,14 @@ static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank)
 	unsigned long status;
 
 	while ((status = brcmstb_gpio_get_active_irqs(bank))) {
-		unsigned int irq, offset;
+		unsigned int offset;
 
 		for_each_set_bit(offset, &status, 32) {
 			if (offset >= bank->width)
 				dev_warn(&priv->pdev->dev,
 					 "IRQ for invalid GPIO (bank=%d, offset=%d)\n",
 					 bank->id, offset);
-			irq = irq_linear_revmap(domain, hwbase + offset);
-			generic_handle_irq(irq);
+			generic_handle_domain_irq(domain, hwbase + offset);
 		}
 	}
 }
diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c
index a4d3239d2594..d8186eac5ce4 100644
--- a/drivers/gpio/gpio-cadence.c
+++ b/drivers/gpio/gpio-cadence.c
@@ -133,7 +133,7 @@ static void cdns_gpio_irq_handler(struct irq_desc *desc)
 		~ioread32(cgpio->regs + CDNS_GPIO_IRQ_MASK);
 
 	for_each_set_bit(hwirq, &status, chip->ngpio)
-		generic_handle_irq(irq_find_mapping(chip->irq.domain, hwirq));
+		generic_handle_domain_irq(chip->irq.domain, hwirq);
 
 	chained_irq_exit(irqchip, desc);
 }
diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
index 6f2138503726..cb5afaa7ed48 100644
--- a/drivers/gpio/gpio-davinci.c
+++ b/drivers/gpio/gpio-davinci.c
@@ -369,8 +369,7 @@ static void gpio_irq_handler(struct irq_desc *desc)
 			 */
 			hw_irq = (bank_num / 2) * 32 + bit;
 
-			generic_handle_irq(
-				irq_find_mapping(d->irq_domain, hw_irq));
+			generic_handle_domain_irq(d->irq_domain, hw_irq);
 		}
 	}
 	chained_irq_exit(irq_desc_get_chip(desc), desc);
diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c
index 4c5f6d0c8d74..026903e3ef54 100644
--- a/drivers/gpio/gpio-dln2.c
+++ b/drivers/gpio/gpio-dln2.c
@@ -395,7 +395,7 @@ static struct irq_chip dln2_gpio_irqchip = {
 static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
 			    const void *data, int len)
 {
-	int pin, irq;
+	int pin, ret;
 
 	const struct {
 		__le16 count;
@@ -416,24 +416,20 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo,
 		return;
 	}
 
-	irq = irq_find_mapping(dln2->gpio.irq.domain, pin);
-	if (!irq) {
-		dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin);
-		return;
-	}
-
 	switch (dln2->irq_type[pin]) {
 	case DLN2_GPIO_EVENT_CHANGE_RISING:
-		if (event->value)
-			generic_handle_irq(irq);
+		if (!event->value)
+			return;
 		break;
 	case DLN2_GPIO_EVENT_CHANGE_FALLING:
-		if (!event->value)
-			generic_handle_irq(irq);
+		if (event->value)
+			return;
 		break;
-	default:
-		generic_handle_irq(irq);
 	}
+
+	ret = generic_handle_domain_irq(dln2->gpio.irq.domain, pin);
+	if (unlikely(ret))
+		dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin);
 }
 
 static int dln2_gpio_probe(struct platform_device *pdev)
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c
index 17a243c528ad..90b336e6ee27 100644
--- a/drivers/gpio/gpio-em.c
+++ b/drivers/gpio/gpio-em.c
@@ -173,7 +173,7 @@ static irqreturn_t em_gio_irq_handler(int irq, void *dev_id)
 	while ((pending = em_gio_read(p, GIO_MST))) {
 		offset = __ffs(pending);
 		em_gio_write(p, GIO_IIR, BIT(offset));
-		generic_handle_irq(irq_find_mapping(p->irq_domain, offset));
+		generic_handle_domain_irq(p->irq_domain, offset);
 		irqs_handled++;
 	}
 
diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c
index ef148b26b587..2e1779709113 100644
--- a/drivers/gpio/gpio-ep93xx.c
+++ b/drivers/gpio/gpio-ep93xx.c
@@ -128,13 +128,13 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc)
 	 */
 	stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS);
 	for_each_set_bit(offset, &stat, 8)
-		generic_handle_irq(irq_find_mapping(epg->gc[0].gc.irq.domain,
-						    offset));
+		generic_handle_domain_irq(epg->gc[0].gc.irq.domain,
+					  offset);
 
 	stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS);
 	for_each_set_bit(offset, &stat, 8)
-		generic_handle_irq(irq_find_mapping(epg->gc[1].gc.irq.domain,
-						    offset));
+		generic_handle_domain_irq(epg->gc[1].gc.irq.domain,
+					  offset);
 
 	chained_irq_exit(irqchip, desc);
 }
diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c
index 4031164780f7..b90a45c939a4 100644
--- a/drivers/gpio/gpio-ftgpio010.c
+++ b/drivers/gpio/gpio-ftgpio010.c
@@ -149,8 +149,7 @@ static void ftgpio_gpio_irq_handler(struct irq_desc *desc)
 	stat = readl(g->base + GPIO_INT_STAT_RAW);
 	if (stat)
 		for_each_set_bit(offset, &stat, gc->ngpio)
-			generic_handle_irq(irq_find_mapping(gc->irq.domain,
-							    offset));
+			generic_handle_domain_irq(gc->irq.domain, offset);
 
 	chained_irq_exit(irqchip, desc);
 }
diff --git a/drivers/gpio/gpio-hisi.c b/drivers/gpio/gpio-hisi.c
index ad3d4da25160..3caabef5c7a2 100644
--- a/drivers/gpio/gpio-hisi.c
+++ b/drivers/gpio/gpio-hisi.c
@@ -186,8 +186,8 @@ static void hisi_gpio_irq_handler(struct irq_desc *desc)
 
 	chained_irq_enter(irq_c, desc);
 	for_each_set_bit(hwirq, &irq_msk, HISI_GPIO_LINE_NUM_MAX)
-		generic_handle_irq(irq_find_mapping(hisi_gpio->chip.irq.domain,
-						    hwirq));
+		generic_handle_domain_irq(hisi_gpio->chip.irq.domain,
+					  hwirq);
 	chained_irq_exit(irq_c, desc);
 }
 
diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c
index 4a17599f6d44..641719a96a1a 100644
--- a/drivers/gpio/gpio-hlwd.c
+++ b/drivers/gpio/gpio-hlwd.c
@@ -97,11 +97,8 @@ static void hlwd_gpio_irqhandler(struct irq_desc *desc)
 
 	chained_irq_enter(chip, desc);
 
-	for_each_set_bit(hwirq, &pending, 32) {
-		int irq = irq_find_mapping(hlwd->gpioc.irq.domain, hwirq);
-
-		generic_handle_irq(irq);
-	}
+	for_each_set_bit(hwirq, &pending, 32)
+		generic_handle_domain_irq(hlwd->gpioc.irq.domain, hwirq);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c
index 22f3ce218f5d..42c4d9d0cd50 100644
--- a/drivers/gpio/gpio-merrifield.c
+++ b/drivers/gpio/gpio-merrifield.c
@@ -359,12 +359,8 @@ static void mrfld_irq_handler(struct irq_desc *desc)
 		/* Only interrupts that are enabled */
 		pending &= enabled;
 
-		for_each_set_bit(gpio, &pending, 32) {
-			unsigned int irq;
-
-			irq = irq_find_mapping(gc->irq.domain, base + gpio);
-			generic_handle_irq(irq);
-		}
+		for_each_set_bit(gpio, &pending, 32)
+			generic_handle_domain_irq(gc->irq.domain, base + gpio);
 	}
 
 	chained_irq_exit(irqchip, desc);
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 4b9157a69fca..d05fd81dca72 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -120,7 +120,7 @@ static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *data)
 	mask = gc->read_reg(mpc8xxx_gc->regs + GPIO_IER)
 		& gc->read_reg(mpc8xxx_gc->regs + GPIO_IMR);
 	for_each_set_bit(i, &mask, 32)
-		generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq, 31 - i));
+		generic_handle_domain_irq(mpc8xxx_gc->irq, 31 - i);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
index 82fb20dca53a..10c0a9bc5ea1 100644
--- a/drivers/gpio/gpio-mt7621.c
+++ b/drivers/gpio/gpio-mt7621.c
@@ -95,9 +95,7 @@ mediatek_gpio_irq_handler(int irq, void *data)
 	pending = mtk_gpio_r32(rg, GPIO_REG_STAT);
 
 	for_each_set_bit(bit, &pending, MTK_BANK_WIDTH) {
-		u32 map = irq_find_mapping(gc->irq.domain, bit);
-
-		generic_handle_irq(map);
+		generic_handle_domain_irq(gc->irq.domain, bit);
 		mtk_gpio_w32(rg, GPIO_REG_STAT, BIT(bit));
 		ret |= IRQ_HANDLED;
 	}
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 157106e1e438..77ad0e130e73 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -241,7 +241,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
 		if (port->both_edges & (1 << irqoffset))
 			mxc_flip_edge(port, irqoffset);
 
-		generic_handle_irq(irq_find_mapping(port->domain, irqoffset));
+		generic_handle_domain_irq(port->domain, irqoffset);
 
 		irq_stat &= ~(1 << irqoffset);
 	}
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 524b668eb1ac..cc6b7101ef9d 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -157,7 +157,7 @@ static void mxs_gpio_irq_handler(struct irq_desc *desc)
 		if (port->both_edges & (1 << irqoffset))
 			mxs_flip_edge(port, irqoffset);
 
-		generic_handle_irq(irq_find_mapping(port->domain, irqoffset));
+		generic_handle_domain_irq(port->domain, irqoffset);
 		irq_stat &= ~(1 << irqoffset);
 	}
 }
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index ca23f72165ca..415e8df89d6f 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -611,8 +611,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
 
 			raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags);
 
-			generic_handle_irq(irq_find_mapping(bank->chip.irq.domain,
-							    bit));
+			generic_handle_domain_irq(bank->chip.irq.domain, bit);
 
 			raw_spin_unlock_irqrestore(&bank->wa_lock,
 						   wa_lock_flags);
diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c
index 9acec76e0b51..71a13a394050 100644
--- a/drivers/gpio/gpio-pci-idio-16.c
+++ b/drivers/gpio/gpio-pci-idio-16.c
@@ -260,7 +260,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id)
 		return IRQ_NONE;
 
 	for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio)
-		generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio));
+		generic_handle_domain_irq(chip->irq.domain, gpio);
 
 	raw_spin_lock(&idio16gpio->lock);
 
diff --git a/drivers/gpio/gpio-pcie-idio-24.c b/drivers/gpio/gpio-pcie-idio-24.c
index 2a07fd96707e..8a9b98fa418f 100644
--- a/drivers/gpio/gpio-pcie-idio-24.c
+++ b/drivers/gpio/gpio-pcie-idio-24.c
@@ -468,8 +468,7 @@ static irqreturn_t idio_24_irq_handler(int irq, void *dev_id)
 	irq_mask = idio24gpio->irq_mask & irq_status;
 
 	for_each_set_bit(gpio, &irq_mask, chip->ngpio - 24)
-		generic_handle_irq(irq_find_mapping(chip->irq.domain,
-			gpio + 24));
+		generic_handle_domain_irq(chip->irq.domain, gpio + 24);
 
 	raw_spin_lock(&idio24gpio->lock);
 
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index f1b53dd1df1a..4ecab700f23f 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -223,8 +223,8 @@ static void pl061_irq_handler(struct irq_desc *desc)
 	pending = readb(pl061->base + GPIOMIS);
 	if (pending) {
 		for_each_set_bit(offset, &pending, PL061_GPIO_NR)
-			generic_handle_irq(irq_find_mapping(gc->irq.domain,
-							    offset));
+			generic_handle_domain_irq(gc->irq.domain,
+						  offset);
 	}
 
 	chained_irq_exit(irqchip, desc);
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c
index 0cb6600b8eee..382468e294e1 100644
--- a/drivers/gpio/gpio-pxa.c
+++ b/drivers/gpio/gpio-pxa.c
@@ -455,9 +455,8 @@ static irqreturn_t pxa_gpio_demux_handler(int in_irq, void *d)
 			for_each_set_bit(n, &gedr, BITS_PER_LONG) {
 				loop = 1;
 
-				generic_handle_irq(
-					irq_find_mapping(pchip->irqdomain,
-							 gpio + n));
+				generic_handle_domain_irq(pchip->irqdomain,
+							  gpio + n);
 			}
 		}
 		handled += loop;
@@ -471,9 +470,9 @@ static irqreturn_t pxa_gpio_direct_handler(int in_irq, void *d)
 	struct pxa_gpio_chip *pchip = d;
 
 	if (in_irq == pchip->irq0) {
-		generic_handle_irq(irq_find_mapping(pchip->irqdomain, 0));
+		generic_handle_domain_irq(pchip->irqdomain, 0);
 	} else if (in_irq == pchip->irq1) {
-		generic_handle_irq(irq_find_mapping(pchip->irqdomain, 1));
+		generic_handle_domain_irq(pchip->irqdomain, 1);
 	} else {
 		pr_err("%s() unknown irq %d\n", __func__, in_irq);
 		return IRQ_NONE;
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index e7092d5fe700..b378aba32602 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -213,8 +213,8 @@ static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
 			  gpio_rcar_read(p, INTMSK))) {
 		offset = __ffs(pending);
 		gpio_rcar_write(p, INTCLR, BIT(offset));
-		generic_handle_irq(irq_find_mapping(p->gpio_chip.irq.domain,
-						    offset));
+		generic_handle_domain_irq(p->gpio_chip.irq.domain,
+					  offset);
 		irqs_handled++;
 	}
 
diff --git a/drivers/gpio/gpio-rda.c b/drivers/gpio/gpio-rda.c
index 28dcbb58b76b..463846431183 100644
--- a/drivers/gpio/gpio-rda.c
+++ b/drivers/gpio/gpio-rda.c
@@ -181,7 +181,7 @@ static void rda_gpio_irq_handler(struct irq_desc *desc)
 	struct irq_chip *ic = irq_desc_get_chip(desc);
 	struct rda_gpio *rda_gpio = gpiochip_get_data(chip);
 	unsigned long status;
-	u32 n, girq;
+	u32 n;
 
 	chained_irq_enter(ic, desc);
 
@@ -189,10 +189,8 @@ static void rda_gpio_irq_handler(struct irq_desc *desc)
 	/* Only lower 8 bits are capable of generating interrupts */
 	status &= RDA_GPIO_IRQ_MASK;
 
-	for_each_set_bit(n, &status, RDA_GPIO_BANK_NR) {
-		girq = irq_find_mapping(chip->irq.domain, n);
-		generic_handle_irq(girq);
-	}
+	for_each_set_bit(n, &status, RDA_GPIO_BANK_NR)
+		generic_handle_domain_irq(chip->irq.domain, n);
 
 	chained_irq_exit(ic, desc);
 }
diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c
index cb64fb5a51aa..eeeb39bc171d 100644
--- a/drivers/gpio/gpio-realtek-otto.c
+++ b/drivers/gpio/gpio-realtek-otto.c
@@ -196,7 +196,6 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc)
 	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
 	unsigned int lines_done;
 	unsigned int port_pin_count;
-	unsigned int irq;
 	unsigned long status;
 	int offset;
 
@@ -205,10 +204,8 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc)
 	for (lines_done = 0; lines_done < gc->ngpio; lines_done += 8) {
 		status = realtek_gpio_read_isr(ctrl, lines_done / 8);
 		port_pin_count = min(gc->ngpio - lines_done, 8U);
-		for_each_set_bit(offset, &status, port_pin_count) {
-			irq = irq_find_mapping(gc->irq.domain, offset);
-			generic_handle_irq(irq);
-		}
+		for_each_set_bit(offset, &status, port_pin_count)
+			generic_handle_domain_irq(gc->irq.domain, offset);
 	}
 
 	chained_irq_exit(irq_chip, desc);
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
index a6f0421d6e50..0600f71462b5 100644
--- a/drivers/gpio/gpio-sch.c
+++ b/drivers/gpio/gpio-sch.c
@@ -259,7 +259,7 @@ static u32 sch_gpio_gpe_handler(acpi_handle gpe_device, u32 gpe, void *context)
 
 	pending = (resume_status << sch->resume_base) | core_status;
 	for_each_set_bit(offset, &pending, sch->chip.ngpio)
-		generic_handle_irq(irq_find_mapping(gc->irq.domain, offset));
+		generic_handle_domain_irq(gc->irq.domain, offset);
 
 	/* Set returning value depending on whether we handled an interrupt */
 	ret = pending ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
diff --git a/drivers/gpio/gpio-sodaville.c b/drivers/gpio/gpio-sodaville.c
index aed988e78251..c2a2c76c1652 100644
--- a/drivers/gpio/gpio-sodaville.c
+++ b/drivers/gpio/gpio-sodaville.c
@@ -84,7 +84,7 @@ static irqreturn_t sdv_gpio_pub_irq_handler(int irq, void *data)
 		return IRQ_NONE;
 
 	for_each_set_bit(irq_bit, &irq_stat, 32)
-		generic_handle_irq(irq_find_mapping(sd->id, irq_bit));
+		generic_handle_domain_irq(sd->id, irq_bit);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/gpio/gpio-sprd.c b/drivers/gpio/gpio-sprd.c
index 36ea8a3bd451..fe023f4060fc 100644
--- a/drivers/gpio/gpio-sprd.c
+++ b/drivers/gpio/gpio-sprd.c
@@ -189,7 +189,7 @@ static void sprd_gpio_irq_handler(struct irq_desc *desc)
 	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
 	struct irq_chip *ic = irq_desc_get_chip(desc);
 	struct sprd_gpio *sprd_gpio = gpiochip_get_data(chip);
-	u32 bank, n, girq;
+	u32 bank, n;
 
 	chained_irq_enter(ic, desc);
 
@@ -198,13 +198,9 @@ static void sprd_gpio_irq_handler(struct irq_desc *desc)
 		unsigned long reg = readl_relaxed(base + SPRD_GPIO_MIS) &
 			SPRD_GPIO_BANK_MASK;
 
-		for_each_set_bit(n, &reg, SPRD_GPIO_BANK_NR) {
-			girq = irq_find_mapping(chip->irq.domain,
-						bank * SPRD_GPIO_BANK_NR + n);
-
-			generic_handle_irq(girq);
-		}
-
+		for_each_set_bit(n, &reg, SPRD_GPIO_BANK_NR)
+			generic_handle_domain_irq(chip->irq.domain,
+						  bank * SPRD_GPIO_BANK_NR + n);
 	}
 	chained_irq_exit(ic, desc);
 }
diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c
index 866201cf5f65..718a508d3b2f 100644
--- a/drivers/gpio/gpio-tb10x.c
+++ b/drivers/gpio/gpio-tb10x.c
@@ -100,7 +100,7 @@ static irqreturn_t tb10x_gpio_irq_cascade(int irq, void *data)
 	int i;
 
 	for_each_set_bit(i, &bits, 32)
-		generic_handle_irq(irq_find_mapping(tb10x_gpio->domain, i));
+		generic_handle_domain_irq(tb10x_gpio->domain, i);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 0025f613d9b3..7f5bc10a6479 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -408,6 +408,8 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc)
 		lvl = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio));
 
 		for_each_set_bit(pin, &sta, 8) {
+			int ret;
+
 			tegra_gpio_writel(tgi, 1 << pin,
 					  GPIO_INT_CLR(tgi, gpio));
 
@@ -420,11 +422,8 @@ static void tegra_gpio_irq_handler(struct irq_desc *desc)
 				chained_irq_exit(chip, desc);
 			}
 
-			irq = irq_find_mapping(domain, gpio + pin);
-			if (WARN_ON(irq == 0))
-				continue;
-
-			generic_handle_irq(irq);
+			ret = generic_handle_domain_irq(domain, gpio + pin);
+			WARN_RATELIMIT(ret, "hwirq = %d", gpio + pin);
 		}
 	}
 
diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c
index 1bd9e44df718..362ef16929c3 100644
--- a/drivers/gpio/gpio-tegra186.c
+++ b/drivers/gpio/gpio-tegra186.c
@@ -466,7 +466,7 @@ static void tegra186_gpio_irq(struct irq_desc *desc)
 
 	for (i = 0; i < gpio->soc->num_ports; i++) {
 		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
-		unsigned int pin, irq;
+		unsigned int pin;
 		unsigned long value;
 		void __iomem *base;
 
@@ -479,11 +479,8 @@ static void tegra186_gpio_irq(struct irq_desc *desc)
 		value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1));
 
 		for_each_set_bit(pin, &value, port->pins) {
-			irq = irq_find_mapping(domain, offset + pin);
-			if (WARN_ON(irq == 0))
-				continue;
-
-			generic_handle_irq(irq);
+			int ret = generic_handle_domain_irq(domain, offset + pin);
+			WARN_RATELIMIT(ret, "hwirq = %d", offset + pin);
 		}
 
 skip:
diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c
index 5022e0ad0fae..e80ff42e94d0 100644
--- a/drivers/gpio/gpio-tqmx86.c
+++ b/drivers/gpio/gpio-tqmx86.c
@@ -183,7 +183,7 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
 	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
 	unsigned long irq_bits;
-	int i = 0, child_irq;
+	int i = 0;
 	u8 irq_status;
 
 	chained_irq_enter(irq_chip, desc);
@@ -192,11 +192,9 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
 	tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 
 	irq_bits = irq_status;
-	for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
-		child_irq = irq_find_mapping(gpio->chip.irq.domain,
-					     i + TQMX86_NGPO);
-		generic_handle_irq(child_irq);
-	}
+	for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
+		generic_handle_domain_irq(gpio->chip.irq.domain,
+					  i + TQMX86_NGPO);
 
 	chained_irq_exit(irq_chip, desc);
 }
diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
index 58776f2d69ff..e0f2b67558e7 100644
--- a/drivers/gpio/gpio-vf610.c
+++ b/drivers/gpio/gpio-vf610.c
@@ -149,7 +149,7 @@ static void vf610_gpio_irq_handler(struct irq_desc *desc)
 	for_each_set_bit(pin, &irq_isfr, VF610_GPIO_PER_PORT) {
 		vf610_gpio_writel(BIT(pin), port->base + PORT_ISFR);
 
-		generic_handle_irq(irq_find_mapping(port->gc.irq.domain, pin));
+		generic_handle_domain_irq(port->gc.irq.domain, pin);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c
index 2d89d0529135..bb02a82e22f4 100644
--- a/drivers/gpio/gpio-ws16c48.c
+++ b/drivers/gpio/gpio-ws16c48.c
@@ -339,8 +339,8 @@ static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)
 		for_each_set_bit(port, &int_pending, 3) {
 			int_id = inb(ws16c48gpio->base + 8 + port);
 			for_each_set_bit(gpio, &int_id, 8)
-				generic_handle_irq(irq_find_mapping(
-					chip->irq.domain, gpio + 8*port));
+				generic_handle_domain_irq(chip->irq.domain,
+							  gpio + 8*port);
 		}
 
 		int_pending = inb(ws16c48gpio->base + 6) & 0x7;
diff --git a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c
index ad5489a65d54..fa9b4d8c3ff5 100644
--- a/drivers/gpio/gpio-xgs-iproc.c
+++ b/drivers/gpio/gpio-xgs-iproc.c
@@ -185,7 +185,7 @@ static irqreturn_t iproc_gpio_irq_handler(int irq, void *data)
 		int_bits = level | event;
 
 		for_each_set_bit(bit, &int_bits, gc->ngpio)
-			generic_handle_irq(irq_linear_revmap(gc->irq.domain, bit));
+			generic_handle_domain_irq(gc->irq.domain, bit);
 	}
 
 	return int_bits ? IRQ_HANDLED : IRQ_NONE;
diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c
index b411d3156e0b..f73b1d87a9d5 100644
--- a/drivers/gpio/gpio-xilinx.c
+++ b/drivers/gpio/gpio-xilinx.c
@@ -509,7 +509,6 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 			unsigned long rising_events, falling_events, all_events;
 			unsigned long flags;
 			u32 data, bit;
-			unsigned int irq;
 
 			spin_lock_irqsave(&chip->gpio_lock, flags);
 			data = xgpio_readreg(chip->regs + XGPIO_DATA_OFFSET +
@@ -529,11 +528,9 @@ static void xgpio_irqhandler(struct irq_desc *desc)
 			chip->gpio_last_irq_read[index] = data;
 			spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
-			for_each_set_bit(bit, &all_events, 32) {
-				irq = irq_find_mapping(chip->gc.irq.domain,
-						       offset + bit);
-				generic_handle_irq(irq);
-			}
+			for_each_set_bit(bit, &all_events, 32)
+				generic_handle_domain_irq(chip->gc.irq.domain,
+							  offset + bit);
 		}
 		offset += chip->gpio_width[index];
 	}
diff --git a/drivers/gpio/gpio-xlp.c b/drivers/gpio/gpio-xlp.c
index d7b16bb9e4e4..0d94d3aef752 100644
--- a/drivers/gpio/gpio-xlp.c
+++ b/drivers/gpio/gpio-xlp.c
@@ -216,8 +216,7 @@ static void xlp_gpio_generic_handler(struct irq_desc *desc)
 		}
 
 		if (gpio_stat & BIT(gpio % XLP_GPIO_REGSZ))
-			generic_handle_irq(irq_find_mapping(
-						priv->chip.irq.domain, gpio));
+			generic_handle_domain_irq(priv->chip.irq.domain, gpio);
 	}
 	chained_irq_exit(irqchip, desc);
 }
diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
index 3521c1dc3ac0..cc6d7b84c81b 100644
--- a/drivers/gpio/gpio-zynq.c
+++ b/drivers/gpio/gpio-zynq.c
@@ -628,12 +628,8 @@ static void zynq_gpio_handle_bank_irq(struct zynq_gpio *gpio,
 	if (!pending)
 		return;
 
-	for_each_set_bit(offset, &pending, 32) {
-		unsigned int gpio_irq;
-
-		gpio_irq = irq_find_mapping(irqdomain, offset + bank_offset);
-		generic_handle_irq(gpio_irq);
-	}
+	for_each_set_bit(offset, &pending, 32)
+		generic_handle_domain_irq(irqdomain, offset + bank_offset);
 }
 
 /**
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 29/39] pinctrl: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (27 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 28/39] gpio: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-21 21:16   ` Krzysztof Kozlowski
  2021-05-20 16:37 ` [PATCH 30/39] PCI: " Marc Zyngier
                   ` (11 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/pinctrl/actions/pinctrl-owl.c      |  5 ++---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c      |  4 ++--
 drivers/pinctrl/bcm/pinctrl-iproc-gpio.c   |  3 +--
 drivers/pinctrl/bcm/pinctrl-nsp-gpio.c     |  3 +--
 drivers/pinctrl/intel/pinctrl-baytrail.c   |  7 ++----
 drivers/pinctrl/intel/pinctrl-cherryview.c |  5 ++---
 drivers/pinctrl/intel/pinctrl-lynxpoint.c  |  8 ++-----
 drivers/pinctrl/mediatek/mtk-eint.c        |  5 ++---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c  |  2 +-
 drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c  |  2 +-
 drivers/pinctrl/pinctrl-amd.c              |  6 ++----
 drivers/pinctrl/pinctrl-at91.c             |  6 ++----
 drivers/pinctrl/pinctrl-equilibrium.c      |  2 +-
 drivers/pinctrl/pinctrl-ingenic.c          |  2 +-
 drivers/pinctrl/pinctrl-microchip-sgpio.c  |  2 +-
 drivers/pinctrl/pinctrl-ocelot.c           |  3 +--
 drivers/pinctrl/pinctrl-oxnas.c            |  2 +-
 drivers/pinctrl/pinctrl-pic32.c            |  2 +-
 drivers/pinctrl/pinctrl-pistachio.c        |  2 +-
 drivers/pinctrl/pinctrl-rockchip.c         | 15 +++++--------
 drivers/pinctrl/pinctrl-single.c           |  4 ++--
 drivers/pinctrl/pinctrl-st.c               |  2 +-
 drivers/pinctrl/qcom/pinctrl-msm.c         |  4 +---
 drivers/pinctrl/samsung/pinctrl-exynos.c   | 15 ++++++-------
 drivers/pinctrl/samsung/pinctrl-s3c24xx.c  | 25 +++++++++-------------
 drivers/pinctrl/samsung/pinctrl-s3c64xx.c  | 17 ++++++---------
 drivers/pinctrl/spear/pinctrl-plgpio.c     |  3 +--
 drivers/pinctrl/sunxi/pinctrl-sunxi.c      |  8 +++----
 28 files changed, 64 insertions(+), 100 deletions(-)

diff --git a/drivers/pinctrl/actions/pinctrl-owl.c b/drivers/pinctrl/actions/pinctrl-owl.c
index c8b3e396ea27..781f2200ed58 100644
--- a/drivers/pinctrl/actions/pinctrl-owl.c
+++ b/drivers/pinctrl/actions/pinctrl-owl.c
@@ -833,7 +833,7 @@ static void owl_gpio_irq_handler(struct irq_desc *desc)
 	unsigned int parent = irq_desc_get_irq(desc);
 	const struct owl_gpio_port *port;
 	void __iomem *base;
-	unsigned int pin, irq, offset = 0, i;
+	unsigned int pin, offset = 0, i;
 	unsigned long pending_irq;
 
 	chained_irq_enter(chip, desc);
@@ -849,8 +849,7 @@ static void owl_gpio_irq_handler(struct irq_desc *desc)
 		pending_irq = readl_relaxed(base + port->intc_pd);
 
 		for_each_set_bit(pin, &pending_irq, port->pins) {
-			irq = irq_find_mapping(domain, offset + pin);
-			generic_handle_irq(irq);
+			generic_handle_domain_irq(domain, offset + pin);
 
 			/* clear pending interrupt */
 			owl_gpio_update_reg(base + port->intc_pd, pin, true);
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 1d21129f7751..fd8db72aa01e 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -395,8 +395,8 @@ static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
 	events &= pc->enabled_irq_map[bank];
 	for_each_set_bit(offset, &events, 32) {
 		gpio = (32 * bank) + offset;
-		generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irq.domain,
-						     gpio));
+		generic_handle_domain_irq(pc->gpio_chip.irq.domain,
+					  gpio);
 	}
 }
 
diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
index e2bd2dce6bb4..be3918a0d250 100644
--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
@@ -176,7 +176,6 @@ static void iproc_gpio_irq_handler(struct irq_desc *desc)
 
 		for_each_set_bit(bit, &val, NGPIOS_PER_BANK) {
 			unsigned pin = NGPIOS_PER_BANK * i + bit;
-			int child_irq = irq_find_mapping(gc->irq.domain, pin);
 
 			/*
 			 * Clear the interrupt before invoking the
@@ -185,7 +184,7 @@ static void iproc_gpio_irq_handler(struct irq_desc *desc)
 			writel(BIT(bit), chip->base + (i * GPIO_BANK_SIZE) +
 			       IPROC_GPIO_INT_CLR_OFFSET);
 
-			generic_handle_irq(child_irq);
+			generic_handle_domain_irq(gc->irq.domain, pin);
 		}
 	}
 
diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
index a00a42a61a90..e03142895f61 100644
--- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
+++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
@@ -155,8 +155,7 @@ static irqreturn_t nsp_gpio_irq_handler(int irq, void *data)
 		int_bits = level | event;
 
 		for_each_set_bit(bit, &int_bits, gc->ngpio)
-			generic_handle_irq(
-				irq_linear_revmap(gc->irq.domain, bit));
+			generic_handle_domain_irq(gc->irq.domain, bit);
 	}
 
 	return  int_bits ? IRQ_HANDLED : IRQ_NONE;
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index 394a421a19d5..8f23d126c6a7 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -1444,7 +1444,6 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
 	u32 base, pin;
 	void __iomem *reg;
 	unsigned long pending;
-	unsigned int virq;
 
 	/* check from GPIO controller which pin triggered the interrupt */
 	for (base = 0; base < vg->chip.ngpio; base += 32) {
@@ -1460,10 +1459,8 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
 		raw_spin_lock(&byt_lock);
 		pending = readl(reg);
 		raw_spin_unlock(&byt_lock);
-		for_each_set_bit(pin, &pending, 32) {
-			virq = irq_find_mapping(vg->chip.irq.domain, base + pin);
-			generic_handle_irq(virq);
-		}
+		for_each_set_bit(pin, &pending, 32)
+			generic_handle_domain_irq(vg->chip.irq.domain, base + pin);
 	}
 	chip->irq_eoi(data);
 }
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
index 2ed17cdf946d..980099028cf8 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -1409,11 +1409,10 @@ static void chv_gpio_irq_handler(struct irq_desc *desc)
 	raw_spin_unlock_irqrestore(&chv_lock, flags);
 
 	for_each_set_bit(intr_line, &pending, community->nirqs) {
-		unsigned int irq, offset;
+		unsigned int offset;
 
 		offset = cctx->intr_lines[intr_line];
-		irq = irq_find_mapping(gc->irq.domain, offset);
-		generic_handle_irq(irq);
+		generic_handle_domain_irq(gc->irq.domain, offset);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
index 0a48ca46ab59..561fa322b0b4 100644
--- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c
+++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c
@@ -653,12 +653,8 @@ static void lp_gpio_irq_handler(struct irq_desc *desc)
 		/* Only interrupts that are enabled */
 		pending = ioread32(reg) & ioread32(ena);
 
-		for_each_set_bit(pin, &pending, 32) {
-			unsigned int irq;
-
-			irq = irq_find_mapping(lg->chip.irq.domain, base + pin);
-			generic_handle_irq(irq);
-		}
+		for_each_set_bit(pin, &pending, 32)
+			generic_handle_domain_irq(lg->chip.irq.domain, base + pin);
 	}
 	chip->irq_eoi(data);
 }
diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
index 3b9b5dbd7968..f7b54a551764 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.c
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -319,7 +319,7 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct mtk_eint *eint = irq_desc_get_handler_data(desc);
 	unsigned int status, eint_num;
-	int offset, mask_offset, index, virq;
+	int offset, mask_offset, index;
 	void __iomem *reg =  mtk_eint_get_offset(eint, 0, eint->regs->stat);
 	int dual_edge, start_level, curr_level;
 
@@ -331,7 +331,6 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
 			offset = __ffs(status);
 			mask_offset = eint_num >> 5;
 			index = eint_num + offset;
-			virq = irq_find_mapping(eint->domain, index);
 			status &= ~BIT(offset);
 
 			/*
@@ -361,7 +360,7 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
 								 index);
 			}
 
-			generic_handle_irq(virq);
+			generic_handle_domain_irq(eint->domain, index);
 
 			if (dual_edge) {
 				curr_level = mtk_eint_flip_edge(eint, index);
diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index abfe11c7b49f..39828e9c3120 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -815,7 +815,7 @@ static void nmk_gpio_irq_handler(struct irq_desc *desc)
 	while (status) {
 		int bit = __ffs(status);
 
-		generic_handle_irq(irq_find_mapping(chip->irq.domain, bit));
+		generic_handle_domain_irq(chip->irq.domain, bit);
 		status &= ~BIT(bit);
 	}
 
diff --git a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
index 2535ca720668..8afc8839fe69 100644
--- a/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
+++ b/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c
@@ -231,7 +231,7 @@ static void npcmgpio_irq_handler(struct irq_desc *desc)
 
 	sts &= en;
 	for_each_set_bit(bit, (const void *)&sts, NPCM7XX_GPIO_PER_BANK)
-		generic_handle_irq(irq_linear_revmap(gc->irq.domain, bit));
+		generic_handle_domain_irq(gc->irq.domain, bit);
 	chained_irq_exit(chip, desc);
 }
 
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 2d4acf21117c..386217012003 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -591,14 +591,12 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 			if (!(regval & PIN_IRQ_PENDING) ||
 			    !(regval & BIT(INTERRUPT_MASK_OFF)))
 				continue;
-			irq = irq_find_mapping(gc->irq.domain, irqnr + i);
-			if (irq != 0)
-				generic_handle_irq(irq);
+			generic_handle_domain_irq(gc->irq.domain, irqnr + i);
 
 			/* Clear interrupt.
 			 * We must read the pin register again, in case the
 			 * value was changed while executing
-			 * generic_handle_irq() above.
+			 * generic_handle_domain_irq() above.
 			 * If we didn't find a mapping for the interrupt,
 			 * disable it in order to avoid a system hang caused
 			 * by an interrupt storm.
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index fc61aaec34cc..50ff37cdee3f 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -1712,10 +1712,8 @@ static void gpio_irq_handler(struct irq_desc *desc)
 			continue;
 		}
 
-		for_each_set_bit(n, &isr, BITS_PER_LONG) {
-			generic_handle_irq(irq_find_mapping(
-					   gpio_chip->irq.domain, n));
-		}
+		for_each_set_bit(n, &isr, BITS_PER_LONG)
+			generic_handle_domain_irq(gpio_chip->irq.domain, n);
 	}
 	chained_irq_exit(chip, desc);
 	/* now it may re-trigger */
diff --git a/drivers/pinctrl/pinctrl-equilibrium.c b/drivers/pinctrl/pinctrl-equilibrium.c
index a194d8089b6f..da218b23985e 100644
--- a/drivers/pinctrl/pinctrl-equilibrium.c
+++ b/drivers/pinctrl/pinctrl-equilibrium.c
@@ -155,7 +155,7 @@ static void eqbr_irq_handler(struct irq_desc *desc)
 	pins = readl(gctrl->membase + GPIO_IRNCR);
 
 	for_each_set_bit(offset, &pins, gc->ngpio)
-		generic_handle_irq(irq_find_mapping(gc->irq.domain, offset));
+		generic_handle_domain_irq(gc->irq.domain, offset);
 
 	chained_irq_exit(ic, desc);
 }
diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
index 983ba9865f77..ce9cc719c395 100644
--- a/drivers/pinctrl/pinctrl-ingenic.c
+++ b/drivers/pinctrl/pinctrl-ingenic.c
@@ -3080,7 +3080,7 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc)
 		flag = ingenic_gpio_read_reg(jzgc, JZ4730_GPIO_GPFR);
 
 	for_each_set_bit(i, &flag, 32)
-		generic_handle_irq(irq_linear_revmap(gc->irq.domain, i));
+		generic_handle_domain_irq(gc->irq.domain, i);
 	chained_irq_exit(irq_chip, desc);
 }
 
diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
index c12fa57ebd12..51f81976c136 100644
--- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
+++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
@@ -673,7 +673,7 @@ static void sgpio_irq_handler(struct irq_desc *desc)
 
 		for_each_set_bit(port, &val, SGPIO_BITS_PER_WORD) {
 			gpio = sgpio_addr_to_pin(priv, port, bit);
-			generic_handle_irq(irq_linear_revmap(chip->irq.domain, gpio));
+			generic_handle_domain_irq(chip->irq.domain, gpio);
 		}
 
 		chained_irq_exit(parent_chip, desc);
diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
index 2fd18e356d0c..c15d7c8593ab 100644
--- a/drivers/pinctrl/pinctrl-ocelot.c
+++ b/drivers/pinctrl/pinctrl-ocelot.c
@@ -1290,8 +1290,7 @@ static void ocelot_irq_handler(struct irq_desc *desc)
 
 		for_each_set_bit(irq, &irqs,
 				 min(32U, info->desc->npins - 32 * i))
-			generic_handle_irq(irq_linear_revmap(chip->irq.domain,
-							     irq + 32 * i));
+			generic_handle_domain_irq(chip->irq.domain, irq + 32 * i);
 
 		chained_irq_exit(parent_chip, desc);
 	}
diff --git a/drivers/pinctrl/pinctrl-oxnas.c b/drivers/pinctrl/pinctrl-oxnas.c
index 5a312279b3c7..cebd810bd6d1 100644
--- a/drivers/pinctrl/pinctrl-oxnas.c
+++ b/drivers/pinctrl/pinctrl-oxnas.c
@@ -1055,7 +1055,7 @@ static void oxnas_gpio_irq_handler(struct irq_desc *desc)
 	stat = readl(bank->reg_base + IRQ_PENDING);
 
 	for_each_set_bit(pin, &stat, BITS_PER_LONG)
-		generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin));
+		generic_handle_domain_irq(gc->irq.domain, pin);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/pinctrl/pinctrl-pic32.c b/drivers/pinctrl/pinctrl-pic32.c
index a6e2a4a4ca95..748dabd8db6e 100644
--- a/drivers/pinctrl/pinctrl-pic32.c
+++ b/drivers/pinctrl/pinctrl-pic32.c
@@ -2101,7 +2101,7 @@ static void pic32_gpio_irq_handler(struct irq_desc *desc)
 	pending = pic32_gpio_get_pending(gc, stat);
 
 	for_each_set_bit(pin, &pending, BITS_PER_LONG)
-		generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin));
+		generic_handle_domain_irq(gc->irq.domain, pin);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c
index ec761ba2a2da..8d271c6b0ca4 100644
--- a/drivers/pinctrl/pinctrl-pistachio.c
+++ b/drivers/pinctrl/pinctrl-pistachio.c
@@ -1306,7 +1306,7 @@ static void pistachio_gpio_irq_handler(struct irq_desc *desc)
 	pending = gpio_readl(bank, GPIO_INTERRUPT_STATUS) &
 		gpio_readl(bank, GPIO_INTERRUPT_EN);
 	for_each_set_bit(pin, &pending, 16)
-		generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin));
+		generic_handle_domain_irq(gc->irq.domain, pin);
 	chained_irq_exit(chip, desc);
 }
 
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 067fc4208de4..d67aa53d0dce 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -2951,18 +2951,11 @@ static void rockchip_irq_demux(struct irq_desc *desc)
 	pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS);
 
 	while (pend) {
-		unsigned int irq, virq;
+		unsigned int irq;
+		int ret;
 
 		irq = __ffs(pend);
 		pend &= ~BIT(irq);
-		virq = irq_find_mapping(bank->domain, irq);
-
-		if (!virq) {
-			dev_err(bank->drvdata->dev, "unmapped irq %d\n", irq);
-			continue;
-		}
-
-		dev_dbg(bank->drvdata->dev, "handling irq %d\n", irq);
 
 		/*
 		 * Triggering IRQ on both rising and falling edge
@@ -2993,7 +2986,9 @@ static void rockchip_irq_demux(struct irq_desc *desc)
 			} while ((data & BIT(irq)) != (data_old & BIT(irq)));
 		}
 
-		generic_handle_irq(virq);
+		ret = generic_handle_domain_irq(bank->domain, irq);
+		if (unlikely(ret))
+			dev_err_ratelimited(bank->drvdata->dev, "unmapped irq %d\n", irq);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 2c9c9835f375..bd318571e4f8 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -1488,8 +1488,8 @@ static int pcs_irq_handle(struct pcs_soc_data *pcs_soc)
 		mask = pcs->read(pcswi->reg);
 		raw_spin_unlock(&pcs->lock);
 		if (mask & pcs_soc->irq_status_mask) {
-			generic_handle_irq(irq_find_mapping(pcs->domain,
-							    pcswi->hwirq));
+			generic_handle_domain_irq(pcs->domain,
+						  pcswi->hwirq);
 			count++;
 		}
 	}
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index 43d9e6c7fd81..fa3edb4b898a 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -1420,7 +1420,7 @@ static void __gpio_irq_handler(struct st_gpio_bank *bank)
 					continue;
 			}
 
-			generic_handle_irq(irq_find_mapping(bank->gpio_chip.irq.domain, n));
+			generic_handle_domain_irq(bank->gpio_chip.irq.domain, n);
 		}
 	}
 }
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index d70caecd21d2..8476a8ac4451 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1177,7 +1177,6 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)
 	const struct msm_pingroup *g;
 	struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int irq_pin;
 	int handled = 0;
 	u32 val;
 	int i;
@@ -1192,8 +1191,7 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)
 		g = &pctrl->soc->groups[i];
 		val = msm_readl_intr_status(pctrl, g);
 		if (val & BIT(g->intr_status_bit)) {
-			irq_pin = irq_find_mapping(gc->irq.domain, i);
-			generic_handle_irq(irq_pin);
+			generic_handle_domain_irq(gc->irq.domain, i);
 			handled++;
 		}
 	}
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 2b99f4130e1e..0489c899b401 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -246,7 +246,8 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
 {
 	struct samsung_pinctrl_drv_data *d = data;
 	struct samsung_pin_bank *bank = d->pin_banks;
-	unsigned int svc, group, pin, virq;
+	unsigned int svc, group, pin;
+	int ret;
 
 	svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
 	group = EXYNOS_SVC_GROUP(svc);
@@ -256,10 +257,10 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
 		return IRQ_HANDLED;
 	bank += (group - 1);
 
-	virq = irq_linear_revmap(bank->irq_domain, pin);
-	if (!virq)
+	ret = generic_handle_domain_irq(bank->irq_domain, pin);
+	if (ret)
 		return IRQ_NONE;
-	generic_handle_irq(virq);
+
 	return IRQ_HANDLED;
 }
 
@@ -473,12 +474,10 @@ static void exynos_irq_eint0_15(struct irq_desc *desc)
 	struct exynos_weint_data *eintd = irq_desc_get_handler_data(desc);
 	struct samsung_pin_bank *bank = eintd->bank;
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int eint_irq;
 
 	chained_irq_enter(chip, desc);
 
-	eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
-	generic_handle_irq(eint_irq);
+	generic_handle_domain_irq(bank->irq_domain, eintd->irq);
 
 	chained_irq_exit(chip, desc);
 }
@@ -490,7 +489,7 @@ static inline void exynos_irq_demux_eint(unsigned int pend,
 
 	while (pend) {
 		irq = fls(pend) - 1;
-		generic_handle_irq(irq_find_mapping(domain, irq));
+		generic_handle_domain_irq(domain, irq);
 		pend &= ~(1 << irq);
 	}
 }
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
index 00d77d6946b5..ac1eba30cf40 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
@@ -234,14 +234,12 @@ static void s3c2410_demux_eint0_3(struct irq_desc *desc)
 {
 	struct irq_data *data = irq_desc_get_irq_data(desc);
 	struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc);
-	unsigned int virq;
+	int ret;
 
 	/* the first 4 eints have a simple 1 to 1 mapping */
-	virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
+	ret = generic_handle_domain_irq(eint_data->domains[data->hwirq], data->hwirq);
 	/* Something must be really wrong if an unmapped EINT is unmasked */
-	BUG_ON(!virq);
-
-	generic_handle_irq(virq);
+	BUG_ON(ret);
 }
 
 /* Handling of EINTs 0-3 on S3C2412 and S3C2413 */
@@ -290,16 +288,14 @@ static void s3c2412_demux_eint0_3(struct irq_desc *desc)
 	struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc);
 	struct irq_data *data = irq_desc_get_irq_data(desc);
 	struct irq_chip *chip = irq_data_get_irq_chip(data);
-	unsigned int virq;
+	int ret;
 
 	chained_irq_enter(chip, desc);
 
 	/* the first 4 eints have a simple 1 to 1 mapping */
-	virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq);
+	ret = generic_handle_domain_irq(eint_data->domains[data->hwirq], data->hwirq);
 	/* Something must be really wrong if an unmapped EINT is unmasked */
-	BUG_ON(!virq);
-
-	generic_handle_irq(virq);
+	BUG_ON(ret);
 
 	chained_irq_exit(chip, desc);
 }
@@ -364,15 +360,14 @@ static inline void s3c24xx_demux_eint(struct irq_desc *desc,
 	pend &= range;
 
 	while (pend) {
-		unsigned int virq, irq;
+		unsigned int irq;
+		int ret;
 
 		irq = __ffs(pend);
 		pend &= ~(1 << irq);
-		virq = irq_linear_revmap(data->domains[irq], irq - offset);
+		ret = generic_handle_domain_irq(data->domains[irq], irq - offset);
 		/* Something is really wrong if an unmapped EINT is unmasked */
-		BUG_ON(!virq);
-
-		generic_handle_irq(virq);
+		BUG_ON(ret);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
index 53e2a6412add..c5f95a1071ae 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
@@ -414,7 +414,7 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc)
 		unsigned int svc;
 		unsigned int group;
 		unsigned int pin;
-		unsigned int virq;
+		int ret;
 
 		svc = readl(drvdata->virt_base + SERVICE_REG);
 		group = SVC_GROUP(svc);
@@ -431,14 +431,12 @@ static void s3c64xx_eint_gpio_irq(struct irq_desc *desc)
 				pin -= 8;
 		}
 
-		virq = irq_linear_revmap(data->domains[group], pin);
+		ret = generic_handle_domain_irq(data->domains[group], pin);
 		/*
 		 * Something must be really wrong if an unmapped EINT
 		 * was unmasked...
 		 */
-		BUG_ON(!virq);
-
-		generic_handle_irq(virq);
+		BUG_ON(ret);
 	} while (1);
 
 	chained_irq_exit(chip, desc);
@@ -607,18 +605,17 @@ static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range)
 	pend &= range;
 
 	while (pend) {
-		unsigned int virq, irq;
+		unsigned int irq;
+		int ret;
 
 		irq = fls(pend) - 1;
 		pend &= ~(1 << irq);
-		virq = irq_linear_revmap(data->domains[irq], data->pins[irq]);
+		ret = generic_handle_domain_irq(data->domains[irq], data->pins[irq]);
 		/*
 		 * Something must be really wrong if an unmapped EINT
 		 * was unmasked...
 		 */
-		BUG_ON(!virq);
-
-		generic_handle_irq(virq);
+		BUG_ON(ret);
 	}
 
 	chained_irq_exit(chip, desc);
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c
index 1ebbc49b16f1..43bb334af1e1 100644
--- a/drivers/pinctrl/spear/pinctrl-plgpio.c
+++ b/drivers/pinctrl/spear/pinctrl-plgpio.c
@@ -400,8 +400,7 @@ static void plgpio_irq_handler(struct irq_desc *desc)
 
 			/* get correct irq line number */
 			pin = i * MAX_GPIO_PER_REG + pin;
-			generic_handle_irq(
-				irq_find_mapping(gc->irq.domain, pin));
+			generic_handle_domain_irq(gc->irq.domain, pin);
 		}
 	}
 	chained_irq_exit(irqchip, desc);
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index dc8d39ae045b..baa4058e024e 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -1149,11 +1149,9 @@ static void sunxi_pinctrl_irq_handler(struct irq_desc *desc)
 	if (val) {
 		int irqoffset;
 
-		for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
-			int pin_irq = irq_find_mapping(pctl->domain,
-						       bank * IRQ_PER_BANK + irqoffset);
-			generic_handle_irq(pin_irq);
-		}
+		for_each_set_bit(irqoffset, &val, IRQ_PER_BANK)
+			generic_handle_domain_irq(pctl->domain,
+						  bank * IRQ_PER_BANK + irqoffset);
 	}
 
 	chained_irq_exit(chip, desc);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (28 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 29/39] pinctrl: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 17:47   ` Rob Herring
  2021-05-21  8:57   ` Geert Uytterhoeven
  2021-05-20 16:37 ` [PATCH 31/39] mfd: " Marc Zyngier
                   ` (10 subsequent siblings)
  40 siblings, 2 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/pci/controller/dwc/pci-dra7xx.c        | 14 +++++---------
 drivers/pci/controller/dwc/pci-keystone.c      |  5 ++---
 .../pci/controller/dwc/pcie-designware-host.c  |  9 ++++-----
 drivers/pci/controller/dwc/pcie-uniphier.c     |  6 ++----
 .../controller/mobiveil/pcie-mobiveil-host.c   | 15 ++++++---------
 drivers/pci/controller/pci-aardvark.c          |  5 ++---
 drivers/pci/controller/pci-ftpci100.c          |  2 +-
 drivers/pci/controller/pci-tegra.c             |  8 +++-----
 drivers/pci/controller/pci-xgene-msi.c         |  9 +++------
 drivers/pci/controller/pcie-altera-msi.c       | 10 ++++------
 drivers/pci/controller/pcie-altera.c           | 10 ++++------
 drivers/pci/controller/pcie-brcmstb.c          |  9 ++++-----
 drivers/pci/controller/pcie-iproc-msi.c        |  4 +---
 drivers/pci/controller/pcie-mediatek-gen3.c    | 13 ++++---------
 drivers/pci/controller/pcie-mediatek.c         | 12 ++++--------
 drivers/pci/controller/pcie-microchip-host.c   | 18 +++++++-----------
 drivers/pci/controller/pcie-rcar-host.c        |  8 +++-----
 drivers/pci/controller/pcie-rockchip-host.c    |  8 +++-----
 drivers/pci/controller/pcie-xilinx-cpm.c       |  4 ++--
 drivers/pci/controller/pcie-xilinx-nwl.c       | 13 +++----------
 drivers/pci/controller/pcie-xilinx.c           |  9 ++++-----
 21 files changed, 71 insertions(+), 120 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index 047cfbdc1330..8f646c79bab9 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -204,7 +204,7 @@ static int dra7xx_pcie_handle_msi(struct pcie_port *pp, int index)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	unsigned long val;
-	int pos, irq;
+	int pos;
 
 	val = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS +
 				   (index * MSI_REG_CTRL_BLOCK_SIZE));
@@ -213,9 +213,8 @@ static int dra7xx_pcie_handle_msi(struct pcie_port *pp, int index)
 
 	pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, 0);
 	while (pos != MAX_MSI_IRQS_PER_CTRL) {
-		irq = irq_find_mapping(pp->irq_domain,
-				       (index * MAX_MSI_IRQS_PER_CTRL) + pos);
-		generic_handle_irq(irq);
+		generic_handle_domain_irq(pp->irq_domain,
+					  (index * MAX_MSI_IRQS_PER_CTRL) + pos);
 		pos++;
 		pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, pos);
 	}
@@ -276,11 +275,8 @@ static void dra7xx_pcie_msi_irq_handler(struct irq_desc *desc)
 	case INTB:
 	case INTC:
 	case INTD:
-		for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
-			virq = irq_find_mapping(dra7xx->irq_domain, bit);
-			if (virq)
-				generic_handle_irq(virq);
-		}
+		for_each_set_bit(bit, &reg, PCI_NUM_INTX)
+			generic_handle_domain_irq(dra7xx->irq_domain, bit);
 		break;
 	}
 
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index bde3b2824e89..7f3f26643e33 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -264,9 +264,8 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie,
 	pending = ks_pcie_app_readl(ks_pcie, IRQ_STATUS(offset));
 
 	if (BIT(0) & pending) {
-		virq = irq_linear_revmap(ks_pcie->legacy_irq_domain, offset);
-		dev_dbg(dev, ": irq: irq_offset %d, virq %d\n", offset, virq);
-		generic_handle_irq(virq);
+		dev_dbg(dev, ": irq: irq_offset %d", offset);
+		generic_handle_domain_irq(ks_pcie->legacy_irq_domain, offset);
 	}
 
 	/* EOI the INTx interrupt */
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index a608ae1fad57..d1d9b8344ec9 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -55,7 +55,7 @@ static struct msi_domain_info dw_pcie_msi_domain_info = {
 /* MSI int handler */
 irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
 {
-	int i, pos, irq;
+	int i, pos;
 	unsigned long val;
 	u32 status, num_ctrls;
 	irqreturn_t ret = IRQ_NONE;
@@ -74,10 +74,9 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
 		pos = 0;
 		while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL,
 					    pos)) != MAX_MSI_IRQS_PER_CTRL) {
-			irq = irq_find_mapping(pp->irq_domain,
-					       (i * MAX_MSI_IRQS_PER_CTRL) +
-					       pos);
-			generic_handle_irq(irq);
+			generic_handle_domain_irq(pp->irq_domain,
+						  (i * MAX_MSI_IRQS_PER_CTRL) +
+						  pos);
 			pos++;
 		}
 	}
diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c
index 7e8bad326770..4be23e540c44 100644
--- a/drivers/pci/controller/dwc/pcie-uniphier.c
+++ b/drivers/pci/controller/dwc/pcie-uniphier.c
@@ -257,10 +257,8 @@ static void uniphier_pcie_irq_handler(struct irq_desc *desc)
 	val = readl(priv->base + PCL_RCV_INTX);
 	reg = FIELD_GET(PCL_RCV_INTX_ALL_STATUS, val);
 
-	for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
-		virq = irq_linear_revmap(priv->legacy_irq_domain, bit);
-		generic_handle_irq(virq);
-	}
+	for_each_set_bit(bit, &reg, PCI_NUM_INTX)
+		generic_handle_domain_irq(priv->legacy_irq_domain, bit);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index c637de3a389b..f3547aa60140 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -92,7 +92,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 	u32 msi_data, msi_addr_lo, msi_addr_hi;
 	u32 intr_status, msi_status;
 	unsigned long shifted_status;
-	u32 bit, virq, val, mask;
+	u32 bit, val, mask;
 
 	/*
 	 * The core provides a single interrupt for both INTx/MSI messages.
@@ -114,11 +114,10 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 		shifted_status >>= PAB_INTX_START;
 		do {
 			for_each_set_bit(bit, &shifted_status, PCI_NUM_INTX) {
-				virq = irq_find_mapping(rp->intx_domain,
-							bit + 1);
-				if (virq)
-					generic_handle_irq(virq);
-				else
+				int ret;
+				ret = generic_handle_domain_irq(rp->intx_domain,
+								bit + 1);
+				if (ret)
 					dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n",
 							    bit);
 
@@ -155,9 +154,7 @@ static void mobiveil_pcie_isr(struct irq_desc *desc)
 		dev_dbg(dev, "MSI registers, data: %08x, addr: %08x:%08x\n",
 			msi_data, msi_addr_hi, msi_addr_lo);
 
-		virq = irq_find_mapping(msi->dev_domain, msi_data);
-		if (virq)
-			generic_handle_irq(virq);
+		generic_handle_domain_irq(msi->dev_domain, msi_data);
 
 		msi_status = readl_relaxed(pcie->apb_csr_base +
 					   MSI_STATUS_OFFSET);
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 051b48bd7985..82794d9aab37 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1007,7 +1007,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 {
 	u32 isr0_val, isr0_mask, isr0_status;
 	u32 isr1_val, isr1_mask, isr1_status;
-	int i, virq;
+	int i;
 
 	isr0_val = advk_readl(pcie, PCIE_ISR0_REG);
 	isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG);
@@ -1035,8 +1035,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 		advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i),
 			    PCIE_ISR1_REG);
 
-		virq = irq_find_mapping(pcie->irq_domain, i);
-		generic_handle_irq(virq);
+		generic_handle_domain_irq(pcie->irq_domain, i);
 	}
 }
 
diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c
index da3cd216da00..939478d3efcd 100644
--- a/drivers/pci/controller/pci-ftpci100.c
+++ b/drivers/pci/controller/pci-ftpci100.c
@@ -314,7 +314,7 @@ static void faraday_pci_irq_handler(struct irq_desc *desc)
 	for (i = 0; i < 4; i++) {
 		if ((irq_stat & BIT(i)) == 0)
 			continue;
-		generic_handle_irq(irq_find_mapping(p->irqdomain, i));
+		generic_handle_domain_irq(p->irqdomain, i);
 	}
 
 	chained_irq_exit(irqchip, desc);
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 8069bd9232d4..f8df16265d0f 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -1553,12 +1553,10 @@ static void tegra_pcie_msi_irq(struct irq_desc *desc)
 		while (reg) {
 			unsigned int offset = find_first_bit(&reg, 32);
 			unsigned int index = i * 32 + offset;
-			unsigned int irq;
+			int ret;
 
-			irq = irq_find_mapping(msi->domain->parent, index);
-			if (irq) {
-				generic_handle_irq(irq);
-			} else {
+			ret = generic_handle_domain_irq(msi->domain->parent, index);
+			if (ret) {
 				/*
 				 * that's weird who triggered this?
 				 * just clear it
diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c
index 1c34c897a7e2..cf3832b905e8 100644
--- a/drivers/pci/controller/pci-xgene-msi.c
+++ b/drivers/pci/controller/pci-xgene-msi.c
@@ -291,8 +291,7 @@ static void xgene_msi_isr(struct irq_desc *desc)
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct xgene_msi_group *msi_groups;
 	struct xgene_msi *xgene_msi;
-	unsigned int virq;
-	int msir_index, msir_val, hw_irq;
+	int msir_index, msir_val, hw_irq, ret;
 	u32 intr_index, grp_select, msi_grp;
 
 	chained_irq_enter(chip, desc);
@@ -330,10 +329,8 @@ static void xgene_msi_isr(struct irq_desc *desc)
 			 * CPU0
 			 */
 			hw_irq = hwirq_to_canonical_hwirq(hw_irq);
-			virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq);
-			WARN_ON(!virq);
-			if (virq != 0)
-				generic_handle_irq(virq);
+			ret = generic_handle_domain_irq(xgene_msi->inner_domain, hw_irq);
+			WARN_ON(ret);
 			msir_val &= ~(1 << intr_index);
 		}
 		grp_select &= ~(1 << msir_index);
diff --git a/drivers/pci/controller/pcie-altera-msi.c b/drivers/pci/controller/pcie-altera-msi.c
index 98aa1dccc6e6..7b1d3ebc34ec 100644
--- a/drivers/pci/controller/pcie-altera-msi.c
+++ b/drivers/pci/controller/pcie-altera-msi.c
@@ -55,7 +55,7 @@ static void altera_msi_isr(struct irq_desc *desc)
 	struct altera_msi *msi;
 	unsigned long status;
 	u32 bit;
-	u32 virq;
+	int ret;
 
 	chained_irq_enter(chip, desc);
 	msi = irq_desc_get_handler_data(desc);
@@ -65,11 +65,9 @@ static void altera_msi_isr(struct irq_desc *desc)
 			/* Dummy read from vector to clear the interrupt */
 			readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
 
-			virq = irq_find_mapping(msi->inner_domain, bit);
-			if (virq)
-				generic_handle_irq(virq);
-			else
-				dev_err(&msi->pdev->dev, "unexpected MSI\n");
+			ret = generic_handle_domain_irq(msi->inner_domain, bit);
+			if (ret)
+				dev_err_ratelimited(&msi->pdev->dev, "unexpected MSI\n");
 		}
 	}
 
diff --git a/drivers/pci/controller/pcie-altera.c b/drivers/pci/controller/pcie-altera.c
index 523bd928b380..2513e9363236 100644
--- a/drivers/pci/controller/pcie-altera.c
+++ b/drivers/pci/controller/pcie-altera.c
@@ -646,7 +646,7 @@ static void altera_pcie_isr(struct irq_desc *desc)
 	struct device *dev;
 	unsigned long status;
 	u32 bit;
-	u32 virq;
+	int ret;
 
 	chained_irq_enter(chip, desc);
 	pcie = irq_desc_get_handler_data(desc);
@@ -658,11 +658,9 @@ static void altera_pcie_isr(struct irq_desc *desc)
 			/* clear interrupts */
 			cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
 
-			virq = irq_find_mapping(pcie->irq_domain, bit);
-			if (virq)
-				generic_handle_irq(virq);
-			else
-				dev_err(dev, "unexpected IRQ, INT%d\n", bit);
+			ret = generic_handle_domain_irq(pcie->irq_domain, bit);
+			if (ret)
+				dev_err_ratelimited(dev, "unexpected IRQ, INT%d\n", bit);
 		}
 	}
 
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 08bc788d9422..cc30215f5a43 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -476,7 +476,7 @@ static struct msi_domain_info brcm_msi_domain_info = {
 static void brcm_pcie_msi_isr(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	unsigned long status, virq;
+	unsigned long status;
 	struct brcm_msi *msi;
 	struct device *dev;
 	u32 bit;
@@ -489,10 +489,9 @@ static void brcm_pcie_msi_isr(struct irq_desc *desc)
 	status >>= msi->legacy_shift;
 
 	for_each_set_bit(bit, &status, msi->nr) {
-		virq = irq_find_mapping(msi->inner_domain, bit);
-		if (virq)
-			generic_handle_irq(virq);
-		else
+		int ret;
+		ret = generic_handle_domain_irq(msi->inner_domain, bit);
+		if (ret)
 			dev_dbg(dev, "unexpected MSI\n");
 	}
 
diff --git a/drivers/pci/controller/pcie-iproc-msi.c b/drivers/pci/controller/pcie-iproc-msi.c
index eede4e8f3f75..da3db5c7c27a 100644
--- a/drivers/pci/controller/pcie-iproc-msi.c
+++ b/drivers/pci/controller/pcie-iproc-msi.c
@@ -322,7 +322,6 @@ static void iproc_msi_handler(struct irq_desc *desc)
 	struct iproc_msi *msi;
 	u32 eq, head, tail, nr_events;
 	unsigned long hwirq;
-	int virq;
 
 	chained_irq_enter(chip, desc);
 
@@ -358,8 +357,7 @@ static void iproc_msi_handler(struct irq_desc *desc)
 		/* process all outstanding events */
 		while (nr_events--) {
 			hwirq = decode_msi_hwirq(msi, eq, head);
-			virq = irq_find_mapping(msi->inner_domain, hwirq);
-			generic_handle_irq(virq);
+			generic_handle_domain_irq(msi->inner_domain, hwirq);
 
 			head++;
 			head %= EQ_LEN;
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index 3c5b97716d40..c26abf66d4f8 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -645,7 +645,6 @@ static void mtk_pcie_msi_handler(struct mtk_pcie_port *port, int set_idx)
 {
 	struct mtk_msi_set *msi_set = &port->msi_sets[set_idx];
 	unsigned long msi_enable, msi_status;
-	unsigned int virq;
 	irq_hw_number_t bit, hwirq;
 
 	msi_enable = readl_relaxed(msi_set->base + PCIE_MSI_SET_ENABLE_OFFSET);
@@ -659,8 +658,7 @@ static void mtk_pcie_msi_handler(struct mtk_pcie_port *port, int set_idx)
 
 		for_each_set_bit(bit, &msi_status, PCIE_MSI_IRQS_PER_SET) {
 			hwirq = bit + set_idx * PCIE_MSI_IRQS_PER_SET;
-			virq = irq_find_mapping(port->msi_bottom_domain, hwirq);
-			generic_handle_irq(virq);
+			generic_handle_domain_irq(port->msi_bottom_domain, hwirq);
 		}
 	} while (true);
 }
@@ -670,18 +668,15 @@ static void mtk_pcie_irq_handler(struct irq_desc *desc)
 	struct mtk_pcie_port *port = irq_desc_get_handler_data(desc);
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned long status;
-	unsigned int virq;
 	irq_hw_number_t irq_bit = PCIE_INTX_SHIFT;
 
 	chained_irq_enter(irqchip, desc);
 
 	status = readl_relaxed(port->base + PCIE_INT_STATUS_REG);
 	for_each_set_bit_from(irq_bit, &status, PCI_NUM_INTX +
-			      PCIE_INTX_SHIFT) {
-		virq = irq_find_mapping(port->intx_domain,
-					irq_bit - PCIE_INTX_SHIFT);
-		generic_handle_irq(virq);
-	}
+			      PCIE_INTX_SHIFT)
+		generic_handle_domain_irq(port->intx_domain,
+					  irq_bit - PCIE_INTX_SHIFT);
 
 	irq_bit = PCIE_MSI_SHIFT;
 	for_each_set_bit_from(irq_bit, &status, PCIE_MSI_SET_NUM +
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 62a042e75d9a..ec8848a810f8 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -602,7 +602,6 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
 	struct mtk_pcie_port *port = irq_desc_get_handler_data(desc);
 	struct irq_chip *irqchip = irq_desc_get_chip(desc);
 	unsigned long status;
-	u32 virq;
 	u32 bit = INTX_SHIFT;
 
 	chained_irq_enter(irqchip, desc);
@@ -612,9 +611,8 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
 		for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) {
 			/* Clear the INTx */
 			writel(1 << bit, port->base + PCIE_INT_STATUS);
-			virq = irq_find_mapping(port->irq_domain,
-						bit - INTX_SHIFT);
-			generic_handle_irq(virq);
+			generic_handle_domain_irq(port->irq_domain,
+						  bit - INTX_SHIFT);
 		}
 	}
 
@@ -623,10 +621,8 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
 			unsigned long imsi_status;
 
 			while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
-				for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) {
-					virq = irq_find_mapping(port->inner_domain, bit);
-					generic_handle_irq(virq);
-				}
+				for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM)
+					generic_handle_domain_irq(port->inner_domain, bit);
 			}
 			/* Clear MSI interrupt status */
 			writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c
index 89c68c56d93b..f26a834a8e02 100644
--- a/drivers/pci/controller/pcie-microchip-host.c
+++ b/drivers/pci/controller/pcie-microchip-host.c
@@ -412,16 +412,14 @@ static void mc_handle_msi(struct irq_desc *desc)
 		port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
 	unsigned long status;
 	u32 bit;
-	u32 virq;
+	int ret;
 
 	status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
 	if (status & PM_MSI_INT_MSI_MASK) {
 		status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);
 		for_each_set_bit(bit, &status, msi->num_vectors) {
-			virq = irq_find_mapping(msi->dev_domain, bit);
-			if (virq)
-				generic_handle_irq(virq);
-			else
+			ret = generic_handle_domain_irq(msi->dev_domain, bit);
+			if (ret)
 				dev_err_ratelimited(dev, "bad MSI IRQ %d\n",
 						    bit);
 		}
@@ -570,17 +568,15 @@ static void mc_handle_intx(struct irq_desc *desc)
 		port->axi_base_addr + MC_PCIE_BRIDGE_ADDR;
 	unsigned long status;
 	u32 bit;
-	u32 virq;
+	int ret;
 
 	status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);
 	if (status & PM_MSI_INT_INTX_MASK) {
 		status &= PM_MSI_INT_INTX_MASK;
 		status >>= PM_MSI_INT_INTX_SHIFT;
 		for_each_set_bit(bit, &status, PCI_NUM_INTX) {
-			virq = irq_find_mapping(port->intx_domain, bit);
-			if (virq)
-				generic_handle_irq(virq);
-			else
+			ret = generic_handle_domain_irq(port->intx_domain, bit);
+			if (ret)
 				dev_err_ratelimited(dev, "bad INTx IRQ %d\n",
 						    bit);
 		}
@@ -745,7 +741,7 @@ static void mc_handle_event(struct irq_desc *desc)
 	events = get_events(port);
 
 	for_each_set_bit(bit, &events, NUM_EVENTS)
-		generic_handle_irq(irq_find_mapping(port->event_domain, bit));
+		generic_handle_domain_irq(port->event_domain, bit);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index 765cf2b45e24..00a8267eda14 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -486,12 +486,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
 
 	while (reg) {
 		unsigned int index = find_first_bit(&reg, 32);
-		unsigned int msi_irq;
+		int ret;
 
-		msi_irq = irq_find_mapping(msi->domain->parent, index);
-		if (msi_irq) {
-			generic_handle_irq(msi_irq);
-		} else {
+		ret = generic_handle_domain_irq(msi->domain->parent, index);
+		if (ret) {
 			/* Unknown MSI, just clear it */
 			dev_dbg(dev, "unexpected MSI\n");
 			rcar_pci_write_reg(pcie, BIT(index), PCIEMSIFR);
diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index f1d08a1b1591..24ba57c1e827 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -517,7 +517,7 @@ static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc)
 	struct device *dev = rockchip->dev;
 	u32 reg;
 	u32 hwirq;
-	u32 virq;
+	int ret;
 
 	chained_irq_enter(chip, desc);
 
@@ -528,10 +528,8 @@ static void rockchip_pcie_legacy_int_handler(struct irq_desc *desc)
 		hwirq = ffs(reg) - 1;
 		reg &= ~BIT(hwirq);
 
-		virq = irq_find_mapping(rockchip->irq_domain, hwirq);
-		if (virq)
-			generic_handle_irq(virq);
-		else
+		ret = generic_handle_domain_irq(rockchip->irq_domain, hwirq);
+		if (ret)
 			dev_err(dev, "unexpected IRQ, INT%d\n", hwirq);
 	}
 
diff --git a/drivers/pci/controller/pcie-xilinx-cpm.c b/drivers/pci/controller/pcie-xilinx-cpm.c
index 67937facd90c..95426df03200 100644
--- a/drivers/pci/controller/pcie-xilinx-cpm.c
+++ b/drivers/pci/controller/pcie-xilinx-cpm.c
@@ -222,7 +222,7 @@ static void xilinx_cpm_pcie_intx_flow(struct irq_desc *desc)
 			pcie_read(port, XILINX_CPM_PCIE_REG_IDRN));
 
 	for_each_set_bit(i, &val, PCI_NUM_INTX)
-		generic_handle_irq(irq_find_mapping(port->intx_domain, i));
+		generic_handle_domain_irq(port->intx_domain, i);
 
 	chained_irq_exit(chip, desc);
 }
@@ -282,7 +282,7 @@ static void xilinx_cpm_pcie_event_flow(struct irq_desc *desc)
 	val =  pcie_read(port, XILINX_CPM_PCIE_REG_IDR);
 	val &= pcie_read(port, XILINX_CPM_PCIE_REG_IMR);
 	for_each_set_bit(i, &val, 32)
-		generic_handle_irq(irq_find_mapping(port->cpm_domain, i));
+		generic_handle_domain_irq(port->cpm_domain, i);
 	pcie_write(port, val, XILINX_CPM_PCIE_REG_IDR);
 
 	/*
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
index 8689311c5ef6..3d178d5b652b 100644
--- a/drivers/pci/controller/pcie-xilinx-nwl.c
+++ b/drivers/pci/controller/pcie-xilinx-nwl.c
@@ -318,18 +318,14 @@ static void nwl_pcie_leg_handler(struct irq_desc *desc)
 	struct nwl_pcie *pcie;
 	unsigned long status;
 	u32 bit;
-	u32 virq;
 
 	chained_irq_enter(chip, desc);
 	pcie = irq_desc_get_handler_data(desc);
 
 	while ((status = nwl_bridge_readl(pcie, MSGF_LEG_STATUS) &
 				MSGF_LEG_SR_MASKALL) != 0) {
-		for_each_set_bit(bit, &status, PCI_NUM_INTX) {
-			virq = irq_find_mapping(pcie->legacy_irq_domain, bit);
-			if (virq)
-				generic_handle_irq(virq);
-		}
+		for_each_set_bit(bit, &status, PCI_NUM_INTX)
+			generic_handle_domain_irq(pcie->legacy_irq_domain, bit);
 	}
 
 	chained_irq_exit(chip, desc);
@@ -340,16 +336,13 @@ static void nwl_pcie_handle_msi_irq(struct nwl_pcie *pcie, u32 status_reg)
 	struct nwl_msi *msi;
 	unsigned long status;
 	u32 bit;
-	u32 virq;
 
 	msi = &pcie->msi;
 
 	while ((status = nwl_bridge_readl(pcie, status_reg)) != 0) {
 		for_each_set_bit(bit, &status, 32) {
 			nwl_bridge_writel(pcie, 1 << bit, status_reg);
-			virq = irq_find_mapping(msi->dev_domain, bit);
-			if (virq)
-				generic_handle_irq(virq);
+			generic_handle_domain_irq(msi->dev_domain, bit);
 		}
 	}
 }
diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c
index 14001febf59a..aa9bdcebc838 100644
--- a/drivers/pci/controller/pcie-xilinx.c
+++ b/drivers/pci/controller/pcie-xilinx.c
@@ -385,7 +385,7 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
 	}
 
 	if (status & (XILINX_PCIE_INTR_INTX | XILINX_PCIE_INTR_MSI)) {
-		unsigned int irq;
+		struct irq_domain *domain;
 
 		val = pcie_read(port, XILINX_PCIE_REG_RPIFR1);
 
@@ -399,19 +399,18 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
 		if (val & XILINX_PCIE_RPIFR1_MSI_INTR) {
 			val = pcie_read(port, XILINX_PCIE_REG_RPIFR2) &
 				XILINX_PCIE_RPIFR2_MSG_DATA;
-			irq = irq_find_mapping(port->msi_domain->parent, val);
+			domain = port->msi_domain->parent;
 		} else {
 			val = (val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
 				XILINX_PCIE_RPIFR1_INTR_SHIFT;
-			irq = irq_find_mapping(port->leg_domain, val);
+			domain = port->leg_domain;
 		}
 
 		/* Clear interrupt FIFO register 1 */
 		pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK,
 			   XILINX_PCIE_REG_RPIFR1);
 
-		if (irq)
-			generic_handle_irq(irq);
+		generic_handle_domain_irq(domain, val);
 	}
 
 	if (status & XILINX_PCIE_INTR_SLV_UNSUPP)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 31/39] mfd: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (29 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 30/39] PCI: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-21  7:06   ` Lee Jones
  2021-05-20 16:37 ` [PATCH 32/39] gpu: " Marc Zyngier
                   ` (9 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/mfd/db8500-prcmu.c    |  2 +-
 drivers/mfd/fsl-imx25-tsadc.c |  4 ++--
 drivers/mfd/ioc3.c            | 10 +++-------
 drivers/mfd/qcom-pm8xxx.c     | 10 ++++------
 4 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 167faac9b75b..3ca7d0bfe2f7 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -2364,7 +2364,7 @@ static bool read_mailbox_0(void)
 
 		for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) {
 			if (ev & prcmu_irq_bit[n])
-				generic_handle_irq(irq_find_mapping(db8500_irq_domain, n));
+				generic_handle_domain_irq(db8500_irq_domain, n);
 		}
 		r = true;
 		break;
diff --git a/drivers/mfd/fsl-imx25-tsadc.c b/drivers/mfd/fsl-imx25-tsadc.c
index 5f6f0a83e1c5..37e5e02a1d05 100644
--- a/drivers/mfd/fsl-imx25-tsadc.c
+++ b/drivers/mfd/fsl-imx25-tsadc.c
@@ -35,10 +35,10 @@ static void mx25_tsadc_irq_handler(struct irq_desc *desc)
 	regmap_read(tsadc->regs, MX25_TSC_TGSR, &status);
 
 	if (status & MX25_TGSR_GCQ_INT)
-		generic_handle_irq(irq_find_mapping(tsadc->domain, 1));
+		generic_handle_domain_irq(tsadc->domain, 1);
 
 	if (status & MX25_TGSR_TCQ_INT)
-		generic_handle_irq(irq_find_mapping(tsadc->domain, 0));
+		generic_handle_domain_irq(tsadc->domain, 0);
 
 	chained_irq_exit(chip, desc);
 }
diff --git a/drivers/mfd/ioc3.c b/drivers/mfd/ioc3.c
index 99b9c113f964..58656837b7c6 100644
--- a/drivers/mfd/ioc3.c
+++ b/drivers/mfd/ioc3.c
@@ -105,19 +105,15 @@ static void ioc3_irq_handler(struct irq_desc *desc)
 	struct ioc3_priv_data *ipd = domain->host_data;
 	struct ioc3 __iomem *regs = ipd->regs;
 	u32 pending, mask;
-	unsigned int irq;
 
 	pending = readl(&regs->sio_ir);
 	mask = readl(&regs->sio_ies);
 	pending &= mask; /* Mask off not enabled interrupts */
 
-	if (pending) {
-		irq = irq_find_mapping(domain, __ffs(pending));
-		if (irq)
-			generic_handle_irq(irq);
-	} else  {
+	if (pending)
+		generic_handle_domain_irq(domain, __ffs(pending));
+	else
 		spurious_interrupt();
-	}
 }
 
 /*
diff --git a/drivers/mfd/qcom-pm8xxx.c b/drivers/mfd/qcom-pm8xxx.c
index acd172ddcbd6..ec18a04de355 100644
--- a/drivers/mfd/qcom-pm8xxx.c
+++ b/drivers/mfd/qcom-pm8xxx.c
@@ -122,7 +122,7 @@ pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp)
 
 static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
 {
-	int pmirq, irq, i, ret = 0;
+	int pmirq, i, ret = 0;
 	unsigned int bits;
 
 	ret = pm8xxx_read_block_irq(chip, block, &bits);
@@ -139,8 +139,7 @@ static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
 	for (i = 0; i < 8; i++) {
 		if (bits & (1 << i)) {
 			pmirq = block * 8 + i;
-			irq = irq_find_mapping(chip->irqdomain, pmirq);
-			generic_handle_irq(irq);
+			generic_handle_domain_irq(chip->irqdomain, pmirq);
 		}
 	}
 	return 0;
@@ -199,7 +198,7 @@ static void pm8xxx_irq_handler(struct irq_desc *desc)
 static void pm8821_irq_block_handler(struct pm_irq_chip *chip,
 				     int master, int block)
 {
-	int pmirq, irq, i, ret;
+	int pmirq, i, ret;
 	unsigned int bits;
 
 	ret = regmap_read(chip->regmap,
@@ -216,8 +215,7 @@ static void pm8821_irq_block_handler(struct pm_irq_chip *chip,
 	for (i = 0; i < 8; i++) {
 		if (bits & BIT(i)) {
 			pmirq = block * 8 + i;
-			irq = irq_find_mapping(chip->irqdomain, pmirq);
-			generic_handle_irq(irq);
+			generic_handle_domain_irq(chip->irqdomain, pmirq);
 		}
 	}
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 32/39] gpu: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (30 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 31/39] mfd: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 33/39] SH: " Marc Zyngier
                   ` (8 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c   |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c  | 15 ++++-----------
 drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c |  3 +--
 drivers/gpu/ipu-v3/ipu-common.c           | 11 ++++-------
 4 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
index 90f50561b43a..5ca7540b6267 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -476,7 +476,7 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev,
 
 	} else if ((client_id == AMDGPU_IRQ_CLIENTID_LEGACY) &&
 		   adev->irq.virq[src_id]) {
-		generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id));
+		generic_handle_domain_irq(adev->irq.domain, src_id);
 
 	} else if (!adev->irq.client[client_id].sources) {
 		DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n",
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
index 06b56fec04e0..bff0bc338938 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
@@ -45,20 +45,13 @@ static void dpu_mdss_irq(struct irq_desc *desc)
 
 	while (interrupts) {
 		irq_hw_number_t hwirq = fls(interrupts) - 1;
-		unsigned int mapping;
 		int rc;
 
-		mapping = irq_find_mapping(dpu_mdss->irq_controller.domain,
-					   hwirq);
-		if (mapping == 0) {
-			DRM_ERROR("couldn't find irq mapping for %lu\n", hwirq);
-			break;
-		}
-
-		rc = generic_handle_irq(mapping);
+		rc = generic_handle_domain_irq(dpu_mdss->irq_controller.domain,
+					       hwirq);
 		if (rc < 0) {
-			DRM_ERROR("handle irq fail: irq=%lu mapping=%u rc=%d\n",
-				  hwirq, mapping, rc);
+			DRM_ERROR("handle irq fail: irq=%lu rc=%d\n",
+				  hwirq, rc);
 			break;
 		}
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
index 09bd46ad820b..2f4895bcb0b0 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
@@ -50,8 +50,7 @@ static irqreturn_t mdss_irq(int irq, void *arg)
 	while (intr) {
 		irq_hw_number_t hwirq = fls(intr) - 1;
 
-		generic_handle_irq(irq_find_mapping(
-				mdp5_mdss->irqcontroller.domain, hwirq));
+		generic_handle_domain_irq(mdp5_mdss->irqcontroller.domain, hwirq);
 		intr &= ~(1 << hwirq);
 	}
 
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index d166ee262ce4..118318513e2d 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -1003,19 +1003,16 @@ static int ipu_submodules_init(struct ipu_soc *ipu,
 static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs)
 {
 	unsigned long status;
-	int i, bit, irq;
+	int i, bit;
 
 	for (i = 0; i < num_regs; i++) {
 
 		status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i]));
 		status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i]));
 
-		for_each_set_bit(bit, &status, 32) {
-			irq = irq_linear_revmap(ipu->domain,
-						regs[i] * 32 + bit);
-			if (irq)
-				generic_handle_irq(irq);
-		}
+		for_each_set_bit(bit, &status, 32)
+			generic_handle_domain_irq(ipu->domain,
+						  regs[i] * 32 + bit);
 	}
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 33/39] SH: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (31 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 32/39] gpu: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 34/39] ARM: " Marc Zyngier
                   ` (7 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/sh/boards/mach-se/7343/irq.c  | 2 +-
 arch/sh/boards/mach-se/7722/irq.c  | 2 +-
 arch/sh/boards/mach-x3proto/gpio.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index 1aedbfe32654..f9f3b14f70d5 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -38,7 +38,7 @@ static void se7343_irq_demux(struct irq_desc *desc)
 	mask = ioread16(se7343_irq_regs + PA_CPLD_ST_REG);
 
 	for_each_set_bit(bit, &mask, SE7343_FPGA_IRQ_NR)
-		generic_handle_irq(irq_linear_revmap(se7343_irq_domain, bit));
+		generic_handle_domain_irq(se7343_irq_domain, bit);
 
 	chip->irq_unmask(data);
 }
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index 6d34592767f8..efa96edd47dc 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -37,7 +37,7 @@ static void se7722_irq_demux(struct irq_desc *desc)
 	mask = ioread16(se7722_irq_regs + IRQ01_STS_REG);
 
 	for_each_set_bit(bit, &mask, SE7722_FPGA_IRQ_NR)
-		generic_handle_irq(irq_linear_revmap(se7722_irq_domain, bit));
+		generic_handle_domain_irq(se7722_irq_domain, bit);
 
 	chip->irq_unmask(data);
 }
diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c
index efc992f641a6..f82d3a6a844a 100644
--- a/arch/sh/boards/mach-x3proto/gpio.c
+++ b/arch/sh/boards/mach-x3proto/gpio.c
@@ -68,7 +68,7 @@ static void x3proto_gpio_irq_handler(struct irq_desc *desc)
 
 	mask = __raw_readw(KEYDETR);
 	for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS)
-		generic_handle_irq(irq_linear_revmap(x3proto_irq_domain, pin));
+		generic_handle_domain_irq(x3proto_irq_domain, pin);
 
 	chip->irq_unmask(data);
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 34/39] ARM: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (32 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 33/39] SH: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 18:04   ` Rob Herring
  2021-05-21 21:17   ` Krzysztof Kozlowski
  2021-05-20 16:37 ` [PATCH 35/39] mips: " Marc Zyngier
                   ` (6 subsequent siblings)
  40 siblings, 2 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++----
 arch/arm/mach-s3c/irq-s3c24xx.c    | 5 ++---
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c
index ec0d9b094744..ce1bbabbad54 100644
--- a/arch/arm/mach-pxa/pxa_cplds_irqs.c
+++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c
@@ -39,10 +39,8 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d)
 
 	do {
 		pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
-		for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
-			generic_handle_irq(irq_find_mapping(fpga->irqdomain,
-							    bit));
-		}
+		for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
+			generic_handle_domain_irq(fpga->irqdomain, bit);
 	} while (pending);
 
 	return IRQ_HANDLED;
diff --git a/arch/arm/mach-s3c/irq-s3c24xx.c b/arch/arm/mach-s3c/irq-s3c24xx.c
index 0c631c14a817..3edc5f614eef 100644
--- a/arch/arm/mach-s3c/irq-s3c24xx.c
+++ b/arch/arm/mach-s3c/irq-s3c24xx.c
@@ -298,7 +298,7 @@ static void s3c_irq_demux(struct irq_desc *desc)
 	struct s3c_irq_data *irq_data = irq_desc_get_chip_data(desc);
 	struct s3c_irq_intc *intc = irq_data->intc;
 	struct s3c_irq_intc *sub_intc = irq_data->sub_intc;
-	unsigned int n, offset, irq;
+	unsigned int n, offset;
 	unsigned long src, msk;
 
 	/* we're using individual domains for the non-dt case
@@ -318,8 +318,7 @@ static void s3c_irq_demux(struct irq_desc *desc)
 	while (src) {
 		n = __ffs(src);
 		src &= ~(1 << n);
-		irq = irq_find_mapping(sub_intc->domain, offset + n);
-		generic_handle_irq(irq);
+		generic_handle_domain_irq(sub_intc->domain, offset + n);
 	}
 
 	chained_irq_exit(chip, desc);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 35/39] mips: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (33 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 34/39] ARM: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 36/39] arc: " Marc Zyngier
                   ` (5 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/mips/ath25/ar2315.c      | 14 +++++++-------
 arch/mips/ath25/ar5312.c      | 13 ++++++-------
 arch/mips/lantiq/irq.c        |  2 +-
 arch/mips/pci/pci-ar2315.c    |  8 +++-----
 arch/mips/pci/pci-rt3883.c    |  5 ++---
 arch/mips/ralink/irq.c        |  2 +-
 arch/mips/sgi-ip27/ip27-irq.c | 16 ++++++----------
 arch/mips/sgi-ip30/ip30-irq.c |  8 +++-----
 8 files changed, 29 insertions(+), 39 deletions(-)

diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c
index 9dbed7b5ea76..76e43a73ba1b 100644
--- a/arch/mips/ath25/ar2315.c
+++ b/arch/mips/ath25/ar2315.c
@@ -69,24 +69,24 @@ static void ar2315_misc_irq_handler(struct irq_desc *desc)
 {
 	u32 pending = ar2315_rst_reg_read(AR2315_ISR) &
 		      ar2315_rst_reg_read(AR2315_IMR);
-	unsigned nr, misc_irq = 0;
+	unsigned nr;
+	int ret = 0;
 
 	if (pending) {
 		struct irq_domain *domain = irq_desc_get_handler_data(desc);
 
 		nr = __ffs(pending);
-		misc_irq = irq_find_mapping(domain, nr);
-	}
 
-	if (misc_irq) {
 		if (nr == AR2315_MISC_IRQ_GPIO)
 			ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO);
 		else if (nr == AR2315_MISC_IRQ_WATCHDOG)
 			ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD);
-		generic_handle_irq(misc_irq);
-	} else {
-		spurious_interrupt();
+
+		ret = generic_handle_domain_irq(domain, nr);
 	}
+
+	if (!pending || ret)
+		spurious_interrupt();
 }
 
 static void ar2315_misc_irq_unmask(struct irq_data *d)
diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c
index 23c879f4b734..822b639dbd1e 100644
--- a/arch/mips/ath25/ar5312.c
+++ b/arch/mips/ath25/ar5312.c
@@ -73,22 +73,21 @@ static void ar5312_misc_irq_handler(struct irq_desc *desc)
 {
 	u32 pending = ar5312_rst_reg_read(AR5312_ISR) &
 		      ar5312_rst_reg_read(AR5312_IMR);
-	unsigned nr, misc_irq = 0;
+	unsigned nr;
+	int ret = 0;
 
 	if (pending) {
 		struct irq_domain *domain = irq_desc_get_handler_data(desc);
 
 		nr = __ffs(pending);
-		misc_irq = irq_find_mapping(domain, nr);
-	}
 
-	if (misc_irq) {
-		generic_handle_irq(misc_irq);
+		ret = generic_handle_domain_irq(domain, nr);
 		if (nr == AR5312_MISC_IRQ_TIMER)
 			ar5312_rst_reg_read(AR5312_TIMER);
-	} else {
-		spurious_interrupt();
 	}
+
+	if (!pending || ret)
+		spurious_interrupt();
 }
 
 /* Enable the specified AR5312_MISC_IRQ interrupt */
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index acfbdc01b0ac..b732495f138a 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -300,7 +300,7 @@ static void ltq_hw_irq_handler(struct irq_desc *desc)
 	 */
 	irq = __fls(irq);
 	hwirq = irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module);
-	generic_handle_irq(irq_linear_revmap(ltq_domain, hwirq));
+	generic_handle_domain_irq(ltq_domain, hwirq);
 
 	/* if this is a EBU irq, we need to ack it or get a deadlock */
 	if (irq == LTQ_ICU_EBU_IRQ && !module && LTQ_EBU_PCC_ISTAT != 0)
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
index c1a655aee599..9a4bfb4e63e3 100644
--- a/arch/mips/pci/pci-ar2315.c
+++ b/arch/mips/pci/pci-ar2315.c
@@ -337,14 +337,12 @@ static void ar2315_pci_irq_handler(struct irq_desc *desc)
 	struct ar2315_pci_ctrl *apc = irq_desc_get_handler_data(desc);
 	u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) &
 		      ar2315_pci_reg_read(apc, AR2315_PCI_IMR);
-	unsigned pci_irq = 0;
+	int ret = 0;
 
 	if (pending)
-		pci_irq = irq_find_mapping(apc->domain, __ffs(pending));
+		ret = generic_handle_domain_irq(apc->domain, __ffs(pending));
 
-	if (pci_irq)
-		generic_handle_irq(pci_irq);
-	else
+	if (!pending || ret)
 		spurious_interrupt();
 }
 
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c
index c48e23cf5b5e..d3c947fa2969 100644
--- a/arch/mips/pci/pci-rt3883.c
+++ b/arch/mips/pci/pci-rt3883.c
@@ -140,10 +140,9 @@ static void rt3883_pci_irq_handler(struct irq_desc *desc)
 	}
 
 	while (pending) {
-		unsigned irq, bit = __ffs(pending);
+		unsigned bit = __ffs(pending);
 
-		irq = irq_find_mapping(rpc->irq_domain, bit);
-		generic_handle_irq(irq);
+		generic_handle_domain_irq(rpc->irq_domain, bit);
 
 		pending &= ~BIT(bit);
 	}
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
index 220ca0cd7945..fa353bc13947 100644
--- a/arch/mips/ralink/irq.c
+++ b/arch/mips/ralink/irq.c
@@ -100,7 +100,7 @@ static void ralink_intc_irq_handler(struct irq_desc *desc)
 
 	if (pending) {
 		struct irq_domain *domain = irq_desc_get_handler_data(desc);
-		generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
+		generic_handle_domain_irq(domain, __ffs(pending));
 	} else {
 		spurious_interrupt();
 	}
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 95c1bff1ab9f..a0dd3bd2b81b 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -190,7 +190,7 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
 	unsigned long *mask = per_cpu(irq_enable_mask, cpu);
 	struct irq_domain *domain;
 	u64 pend0;
-	int irq;
+	int ret;
 
 	/* copied from Irix intpend0() */
 	pend0 = LOCAL_HUB_L(PI_INT_PEND0);
@@ -216,10 +216,8 @@ static void ip27_do_irq_mask0(struct irq_desc *desc)
 #endif
 	{
 		domain = irq_desc_get_handler_data(desc);
-		irq = irq_linear_revmap(domain, __ffs(pend0));
-		if (irq)
-			generic_handle_irq(irq);
-		else
+		ret = generic_handle_domain_irq(domain, __ffs(pend0));
+		if (ret)
 			spurious_interrupt();
 	}
 
@@ -232,7 +230,7 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
 	unsigned long *mask = per_cpu(irq_enable_mask, cpu);
 	struct irq_domain *domain;
 	u64 pend1;
-	int irq;
+	int ret;
 
 	/* copied from Irix intpend0() */
 	pend1 = LOCAL_HUB_L(PI_INT_PEND1);
@@ -242,10 +240,8 @@ static void ip27_do_irq_mask1(struct irq_desc *desc)
 		return;
 
 	domain = irq_desc_get_handler_data(desc);
-	irq = irq_linear_revmap(domain, __ffs(pend1) + 64);
-	if (irq)
-		generic_handle_irq(irq);
-	else
+	ret = generic_handle_domain_irq(domain, __ffs(pend1) + 64);
+	if (ret)
 		spurious_interrupt();
 
 	LOCAL_HUB_L(PI_INT_PEND1);
diff --git a/arch/mips/sgi-ip30/ip30-irq.c b/arch/mips/sgi-ip30/ip30-irq.c
index ba87704073c8..423c32cb66ed 100644
--- a/arch/mips/sgi-ip30/ip30-irq.c
+++ b/arch/mips/sgi-ip30/ip30-irq.c
@@ -99,7 +99,7 @@ static void ip30_normal_irq(struct irq_desc *desc)
 	int cpu = smp_processor_id();
 	struct irq_domain *domain;
 	u64 pend, mask;
-	int irq;
+	int ret;
 
 	pend = heart_read(&heart_regs->isr);
 	mask = (heart_read(&heart_regs->imr[cpu]) &
@@ -130,10 +130,8 @@ static void ip30_normal_irq(struct irq_desc *desc)
 #endif
 	{
 		domain = irq_desc_get_handler_data(desc);
-		irq = irq_linear_revmap(domain, __ffs(pend));
-		if (irq)
-			generic_handle_irq(irq);
-		else
+		ret = generic_handle_domain_irq(domain, __ffs(pend));
+		if (ret)
 			spurious_interrupt();
 	}
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 36/39] arc: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (34 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 35/39] mips: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-06-01 18:00   ` Vineet Gupta
  2021-05-20 16:37 ` [PATCH 37/39] xtensa: " Marc Zyngier
                   ` (4 subsequent siblings)
  40 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arc/kernel/mcip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
index abf9398cc333..f9fdb557c263 100644
--- a/arch/arc/kernel/mcip.c
+++ b/arch/arc/kernel/mcip.c
@@ -352,7 +352,7 @@ static void idu_cascade_isr(struct irq_desc *desc)
 	irq_hw_number_t idu_hwirq = core_hwirq - FIRST_EXT_IRQ;
 
 	chained_irq_enter(core_chip, desc);
-	generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
+	generic_handle_domain_irq(idu_domain, idu_hwirq);
 	chained_irq_exit(core_chip, desc);
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 37/39] xtensa: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (35 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 36/39] arc: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 38/39] nios2: " Marc Zyngier
                   ` (3 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/xtensa/kernel/irq.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index a48bf2d10ac2..764b54bef701 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -33,8 +33,6 @@ DECLARE_PER_CPU(unsigned long, nmi_count);
 
 asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
 {
-	int irq = irq_find_mapping(NULL, hwirq);
-
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 	/* Debugging check for stack overflow: is there less than 1KB free? */
 	{
@@ -48,7 +46,7 @@ asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
 			       sp - sizeof(struct thread_info));
 	}
 #endif
-	generic_handle_irq(irq);
+	generic_handle_domain_irq(NULL, hwirq);
 }
 
 int arch_show_interrupts(struct seq_file *p, int prec)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 38/39] nios2: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (36 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 37/39] xtensa: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 16:37 ` [PATCH 39/39] powerpc: " Marc Zyngier
                   ` (2 subsequent siblings)
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/nios2/kernel/irq.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/nios2/kernel/irq.c b/arch/nios2/kernel/irq.c
index c6a1a9f6ac42..6b7890e5f7af 100644
--- a/arch/nios2/kernel/irq.c
+++ b/arch/nios2/kernel/irq.c
@@ -19,11 +19,9 @@ static u32 ienable;
 asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
 {
 	struct pt_regs *oldregs = set_irq_regs(regs);
-	int irq;
 
 	irq_enter();
-	irq = irq_find_mapping(NULL, hwirq);
-	generic_handle_irq(irq);
+	generic_handle_domain_irq(NULL, hwirq);
 	irq_exit();
 
 	set_irq_regs(oldregs);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 39/39] powerpc: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (37 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 38/39] nios2: " Marc Zyngier
@ 2021-05-20 16:37 ` Marc Zyngier
  2021-05-20 23:33 ` [PATCH 00/39] irqdomain: Simplify interrupt handling Linus Walleij
  2021-06-01 14:29 ` Marc Zyngier
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-20 16:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

Wherever possible, replace constructs that match either
generic_handle_irq(irq_find_mapping()) or
generic_handle_irq(irq_linear_revmap()) to a single call to
generic_handle_domain_irq().

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/powerpc/platforms/4xx/uic.c              |  4 +---
 .../powerpc/platforms/512x/mpc5121_ads_cpld.c | 23 ++++++++-----------
 arch/powerpc/platforms/52xx/media5200.c       |  9 ++++----
 arch/powerpc/platforms/52xx/mpc52xx_gpt.c     |  7 ++----
 arch/powerpc/platforms/82xx/pq2ads-pci-pic.c  |  6 ++---
 arch/powerpc/platforms/cell/interrupt.c       |  8 ++-----
 arch/powerpc/platforms/cell/spider-pic.c      | 11 +++------
 arch/powerpc/platforms/embedded6xx/hlwd-pic.c | 15 ++++++------
 arch/powerpc/platforms/powernv/opal-irqchip.c | 11 ++++-----
 arch/powerpc/sysdev/fsl_mpic_err.c            | 11 ++++-----
 arch/powerpc/sysdev/fsl_msi.c                 |  8 +++----
 11 files changed, 43 insertions(+), 70 deletions(-)

diff --git a/arch/powerpc/platforms/4xx/uic.c b/arch/powerpc/platforms/4xx/uic.c
index 36fb66ce54cf..89e2587b1a59 100644
--- a/arch/powerpc/platforms/4xx/uic.c
+++ b/arch/powerpc/platforms/4xx/uic.c
@@ -198,7 +198,6 @@ static void uic_irq_cascade(struct irq_desc *desc)
 	struct uic *uic = irq_desc_get_handler_data(desc);
 	u32 msr;
 	int src;
-	int subvirq;
 
 	raw_spin_lock(&desc->lock);
 	if (irqd_is_level_type(idata))
@@ -213,8 +212,7 @@ static void uic_irq_cascade(struct irq_desc *desc)
 
 	src = 32 - ffs(msr);
 
-	subvirq = irq_linear_revmap(uic->irqhost, src);
-	generic_handle_irq(subvirq);
+	generic_handle_domain_irq(uic->irqhost, src);
 
 uic_irq_ret:
 	raw_spin_lock(&desc->lock);
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index b2981634f1f8..ea46870e5d6e 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -81,11 +81,10 @@ static struct irq_chip cpld_pic = {
 	.irq_unmask = cpld_unmask_irq,
 };
 
-static int
+static unsigned int
 cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp,
 			    u8 __iomem *maskp)
 {
-	int cpld_irq;
 	u8 status = in_8(statusp);
 	u8 mask = in_8(maskp);
 
@@ -93,28 +92,26 @@ cpld_pic_get_irq(int offset, u8 ignore, u8 __iomem *statusp,
 	status |= (ignore | mask);
 
 	if (status == 0xff)
-		return 0;
-
-	cpld_irq = ffz(status) + offset;
+		return ~0;
 
-	return irq_linear_revmap(cpld_pic_host, cpld_irq);
+	return ffz(status) + offset;
 }
 
 static void cpld_pic_cascade(struct irq_desc *desc)
 {
-	unsigned int irq;
+	unsigned int hwirq;
 
-	irq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status,
+	hwirq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status,
 		&cpld_regs->pci_mask);
-	if (irq) {
-		generic_handle_irq(irq);
+	if (hwirq != ~0) {
+		generic_handle_domain_irq(cpld_pic_host, hwirq);
 		return;
 	}
 
-	irq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status,
+	hwirq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status,
 		&cpld_regs->misc_mask);
-	if (irq) {
-		generic_handle_irq(irq);
+	if (hwirq != ~0) {
+		generic_handle_domain_irq(cpld_pic_host, hwirq);
 		return;
 	}
 }
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index efb8bdecbcc7..110c444f4bc7 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -78,7 +78,7 @@ static struct irq_chip media5200_irq_chip = {
 static void media5200_irq_cascade(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
-	int sub_virq, val;
+	int val;
 	u32 status, enable;
 
 	/* Mask off the cascaded IRQ */
@@ -92,11 +92,10 @@ static void media5200_irq_cascade(struct irq_desc *desc)
 	enable = in_be32(media5200_irq.regs + MEDIA5200_IRQ_STATUS);
 	val = ffs((status & enable) >> MEDIA5200_IRQ_SHIFT);
 	if (val) {
-		sub_virq = irq_linear_revmap(media5200_irq.irqhost, val - 1);
-		/* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i subvirq=%i\n",
-		 *          __func__, virq, status, enable, val - 1, sub_virq);
+		generic_handle_domain_irq(media5200_irq.irqhost, val - 1);
+		/* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i\n",
+		 *          __func__, virq, status, enable, val - 1);
 		 */
-		generic_handle_irq(sub_virq);
 	}
 
 	/* Processing done; can reenable the cascade now */
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 8c0d324f657e..acc211ceb719 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -190,14 +190,11 @@ static struct irq_chip mpc52xx_gpt_irq_chip = {
 static void mpc52xx_gpt_irq_cascade(struct irq_desc *desc)
 {
 	struct mpc52xx_gpt_priv *gpt = irq_desc_get_handler_data(desc);
-	int sub_virq;
 	u32 status;
 
 	status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK;
-	if (status) {
-		sub_virq = irq_linear_revmap(gpt->irqhost, 0);
-		generic_handle_irq(sub_virq);
-	}
+	if (status)
+		generic_handle_domain_irq(gpt->irqhost, 0);
 }
 
 static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq,
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index f82f75a6085c..285bfe19b798 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -91,10 +91,8 @@ static void pq2ads_pci_irq_demux(struct irq_desc *desc)
 			break;
 
 		for (bit = 0; pend != 0; ++bit, pend <<= 1) {
-			if (pend & 0x80000000) {
-				int virq = irq_linear_revmap(priv->host, bit);
-				generic_handle_irq(virq);
-			}
+			if (pend & 0x80000000)
+				generic_handle_domain_irq(priv->host, bit);
 		}
 	}
 }
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index c0ab62ba6f16..0873a7a20271 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -106,13 +106,9 @@ static void iic_ioexc_cascade(struct irq_desc *desc)
 			out_be64(&node_iic->iic_is, ack);
 		/* handle them */
 		for (cascade = 63; cascade >= 0; cascade--)
-			if (bits & (0x8000000000000000UL >> cascade)) {
-				unsigned int cirq =
-					irq_linear_revmap(iic_host,
+			if (bits & (0x8000000000000000UL >> cascade))
+				generic_handle_domain_irq(iic_host,
 							  base | cascade);
-				if (cirq)
-					generic_handle_irq(cirq);
-			}
 		/* post-ack level interrupts */
 		ack = bits & ~IIC_ISR_EDGE_MASK;
 		if (ack)
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 210785f59271..1bffccbe9772 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -190,16 +190,11 @@ static void spider_irq_cascade(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct spider_pic *pic = irq_desc_get_handler_data(desc);
-	unsigned int cs, virq;
+	unsigned int cs;
 
 	cs = in_be32(pic->regs + TIR_CS) >> 24;
-	if (cs == SPIDER_IRQ_INVALID)
-		virq = 0;
-	else
-		virq = irq_linear_revmap(pic->host, cs);
-
-	if (virq)
-		generic_handle_irq(virq);
+	if (cs != SPIDER_IRQ_INVALID)
+		generic_handle_domain_irq((pic->host, cs);
 
 	chip->irq_eoi(&desc->irq_data);
 }
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index a1b7f79a8a15..15396333a90b 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -108,7 +108,6 @@ static const struct irq_domain_ops hlwd_irq_domain_ops = {
 static unsigned int __hlwd_pic_get_irq(struct irq_domain *h)
 {
 	void __iomem *io_base = h->host_data;
-	int irq;
 	u32 irq_status;
 
 	irq_status = in_be32(io_base + HW_BROADWAY_ICR) &
@@ -116,23 +115,22 @@ static unsigned int __hlwd_pic_get_irq(struct irq_domain *h)
 	if (irq_status == 0)
 		return 0;	/* no more IRQs pending */
 
-	irq = __ffs(irq_status);
-	return irq_linear_revmap(h, irq);
+	return __ffs(irq_status);
 }
 
 static void hlwd_pic_irq_cascade(struct irq_desc *desc)
 {
 	struct irq_chip *chip = irq_desc_get_chip(desc);
 	struct irq_domain *irq_domain = irq_desc_get_handler_data(desc);
-	unsigned int virq;
+	unsigned int hwirq;
 
 	raw_spin_lock(&desc->lock);
 	chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */
 	raw_spin_unlock(&desc->lock);
 
-	virq = __hlwd_pic_get_irq(irq_domain);
-	if (virq)
-		generic_handle_irq(virq);
+	hwirq = __hlwd_pic_get_irq(irq_domain);
+	if (hwirq)
+		generic_handle_domain_irq(irq_domain, hwirq);
 	else
 		pr_err("spurious interrupt!\n");
 
@@ -190,7 +188,8 @@ static struct irq_domain *hlwd_pic_init(struct device_node *np)
 
 unsigned int hlwd_pic_get_irq(void)
 {
-	return __hlwd_pic_get_irq(hlwd_irq_host);
+	unsigned int hwirq = __hlwd_pic_get_irq(hlwd_irq_host);
+	return hwirq ? irq_linear_revmap(hlwd_irq_host, hwirq) : 0;
 }
 
 /*
diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c
index c164419e254d..d55652b5f6fa 100644
--- a/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ b/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -46,18 +46,15 @@ void opal_handle_events(void)
 	e = READ_ONCE(last_outstanding_events) & opal_event_irqchip.mask;
 again:
 	while (e) {
-		int virq, hwirq;
+		int hwirq;
 
 		hwirq = fls64(e) - 1;
 		e &= ~BIT_ULL(hwirq);
 
 		local_irq_disable();
-		virq = irq_find_mapping(opal_event_irqchip.domain, hwirq);
-		if (virq) {
-			irq_enter();
-			generic_handle_irq(virq);
-			irq_exit();
-		}
+		irq_enter();
+		generic_handle_domain_irq(opal_event_irqchip.domain, hwirq);
+		irq_exit();
 		local_irq_enable();
 
 		cond_resched();
diff --git a/arch/powerpc/sysdev/fsl_mpic_err.c b/arch/powerpc/sysdev/fsl_mpic_err.c
index 5fa5fa215541..9a98bb212922 100644
--- a/arch/powerpc/sysdev/fsl_mpic_err.c
+++ b/arch/powerpc/sysdev/fsl_mpic_err.c
@@ -99,7 +99,6 @@ static irqreturn_t fsl_error_int_handler(int irq, void *data)
 	struct mpic *mpic = (struct mpic *) data;
 	u32 eisr, eimr;
 	int errint;
-	unsigned int cascade_irq;
 
 	eisr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EISR);
 	eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR);
@@ -108,13 +107,11 @@ static irqreturn_t fsl_error_int_handler(int irq, void *data)
 		return IRQ_NONE;
 
 	while (eisr) {
+		int ret;
 		errint = __builtin_clz(eisr);
-		cascade_irq = irq_linear_revmap(mpic->irqhost,
-				 mpic->err_int_vecs[errint]);
-		WARN_ON(!cascade_irq);
-		if (cascade_irq) {
-			generic_handle_irq(cascade_irq);
-		} else {
+		ret = generic_handle_domain_irq(mpic->irqhost,
+						mpic->err_int_vecs[errint]);
+		if (WARN_ON(ret)) {
 			eimr |=  1 << (31 - errint);
 			mpic_fsl_err_write(mpic->err_regs, eimr);
 		}
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 808e7118abfc..e9c4aa211f04 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -305,15 +305,15 @@ static irqreturn_t fsl_msi_cascade(int irq, void *data)
 	}
 
 	while (msir_value) {
+		int err;
 		intr_index = ffs(msir_value) - 1;
 
-		cascade_irq = irq_linear_revmap(msi_data->irqhost,
+		err = generic_handle_domain_irq(msi_data->irqhost,
 				msi_hwirq(msi_data, msir_index,
 					  intr_index + have_shift));
-		if (cascade_irq) {
-			generic_handle_irq(cascade_irq);
+		if (!err)
 			ret = IRQ_HANDLED;
-		}
+
 		have_shift += intr_index + 1;
 		msir_value = msir_value >> (intr_index + 1);
 	}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 30/39] PCI: " Marc Zyngier
@ 2021-05-20 17:47   ` Rob Herring
  2021-05-24  8:38     ` Marc Zyngier
  2021-05-21  8:57   ` Geert Uytterhoeven
  1 sibling, 1 reply; 65+ messages in thread
From: Rob Herring @ 2021-05-20 17:47 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, May 20, 2021 at 11:57 AM Marc Zyngier <maz@kernel.org> wrote:
>
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/pci/controller/dwc/pci-dra7xx.c        | 14 +++++---------
>  drivers/pci/controller/dwc/pci-keystone.c      |  5 ++---
>  .../pci/controller/dwc/pcie-designware-host.c  |  9 ++++-----
>  drivers/pci/controller/dwc/pcie-uniphier.c     |  6 ++----
>  .../controller/mobiveil/pcie-mobiveil-host.c   | 15 ++++++---------
>  drivers/pci/controller/pci-aardvark.c          |  5 ++---
>  drivers/pci/controller/pci-ftpci100.c          |  2 +-
>  drivers/pci/controller/pci-tegra.c             |  8 +++-----
>  drivers/pci/controller/pci-xgene-msi.c         |  9 +++------
>  drivers/pci/controller/pcie-altera-msi.c       | 10 ++++------
>  drivers/pci/controller/pcie-altera.c           | 10 ++++------
>  drivers/pci/controller/pcie-brcmstb.c          |  9 ++++-----
>  drivers/pci/controller/pcie-iproc-msi.c        |  4 +---
>  drivers/pci/controller/pcie-mediatek-gen3.c    | 13 ++++---------
>  drivers/pci/controller/pcie-mediatek.c         | 12 ++++--------
>  drivers/pci/controller/pcie-microchip-host.c   | 18 +++++++-----------
>  drivers/pci/controller/pcie-rcar-host.c        |  8 +++-----
>  drivers/pci/controller/pcie-rockchip-host.c    |  8 +++-----
>  drivers/pci/controller/pcie-xilinx-cpm.c       |  4 ++--
>  drivers/pci/controller/pcie-xilinx-nwl.c       | 13 +++----------
>  drivers/pci/controller/pcie-xilinx.c           |  9 ++++-----
>  21 files changed, 71 insertions(+), 120 deletions(-)


> diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c
> index 1c34c897a7e2..cf3832b905e8 100644
> --- a/drivers/pci/controller/pci-xgene-msi.c
> +++ b/drivers/pci/controller/pci-xgene-msi.c
> @@ -291,8 +291,7 @@ static void xgene_msi_isr(struct irq_desc *desc)
>         struct irq_chip *chip = irq_desc_get_chip(desc);
>         struct xgene_msi_group *msi_groups;
>         struct xgene_msi *xgene_msi;
> -       unsigned int virq;
> -       int msir_index, msir_val, hw_irq;
> +       int msir_index, msir_val, hw_irq, ret;
>         u32 intr_index, grp_select, msi_grp;
>
>         chained_irq_enter(chip, desc);
> @@ -330,10 +329,8 @@ static void xgene_msi_isr(struct irq_desc *desc)
>                          * CPU0
>                          */
>                         hw_irq = hwirq_to_canonical_hwirq(hw_irq);
> -                       virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq);
> -                       WARN_ON(!virq);
> -                       if (virq != 0)
> -                               generic_handle_irq(virq);
> +                       ret = generic_handle_domain_irq(xgene_msi->inner_domain, hw_irq);
> +                       WARN_ON(ret);

There's various error prints in some of the handlers. I think they
should be moved to the core. I can't imagine handling the irq is ever
optional.

Rob

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 34/39] ARM: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 34/39] ARM: " Marc Zyngier
@ 2021-05-20 18:04   ` Rob Herring
  2021-05-24  8:32     ` Marc Zyngier
  2021-05-21 21:17   ` Krzysztof Kozlowski
  1 sibling, 1 reply; 65+ messages in thread
From: Rob Herring @ 2021-05-20 18:04 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, May 20, 2021 at 11:58 AM Marc Zyngier <maz@kernel.org> wrote:
>
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++----
>  arch/arm/mach-s3c/irq-s3c24xx.c    | 5 ++---
>  2 files changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c
> index ec0d9b094744..ce1bbabbad54 100644
> --- a/arch/arm/mach-pxa/pxa_cplds_irqs.c
> +++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c
> @@ -39,10 +39,8 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d)
>
>         do {
>                 pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
> -               for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
> -                       generic_handle_irq(irq_find_mapping(fpga->irqdomain,
> -                                                           bit));
> -               }
> +               for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
> +                       generic_handle_domain_irq(fpga->irqdomain, bit);

We see this pattern a bit, I'm wondering if we can come up with a
common helper. For an even longer name, something like:

generic_handle_domain_irq_for_bitmap(fpga->irqdomain, &pending, CPLDS_NB_IRQ);

Rob

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/39] irqdomain: Simplify interrupt handling
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (38 preceding siblings ...)
  2021-05-20 16:37 ` [PATCH 39/39] powerpc: " Marc Zyngier
@ 2021-05-20 23:33 ` Linus Walleij
  2021-05-24  8:53   ` Marc Zyngier
  2021-06-01 14:29 ` Marc Zyngier
  40 siblings, 1 reply; 65+ messages in thread
From: Linus Walleij @ 2021-05-20 23:33 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Lee Jones, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, May 20, 2021 at 6:37 PM Marc Zyngier <maz@kernel.org> wrote:

> Wouldn't it be nice if the irqdomain
> would cache the irq_desc instead of forcing the core code to look it
> up on each and every interrupt? This is what this long series is all
> about.

For gpio and pinctrl bulk conversions:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

I agree that Rob's idea to create a bitmap walker may be helpful
if you have the energy for it, but this as a whole is nevertheless good.

Do they have to be applied en masse?

I think there could be some clashes and new drivers that will
create weirdness in that case so an immutable branch for
maintainers to pull in will be needed if you want it all in the
next merge window.

Unless you plan to merge the bottom
patches and then let subsystem maintainers convert each
subsystem in the next merge window.

Or a base to be pulled in and then each subsystem can
apply the bulk conversion to their subsystem only.

So looking for a merging strategy!

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/39] mfd: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 31/39] mfd: " Marc Zyngier
@ 2021-05-21  7:06   ` Lee Jones
  0 siblings, 0 replies; 65+ messages in thread
From: Lee Jones @ 2021-05-21  7:06 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

On Thu, 20 May 2021, Marc Zyngier wrote:

> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/mfd/db8500-prcmu.c    |  2 +-
>  drivers/mfd/fsl-imx25-tsadc.c |  4 ++--
>  drivers/mfd/ioc3.c            | 10 +++-------
>  drivers/mfd/qcom-pm8xxx.c     | 10 ++++------
>  4 files changed, 10 insertions(+), 16 deletions(-)

If the premise is solid, the code looks fine, so:

Acked-by: Lee Jones <lee.jones@linaro.org>

-- 
Lee Jones [李琼斯]
Senior Technical Lead - Developer Services
Linaro.org │ Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 03/39] mfd: ioc3: Directly include linux/irqdomain.h
  2021-05-20 16:37 ` [PATCH 03/39] mfd: ioc3: Directly include linux/irqdomain.h Marc Zyngier
@ 2021-05-21  7:07   ` Lee Jones
  0 siblings, 0 replies; 65+ messages in thread
From: Lee Jones @ 2021-05-21  7:07 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

On Thu, 20 May 2021, Marc Zyngier wrote:

> This driver include linux/irqdomain.h via a bizarre set of
> indirection, which we are about to break.
> 
> Directly include the required file.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/mfd/ioc3.c | 1 +
>  1 file changed, 1 insertion(+)

Applied, thanks.

-- 
Lee Jones [李琼斯]
Senior Technical Lead - Developer Services
Linaro.org │ Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq() Marc Zyngier
@ 2021-05-21  8:54   ` Geert Uytterhoeven
  2021-05-21 21:10   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 65+ messages in thread
From: Geert Uytterhoeven @ 2021-05-21  8:54 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Linux Kernel Mailing List, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, May 20, 2021 at 6:57 PM Marc Zyngier <maz@kernel.org> wrote:
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>

>  drivers/irqchip/irq-renesas-irqc.c     |  2 +-

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 30/39] PCI: " Marc Zyngier
  2021-05-20 17:47   ` Rob Herring
@ 2021-05-21  8:57   ` Geert Uytterhoeven
  1 sibling, 0 replies; 65+ messages in thread
From: Geert Uytterhoeven @ 2021-05-21  8:57 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Linux Kernel Mailing List, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, May 20, 2021 at 6:57 PM Marc Zyngier <maz@kernel.org> wrote:
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>

>  drivers/pci/controller/pcie-rcar-host.c        |  8 +++-----

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 28/39] gpio: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 28/39] gpio: " Marc Zyngier
@ 2021-05-21  8:59   ` Geert Uytterhoeven
  0 siblings, 0 replies; 65+ messages in thread
From: Geert Uytterhoeven @ 2021-05-21  8:59 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Linux Kernel Mailing List, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, May 20, 2021 at 6:57 PM Marc Zyngier <maz@kernel.org> wrote:
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>

>  drivers/gpio/gpio-em.c           |  2 +-
>  drivers/gpio/gpio-rcar.c         |  4 ++--

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq() Marc Zyngier
  2021-05-21  8:54   ` Geert Uytterhoeven
@ 2021-05-21 21:10   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2021-05-21 21:10 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Rob Herring,
	Bjorn Helgaas, Bartosz Golaszewski, kernel-team

On 20/05/2021 12:37, Marc Zyngier wrote:
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  drivers/irqchip/exynos-combiner.c      | 10 ++++------

For Exynos:
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 29/39] pinctrl: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 29/39] pinctrl: " Marc Zyngier
@ 2021-05-21 21:16   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2021-05-21 21:16 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Rob Herring,
	Bjorn Helgaas, Bartosz Golaszewski, kernel-team

On 20/05/2021 12:37, Marc Zyngier wrote:
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---


>  drivers/pinctrl/samsung/pinctrl-exynos.c   | 15 ++++++-------
>  drivers/pinctrl/samsung/pinctrl-s3c24xx.c  | 25 +++++++++-------------
>  drivers/pinctrl/samsung/pinctrl-s3c64xx.c  | 17 ++++++---------
For Samsung:
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

I cannot provide you testing at the moment.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 34/39] ARM: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 34/39] ARM: " Marc Zyngier
  2021-05-20 18:04   ` Rob Herring
@ 2021-05-21 21:17   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 65+ messages in thread
From: Krzysztof Kozlowski @ 2021-05-21 21:17 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Rob Herring,
	Bjorn Helgaas, Bartosz Golaszewski, kernel-team

On 20/05/2021 12:37, Marc Zyngier wrote:
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++----
>  arch/arm/mach-s3c/irq-s3c24xx.c    | 5 ++---

For S3C:

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>


Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 34/39] ARM: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 18:04   ` Rob Herring
@ 2021-05-24  8:32     ` Marc Zyngier
  0 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-24  8:32 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, 20 May 2021 19:04:17 +0100,
Rob Herring <robh@kernel.org> wrote:
> 
> On Thu, May 20, 2021 at 11:58 AM Marc Zyngier <maz@kernel.org> wrote:
> >
> > Wherever possible, replace constructs that match either
> > generic_handle_irq(irq_find_mapping()) or
> > generic_handle_irq(irq_linear_revmap()) to a single call to
> > generic_handle_domain_irq().
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++----
> >  arch/arm/mach-s3c/irq-s3c24xx.c    | 5 ++---
> >  2 files changed, 4 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c
> > index ec0d9b094744..ce1bbabbad54 100644
> > --- a/arch/arm/mach-pxa/pxa_cplds_irqs.c
> > +++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c
> > @@ -39,10 +39,8 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d)
> >
> >         do {
> >                 pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
> > -               for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
> > -                       generic_handle_irq(irq_find_mapping(fpga->irqdomain,
> > -                                                           bit));
> > -               }
> > +               for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
> > +                       generic_handle_domain_irq(fpga->irqdomain, bit);
> 
> We see this pattern a bit, I'm wondering if we can come up with a
> common helper. For an even longer name, something like:
> 
> generic_handle_domain_irq_for_bitmap(fpga->irqdomain, &pending, CPLDS_NB_IRQ);

Maybe. However, people may want to (should?) do something when
generic_handle_domain_irq() returns an error, and this wrapper would
hide the error entirely (and being a secondary interrupt controller,
things are as non-standard as you can imagine them).

If we can come up with a common approach for most of the bitmap-driven
I'd be happy to add something to that effect. Not as part of this
series though.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 17:47   ` Rob Herring
@ 2021-05-24  8:38     ` Marc Zyngier
  2021-05-24 13:28       ` Rob Herring
  0 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-24  8:38 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Thu, 20 May 2021 18:47:06 +0100,
Rob Herring <robh@kernel.org> wrote:
> 
> On Thu, May 20, 2021 at 11:57 AM Marc Zyngier <maz@kernel.org> wrote:
> >
> > Wherever possible, replace constructs that match either
> > generic_handle_irq(irq_find_mapping()) or
> > generic_handle_irq(irq_linear_revmap()) to a single call to
> > generic_handle_domain_irq().
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> >  drivers/pci/controller/dwc/pci-dra7xx.c        | 14 +++++---------
> >  drivers/pci/controller/dwc/pci-keystone.c      |  5 ++---
> >  .../pci/controller/dwc/pcie-designware-host.c  |  9 ++++-----
> >  drivers/pci/controller/dwc/pcie-uniphier.c     |  6 ++----
> >  .../controller/mobiveil/pcie-mobiveil-host.c   | 15 ++++++---------
> >  drivers/pci/controller/pci-aardvark.c          |  5 ++---
> >  drivers/pci/controller/pci-ftpci100.c          |  2 +-
> >  drivers/pci/controller/pci-tegra.c             |  8 +++-----
> >  drivers/pci/controller/pci-xgene-msi.c         |  9 +++------
> >  drivers/pci/controller/pcie-altera-msi.c       | 10 ++++------
> >  drivers/pci/controller/pcie-altera.c           | 10 ++++------
> >  drivers/pci/controller/pcie-brcmstb.c          |  9 ++++-----
> >  drivers/pci/controller/pcie-iproc-msi.c        |  4 +---
> >  drivers/pci/controller/pcie-mediatek-gen3.c    | 13 ++++---------
> >  drivers/pci/controller/pcie-mediatek.c         | 12 ++++--------
> >  drivers/pci/controller/pcie-microchip-host.c   | 18 +++++++-----------
> >  drivers/pci/controller/pcie-rcar-host.c        |  8 +++-----
> >  drivers/pci/controller/pcie-rockchip-host.c    |  8 +++-----
> >  drivers/pci/controller/pcie-xilinx-cpm.c       |  4 ++--
> >  drivers/pci/controller/pcie-xilinx-nwl.c       | 13 +++----------
> >  drivers/pci/controller/pcie-xilinx.c           |  9 ++++-----
> >  21 files changed, 71 insertions(+), 120 deletions(-)
> 
> 
> > diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c
> > index 1c34c897a7e2..cf3832b905e8 100644
> > --- a/drivers/pci/controller/pci-xgene-msi.c
> > +++ b/drivers/pci/controller/pci-xgene-msi.c
> > @@ -291,8 +291,7 @@ static void xgene_msi_isr(struct irq_desc *desc)
> >         struct irq_chip *chip = irq_desc_get_chip(desc);
> >         struct xgene_msi_group *msi_groups;
> >         struct xgene_msi *xgene_msi;
> > -       unsigned int virq;
> > -       int msir_index, msir_val, hw_irq;
> > +       int msir_index, msir_val, hw_irq, ret;
> >         u32 intr_index, grp_select, msi_grp;
> >
> >         chained_irq_enter(chip, desc);
> > @@ -330,10 +329,8 @@ static void xgene_msi_isr(struct irq_desc *desc)
> >                          * CPU0
> >                          */
> >                         hw_irq = hwirq_to_canonical_hwirq(hw_irq);
> > -                       virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq);
> > -                       WARN_ON(!virq);
> > -                       if (virq != 0)
> > -                               generic_handle_irq(virq);
> > +                       ret = generic_handle_domain_irq(xgene_msi->inner_domain, hw_irq);
> > +                       WARN_ON(ret);
> 
> There's various error prints in some of the handlers. I think they
> should be moved to the core. I can't imagine handling the irq is ever
> optional.

Printing stuff like this is a sure recipe for disaster, and there is
no way I'm moving such crap into core code. If the interrupt handling
fails (most likely because there is no mapping for this interrupt), it
is the driver's responsibility to handle the error (either disabling
the input or the output of the secondary irqchip). There isn't much
the core code can do about it.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/39] irqdomain: Simplify interrupt handling
  2021-05-20 23:33 ` [PATCH 00/39] irqdomain: Simplify interrupt handling Linus Walleij
@ 2021-05-24  8:53   ` Marc Zyngier
  2021-05-24  9:39     ` Linus Walleij
  0 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-05-24  8:53 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Lee Jones, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Fri, 21 May 2021 00:33:58 +0100,
Linus Walleij <linus.walleij@linaro.org> wrote:
> 
> On Thu, May 20, 2021 at 6:37 PM Marc Zyngier <maz@kernel.org> wrote:
> 
> > Wouldn't it be nice if the irqdomain
> > would cache the irq_desc instead of forcing the core code to look it
> > up on each and every interrupt? This is what this long series is all
> > about.
> 
> For gpio and pinctrl bulk conversions:
> Acked-by: Linus Walleij <linus.walleij@linaro.org>

Thanks for that.

> I agree that Rob's idea to create a bitmap walker may be helpful
> if you have the energy for it, but this as a whole is nevertheless
> good.

I'll look into that once I figure out a good solution for handling
errors, which the caller should most probably be made aware of.

> Do they have to be applied en masse?

Not necessarily. As long as the initial infrastructure is in place,
maintainers can take the subsequent patches on their own time, as all
the original APIs are preserved.

> I think there could be some clashes and new drivers that will
> create weirdness in that case so an immutable branch for
> maintainers to pull in will be needed if you want it all in the
> next merge window.
> 
> Unless you plan to merge the bottom
> patches and then let subsystem maintainers convert each
> subsystem in the next merge window.
> 
> Or a base to be pulled in and then each subsystem can
> apply the bulk conversion to their subsystem only.

This last option is my preferred approach for busy subsystems. I'm
happy to take care of irqchip and of the quieter architectures such as
NIOS2 and SH, and leave the rest to their respective maintainers.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/39] irqdomain: Simplify interrupt handling
  2021-05-24  8:53   ` Marc Zyngier
@ 2021-05-24  9:39     ` Linus Walleij
  0 siblings, 0 replies; 65+ messages in thread
From: Linus Walleij @ 2021-05-24  9:39 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Lee Jones, Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Mon, May 24, 2021 at 10:53 AM Marc Zyngier <maz@kernel.org> wrote:

> > Or a base to be pulled in and then each subsystem can
> > apply the bulk conversion to their subsystem only.
>
> This last option is my preferred approach for busy subsystems. I'm
> happy to take care of irqchip and of the quieter architectures such as
> NIOS2 and SH, and leave the rest to their respective maintainers.

OK once the dust settles on the series just send a pull request to
me for pin control and to Bartosz for GPIO and we can pull that
in and do the bulk conversion on top.

Thanks!
Linus Walleij

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
  2021-05-24  8:38     ` Marc Zyngier
@ 2021-05-24 13:28       ` Rob Herring
  2021-05-24 15:06         ` Marc Zyngier
  0 siblings, 1 reply; 65+ messages in thread
From: Rob Herring @ 2021-05-24 13:28 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Mon, May 24, 2021 at 3:38 AM Marc Zyngier <maz@kernel.org> wrote:
>
> On Thu, 20 May 2021 18:47:06 +0100,
> Rob Herring <robh@kernel.org> wrote:
> >
> > On Thu, May 20, 2021 at 11:57 AM Marc Zyngier <maz@kernel.org> wrote:
> > >
> > > Wherever possible, replace constructs that match either
> > > generic_handle_irq(irq_find_mapping()) or
> > > generic_handle_irq(irq_linear_revmap()) to a single call to
> > > generic_handle_domain_irq().
> > >
> > > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > > ---
> > >  drivers/pci/controller/dwc/pci-dra7xx.c        | 14 +++++---------
> > >  drivers/pci/controller/dwc/pci-keystone.c      |  5 ++---
> > >  .../pci/controller/dwc/pcie-designware-host.c  |  9 ++++-----
> > >  drivers/pci/controller/dwc/pcie-uniphier.c     |  6 ++----
> > >  .../controller/mobiveil/pcie-mobiveil-host.c   | 15 ++++++---------
> > >  drivers/pci/controller/pci-aardvark.c          |  5 ++---
> > >  drivers/pci/controller/pci-ftpci100.c          |  2 +-
> > >  drivers/pci/controller/pci-tegra.c             |  8 +++-----
> > >  drivers/pci/controller/pci-xgene-msi.c         |  9 +++------
> > >  drivers/pci/controller/pcie-altera-msi.c       | 10 ++++------
> > >  drivers/pci/controller/pcie-altera.c           | 10 ++++------
> > >  drivers/pci/controller/pcie-brcmstb.c          |  9 ++++-----
> > >  drivers/pci/controller/pcie-iproc-msi.c        |  4 +---
> > >  drivers/pci/controller/pcie-mediatek-gen3.c    | 13 ++++---------
> > >  drivers/pci/controller/pcie-mediatek.c         | 12 ++++--------
> > >  drivers/pci/controller/pcie-microchip-host.c   | 18 +++++++-----------
> > >  drivers/pci/controller/pcie-rcar-host.c        |  8 +++-----
> > >  drivers/pci/controller/pcie-rockchip-host.c    |  8 +++-----
> > >  drivers/pci/controller/pcie-xilinx-cpm.c       |  4 ++--
> > >  drivers/pci/controller/pcie-xilinx-nwl.c       | 13 +++----------
> > >  drivers/pci/controller/pcie-xilinx.c           |  9 ++++-----
> > >  21 files changed, 71 insertions(+), 120 deletions(-)
> >
> >
> > > diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c
> > > index 1c34c897a7e2..cf3832b905e8 100644
> > > --- a/drivers/pci/controller/pci-xgene-msi.c
> > > +++ b/drivers/pci/controller/pci-xgene-msi.c
> > > @@ -291,8 +291,7 @@ static void xgene_msi_isr(struct irq_desc *desc)
> > >         struct irq_chip *chip = irq_desc_get_chip(desc);
> > >         struct xgene_msi_group *msi_groups;
> > >         struct xgene_msi *xgene_msi;
> > > -       unsigned int virq;
> > > -       int msir_index, msir_val, hw_irq;
> > > +       int msir_index, msir_val, hw_irq, ret;
> > >         u32 intr_index, grp_select, msi_grp;
> > >
> > >         chained_irq_enter(chip, desc);
> > > @@ -330,10 +329,8 @@ static void xgene_msi_isr(struct irq_desc *desc)
> > >                          * CPU0
> > >                          */
> > >                         hw_irq = hwirq_to_canonical_hwirq(hw_irq);
> > > -                       virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq);
> > > -                       WARN_ON(!virq);
> > > -                       if (virq != 0)
> > > -                               generic_handle_irq(virq);
> > > +                       ret = generic_handle_domain_irq(xgene_msi->inner_domain, hw_irq);
> > > +                       WARN_ON(ret);
> >
> > There's various error prints in some of the handlers. I think they
> > should be moved to the core. I can't imagine handling the irq is ever
> > optional.
>
> Printing stuff like this is a sure recipe for disaster, and there is
> no way I'm moving such crap into core code.

Then why maintain such crap code? I'm fine with just removing. I just
think we should have some consistency.

> If the interrupt handling
> fails (most likely because there is no mapping for this interrupt), it
> is the driver's responsibility to handle the error (either disabling
> the input or the output of the secondary irqchip). There isn't much
> the core code can do about it.

I would imagine the errors here would be the 'this should never
happen' kind. Maybe a race with tearing down the domain. Seems to me
the core code should be warning when the calling code has made
mistakes.

Rob

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
  2021-05-24 13:28       ` Rob Herring
@ 2021-05-24 15:06         ` Marc Zyngier
  0 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-05-24 15:06 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Bjorn Helgaas,
	Bartosz Golaszewski, Android Kernel Team

On Mon, 24 May 2021 14:28:42 +0100,
Rob Herring <robh@kernel.org> wrote:
> 
> On Mon, May 24, 2021 at 3:38 AM Marc Zyngier <maz@kernel.org> wrote:
> >
> > On Thu, 20 May 2021 18:47:06 +0100,
> > Rob Herring <robh@kernel.org> wrote:
> > >
> > > On Thu, May 20, 2021 at 11:57 AM Marc Zyngier <maz@kernel.org> wrote:
> > > >
> > > > Wherever possible, replace constructs that match either
> > > > generic_handle_irq(irq_find_mapping()) or
> > > > generic_handle_irq(irq_linear_revmap()) to a single call to
> > > > generic_handle_domain_irq().
> > > >
> > > > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > > > ---
> > > >  drivers/pci/controller/dwc/pci-dra7xx.c        | 14 +++++---------
> > > >  drivers/pci/controller/dwc/pci-keystone.c      |  5 ++---
> > > >  .../pci/controller/dwc/pcie-designware-host.c  |  9 ++++-----
> > > >  drivers/pci/controller/dwc/pcie-uniphier.c     |  6 ++----
> > > >  .../controller/mobiveil/pcie-mobiveil-host.c   | 15 ++++++---------
> > > >  drivers/pci/controller/pci-aardvark.c          |  5 ++---
> > > >  drivers/pci/controller/pci-ftpci100.c          |  2 +-
> > > >  drivers/pci/controller/pci-tegra.c             |  8 +++-----
> > > >  drivers/pci/controller/pci-xgene-msi.c         |  9 +++------
> > > >  drivers/pci/controller/pcie-altera-msi.c       | 10 ++++------
> > > >  drivers/pci/controller/pcie-altera.c           | 10 ++++------
> > > >  drivers/pci/controller/pcie-brcmstb.c          |  9 ++++-----
> > > >  drivers/pci/controller/pcie-iproc-msi.c        |  4 +---
> > > >  drivers/pci/controller/pcie-mediatek-gen3.c    | 13 ++++---------
> > > >  drivers/pci/controller/pcie-mediatek.c         | 12 ++++--------
> > > >  drivers/pci/controller/pcie-microchip-host.c   | 18 +++++++-----------
> > > >  drivers/pci/controller/pcie-rcar-host.c        |  8 +++-----
> > > >  drivers/pci/controller/pcie-rockchip-host.c    |  8 +++-----
> > > >  drivers/pci/controller/pcie-xilinx-cpm.c       |  4 ++--
> > > >  drivers/pci/controller/pcie-xilinx-nwl.c       | 13 +++----------
> > > >  drivers/pci/controller/pcie-xilinx.c           |  9 ++++-----
> > > >  21 files changed, 71 insertions(+), 120 deletions(-)
> > >
> > >
> > > > diff --git a/drivers/pci/controller/pci-xgene-msi.c b/drivers/pci/controller/pci-xgene-msi.c
> > > > index 1c34c897a7e2..cf3832b905e8 100644
> > > > --- a/drivers/pci/controller/pci-xgene-msi.c
> > > > +++ b/drivers/pci/controller/pci-xgene-msi.c
> > > > @@ -291,8 +291,7 @@ static void xgene_msi_isr(struct irq_desc *desc)
> > > >         struct irq_chip *chip = irq_desc_get_chip(desc);
> > > >         struct xgene_msi_group *msi_groups;
> > > >         struct xgene_msi *xgene_msi;
> > > > -       unsigned int virq;
> > > > -       int msir_index, msir_val, hw_irq;
> > > > +       int msir_index, msir_val, hw_irq, ret;
> > > >         u32 intr_index, grp_select, msi_grp;
> > > >
> > > >         chained_irq_enter(chip, desc);
> > > > @@ -330,10 +329,8 @@ static void xgene_msi_isr(struct irq_desc *desc)
> > > >                          * CPU0
> > > >                          */
> > > >                         hw_irq = hwirq_to_canonical_hwirq(hw_irq);
> > > > -                       virq = irq_find_mapping(xgene_msi->inner_domain, hw_irq);
> > > > -                       WARN_ON(!virq);
> > > > -                       if (virq != 0)
> > > > -                               generic_handle_irq(virq);
> > > > +                       ret = generic_handle_domain_irq(xgene_msi->inner_domain, hw_irq);
> > > > +                       WARN_ON(ret);
> > >
> > > There's various error prints in some of the handlers. I think they
> > > should be moved to the core. I can't imagine handling the irq is ever
> > > optional.
> >
> > Printing stuff like this is a sure recipe for disaster, and there is
> > no way I'm moving such crap into core code.
> 
> Then why maintain such crap code? I'm fine with just removing. I just
> think we should have some consistency.

Then by any mean, remove it. I'd even be tempted to say "remove the
driver", but there is an XGene-1 box right behind me...

> 
> > If the interrupt handling
> > fails (most likely because there is no mapping for this interrupt), it
> > is the driver's responsibility to handle the error (either disabling
> > the input or the output of the secondary irqchip). There isn't much
> > the core code can do about it.
> 
> I would imagine the errors here would be the 'this should never
> happen' kind. Maybe a race with tearing down the domain. Seems to me
> the core code should be warning when the calling code has made
> mistakes.

The core code already returns an error, which is plenty. It doesn't
have the context to actually *do* anything, and I don't think moaning
on the console helps much.

The onus is firmly on the caller side to get their act together.

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/39] irqdomain: Simplify interrupt handling
  2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
                   ` (39 preceding siblings ...)
  2021-05-20 23:33 ` [PATCH 00/39] irqdomain: Simplify interrupt handling Linus Walleij
@ 2021-06-01 14:29 ` Marc Zyngier
  40 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-06-01 14:29 UTC (permalink / raw)
  To: linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

On Thu, 20 May 2021 17:37:12 +0100,
Marc Zyngier <maz@kernel.org> wrote:
> 
> Although most device drivers only deal with an interrupt number, the
> core IRQ code is mostly concerned with the irq_desc structure that
> describes the full interrupt context (hierarchy, handlers, state).
> 
> However, the low-level interrupt handling code that relies on the
> irqdomain abstraction has to perform an annoying dance to eventually
> get the core code to invoke interrupt handlers: the irqdomain code
> converts a low-level identifier to the unique Linux interrupt number,
> and the core code resolves this into an irq_desc pointer.
> 
> Each of these two lookups ends-up parsing a radix tree (although the
> irqdomain code can use a linear mapping for the smallest domains),
> which is obviously one too many. Wouldn't it be nice if the irqdomain
> would cache the irq_desc instead of forcing the core code to look it
> up on each and every interrupt? This is what this long series is all
> about.
> 
> There is roughly 3 parts here:
> 
> - a substantial amount of massaging for some architectures (nios, mips
>   and powerpc) to disentangle weird include constructs (asm/irq.h
>   including linux/irqdomain.h is pretty bad...) and simplify bits of
>   the irqdomain code
> 
> - some rework of the irqdomain code to allow the caching of a irq_data
>   pointer, unify the RCU behaviour and offer new APIs.
> 
> - Perform a bulk of conversions that turn constructs similar to
>   generic_handle_irq(irq_find_mapping(domain, hwirq)) into a simpler
>   call to generic_handle_domain_irq(domain, hwirq). Yes, this is a
>   mouthful.
> 
> I've kept most of the conversions per-subsystem/per-arch in order to
> keep the number of patches low (though it is debatable whether I have
> succeeded).
> 
> This ends up with a negative diffstat, so it can't be completely bad!
> Given the breadth of the changes, I do expect some breakage, although
> I've extensively compile-tested it and the kbuild robot has been
> invaluable in helping with the coverage.

Slight nudge in the direction of the cc'd arch maintainers. I'd like
to take the core of this series into -next (in practice, patches #1
through to #27). Any comment on the early, arch-specific patches would
be most welcome.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 36/39] arc: Bulk conversion to generic_handle_domain_irq()
  2021-05-20 16:37 ` [PATCH 36/39] arc: " Marc Zyngier
@ 2021-06-01 18:00   ` Vineet Gupta
  0 siblings, 0 replies; 65+ messages in thread
From: Vineet Gupta @ 2021-06-01 18:00 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

On 5/20/21 9:37 AM, Marc Zyngier wrote:
> Wherever possible, replace constructs that match either
> generic_handle_irq(irq_find_mapping()) or
> generic_handle_irq(irq_linear_revmap()) to a single call to
> generic_handle_domain_irq().
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>

Thx for doing this Marc.

Acked-by: Vineet Gupta <vgupta@synopsys.com>

-Vineet

> ---
>   arch/arc/kernel/mcip.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c
> index abf9398cc333..f9fdb557c263 100644
> --- a/arch/arc/kernel/mcip.c
> +++ b/arch/arc/kernel/mcip.c
> @@ -352,7 +352,7 @@ static void idu_cascade_isr(struct irq_desc *desc)
>   	irq_hw_number_t idu_hwirq = core_hwirq - FIRST_EXT_IRQ;
>   
>   	chained_irq_enter(core_chip, desc);
> -	generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq));
> +	generic_handle_domain_irq(idu_domain, idu_hwirq);
>   	chained_irq_exit(core_chip, desc);
>   }
>   


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping()
  2021-05-20 16:37 ` [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping() Marc Zyngier
@ 2021-06-10  2:22   ` Qian Cai
  2021-06-10  7:24     ` Marc Zyngier
  0 siblings, 1 reply; 65+ messages in thread
From: Qian Cai @ 2021-06-10  2:22 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, Benjamin Herrenschmidt,
	Paul Mackerras, Ley Foon Tan, Chris Zankel, Max Filippov,
	Vineet Gupta, Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team



On 5/20/2021 12:37 PM, Marc Zyngier wrote:
> Rework irq_find_mapping() to return an irq_desc pointer, and
> rename the result to irq_resolve_mapping().
> 
> irq_find_mapping() is then rewritten in terms of ir_resolve_mapping().
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>

Marc, there is an use-after-free that "git blame" pointed to this commit. Any thoughts?

__irq_resolve_mapping+0x34c/0x360:
__irq_resolve_mapping at /usr/src/linux-next/kernel/irq/irqdomain.c:917

[   52.773282][    C0] BUG: KASAN: use-after-free in __irq_resolve_mapping+0x34c/0x360
[   52.780946][    C0] Read of size 8 at addr ffff00005e8e4950 by task swapper/0/0
[   52.788256][    C0]
[   52.790441][    C0] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W         5.13.0-rc5-next-20210609+ #22
[   52.800181][    C0] Hardware name: MiTAC RAPTOR EV-883832-X3-0001/RAPTOR, BIOS 1.6 06/28/2020
[   52.808706][    C0] Call trace:
[   52.811845][    C0]  dump_backtrace+0x0/0x3b8
[   52.816207][    C0]  show_stack+0x20/0x30
[   52.820217][    C0]  dump_stack_lvl+0x144/0x190
[   52.824749][    C0]  print_address_description.constprop.0+0x74/0x3c8
[   52.831191][    C0]  kasan_report+0x1f0/0x208
[   52.835548][    C0]  __asan_report_load8_noabort+0x34/0x60
[   52.841034][    C0]  __irq_resolve_mapping+0x34c/0x360
[   52.846171][    C0]  handle_domain_irq+0x88/0x168
[   52.850875][    C0]  gic_handle_irq+0x5c/0x150
[   52.855319][    C0]  call_on_irq_stack+0x28/0x50
[   52.859936][    C0]  do_interrupt_handler+0x80/0xa8
[   52.864813][    C0]  el1_interrupt+0x30/0x48
[   52.869083][    C0]  el1h_64_irq_handler+0x18/0x28
[   52.873874][    C0]  el1h_64_irq+0x74/0x78
[   52.877968][    C0]  cpuidle_enter_state+0x2a4/0xff0
[   52.882934][    C0]  cpuidle_enter+0x60/0xb0
[   52.887203][    C0]  call_cpuidle+0x44/0xc0
[   52.891385][    C0]  do_idle+0x36c/0x420
[   52.895306][    C0]  cpu_startup_entry+0x30/0x88
[   52.899923][    C0]  rest_init+0x380/0x4f0
[   52.904017][    C0]  arch_call_rest_init+0x18/0x24
[   52.908809][    C0]  start_kernel+0x3b4/0x3ec
[   52.913165][    C0]  __primary_switched+0xc0/0xc8
[   52.917869][    C0]
[   52.920051][    C0] Allocated by task 7:
[   52.923970][    C0]  kasan_save_stack+0x28/0x58
[   52.928500][    C0]  __kasan_kmalloc+0x8c/0xb0
[   52.932942][    C0]  kmem_cache_alloc_node_trace+0x288/0x3c8
[   52.938600][    C0]  __irq_domain_alloc_irqs+0x110/0x738
[   52.943911][    C0]  __msi_domain_alloc_irqs+0x1f8/0xc18
[   52.949221][    C0]  msi_domain_alloc_irqs+0x78/0xd0
[   52.954184][    C0]  pci_msi_setup_msi_irqs.isra.0+0x78/0xb8
[   52.959843][    C0]  __pci_enable_msix_range+0x5d8/0xc10
[   52.965152][    C0]  pci_alloc_irq_vectors_affinity+0x144/0x1e8
[   52.971069][    C0]  nvme_reset_work+0x338/0x2aa4 [nvme]
[   52.976391][    C0]  process_one_work+0x7e4/0x1998
[   52.981182][    C0]  worker_thread+0x334/0xad0
[   52.985623][    C0]  kthread+0x3ac/0x460
[   52.989545][    C0]  ret_from_fork+0x10/0x18
[   52.993813][    C0]
[   52.995995][    C0] Freed by task 7:
[   52.999567][    C0]  kasan_save_stack+0x28/0x58
[   53.004100][    C0]  kasan_set_track+0x28/0x40
[   53.008548][    C0]  kasan_set_free_info+0x28/0x50
[   53.013339][    C0]  __kasan_slab_free+0xfc/0x150
[   53.018042][    C0]  slab_free_freelist_hook+0x128/0x258
[   53.023353][    C0]  kfree+0x150/0x4c0
[   53.027100][    C0]  irq_domain_free_irq_data+0x94/0xe0
[   53.032323][    C0]  irq_domain_free_irqs+0x200/0x2d0
[   53.037373][    C0]  __msi_domain_free_irqs+0xbc/0x138
[   53.042509][    C0]  msi_domain_free_irqs+0x78/0xb8
[   53.047385][    C0]  free_msi_irqs+0x420/0x598
[   53.051827][    C0]  pci_disable_msix+0x250/0x330
[   53.056528][    C0]  pci_free_irq_vectors+0x20/0x38
[   53.061404][    C0]  nvme_reset_work+0x11dc/0x2aa4 [nvme]
[   53.066809][    C0]  process_one_work+0x7e4/0x1998
[   53.071599][    C0]  worker_thread+0x334/0xad0
[   53.076040][    C0]  kthread+0x3ac/0x460
[   53.079962][    C0]  ret_from_fork+0x10/0x18
[   53.084230][    C0]
[   53.086411][    C0] The buggy address belongs to the object at ffff00005e8e4940
[   53.086411][    C0]  which belongs to the cache kmalloc-64 of size 64
[   53.100141][    C0] The buggy address is located 16 bytes inside of
[   53.100141][    C0]  64-byte region [ffff00005e8e4940, ffff00005e8e4980)
[   53.113090][    C0] The buggy address belongs to the page:
[   53.118574][    C0] page:ffffffc00017a380 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xde8e
[   53.128486][    C0] flags: 0x7ffff800000200(slab|node=0|zone=0|lastcpupid=0xfffff)
[   53.136059][    C0] raw: 007ffff800000200 ffffffc00211b648 ffffffc00211ec88 ffff0000129103c0
[   53.144494][    C0] raw: 0000000000000000 0000000001000100 00000001ffffffff 0000000000000000
[   53.152927][    C0] page dumped because: kasan: bad access detected
[   53.159189][    C0]
[   53.161371][    C0] Memory state around the buggy address:
[   53.166853][    C0]  ffff00005e8e4800: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
[   53.174765][    C0]  ffff00005e8e4880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[   53.182678][    C0] >ffff00005e8e4900: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
[   53.190590][    C0]                                                  ^
[   53.197114][    C0]  ffff00005e8e4980: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[   53.205027][    C0]  ffff00005e8e4a00: fc fc fc fc fc fc fc fc 00 00 00 00 00 00 00 00
[   53.212939][    C0] ==================================================================
[   53.220850][    C0] Disabling lock debugging due to kernel taint
[   53.226850][    C0] irq 320, desc: ffff000840982800, depth: 1, count: 0, unhandled: 0
[   53.234672][    C0] ->handle_irq():  ffff800010258d30, handle_bad_irq+0x0/0x570
[   53.241980][    C0] ->irq_data.chip(): ffff800018d20520, no_irq_chip+0x0/0x760
[   53.241988][    C0] ->action(): 0000000000000000


> ---
>  include/linux/irqdomain.h | 18 +++++++++++++++---
>  kernel/irq/irqdomain.c    | 22 ++++++++++++++--------
>  2 files changed, 29 insertions(+), 11 deletions(-)
> 
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index 2b696c9bcaaf..189f559fb26c 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -31,7 +31,8 @@
>  #define _LINUX_IRQDOMAIN_H
>  
>  #include <linux/types.h>
> -#include <linux/irqhandler.h>
> +#include <linux/irq.h>
> +#include <linux/irqdesc.h>
>  #include <linux/of.h>
>  #include <linux/mutex.h>
>  #include <linux/radix-tree.h>
> @@ -401,13 +402,24 @@ static inline unsigned int irq_create_mapping(struct irq_domain *host,
>  	return irq_create_mapping_affinity(host, hwirq, NULL);
>  }
>  
> +extern struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
> +					    irq_hw_number_t hwirq);
> +
>  /**
>   * irq_find_mapping() - Find a linux irq from a hw irq number.
>   * @domain: domain owning this hardware interrupt
>   * @hwirq: hardware irq number in that domain space
>   */
> -extern unsigned int irq_find_mapping(struct irq_domain *host,
> -				     irq_hw_number_t hwirq);
> +static inline unsigned int irq_find_mapping(struct irq_domain *domain,
> +					    irq_hw_number_t hwirq)
> +{
> +	struct irq_desc *desc = irq_resolve_mapping(domain, hwirq);
> +
> +	if (unlikely(!desc))
> +		return 0;
> +
> +	return irq_desc_get_irq(desc);
> +}
>  
>  static inline unsigned int irq_linear_revmap(struct irq_domain *domain,
>  					     irq_hw_number_t hwirq)
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 8e55bb8c3073..13a3021e9370 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -876,29 +876,32 @@ void irq_dispose_mapping(unsigned int virq)
>  EXPORT_SYMBOL_GPL(irq_dispose_mapping);
>  
>  /**
> - * irq_find_mapping() - Find a linux irq from a hw irq number.
> + * irq_resolve_mapping() - Find a linux irq from a hw irq number.
>   * @domain: domain owning this hardware interrupt
>   * @hwirq: hardware irq number in that domain space
> + *
> + * Returns the interrupt descriptor.
>   */
> -unsigned int irq_find_mapping(struct irq_domain *domain,
> -			      irq_hw_number_t hwirq)
> +struct irq_desc *irq_resolve_mapping(struct irq_domain *domain,
> +				     irq_hw_number_t hwirq)
>  {
> +	struct irq_desc *desc = NULL;
>  	struct irq_data *data;
>  
>  	/* Look for default domain if necessary */
>  	if (domain == NULL)
>  		domain = irq_default_domain;
>  	if (domain == NULL)
> -		return 0;
> +		return desc;
>  
>  	if (irq_domain_is_nomap(domain)) {
>  		if (hwirq < domain->revmap_size) {
>  			data = irq_domain_get_irq_data(domain, hwirq);
>  			if (data && data->hwirq == hwirq)
> -				return hwirq;
> +				desc = irq_data_to_desc(data);
>  		}
>  
> -		return 0;
> +		return desc;
>  	}
>  
>  	rcu_read_lock();
> @@ -907,10 +910,13 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
>  		data = rcu_dereference(domain->revmap[hwirq]);
>  	else
>  		data = radix_tree_lookup(&domain->revmap_tree, hwirq);
> +
> +	if (likely(data))
> +		desc = irq_data_to_desc(data);
>  	rcu_read_unlock();
> -	return data ? data->irq : 0;
> +	return desc;
>  }
> -EXPORT_SYMBOL_GPL(irq_find_mapping);
> +EXPORT_SYMBOL_GPL(irq_resolve_mapping);
>  
>  /**
>   * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping()
  2021-06-10  2:22   ` Qian Cai
@ 2021-06-10  7:24     ` Marc Zyngier
  0 siblings, 0 replies; 65+ messages in thread
From: Marc Zyngier @ 2021-06-10  7:24 UTC (permalink / raw)
  To: Qian Cai
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman,
	Benjamin Herrenschmidt, Paul Mackerras, Ley Foon Tan,
	Chris Zankel, Max Filippov, Vineet Gupta, Thomas Bogendoerfer,
	Robert Jarzmik, Russell King, Krzysztof Kozlowski,
	Yoshinori Sato, Rich Felker, Geert Uytterhoeven, Alex Deucher,
	Christian König, David Airlie, Daniel Vetter, Rob Clark,
	Linus Walleij, Lee Jones, Lorenzo Pieralisi, Rob Herring,
	Bjorn Helgaas, Bartosz Golaszewski, kernel-team

On 2021-06-10 03:22, Qian Cai wrote:
> On 5/20/2021 12:37 PM, Marc Zyngier wrote:
>> Rework irq_find_mapping() to return an irq_desc pointer, and
>> rename the result to irq_resolve_mapping().
>> 
>> irq_find_mapping() is then rewritten in terms of ir_resolve_mapping().
>> 
>> Signed-off-by: Marc Zyngier <maz@kernel.org>
> 
> Marc, there is an use-after-free that "git blame" pointed to this
> commit. Any thoughts?
> 
> __irq_resolve_mapping+0x34c/0x360:
> __irq_resolve_mapping at /usr/src/linux-next/kernel/irq/irqdomain.c:917

Yup, this was reported yesterday by John Gary. I'm on it.

         M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 20/39] irqdomain: Protect the linear revmap with RCU
  2021-05-20 16:37 ` [PATCH 20/39] irqdomain: Protect the linear revmap with RCU Marc Zyngier
@ 2021-06-19 11:37   ` Thomas Gleixner
  0 siblings, 0 replies; 65+ messages in thread
From: Thomas Gleixner @ 2021-06-19 11:37 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel
  Cc: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	Ley Foon Tan, Chris Zankel, Max Filippov, Vineet Gupta,
	Thomas Bogendoerfer, Robert Jarzmik, Russell King,
	Krzysztof Kozlowski, Yoshinori Sato, Rich Felker,
	Geert Uytterhoeven, Alex Deucher, Christian König,
	David Airlie, Daniel Vetter, Rob Clark, Linus Walleij, Lee Jones,
	Lorenzo Pieralisi, Rob Herring, Bjorn Helgaas,
	Bartosz Golaszewski, kernel-team

On Thu, May 20 2021 at 17:37, Marc Zyngier wrote:
>  static void irq_domain_clear_mapping(struct irq_domain *domain,
> @@ -902,12 +901,12 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
>  		return 0;
>  	}
>  
> +	rcu_read_lock();
>  	/* Check if the hwirq is in the linear revmap. */
>  	if (hwirq < domain->revmap_size)
> -		return domain->revmap[hwirq]->irq;
> -
> -	rcu_read_lock();
> -	data = radix_tree_lookup(&domain->revmap_tree, hwirq);
> +		data = rcu_dereference(domain->revmap[hwirq]);
> +	else
> +		data = radix_tree_lookup(&domain->revmap_tree, hwirq);
>  	rcu_read_unlock();
>  	return data ? data->irq : 0;

This is wrong and was wrong before. This wants to be:

     irq = data ? data->irq : 0;
     rcu_read_unlock();
     return irq;

Thanks,

        tglx

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive
  2021-05-20 16:37 ` [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive Marc Zyngier
@ 2021-11-15 19:05   ` Cédric Le Goater
  2021-11-16  8:33     ` Marc Zyngier
  0 siblings, 1 reply; 65+ messages in thread
From: Cédric Le Goater @ 2021-11-15 19:05 UTC (permalink / raw)
  To: Marc Zyngier, linux-kernel
  Cc: Thomas Gleixner, Michael Ellerman, PowerPC, Greg Kurz

Hello Mark,

On 5/20/21 18:37, Marc Zyngier wrote:
> Direct mappings are completely exclusive of normal mappings, meaning
> that we can refactor the code slightly so that we can get rid of
> the revmap_direct_max_irq field and use the revmap_size field
> instead, reducing the size of the irqdomain structure.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>


This patch is breaking the POWER9/POWER10 XIVE driver (these are not
old PPC systems :) on machines sharing the same LSI HW IRQ. For instance,
a linux KVM guest with a virtio-rng and a virtio-balloon device. In that
case, Linux creates two distinct IRQ mappings which can lead to some
unexpected behavior.

A fix to go forward would be to change the XIVE IRQ domain to use a
'Tree' domain for reverse mapping and not the 'No Map' domain mapping.
I will keep you updated for XIVE.

Thanks,

C.


> ---
>   include/linux/irqdomain.h |  6 +++---
>   kernel/irq/irqdomain.c    | 45 ++++++++++++++++++++++++++++++---------
>   2 files changed, 38 insertions(+), 13 deletions(-)
> 
> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
> index 723495ec5a2f..0916cf9c6e20 100644
> --- a/include/linux/irqdomain.h
> +++ b/include/linux/irqdomain.h
> @@ -149,8 +149,6 @@ struct irq_domain_chip_generic;
>    * @parent: Pointer to parent irq_domain to support hierarchy irq_domains
>    *
>    * Revmap data, used internally by irq_domain
> - * @revmap_direct_max_irq: The largest hwirq that can be set for controllers that
> - *                         support direct mapping
>    * @revmap_size: Size of the linear map table @revmap[]
>    * @revmap_tree: Radix map tree for hwirqs that don't fit in the linear map
>    * @revmap: Linear table of hwirq->virq reverse mappings
> @@ -173,7 +171,6 @@ struct irq_domain {
>   
>   	/* reverse map data. The linear map gets appended to the irq_domain */
>   	irq_hw_number_t hwirq_max;
> -	unsigned int revmap_direct_max_irq;
>   	unsigned int revmap_size;
>   	struct radix_tree_root revmap_tree;
>   	struct mutex revmap_tree_mutex;
> @@ -207,6 +204,9 @@ enum {
>   	 */
>   	IRQ_DOMAIN_MSI_NOMASK_QUIRK	= (1 << 6),
>   
> +	/* Irq domain doesn't translate anything */
> +	IRQ_DOMAIN_FLAG_NO_MAP		= (1 << 7),
> +
>   	/*
>   	 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
>   	 * for implementation specific purposes and ignored by the
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index e0143e640683..fa94c86e47d4 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -146,6 +146,10 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
>   
>   	static atomic_t unknown_domains;
>   
> +	if (WARN_ON((size && direct_max) ||
> +		    (!IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) && direct_max)))
> +		return NULL;
> +
>   	domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
>   			      GFP_KERNEL, of_node_to_nid(to_of_node(fwnode)));
>   	if (!domain)
> @@ -213,8 +217,14 @@ struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, int size,
>   	domain->ops = ops;
>   	domain->host_data = host_data;
>   	domain->hwirq_max = hwirq_max;
> +
> +	if (direct_max) {
> +		size = direct_max;
> +		domain->flags |= IRQ_DOMAIN_FLAG_NO_MAP;
> +	}
> +
>   	domain->revmap_size = size;
> -	domain->revmap_direct_max_irq = direct_max;
> +
>   	irq_domain_check_hierarchy(domain);
>   
>   	mutex_lock(&irq_domain_mutex);
> @@ -482,9 +492,18 @@ struct irq_domain *irq_get_default_host(void)
>   	return irq_default_domain;
>   }
>   
> +static bool irq_domain_is_nomap(struct irq_domain *domain)
> +{
> +	return IS_ENABLED(CONFIG_IRQ_DOMAIN_NOMAP) &&
> +	       (domain->flags & IRQ_DOMAIN_FLAG_NO_MAP);
> +}
> +
>   static void irq_domain_clear_mapping(struct irq_domain *domain,
>   				     irq_hw_number_t hwirq)
>   {
> +	if (irq_domain_is_nomap(domain))
> +		return;
> +
>   	if (hwirq < domain->revmap_size) {
>   		domain->revmap[hwirq] = 0;
>   	} else {
> @@ -498,6 +517,9 @@ static void irq_domain_set_mapping(struct irq_domain *domain,
>   				   irq_hw_number_t hwirq,
>   				   struct irq_data *irq_data)
>   {
> +	if (irq_domain_is_nomap(domain))
> +		return;
> +
>   	if (hwirq < domain->revmap_size) {
>   		domain->revmap[hwirq] = irq_data->irq;
>   	} else {
> @@ -629,9 +651,9 @@ unsigned int irq_create_direct_mapping(struct irq_domain *domain)
>   		pr_debug("create_direct virq allocation failed\n");
>   		return 0;
>   	}
> -	if (virq >= domain->revmap_direct_max_irq) {
> +	if (virq >= domain->revmap_size) {
>   		pr_err("ERROR: no free irqs available below %i maximum\n",
> -			domain->revmap_direct_max_irq);
> +			domain->revmap_size);
>   		irq_free_desc(virq);
>   		return 0;
>   	}
> @@ -879,10 +901,14 @@ unsigned int irq_find_mapping(struct irq_domain *domain,
>   	if (domain == NULL)
>   		return 0;
>   
> -	if (hwirq < domain->revmap_direct_max_irq) {
> -		data = irq_domain_get_irq_data(domain, hwirq);
> -		if (data && data->hwirq == hwirq)
> -			return hwirq;
> +	if (irq_domain_is_nomap(domain)) {
> +		if (hwirq < domain->revmap_size) {
> +			data = irq_domain_get_irq_data(domain, hwirq);
> +			if (data && data->hwirq == hwirq)
> +				return hwirq;
> +		}
> +
> +		return 0;
>   	}
>   
>   	/* Check if the hwirq is in the linear revmap. */
> @@ -1470,7 +1496,7 @@ static void irq_domain_fix_revmap(struct irq_data *d)
>   {
>   	void __rcu **slot;
>   
> -	if (d->hwirq < d->domain->revmap_size)
> +	if (irq_domain_is_nomap(d->domain) || d->hwirq < d->domain->revmap_size)
>   		return; /* Not using radix tree. */
>   
>   	/* Fix up the revmap. */
> @@ -1830,8 +1856,7 @@ static void
>   irq_domain_debug_show_one(struct seq_file *m, struct irq_domain *d, int ind)
>   {
>   	seq_printf(m, "%*sname:   %s\n", ind, "", d->name);
> -	seq_printf(m, "%*ssize:   %u\n", ind + 1, "",
> -		   d->revmap_size + d->revmap_direct_max_irq);
> +	seq_printf(m, "%*ssize:   %u\n", ind + 1, "", d->revmap_size);
>   	seq_printf(m, "%*smapped: %u\n", ind + 1, "", d->mapcount);
>   	seq_printf(m, "%*sflags:  0x%08x\n", ind +1 , "", d->flags);
>   	if (d->ops && d->ops->debug_show)
> 


^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive
  2021-11-15 19:05   ` Cédric Le Goater
@ 2021-11-16  8:33     ` Marc Zyngier
  2021-11-16 10:27       ` Cédric Le Goater
  0 siblings, 1 reply; 65+ messages in thread
From: Marc Zyngier @ 2021-11-16  8:33 UTC (permalink / raw)
  To: Cédric Le Goater
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman, PowerPC, Greg Kurz

On Mon, 15 Nov 2021 19:05:17 +0000,
Cédric Le Goater <clg@kaod.org> wrote:
> 
> Hello Mark,

s/k/c/

> 
> On 5/20/21 18:37, Marc Zyngier wrote:
> > Direct mappings are completely exclusive of normal mappings, meaning
> > that we can refactor the code slightly so that we can get rid of
> > the revmap_direct_max_irq field and use the revmap_size field
> > instead, reducing the size of the irqdomain structure.
> > 
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> 
> 
> This patch is breaking the POWER9/POWER10 XIVE driver (these are not
> old PPC systems :) on machines sharing the same LSI HW IRQ. For instance,
> a linux KVM guest with a virtio-rng and a virtio-balloon device. In that
> case, Linux creates two distinct IRQ mappings which can lead to some
> unexpected behavior.

Either the irq domain translates, or it doesn't. If the driver creates
a nomap domain, and yet expects some sort of translation to happen,
then the driver is fundamentally broken. And even without that: how do
you end-up with a single HW interrupt having two mappings?

> A fix to go forward would be to change the XIVE IRQ domain to use a
> 'Tree' domain for reverse mapping and not the 'No Map' domain mapping.
> I will keep you updated for XIVE.

I bet there is a bit more to it. From what you are saying above,
something rather ungodly is happening in the XIVE code.

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive
  2021-11-16  8:33     ` Marc Zyngier
@ 2021-11-16 10:27       ` Cédric Le Goater
  0 siblings, 0 replies; 65+ messages in thread
From: Cédric Le Goater @ 2021-11-16 10:27 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-kernel, Thomas Gleixner, Michael Ellerman, PowerPC, Greg Kurz

Hello Marc,

>> This patch is breaking the POWER9/POWER10 XIVE driver (these are not
>> old PPC systems :) on machines sharing the same LSI HW IRQ. For instance,
>> a linux KVM guest with a virtio-rng and a virtio-balloon device. In that
>> case, Linux creates two distinct IRQ mappings which can lead to some
>> unexpected behavior.
> 
> Either the irq domain translates, or it doesn't. If the driver creates
> a nomap domain, and yet expects some sort of translation to happen,
> then the driver is fundamentally broken. And even without that: how do
> you end-up with a single HW interrupt having two mappings?
> 
>> A fix to go forward would be to change the XIVE IRQ domain to use a
>> 'Tree' domain for reverse mapping and not the 'No Map' domain mapping.
>> I will keep you updated for XIVE.
> 
> I bet there is a bit more to it. From what you are saying above,
> something rather ungodly is happening in the XIVE code.

It's making progress.

This change in irq_find_mapping() is what 'breaks' XIVE :

   +       if (irq_domain_is_nomap(domain)) {
   +               if (hwirq < domain->revmap_size) {
   +                      data = irq_domain_get_irq_data(domain, hwirq);
   +                      if (data && data->hwirq == hwirq)
   +                               return hwirq;
   +               }
   +
   +               return 0;


With the introduction of IRQ_DOMAIN_FLAG_NO_MAP, the revmap_tree lookup
is skipped and the previously mapped IRQ is not found. XIVE was relying
on a side effect of irq_domain_set_mapping() which is not true anymore.

I guess the easiest fix for 5.14 and 5.15 (in which was introduced MSI
domains) is to change the XIVE IRQ domain to a domain tree. Since the HW
can handle 1MB interrupts, this looks like a better choice for the driver.

Thanks,

C.

^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2021-11-16 11:03 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-20 16:37 [PATCH 00/39] irqdomain: Simplify interrupt handling Marc Zyngier
2021-05-20 16:37 ` [PATCH 01/39] nios2: Do not include linux/irqdomain.h from asm/irq.h Marc Zyngier
2021-05-20 16:37 ` [PATCH 02/39] staging: octeon-hcd: Directly include linux/of.h Marc Zyngier
2021-05-20 16:37 ` [PATCH 03/39] mfd: ioc3: Directly include linux/irqdomain.h Marc Zyngier
2021-05-21  7:07   ` Lee Jones
2021-05-20 16:37 ` [PATCH 04/39] watchdog/octeon-wdt: " Marc Zyngier
2021-05-20 16:37 ` [PATCH 05/39] irqchip/mips-gic: " Marc Zyngier
2021-05-20 16:37 ` [PATCH 06/39] MIPS: lantiq: Directly include linux/of.h in xway/dma.c Marc Zyngier
2021-05-20 16:37 ` [PATCH 07/39] MIPS: Add missing linux/irqdomain.h includes Marc Zyngier
2021-05-20 16:37 ` [PATCH 08/39] MIPS: Do not include linux/irqdomain.h from asm/irq.h Marc Zyngier
2021-05-20 16:37 ` [PATCH 09/39] powerpc: Add missing linux/{of.h,irqdomain.h} include directives Marc Zyngier
2021-05-20 16:37 ` [PATCH 10/39] scsi/ibmvscsi: Directly include linux/{of.h,irqdomain.h} Marc Zyngier
2021-05-20 16:37 ` [PATCH 11/39] powerpc: Convert irq_domain_add_legacy_isa use to irq_domain_add_legacy Marc Zyngier
2021-05-20 16:37 ` [PATCH 12/39] powerpc: Drop dependency between asm/irq.h and linux/irqdomain.h Marc Zyngier
2021-05-20 16:37 ` [PATCH 13/39] irqdomain: Kill irq_domain_add_legacy_isa Marc Zyngier
2021-05-20 16:37 ` [PATCH 14/39] irqdomain: Reimplement irq_linear_revmap() with irq_find_mapping() Marc Zyngier
2021-05-20 16:37 ` [PATCH 15/39] powerpc: Move the use of irq_domain_add_nomap() behind a config option Marc Zyngier
2021-05-20 16:37 ` [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive Marc Zyngier
2021-11-15 19:05   ` Cédric Le Goater
2021-11-16  8:33     ` Marc Zyngier
2021-11-16 10:27       ` Cédric Le Goater
2021-05-20 16:37 ` [PATCH 17/39] irqdomain: Use struct_size() helper when allocating irqdomain Marc Zyngier
2021-05-20 16:37 ` [PATCH 18/39] irqdomain: Cache irq_data instead of a virq number in the revmap Marc Zyngier
2021-05-20 16:37 ` [PATCH 19/39] irqdomain: Implement irq_domain_clear_mapping() with irq_domain_set_mapping() Marc Zyngier
2021-05-20 16:37 ` [PATCH 20/39] irqdomain: Protect the linear revmap with RCU Marc Zyngier
2021-06-19 11:37   ` Thomas Gleixner
2021-05-20 16:37 ` [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping() Marc Zyngier
2021-06-10  2:22   ` Qian Cai
2021-06-10  7:24     ` Marc Zyngier
2021-05-20 16:37 ` [PATCH 22/39] genirq: Use irq_resolve_mapping() to implement __handle_domain_irq() and co Marc Zyngier
2021-05-20 16:37 ` [PATCH 23/39] irqdesc: Fix __handle_domain_irq() comment Marc Zyngier
2021-05-20 16:37 ` [PATCH 24/39] irqchip/nvic: Convert from handle_IRQ() to handle_domain_irq() Marc Zyngier
2021-05-20 16:37 ` [PATCH 25/39] genirq: Add generic_handle_domain_irq() helper Marc Zyngier
2021-05-20 16:37 ` [PATCH 26/39] genirq: Move non-irqdomain handle_domain_irq() handling into ARM's handle_IRQ() Marc Zyngier
2021-05-20 16:37 ` [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq() Marc Zyngier
2021-05-21  8:54   ` Geert Uytterhoeven
2021-05-21 21:10   ` Krzysztof Kozlowski
2021-05-20 16:37 ` [PATCH 28/39] gpio: " Marc Zyngier
2021-05-21  8:59   ` Geert Uytterhoeven
2021-05-20 16:37 ` [PATCH 29/39] pinctrl: " Marc Zyngier
2021-05-21 21:16   ` Krzysztof Kozlowski
2021-05-20 16:37 ` [PATCH 30/39] PCI: " Marc Zyngier
2021-05-20 17:47   ` Rob Herring
2021-05-24  8:38     ` Marc Zyngier
2021-05-24 13:28       ` Rob Herring
2021-05-24 15:06         ` Marc Zyngier
2021-05-21  8:57   ` Geert Uytterhoeven
2021-05-20 16:37 ` [PATCH 31/39] mfd: " Marc Zyngier
2021-05-21  7:06   ` Lee Jones
2021-05-20 16:37 ` [PATCH 32/39] gpu: " Marc Zyngier
2021-05-20 16:37 ` [PATCH 33/39] SH: " Marc Zyngier
2021-05-20 16:37 ` [PATCH 34/39] ARM: " Marc Zyngier
2021-05-20 18:04   ` Rob Herring
2021-05-24  8:32     ` Marc Zyngier
2021-05-21 21:17   ` Krzysztof Kozlowski
2021-05-20 16:37 ` [PATCH 35/39] mips: " Marc Zyngier
2021-05-20 16:37 ` [PATCH 36/39] arc: " Marc Zyngier
2021-06-01 18:00   ` Vineet Gupta
2021-05-20 16:37 ` [PATCH 37/39] xtensa: " Marc Zyngier
2021-05-20 16:37 ` [PATCH 38/39] nios2: " Marc Zyngier
2021-05-20 16:37 ` [PATCH 39/39] powerpc: " Marc Zyngier
2021-05-20 23:33 ` [PATCH 00/39] irqdomain: Simplify interrupt handling Linus Walleij
2021-05-24  8:53   ` Marc Zyngier
2021-05-24  9:39     ` Linus Walleij
2021-06-01 14:29 ` Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).