]> git.kernelconcepts.de Git - karo-tx-linux.git/commit
sparc64: Fix lost interrupts on sun4u.
authorDavid S. Miller <davem@davemloft.net>
Wed, 4 Mar 2009 22:43:47 +0000 (14:43 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 12 Jun 2009 03:01:14 +0000 (20:01 -0700)
commit9c0ec2384c31df111f4029eabd7957692c115260
treefdbb77899042c84c3f7f957e37173ca74d0fe5cf
parentccfc46013757a25fb2002ede397a2702f50a612e
sparc64: Fix lost interrupts on sun4u.

[ Upstream commit d0cac39e4ec8097e4c7099d291b1fdcc0fe56b58 ]

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: Meelis Roos <mroos@linux.ee>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/sparc64/kernel/irq.c