• David S. Miller's avatar
    sparc64: Fix lost interrupts on sun4u. · d0cac39e
    David S. Miller authored
    Based upon a report by Meelis Roos.
    
    Sparc64 SBUS and PCI controllers use a combination of IMAP and ICLR
    registers to manage device interrupts.
    
    The IMAP register contains the "valid" enable bit as well as CPU
    targetting information.  Whereas the ICLR register is written with
    zero at the end of handling an interrupt to reset the state machine
    for that interrupt to IDLE so it can be sent again.
    
    For PCI slot and SBUS slot devices we can have multiple interrupts
    sharing the same IMAP register.  There are individual ICLR registers
    but only one IMAP register for managing those.
    
    We represent each shared case with individual virtual IRQs so the
    generic IRQ layer thinks there is only one user of the IRQ instance.
    
    In such shared IMAP cases this is wrong, so if there are multiple
    active users then a free_irq() call will prematurely turn off the
    interrupt by clearing the Valid bit in the IMAP register even though
    there are other active users.
    
    Fix this by simply doing nothing in sun4u_disable_irq() and checking
    IRQF_DISABLED during IRQ dispatch.
    
    This situation doesn't exist in the hypervisor sun4v cases, so I left
    those alone.
    Tested-by: default avatarMeelis Roos <mroos@linux.ee>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d0cac39e
irq_64.c 25.4 KB