aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMayurkumar Patel <mayurkumar.patel@intel.com>2016-09-09 10:10:17 -0400
committerBjorn Helgaas <bhelgaas@google.com>2016-09-14 15:24:40 -0400
commit0c923d1da394b96727b813d1e64412b72f1dc580 (patch)
tree7a023b2ba1d8efbbb9a57c97ec40ff9a65a662d4
parentfad214b0aa726ee21adcac4308d388efcb89d6bd (diff)
PCI: pciehp: Don't re-read Slot Status when queuing hotplug event
Previously we read Slot Status to learn about hotplug events, then cleared the events, then re-read Slot Status to find out what happened. But Slot Status might have changed before the second read. Capture the Slot Status once before clearing the events. Also capture the Link Status if we had a link status change. [bhelgaas: changelog, split to separate patch] Tested-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Mayurkumar Patel <mayurkumar.patel@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 625fa6a2f3ab..fe99b45c5925 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -566,6 +566,10 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
566 if (!events) 566 if (!events)
567 return IRQ_NONE; 567 return IRQ_NONE;
568 568
569 /* Capture link status before clearing interrupts */
570 if (events & PCI_EXP_SLTSTA_DLLSC)
571 link = pciehp_check_link_active(ctrl);
572
569 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events); 573 pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events);
570 ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events); 574 ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events);
571 575
@@ -598,7 +602,7 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
598 602
599 /* Check Presence Detect Changed */ 603 /* Check Presence Detect Changed */
600 if (events & PCI_EXP_SLTSTA_PDC) { 604 if (events & PCI_EXP_SLTSTA_PDC) {
601 pciehp_get_adapter_status(slot, &present); 605 present = !!(status & PCI_EXP_SLTSTA_PDS);
602 ctrl_info(ctrl, "Card %spresent on Slot(%s)\n", 606 ctrl_info(ctrl, "Card %spresent on Slot(%s)\n",
603 present ? "" : "not ", slot_name(slot)); 607 present ? "" : "not ", slot_name(slot));
604 pciehp_queue_interrupt_event(slot, present ? INT_PRESENCE_ON : 608 pciehp_queue_interrupt_event(slot, present ? INT_PRESENCE_ON :
@@ -613,7 +617,6 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
613 } 617 }
614 618
615 if (events & PCI_EXP_SLTSTA_DLLSC) { 619 if (events & PCI_EXP_SLTSTA_DLLSC) {
616 link = pciehp_check_link_active(ctrl);
617 ctrl_info(ctrl, "slot(%s): Link %s event\n", 620 ctrl_info(ctrl, "slot(%s): Link %s event\n",
618 slot_name(slot), link ? "Up" : "Down"); 621 slot_name(slot), link ? "Up" : "Down");
619 pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP : 622 pciehp_queue_interrupt_event(slot, link ? INT_LINK_UP :