diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index b57fc6d6e28a..026830a138ae 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -620,8 +620,18 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) pciehp_queue_interrupt_event(slot, INT_BUTTON_PRESS); } - /* Check Presence Detect Changed */ - if (events & PCI_EXP_SLTSTA_PDC) { + /* + * Check Link Status Changed at higher precedence than Presence + * Detect Changed. The PDS value may be set to "card present" from + * out-of-band detection, which may be in conflict with a Link Down + * and cause the wrong event to queue. + */ + if (events & PCI_EXP_SLTSTA_DLLSC) { + ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot), + link ? "Up" : "Down"); + pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP : + INT_LINK_DOWN); + } else if (events & PCI_EXP_SLTSTA_PDC) { present = !!(status & PCI_EXP_SLTSTA_PDS); ctrl_info(ctrl, "Slot(%s): Card %spresent\n", slot_name(slot), present ? "" : "not "); @@ -636,13 +646,6 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) pciehp_queue_interrupt_event(slot, INT_POWER_FAULT); } - if (events & PCI_EXP_SLTSTA_DLLSC) { - ctrl_info(ctrl, "Slot(%s): Link %s\n", slot_name(slot), - link ? "Up" : "Down"); - pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP : - INT_LINK_DOWN); - } - return IRQ_HANDLED; } |