projects/linux·commit c8d0267e

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

c8d0267e · Linus Torvalds <[email protected]> · 2016-08-02 17:12:29 -04:00

Pull PCI updates from Bjorn Helgaas:
 "Highlights:

   - ARM64 support for ACPI host bridges

   - new drivers for Axis ARTPEC-6 and Marvell Aardvark

   - new pci_alloc_irq_vectors() interface for MSI-X, MSI, legacy INTx

   - pci_resource_to_user() cleanup (more to come)

  Detailed summary:

  Enumeration:
   - Move ecam.h to linux/include/pci-ecam.h (Jayachandran C)
   - Add parent device field to ECAM struct pci_config_window (Jayachandran C)
   - Add generic MCFG table handling (Tomasz Nowicki)
   - Refactor pci_bus_assign_domain_nr() for CONFIG_PCI_DOMAINS_GENERIC (Tomasz Nowicki)
   - Factor DT-specific pci_bus_find_domain_nr() code out (Tomasz Nowicki)

  Resource management:
   - Add devm_request_pci_bus_resources() (Bjorn Helgaas)
   - Unify pci_resource_to_user() declarations (Bjorn Helgaas)
   - Implement pci_resource_to_user() with pcibios_resource_to_bus() (microblaze, powerpc, sparc) (Bjorn Helgaas)
   - Request host bridge window resources (designware, iproc, rcar, xgene, xilinx, xilinx-nwl) (Bjorn Helgaas)
   - Make PCI I/O space optional on ARM32 (Bjorn Helgaas)
   - Ignore write combining when mapping I/O port space (Bjorn Helgaas)
   - Claim bus resources on MIPS PCI_PROBE_ONLY set-ups (Bjorn Helgaas)
   - Remove unicore32 pci=firmware command line parameter handling (Bjorn Helgaas)
   - Support I/O resources when parsing host bridge resources (Jayachandran C)
   - Add helpers to request/release memory and I/O regions (Johannes Thumshirn)
   - Use pci_(request|release)_mem_regions (NVMe, lpfc, GenWQE, ethernet/intel, alx) (Johannes Thumshirn)
   - Extend pci=resource_alignment to specify device/vendor IDs (Koehrer Mathias (ETAS/ESW5))
   - Add generic pci_bus_claim_resources() (Lorenzo Pieralisi)
   - Claim bus resources on ARM32 PCI_PROBE_ONLY set-ups (Lorenzo Pieralisi)
   - Remove ARM32 and ARM64 arch-specific pcibios_enable_device() (Lorenzo Pieralisi)
   - Add pci_unmap_iospace() to unmap I/O resources (Sinan Kaya)
   - Remove powerpc __pci_mmap_set_pgprot() (Yinghai Lu)

  PCI device hotplug:
   - Allow additional bus numbers for hotplug bridges (Keith Busch)
   - Ignore interrupts during D3cold (Lukas Wunner)

  Power management:
   - Enforce type casting for pci_power_t (Andy Shevchenko)
   - Don't clear d3cold_allowed for PCIe ports (Mika Westerberg)
   - Put PCIe ports into D3 during suspend (Mika Westerberg)
   - Power on bridges before scanning new devices (Mika Westerberg)
   - Runtime resume bridge before rescan (Mika Westerberg)
   - Add runtime PM support for PCIe ports (Mika Westerberg)
   - Remove redundant check of pcie_set_clkpm (Shawn Lin)

  Virtualization:
   - Add function 1 DMA alias quirk for Marvell 88SE9182 (Aaron Sierra)
   - Add DMA alias quirk for Adaptec 3805 (Alex Williamson)
   - Mark Atheros AR9485 and QCA9882 to avoid bus reset (Chris Blake)
   - Add ACS quirk for Solarflare SFC9220 (Edward Cree)

  MSI:
   - Fix PCI_MSI dependencies (Arnd Bergmann)
   - Add pci_msix_desc_addr() helper (Christoph Hellwig)
   - Switch msix_program_entries() to use pci_msix_desc_addr() (Christoph Hellwig)
   - Make the "entries" argument to pci_enable_msix() optional (Christoph Hellwig)
   - Provide sensible IRQ vector alloc/free routines (Christoph Hellwig)
   - Spread interrupt vectors in pci_alloc_irq_vectors() (Christoph Hellwig)

  Error Handling:
   - Bind DPC to Root Ports as well as Downstream Ports (Keith Busch)
   - Remove DPC tristate module option (Keith Busch)
   - Convert Downstream Port Containment driver to use devm_* functions (Mika Westerberg)

  Generic host bridge driver:
   - Select IRQ_DOMAIN (Arnd Bergmann)
   - Claim bus resources on PCI_PROBE_ONLY set-ups (Lorenzo Pieralisi)

  ACPI host bridge driver:
   - Add ARM64 acpi_pci_bus_find_domain_nr() (Tomasz Nowicki)
   - Add ARM64 ACPI support for legacy IRQs parsing and consolidation with DT code (Tomasz Nowicki)
   - Implement ARM64 AML accessors for PCI_Config region (Tomasz Nowicki)
   - Support ARM64 ACPI-based PCI host controller (Tomasz Nowicki)

  Altera host bridge driver:
   - Check link status before retrain link (Ley Foon Tan)
   - Poll for link up status after retraining the link (Ley Foon Tan)

  Axis ARTPEC-6 host bridge driver:
   - Add PCI_MSI_IRQ_DOMAIN dependency (Arnd Bergmann)
   - Add DT binding for Axis ARTPEC-6 PCIe controller (Niklas Cassel)
   - Add Axis ARTPEC-6 PCIe controller driver (Niklas Cassel)

  Intel VMD host bridge driver:
   - Use lock save/restore in interrupt enable path (Jon Derrick)
   - Select device dma ops to override (Keith Busch)
   - Initialize list item in IRQ disable (Keith Busch)
   - Use x86_vector_domain as parent domain (Keith Busch)
   - Separate MSI and MSI-X vector sharing (Keith Busch)

  Marvell Aardvark host bridge driver:
   - Add DT binding for the Aardvark PCIe controller (Thomas Petazzoni)
   - Add Aardvark PCI host controller driver (Thomas Petazzoni)
   - Add Aardvark PCIe support for Armada 3700 (Thomas Petazzoni)

  Microsoft Hyper-V host bridge driver:
   - Fix interrupt cleanup path (Cathy Avery)
   - Don't leak buffer in hv_pci_onchannelcallback() (Vitaly Kuznetsov)
   - Handle all pending messages in hv_pci_onchannelcallback() (Vitaly Kuznetsov)

  NVIDIA Tegra host bridge driver:
   - Program PADS_REFCLK_CFG* always, not just on legacy SoCs (Stephen Warren)
   - Program PADS_REFCLK_CFG* registers with per-SoC values (Stephen Warren)
   - Use lower-case hex consistently for register definitions (Thierry Reding)
   - Use generic pci_remap_iospace() rather than ARM32-specific one (Thierry Reding)
   - Stop setting pcibios_min_mem (Thierry Reding)

  Renesas R-Car host bridge driver:
   - Drop gen2 dummy I/O port region (Bjorn Helgaas)

  TI DRA7xx host bridge driver:
   - Fix return value in case of error (Christophe JAILLET)

  Xilinx AXI host bridge driver:
   - Fix return value in case of error (Christophe JAILLET)

  Miscellaneous:
   - Make bus_attr_resource_alignment static (Ben Dooks)
   - Include <asm/dma.h> for isa_dma_bridge_buggy (Ben Dooks)
   - MAINTAINERS: Add file patterns for PCI device tree bindings (Geert Uytterhoeven)
   - Make host bridge drivers explicitly non-modular (Paul Gortmaker)"

