Merge tag 'pci-v4.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI changes from Bjorn Helgaas:
 "Enumeration
    - Read capability list as dwords, not bytes (Sean O. Stalley)

  Resource management
    - Don't check for PNP overlaps with unassigned PCI BARs (Bjorn Helgaas)
    - Mark invalid BARs as unassigned (Bjorn Helgaas)
    - Show driver, BAR#, and resource on pci_ioremap_bar() failure (Bjorn Helgaas)
    - Fail pci_ioremap_bar() on unassigned resources (Bjorn Helgaas)
    - Assign resources before drivers claim devices (Yijing Wang)
    - Claim bus resources before pci_bus_add_devices() (Yijing Wang)

  Power management
    - Optimize device state transition delays (Aaron Lu)
    - Don't clear ASPM bits when the FADT declares it's unsupported (Matthew Garrett)

  Virtualization
    - Add ACS quirks for Intel 1G NICs (Alex Williamson)

  IOMMU
    - Add ptr to OF node arg to of_iommu_configure() (Murali Karicheri)
    - Move of_dma_configure() to device.c to help re-use (Murali Karicheri)
    - Fix size when dma-range is not used (Murali Karicheri)
    - Add helper functions pci_get[put]_host_bridge_device() (Murali Karicheri)
    - Add of_pci_dma_configure() to update DMA configuration (Murali Karicheri)
    - Update DMA configuration from DT (Murali Karicheri)
    - dma-mapping: limit IOMMU mapping size (Murali Karicheri)
    - Calculate device DMA masks based on DT dma-range size (Murali Karicheri)

  ARM Versatile host bridge driver
    - Check for devm_ioremap_resource() failures (Jisheng Zhang)

  Broadcom iProc host bridge driver
    - Add Broadcom iProc PCIe driver (Ray Jui)

  Marvell MVEBU host bridge driver
    - Add suspend/resume support (Thomas Petazzoni)

  Renesas R-Car host bridge driver
    - Fix position of MSI enable bit (Nobuhiro Iwamatsu)
    - Write zeroes to reserved PCIEPARL bits (Nobuhiro Iwamatsu)
    - Change PCIEPARL and PCIEPARH to PCIEPALR and PCIEPAUR (Nobuhiro Iwamatsu)
    - Verify that mem_res is 64K-aligned (Nobuhiro Iwamatsu)

  Samsung Exynos host bridge driver
    - Fix INTx enablement statement termination error (Jaehoon Chung)

  Miscellaneous
    - Make a shareable UUID for PCI firmware ACPI _DSM (Aaron Lu)
    - Clarify policy for vendor IDs in pci.txt (Michael S. Tsirkin)"

* tag 'pci-v4.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (36 commits)
  PCI: Read capability list as dwords, not bytes
  PCI: layerscape: Simplify platform_get_resource_byname() failure checking
  PCI: keystone: Don't dereference possible NULL pointer
  PCI: versatile: Check for devm_ioremap_resource() failures
  PCI: Don't clear ASPM bits when the FADT declares it's unsupported
  PCI: Clarify policy for vendor IDs in pci.txt
  PCI/ACPI: Optimize device state transition delays
  PCI: Export pci_find_host_bridge() for use inside PCI core
  PCI: Make a shareable UUID for PCI firmware ACPI _DSM
  PCI: Fix typo in Thunderbolt kernel message
  PCI: exynos: Fix INTx enablement statement termination error
  PCI: iproc: Add Broadcom iProc PCIe support
  PCI: iproc: Add DT docs for Broadcom iProc PCIe driver
  PCI: Export symbols required for loadable host driver modules
  PCI: Add ACS quirks for Intel 1G NICs
  PCI: mvebu: Add suspend/resume support
  PCI: Cleanup control flow
  sparc/PCI: Claim bus resources before pci_bus_add_devices()
  PCI: Assign resources before drivers claim devices (pci_scan_root_bus())
  PCI: Fail pci_ioremap_bar() on unassigned resources
  ...
