mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
PCI: Drop unnecessary retries when restoring BARs
In 2012, commit26f41062f2("PCI: check for pci bar restore completion and retry") amended pci_restore_state() to attempt BAR restoration up to 10 times. This was necessary because back in the day, only a 100 msec delay was observed after pcie_flr() carried out a Function Level Reset. The retries ensured that BARs were restored even if devices needed more time to come out of reset. In 2016, commit5adecf817d("PCI: Wait for up to 1000ms after FLR reset") extended the delay to 1 sec. Commita2758b6b8f("PCI: Rename pci_flr_wait() to pci_dev_wait() and make it generic") subsequently extended it further to 60 sec. The lengthened delay makes it unnecessary to retry BAR restoration, so drop it. Reported-by: Bjorn Helgaas <bhelgaas@google.com> Closes: https://lore.kernel.org/r/20260416225745.GA41850@bhelgaas/ Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://patch.msgid.link/785c98b50a7a00d0698848c75d51b8f5669ad18f.1777814679.git.lukas@wunner.de
This commit is contained in:
parent
41167a1e98
commit
10baa9b4df
|
|
@ -1784,7 +1784,7 @@ int pci_save_state(struct pci_dev *dev)
|
|||
EXPORT_SYMBOL(pci_save_state);
|
||||
|
||||
static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
|
||||
u32 saved_val, int retry, bool force)
|
||||
u32 saved_val, bool force)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
|
|
@ -1792,52 +1792,42 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
|
|||
if (!force && val == saved_val)
|
||||
return;
|
||||
|
||||
for (;;) {
|
||||
pci_dbg(pdev, "restore config %#04x: %#010x -> %#010x\n",
|
||||
offset, val, saved_val);
|
||||
pci_write_config_dword(pdev, offset, saved_val);
|
||||
if (retry-- <= 0)
|
||||
return;
|
||||
pci_dbg(pdev, "restore config %#04x: %#010x -> %#010x\n", offset, val,
|
||||
saved_val);
|
||||
|
||||
pci_read_config_dword(pdev, offset, &val);
|
||||
if (val == saved_val)
|
||||
return;
|
||||
|
||||
mdelay(1);
|
||||
}
|
||||
pci_write_config_dword(pdev, offset, saved_val);
|
||||
}
|
||||
|
||||
static void pci_restore_config_space_range(struct pci_dev *pdev,
|
||||
int start, int end, int retry,
|
||||
bool force)
|
||||
int start, int end, bool force)
|
||||
{
|
||||
int index;
|
||||
|
||||
for (index = end; index >= start; index--)
|
||||
pci_restore_config_dword(pdev, 4 * index,
|
||||
pdev->saved_config_space[index],
|
||||
retry, force);
|
||||
force);
|
||||
}
|
||||
|
||||
static void pci_restore_config_space(struct pci_dev *pdev)
|
||||
{
|
||||
if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
|
||||
pci_restore_config_space_range(pdev, 10, 15, 0, false);
|
||||
pci_restore_config_space_range(pdev, 10, 15, false);
|
||||
/* Restore BARs before the command register. */
|
||||
pci_restore_config_space_range(pdev, 4, 9, 10, false);
|
||||
pci_restore_config_space_range(pdev, 0, 3, 0, false);
|
||||
pci_restore_config_space_range(pdev, 4, 9, false);
|
||||
pci_restore_config_space_range(pdev, 0, 3, false);
|
||||
} else if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
pci_restore_config_space_range(pdev, 12, 15, 0, false);
|
||||
pci_restore_config_space_range(pdev, 12, 15, false);
|
||||
|
||||
/*
|
||||
* Force rewriting of prefetch registers to avoid S3 resume
|
||||
* issues on Intel PCI bridges that occur when these
|
||||
* registers are not explicitly written.
|
||||
*/
|
||||
pci_restore_config_space_range(pdev, 9, 11, 0, true);
|
||||
pci_restore_config_space_range(pdev, 0, 8, 0, false);
|
||||
pci_restore_config_space_range(pdev, 9, 11, true);
|
||||
pci_restore_config_space_range(pdev, 0, 8, false);
|
||||
} else {
|
||||
pci_restore_config_space_range(pdev, 0, 15, 0, false);
|
||||
pci_restore_config_space_range(pdev, 0, 15, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user