* tag 'pci-v4.8-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (125 commits)
  PCI: xgene: Make explicitly non-modular
  PCI: thunder-pem: Make explicitly non-modular
  PCI: thunder-ecam: Make explicitly non-modular
  PCI: tegra: Make explicitly non-modular
  PCI: rcar-gen2: Make explicitly non-modular
  PCI: rcar: Make explicitly non-modular
  PCI: mvebu: Make explicitly non-modular
  PCI: layerscape: Make explicitly non-modular
  PCI: keystone: Make explicitly non-modular
  PCI: hisi: Make explicitly non-modular
  PCI: generic: Make explicitly non-modular
  PCI: designware-plat: Make it explicitly non-modular
  PCI: artpec6: Make explicitly non-modular
  PCI: armada8k: Make explicitly non-modular
  PCI: artpec: Add PCI_MSI_IRQ_DOMAIN dependency
  PCI: Add ACS quirk for Solarflare SFC9220
  arm64: dts: marvell: Add Aardvark PCIe support for Armada 3700
  PCI: aardvark: Add Aardvark PCI host controller driver
  dt-bindings: add DT binding for the Aardvark PCIe controller
  PCI: tegra: Program PADS_REFCLK_CFG* registers with per-SoC values
  ...
Commit
c8d0267efdb4ab16cd0ed6e0218e8c164006de48
Parents
affe8a2a · 9454c238

Merge commit. Changes below are compared with the first parent: affe8a2a.

Changes

87 files changed · +3014 −1176

