irqdomain: Simplify interrupt handling
Subsystems (114)
Marc Zyngier
maintainercover irqdomain: Simplify interrupt handling
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(-)
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 1/39 nios2: Do not include linux/irqdomain.h from asm/irq.h
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.
--- arch/nios2/include/asm/irq.h | 1 - arch/nios2/kernel/irq.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
arch/nios2/include/asm/irq.h +0 -1
@@ -10,6 +10,5 @@#define NIOS2_CPU_NR_IRQS 32#include <asm-generic/irq.h> -#include <linux/irqdomain.h> #endif
arch/nios2/kernel/irq.c +1 -0
@@ -11,6 +11,7 @@#include <linux/init.h> #include <linux/interrupt.h> +#include <linux/irqdomain.h> #include <linux/of.h> static u32 ienable;
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 2/39 staging: octeon-hcd: Directly include linux/of.h
In reply to Marc ZyngierThis 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.
--- drivers/staging/octeon-usb/octeon-hcd.c | 1 + 1 file changed, 1 insertion(+)
drivers/staging/octeon-usb/octeon-hcd.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 3/39 mfd: ioc3: Directly include linux/irqdomain.h
In reply to Marc ZyngierThis driver include linux/irqdomain.h via a bizarre set of indirection, which we are about to break.
Directly include the required file.
--- drivers/mfd/ioc3.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/ioc3.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Lee Jones
AppliedRe: [PATCH 03/39] mfd: ioc3: Directly include linux/irqdomain.h
Quoted 9 lines · Marc Zyngier
This driver include
linux/irqdomain.hvia a bizarre set of indirection, which we are about to break.Directly include the required file.
Signed-off-by Marc Zyngier <[email protected]>--- drivers/mfd/ioc3.c | 1 + 1 file changed, 1 insertion(+)
Applied, thanks.
Signature · 4 lines
Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog
Marc Zyngier
maintainerPATCH 4/39 watchdog/octeon-wdt: Directly include linux/irqdomain.h
In reply to Marc ZyngierThis 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.
--- drivers/watchdog/octeon-wdt-main.c | 1 + 1 file changed, 1 insertion(+)
drivers/watchdog/octeon-wdt-main.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 5/39 irqchip/mips-gic: Directly include linux/irqdomain.h
In reply to Marc ZyngierThis 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.
--- drivers/irqchip/irq-mips-gic.c | 1 + 1 file changed, 1 insertion(+)
drivers/irqchip/irq-mips-gic.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 6/39 MIPS: lantiq: Directly include linux/of.h in xway/dma.c
In reply to Marc ZyngierThis 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.
--- arch/mips/lantiq/xway/dma.c | 1 + 1 file changed, 1 insertion(+)
arch/mips/lantiq/xway/dma.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 7/39 MIPS: Add missing linux/irqdomain.h includes
In reply to Marc ZyngierA number of MIPS platforms are failing to directly include irqdomain.h. Fix this so that we can drop unnecessary dependencies
--- 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(+)
arch/mips/pci/pci-rt3883.c +1 -0
@@ -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>
arch/mips/pci/pci-xtalk-bridge.c +1 -0
@@ -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>
arch/mips/sgi-ip27/ip27-irq.c +1 -0
@@ -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>
arch/mips/sgi-ip30/ip30-irq.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 8/39 MIPS: Do not include linux/irqdomain.h from asm/irq.h
In reply to Marc ZyngierIncluding 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.
--- arch/mips/include/asm/irq.h | 1 - 1 file changed, 1 deletion(-)
arch/mips/include/asm/irq.h +0 -1
@@ -11,7 +11,6 @@#include <linux/linkage.h> #include <linux/smp.h> -#include <linux/irqdomain.h> #include <asm/mipsmtregs.h>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 9/39 powerpc: Add missing linux/{of.h,irqdomain.h} include directives
In reply to Marc ZyngierA 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.
--- 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(+)
arch/powerpc/kernel/mce.c +1 -0
@@ -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>
arch/powerpc/kvm/book3s_hv_uvmem.c +1 -0
@@ -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>
arch/powerpc/kvm/book3s_xive.c +1 -0
@@ -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>
arch/powerpc/kvm/book3s_xive_native.c +1 -0
@@ -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>
arch/powerpc/mm/book3s64/radix_pgtable.c +1 -0
@@ -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>
arch/powerpc/platforms/cell/pmu.c +1 -0
@@ -10,6 +10,7 @@*/ #include <linux/interrupt.h> +#include <linux/irqdomain.h> #include <linux/types.h> #include <linux/export.h> #include <asm/io.h>
arch/powerpc/platforms/embedded6xx/flipper-pic.c +1 -0
@@ -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>
arch/powerpc/platforms/ps3/interrupt.c +1 -0
@@ -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>
arch/powerpc/platforms/pseries/ibmebus.c +1 -0
@@ -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>
arch/powerpc/sysdev/ehv_pic.c +1 -0
@@ -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>
arch/powerpc/sysdev/fsl_mpic_err.c +1 -0
@@ -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>
arch/powerpc/sysdev/xics/icp-hv.c +1 -0
@@ -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>
arch/powerpc/sysdev/xics/icp-opal.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 10/39 scsi/ibmvscsi: Directly include linux/{of.h,irqdomain.h}
In reply to Marc ZyngierA 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.
--- drivers/scsi/ibmvscsi/ibmvfc.c | 1 + drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 1 + 2 files changed, 2 insertions(+)
drivers/scsi/ibmvscsi/ibmvfc.c +1 -0
@@ -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>
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +1 -0
@@ -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>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 11/39 powerpc: Convert irq_domain_add_legacy_isa use to irq_domain_add_legacy
In reply to Marc Zyngierirq_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.
--- 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(-)
arch/powerpc/include/asm/irq.h +2 -2
@@ -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 16extern irq_hw_number_t virq_to_hw (unsigned int virq);
arch/powerpc/platforms/ps3/interrupt.c +2 -2
@@ -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 ();
arch/powerpc/sysdev/i8259.c +2 -1
@@ -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 ;
arch/powerpc/sysdev/mpic.c +1 -1
@@ -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);
arch/powerpc/sysdev/tsi108_pci.c +2 -1
@@ -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 ;
arch/powerpc/sysdev/xics/xics-common.c +1 -1
@@ -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)
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 12/39 powerpc: Drop dependency between asm/irq.h and linux/irqdomain.h
In reply to Marc ZyngierDirectly including linux/irqdomain.h was hiding all sort of sins, which have now been fixed. Drop the spurious include.
--- arch/powerpc/include/asm/irq.h | 1 - 1 file changed, 1 deletion(-)
arch/powerpc/include/asm/irq.h +0 -1
@@ -6,7 +6,6 @@/* */ -#include <linux/irqdomain.h> #include <linux/threads.h> #include <linux/list.h> #include <linux/radix-tree.h>
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 13/39 irqdomain: Kill irq_domain_add_legacy_isa
In reply to Marc ZyngierThis helper doesn't have a user anymore, let's remove it.
--- Documentation/core-api/irq/irq-domain.rst | 1 - include/linux/irqdomain.h | 11 ----------- 2 files changed, 12 deletions(-)
Documentation/core-api/irq/irq-domain.rst +0 -1
@@ -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()
include/linux/irqdomain.h +0 -11
@@ -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)
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 14/39 irqdomain: Reimplement irq_linear_revmap() with irq_find_mapping()
In reply to Marc Zyngierirq_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.
--- include/linux/irqdomain.h | 22 +++++++++------------- kernel/irq/irqdomain.c | 6 +++--- 2 files changed, 12 insertions(+), 16 deletions(-)
include/linux/irqdomain.h +9 -13
@@ -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;
kernel/irq/irqdomain.c +3 -3
@@ -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);
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 15/39 powerpc: Move the use of irq_domain_add_nomap() behind a config option
In reply to Marc ZyngierOnly 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.
--- 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(-)
arch/powerpc/platforms/cell/Kconfig +1 -0
@@ -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"
arch/powerpc/platforms/powermac/Kconfig +1 -0
@@ -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
arch/powerpc/platforms/ps3/Kconfig +1 -0
@@ -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
arch/powerpc/sysdev/xive/Kconfig +1 -0
@@ -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
include/linux/irqdomain.h +6 -2
@@ -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 */
kernel/irq/Kconfig +5 -0
@@ -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
kernel/irq/irqdomain.c +2 -0
@@ -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
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 16/39 irqdomain: Make normal and nomap irqdomains exclusive
In reply to Marc ZyngierDirect 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.
--- include/linux/irqdomain.h | 6 +++--- kernel/irq/irqdomain.c | 45 ++++++++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 13 deletions(-)
include/linux/irqdomain.h +3 -3
@@ -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
kernel/irq/irqdomain.c +35 -10
98 lines not on this page · raw message
Signature · 1 line
2.30.2
Re: [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive
Hello Mark,
Quoted 6 lines · Marc Zyngier
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_irqfield and use therevmap_sizefield instead, reducing the size of the irqdomain structure.Signed-off-by Marc Zyngier <[email protected]>
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.
Quoted 147 lines
--- include/linux/irqdomain.h | 6 +++--- kernel/irq/irqdomain.c | 45 ++++++++++++++++++++++++++++++--------- 2 files changed, 38 insertions(+), 13 deletions(-)include/linux/irqdomain.h +3
-3@@ -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 kernel/irq/irqdomain.c +35
-10@@ -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)
Marc Zyngier
maintainerRe: [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive
Quoted 2 lines · Cédric Le Goater
Hello Mark,
s/k/c/
Quoted 7 lines · Marc Zyngier
Quoted 5 lines
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_irqfield and use therevmap_sizefield instead, reducing the size of the irqdomain structure.
Quoted 8 lines
Quoted 1 line
Signed-off-by Marc Zyngier <[email protected]>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?
Quoted 3 lines
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.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Re: [PATCH 16/39] irqdomain: Make normal and nomap irqdomains exclusive
Hello Marc,
Quoted 11 lines
Quoted 5 lines
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?
Quoted 6 lines
Quoted 3 lines
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.
Marc Zyngier
maintainerPATCH 17/39 irqdomain: Use struct_size() helper when allocating irqdomain
In reply to Marc ZyngierInstead 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.
--- kernel/irq/irqdomain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/irq/irqdomain.c +1 -1
@@ -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 ;
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 18/39 irqdomain: Cache irq_data instead of a virq number in the revmap
In reply to Marc ZyngierCaching 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.
--- include/linux/irqdomain.h | 4 ++-- kernel/irq/irqdomain.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-)
include/linux/irqdomain.h +2 -2
@@ -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 */
kernel/irq/irqdomain.c +11 -5
@@ -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);
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 19/39 irqdomain: Implement irq_domain_clear_mapping() with irq_domain_set_mapping()
In reply to Marc ZyngierNow 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.
--- kernel/irq/irqdomain.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-)
kernel/irq/irqdomain.c +6 -15
@@ -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);
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 20/39 irqdomain: Protect the linear revmap with RCU
In reply to Marc ZyngierIt 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.
--- include/linux/irqdomain.h | 5 +++-- kernel/irq/irqdomain.c | 38 ++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 22 deletions(-)
include/linux/irqdomain.h +3 -2
@@ -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 */
kernel/irq/irqdomain.c +18 -20
@@ -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); }/**
Signature · 1 line
2.30.2
Re: [PATCH 20/39] irqdomain: Protect the linear revmap with RCU
Quoted 7 lines · Marc Zyngier
static void irq_domain_clear_mapping(struct
irq_domain*domain,kernel/irq/irqdomain.c +1
-0@@ -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. */
kernel/irq/irqdomain.c unsigned int irq_find_mapping(struct irq_domain *domain, · line 911
Quoted 10 lines
kernel/irq/irqdomain.c +3
-4if (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
Marc Zyngier
maintainerPATCH 21/39 irqdomain: Introduce irq_resolve_mapping()
In reply to Marc ZyngierRework 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().
--- include/linux/irqdomain.h | 18 +++++++++++++++--- kernel/irq/irqdomain.c | 22 ++++++++++++++-------- 2 files changed, 29 insertions(+), 11 deletions(-)
include/linux/irqdomain.h +15 -3
@@ -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)
kernel/irq/irqdomain.c +14 -8
@@ -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
Signature · 1 line
2.30.2
Re: [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping()
Quoted 6 lines · Marc Zyngier
Rework
irq_find_mapping()to return anirq_descpointer, and rename the result toirq_resolve_mapping().
irq_find_mapping()is then rewritten in terms ofir_resolve_mapping().Signed-off-by Marc Zyngier <[email protected]>
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
Quoted 106 lines
--- include/linux/irqdomain.h | 18 +++++++++++++++--- kernel/irq/irqdomain.c | 22 ++++++++++++++-------- 2 files changed, 29 insertions(+), 11 deletions(-)include/linux/irqdomain.h +15
-3@@ -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)kernel/irq/irqdomain.c +14
-8@@ -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
Marc Zyngier
maintainerRe: [PATCH 21/39] irqdomain: Introduce irq_resolve_mapping()
Quoted 6 lines · Qian Cai
Quoted 5 lines · Marc Zyngier
Rework
irq_find_mapping()to return anirq_descpointer, and rename the result toirq_resolve_mapping().
irq_find_mapping()is then rewritten in terms ofir_resolve_mapping().
Quoted 7 lines
Quoted 1 line
Signed-off-by Marc Zyngier <[email protected]>Marc, there is an use-after-free that "git blame" pointed to this commit. Any thoughts?
__irq_resolve_mapping+0x34c/0x360:__irq_resolve_mappingat/usr/src/linux-next/kernel/irq/irqdomain.c:917
Yup, this was reported yesterday by John Gary. I'm on it.
M.
Signature · 1 line
Jazz is not dead. It just smells funny...
Marc Zyngier
maintainerPATCH 22/39 genirq: Use irq_resolve_mapping() to implement __handle_domain_irq() and co
In reply to Marc ZyngierIn 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.
--- include/linux/irqdesc.h | 1 + kernel/irq/irqdesc.c | 60 ++++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 25 deletions(-)
include/linux/irqdesc.h +1 -0
@@ -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
kernel/irq/irqdesc.c +35 -25
103 lines not on this page · raw message
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 23/39 irqdesc: Fix __handle_domain_irq() comment
In reply to Marc ZyngierIt appears that the comment about a NULL domain meaning anything has always been wrong. Fix it.
--- include/linux/irqdesc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/linux/irqdesc.h +1 -2
@@ -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);
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 24/39 irqchip/nvic: Convert from handle_IRQ() to handle_domain_irq()
In reply to Marc ZyngierGiven 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().
--- drivers/irqchip/irq-nvic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/irqchip/irq-nvic.c +1 -3
@@ -40,9 +40,7 @@ static struct irq_domain *nvic_irq_domain; asmlinkage void __exception_irq_entrynvic_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,
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 25/39 genirq: Add generic_handle_domain_irq() helper
In reply to Marc ZyngierProvide generic_handle_domain_irq() as a pendent to handle_domain_irq() for non-root interrupt controllers
--- include/linux/irqdesc.h | 2 ++ kernel/irq/irqdesc.c | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-)
include/linux/irqdesc.h +2 -0
@@ -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) {
kernel/irq/irqdesc.c +18 -1
@@ -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
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 26/39 genirq: Move non-irqdomain handle_domain_irq() handling into ARM's handle_IRQ()
In reply to Marc ZyngierDespite 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.
--- arch/arm/kernel/irq.c | 22 +++++++++++++++++++++- include/linux/irqdesc.h | 14 ++++---------- kernel/irq/irqdesc.c | 30 ++++++++---------------------- 3 files changed, 33 insertions(+), 33 deletions(-)
arch/arm/kernel/irq.c +21 -1
@@ -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); }/*
include/linux/irqdesc.h +4 -10
@@ -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
kernel/irq/irqdesc.c +8 -22
@@ -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
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 27/39 irqchip: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
drivers/irqchip/exynos-combiner.c +4 -6
@@ -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);
drivers/irqchip/irq-al-fic.c +2 -5
@@ -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); }
drivers/irqchip/irq-armada-370-xp.c +8 -11
@@ -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);
drivers/irqchip/irq-aspeed-i2c-ic.c +3 -5
@@ -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); }
drivers/irqchip/irq-aspeed-scu-ic.c +2 -4
@@ -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 ));
drivers/irqchip/irq-ath79-misc.c +1 -1
@@ -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); }
drivers/irqchip/irq-bcm2835.c +1 -1
@@ -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",
drivers/irqchip/irq-bcm2836.c +1 -1
@@ -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);
drivers/irqchip/irq-bcm7038-l1.c +2 -4
@@ -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);
drivers/irqchip/irq-bcm7120-l2.c +2 -4
@@ -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);
drivers/irqchip/irq-brcmstb-l2.c +1 -1
@@ -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);
drivers/irqchip/irq-dw-apb-ictl.c +1 -2
@@ -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); } }
drivers/irqchip/irq-gic.c +5 -8
@@ -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); }
drivers/irqchip/irq-goldfish-pic.c +2 -3
@@ -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); }
drivers/irqchip/irq-i8259.c +1 -3
@@ -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)
drivers/irqchip/irq-idt3243x.c +2 -4
@@ -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); }
drivers/irqchip/irq-imgpdc.c +4 -7
@@ -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)); } }
drivers/irqchip/irq-imx-intmux.c +3 -6
@@ -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); }
drivers/irqchip/irq-imx-irqsteer.c +3 -6
@@ -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);
drivers/irqchip/irq-ingenic-tcu.c +1 -1
@@ -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); }
drivers/irqchip/irq-ingenic.c +1 -2
@@ -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); } }
drivers/irqchip/irq-keystone.c +6 -8
@@ -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); } }
drivers/irqchip/irq-loongson-htpic.c +1 -1
@@ -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);
drivers/irqchip/irq-loongson-htvec.c +2 -2
@@ -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; }
drivers/irqchip/irq-loongson-liointc.c +1 -1
@@ -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); }
drivers/irqchip/irq-lpc32xx.c +1 -1
@@ -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);
drivers/irqchip/irq-ls-scfg-msi.c +2 -4
@@ -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);
drivers/irqchip/irq-ls1x.c +1 -1
@@ -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); }
drivers/irqchip/irq-mips-gic.c +10 -10
@@ -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))); } }
drivers/irqchip/irq-mscc-ocelot.c +1 -1
@@ -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)); }
drivers/irqchip/irq-mvebu-pic.c +2 -5
@@ -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); }
drivers/irqchip/irq-mvebu-sei.c +4 -9
@@ -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); } }
drivers/irqchip/irq-orion.c +1 -1
@@ -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); } }
drivers/irqchip/irq-partition-percpu.c +3 -6
@@ -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); }
drivers/irqchip/irq-pruss-intc.c +3 -6
@@ -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);
drivers/irqchip/irq-realtek-rtl.c +1 -1
@@ -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);
drivers/irqchip/irq-renesas-irqc.c +1 -1
@@ -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 ;
drivers/irqchip/irq-sifive-plic.c +3 -5
@@ -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);
drivers/irqchip/irq-stm32-exti.c +4 -6
@@ -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);
drivers/irqchip/irq-sunxi-nmi.c +1 -2
@@ -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); }
drivers/irqchip/irq-tb10x.c +1 -1
@@ -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,
drivers/irqchip/irq-ti-sci-inta.c +3 -6
@@ -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); }
drivers/irqchip/irq-ts4800.c +1 -2
@@ -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:
drivers/irqchip/irq-versatile-fpga.c +1 -1
@@ -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:
drivers/irqchip/irq-vic.c +1 -1
@@ -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);
drivers/irqchip/irq-xilinx-intc.c +5 -17
@@ -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); }
drivers/irqchip/qcom-irq-combiner.c +1 -5
@@ -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); } }
Signature · 1 line
2.30.2
Re: [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq()
Quoted 8 lines · Marc Zyngier
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 <[email protected]>drivers/irqchip/irq-renesas-irqc.c | 2 +-
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] 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
Re: [PATCH 27/39] irqchip: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierQuoted 8 lines · Marc Zyngier
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 <[email protected]>--- drivers/irqchip/exynos-combiner.c | 10 ++++------
For Exynos:
Best regards,
Krzysztof
Marc Zyngier
maintainerPATCH 28/39 gpio: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
drivers/gpio/gpio-104-dio-48e.c +2 -2
@@ -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);
drivers/gpio/gpio-104-idi-48.c +2 -2
@@ -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); } }
drivers/gpio/gpio-104-idio-16.c +1 -1
@@ -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);
drivers/gpio/gpio-altera.c +5 -6
@@ -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); }
drivers/gpio/gpio-aspeed-sgpio.c +3 -6
@@ -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, ®,32 ) { - girq =irq_find_mapping (gc->irq.domain, i *32 + p); -generic_handle_irq (girq); - } - +for_each_set_bit (p, ®,32 ) +generic_handle_domain_irq (gc->irq.domain, i *32 + p); }chained_irq_exit (ic, desc);
drivers/gpio/gpio-aspeed.c +3 -6
@@ -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, ®,32 ) { - girq =irq_find_mapping (gc->irq.domain, i *32 + p); -generic_handle_irq (girq); - } - +for_each_set_bit (p, ®,32 ) +generic_handle_domain_irq (gc->irq.domain, i *32 + p); }chained_irq_exit (ic, desc);
drivers/gpio/gpio-ath79.c +2 -5
@@ -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); }
drivers/gpio/gpio-bcm-kona.c +2 -4
@@ -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); } }
drivers/gpio/gpio-brcmstb.c +2 -3
@@ -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); } } }
drivers/gpio/gpio-cadence.c +1 -1
@@ -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); }
drivers/gpio/gpio-davinci.c +1 -2
@@ -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);
drivers/gpio/gpio-dln2.c +9 -13
@@ -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)
drivers/gpio/gpio-em.c +1 -1
@@ -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++; }
drivers/gpio/gpio-ep93xx.c +4 -4
@@ -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); }
drivers/gpio/gpio-ftgpio010.c +1 -2
@@ -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); }
drivers/gpio/gpio-hisi.c +2 -2
@@ -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); }
drivers/gpio/gpio-hlwd.c +2 -5
@@ -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); }
drivers/gpio/gpio-merrifield.c +2 -6
@@ -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);
drivers/gpio/gpio-mpc8xxx.c +1 -1
@@ -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 ; }
drivers/gpio/gpio-mt7621.c +1 -3
@@ -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 ; }
drivers/gpio/gpio-mxc.c +1 -1
@@ -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); }
drivers/gpio/gpio-mxs.c +1 -1
@@ -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); } }
drivers/gpio/gpio-omap.c +1 -2
@@ -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);
drivers/gpio/gpio-pci-idio-16.c +1 -1
@@ -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);
drivers/gpio/gpio-pcie-idio-24.c +1 -2
@@ -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);
drivers/gpio/gpio-pl061.c +2 -2
@@ -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);
drivers/gpio/gpio-pxa.c +4 -5
@@ -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 ;
drivers/gpio/gpio-rcar.c +2 -2
@@ -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++; }
drivers/gpio/gpio-rda.c +3 -5
@@ -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); }
drivers/gpio/gpio-realtek-otto.c +2 -5
@@ -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);
drivers/gpio/gpio-sch.c +1 -1
@@ -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 ;
drivers/gpio/gpio-sodaville.c +1 -1
@@ -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 ; }
drivers/gpio/gpio-sprd.c +4 -8
@@ -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, ®,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, ®,SPRD_GPIO_BANK_NR ) +generic_handle_domain_irq (chip->irq.domain, + bank *SPRD_GPIO_BANK_NR + n); }chained_irq_exit (ic, desc); }
drivers/gpio/gpio-tb10x.c +1 -1
@@ -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 ; }
drivers/gpio/gpio-tegra.c +4 -5
@@ -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); } }
drivers/gpio/gpio-tegra186.c +3 -6
@@ -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:
drivers/gpio/gpio-tqmx86.c +4 -6
@@ -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); }
drivers/gpio/gpio-vf610.c +1 -1
@@ -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);
drivers/gpio/gpio-ws16c48.c +2 -2
@@ -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 ;
drivers/gpio/gpio-xgs-iproc.c +1 -1
@@ -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 ;
drivers/gpio/gpio-xilinx.c +3 -6
@@ -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]; }
drivers/gpio/gpio-xlp.c +1 -2
@@ -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); }
drivers/gpio/gpio-zynq.c +2 -6
@@ -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); }/**
Signature · 1 line
2.30.2
Re: [PATCH 28/39] gpio: Bulk conversion to generic_handle_domain_irq()
Quoted 9 lines · Marc Zyngier
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 <[email protected]>drivers/gpio/gpio-em.c | 2 +- drivers/gpio/gpio-rcar.c | 4 ++--
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] 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
Marc Zyngier
maintainerPATCH 29/39 pinctrl: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
drivers/pinctrl/actions/pinctrl-owl.c +2 -3
@@ -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);
drivers/pinctrl/bcm/pinctrl-bcm2835.c +2 -2
@@ -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); } }
drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +1 -2
@@ -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); } }
drivers/pinctrl/bcm/pinctrl-nsp-gpio.c +1 -2
@@ -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 ;
drivers/pinctrl/intel/pinctrl-baytrail.c +2 -5
@@ -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); }
drivers/pinctrl/intel/pinctrl-cherryview.c +2 -3
@@ -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);
drivers/pinctrl/intel/pinctrl-lynxpoint.c +2 -6
@@ -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); }
drivers/pinctrl/mediatek/mtk-eint.c +2 -3
@@ -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);
drivers/pinctrl/nomadik/pinctrl-nomadik.c +1 -1
@@ -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); }
drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c +1 -1
@@ -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); }
drivers/pinctrl/pinctrl-amd.c +2 -4
@@ -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.
drivers/pinctrl/pinctrl-at91.c +2 -4
@@ -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 */
drivers/pinctrl/pinctrl-equilibrium.c +1 -1
@@ -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); }
drivers/pinctrl/pinctrl-ingenic.c +1 -1
@@ -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); }
drivers/pinctrl/pinctrl-microchip-sgpio.c +1 -1
@@ -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);
drivers/pinctrl/pinctrl-ocelot.c +1 -2
@@ -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); }
drivers/pinctrl/pinctrl-oxnas.c +1 -1
@@ -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); }
drivers/pinctrl/pinctrl-pic32.c +1 -1
@@ -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); }
drivers/pinctrl/pinctrl-pistachio.c +1 -1
@@ -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); }
drivers/pinctrl/pinctrl-rockchip.c +5 -10
@@ -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);
drivers/pinctrl/pinctrl-single.c +2 -2
@@ -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++; } }
drivers/pinctrl/pinctrl-st.c +1 -1
@@ -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); } } }
drivers/pinctrl/qcom/pinctrl-msm.c +1 -3
@@ -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++; } }
drivers/pinctrl/samsung/pinctrl-exynos.c +7 -8
@@ -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); } }
drivers/pinctrl/samsung/pinctrl-s3c24xx.c +10 -15
@@ -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);
drivers/pinctrl/samsung/pinctrl-s3c64xx.c +7 -10
@@ -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);
drivers/pinctrl/spear/pinctrl-plgpio.c +1 -2
@@ -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);
drivers/pinctrl/sunxi/pinctrl-sunxi.c +3 -5
@@ -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);
Signature · 1 line
2.30.2
Re: [PATCH 29/39] pinctrl: Bulk conversion to generic_handle_domain_irq()
Quoted 5 lines · Marc Zyngier
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().
Quoted 7 lines
Signed-off-by Marc Zyngier <[email protected]>---
drivers/pinctrl/samsung/pinctrl-exynos.c | 15 ++++++------- drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 25 +++++++++------------- drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 17 ++++++---------
For Samsung:
I cannot provide you testing at the moment.
Best regards,
Krzysztof
Marc Zyngier
maintainerPATCH 30/39 PCI: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
drivers/pci/controller/dwc/pci-dra7xx.c +5 -9
@@ -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, ®,PCI_NUM_INTX ) { - virq =irq_find_mapping (dra7xx->irq_domain, bit); -if (virq) -generic_handle_irq (virq); - } +for_each_set_bit (bit, ®,PCI_NUM_INTX ) +generic_handle_domain_irq (dra7xx->irq_domain, bit);break ; }
drivers/pci/controller/dwc/pci-keystone.c +2 -3
@@ -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 */
drivers/pci/controller/dwc/pcie-designware-host.c +4 -5
@@ -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++; } }
drivers/pci/controller/dwc/pcie-uniphier.c +2 -4
@@ -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, ®,PCI_NUM_INTX ) { - virq =irq_linear_revmap (priv->legacy_irq_domain, bit); -generic_handle_irq (virq); - } +for_each_set_bit (bit, ®,PCI_NUM_INTX ) +generic_handle_domain_irq (priv->legacy_irq_domain, bit);chained_irq_exit (chip, desc); }
drivers/pci/controller/mobiveil/pcie-mobiveil-host.c +6 -9
@@ -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 );
drivers/pci/controller/pci-aardvark.c +2 -3
@@ -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); } }
drivers/pci/controller/pci-ftpci100.c +1 -1
@@ -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);
drivers/pci/controller/pci-tegra.c +3 -5
@@ -1553,12 +1553,10 @@ static void tegra_pcie_msi_irq(struct irq_desc *desc)while (reg) {unsigned int offset =find_first_bit (®,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
drivers/pci/controller/pci-xgene-msi.c +3 -6
@@ -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);
drivers/pci/controller/pcie-altera-msi.c +4 -6
@@ -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" ); } }
drivers/pci/controller/pcie-altera.c +4 -6
@@ -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); } }
drivers/pci/controller/pcie-brcmstb.c +4 -5
@@ -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" ); }
drivers/pci/controller/pcie-iproc-msi.c +1 -3
@@ -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 ;
drivers/pci/controller/pcie-mediatek-gen3.c +4 -9
@@ -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 +
drivers/pci/controller/pcie-mediatek.c +4 -8
@@ -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 );
drivers/pci/controller/pcie-microchip-host.c +7 -11
@@ -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); }
drivers/pci/controller/pcie-rcar-host.c +3 -5
@@ -486,12 +486,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)while (reg) {unsigned int index =find_first_bit (®,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 );
drivers/pci/controller/pcie-rockchip-host.c +3 -5
@@ -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); }
drivers/pci/controller/pcie-xilinx-cpm.c +2 -2
@@ -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 );/*
drivers/pci/controller/pcie-xilinx-nwl.c +3 -10
@@ -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); } } }
drivers/pci/controller/pcie-xilinx.c +4 -5
@@ -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 )
Signature · 1 line
2.30.2
Rob Herring
reviewerRe: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
Quoted 47 lines · Marc Zyngier
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 <[email protected]>--- 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(-)drivers/pci/controller/pci-xgene-msi.c +1
-2@@ -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);
drivers/pci/controller/pci-xgene-msi.c static void xgene_msi_isr(struct irq_desc *desc) · line 333
Quoted 9 lines
drivers/pci/controller/pci-xgene-msi.c +2
-4@@ -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
Marc Zyngier
maintainerRe: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
Quoted 47 lines · Rob Herring
Quoted 45 lines · Marc Zyngier
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 <[email protected]>--- 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(-)drivers/pci/controller/pci-xgene-msi.c +1
-2@@ -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;
Quoted 15 lines
drivers/pci/controller/pci-xgene-msi.c static void xgene_msi_isr(struct irq_desc *desc) · line 333
Quoted 11 lines
drivers/pci/controller/pci-xgene-msi.c +2
-4chained_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.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Rob Herring
reviewerRe: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
Quoted 66 lines · Marc Zyngier
Quoted 47 lines · Rob Herring
Quoted 45 lines · Marc Zyngier
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 <[email protected]>--- 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(-)drivers/pci/controller/pci-xgene-msi.c +1
-2@@ -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;Quoted 15 lines
drivers/pci/controller/pci-xgene-msi.c static void xgene_msi_isr(struct irq_desc *desc) · line 333
Quoted 11 lines
drivers/pci/controller/pci-xgene-msi.c +2
-4chained_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.
Quoted 2 lines
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.
Quoted 5 lines
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
Marc Zyngier
maintainerRe: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
Quoted 68 lines · Rob Herring
Quoted 66 lines · Marc Zyngier
Quoted 62 lines · Rob Herring
Quoted 47 lines · Marc Zyngier
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 <[email protected]>--- 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(-)drivers/pci/controller/pci-xgene-msi.c +1
-2@@ -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);drivers/pci/controller/pci-xgene-msi.c static void xgene_msi_isr(struct irq_desc *desc) · line 333
Quoted 9 lines
drivers/pci/controller/pci-xgene-msi.c +2
-4@@ -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.
Quoted 5 lines
Quoted 2 lines
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...
Quoted 11 lines
Quoted 6 lines
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.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Re: [PATCH 30/39] PCI: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierQuoted 8 lines · Marc Zyngier
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 <[email protected]>drivers/pci/controller/pcie-rcar-host.c | 8 +++-----
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] 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
Marc Zyngier
maintainerPATCH 31/39 mfd: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
drivers/mfd/db8500-prcmu.c +1 -1
@@ -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 ;
drivers/mfd/fsl-imx25-tsadc.c +2 -2
@@ -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); }
drivers/mfd/ioc3.c +3 -7
@@ -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 (®s->sio_ir); mask =readl (®s->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 (); - } }/*
drivers/mfd/qcom-pm8xxx.c +4 -6
@@ -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); } } }
Signature · 1 line
2.30.2
Re: [PATCH 31/39] mfd: Bulk conversion to generic_handle_domain_irq()
Quoted 5 lines · Marc Zyngier
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().
Quoted 7 lines
Signed-off-by Marc Zyngier <[email protected]>--- 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:
Signature · 4 lines
Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog
Marc Zyngier
maintainerPATCH 32/39 gpu: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +1 -1
@@ -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",
drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +4 -11
@@ -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 ; }
drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c +1 -2
@@ -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); }
drivers/gpu/ipu-v3/ipu-common.c +4 -7
@@ -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); } }
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 33/39 SH: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
arch/sh/boards/mach-se/7343/irq.c +1 -1
@@ -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); }
arch/sh/boards/mach-se/7722/irq.c +1 -1
@@ -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); }
arch/sh/boards/mach-x3proto/gpio.c +1 -1
@@ -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); }
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 34/39 ARM: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++---- arch/arm/mach-s3c/irq-s3c24xx.c | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-)
arch/arm/mach-pxa/pxa_cplds_irqs.c +2 -4
@@ -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 ;
arch/arm/mach-s3c/irq-s3c24xx.c +2 -3
@@ -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);
Signature · 1 line
2.30.2
Rob Herring
reviewerRe: [PATCH 34/39] ARM: Bulk conversion to generic_handle_domain_irq()
Quoted 17 lines · Marc Zyngier
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 <[email protected]>--- arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++---- arch/arm/mach-s3c/irq-s3c24xx.c | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-)arch/arm/mach-pxa/pxa_cplds_irqs.c +0
-0
arch/arm/mach-pxa/pxa_cplds_irqs.c static irqreturn_t cplds_irq_handler(int in_irq, void *d) · line 43
Quoted 9 lines
arch/arm/mach-pxa/pxa_cplds_irqs.c +2
-4@@ -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
Marc Zyngier
maintainerRe: [PATCH 34/39] ARM: Bulk conversion to generic_handle_domain_irq()
Quoted 32 lines · Rob Herring
Quoted 17 lines · Marc Zyngier
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 <[email protected]>--- arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++---- arch/arm/mach-s3c/irq-s3c24xx.c | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-)arch/arm/mach-pxa/pxa_cplds_irqs.c +0
-0arch/arm/mach-pxa/pxa_cplds_irqs.c static irqreturn_t cplds_irq_handler(int in_irq, void *d) · line 43
Quoted 9 lines
arch/arm/mach-pxa/pxa_cplds_irqs.c +2
-4@@ -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:
Quoted 1 line
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.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Re: [PATCH 34/39] ARM: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierQuoted 9 lines · Marc Zyngier
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 <[email protected]>--- arch/arm/mach-pxa/pxa_cplds_irqs.c | 6 ++---- arch/arm/mach-s3c/irq-s3c24xx.c | 5 ++---
For S3C:
Best regards,
Krzysztof
Marc Zyngier
maintainerPATCH 35/39 mips: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
arch/mips/ath25/ar2315.c +7 -7
@@ -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)
arch/mips/ath25/ar5312.c +6 -7
@@ -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 */
arch/mips/lantiq/irq.c +1 -1
@@ -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 &<Q_EBU_PCC_ISTAT !=0 )
arch/mips/pci/pci-ar2315.c +3 -5
@@ -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 (); }
arch/mips/pci/pci-rt3883.c +2 -3
@@ -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); }
arch/mips/ralink/irq.c +1 -1
@@ -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 (); }
arch/mips/sgi-ip27/ip27-irq.c +6 -10
@@ -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 );
arch/mips/sgi-ip30/ip30-irq.c +3 -5
@@ -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 (); } }
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 36/39 arc: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- arch/arc/kernel/mcip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arc/kernel/mcip.c +1 -1
@@ -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); }
Signature · 1 line
2.30.2
Re: [PATCH 36/39] arc: Bulk conversion to generic_handle_domain_irq()
Quoted 6 lines · Marc Zyngier
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 <[email protected]>
Thx for doing this Marc.
-Vineet
Quoted 17 lines
--- arch/arc/kernel/mcip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/arc/kernel/mcip.c +1
-1@@ -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); }
Marc Zyngier
maintainerPATCH 37/39 xtensa: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- arch/xtensa/kernel/irq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/xtensa/kernel/irq.c +1 -3
@@ -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)
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 38/39 nios2: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- arch/nios2/kernel/irq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
arch/nios2/kernel/irq.c +1 -3
@@ -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);
Signature · 1 line
2.30.2
Marc Zyngier
maintainerPATCH 39/39 powerpc: Bulk conversion to generic_handle_domain_irq()
In reply to Marc ZyngierWherever 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().
--- 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(-)
arch/powerpc/platforms/4xx/uic.c +1 -3
@@ -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);
arch/powerpc/platforms/512x/mpc5121_ads_cpld.c +10 -13
@@ -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 ; } }
arch/powerpc/platforms/52xx/media5200.c +4 -5
@@ -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 */
arch/powerpc/platforms/52xx/mpc52xx_gpt.c +2 -5
@@ -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,
arch/powerpc/platforms/82xx/pq2ads-pci-pic.c +2 -4
@@ -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); } } }
arch/powerpc/platforms/cell/interrupt.c +2 -6
@@ -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)
arch/powerpc/platforms/cell/spider-pic.c +3 -8
@@ -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); }
arch/powerpc/platforms/embedded6xx/hlwd-pic.c +7 -8
@@ -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 ; }/*
arch/powerpc/platforms/powernv/opal-irqchip.c +4 -7
@@ -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 ();
arch/powerpc/sysdev/fsl_mpic_err.c +4 -7
@@ -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); }
arch/powerpc/sysdev/fsl_msi.c +4 -4
@@ -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 ); }
Signature · 1 line
2.30.2
Quoted 4 lines · Marc Zyngier
Wouldn't it be nice if the irqdomain
would cache theirq_descinstead 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:
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
Marc Zyngier
maintainerQuoted 10 lines · Linus Walleij
Quoted 4 lines · Marc Zyngier
Wouldn't it be nice if the irqdomain
would cache theirq_descinstead 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 <[email protected]>
Thanks for that.
Quoted 3 lines
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.
Quoted 1 line
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.
Quoted 11 lines
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.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Quoted 6 lines · Marc Zyngier
Quoted 2 lines
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
Marc Zyngier
maintainerQuoted 33 lines · Marc Zyngier
Although most device drivers only deal with an interrupt number, the core IRQ code is mostly concerned with the
irq_descstructure 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_descpointer.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_descinstead 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.hincludinglinux/irqdomain.his pretty bad...) and simplify bits of the irqdomain code- some rework of the irqdomain code to allow the caching of a
irq_datapointer, 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 togeneric_handle_domain_irq(domain, hwirq). Yes, this is a mouthful.
Quoted 8 lines
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.
Signature · 1 line
Without deviation from the norm, progress is not possible.