aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c31
1 files changed, 11 insertions, 20 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index c1a312f24060..07bd32151146 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -548,23 +548,21 @@ static int hpc_power_on_slot(struct slot * slot)
548 548
549 slot_cmd = POWER_ON; 549 slot_cmd = POWER_ON;
550 cmd_mask = PCI_EXP_SLTCTL_PCC; 550 cmd_mask = PCI_EXP_SLTCTL_PCC;
551 /* Enable detection that we turned off at slot power-off time */
552 if (!pciehp_poll_mode) { 551 if (!pciehp_poll_mode) {
553 slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | 552 /* Enable power fault detection turned off at power off time */
554 PCI_EXP_SLTCTL_PDCE); 553 slot_cmd |= PCI_EXP_SLTCTL_PFDE;
555 cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | 554 cmd_mask |= PCI_EXP_SLTCTL_PFDE;
556 PCI_EXP_SLTCTL_PDCE);
557 } 555 }
558 556
559 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 557 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
560
561 if (retval) { 558 if (retval) {
562 ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); 559 ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
563 return -1; 560 return retval;
564 } 561 }
565 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", 562 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
566 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); 563 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
567 564
565 ctrl->power_fault_detected = 0;
568 return retval; 566 return retval;
569} 567}
570 568
@@ -621,18 +619,10 @@ static int hpc_power_off_slot(struct slot * slot)
621 619
622 slot_cmd = POWER_OFF; 620 slot_cmd = POWER_OFF;
623 cmd_mask = PCI_EXP_SLTCTL_PCC; 621 cmd_mask = PCI_EXP_SLTCTL_PCC;
624 /*
625 * If we get MRL or presence detect interrupts now, the isr
626 * will notice the sticky power-fault bit too and issue power
627 * indicator change commands. This will lead to an endless loop
628 * of command completions, since the power-fault bit remains on
629 * till the slot is powered on again.
630 */
631 if (!pciehp_poll_mode) { 622 if (!pciehp_poll_mode) {
632 slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | 623 /* Disable power fault detection */
633 PCI_EXP_SLTCTL_PDCE); 624 slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
634 cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE | 625 cmd_mask |= PCI_EXP_SLTCTL_PFDE;
635 PCI_EXP_SLTCTL_PDCE);
636 } 626 }
637 627
638 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 628 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
@@ -710,9 +700,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
710 pciehp_handle_presence_change(p_slot); 700 pciehp_handle_presence_change(p_slot);
711 701
712 /* Check Power Fault Detected */ 702 /* Check Power Fault Detected */
713 if (intr_loc & PCI_EXP_SLTSTA_PFD) 703 if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
704 ctrl->power_fault_detected = 1;
714 pciehp_handle_power_fault(p_slot); 705 pciehp_handle_power_fault(p_slot);
715 706 }
716 return IRQ_HANDLED; 707 return IRQ_HANDLED;
717} 708}
718 709