• Paul Burton's avatar
    irqchip/mips-gic: Fix local interrupts · e875bd66
    Paul Burton authored
    Since the device hierarchy domain was added by commit c98c1822
    ("irqchip/mips-gic: Add device hierarchy domain"), GIC local interrupts
    have been broken.
    
    Users attempting to setup a per-cpu local IRQ, for example the GIC timer
    clock events code in drivers/clocksource/mips-gic-timer.c, the
    setup_percpu_irq function would refuse with -EINVAL because the GIC
    irqchip driver never called irq_set_percpu_devid so the
    IRQ_PER_CPU_DEVID flag was never set for the IRQ. This happens because
    irq_set_percpu_devid was being called from the gic_irq_domain_map
    function which is no longer called.
    
    Doing only that runs into further problems because gic_dev_domain_alloc
    set the struct irq_chip for all interrupts, local or shared, to
    gic_level_irq_controller despite that only being suitable for shared
    interrupts. The typical outcome of this is that gic_level_irq_controller
    callback functions are called for local interrupts, and then hwirq
    number calculations overflow & the driver ends up attempting to access
    some invalid register with an address calculated from an invalid hwirq
    number. Best case scenario is that this then leads to a bus error. This
    is fixed by abstracting the setup of the hwirq & chip to a new function
    gic_setup_dev_chip which is used by both the root GIC IRQ domain & the
    device domain.
    
    Finally, decoding local interrupts failed because gic_dev_domain_alloc
    only called irq_domain_alloc_irqs_parent for shared interrupts. Local
    ones were therefore never associated with hwirqs in the root GIC IRQ
    domain and the virq in gic_handle_local_int would always be 0. This is
    fixed by calling irq_domain_alloc_irqs_parent unconditionally & having
    gic_irq_domain_alloc handle both local & shared interrupts, which is
    easy due to the aforementioned abstraction of chip setup into
    gic_setup_dev_chip.
    
    This fixes use of the MIPS GIC timer for clock events, which has been
    broken since c98c1822 ("irqchip/mips-gic: Add device hierarchy
    domain") but hadn't been noticed due to a silent fallback to the MIPS
    coprocessor 0 count/compare clock events device.
    
    Fixes: c98c1822 ("irqchip/mips-gic: Add device hierarchy domain")
    Signed-off-by: 's avatarPaul Burton <paul.burton@imgtec.com>
    Cc: linux-mips@linux-mips.org
    Cc: Jason Cooper <jason@lakedaemon.net>
    Cc: Qais Yousef <qsyousef@gmail.com>
    Cc: stable@vger.kernel.org
    Cc: Marc Zyngier <marc.zyngier@arm.com>
    Link: http://lkml.kernel.org/r/20160913165335.31389-1-paul.burton@imgtec.comSigned-off-by: 's avatarThomas Gleixner <tglx@linutronix.de>
    e875bd66
Name
Last commit
Last update
..
Kconfig Loading commit data...
Makefile Loading commit data...
alphascale_asm9260-icoll.h Loading commit data...
exynos-combiner.c Loading commit data...
irq-alpine-msi.c Loading commit data...
irq-armada-370-xp.c Loading commit data...
irq-aspeed-vic.c Loading commit data...
irq-ath79-cpu.c Loading commit data...
irq-ath79-misc.c Loading commit data...
irq-atmel-aic-common.c Loading commit data...
irq-atmel-aic-common.h Loading commit data...
irq-atmel-aic.c Loading commit data...
irq-atmel-aic5.c Loading commit data...
irq-bcm2835.c Loading commit data...
irq-bcm2836.c Loading commit data...
irq-bcm6345-l1.c Loading commit data...
irq-bcm7038-l1.c Loading commit data...
irq-bcm7120-l2.c Loading commit data...
irq-brcmstb-l2.c Loading commit data...
irq-clps711x.c Loading commit data...
irq-crossbar.c Loading commit data...
irq-digicolor.c Loading commit data...
irq-dw-apb-ictl.c Loading commit data...
irq-eznps.c Loading commit data...
irq-gic-common.c Loading commit data...
irq-gic-common.h Loading commit data...
irq-gic-pm.c Loading commit data...
irq-gic-realview.c Loading commit data...
irq-gic-v2m.c Loading commit data...
irq-gic-v3-its-pci-msi.c Loading commit data...
irq-gic-v3-its-platform-msi.c Loading commit data...
irq-gic-v3-its.c Loading commit data...
irq-gic-v3.c Loading commit data...
irq-gic.c Loading commit data...
irq-hip04.c Loading commit data...
irq-i8259.c Loading commit data...
irq-imgpdc.c Loading commit data...
irq-imx-gpcv2.c Loading commit data...
irq-ingenic.c Loading commit data...
irq-keystone.c Loading commit data...
irq-lpc32xx.c Loading commit data...
irq-ls-scfg-msi.c Loading commit data...
irq-mbigen.c Loading commit data...
irq-metag-ext.c Loading commit data...
irq-metag.c Loading commit data...
irq-mips-cpu.c Loading commit data...
irq-mips-gic.c Loading commit data...
irq-mmp.c Loading commit data...
irq-moxart.c Loading commit data...
irq-mtk-sysirq.c Loading commit data...
irq-mvebu-odmi.c Loading commit data...
irq-mxs.c Loading commit data...
irq-nvic.c Loading commit data...
irq-omap-intc.c Loading commit data...
irq-or1k-pic.c Loading commit data...
irq-orion.c Loading commit data...
irq-partition-percpu.c Loading commit data...
irq-pic32-evic.c Loading commit data...
irq-renesas-h8300h.c Loading commit data...
irq-renesas-h8s.c Loading commit data...
irq-renesas-intc-irqpin.c Loading commit data...
irq-renesas-irqc.c Loading commit data...
irq-s3c24xx.c Loading commit data...
irq-sa11x0.c Loading commit data...
irq-sirfsoc.c Loading commit data...
irq-st.c Loading commit data...
irq-sun4i.c Loading commit data...
irq-sunxi-nmi.c Loading commit data...
irq-tango.c Loading commit data...
irq-tb10x.c Loading commit data...
irq-tegra.c Loading commit data...
irq-ts4800.c Loading commit data...
irq-versatile-fpga.c Loading commit data...
irq-vf610-mscm-ir.c Loading commit data...
irq-vic.c Loading commit data...
irq-vt8500.c Loading commit data...
irq-xtensa-mx.c Loading commit data...
irq-xtensa-pic.c Loading commit data...
irq-zevio.c Loading commit data...
irqchip.c Loading commit data...
spear-shirq.c Loading commit data...