|
@@ -548,23 +548,21 @@ static int hpc_power_on_slot(struct slot * slot)
|
|
|
|
|
|
slot_cmd = POWER_ON;
|
|
|
cmd_mask = PCI_EXP_SLTCTL_PCC;
|
|
|
- /* Enable detection that we turned off at slot power-off time */
|
|
|
if (!pciehp_poll_mode) {
|
|
|
- slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
|
|
|
- PCI_EXP_SLTCTL_PDCE);
|
|
|
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
|
|
|
- PCI_EXP_SLTCTL_PDCE);
|
|
|
+ /* Enable power fault detection turned off at power off time */
|
|
|
+ slot_cmd |= PCI_EXP_SLTCTL_PFDE;
|
|
|
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
|
|
|
}
|
|
|
|
|
|
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
|
|
|
-
|
|
|
if (retval) {
|
|
|
ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
|
|
|
- return -1;
|
|
|
+ return retval;
|
|
|
}
|
|
|
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
|
|
|
__func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
|
|
|
|
|
|
+ ctrl->power_fault_detected = 0;
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
@@ -621,18 +619,10 @@ static int hpc_power_off_slot(struct slot * slot)
|
|
|
|
|
|
slot_cmd = POWER_OFF;
|
|
|
cmd_mask = PCI_EXP_SLTCTL_PCC;
|
|
|
- /*
|
|
|
- * If we get MRL or presence detect interrupts now, the isr
|
|
|
- * will notice the sticky power-fault bit too and issue power
|
|
|
- * indicator change commands. This will lead to an endless loop
|
|
|
- * of command completions, since the power-fault bit remains on
|
|
|
- * till the slot is powered on again.
|
|
|
- */
|
|
|
if (!pciehp_poll_mode) {
|
|
|
- slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
|
|
|
- PCI_EXP_SLTCTL_PDCE);
|
|
|
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
|
|
|
- PCI_EXP_SLTCTL_PDCE);
|
|
|
+ /* Disable power fault detection */
|
|
|
+ slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
|
|
|
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
|
|
|
}
|
|
|
|
|
|
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
|
|
@@ -710,9 +700,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|
|
pciehp_handle_presence_change(p_slot);
|
|
|
|
|
|
/* Check Power Fault Detected */
|
|
|
- if (intr_loc & PCI_EXP_SLTSTA_PFD)
|
|
|
+ if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
|
|
|
+ ctrl->power_fault_detected = 1;
|
|
|
pciehp_handle_power_fault(p_slot);
|
|
|
-
|
|
|
+ }
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|