mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 22:53:55 +08:00
PCI: pciehp: Wait for hotplug command completion lazily
Previously we issued a hotplug command and waited for it to complete. But there's no need to wait until we're ready to issue the *next* command. The next command will probably be much later, so the first one may have already completed and we may not have to actually wait at all. Because of hardware errata, some controllers generate command completion events for some commands but not others. In the case of Intel CF118 (see spec update reference), the controller indicates command completion only for Slot Control writes that change the value of the following bits: Power Controller Control Power Indicator Control Attention Indicator Control Electromechanical Interlock Control Changes to other bits, e.g., the interrupt enable bits, do not cause the Command Completed bit to be set. Controllers from AMD and Nvidia are reported to have similar errata. These errata cause timeouts when pcie_enable_notification() enables interrupts. Previously that timeout occurred at boot-time. With this change, the timeout occurs later, when we change the state of the slot power, indicators, or interlock. This speeds up boot but causes a timeout at the first hotplug event on the slot. Subsequent events don't timeout because only the first (boot-time) hotplug command updates Slot Control without touching the power/indicator/interlock controls. Link: http://www.intel.com/content/www/us/en/processors/xeon/xeon-e7-v2-spec-update.html Tested-by: Rajat Jain <rajatxjain@gmail.com> (IDT 807a controller) Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Yinghai Lu <yinghai@kernel.org>
This commit is contained in:
parent
4283c70e91
commit
3461a06866
@ -168,6 +168,9 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
|
|||||||
|
|
||||||
mutex_lock(&ctrl->ctrl_lock);
|
mutex_lock(&ctrl->ctrl_lock);
|
||||||
|
|
||||||
|
/* Wait for any previous command that might still be in progress */
|
||||||
|
pcie_wait_cmd(ctrl);
|
||||||
|
|
||||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
|
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
|
||||||
if (slot_status & PCI_EXP_SLTSTA_CC) {
|
if (slot_status & PCI_EXP_SLTSTA_CC) {
|
||||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
|
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
|
||||||
@ -200,10 +203,6 @@ static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
|
|||||||
pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl);
|
pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, slot_ctrl);
|
||||||
ctrl->slot_ctrl = slot_ctrl;
|
ctrl->slot_ctrl = slot_ctrl;
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait for command completion.
|
|
||||||
*/
|
|
||||||
pcie_wait_cmd(ctrl);
|
|
||||||
mutex_unlock(&ctrl->ctrl_lock);
|
mutex_unlock(&ctrl->ctrl_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user