FileStatusAddDelContent
Documentation/PCI/MSI-HOWTO.txtmodified+79−390View file
Documentation/devicetree/bindings/pci/aardvark-pci.txtadded+56−0View file
Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txtadded+46−0View file
Documentation/kernel-parameters.txtmodified+9−0View file
MAINTAINERSmodified+17−0View file
arch/arm/Kconfigmodified+1−1View file
arch/arm/include/asm/mach/pci.hmodified+1−0View file
arch/arm/kernel/bios32.cmodified+20−25View file
arch/arm64/Kconfigmodified+4−2View file
arch/arm64/boot/dts/marvell/armada-3720-db.dtsmodified+5−0View file
arch/arm64/boot/dts/marvell/armada-37xx.dtsimodified+25−0View file
arch/arm64/kernel/pci.cmodified+138−21View file
arch/microblaze/include/asm/pci.hmodified+0−3View file
arch/microblaze/pci/pci-common.cmodified+15−58View file
arch/mips/include/asm/pci.hmodified+0−10View file
arch/mips/pci/pci.cmodified+18−1View file
arch/powerpc/include/asm/pci.hmodified+0−3View file
arch/powerpc/kernel/pci-common.cmodified+18−61View file
arch/sparc/include/asm/pci_64.hmodified+0−3View file
arch/sparc/kernel/pci.cmodified+11−9View file
arch/unicore32/kernel/pci.cmodified+2−7View file
arch/x86/pci/common.cmodified+1−1View file
arch/x86/pci/vmd.cmodified+25−16View file
drivers/acpi/Kconfigmodified+3−0View file
drivers/acpi/Makefilemodified+1−0View file
drivers/acpi/pci_mcfg.cadded+92−0View file
drivers/acpi/pci_root.cmodified+35−0View file
drivers/irqchip/Kconfigmodified+8−10View file
drivers/misc/genwqe/card_base.cmodified+7−11View file
drivers/net/ethernet/atheros/alx/main.cmodified+5−7View file
drivers/net/ethernet/intel/e1000e/netdev.cmodified+2−4View file
drivers/net/ethernet/intel/fm10k/fm10k_pci.cmodified+3−8View file
drivers/net/ethernet/intel/i40e/i40e_main.cmodified+3−6View file
drivers/net/ethernet/intel/igb/igb_main.cmodified+3−7View file
drivers/net/ethernet/intel/ixgbe/ixgbe_main.cmodified+3−6View file
drivers/nvme/host/pci.cmodified+3−12View file
drivers/pci/Kconfigmodified+1−1View file
drivers/pci/bus.cmodified+30−1View file
drivers/pci/ecam.cmodified+3−3View file
drivers/pci/host/Kconfigmodified+39−10View file
drivers/pci/host/Makefilemodified+2−0View file
drivers/pci/host/pci-aardvark.cadded+1001−0View file
drivers/pci/host/pci-dra7xx.cmodified+2−2View file
drivers/pci/host/pci-host-common.cmodified+20−24View file
drivers/pci/host/pci-host-generic.cmodified+3−10View file
drivers/pci/host/pci-hyperv.cmodified+17−13View file
drivers/pci/host/pci-keystone.cmodified+2−8View file
drivers/pci/host/pci-layerscape.cmodified+2−8View file
drivers/pci/host/pci-mvebu.cmodified+11−17View file
drivers/pci/host/pci-rcar-gen2.cmodified+8−19View file
drivers/pci/host/pci-tegra.cmodified+33−66View file
drivers/pci/host/pci-thunder-ecam.cmodified+3−8View file
drivers/pci/host/pci-thunder-pem.cmodified+5−9View file
drivers/pci/host/pci-versatile.cmodified+10−19View file
drivers/pci/host/pci-xgene.cmodified+15−9View file
drivers/pci/host/pcie-altera.cmodified+42−41View file
drivers/pci/host/pcie-armada8k.cmodified+5−9View file
drivers/pci/host/pcie-artpec6.cadded+280−0View file
drivers/pci/host/pcie-designware-plat.cmodified+2−8View file
drivers/pci/host/pcie-designware.cmodified+22−12View file
drivers/pci/host/pcie-hisi.cmodified+2−11View file
drivers/pci/host/pcie-iproc.cmodified+4−0View file
drivers/pci/host/pcie-rcar.cmodified+12−32View file
drivers/pci/host/pcie-xilinx-nwl.cmodified+15−5View file
drivers/pci/host/pcie-xilinx.cmodified+16−6View file
drivers/pci/hotplug/acpiphp_glue.cmodified+4−0View file
drivers/pci/hotplug/pciehp_hpc.cmodified+4−0View file
drivers/pci/msi.cmodified+200−66View file
drivers/pci/pci-driver.cmodified+1−4View file
drivers/pci/pci-sysfs.cmodified+5−0View file
drivers/pci/pci.cmodified+259−22View file
drivers/pci/pci.hmodified+11−0View file
drivers/pci/pcie/Kconfigmodified+1−4View file
drivers/pci/pcie/aspm.cmodified+1−1View file
drivers/pci/pcie/pcie-dpc.cmodified+7−12View file
drivers/pci/pcie/portdrv_core.cmodified+3−0View file
drivers/pci/pcie/portdrv_pci.cmodified+49−3View file
drivers/pci/probe.cmodified+21−1View file
drivers/pci/proc.cmodified+6−3View file
drivers/pci/quirks.cmodified+13−4View file
drivers/pci/remove.cmodified+2−0View file
drivers/pci/setup-bus.cmodified+68−0View file
drivers/scsi/lpfc/lpfc_init.cmodified+4−11View file
drivers/usb/host/xhci-pci.cmodified+1−1View file
include/linux/pci-acpi.hmodified+2−0View file
drivers/pci/ecam.h → include/linux/pci-ecam.hrenamed+2−2View file
include/linux/pci.hmodified+84−9View file

Only the first 600 diff lines are shown. Download the complete patch.

Documentation/PCI/MSI-HOWTO.txt

