diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-05 19:11:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-05 19:11:16 -0400 |
commit | 5943a9bbbb98b5c957662edd2fc902cc14e65895 (patch) | |
tree | 84603ce3f01c192cd4ca3b2fbeeddf88b915b3d1 | |
parent | b98d6cb80b0dc44e1d3382bc8c530eaa80ad5b6c (diff) | |
parent | 95375f2ab2960c135484d83ea9f8f357cb1be26a (diff) |
Merge tag 'pci-v4.19-fixes-3' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Bjorn writes:
"PCI fixes for v4.19:
- Reprogram bridge prefetch registers to fix NVIDIA and Radeon issues
after suspend/resume (Daniel Drake)
- Fix mvebu I/O mapping creation sequence (Thomas Petazzoni)
- Fix minor MAINTAINERS file match issue (Bjorn Helgaas)"
* tag 'pci-v4.19-fixes-3' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
PCI: mvebu: Fix PCI I/O mapping creation sequence
MAINTAINERS: Remove obsolete drivers/pci pattern from ACPI section
PCI: Reprogram bridge prefetch registers on resume
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/pci/controller/pci-mvebu.c | 52 | ||||
-rw-r--r-- | drivers/pci/pci.c | 27 |
3 files changed, 67 insertions, 13 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index e2d974963359..48a65c3a4189 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -324,7 +324,6 @@ F: Documentation/ABI/testing/sysfs-bus-acpi | |||
324 | F: Documentation/ABI/testing/configfs-acpi | 324 | F: Documentation/ABI/testing/configfs-acpi |
325 | F: drivers/pci/*acpi* | 325 | F: drivers/pci/*acpi* |
326 | F: drivers/pci/*/*acpi* | 326 | F: drivers/pci/*/*acpi* |
327 | F: drivers/pci/*/*/*acpi* | ||
328 | F: tools/power/acpi/ | 327 | F: tools/power/acpi/ |
329 | 328 | ||
330 | ACPI APEI | 329 | ACPI APEI |
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c index 50eb0729385b..a41d79b8d46a 100644 --- a/drivers/pci/controller/pci-mvebu.c +++ b/drivers/pci/controller/pci-mvebu.c | |||
@@ -1145,7 +1145,6 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie) | |||
1145 | { | 1145 | { |
1146 | struct device *dev = &pcie->pdev->dev; | 1146 | struct device *dev = &pcie->pdev->dev; |
1147 | struct device_node *np = dev->of_node; | 1147 | struct device_node *np = dev->of_node; |
1148 | unsigned int i; | ||
1149 | int ret; | 1148 | int ret; |
1150 | 1149 | ||
1151 | INIT_LIST_HEAD(&pcie->resources); | 1150 | INIT_LIST_HEAD(&pcie->resources); |
@@ -1179,13 +1178,58 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie) | |||
1179 | resource_size(&pcie->io) - 1); | 1178 | resource_size(&pcie->io) - 1); |
1180 | pcie->realio.name = "PCI I/O"; | 1179 | pcie->realio.name = "PCI I/O"; |
1181 | 1180 | ||
1181 | pci_add_resource(&pcie->resources, &pcie->realio); | ||
1182 | } | ||
1183 | |||
1184 | return devm_request_pci_bus_resources(dev, &pcie->resources); | ||
1185 | } | ||
1186 | |||
1187 | /* | ||
1188 | * This is a copy of pci_host_probe(), except that it does the I/O | ||
1189 | * remap as the last step, once we are sure we won't fail. | ||
1190 | * | ||
1191 | * It should be removed once the I/O remap error handling issue has | ||
1192 | * been sorted out. | ||
1193 | */ | ||
1194 | static int mvebu_pci_host_probe(struct pci_host_bridge *bridge) | ||
1195 | { | ||
1196 | struct mvebu_pcie *pcie; | ||
1197 | struct pci_bus *bus, *child; | ||
1198 | int ret; | ||
1199 | |||
1200 | ret = pci_scan_root_bus_bridge(bridge); | ||
1201 | if (ret < 0) { | ||
1202 | dev_err(bridge->dev.parent, "Scanning root bridge failed"); | ||
1203 | return ret; | ||
1204 | } | ||
1205 | |||
1206 | pcie = pci_host_bridge_priv(bridge); | ||
1207 | if (resource_size(&pcie->io) != 0) { | ||
1208 | unsigned int i; | ||
1209 | |||
1182 | for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K) | 1210 | for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K) |
1183 | pci_ioremap_io(i, pcie->io.start + i); | 1211 | pci_ioremap_io(i, pcie->io.start + i); |
1212 | } | ||
1184 | 1213 | ||
1185 | pci_add_resource(&pcie->resources, &pcie->realio); | 1214 | bus = bridge->bus; |
1215 | |||
1216 | /* | ||
1217 | * We insert PCI resources into the iomem_resource and | ||
1218 | * ioport_resource trees in either pci_bus_claim_resources() | ||
1219 | * or pci_bus_assign_resources(). | ||
1220 | */ | ||
1221 | if (pci_has_flag(PCI_PROBE_ONLY)) { | ||
1222 | pci_bus_claim_resources(bus); | ||
1223 | } else { | ||
1224 | pci_bus_size_bridges(bus); | ||
1225 | pci_bus_assign_resources(bus); | ||
1226 | |||
1227 | list_for_each_entry(child, &bus->children, node) | ||
1228 | pcie_bus_configure_settings(child); | ||
1186 | } | 1229 | } |
1187 | 1230 | ||
1188 | return devm_request_pci_bus_resources(dev, &pcie->resources); | 1231 | pci_bus_add_devices(bus); |
1232 | return 0; | ||
1189 | } | 1233 | } |
1190 | 1234 | ||
1191 | static int mvebu_pcie_probe(struct platform_device *pdev) | 1235 | static int mvebu_pcie_probe(struct platform_device *pdev) |
@@ -1268,7 +1312,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev) | |||
1268 | bridge->align_resource = mvebu_pcie_align_resource; | 1312 | bridge->align_resource = mvebu_pcie_align_resource; |
1269 | bridge->msi = pcie->msi; | 1313 | bridge->msi = pcie->msi; |
1270 | 1314 | ||
1271 | return pci_host_probe(bridge); | 1315 | return mvebu_pci_host_probe(bridge); |
1272 | } | 1316 | } |
1273 | 1317 | ||
1274 | static const struct of_device_id mvebu_pcie_of_match_table[] = { | 1318 | static const struct of_device_id mvebu_pcie_of_match_table[] = { |
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 | ||