mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 17:11:46 +00:00
pci-v4.13-changes
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJZYAFUAAoJEFmIoMA60/r8cFQP/A4fpdjhd42WRNQXGTpZieop i40lBQtGdBn/UY97U6BoutcS1ygDi9OiSzg+IR6I90iMgidqyUHFhe4hGWgVHD2g Tg0KLzd+lKKfQ6Gqt1P6t4dLGLvyEj5NUbCeFE4XYODAUkkiBaOndax6DK1GvU54 Vjuj63rHtMKFR/tG/4iFTigObqyI8QE6O9JVxwuvIyEX6RXKbJe+wkulv5taSnWt Ne94950i10MrELtNreVdi8UbCbXiqjg0r5sKI/WTJ7Bc7WsC7X5PhWlhcNrbHyBT Ivhoypkui3Ky8gvwWqL0KBG+cRp8prBXAdabrD9wRbz0TKnfGI6pQzseCGRnkE6T mhlSJpsSNIHaejoCjk93yPn5oRiTNtPMdVhMpEQL9V/crVRGRRmbd7v2TYvpMHVR JaPZ8bv+C2aBTY8uL3/v/rgrjsMKOYFeaxeNklpErxrknsbgb6BgubmeZXDvTBVv YUIbAkvveonUKisv+kbD8L7tp1+jdbRUT0AikS0NVgAJQhfArOmBcDpTL9YC51vE feFhkVx4A32vvOm7Zcg9A7IMXNjeSfccKGw3dJOAvzgDODuJiaCG6S0o7B5Yngze axMi87ixGT4QM98z/I4MC8E9rDrJdIitlpvb6ZBgiLzoO3kmvsIZZKt8UxWqf5r8 w3U2HoyKH13Qbkn1xkum =mkyb -----END PGP SIGNATURE----- Merge tag 'pci-v4.13-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI updates from Bjorn Helgaas: - add sysfs max_link_speed/width, current_link_speed/width (Wong Vee Khee) - make host bridge IRQ mapping much more generic (Matthew Minter, Lorenzo Pieralisi) - convert most drivers to pci_scan_root_bus_bridge() (Lorenzo Pieralisi) - mutex sriov_configure() (Jakub Kicinski) - mutex pci_error_handlers callbacks (Christoph Hellwig) - split ->reset_notify() into ->reset_prepare()/reset_done() (Christoph Hellwig) - support multiple PCIe portdrv interrupts for MSI as well as MSI-X (Gabriele Paoloni) - allocate MSI/MSI-X vector for Downstream Port Containment (Gabriele Paoloni) - fix MSI IRQ affinity pre/post/min_vecs issue (Michael Hernandez) - test INTx masking during enumeration, not at run-time (Piotr Gregor) - avoid using device_may_wakeup() for runtime PM (Rafael J. Wysocki) - restore the status of PCI devices across hibernation (Chen Yu) - keep parent resources that start at 0x0 (Ard Biesheuvel) - enable ECRC only if device supports it (Bjorn Helgaas) - restore PRI and PASID state after Function-Level Reset (CQ Tang) - skip DPC event if device is not present (Keith Busch) - check domain when matching SMBIOS info (Sujith Pandel) - mark Intel XXV710 NIC INTx masking as broken (Alex Williamson) - avoid AMD SB7xx EHCI USB wakeup defect (Kai-Heng Feng) - work around long-standing Macbook Pro poweroff issue (Bjorn Helgaas) - add Switchtec "running" status flag (Logan Gunthorpe) - fix dra7xx incorrect RW1C IRQ register usage (Arvind Yadav) - modify xilinx-nwl IRQ chip for legacy interrupts (Bharat Kumar Gogada) - move VMD SRCU cleanup after bus, child device removal (Jon Derrick) - add Faraday clock handling (Linus Walleij) - configure Rockchip MPS and reorganize (Shawn Lin) - limit Qualcomm TLP size to 2K (hardware issue) (Srinivas Kandagatla) - support Tegra MSI 64-bit addressing (Thierry Reding) - use Rockchip normal (not privileged) register bank (Shawn Lin) - add HiSilicon Kirin SoC PCIe controller driver (Xiaowei Song) - add Sigma Designs Tango SMP8759 PCIe controller driver (Marc Gonzalez) - add MediaTek PCIe host controller support (Ryder Lee) - add Qualcomm IPQ4019 support (John Crispin) - add HyperV vPCI protocol v1.2 support (Jork Loeser) - add i.MX6 regulator support (Quentin Schulz) * tag 'pci-v4.13-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (113 commits) PCI: tango: Add Sigma Designs Tango SMP8759 PCIe host bridge support PCI: Add DT binding for Sigma Designs Tango PCIe controller PCI: rockchip: Use normal register bank for config accessors dt-bindings: PCI: Add documentation for MediaTek PCIe PCI: Remove __pci_dev_reset() and pci_dev_reset() PCI: Split ->reset_notify() method into ->reset_prepare() and ->reset_done() PCI: xilinx: Make of_device_ids const PCI: xilinx-nwl: Modify IRQ chip for legacy interrupts PCI: vmd: Move SRCU cleanup after bus, child device removal PCI: vmd: Correct comment: VMD domains start at 0x10000, not 0x1000 PCI: versatile: Add local struct device pointers PCI: tegra: Do not allocate MSI target memory PCI: tegra: Support MSI 64-bit addressing PCI: rockchip: Use local struct device pointer consistently PCI: rockchip: Check for clk_prepare_enable() errors during resume MAINTAINERS: Remove Wenrui Li as Rockchip PCIe driver maintainer PCI: rockchip: Configure RC's MPS setting PCI: rockchip: Reconfigure configuration space header type PCI: rockchip: Split out rockchip_pcie_cfg_configuration_accesses() PCI: rockchip: Move configuration accesses into rockchip_pcie_cfg_atu() ...
This commit is contained in:
commit
f263fbb8d6
90 changed files with 3789 additions and 825 deletions
|
@ -28,6 +28,7 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pci_hotplug.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/pci-ats.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/dma.h>
|
||||
#include <linux/aer.h>
|
||||
|
@ -455,7 +456,7 @@ struct resource *pci_find_parent_resource(const struct pci_dev *dev,
|
|||
pci_bus_for_each_resource(bus, r, i) {
|
||||
if (!r)
|
||||
continue;
|
||||
if (res->start && resource_contains(r, res)) {
|
||||
if (resource_contains(r, res)) {
|
||||
|
||||
/*
|
||||
* If the window is prefetchable but the BAR is
|
||||
|
@ -1166,6 +1167,8 @@ void pci_restore_state(struct pci_dev *dev)
|
|||
|
||||
/* PCI Express register must be restored first */
|
||||
pci_restore_pcie_state(dev);
|
||||
pci_restore_pasid_state(dev);
|
||||
pci_restore_pri_state(dev);
|
||||
pci_restore_ats_state(dev);
|
||||
pci_restore_vc_state(dev);
|
||||
|
||||
|
@ -1966,12 +1969,13 @@ EXPORT_SYMBOL(pci_wake_from_d3);
|
|||
/**
|
||||
* pci_target_state - find an appropriate low power state for a given PCI dev
|
||||
* @dev: PCI device
|
||||
* @wakeup: Whether or not wakeup functionality will be enabled for the device.
|
||||
*
|
||||
* Use underlying platform code to find a supported low power state for @dev.
|
||||
* If the platform can't manage @dev, return the deepest state from which it
|
||||
* can generate wake events, based on any available PME info.
|
||||
*/
|
||||
static pci_power_t pci_target_state(struct pci_dev *dev)
|
||||
static pci_power_t pci_target_state(struct pci_dev *dev, bool wakeup)
|
||||
{
|
||||
pci_power_t target_state = PCI_D3hot;
|
||||
|
||||
|
@ -2008,7 +2012,7 @@ static pci_power_t pci_target_state(struct pci_dev *dev)
|
|||
if (dev->current_state == PCI_D3cold)
|
||||
target_state = PCI_D3cold;
|
||||
|
||||
if (device_may_wakeup(&dev->dev)) {
|
||||
if (wakeup) {
|
||||
/*
|
||||
* Find the deepest state from which the device can generate
|
||||
* wake-up events, make it the target state and enable device
|
||||
|
@ -2034,13 +2038,14 @@ static pci_power_t pci_target_state(struct pci_dev *dev)
|
|||
*/
|
||||
int pci_prepare_to_sleep(struct pci_dev *dev)
|
||||
{
|
||||
pci_power_t target_state = pci_target_state(dev);
|
||||
bool wakeup = device_may_wakeup(&dev->dev);
|
||||
pci_power_t target_state = pci_target_state(dev, wakeup);
|
||||
int error;
|
||||
|
||||
if (target_state == PCI_POWER_ERROR)
|
||||
return -EIO;
|
||||
|
||||
pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev));
|
||||
pci_enable_wake(dev, target_state, wakeup);
|
||||
|
||||
error = pci_set_power_state(dev, target_state);
|
||||
|
||||
|
@ -2073,9 +2078,10 @@ EXPORT_SYMBOL(pci_back_from_sleep);
|
|||
*/
|
||||
int pci_finish_runtime_suspend(struct pci_dev *dev)
|
||||
{
|
||||
pci_power_t target_state = pci_target_state(dev);
|
||||
pci_power_t target_state;
|
||||
int error;
|
||||
|
||||
target_state = pci_target_state(dev, device_can_wakeup(&dev->dev));
|
||||
if (target_state == PCI_POWER_ERROR)
|
||||
return -EIO;
|
||||
|
||||
|
@ -2111,8 +2117,8 @@ bool pci_dev_run_wake(struct pci_dev *dev)
|
|||
if (!dev->pme_support)
|
||||
return false;
|
||||
|
||||
/* PME-capable in principle, but not from the intended sleep state */
|
||||
if (!pci_pme_capable(dev, pci_target_state(dev)))
|
||||
/* PME-capable in principle, but not from the target power state */
|
||||
if (!pci_pme_capable(dev, pci_target_state(dev, false)))
|
||||
return false;
|
||||
|
||||
while (bus->parent) {
|
||||
|
@ -2147,9 +2153,10 @@ EXPORT_SYMBOL_GPL(pci_dev_run_wake);
|
|||
bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
|
||||
{
|
||||
struct device *dev = &pci_dev->dev;
|
||||
bool wakeup = device_may_wakeup(dev);
|
||||
|
||||
if (!pm_runtime_suspended(dev)
|
||||
|| pci_target_state(pci_dev) != pci_dev->current_state
|
||||
|| pci_target_state(pci_dev, wakeup) != pci_dev->current_state
|
||||
|| platform_pci_need_resume(pci_dev)
|
||||
|| (pci_dev->dev_flags & PCI_DEV_FLAGS_NEEDS_RESUME))
|
||||
return false;
|
||||
|
@ -2167,7 +2174,7 @@ bool pci_dev_keep_suspended(struct pci_dev *pci_dev)
|
|||
spin_lock_irq(&dev->power.lock);
|
||||
|
||||
if (pm_runtime_suspended(dev) && pci_dev->current_state < PCI_D3cold &&
|
||||
!device_may_wakeup(dev))
|
||||
!wakeup)
|
||||
__pci_pme_active(pci_dev, false);
|
||||
|
||||
spin_unlock_irq(&dev->power.lock);
|
||||
|
@ -3715,46 +3722,6 @@ void pci_intx(struct pci_dev *pdev, int enable)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pci_intx);
|
||||
|
||||
/**
|
||||
* pci_intx_mask_supported - probe for INTx masking support
|
||||
* @dev: the PCI device to operate on
|
||||
*
|
||||
* Check if the device dev support INTx masking via the config space
|
||||
* command word.
|
||||
*/
|
||||
bool pci_intx_mask_supported(struct pci_dev *dev)
|
||||
{
|
||||
bool mask_supported = false;
|
||||
u16 orig, new;
|
||||
|
||||
if (dev->broken_intx_masking)
|
||||
return false;
|
||||
|
||||
pci_cfg_access_lock(dev);
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &orig);
|
||||
pci_write_config_word(dev, PCI_COMMAND,
|
||||
orig ^ PCI_COMMAND_INTX_DISABLE);
|
||||
pci_read_config_word(dev, PCI_COMMAND, &new);
|
||||
|
||||
/*
|
||||
* There's no way to protect against hardware bugs or detect them
|
||||
* reliably, but as long as we know what the value should be, let's
|
||||
* go ahead and check it.
|
||||
*/
|
||||
if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
|
||||
dev_err(&dev->dev, "Command register changed from 0x%x to 0x%x: driver or hardware bug?\n",
|
||||
orig, new);
|
||||
} else if ((new ^ orig) & PCI_COMMAND_INTX_DISABLE) {
|
||||
mask_supported = true;
|
||||
pci_write_config_word(dev, PCI_COMMAND, orig);
|
||||
}
|
||||
|
||||
pci_cfg_access_unlock(dev);
|
||||
return mask_supported;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_intx_mask_supported);
|
||||
|
||||
static bool pci_check_and_set_intx_mask(struct pci_dev *dev, bool mask)
|
||||
{
|
||||
struct pci_bus *bus = dev->bus;
|
||||
|
@ -3805,7 +3772,7 @@ done:
|
|||
* @dev: the PCI device to operate on
|
||||
*
|
||||
* Check if the device dev has its INTx line asserted, mask it and
|
||||
* return true in that case. False is returned if not interrupt was
|
||||
* return true in that case. False is returned if no interrupt was
|
||||
* pending.
|
||||
*/
|
||||
bool pci_check_and_mask_intx(struct pci_dev *dev)
|
||||
|
@ -4075,40 +4042,6 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe)
|
|||
return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
|
||||
}
|
||||
|
||||
static int __pci_dev_reset(struct pci_dev *dev, int probe)
|
||||
{
|
||||
int rc;
|
||||
|
||||
might_sleep();
|
||||
|
||||
rc = pci_dev_specific_reset(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
if (pcie_has_flr(dev)) {
|
||||
if (!probe)
|
||||
pcie_flr(dev);
|
||||
rc = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = pci_af_flr(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
rc = pci_pm_reset(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
rc = pci_dev_reset_slot_function(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
rc = pci_parent_bus_reset(dev, probe);
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void pci_dev_lock(struct pci_dev *dev)
|
||||
{
|
||||
pci_cfg_access_lock(dev);
|
||||
|
@ -4134,26 +4067,18 @@ static void pci_dev_unlock(struct pci_dev *dev)
|
|||
pci_cfg_access_unlock(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_reset_notify - notify device driver of reset
|
||||
* @dev: device to be notified of reset
|
||||
* @prepare: 'true' if device is about to be reset; 'false' if reset attempt
|
||||
* completed
|
||||
*
|
||||
* Must be called prior to device access being disabled and after device
|
||||
* access is restored.
|
||||
*/
|
||||
static void pci_reset_notify(struct pci_dev *dev, bool prepare)
|
||||
static void pci_dev_save_and_disable(struct pci_dev *dev)
|
||||
{
|
||||
const struct pci_error_handlers *err_handler =
|
||||
dev->driver ? dev->driver->err_handler : NULL;
|
||||
if (err_handler && err_handler->reset_notify)
|
||||
err_handler->reset_notify(dev, prepare);
|
||||
}
|
||||
|
||||
static void pci_dev_save_and_disable(struct pci_dev *dev)
|
||||
{
|
||||
pci_reset_notify(dev, true);
|
||||
/*
|
||||
* dev->driver->err_handler->reset_prepare() is protected against
|
||||
* races with ->remove() by the device lock, which must be held by
|
||||
* the caller.
|
||||
*/
|
||||
if (err_handler && err_handler->reset_prepare)
|
||||
err_handler->reset_prepare(dev);
|
||||
|
||||
/*
|
||||
* Wake-up device prior to save. PM registers default to D0 after
|
||||
|
@ -4175,23 +4100,18 @@ static void pci_dev_save_and_disable(struct pci_dev *dev)
|
|||
|
||||
static void pci_dev_restore(struct pci_dev *dev)
|
||||
{
|
||||
const struct pci_error_handlers *err_handler =
|
||||
dev->driver ? dev->driver->err_handler : NULL;
|
||||
|
||||
pci_restore_state(dev);
|
||||
pci_reset_notify(dev, false);
|
||||
}
|
||||
|
||||
static int pci_dev_reset(struct pci_dev *dev, int probe)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!probe)
|
||||
pci_dev_lock(dev);
|
||||
|
||||
rc = __pci_dev_reset(dev, probe);
|
||||
|
||||
if (!probe)
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
return rc;
|
||||
/*
|
||||
* dev->driver->err_handler->reset_done() is protected against
|
||||
* races with ->remove() by the device lock, which must be held by
|
||||
* the caller.
|
||||
*/
|
||||
if (err_handler && err_handler->reset_done)
|
||||
err_handler->reset_done(dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4213,7 +4133,13 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
|
|||
*/
|
||||
int __pci_reset_function(struct pci_dev *dev)
|
||||
{
|
||||
return pci_dev_reset(dev, 0);
|
||||
int ret;
|
||||
|
||||
pci_dev_lock(dev);
|
||||
ret = __pci_reset_function_locked(dev);
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__pci_reset_function);
|
||||
|
||||
|
@ -4238,7 +4164,27 @@ EXPORT_SYMBOL_GPL(__pci_reset_function);
|
|||
*/
|
||||
int __pci_reset_function_locked(struct pci_dev *dev)
|
||||
{
|
||||
return __pci_dev_reset(dev, 0);
|
||||
int rc;
|
||||
|
||||
might_sleep();
|
||||
|
||||
rc = pci_dev_specific_reset(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
if (pcie_has_flr(dev)) {
|
||||
pcie_flr(dev);
|
||||
return 0;
|
||||
}
|
||||
rc = pci_af_flr(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_pm_reset(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_dev_reset_slot_function(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
return pci_parent_bus_reset(dev, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
|
||||
|
||||
|
@ -4255,7 +4201,26 @@ EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
|
|||
*/
|
||||
int pci_probe_reset_function(struct pci_dev *dev)
|
||||
{
|
||||
return pci_dev_reset(dev, 1);
|
||||
int rc;
|
||||
|
||||
might_sleep();
|
||||
|
||||
rc = pci_dev_specific_reset(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
if (pcie_has_flr(dev))
|
||||
return 0;
|
||||
rc = pci_af_flr(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_pm_reset(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_dev_reset_slot_function(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
|
||||
return pci_parent_bus_reset(dev, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4278,15 +4243,17 @@ int pci_reset_function(struct pci_dev *dev)
|
|||
{
|
||||
int rc;
|
||||
|
||||
rc = pci_dev_reset(dev, 1);
|
||||
rc = pci_probe_reset_function(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
pci_dev_lock(dev);
|
||||
pci_dev_save_and_disable(dev);
|
||||
|
||||
rc = pci_dev_reset(dev, 0);
|
||||
rc = __pci_reset_function_locked(dev);
|
||||
|
||||
pci_dev_restore(dev);
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -4302,20 +4269,18 @@ int pci_try_reset_function(struct pci_dev *dev)
|
|||
{
|
||||
int rc;
|
||||
|
||||
rc = pci_dev_reset(dev, 1);
|
||||
rc = pci_probe_reset_function(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
pci_dev_save_and_disable(dev);
|
||||
if (!pci_dev_trylock(dev))
|
||||
return -EAGAIN;
|
||||
|
||||
if (pci_dev_trylock(dev)) {
|
||||
rc = __pci_dev_reset(dev, 0);
|
||||
pci_dev_unlock(dev);
|
||||
} else
|
||||
rc = -EAGAIN;
|
||||
pci_dev_save_and_disable(dev);
|
||||
rc = __pci_reset_function_locked(dev);
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
pci_dev_restore(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_try_reset_function);
|
||||
|
@ -4465,7 +4430,9 @@ static void pci_bus_save_and_disable(struct pci_bus *bus)
|
|||
struct pci_dev *dev;
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pci_dev_lock(dev);
|
||||
pci_dev_save_and_disable(dev);
|
||||
pci_dev_unlock(dev);
|
||||
if (dev->subordinate)
|
||||
pci_bus_save_and_disable(dev->subordinate);
|
||||
}
|
||||
|
@ -4480,7 +4447,9 @@ static void pci_bus_restore(struct pci_bus *bus)
|
|||
struct pci_dev *dev;
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pci_dev_lock(dev);
|
||||
pci_dev_restore(dev);
|
||||
pci_dev_unlock(dev);
|
||||
if (dev->subordinate)
|
||||
pci_bus_restore(dev->subordinate);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue