aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 15:03:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-09 15:03:49 -0400
commit80213c03c4151d900cf293ef0fc51f8d88495e14 (patch)
treeaf2422fa255aed96c23cef894e0adbf817f30c45 /drivers/pci/probe.c
parentea584595fc85e65796335033dfca25ed655cd0ed (diff)
parentf92d9ee3ab39841d1f29f2d1aa96ff7c74b36ee1 (diff)
Merge tag 'pci-v3.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas: "The interesting things here are: - Turn on Config Request Retry Status Software Visibility. This caused hangs last time, but we included a fix this time. - Rework PCI device configuration to use _HPP/_HPX more aggressively - Allow PCI devices to be put into D3cold during system suspend - Add arm64 PCI support - Add APM X-Gene host bridge driver - Add TI Keystone host bridge driver - Add Xilinx AXI host bridge driver More detailed summary: Enumeration - Check Vendor ID only for Config Request Retry Status (Rajat Jain) - Enable Config Request Retry Status when supported (Rajat Jain) - Add generic domain handling (Catalin Marinas) - Generate uppercase hex for modalias interface class (Ricardo Ribalda Delgado) Resource management - Add missing MEM_64 mask in pci_assign_unassigned_bridge_resources() (Yinghai Lu) - Increase IBM ipr SAS Crocodile BARs to at least system page size (Douglas Lehr) PCI device hotplug - Prevent NULL dereference during pciehp probe (Andreas Noever) - Move _HPP & _HPX handling into core (Bjorn Helgaas) - Apply _HPP to PCIe devices as well as PCI (Bjorn Helgaas) - Apply _HPP/_HPX to display devices (Bjorn Helgaas) - Preserve SERR & PARITY settings when applying _HPP/_HPX (Bjorn Helgaas) - Preserve MPS and MRRS settings when applying _HPP/_HPX (Bjorn Helgaas) - Apply _HPP/_HPX to all devices, not just hot-added ones (Bjorn Helgaas) - Fix wait time in pciehp timeout message (Yinghai Lu) - Add more pciehp Slot Control debug output (Yinghai Lu) - Stop disabling pciehp notifications during init (Yinghai Lu) MSI - Remove arch_msi_check_device() (Alexander Gordeev) - Rename pci_msi_check_device() to pci_msi_supported() (Alexander Gordeev) - Move D0 check into pci_msi_check_device() (Alexander Gordeev) - Remove unused kobject from struct msi_desc (Yijing Wang) - Remove "pos" from the struct msi_desc msi_attrib (Yijing Wang) - Add "msi_bus" sysfs MSI/MSI-X control for endpoints (Yijing Wang) - Use __get_cached_msi_msg() instead of get_cached_msi_msg() (Yijing Wang) - Use __read_msi_msg() instead of read_msi_msg() (Yijing Wang) - Use __write_msi_msg() instead of write_msi_msg() (Yijing Wang) Power management - Drop unused runtime PM support code for PCIe ports (Rafael J. Wysocki) - Allow PCI devices to be put into D3cold during system suspend (Rafael J. Wysocki) AER - Add additional AER error strings (Gong Chen) - Make <linux/aer.h> standalone includable (Thierry Reding) Virtualization - Add ACS quirk for Solarflare SFC9120 & SFC9140 (Alex Williamson) - Add ACS quirk for Intel 10G NICs (Alex Williamson) - Add ACS quirk for AMD A88X southbridge (Marti Raudsepp) - Remove unused pci_find_upstream_pcie_bridge(), pci_get_dma_source() (Alex Williamson) - Add device flag helpers (Ethan Zhao) - Assume all Mellanox devices have broken INTx masking (Gavin Shan) Generic host bridge driver - Fix ioport_map() for !CONFIG_GENERIC_IOMAP (Liviu Dudau) - Add pci_register_io_range() and pci_pio_to_address() (Liviu Dudau) - Define PCI_IOBASE as the base of virtual PCI IO space (Liviu Dudau) - Fix the conversion of IO ranges into IO resources (Liviu Dudau) - Add pci_get_new_domain_nr() and of_get_pci_domain_nr() (Liviu Dudau) - Add support for parsing PCI host bridge resources from DT (Liviu Dudau) - Add pci_remap_iospace() to map bus I/O resources (Liviu Dudau) - Add arm64 architectural support for PCI (Liviu Dudau) APM X-Gene - Add APM X-Gene PCIe driver (Tanmay Inamdar) - Add arm64 DT APM X-Gene PCIe device tree nodes (Tanmay Inamdar) Freescale i.MX6 - Probe in module_init(), not fs_initcall() (Lucas Stach) - Delay enabling reference clock for SS until it stabilizes (Tim Harvey) Marvell MVEBU - Fix uninitialized variable in mvebu_get_tgt_attr() (Thomas Petazzoni) NVIDIA Tegra - Make sure the PCIe PLL is really reset (Eric Yuen) - Add error path tegra_msi_teardown_irq() cleanup (Jisheng Zhang) - Fix extended configuration space mapping (Peter Daifuku) - Implement resource hierarchy (Thierry Reding) - Clear CLKREQ# enable on port disable (Thierry Reding) - Add Tegra124 support (Thierry Reding) ST Microelectronics SPEAr13xx - Pass config resource through reg property (Pratyush Anand) Synopsys DesignWare - Use NULL instead of false (Fabio Estevam) - Parse bus-range property from devicetree (Lucas Stach) - Use pci_create_root_bus() instead of pci_scan_root_bus() (Lucas Stach) - Remove pci_assign_unassigned_resources() (Lucas Stach) - Check private_data validity in single place (Lucas Stach) - Setup and clear exactly one MSI at a time (Lucas Stach) - Remove open-coded bitmap operations (Lucas Stach) - Fix configuration base address when using 'reg' (Minghuan Lian) - Fix IO resource end address calculation (Minghuan Lian) - Rename get_msi_data() to get_msi_addr() (Minghuan Lian) - Add get_msi_data() to pcie_host_ops (Minghuan Lian) - Add support for v3.65 hardware (Murali Karicheri) - Fold struct pcie_port_info into struct pcie_port (Pratyush Anand) TI Keystone - Add TI Keystone PCIe driver (Murali Karicheri) - Limit MRSS for all downstream devices (Murali Karicheri) - Assume controller is already in RC mode (Murali Karicheri) - Set device ID based on SoC to support multiple ports (Murali Karicheri) Xilinx AXI - Add Xilinx AXI PCIe driver (Srikanth Thokala) - Fix xilinx_pcie_assign_msi() return value test (Dan Carpenter) Miscellaneous - Clean up whitespace (Quentin Lambert) - Remove assignments from "if" conditions (Quentin Lambert) - Move PCI_VENDOR_ID_VMWARE to pci_ids.h (Francesco Ruggeri) - x86: Mark DMI tables as initialization data (Mathias Krause) - x86: Move __init annotation to the correct place (Mathias Krause) - x86: Mark constants of pci_mmcfg_nvidia_mcp55() as __initconst (Mathias Krause) - x86: Constify pci_mmcfg_probes[] array (Mathias Krause) - x86: Mark PCI BIOS initialization code as such (Mathias Krause) - Parenthesize PCI_DEVID and PCI_VPD_LRDT_ID parameters (Megan Kamiya) - Remove unnecessary variable in pci_add_dynid() (Tobias Klauser)" * tag 'pci-v3.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (109 commits) arm64: dts: Add APM X-Gene PCIe device tree nodes PCI: Add ACS quirk for AMD A88X southbridge devices PCI: xgene: Add APM X-Gene PCIe driver PCI: designware: Remove open-coded bitmap operations PCI/MSI: Remove unnecessary temporary variable PCI/MSI: Use __write_msi_msg() instead of write_msi_msg() MSI/powerpc: Use __read_msi_msg() instead of read_msi_msg() PCI/MSI: Use __get_cached_msi_msg() instead of get_cached_msi_msg() PCI/MSI: Add "msi_bus" sysfs MSI/MSI-X control for endpoints PCI/MSI: Remove "pos" from the struct msi_desc msi_attrib PCI/MSI: Remove unused kobject from struct msi_desc PCI/MSI: Rename pci_msi_check_device() to pci_msi_supported() PCI/MSI: Move D0 check into pci_msi_check_device() PCI/MSI: Remove arch_msi_check_device() irqchip: armada-370-xp: Remove arch_msi_check_device() PCI/MSI/PPC: Remove arch_msi_check_device() arm64: Add architectural support for PCI PCI: Add pci_remap_iospace() to map bus I/O resources of/pci: Add support for parsing PCI host bridge resources from DT of/pci: Add pci_get_new_domain_nr() and of_get_pci_domain_nr() ... Conflicts: arch/arm64/boot/dts/apm-storm.dtsi
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c167
1 files changed, 162 insertions, 5 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4170113cde61..5ed99309c758 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -6,6 +6,7 @@
6#include <linux/delay.h> 6#include <linux/delay.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/pci.h> 8#include <linux/pci.h>
9#include <linux/pci_hotplug.h>
9#include <linux/slab.h> 10#include <linux/slab.h>
10#include <linux/module.h> 11#include <linux/module.h>
11#include <linux/cpumask.h> 12#include <linux/cpumask.h>
@@ -485,7 +486,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
485 } 486 }
486} 487}
487 488
488static struct pci_bus *pci_alloc_bus(void) 489static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
489{ 490{
490 struct pci_bus *b; 491 struct pci_bus *b;
491 492
@@ -500,6 +501,10 @@ static struct pci_bus *pci_alloc_bus(void)
500 INIT_LIST_HEAD(&b->resources); 501 INIT_LIST_HEAD(&b->resources);
501 b->max_bus_speed = PCI_SPEED_UNKNOWN; 502 b->max_bus_speed = PCI_SPEED_UNKNOWN;
502 b->cur_bus_speed = PCI_SPEED_UNKNOWN; 503 b->cur_bus_speed = PCI_SPEED_UNKNOWN;
504#ifdef CONFIG_PCI_DOMAINS_GENERIC
505 if (parent)
506 b->domain_nr = parent->domain_nr;
507#endif
503 return b; 508 return b;
504} 509}
505 510
@@ -671,7 +676,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
671 /* 676 /*
672 * Allocate a new bus, and inherit stuff from the parent.. 677 * Allocate a new bus, and inherit stuff from the parent..
673 */ 678 */
674 child = pci_alloc_bus(); 679 child = pci_alloc_bus(parent);
675 if (!child) 680 if (!child)
676 return NULL; 681 return NULL;
677 682
@@ -740,6 +745,17 @@ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
740} 745}
741EXPORT_SYMBOL(pci_add_new_bus); 746EXPORT_SYMBOL(pci_add_new_bus);
742 747
748static void pci_enable_crs(struct pci_dev *pdev)
749{
750 u16 root_cap = 0;
751
752 /* Enable CRS Software Visibility if supported */
753 pcie_capability_read_word(pdev, PCI_EXP_RTCAP, &root_cap);
754 if (root_cap & PCI_EXP_RTCAP_CRSVIS)
755 pcie_capability_set_word(pdev, PCI_EXP_RTCTL,
756 PCI_EXP_RTCTL_CRSSVE);
757}
758
743/* 759/*
744 * If it's a bridge, configure it and scan the bus behind it. 760 * If it's a bridge, configure it and scan the bus behind it.
745 * For CardBus bridges, we don't scan behind as the devices will 761 * For CardBus bridges, we don't scan behind as the devices will
@@ -787,6 +803,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
787 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, 803 pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
788 bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); 804 bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
789 805
806 pci_enable_crs(dev);
807
790 if ((secondary || subordinate) && !pcibios_assign_all_busses() && 808 if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
791 !is_cardbus && !broken) { 809 !is_cardbus && !broken) {
792 unsigned int cmax; 810 unsigned int cmax;
@@ -1226,6 +1244,137 @@ int pci_setup_device(struct pci_dev *dev)
1226 return 0; 1244 return 0;
1227} 1245}
1228 1246
1247static struct hpp_type0 pci_default_type0 = {
1248 .revision = 1,
1249 .cache_line_size = 8,
1250 .latency_timer = 0x40,
1251 .enable_serr = 0,
1252 .enable_perr = 0,
1253};
1254
1255static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
1256{
1257 u16 pci_cmd, pci_bctl;
1258
1259 if (!hpp)
1260 hpp = &pci_default_type0;
1261
1262 if (hpp->revision > 1) {
1263 dev_warn(&dev->dev,
1264 "PCI settings rev %d not supported; using defaults\n",
1265 hpp->revision);
1266 hpp = &pci_default_type0;
1267 }
1268
1269 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
1270 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
1271 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
1272 if (hpp->enable_serr)
1273 pci_cmd |= PCI_COMMAND_SERR;
1274 if (hpp->enable_perr)
1275 pci_cmd |= PCI_COMMAND_PARITY;
1276 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
1277
1278 /* Program bridge control value */
1279 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
1280 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
1281 hpp->latency_timer);
1282 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
1283 if (hpp->enable_serr)
1284 pci_bctl |= PCI_BRIDGE_CTL_SERR;
1285 if (hpp->enable_perr)
1286 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
1287 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
1288 }
1289}
1290
1291static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
1292{
1293 if (hpp)
1294 dev_warn(&dev->dev, "PCI-X settings not supported\n");
1295}
1296
1297static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
1298{
1299 int pos;
1300 u32 reg32;
1301
1302 if (!hpp)
1303 return;
1304
1305 if (hpp->revision > 1) {
1306 dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
1307 hpp->revision);
1308 return;
1309 }
1310
1311 /*
1312 * Don't allow _HPX to change MPS or MRRS settings. We manage
1313 * those to make sure they're consistent with the rest of the
1314 * platform.
1315 */
1316 hpp->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
1317 PCI_EXP_DEVCTL_READRQ;
1318 hpp->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
1319 PCI_EXP_DEVCTL_READRQ);
1320
1321 /* Initialize Device Control Register */
1322 pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
1323 ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
1324
1325 /* Initialize Link Control Register */
1326 if (dev->subordinate)
1327 pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
1328 ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
1329
1330 /* Find Advanced Error Reporting Enhanced Capability */
1331 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
1332 if (!pos)
1333 return;
1334
1335 /* Initialize Uncorrectable Error Mask Register */
1336 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
1337 reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
1338 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
1339
1340 /* Initialize Uncorrectable Error Severity Register */
1341 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
1342 reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
1343 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
1344
1345 /* Initialize Correctable Error Mask Register */
1346 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
1347 reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
1348 pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
1349
1350 /* Initialize Advanced Error Capabilities and Control Register */
1351 pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
1352 reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
1353 pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
1354
1355 /*
1356 * FIXME: The following two registers are not supported yet.
1357 *
1358 * o Secondary Uncorrectable Error Severity Register
1359 * o Secondary Uncorrectable Error Mask Register
1360 */
1361}
1362
1363static void pci_configure_device(struct pci_dev *dev)
1364{
1365 struct hotplug_params hpp;
1366 int ret;
1367
1368 memset(&hpp, 0, sizeof(hpp));
1369 ret = pci_get_hp_params(dev, &hpp);
1370 if (ret)
1371 return;
1372
1373 program_hpp_type2(dev, hpp.t2);
1374 program_hpp_type1(dev, hpp.t1);
1375 program_hpp_type0(dev, hpp.t0);
1376}
1377
1229static void pci_release_capabilities(struct pci_dev *dev) 1378static void pci_release_capabilities(struct pci_dev *dev)
1230{ 1379{
1231 pci_vpd_release(dev); 1380 pci_vpd_release(dev);
@@ -1282,8 +1431,13 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
1282 *l == 0x0000ffff || *l == 0xffff0000) 1431 *l == 0x0000ffff || *l == 0xffff0000)
1283 return false; 1432 return false;
1284 1433
1285 /* Configuration request Retry Status */ 1434 /*
1286 while (*l == 0xffff0001) { 1435 * Configuration Request Retry Status. Some root ports return the
1436 * actual device ID instead of the synthetic ID (0xFFFF) required
1437 * by the PCIe spec. Ignore the device ID and only check for
1438 * (vendor id == 1).
1439 */
1440 while ((*l & 0xffff) == 0x0001) {
1287 if (!crs_timeout) 1441 if (!crs_timeout)
1288 return false; 1442 return false;
1289 1443
@@ -1363,6 +1517,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
1363{ 1517{
1364 int ret; 1518 int ret;
1365 1519
1520 pci_configure_device(dev);
1521
1366 device_initialize(&dev->dev); 1522 device_initialize(&dev->dev);
1367 dev->dev.release = pci_release_dev; 1523 dev->dev.release = pci_release_dev;
1368 1524
@@ -1751,13 +1907,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1751 char bus_addr[64]; 1907 char bus_addr[64];
1752 char *fmt; 1908 char *fmt;
1753 1909
1754 b = pci_alloc_bus(); 1910 b = pci_alloc_bus(NULL);
1755 if (!b) 1911 if (!b)
1756 return NULL; 1912 return NULL;
1757 1913
1758 b->sysdata = sysdata; 1914 b->sysdata = sysdata;
1759 b->ops = ops; 1915 b->ops = ops;
1760 b->number = b->busn_res.start = bus; 1916 b->number = b->busn_res.start = bus;
1917 pci_bus_assign_domain_nr(b, parent);
1761 b2 = pci_find_bus(pci_domain_nr(b), bus); 1918 b2 = pci_find_bus(pci_domain_nr(b), bus);
1762 if (b2) { 1919 if (b2) {
1763 /* If we already got to this bus through a different bridge, ignore it */ 1920 /* If we already got to this bus through a different bridge, ignore it */