aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-05 19:11:16 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-05 19:11:16 -0400
commit5943a9bbbb98b5c957662edd2fc902cc14e65895 (patch)
tree84603ce3f01c192cd4ca3b2fbeeddf88b915b3d1
parentb98d6cb80b0dc44e1d3382bc8c530eaa80ad5b6c (diff)
parent95375f2ab2960c135484d83ea9f8f357cb1be26a (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--MAINTAINERS1
-rw-r--r--drivers/pci/controller/pci-mvebu.c52
-rw-r--r--drivers/pci/pci.c27
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
324F: Documentation/ABI/testing/configfs-acpi 324F: Documentation/ABI/testing/configfs-acpi
325F: drivers/pci/*acpi* 325F: drivers/pci/*acpi*
326F: drivers/pci/*/*acpi* 326F: drivers/pci/*/*acpi*
327F: drivers/pci/*/*/*acpi*
328F: tools/power/acpi/ 327F: tools/power/acpi/
329 328
330ACPI APEI 329ACPI 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 */
1194static 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
1191static int mvebu_pcie_probe(struct platform_device *pdev) 1235static 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
1274static const struct of_device_id mvebu_pcie_of_match_table[] = { 1318static 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)
1289EXPORT_SYMBOL(pci_save_state); 1289EXPORT_SYMBOL(pci_save_state);
1290 1290
1291static void pci_restore_config_dword(struct pci_dev *pdev, int offset, 1291static 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
1315static void pci_restore_config_space_range(struct pci_dev *pdev, 1315static 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
1326static void pci_restore_config_space(struct pci_dev *pdev) 1327static 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