diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 06:18:18 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 06:18:18 +0100 |
commit | 556f12f602ac0a18a82ca83e9f8e8547688fc633 (patch) | |
tree | d4051f6dd57968c8e8e660ad117c5bedc2aa7e8e /drivers/pci/pci.c | |
parent | Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux (diff) | |
parent | Merge branch 'pci/yinghai-root-bus-hotplug' into next (diff) | |
download | linux-556f12f602ac0a18a82ca83e9f8e8547688fc633.tar.xz linux-556f12f602ac0a18a82ca83e9f8e8547688fc633.zip |
Merge tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Host bridge hotplug
- Major overhaul of ACPI host bridge add/start (Rafael Wysocki, Yinghai Lu)
- Major overhaul of PCI/ACPI binding (Rafael Wysocki, Yinghai Lu)
- Split out ACPI host bridge and ACPI PCI device hotplug (Yinghai Lu)
- Stop caching _PRT and make independent of bus numbers (Yinghai Lu)
PCI device hotplug
- Clean up cpqphp dead code (Sasha Levin)
- Disable ARI unless device and upstream bridge support it (Yijing Wang)
- Initialize all hot-added devices (not functions 0-7) (Yijing Wang)
Power management
- Don't touch ASPM if disabled (Joe Lawrence)
- Fix ASPM link state management (Myron Stowe)
Miscellaneous
- Fix PCI_EXP_FLAGS accessor (Alex Williamson)
- Disable Bus Master in pci_device_shutdown (Konstantin Khlebnikov)
- Document hotplug resource and MPS parameters (Yijing Wang)
- Add accessor for PCIe capabilities (Myron Stowe)
- Drop pciehp suspend/resume messages (Paul Bolle)
- Make pci_slot built-in only (not a module) (Jiang Liu)
- Remove unused PCI/ACPI bind ops (Jiang Liu)
- Removed used pci_root_bus (Bjorn Helgaas)"
* tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (51 commits)
PCI/ACPI: Don't cache _PRT, and don't associate them with bus numbers
PCI: Fix PCI Express Capability accessors for PCI_EXP_FLAGS
ACPI / PCI: Make pci_slot built-in only, not a module
PCI/PM: Clear state_saved during suspend
PCI: Use atomic_inc_return() rather than atomic_add_return()
PCI: Catch attempts to disable already-disabled devices
PCI: Disable Bus Master unconditionally in pci_device_shutdown()
PCI: acpiphp: Remove dead code for PCI host bridge hotplug
PCI: acpiphp: Create companion ACPI devices before creating PCI devices
PCI: Remove unused "rc" in virtfn_add_bus()
PCI: pciehp: Drop suspend/resume ENTRY messages
PCI/ASPM: Don't touch ASPM if forcibly disabled
PCI/ASPM: Deallocate upstream link state even if device is not PCIe
PCI: Document MPS parameters pci=pcie_bus_safe, pci=pcie_bus_perf, etc
PCI: Document hpiosize= and hpmemsize= resource reservation parameters
PCI: Use PCI Express Capability accessor
PCI: Introduce accessor to retrieve PCIe Capabilities Register
PCI: Put pci_dev in device tree as early as possible
PCI: Skip attaching driver in device_add()
PCI: acpiphp: Keep driver loaded even if no slots found
...
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0c4f641b7be1..924e4665bd57 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1151,8 +1151,7 @@ int pci_reenable_device(struct pci_dev *dev) return 0; } -static int __pci_enable_device_flags(struct pci_dev *dev, - resource_size_t flags) +static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) { int err; int i, bars = 0; @@ -1169,7 +1168,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); } - if (atomic_add_return(1, &dev->enable_cnt) > 1) + if (atomic_inc_return(&dev->enable_cnt) > 1) return 0; /* already enabled */ /* only skip sriov related */ @@ -1196,7 +1195,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, */ int pci_enable_device_io(struct pci_dev *dev) { - return __pci_enable_device_flags(dev, IORESOURCE_IO); + return pci_enable_device_flags(dev, IORESOURCE_IO); } /** @@ -1209,7 +1208,7 @@ int pci_enable_device_io(struct pci_dev *dev) */ int pci_enable_device_mem(struct pci_dev *dev) { - return __pci_enable_device_flags(dev, IORESOURCE_MEM); + return pci_enable_device_flags(dev, IORESOURCE_MEM); } /** @@ -1225,7 +1224,7 @@ int pci_enable_device_mem(struct pci_dev *dev) */ int pci_enable_device(struct pci_dev *dev) { - return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); + return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); } /* @@ -1396,7 +1395,10 @@ pci_disable_device(struct pci_dev *dev) if (dr) dr->enabled = 0; - if (atomic_sub_return(1, &dev->enable_cnt) != 0) + dev_WARN_ONCE(&dev->dev, atomic_read(&dev->enable_cnt) <= 0, + "disabling already-disabled device"); + + if (atomic_dec_return(&dev->enable_cnt) != 0) return; do_pci_disable_device(dev); @@ -2043,10 +2045,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) } /** - * pci_enable_ari - enable ARI forwarding if hardware support it + * pci_configure_ari - enable or disable ARI forwarding * @dev: the PCI device + * + * If @dev and its upstream bridge both support ARI, enable ARI in the + * bridge. Otherwise, disable ARI in the bridge. */ -void pci_enable_ari(struct pci_dev *dev) +void pci_configure_ari(struct pci_dev *dev) { u32 cap; struct pci_dev *bridge; @@ -2054,9 +2059,6 @@ void pci_enable_ari(struct pci_dev *dev) if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) return; - if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) - return; - bridge = dev->bus->self; if (!bridge) return; @@ -2065,8 +2067,15 @@ void pci_enable_ari(struct pci_dev *dev) if (!(cap & PCI_EXP_DEVCAP2_ARI)) return; - pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); - bridge->ari_enabled = 1; + if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) { + pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_ARI); + bridge->ari_enabled = 1; + } else { + pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_ARI); + bridge->ari_enabled = 0; + } } /** @@ -3742,18 +3751,6 @@ resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) return align; } -/** - * pci_is_reassigndev - check if specified PCI is target device to reassign - * @dev: the PCI device to check - * - * RETURNS: non-zero for PCI device is a target device to reassign, - * or zero is not. - */ -int pci_is_reassigndev(struct pci_dev *dev) -{ - return (pci_specified_resource_alignment(dev) != 0); -} - /* * This function disables memory decoding and releases memory resources * of the device specified by kernel's boot parameter 'pci=resource_alignment='. @@ -3768,7 +3765,9 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) resource_size_t align, size; u16 command; - if (!pci_is_reassigndev(dev)) + /* check if specified PCI is target device to reassign */ + align = pci_specified_resource_alignment(dev); + if (!align) return; if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && @@ -3784,7 +3783,6 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) command &= ~PCI_COMMAND_MEMORY; pci_write_config_word(dev, PCI_COMMAND, command); - align = pci_specified_resource_alignment(dev); for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { r = &dev->resource[i]; if (!(r->flags & IORESOURCE_MEM)) |