• 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
    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: default 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: default avatarThomas Gleixner <tglx@linutronix.de>