• Samuel Holland's avatar
    irqchip/sun6i-r: Use a stacked irqchip driver · 4e346146
    Samuel Holland authored
    The R_INTC in the A31 and newer sun8i/sun50i SoCs is more similar to the
    original sun4i interrupt controller than the sun7i/sun9i NMI controller.
    It is used for two distinct purposes:
     - To control the trigger, latch, and mask for the NMI input pin
     - To provide the interrupt input for the ARISC coprocessor
    
    As this interrupt controller is not documented, information about it
    comes from vendor-provided firmware blobs and from experimentation.
    
    Differences from the sun4i interrupt controller appear to be:
     - It only has one or two registers of each kind (max 32 or 64 IRQs)
     - Multiplexing logic is added to support additional inputs
     - There is no FIQ-related logic
     - There is no interrupt priority logic
    
    In order to fulfill its two purposes, this hardware block combines four
    types of IRQs. First, the NMI pin is routed to the "IRQ 0" input on this
    chip, with a trigger type controlled by the NMI_CTRL_REG. The "IRQ 0
    pending" output from this chip, if enabled, is then routed to a SPI IRQ
    input on the GIC. In other words, bit 0 of IRQ_ENABLE_REG *does* affect
    the NMI IRQ seen at the GIC.
    
    The NMI is followed by a contiguous block of 15 "direct" (my name for
    them) IRQ inputs that are connected in parallel to both R_INTC and the
    GIC. Or in other words, these bits of IRQ_ENABLE_REG *do not* affect the
    IRQs seen at the GIC.
    
    Following the direct IRQs are the ARISC's copy of banked IRQs for shared
    peripherals. These are not relevant to Linux. The remaining IRQs are
    connected to a multiplexer and provide access to the first (up to) 128
    SPIs from the ARISC. This range of SPIs overlaps with the direct IRQs.
    
    Because of the 1:1 correspondence between R_INTC and GIC inputs, this is
    a perfect scenario for using a stacked irqchip driver. We want to hook
    into setting the NMI trigger type, but not actually handle any IRQ here.
    
    To allow access to all multiplexed IRQs, this driver requires a new
    binding where the interrupt number matches the GIC interrupt number.
    (This moves the NMI from number 0 to 32 or 96, depending on the SoC.)
    For simplicity, copy the three-cell GIC binding; this disambiguates
    interrupt 0 in the old binding (the NMI) from interrupt 0 in the new
    binding (SPI 0) by the number of cells.
    
    Since R_INTC is in the always-on power domain, and its output is visible
    to the power management coprocessor, a stacked irqchip driver provides a
    simple way to add wakeup support to any of its IRQs. That is the next
    patch; for now, just the NMI is moved over.
    
    This commit mostly reverts commit 173bda53 ("irqchip/sunxi-nmi:
    Support sun6i-a31-r-intc compatible").
    Acked-by: default avatarMaxime Ripard <mripard@kernel.org>
    Signed-off-by: default avatarSamuel Holland <samuel@sholland.org>
    Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
    Link: https://lore.kernel.org/r/20210118055040.21910-4-samuel@sholland.org
    4e346146
irq-sunxi-nmi.c 6.49 KB