summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/axon_msi.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2008-12-12 09:19:50 (GMT)
committerPaul Mackerras <paulus@samba.org>2008-12-16 02:48:18 (GMT)
commit23e0e8afafd9ac065d81506524adf3339584044b (patch)
tree2bbc2c95e49687be2f499096ccc7c94ddecb823b /arch/powerpc/platforms/cell/axon_msi.c
parenta4c74ddd5ea3db53fc73d29c222b22656a7d05be (diff)
downloadlinux-fsl-qoriq-23e0e8afafd9ac065d81506524adf3339584044b.tar.xz
powerpc/cell/axon-msi: Fix MSI after kexec
Commit d015fe995 'powerpc/cell/axon-msi: Retry on missing interrupt' has turned a rare failure to kexec on QS22 into a reproducible error, which we have now analysed. The problem is that after a kexec, the MSIC hardware still points into the middle of the old ring buffer. We set up the ring buffer during reboot, but not the offset into it. On older kernels, this would cause a storm of thousands of spurious interrupts after a kexec, which would most of the time get dropped silently. With the new code, we time out on each interrupt, waiting for it to become valid. If more interrupts come in that we time out on, this goes on indefinitely, which eventually leads to a hard crash. The solution in this commit is to read the current offset from the MSIC when reinitializing it. This now works correctly, as expected. Reported-by: Dirk Herrendoerfer <d.herrendoerfer@de.ibm.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/axon_msi.c')
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 442cf36..0ce45c2 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -413,6 +413,9 @@ static int axon_msi_probe(struct of_device *device,
MSIC_CTRL_IRQ_ENABLE | MSIC_CTRL_ENABLE |
MSIC_CTRL_FIFO_SIZE);
+ msic->read_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG)
+ & MSIC_FIFO_SIZE_MASK;
+
device->dev.platform_data = msic;
ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;