View file
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt
index 1179850..c55df29 100644
--- a/Documentation/PCI/MSI-HOWTO.txt
+++ b/Documentation/PCI/MSI-HOWTO.txt
@@ -78,422 +78,111 @@ CONFIG_PCI_MSI option.
4.2 Using MSI
-Most of the hard work is done for the driver in the PCI layer. It simply
-has to request that the PCI layer set up the MSI capability for this
+Most of the hard work is done for the driver in the PCI layer. The driver
+simply has to request that the PCI layer set up the MSI capability for this
device.
-4.2.1 pci_enable_msi
+To automatically use MSI or MSI-X interrupt vectors, use the following
+function:
-int pci_enable_msi(struct pci_dev *dev)
+ int pci_alloc_irq_vectors(struct pci_dev *dev, unsigned int min_vecs,
+ unsigned int max_vecs, unsigned int flags);
-A successful call allocates ONE interrupt to the device, regardless
-of how many MSIs the device supports. The device is switched from
-pin-based interrupt mode to MSI mode. The dev->irq number is changed
-to a new number which represents the message signaled interrupt;
-consequently, this function should be called before the driver calls
-request_irq(), because an MSI is delivered via a vector that is
-different from the vector of a pin-based interrupt.
+which allocates up to max_vecs interrupt vectors for a PCI device. It
+returns the number of vectors allocated or a negative error. If the device
+has a requirements for a minimum number of vectors the driver can pass a
+min_vecs argument set to this limit, and the PCI core will return -ENOSPC
+if it can't meet the minimum number of vectors.
-4.2.2 pci_enable_msi_range
+The flags argument should normally be set to 0, but can be used to pass the
+PCI_IRQ_NOMSI and PCI_IRQ_NOMSIX flag in case a device claims to support
+MSI or MSI-X, but the support is broken, or to pass PCI_IRQ_NOLEGACY in
+case the device does not support legacy interrupt lines.
-int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
+By default this function will spread the interrupts around the available
+CPUs, but this feature can be disabled by passing the PCI_IRQ_NOAFFINITY
+flag.
-This function allows a device driver to request any number of MSI
-interrupts within specified range from 'minvec' to 'maxvec'.
+To get the Linux IRQ numbers passed to request_irq() and free_irq() and the
+vectors, use the following function:
-If this function returns a positive number it indicates the number of
-MSI interrupts that have been successfully allocated. In this case
-the device is switched from pin-based interrupt mode to MSI mode and
-updates dev->irq to be the lowest of the new interrupts assigned to it.
-The other interrupts assigned to the device are in the range dev->irq
-to dev->irq + returned value - 1. Device driver can use the returned
-number of successfully allocated MSI interrupts to further allocate
-and initialize device resources.
+ int pci_irq_vector(struct pci_dev *dev, unsigned int nr);
-If this function returns a negative number, it indicates an error and
-the driver should not attempt to request any more MSI interrupts for
-this device.
+Any allocated resources should be freed before removing the device using
+the following function:
-This function should be called before the driver calls request_irq(),
-because MSI interrupts are delivered via vectors that are different
-from the vector of a pin-based interrupt.
+ void pci_free_irq_vectors(struct pci_dev *dev);
-It is ideal if drivers can cope with a variable number of MSI interrupts;
-there are many reasons why the platform may not be able to provide the
-exact number that a driver asks for.
+If a device supports both MSI-X and MSI capabilities, this API will use the
+MSI-X facilities in preference to the MSI facilities. MSI-X supports any
+number of interrupts between 1 and 2048. In contrast, MSI is restricted to
+a maximum of 32 interrupts (and must be a power of two). In addition, the
+MSI interrupt vectors must be allocated consecutively, so the system might
+not be able to allocate as many vectors for MSI as it could for MSI-X. On
+some platforms, MSI interrupts must all be targeted at the same set of CPUs
+whereas MSI-X interrupts can all be targeted at different CPUs.
-There could be devices that can not operate with just any number of MSI
-interrupts within a range. See chapter 4.3.1.3 to get the idea how to
-handle such devices for MSI-X - the same logic applies to MSI.
+If a device supports neither MSI-X or MSI it will fall back to a single
+legacy IRQ vector.
-4.2.1.1 Maximum possible number of MSI interrupts
+The typical usage of MSI or MSI-X interrupts is to allocate as many vectors
+as possible, likely up to the limit supported by the device. If nvec is
+larger than the number supported by the device it will automatically be
+capped to the supported limit, so there is no need to query the number of
+vectors supported beforehand:
-The typical usage of MSI interrupts is to allocate as many vectors as
-possible, likely up to the limit returned by pci_msi_vec_count() function:
-
-static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec)
-{
- return pci_enable_msi_range(pdev, 1, nvec);
-}
-
-Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive,
-the value of 0 would be meaningless and could result in error.
-
-Some devices have a minimal limit on number of MSI interrupts.
-In this case the function could look like this:
-
-static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec)
-{
- return pci_enable_msi_range(pdev, FOO_DRIVER_MINIMUM_NVEC, nvec);
-}
-
-4.2.1.2 Exact number of MSI interrupts
+ nvec = pci_alloc_irq_vectors(pdev, 1, nvec, 0);
+ if (nvec < 0)
+ goto out_err;
If a driver is unable or unwilling to deal with a variable number of MSI
-interrupts it could request a particular number of interrupts by passing
-that number to pci_enable_msi_range() function as both 'minvec' and 'maxvec'
-parameters:
-
-static int foo_driver_enable_msi(struct pci_dev *pdev, int nvec)
-{
- return pci_enable_msi_range(pdev, nvec, nvec);
-}
-
-Note, unlike pci_enable_msi_exact() function, which could be also used to
-enable a particular number of MSI-X interrupts, pci_enable_msi_range()
-returns either a negative errno or 'nvec' (not negative errno or 0 - as
-pci_enable_msi_exact() does).
-
-4.2.1.3 Single MSI mode
-
-The most notorious example of the request type described above is
-enabling the single MSI mode for a device. It could be done by passing
-two 1s as 'minvec' and 'maxvec':
-
-static int foo_driver_enable_single_msi(struct pci_dev *pdev)
-{
- return pci_enable_msi_range(pdev, 1, 1);
-}
-
-Note, unlike pci_enable_msi() function, which could be also used to
-enable the single MSI mode, pci_enable_msi_range() returns either a
-negative errno or 1 (not negative errno or 0 - as pci_enable_msi()
-does).
-
-4.2.3 pci_enable_msi_exact
-
-int pci_enable_msi_exact(struct pci_dev *dev, int nvec)
-
-This variation on pci_enable_msi_range() call allows a device driver to
-request exactly 'nvec' MSIs.
-
-If this function returns a negative number, it indicates an error and
-the driver should not attempt to request any more MSI interrupts for
-this device.
-
-By contrast with pci_enable_msi_range() function, pci_enable_msi_exact()
-returns zero in case of success, which indicates MSI interrupts have been
-successfully allocated.
-
-4.2.4 pci_disable_msi
-
-void pci_disable_msi(struct pci_dev *dev)
-
-This function should be used to undo the effect of pci_enable_msi_range().
-Calling it restores dev->irq to the pin-based interrupt number and frees
-the previously allocated MSIs. The interrupts may subsequently be assigned
-to another device, so drivers should not cache the value of dev->irq.
-
-Before calling this function, a device driver must always call free_irq()
-on any interrupt for which it previously called request_irq().
-Failure to do so results in a BUG_ON(), leaving the device with
-MSI enabled and thus leaking its vector.
-
-4.2.4 pci_msi_vec_count
-
-int pci_msi_vec_count(struct pci_dev *dev)
-
-This function could be used to retrieve the number of MSI vectors the
-device requested (via the Multiple Message Capable register). The MSI
-specification only allows the returned value to be a power of two,
-up to a maximum of 2^5 (32).
-
-If this function returns a negative number, it indicates the device is
-not capable of sending MSIs.
-
-If this function returns a positive number, it indicates the maximum
-number of MSI interrupt vectors that could be allocated.
-
-4.3 Using MSI-X
-
-The MSI-X capability is much more flexible than the MSI capability.
-It supports up to 2048 interrupts, each of which can be controlled
-independently. To support this flexibility, drivers must use an array of
-`struct msix_entry':
-
-struct msix_entry {
- u16 vector; /* kernel uses to write alloc vector */
- u16 entry; /* driver uses to specify entry */
-};
-
-This allows for the device to use these interrupts in a sparse fashion;
-for example, it could use interrupts 3 and 1027 and yet allocate only a
-two-element array. The driver is expected to fill in the 'entry' value
-in each element of the array to indicate for which entries the kernel
-should assign interrupts; it is invalid to fill in two entries with the
-same number.
-
-4.3.1 pci_enable_msix_range
-
-int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
- int minvec, int maxvec)
-
-Calling this function asks the PCI subsystem to allocate any number of
-MSI-X interrupts within specified range from 'minvec' to 'maxvec'.
-The 'entries' argument is a pointer to an array of msix_entry structs
-which should be at least 'maxvec' entries in size.
-
-On success, the device is switched into MSI-X mode and the function
-returns the number of MSI-X interrupts that have been successfully
-allocated. In this case the 'vector' member in entries numbered from
-0 to the returned value - 1 is populated with the interrupt number;
-the driver should then call request_irq() for each 'vector' that it
-decides to use. The device driver is responsible for keeping track of the
-interrupts assigned to the MSI-X vectors so it can free them again later.
-Device driver can use the returned number of successfully allocated MSI-X
-interrupts to further allocate and initialize device resources.
-
-If this function returns a negative number, it indicates an error and
-the driver should not attempt to allocate any more MSI-X interrupts for
-this device.
-
-This function, in contrast with pci_enable_msi_range(), does not adjust
-dev->irq. The device will not generate interrupts for this interrupt
-number once MSI-X is enabled.
-
-Device drivers should normally call this function once per device
-during the initialization phase.
-
-It is ideal if drivers can cope with a variable number of MSI-X interrupts;
-there are many reasons why the platform may not be able to provide the
-exact number that a driver asks for.
-
-There could be devices that can not operate with just any number of MSI-X
-interrupts within a range. E.g., an network adapter might need let's say
-four vectors per each queue it provides. Therefore, a number of MSI-X
-interrupts allocated should be a multiple of four. In this case interface
-pci_enable_msix_range() can not be used alone to request MSI-X interrupts
-(since it can allocate any number within the range, without any notion of
-the multiple of four) and the device driver should master a custom logic
-to request the required number of MSI-X interrupts.
-
-4.3.1.1 Maximum possible number of MSI-X interrupts
-
-The typical usage of MSI-X interrupts is to allocate as many vectors as
-possible, likely up to the limit returned by pci_msix_vec_count() function:
-
-static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
-{
- return pci_enable_msix_range(adapter->pdev, adapter->msix_entries,
- 1, nvec);
-}
-
-Note the value of 'minvec' parameter is 1. As 'minvec' is inclusive,
-the value of 0 would be meaningless and could result in error.
-
-Some devices have a minimal limit on number of MSI-X interrupts.
-In this case the function could look like this:
-
-static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
-{
- return pci_enable_msix_range(adapter->pdev, adapter->msix_entries,
- FOO_DRIVER_MINIMUM_NVEC, nvec);
-}
-
-4.3.1.2 Exact number of MSI-X interrupts
-
-If a driver is unable or unwilling to deal with a variable number of MSI-X
-interrupts it could request a particular number of interrupts by passing
-that number to pci_enable_msix_range() function as both 'minvec' and 'maxvec'
-parameters:
-
-static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
-{
- return pci_enable_msix_range(adapter->pdev, adapter->msix_entries,
- nvec, nvec);
-}
-
-Note, unlike pci_enable_msix_exact() function, which could be also used to
-enable a particular number of MSI-X interrupts, pci_enable_msix_range()
-returns either a negative errno or 'nvec' (not negative errno or 0 - as
-pci_enable_msix_exact() does).
-
-4.3.1.3 Specific requirements to the number of MSI-X interrupts
-
-As noted above, there could be devices that can not operate with just any
-number of MSI-X interrupts within a range. E.g., let's assume a device that
-is only capable sending the number of MSI-X interrupts which is a power of
-two. A routine that enables MSI-X mode for such device might look like this:
-
-/*
- * Assume 'minvec' and 'maxvec' are non-zero
- */
-static int foo_driver_enable_msix(struct foo_adapter *adapter,
- int minvec, int maxvec)
-{
- int rc;
-
- minvec = roundup_pow_of_two(minvec);
- maxvec = rounddown_pow_of_two(maxvec);
-
- if (minvec > maxvec)
- return -ERANGE;
-
-retry:
- rc = pci_enable_msix_range(adapter->pdev, adapter->msix_entries,
- maxvec, maxvec);
- /*
- * -ENOSPC is the only error code allowed to be analyzed
- */
- if (rc == -ENOSPC) {
- if (maxvec == 1)
- return -ENOSPC;
-
- maxvec /= 2;
-
- if (minvec > maxvec)
- return -ENOSPC;
-
- goto retry;
- }
-
- return rc;
-}
-
-Note how pci_enable_msix_range() return value is analyzed for a fallback -
-any error code other than -ENOSPC indicates a fatal error and should not
-be retried.
-
-4.3.2 pci_enable_msix_exact
-
-int pci_enable_msix_exact(struct pci_dev *dev,
- struct msix_entry *entries, int nvec)
-
-This variation on pci_enable_msix_range() call allows a device driver to
-request exactly 'nvec' MSI-Xs.
-
-If this function returns a negative number, it indicates an error and
-the driver should not attempt to allocate any more MSI-X interrupts for
-this device.
-
-By contrast with pci_enable_msix_range() function, pci_enable_msix_exact()
-returns zero in case of success, which indicates MSI-X interrupts have been
-successfully allocated.
-
-Another version of a routine that enables MSI-X mode for a device with
-specific requirements described in chapter 4.3.1.3 might look like this:
-
-/*
- * Assume 'minvec' and 'maxvec' are non-zero
- */
-static int foo_driver_enable_msix(struct foo_adapter *adapter,
- int minvec, int maxvec)
-{
- int rc;
-
- minvec = roundup_pow_of_two(minvec);
- maxvec = rounddown_pow_of_two(maxvec);
-
- if (minvec > maxvec)
- return -ERANGE;
-
-retry:
- rc = pci_enable_msix_exact(adapter->pdev,
- adapter->msix_entries, maxvec);
-
- /*
- * -ENOSPC is the only error code allowed to be analyzed
- */
- if (rc == -ENOSPC) {
- if (maxvec == 1)
- return -ENOSPC;
-
- maxvec /= 2;
-
- if (minvec > maxvec)
- return -ENOSPC;
-
- goto retry;
- } else if (rc < 0) {
- return rc;
- }
-
- return maxvec;
-}
-
-4.3.3 pci_disable_msix
-
-void pci_disable_msix(struct pci_dev *dev)
-
-This function should be used to undo the effect of pci_enable_msix_range().
-It frees the previously allocated MSI-X interrupts. The interrupts may
-subsequently be assigned to another device, so drivers should not cache
-the value of the 'vector' elements over a call to pci_disable_msix().
-
-Before calling this function, a device driver must always call free_irq()
-on any interrupt for which it previously called request_irq().
-Failure to do so results in a BUG_ON(), leaving the device with
-MSI-X enabled and thus leaking its vector.
-
-4.3.3 The MSI-X Table
-
-The MSI-X capability specifies a BAR and offset within that BAR for the
-MSI-X Table. This address is mapped by the PCI subsystem, and should not
-be accessed directly by the device driver. If the driver wishes to
-mask or unmask an interrupt, it should call disable_irq() / enable_irq().
+interrupts it can request a particular number of interrupts by passing that
+number to pci_alloc_irq_vectors() function as both 'min_vecs' and
+'max_vecs' parameters:
-4.3.4 pci_msix_vec_count
+ ret = pci_alloc_irq_vectors(pdev, nvec, nvec, 0);
+ if (ret < 0)
+ goto out_err;
-int pci_msix_vec_count(struct pci_dev *dev)
+The most notorious example of the request type described above is enabling
+the single MSI mode for a device. It could be done by passing two 1s as
+'min_vecs' and 'max_vecs':
-This function could be used to retrieve number of entries in the device
-MSI-X table.
+ ret = pci_alloc_irq_vectors(pdev, 1, 1, 0);
+ if (ret < 0)
+ goto out_err;
-If this function returns a negative number, it indicates the device is
-not capable of sending MSI-Xs.
+Some devices might not support using legacy line interrupts, in which case
+the PCI_IRQ_NOLEGACY flag can be used to fail the request if the platform
+can't provide MSI or MSI-X interrupts:
-If this function returns a positive number, it indicates the maximum
-number of MSI-X interrupt vectors that could be allocated.
+ nvec = pci_alloc_irq_vectors(pdev, 1, nvec, PCI_IRQ_NOLEGACY);
+ if (nvec < 0)
+ goto out_err;
-4.4 Handling devices implementing both MSI and MSI-X capabilities
+4.3 Legacy APIs
-If a device implements both MSI and MSI-X capabilities, it can
-run in either MSI mode or MSI-X mode, but not both simultaneously.
-This is a requirement of the PCI spec, and it is enforced by the
-PCI layer. Calling pci_enable_msi_range() when MSI-X is already
-enabled or pci_enable_msix_range() when MSI is already enabled
-results in an error. If a device driver wishes to switch between MSI
-and MSI-X at runtime, it must first quiesce the device, then switch
-it back to pin-interrupt mode, before calling pci_enable_msi_range()
-or pci_enable_msix_range() and resuming operation. This is not expected
-to be a common operation but may be useful for debugging or testing
-during development.
+The following old APIs to enable and disable MSI or MSI-X interrupts should
+not be used in new code:
-4.5 Considerations when using MSIs
+ pci_enable_msi() /* deprecated */
+ pci_enable_msi_range() /* deprecated */
+ pci_enable_msi_exact() /* deprecated */
+ pci_disable_msi() /* deprecated */
+ pci_enable_msix_range() /* deprecated */
+ pci_enable_msix_exact() /* deprecated */
+ pci_disable_msix() /* deprecated */
-4.5.1 Choosing between MSI-X and MSI
+Additionally there are APIs to provide the number of supported MSI or MSI-X
+vectors: pci_msi_vec_count() and pci_msix_vec_count(). In general these
+should be avoided in favor of letting pci_alloc_irq_vectors() cap the
+number of vectors. If you have a legitimate special use case for the count
+of vectors we might have to revisit that decision and add a
+pci_nr_irq_vectors() helper that handles MSI and MSI-X transparently.
-If your device supports both MSI-X and MSI capabilities, you should use
-the MSI-X facilities in preference to the MSI facilities. As mentioned
-above, MSI-X supports any number of interrupts between 1 and 2048.
-In contrast, MSI is restricted to a maximum of 32 interrupts (and
-must be a power of two). In addition, the MSI interrupt vectors must
-be allocated consecutively, so the system might not be able to allocate
-as many vectors for MSI as it could for MSI-X. On some platforms, MSI
-interrupts must all be targeted at the same set of CPUs whereas MSI-X
-interrupts can all be targeted at different CPUs.
+4.4 Considerations when using MSIs
-4.5.2 Spinlocks
+4.4.1 Spinlocks
Most device drivers have a per-device spinlock which is taken in the
interrupt handler. With pin-based interrupts or a single MSI, it is not
@@ -505,7 +194,7 @@ acquire the spinlock. Such deadlocks can be avoided by using
spin_lock_irqsave() or spin_lock_irq() which disable local interrupts
and acquire the lock (see Documentation/DocBook/kernel-locking).
-4.6 How to tell whether MSI/MSI-X is enabled on a device
+4.5 How to tell whether MSI/MSI-X is enabled on a device
Using 'lspci -v' (as root) may show some devices with "MSI", "Message
Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities

Documentation/devicetree/bindings/pci/aardvark-pci.txt

View file
diff --git a/Documentation/devicetree/bindings/pci/aardvark-pci.txt b/Documentation/devicetree/bindings/pci/aardvark-pci.txt
new file mode 100644
index 0000000..bbcd9f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/aardvark-pci.txt
@@ -0,0 +1,56 @@
+Aardvark PCIe controller
+
+This PCIe controller is used on the Marvell Armada 3700 ARM64 SoC.
+
+The Device Tree node describing an Aardvark PCIe controller must
+contain the following properties:
+
+ - compatible: Should be "marvell,armada-3700-pcie"
+ - reg: range of registers for the PCIe controller
+ - interrupts: the interrupt line of the PCIe controller
+ - #address-cells: set to <3>
+ - #size-cells: set to <2>
+ - device_type: set to "pci"
+ - ranges: ranges for the PCI memory and I/O regions
+ - #interrupt-cells: set to <1>
+ - msi-controller: indicates that the PCIe controller can itself
+ handle MSI interrupts
+ - msi-parent: pointer to the MSI controller to be used
+ - interrupt-map-mask and interrupt-map: standard PCI properties to
+ define the mapping of the PCIe interface to interrupt numbers.
+ - bus-range: PCI bus numbers covered
+
+In addition, the Device Tree describing an Aardvark PCIe controller
+must include a sub-node that describes the legacy interrupt controller
+built into the PCIe controller. This sub-node must have the following
+properties:
+
+ - interrupt-controller
+ - #interrupt-cells: set to <1>
+
+Example:
+
+ pcie0: pcie@d0070000 {
+ compatible = "marvell,armada-3700-pcie";
+ device_type = "pci";
+ status = "disabled";
+ reg = <0 0xd0070000 0 0x20000>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x00 0xff>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <1>;
+ msi-controller;
+ msi-parent = <&pcie0>;
+ ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */
+ 0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/
+ interrupt-map-mask = <0 0 0 7>;
+ interrupt-map = <0 0 0 1 &pcie_intc 0>,
+ <0 0 0 2 &pcie_intc 1>,
+ <0 0 0 3 &pcie_intc 2>,
+ <0 0 0 4 &pcie_intc 3>;
+ pcie_intc: interrupt-controller {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };

Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt

View file
diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
new file mode 100644
index 0000000..330a45b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
@@ -0,0 +1,46 @@
+* Axis ARTPEC-6 PCIe interface
+
+This PCIe host controller is based on the Synopsys DesignWare PCIe IP
+and thus inherits all the common properties defined in designware-pcie.txt.
+
+Required properties:
+- compatible: "axis,artpec6-pcie", "snps,dw-pcie"
+- reg: base addresses and lengths of the PCIe controller (DBI),
+ the phy controller, and configuration address space.
+- reg-names: Must include the following entries:
+ - "dbi"
+ - "phy"
+ - "config"
+- interrupts: A list of interrupt outputs of the controller. Must contain an
+ entry for each entry in the interrupt-names property.
+- interrupt-names: Must include the following entries:
+ - "msi": The interrupt that is asserted when an MSI is received
+- axis,syscon-pcie: A phandle pointing to the ARTPEC-6 system controller,

This diff is incomplete. Download the complete patch.

Documentation/kernel-parameters.txt

View file

This diff is incomplete. Download the complete patch.

MAINTAINERS

View file

This diff is incomplete. Download the complete patch.

arch/arm/Kconfig

View file

This diff is incomplete. Download the complete patch.

arch/arm/include/asm/mach/pci.h

View file

This diff is incomplete. Download the complete patch.

arch/arm/kernel/bios32.c

View file

This diff is incomplete. Download the complete patch.

arch/arm64/Kconfig

View file

This diff is incomplete. Download the complete patch.

arch/arm64/boot/dts/marvell/armada-3720-db.dts

View file

This diff is incomplete. Download the complete patch.

arch/arm64/boot/dts/marvell/armada-37xx.dtsi

View file

This diff is incomplete. Download the complete patch.

arch/arm64/kernel/pci.c

View file

This diff is incomplete. Download the complete patch.

arch/microblaze/include/asm/pci.h

View file

This diff is incomplete. Download the complete patch.

arch/microblaze/pci/pci-common.c

View file

This diff is incomplete. Download the complete patch.

arch/mips/include/asm/pci.h

View file

This diff is incomplete. Download the complete patch.

arch/mips/pci/pci.c

View file

This diff is incomplete. Download the complete patch.

arch/powerpc/include/asm/pci.h

View file

This diff is incomplete. Download the complete patch.

arch/powerpc/kernel/pci-common.c

View file

This diff is incomplete. Download the complete patch.

arch/sparc/include/asm/pci_64.h

View file

This diff is incomplete. Download the complete patch.

arch/sparc/kernel/pci.c

View file

This diff is incomplete. Download the complete patch.

arch/unicore32/kernel/pci.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/pci/common.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/pci/vmd.c

View file

This diff is incomplete. Download the complete patch.

drivers/acpi/Kconfig

View file

This diff is incomplete. Download the complete patch.

drivers/acpi/Makefile

View file

This diff is incomplete. Download the complete patch.

drivers/acpi/pci_mcfg.c

View file

This diff is incomplete. Download the complete patch.

drivers/acpi/pci_root.c

View file

This diff is incomplete. Download the complete patch.

drivers/irqchip/Kconfig

View file

This diff is incomplete. Download the complete patch.

drivers/misc/genwqe/card_base.c

View file

This diff is incomplete. Download the complete patch.

drivers/net/ethernet/atheros/alx/main.c

View file

This diff is incomplete. Download the complete patch.

drivers/net/ethernet/intel/e1000e/netdev.c

View file

This diff is incomplete. Download the complete patch.

drivers/net/ethernet/intel/fm10k/fm10k_pci.c

View file

This diff is incomplete. Download the complete patch.

drivers/net/ethernet/intel/i40e/i40e_main.c

View file

This diff is incomplete. Download the complete patch.

drivers/net/ethernet/intel/igb/igb_main.c

View file

This diff is incomplete. Download the complete patch.

drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

View file

This diff is incomplete. Download the complete patch.

drivers/nvme/host/pci.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/Kconfig

View file

This diff is incomplete. Download the complete patch.

drivers/pci/bus.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/ecam.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/Kconfig

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/Makefile

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-aardvark.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-dra7xx.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-host-common.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-host-generic.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-hyperv.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-keystone.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-layerscape.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-mvebu.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-rcar-gen2.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-tegra.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-thunder-ecam.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-thunder-pem.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-versatile.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pci-xgene.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-altera.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-armada8k.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-artpec6.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-designware-plat.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-designware.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-hisi.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-iproc.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-rcar.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-xilinx-nwl.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/host/pcie-xilinx.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/hotplug/acpiphp_glue.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/hotplug/pciehp_hpc.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/msi.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pci-driver.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pci-sysfs.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pci.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pci.h

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pcie/Kconfig

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pcie/aspm.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pcie/pcie-dpc.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pcie/portdrv_core.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/pcie/portdrv_pci.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/probe.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/proc.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/quirks.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/remove.c

View file

This diff is incomplete. Download the complete patch.

drivers/pci/setup-bus.c

View file

This diff is incomplete. Download the complete patch.

drivers/scsi/lpfc/lpfc_init.c

View file

This diff is incomplete. Download the complete patch.

drivers/usb/host/xhci-pci.c

View file

This diff is incomplete. Download the complete patch.

include/linux/pci-acpi.h

View file

This diff is incomplete. Download the complete patch.

include/linux/pci-ecam.h

View file

This diff is incomplete. Download the complete patch.

include/linux/pci.h

View file

This diff is incomplete. Download the complete patch.