This commit is contained in:
Linus Torvalds
2015-04-13 15:45:47 -07:00
61 changed files with 1008 additions and 229 deletions

View File

@@ -18,6 +18,15 @@
#include <linux/pm_qos.h>
#include "pci.h"
/*
* The UUID is defined in the PCI Firmware Specification available here:
* https://www.pcisig.com/members/downloads/pcifw_r3_1_13Dec10.pdf
*/
const u8 pci_acpi_dsm_uuid[] = {
0xd0, 0x37, 0xc9, 0xe5, 0x53, 0x35, 0x7a, 0x4d,
0x91, 0x17, 0xea, 0x4d, 0x19, 0xc3, 0x43, 0x4d
};
phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
{
acpi_status status = AE_NOT_EXIST;
@@ -531,11 +540,32 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = {
void acpi_pci_add_bus(struct pci_bus *bus)
{
union acpi_object *obj;
struct pci_host_bridge *bridge;
if (acpi_pci_disabled || !bus->bridge)
return;
acpi_pci_slot_enumerate(bus);
acpiphp_enumerate_slots(bus);
/*
* For a host bridge, check its _DSM for function 8 and if
* that is available, mark it in pci_host_bridge.
*/
if (!pci_is_root_bus(bus))
return;
obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), pci_acpi_dsm_uuid, 3,
RESET_DELAY_DSM, NULL);
if (!obj)
return;
if (obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 1) {
bridge = pci_find_host_bridge(bus);
bridge->ignore_reset_delay = 1;
}
ACPI_FREE(obj);
}
void acpi_pci_remove_bus(struct pci_bus *bus)
@@ -561,6 +591,57 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev)
check_children);
}
/**
* pci_acpi_optimize_delay - optimize PCI D3 and D3cold delay from ACPI
* @pdev: the PCI device whose delay is to be updated
* @adev: the companion ACPI device of this PCI device
*
* Update the d3_delay and d3cold_delay of a PCI device from the ACPI _DSM
* control method of either the device itself or the PCI host bridge.
*
* Function 8, "Reset Delay," applies to the entire hierarchy below a PCI
* host bridge. If it returns one, the OS may assume that all devices in
* the hierarchy have already completed power-on reset delays.
*
* Function 9, "Device Readiness Durations," applies only to the object
* where it is located. It returns delay durations required after various
* events if the device requires less time than the spec requires. Delays
* from this function take precedence over the Reset Delay function.
*
* These _DSM functions are defined by the draft ECN of January 28, 2014,
* titled "ACPI additions for FW latency optimizations."
*/
static void pci_acpi_optimize_delay(struct pci_dev *pdev,
acpi_handle handle)
{
struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);
int value;
union acpi_object *obj, *elements;
if (bridge->ignore_reset_delay)
pdev->d3cold_delay = 0;
obj = acpi_evaluate_dsm(handle, pci_acpi_dsm_uuid, 3,
FUNCTION_DELAY_DSM, NULL);
if (!obj)
return;
if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 5) {
elements = obj->package.elements;
if (elements[0].type == ACPI_TYPE_INTEGER) {
value = (int)elements[0].integer.value / 1000;
if (value < PCI_PM_D3COLD_WAIT)
pdev->d3cold_delay = value;
}
if (elements[3].type == ACPI_TYPE_INTEGER) {
value = (int)elements[3].integer.value / 1000;
if (value < PCI_PM_D3_WAIT)
pdev->d3_delay = value;
}
}
ACPI_FREE(obj);
}
static void pci_acpi_setup(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -569,6 +650,8 @@ static void pci_acpi_setup(struct device *dev)
if (!adev)
return;
pci_acpi_optimize_delay(pci_dev, adev->handle);
pci_acpi_add_pm_notifier(adev, pci_dev);
if (!adev->wakeup.flags.valid)
return;