diff options
| author | Ingo Molnar <mingo@kernel.org> | 2018-10-23 06:30:19 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2018-10-23 06:30:19 -0400 |
| commit | dda93b45389f025fd3422d22cc31cc1ea6040305 (patch) | |
| tree | 44a856744843e24ed1baf6ca4edb1be04809a606 /drivers/pci/pci.c | |
| parent | 2e62024c265aa69315ed02835623740030435380 (diff) | |
| parent | b61b8bba18fe2b63d38fdaf9b83de25e2d787dfe (diff) | |
Merge branch 'x86/cache' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/pci/pci.c')
| -rw-r--r-- | drivers/pci/pci.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1835f3a7aa8d..51b6c81671c1 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1289,12 +1289,12 @@ int pci_save_state(struct pci_dev *dev) | |||
| 1289 | EXPORT_SYMBOL(pci_save_state); | 1289 | EXPORT_SYMBOL(pci_save_state); |
| 1290 | 1290 | ||
| 1291 | static void pci_restore_config_dword(struct pci_dev *pdev, int offset, | 1291 | static void pci_restore_config_dword(struct pci_dev *pdev, int offset, |
| 1292 | u32 saved_val, int retry) | 1292 | u32 saved_val, int retry, bool force) |
| 1293 | { | 1293 | { |
| 1294 | u32 val; | 1294 | u32 val; |
| 1295 | 1295 | ||
| 1296 | pci_read_config_dword(pdev, offset, &val); | 1296 | pci_read_config_dword(pdev, offset, &val); |
| 1297 | if (val == saved_val) | 1297 | if (!force && val == saved_val) |
| 1298 | return; | 1298 | return; |
| 1299 | 1299 | ||
| 1300 | for (;;) { | 1300 | for (;;) { |
| @@ -1313,25 +1313,36 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset, | |||
| 1313 | } | 1313 | } |
| 1314 | 1314 | ||
| 1315 | static void pci_restore_config_space_range(struct pci_dev *pdev, | 1315 | static void pci_restore_config_space_range(struct pci_dev *pdev, |
| 1316 | int start, int end, int retry) | 1316 | int start, int end, int retry, |
| 1317 | bool force) | ||
| 1317 | { | 1318 | { |
| 1318 | int index; | 1319 | int index; |
| 1319 | 1320 | ||
| 1320 | for (index = end; index >= start; index--) | 1321 | for (index = end; index >= start; index--) |
| 1321 | pci_restore_config_dword(pdev, 4 * index, | 1322 | pci_restore_config_dword(pdev, 4 * index, |
| 1322 | pdev->saved_config_space[index], | 1323 | pdev->saved_config_space[index], |
| 1323 | retry); | 1324 | retry, force); |
| 1324 | } | 1325 | } |
| 1325 | 1326 | ||
| 1326 | static void pci_restore_config_space(struct pci_dev *pdev) | 1327 | static void pci_restore_config_space(struct pci_dev *pdev) |
| 1327 | { | 1328 | { |
| 1328 | if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { | 1329 | if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { |
| 1329 | pci_restore_config_space_range(pdev, 10, 15, 0); | 1330 | pci_restore_config_space_range(pdev, 10, 15, 0, false); |
| 1330 | /* Restore BARs before the command register. */ | 1331 | /* Restore BARs before the command register. */ |
| 1331 | pci_restore_config_space_range(pdev, 4, 9, 10); | 1332 | pci_restore_config_space_range(pdev, 4, 9, 10, false); |
| 1332 | pci_restore_config_space_range(pdev, 0, 3, 0); | 1333 | pci_restore_config_space_range(pdev, 0, 3, 0, false); |
| 1334 | } else if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
| 1335 | pci_restore_config_space_range(pdev, 12, 15, 0, false); | ||
| 1336 | |||
| 1337 | /* | ||
| 1338 | * Force rewriting of prefetch registers to avoid S3 resume | ||
| 1339 | * issues on Intel PCI bridges that occur when these | ||
| 1340 | * registers are not explicitly written. | ||
| 1341 | */ | ||
| 1342 | pci_restore_config_space_range(pdev, 9, 11, 0, true); | ||
| 1343 | pci_restore_config_space_range(pdev, 0, 8, 0, false); | ||
| 1333 | } else { | 1344 | } else { |
| 1334 | pci_restore_config_space_range(pdev, 0, 15, 0); | 1345 | pci_restore_config_space_range(pdev, 0, 15, 0, false); |
| 1335 | } | 1346 | } |
| 1336 | } | 1347 | } |
| 1337 | 1348 | ||
