Commit 08685897b3586aad622cb48fe1fb07bc19bb78f5
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'pci-v3.18-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI fixes from Bjorn Helgaas: "These are fixes for an issue with 64-bit PCI bus addresses on 32-bit PAE kernels, an APM X-Gene problem (it depended on a generic change we removed before merging), a fix for my hotplug device configuration changes, and a devicetree documentation update. Resource management: - Support 64-bit bridge windows if we have 64-bit dma_addr_t (Yinghai Lu) PCI device hotplug: - Apply _HPX Link Control settings to all devices with a link (Yinghai Lu) Generic host bridge driver: - Add DT binding for "linux,pci-domain" property (Lucas Stach) APM X-Gene: - Assign resources to bus before adding new devices (Duc Dang)" * tag 'pci-v3.18-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: PCI: Support 64-bit bridge windows if we have 64-bit dma_addr_t PCI: Apply _HPX Link Control settings to all devices with a link PCI: Add missing DT binding for "linux,pci-domain" property PCI: xgene: Assign resources to bus before adding new devices
Showing 5 changed files Side-by-side Diff
Documentation/devicetree/bindings/pci/pci.txt
... | ... | @@ -7,4 +7,15 @@ |
7 | 7 | |
8 | 8 | Open Firmware Recommended Practice: Interrupt Mapping |
9 | 9 | http://www.openfirmware.org/1275/practice/imap/imap0_9d.pdf |
10 | + | |
11 | +Additionally to the properties specified in the above standards a host bridge | |
12 | +driver implementation may support the following properties: | |
13 | + | |
14 | +- linux,pci-domain: | |
15 | + If present this property assigns a fixed PCI domain number to a host bridge, | |
16 | + otherwise an unstable (across boots) unique number will be assigned. | |
17 | + It is required to either not set this property at all or set it for all | |
18 | + host bridges in the system, otherwise potentially conflicting domain numbers | |
19 | + may be assigned to root buses behind different host bridges. The domain | |
20 | + number for each host bridge in the system must be unique. |
drivers/pci/access.c
drivers/pci/host/pci-xgene.c
... | ... | @@ -631,9 +631,14 @@ |
631 | 631 | if (ret) |
632 | 632 | return ret; |
633 | 633 | |
634 | - bus = pci_scan_root_bus(&pdev->dev, 0, &xgene_pcie_ops, port, &res); | |
634 | + bus = pci_create_root_bus(&pdev->dev, 0, | |
635 | + &xgene_pcie_ops, port, &res); | |
635 | 636 | if (!bus) |
636 | 637 | return -ENOMEM; |
638 | + | |
639 | + pci_scan_child_bus(bus); | |
640 | + pci_assign_unassigned_bus_resources(bus); | |
641 | + pci_bus_add_devices(bus); | |
637 | 642 | |
638 | 643 | platform_set_drvdata(pdev, port); |
639 | 644 | return 0; |
drivers/pci/pci.h
drivers/pci/probe.c
... | ... | @@ -407,15 +407,16 @@ |
407 | 407 | { |
408 | 408 | struct pci_dev *dev = child->self; |
409 | 409 | u16 mem_base_lo, mem_limit_lo; |
410 | - unsigned long base, limit; | |
410 | + u64 base64, limit64; | |
411 | + dma_addr_t base, limit; | |
411 | 412 | struct pci_bus_region region; |
412 | 413 | struct resource *res; |
413 | 414 | |
414 | 415 | res = child->resource[2]; |
415 | 416 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); |
416 | 417 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); |
417 | - base = ((unsigned long) mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | |
418 | - limit = ((unsigned long) mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | |
418 | + base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | |
419 | + limit64 = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | |
419 | 420 | |
420 | 421 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { |
421 | 422 | u32 mem_base_hi, mem_limit_hi; |
422 | 423 | |
... | ... | @@ -429,17 +430,20 @@ |
429 | 430 | * this, just assume they are not being used. |
430 | 431 | */ |
431 | 432 | if (mem_base_hi <= mem_limit_hi) { |
432 | -#if BITS_PER_LONG == 64 | |
433 | - base |= ((unsigned long) mem_base_hi) << 32; | |
434 | - limit |= ((unsigned long) mem_limit_hi) << 32; | |
435 | -#else | |
436 | - if (mem_base_hi || mem_limit_hi) { | |
437 | - dev_err(&dev->dev, "can't handle 64-bit address space for bridge\n"); | |
438 | - return; | |
439 | - } | |
440 | -#endif | |
433 | + base64 |= (u64) mem_base_hi << 32; | |
434 | + limit64 |= (u64) mem_limit_hi << 32; | |
441 | 435 | } |
442 | 436 | } |
437 | + | |
438 | + base = (dma_addr_t) base64; | |
439 | + limit = (dma_addr_t) limit64; | |
440 | + | |
441 | + if (base != base64) { | |
442 | + dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n", | |
443 | + (unsigned long long) base64); | |
444 | + return; | |
445 | + } | |
446 | + | |
443 | 447 | if (base <= limit) { |
444 | 448 | res->flags = (mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) | |
445 | 449 | IORESOURCE_MEM | IORESOURCE_PREFETCH; |
... | ... | @@ -1323,7 +1327,7 @@ |
1323 | 1327 | ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); |
1324 | 1328 | |
1325 | 1329 | /* Initialize Link Control Register */ |
1326 | - if (dev->subordinate) | |
1330 | + if (pcie_cap_has_lnkctl(dev)) | |
1327 | 1331 | pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, |
1328 | 1332 | ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); |
1329 | 1333 |