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.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a16c6897bb9..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);
@@ -672,10 +662,11 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
672 detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | 662 detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
673 PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC | 663 PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
674 PCI_EXP_SLTSTA_CC); 664 PCI_EXP_SLTSTA_CC);
665 detected &= ~intr_loc;
675 intr_loc |= detected; 666 intr_loc |= detected;
676 if (!intr_loc) 667 if (!intr_loc)
677 return IRQ_NONE; 668 return IRQ_NONE;
678 if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, detected)) { 669 if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, intr_loc)) {
679 ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n", 670 ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
680 __func__); 671 __func__);
681 return IRQ_NONE; 672 return IRQ_NONE;
@@ -709,9 +700,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
709 pciehp_handle_presence_change(p_slot); 700 pciehp_handle_presence_change(p_slot);
710 701
711 /* Check Power Fault Detected */ 702 /* Check Power Fault Detected */
712 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;
713 pciehp_handle_power_fault(p_slot); 705 pciehp_handle_power_fault(p_slot);
714 706 }
715 return IRQ_HANDLED; 707 return IRQ_HANDLED;
716} 708}
717 709