diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index ac1e495c314ead9d803658a0ae296f4010c56898..77e530321de2c51d58a1ccf6f2ffe3caf254a1b7 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -787,8 +787,13 @@ static int hpc_power_on_slot(struct slot * slot) slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; + /* Enable detection that we turned off at slot power-off time */ if (!pciehp_poll_mode) - slot_cmd = slot_cmd | HP_INTR_ENABLE; + slot_cmd = slot_cmd | + PWR_FAULT_DETECT_ENABLE | + MRL_DETECT_ENABLE | + PRSN_DETECT_ENABLE | + HP_INTR_ENABLE; retval = pcie_write_cmd(slot, slot_cmd); @@ -833,8 +838,18 @@ static int hpc_power_off_slot(struct slot * slot) slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; + /* + * 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 = slot_cmd | HP_INTR_ENABLE; + slot_cmd = (slot_cmd & + ~PWR_FAULT_DETECT_ENABLE & + ~MRL_DETECT_ENABLE & + ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE; retval = pcie_write_cmd(slot, slot_cmd);