diff options
| author | Andre Detsch <adetsch@br.ibm.com> | 2009-11-04 10:03:19 -0500 |
|---|---|---|
| committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-11-05 01:06:27 -0500 |
| commit | 8435b027b87a78145992c37b0b8ed0f1b7761bf0 (patch) | |
| tree | f0972989a6b199079503294b20c25f81713c062c | |
| parent | 978d7eb31d44de34a7f71e04ed4158f3f854688d (diff) | |
powerpc/pci: Fix regression in powerpc MSI-X
Patch f598282f5145036312d90875d0ed5c14b49fd8a7 exposed a problem in
powerpc MSI-X functionality, making network interfaces such as ixgbe
and cxgb3 stop to work when MSI-X is enabled. RX interrupts were not
being generated.
The problem was caused because MSI irq was not being effectively
unmasked after device initialization.
Signed-off-by: Andre Detsch <adetsch@br.ibm.com>
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
| -rw-r--r-- | arch/powerpc/platforms/pseries/msi.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 9 |
2 files changed, 9 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index bf2e1ac41308..1164c3430f2c 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c | |||
| @@ -432,8 +432,6 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
| 432 | /* Read config space back so we can restore after reset */ | 432 | /* Read config space back so we can restore after reset */ |
| 433 | read_msi_msg(virq, &msg); | 433 | read_msi_msg(virq, &msg); |
| 434 | entry->msg = msg; | 434 | entry->msg = msg; |
| 435 | |||
| 436 | unmask_msi_irq(virq); | ||
| 437 | } | 435 | } |
| 438 | 436 | ||
| 439 | return 0; | 437 | return 0; |
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 419f8a637ffe..b9bf0eedccf2 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/radix-tree.h> | 19 | #include <linux/radix-tree.h> |
| 20 | #include <linux/cpu.h> | 20 | #include <linux/cpu.h> |
| 21 | #include <linux/msi.h> | ||
| 21 | #include <linux/of.h> | 22 | #include <linux/of.h> |
| 22 | 23 | ||
| 23 | #include <asm/firmware.h> | 24 | #include <asm/firmware.h> |
| @@ -219,6 +220,14 @@ static void xics_unmask_irq(unsigned int virq) | |||
| 219 | 220 | ||
| 220 | static unsigned int xics_startup(unsigned int virq) | 221 | static unsigned int xics_startup(unsigned int virq) |
| 221 | { | 222 | { |
| 223 | /* | ||
| 224 | * The generic MSI code returns with the interrupt disabled on the | ||
| 225 | * card, using the MSI mask bits. Firmware doesn't appear to unmask | ||
| 226 | * at that level, so we do it here by hand. | ||
| 227 | */ | ||
| 228 | if (irq_to_desc(virq)->msi_desc) | ||
| 229 | unmask_msi_irq(virq); | ||
| 230 | |||
| 222 | /* unmask it */ | 231 | /* unmask it */ |
| 223 | xics_unmask_irq(virq); | 232 | xics_unmask_irq(virq); |
| 224 | return 0; | 233 | return 0; |
