summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2013-07-24 10:25:00 +0800
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-07-24 14:18:49 +1000
commit91150af3adf67463c4ca7d72d4fe1a84da37792c (patch)
tree8a77a60b8439ee9ffd1c2d270cdeb394e448ee96
parent4b83bd452f17582c8d1c916568fd28a237a2eb46 (diff)
downloadlinux-stable-91150af3adf67463c4ca7d72d4fe1a84da37792c.tar.gz
linux-stable-91150af3adf67463c4ca7d72d4fe1a84da37792c.tar.bz2
linux-stable-91150af3adf67463c4ca7d72d4fe1a84da37792c.zip
powerpc/eeh: Fix unbalanced enable for IRQ
The patch fixes following issue: Unbalanced enable for IRQ 23 ------------[ cut here ]------------ WARNING: at kernel/irq/manage.c:437 : NIP [c00000000016de8c] .__enable_irq+0x11c/0x140 LR [c00000000016de88] .__enable_irq+0x118/0x140 Call Trace: [c000003ea1f23880] [c00000000016de88] .__enable_irq+0x118/0x140 (unreliable) [c000003ea1f23910] [c00000000016df08] .enable_irq+0x58/0xa0 [c000003ea1f239a0] [c0000000000388b4] .eeh_enable_irq+0xc4/0xe0 [c000003ea1f23a30] [c000000000038a28] .eeh_report_reset+0x78/0x130 [c000003ea1f23ac0] [c000000000037508] .eeh_pe_dev_traverse+0x98/0x170 [c000003ea1f23b60] [c0000000000391ac] .eeh_handle_normal_event+0x2fc/0x3d0 [c000003ea1f23bf0] [c000000000039538] .eeh_handle_event+0x2b8/0x2c0 [c000003ea1f23c90] [c000000000039600] .eeh_event_handler+0xc0/0x170 [c000003ea1f23d30] [c0000000000da9a0] .kthread+0xf0/0x100 [c000003ea1f23e30] [c00000000000a1dc] .ret_from_kernel_thread+0x5c/0x80 Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/kernel/eeh_driver.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 9fda75d1f5aa..36bed5a12750 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -143,10 +143,14 @@ static void eeh_disable_irq(struct pci_dev *dev)
static void eeh_enable_irq(struct pci_dev *dev)
{
struct eeh_dev *edev = pci_dev_to_eeh_dev(dev);
+ struct irq_desc *desc;
if ((edev->mode) & EEH_DEV_IRQ_DISABLED) {
edev->mode &= ~EEH_DEV_IRQ_DISABLED;
- enable_irq(dev->irq);
+
+ desc = irq_to_desc(dev->irq);
+ if (desc && desc->depth > 0)
+ enable_irq(dev->irq);
}
}