You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'pci-v4.11-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas: - add ASPM L1 substate support - enable PCIe Extended Tags when supported - configure PCIe MPS settings on iProc, Versatile, X-Gene, and Xilinx - increase VPD access timeout - add ACS quirks for Intel Union Point, Qualcomm QDF2400 and QDF2432 - use new pci_irq_alloc_vectors() in more drivers - fix MSI affinity memory leak - remove unused MSI interfaces and update documentation - remove unused AER .link_reset() callback - avoid pci_lock / p->pi_lock deadlock seen with perf - serialize sysfs enable/disable num_vfs operations - move DesignWare IP from drivers/pci/host/ to drivers/pci/dwc/ and refactor so we can support both hosts and endpoints - add DT ECAM-like support for HiSilicon Hip06/Hip07 controllers - add Rockchip system power management support - add Thunder-X cn81xx and cn83xx support - add Exynos 5440 PCIe PHY support * tag 'pci-v4.11-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (93 commits) PCI: dwc: Remove dependency of designware on CONFIG_PCI PCI: dwc: Add CONFIG_PCIE_DW_HOST to enable PCI dwc host PCI: dwc: Split pcie-designware.c into host and core files PCI: dwc: designware: Fix style errors in pcie-designware.c PCI: dwc: designware: Parse "num-lanes" property in dw_pcie_setup_rc() PCI: dwc: all: Split struct pcie_port into host-only and core structures PCI: dwc: designware: Get device pointer at the start of dw_pcie_host_init() PCI: dwc: all: Rename cfg_read/cfg_write to read/write PCI: dwc: all: Use platform_set_drvdata() to save private data PCI: dwc: designware: Move register defines to designware header file PCI: dwc: Use PTR_ERR_OR_ZERO to simplify code PCI: dra7xx: Group PHY API invocations PCI: dra7xx: Enable MSI and legacy interrupts simultaneously PCI: dra7xx: Add support to force RC to work in GEN1 mode PCI: dra7xx: Simplify probe code with devm_gpiod_get_optional() PCI: Move DesignWare IP support to new drivers/pci/dwc/ directory PCI: exynos: Support the PHY generic framework Documentation: binding: Modify the exynos5440 PCIe binding phy: phy-exynos-pcie: Add support for Exynos PCIe PHY Documentation: samsung-phy: Add exynos-pcie-phy binding ...
This commit is contained in:
@@ -162,8 +162,6 @@ The following old APIs to enable and disable MSI or MSI-X interrupts should
|
||||
not be used in new code:
|
||||
|
||||
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 */
|
||||
@@ -268,5 +266,5 @@ or disabled (0). If 0 is found in any of the msi_bus files belonging
|
||||
to bridges between the PCI root and the device, MSIs are disabled.
|
||||
|
||||
It is also worth checking the device driver to see whether it supports MSIs.
|
||||
For example, it may contain calls to pci_enable_msi_range() or
|
||||
pci_enable_msix_range().
|
||||
For example, it may contain calls to pci_irq_alloc_vectors() with the
|
||||
PCI_IRQ_MSI or PCI_IRQ_MSIX flags.
|
||||
|
||||
@@ -161,21 +161,13 @@ Since all service drivers of a PCI-PCI Bridge Port device are
|
||||
allowed to run simultaneously, below lists a few of possible resource
|
||||
conflicts with proposed solutions.
|
||||
|
||||
6.1 MSI Vector Resource
|
||||
6.1 MSI and MSI-X Vector Resource
|
||||
|
||||
The MSI capability structure enables a device software driver to call
|
||||
pci_enable_msi to request MSI based interrupts. Once MSI interrupts
|
||||
are enabled on a device, it stays in this mode until a device driver
|
||||
calls pci_disable_msi to disable MSI interrupts and revert back to
|
||||
INTx emulation mode. Since service drivers of the same PCI-PCI Bridge
|
||||
port share the same physical device, if an individual service driver
|
||||
calls pci_enable_msi/pci_disable_msi it may result unpredictable
|
||||
behavior. For example, two service drivers run simultaneously on the
|
||||
same physical Root Port. Both service drivers call pci_enable_msi to
|
||||
request MSI based interrupts. A service driver may not know whether
|
||||
any other service drivers have run on this Root Port. If either one
|
||||
of them calls pci_disable_msi, it puts the other service driver
|
||||
in a wrong interrupt mode.
|
||||
Once MSI or MSI-X interrupts are enabled on a device, it stays in this
|
||||
mode until they are disabled again. Since service drivers of the same
|
||||
PCI-PCI Bridge port share the same physical device, if an individual
|
||||
service driver enables or disables MSI/MSI-X mode it may result
|
||||
unpredictable behavior.
|
||||
|
||||
To avoid this situation all service drivers are not permitted to
|
||||
switch interrupt mode on its device. The PCI Express Port Bus driver
|
||||
@@ -187,17 +179,6 @@ driver. Service drivers should use (struct pcie_device*)dev->irq to
|
||||
call request_irq/free_irq. In addition, the interrupt mode is stored
|
||||
in the field interrupt_mode of struct pcie_device.
|
||||
|
||||
6.2 MSI-X Vector Resources
|
||||
|
||||
Similar to the MSI a device driver for an MSI-X capable device can
|
||||
call pci_enable_msix to request MSI-X interrupts. All service drivers
|
||||
are not permitted to switch interrupt mode on its device. The PCI
|
||||
Express Port Bus driver is responsible for determining the interrupt
|
||||
mode and this should be transparent to service drivers. Any attempt
|
||||
by service driver to call pci_enable_msix/pci_disable_msix may
|
||||
result unpredictable behavior. Service drivers should use
|
||||
(struct pcie_device*)dev->irq and call request_irq/free_irq.
|
||||
|
||||
6.3 PCI Memory/IO Mapped Regions
|
||||
|
||||
Service drivers for PCI Express Power Management (PME), Advanced
|
||||
|
||||
@@ -78,7 +78,6 @@ struct pci_error_handlers
|
||||
{
|
||||
int (*error_detected)(struct pci_dev *dev, enum pci_channel_state);
|
||||
int (*mmio_enabled)(struct pci_dev *dev);
|
||||
int (*link_reset)(struct pci_dev *dev);
|
||||
int (*slot_reset)(struct pci_dev *dev);
|
||||
void (*resume)(struct pci_dev *dev);
|
||||
};
|
||||
@@ -104,8 +103,7 @@ if it implements any, it must implement error_detected(). If a callback
|
||||
is not implemented, the corresponding feature is considered unsupported.
|
||||
For example, if mmio_enabled() and resume() aren't there, then it
|
||||
is assumed that the driver is not doing any direct recovery and requires
|
||||
a slot reset. If link_reset() is not implemented, the card is assumed to
|
||||
not care about link resets. Typically a driver will want to know about
|
||||
a slot reset. Typically a driver will want to know about
|
||||
a slot_reset().
|
||||
|
||||
The actual steps taken by a platform to recover from a PCI error
|
||||
@@ -232,25 +230,9 @@ proceeds to STEP 4 (Slot Reset)
|
||||
|
||||
STEP 3: Link Reset
|
||||
------------------
|
||||
The platform resets the link, and then calls the link_reset() callback
|
||||
on all affected device drivers. This is a PCI-Express specific state
|
||||
The platform resets the link. This is a PCI-Express specific step
|
||||
and is done whenever a non-fatal error has been detected that can be
|
||||
"solved" by resetting the link. This call informs the driver of the
|
||||
reset and the driver should check to see if the device appears to be
|
||||
in working condition.
|
||||
|
||||
The driver is not supposed to restart normal driver I/O operations
|
||||
at this point. It should limit itself to "probing" the device to
|
||||
check its recoverability status. If all is right, then the platform
|
||||
will call resume() once all drivers have ack'd link_reset().
|
||||
|
||||
Result codes:
|
||||
(identical to STEP 3 (MMIO Enabled)
|
||||
|
||||
The platform then proceeds to either STEP 4 (Slot Reset) or STEP 5
|
||||
(Resume Operations).
|
||||
|
||||
>>> The current powerpc implementation does not implement this callback.
|
||||
"solved" by resetting the link.
|
||||
|
||||
STEP 4: Slot Reset
|
||||
------------------
|
||||
|
||||
+11
-11
@@ -382,18 +382,18 @@ The fundamental difference between MSI and MSI-X is how multiple
|
||||
"vectors" get allocated. MSI requires contiguous blocks of vectors
|
||||
while MSI-X can allocate several individual ones.
|
||||
|
||||
MSI capability can be enabled by calling pci_enable_msi() or
|
||||
pci_enable_msix() before calling request_irq(). This causes
|
||||
the PCI support to program CPU vector data into the PCI device
|
||||
capability registers.
|
||||
MSI capability can be enabled by calling pci_alloc_irq_vectors() with the
|
||||
PCI_IRQ_MSI and/or PCI_IRQ_MSIX flags before calling request_irq(). This
|
||||
causes the PCI support to program CPU vector data into the PCI device
|
||||
capability registers. Many architectures, chip-sets, or BIOSes do NOT
|
||||
support MSI or MSI-X and a call to pci_alloc_irq_vectors with just
|
||||
the PCI_IRQ_MSI and PCI_IRQ_MSIX flags will fail, so try to always
|
||||
specify PCI_IRQ_LEGACY as well.
|
||||
|
||||
If your PCI device supports both, try to enable MSI-X first.
|
||||
Only one can be enabled at a time. Many architectures, chip-sets,
|
||||
or BIOSes do NOT support MSI or MSI-X and the call to pci_enable_msi/msix
|
||||
will fail. This is important to note since many drivers have
|
||||
two (or more) interrupt handlers: one for MSI/MSI-X and another for IRQs.
|
||||
They choose which handler to register with request_irq() based on the
|
||||
return value from pci_enable_msi/msix().
|
||||
Drivers that have different interrupt handlers for MSI/MSI-X and
|
||||
legacy INTx should chose the right one based on the msi_enabled
|
||||
and msix_enabled flags in the pci_dev structure after calling
|
||||
pci_alloc_irq_vectors.
|
||||
|
||||
There are (at least) two really good reasons for using MSI:
|
||||
1) MSI is an exclusive interrupt vector by definition.
|
||||
|
||||
@@ -42,3 +42,40 @@ Hip05 Example (note that Hip06 is the same except compatible):
|
||||
0x0 0 0 4 &mbigen_pcie 4 13>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
HiSilicon Hip06/Hip07 PCIe host bridge DT (almost-ECAM) description.
|
||||
The properties and their meanings are identical to those described in
|
||||
host-generic-pci.txt except as listed below.
|
||||
|
||||
Properties of the host controller node that differ from
|
||||
host-generic-pci.txt:
|
||||
|
||||
- compatible : Must be "hisilicon,pcie-almost-ecam"
|
||||
|
||||
- reg : Two entries: First the ECAM configuration space for any
|
||||
other bus underneath the root bus. Second, the base
|
||||
and size of the HiSilicon host bridge registers include
|
||||
the RC's own config space.
|
||||
|
||||
Example:
|
||||
pcie0: pcie@a0090000 {
|
||||
compatible = "hisilicon,pcie-almost-ecam";
|
||||
reg = <0 0xb0000000 0 0x2000000>, /* ECAM configuration space */
|
||||
<0 0xa0090000 0 0x10000>; /* host bridge registers */
|
||||
bus-range = <0 31>;
|
||||
msi-map = <0x0000 &its_dsa 0x0000 0x2000>;
|
||||
msi-map-mask = <0xffff>;
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
device_type = "pci";
|
||||
dma-coherent;
|
||||
ranges = <0x02000000 0 0xb2000000 0x0 0xb2000000 0 0x5ff0000
|
||||
0x01000000 0 0 0 0xb7ff0000 0 0x10000>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0xf800 0 0 7>;
|
||||
interrupt-map = <0x0 0 0 1 &mbigen_pcie0 650 4
|
||||
0x0 0 0 2 &mbigen_pcie0 650 4
|
||||
0x0 0 0 3 &mbigen_pcie0 650 4
|
||||
0x0 0 0 4 &mbigen_pcie0 650 4>;
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
@@ -78,7 +78,8 @@ and the following optional properties:
|
||||
multiple lanes. If this property is not found, we assume that the
|
||||
value is 0.
|
||||
- reset-gpios: optional gpio to PERST#
|
||||
- reset-delay-us: delay in us to wait after reset de-assertion
|
||||
- reset-delay-us: delay in us to wait after reset de-assertion, if not
|
||||
specified will default to 100ms, as required by the PCIe specification.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC;
|
||||
"renesas,pcie-r8a7791" for the R8A7791 SoC;
|
||||
"renesas,pcie-r8a7793" for the R8A7793 SoC;
|
||||
"renesas,pcie-r8a7795" for the R8A7795 SoC;
|
||||
"renesas,pcie-r8a7796" for the R8A7796 SoC;
|
||||
"renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device.
|
||||
"renesas,pcie-rcar-gen3" for a generic R-Car Gen3 compatible device.
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@ Required properties:
|
||||
- interrupt-map-mask and interrupt-map: standard PCI properties
|
||||
|
||||
Optional Property:
|
||||
- aspm-no-l0s: RC won't support ASPM L0s. This property is needed if
|
||||
using 24MHz OSC for RC's PHY.
|
||||
- ep-gpios: contain the entry for pre-reset gpio
|
||||
- num-lanes: number of lanes to use
|
||||
- vpcie3v3-supply: The phandle to the 3.3v regulator to use for PCIe.
|
||||
|
||||
@@ -7,8 +7,19 @@ Required properties:
|
||||
- compatible: "samsung,exynos5440-pcie"
|
||||
- reg: base addresses and lengths of the pcie controller,
|
||||
the phy controller, additional register for the phy controller.
|
||||
(Registers for the phy controller are DEPRECATED.
|
||||
Use the PHY framework.)
|
||||
- reg-names : First name should be set to "elbi".
|
||||
And use the "config" instead of getting the confgiruation address space
|
||||
from "ranges".
|
||||
NOTE: When use the "config" property, reg-names must be set.
|
||||
- interrupts: A list of interrupt outputs for level interrupt,
|
||||
pulse interrupt, special interrupt.
|
||||
- phys: From PHY binding. Phandle for the Generic PHY.
|
||||
Refer to Documentation/devicetree/bindings/phy/samsung-phy.txt
|
||||
|
||||
Other common properties refer to
|
||||
Documentation/devicetree/binding/pci/designware-pcie.txt
|
||||
|
||||
Example:
|
||||
|
||||
@@ -54,6 +65,24 @@ SoC specific DT Entry:
|
||||
num-lanes = <4>;
|
||||
};
|
||||
|
||||
With using PHY framework:
|
||||
pcie_phy0: pcie-phy@270000 {
|
||||
...
|
||||
reg = <0x270000 0x1000>, <0x271000 0x40>;
|
||||
reg-names = "phy", "block";
|
||||
...
|
||||
};
|
||||
|
||||
pcie@290000 {
|
||||
...
|
||||
reg = <0x290000 0x1000>, <0x40000000 0x1000>;
|
||||
reg-names = "elbi", "config";
|
||||
phys = <&pcie_phy0>;
|
||||
ranges = <0x81000000 0 0 0x60001000 0 0x00010000
|
||||
0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>;
|
||||
...
|
||||
};
|
||||
|
||||
Board specific DT Entry:
|
||||
|
||||
pcie@290000 {
|
||||
|
||||
@@ -191,3 +191,20 @@ Example:
|
||||
usbdrdphy0 = &usb3_phy0;
|
||||
usbdrdphy1 = &usb3_phy1;
|
||||
};
|
||||
|
||||
Samsung Exynos SoC series PCIe PHY controller
|
||||
--------------------------------------------------
|
||||
Required properties:
|
||||
- compatible : Should be set to "samsung,exynos5440-pcie-phy"
|
||||
- #phy-cells : Must be zero
|
||||
- reg : a register used by phy driver.
|
||||
- First is for phy register, second is for block register.
|
||||
- reg-names : Must be set to "phy" and "block".
|
||||
|
||||
Example:
|
||||
pcie_phy0: pcie-phy@270000 {
|
||||
#phy-cells = <0>;
|
||||
compatible = "samsung,exynos5440-pcie-phy";
|
||||
reg = <0x270000 0x1000>, <0x271000 0x40>;
|
||||
reg-names = "phy", "block";
|
||||
};
|
||||
|
||||
+11
-11
@@ -9551,7 +9551,7 @@ L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/pci-armada8k.txt
|
||||
F: drivers/pci/host/pcie-armada8k.c
|
||||
F: drivers/pci/dwc/pcie-armada8k.c
|
||||
|
||||
PCI DRIVER FOR APPLIEDMICRO XGENE
|
||||
M: Tanmay Inamdar <tinamdar@apm.com>
|
||||
@@ -9569,7 +9569,7 @@ L: linuxppc-dev@lists.ozlabs.org
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org
|
||||
S: Maintained
|
||||
F: drivers/pci/host/*layerscape*
|
||||
F: drivers/pci/dwc/*layerscape*
|
||||
|
||||
PCI DRIVER FOR IMX6
|
||||
M: Richard Zhu <hongxing.zhu@nxp.com>
|
||||
@@ -9578,14 +9578,14 @@ L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
|
||||
F: drivers/pci/host/*imx6*
|
||||
F: drivers/pci/dwc/*imx6*
|
||||
|
||||
PCI DRIVER FOR TI KEYSTONE
|
||||
M: Murali Karicheri <m-karicheri2@ti.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: drivers/pci/host/*keystone*
|
||||
F: drivers/pci/dwc/*keystone*
|
||||
|
||||
PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
|
||||
M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
@@ -9617,7 +9617,7 @@ L: linux-omap@vger.kernel.org
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/pci/ti-pci.txt
|
||||
F: drivers/pci/host/pci-dra7xx.c
|
||||
F: drivers/pci/dwc/pci-dra7xx.c
|
||||
|
||||
PCI DRIVER FOR RENESAS R-CAR
|
||||
M: Simon Horman <horms@verge.net.au>
|
||||
@@ -9632,7 +9632,7 @@ L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: drivers/pci/host/pci-exynos.c
|
||||
F: drivers/pci/dwc/pci-exynos.c
|
||||
|
||||
PCI DRIVER FOR SYNOPSIS DESIGNWARE
|
||||
M: Jingoo Han <jingoohan1@gmail.com>
|
||||
@@ -9640,7 +9640,7 @@ M: Joao Pinto <Joao.Pinto@synopsys.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/designware-pcie.txt
|
||||
F: drivers/pci/host/*designware*
|
||||
F: drivers/pci/dwc/*designware*
|
||||
|
||||
PCI DRIVER FOR GENERIC OF HOSTS
|
||||
M: Will Deacon <will.deacon@arm.com>
|
||||
@@ -9661,7 +9661,7 @@ PCIE DRIVER FOR ST SPEAR13XX
|
||||
M: Pratyush Anand <pratyush.anand@gmail.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/pci/host/*spear*
|
||||
F: drivers/pci/dwc/*spear*
|
||||
|
||||
PCI MSI DRIVER FOR ALTERA MSI IP
|
||||
M: Ley Foon Tan <lftan@altera.com>
|
||||
@@ -9686,7 +9686,7 @@ L: linux-arm-kernel@axis.com
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/axis,artpec*
|
||||
F: drivers/pci/host/*artpec*
|
||||
F: drivers/pci/dwc/*artpec*
|
||||
|
||||
PCIE DRIVER FOR HISILICON
|
||||
M: Zhou Wang <wangzhou1@hisilicon.com>
|
||||
@@ -9694,7 +9694,7 @@ M: Gabriele Paoloni <gabriele.paoloni@huawei.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
|
||||
F: drivers/pci/host/pcie-hisi.c
|
||||
F: drivers/pci/dwc/pcie-hisi.c
|
||||
|
||||
PCIE DRIVER FOR ROCKCHIP
|
||||
M: Shawn Lin <shawn.lin@rock-chips.com>
|
||||
@@ -9710,7 +9710,7 @@ M: Stanimir Varbanov <svarbanov@mm-sol.com>
|
||||
L: linux-pci@vger.kernel.org
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/pci/host/*qcom*
|
||||
F: drivers/pci/dwc/*qcom*
|
||||
|
||||
PCIE DRIVER FOR CAVIUM THUNDERX
|
||||
M: David Daney <david.daney@cavium.com>
|
||||
|
||||
@@ -82,7 +82,7 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
if (domain == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
return pci_msi_domain_alloc_irqs(domain, dev, nvec, type);
|
||||
return msi_domain_alloc_irqs(domain, &dev->dev, nvec);
|
||||
}
|
||||
|
||||
void native_teardown_msi_irq(unsigned int irq)
|
||||
|
||||
@@ -15,6 +15,9 @@ obj-$(CONFIG_PINCTRL) += pinctrl/
|
||||
obj-$(CONFIG_GPIOLIB) += gpio/
|
||||
obj-y += pwm/
|
||||
obj-$(CONFIG_PCI) += pci/
|
||||
# PCI dwc controller drivers
|
||||
obj-y += pci/dwc/
|
||||
|
||||
obj-$(CONFIG_PARISC) += parisc/
|
||||
obj-$(CONFIG_RAPIDIO) += rapidio/
|
||||
obj-y += video/
|
||||
|
||||
@@ -195,11 +195,10 @@ int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
|
||||
goto skip_lookup;
|
||||
|
||||
/*
|
||||
* We expect exact match, unless MCFG entry end bus covers more than
|
||||
* specified by caller.
|
||||
* We expect the range in bus_res in the coverage of MCFG bus range.
|
||||
*/
|
||||
list_for_each_entry(e, &pci_mcfg_list, list) {
|
||||
if (e->segment == seg && e->bus_start == bus_res->start &&
|
||||
if (e->segment == seg && e->bus_start <= bus_res->start &&
|
||||
e->bus_end >= bus_res->end) {
|
||||
root->mcfg_addr = e->addr;
|
||||
}
|
||||
|
||||
@@ -122,104 +122,40 @@
|
||||
#include "xgbe.h"
|
||||
#include "xgbe-common.h"
|
||||
|
||||
static int xgbe_config_msi(struct xgbe_prv_data *pdata)
|
||||
static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
unsigned int msi_count;
|
||||
unsigned int vector_count;
|
||||
unsigned int i, j;
|
||||
int ret;
|
||||
|
||||
msi_count = XGBE_MSIX_BASE_COUNT;
|
||||
msi_count += max(pdata->rx_ring_count,
|
||||
pdata->tx_ring_count);
|
||||
msi_count = roundup_pow_of_two(msi_count);
|
||||
vector_count = XGBE_MSI_BASE_COUNT;
|
||||
vector_count += max(pdata->rx_ring_count,
|
||||
pdata->tx_ring_count);
|
||||
|
||||
ret = pci_enable_msi_exact(pdata->pcidev, msi_count);
|
||||
ret = pci_alloc_irq_vectors(pdata->pcidev, XGBE_MSI_MIN_COUNT,
|
||||
vector_count, PCI_IRQ_MSI | PCI_IRQ_MSIX);
|
||||
if (ret < 0) {
|
||||
dev_info(pdata->dev, "MSI request for %u interrupts failed\n",
|
||||
msi_count);
|
||||
|
||||
ret = pci_enable_msi(pdata->pcidev);
|
||||
if (ret < 0) {
|
||||
dev_info(pdata->dev, "MSI enablement failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
msi_count = 1;
|
||||
}
|
||||
|
||||
pdata->irq_count = msi_count;
|
||||
|
||||
pdata->dev_irq = pdata->pcidev->irq;
|
||||
|
||||
if (msi_count > 1) {
|
||||
pdata->ecc_irq = pdata->pcidev->irq + 1;
|
||||
pdata->i2c_irq = pdata->pcidev->irq + 2;
|
||||
pdata->an_irq = pdata->pcidev->irq + 3;
|
||||
|
||||
for (i = XGBE_MSIX_BASE_COUNT, j = 0;
|
||||
(i < msi_count) && (j < XGBE_MAX_DMA_CHANNELS);
|
||||
i++, j++)
|
||||
pdata->channel_irq[j] = pdata->pcidev->irq + i;
|
||||
pdata->channel_irq_count = j;
|
||||
|
||||
pdata->per_channel_irq = 1;
|
||||
pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL;
|
||||
} else {
|
||||
pdata->ecc_irq = pdata->pcidev->irq;
|
||||
pdata->i2c_irq = pdata->pcidev->irq;
|
||||
pdata->an_irq = pdata->pcidev->irq;
|
||||
}
|
||||
|
||||
if (netif_msg_probe(pdata))
|
||||
dev_dbg(pdata->dev, "MSI interrupts enabled\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xgbe_config_msix(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
unsigned int msix_count;
|
||||
unsigned int i, j;
|
||||
int ret;
|
||||
|
||||
msix_count = XGBE_MSIX_BASE_COUNT;
|
||||
msix_count += max(pdata->rx_ring_count,
|
||||
pdata->tx_ring_count);
|
||||
|
||||
pdata->msix_entries = devm_kcalloc(pdata->dev, msix_count,
|
||||
sizeof(struct msix_entry),
|
||||
GFP_KERNEL);
|
||||
if (!pdata->msix_entries)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < msix_count; i++)
|
||||
pdata->msix_entries[i].entry = i;
|
||||
|
||||
ret = pci_enable_msix_range(pdata->pcidev, pdata->msix_entries,
|
||||
XGBE_MSIX_MIN_COUNT, msix_count);
|
||||
if (ret < 0) {
|
||||
dev_info(pdata->dev, "MSI-X enablement failed\n");
|
||||
devm_kfree(pdata->dev, pdata->msix_entries);
|
||||
pdata->msix_entries = NULL;
|
||||
dev_info(pdata->dev, "multi MSI/MSI-X enablement failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata->irq_count = ret;
|
||||
|
||||
pdata->dev_irq = pdata->msix_entries[0].vector;
|
||||
pdata->ecc_irq = pdata->msix_entries[1].vector;
|
||||
pdata->i2c_irq = pdata->msix_entries[2].vector;
|
||||
pdata->an_irq = pdata->msix_entries[3].vector;
|
||||
pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
|
||||
pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 1);
|
||||
pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 2);
|
||||
pdata->an_irq = pci_irq_vector(pdata->pcidev, 3);
|
||||
|
||||
for (i = XGBE_MSIX_BASE_COUNT, j = 0; i < ret; i++, j++)
|
||||
pdata->channel_irq[j] = pdata->msix_entries[i].vector;
|
||||
for (i = XGBE_MSI_BASE_COUNT, j = 0; i < ret; i++, j++)
|
||||
pdata->channel_irq[j] = pci_irq_vector(pdata->pcidev, i);
|
||||
pdata->channel_irq_count = j;
|
||||
|
||||
pdata->per_channel_irq = 1;
|
||||
pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL;
|
||||
|
||||
if (netif_msg_probe(pdata))
|
||||
dev_dbg(pdata->dev, "MSI-X interrupts enabled\n");
|
||||
dev_dbg(pdata->dev, "multi %s interrupts enabled\n",
|
||||
pdata->pcidev->msix_enabled ? "MSI-X" : "MSI");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -228,21 +164,28 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = xgbe_config_msix(pdata);
|
||||
ret = xgbe_config_multi_msi(pdata);
|
||||
if (!ret)
|
||||
goto out;
|
||||
|
||||
ret = xgbe_config_msi(pdata);
|
||||
if (!ret)
|
||||
goto out;
|
||||
ret = pci_alloc_irq_vectors(pdata->pcidev, 1, 1,
|
||||
PCI_IRQ_LEGACY | PCI_IRQ_MSI);
|
||||
if (ret < 0) {
|
||||
dev_info(pdata->dev, "single IRQ enablement failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdata->irq_count = 1;
|
||||
pdata->irq_shared = 1;
|
||||
pdata->channel_irq_count = 1;
|
||||
|
||||
pdata->dev_irq = pdata->pcidev->irq;
|
||||
pdata->ecc_irq = pdata->pcidev->irq;
|
||||
pdata->i2c_irq = pdata->pcidev->irq;
|
||||
pdata->an_irq = pdata->pcidev->irq;
|
||||
pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0);
|
||||
pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 0);
|
||||
pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 0);
|
||||
pdata->an_irq = pci_irq_vector(pdata->pcidev, 0);
|
||||
|
||||
if (netif_msg_probe(pdata))
|
||||
dev_dbg(pdata->dev, "single %s interrupt enabled\n",
|
||||
pdata->pcidev->msi_enabled ? "MSI" : "legacy");
|
||||
|
||||
out:
|
||||
if (netif_msg_probe(pdata)) {
|
||||
@@ -425,12 +368,15 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* Configure the netdev resource */
|
||||
ret = xgbe_config_netdev(pdata);
|
||||
if (ret)
|
||||
goto err_pci_enable;
|
||||
goto err_irq_vectors;
|
||||
|
||||
netdev_notice(pdata->netdev, "net device enabled\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq_vectors:
|
||||
pci_free_irq_vectors(pdata->pcidev);
|
||||
|
||||
err_pci_enable:
|
||||
xgbe_free_pdata(pdata);
|
||||
|
||||
@@ -446,6 +392,8 @@ static void xgbe_pci_remove(struct pci_dev *pdev)
|
||||
|
||||
xgbe_deconfig_netdev(pdata);
|
||||
|
||||
pci_free_irq_vectors(pdata->pcidev);
|
||||
|
||||
xgbe_free_pdata(pdata);
|
||||
}
|
||||
|
||||
|
||||
@@ -211,9 +211,9 @@
|
||||
#define XGBE_MAC_PROP_OFFSET 0x1d000
|
||||
#define XGBE_I2C_CTRL_OFFSET 0x1e000
|
||||
|
||||
/* PCI MSIx support */
|
||||
#define XGBE_MSIX_BASE_COUNT 4
|
||||
#define XGBE_MSIX_MIN_COUNT (XGBE_MSIX_BASE_COUNT + 1)
|
||||
/* PCI MSI/MSIx support */
|
||||
#define XGBE_MSI_BASE_COUNT 4
|
||||
#define XGBE_MSI_MIN_COUNT (XGBE_MSI_BASE_COUNT + 1)
|
||||
|
||||
/* PCI clock frequencies */
|
||||
#define XGBE_V2_DMA_CLOCK_FREQ 500000000 /* 500 MHz */
|
||||
@@ -982,14 +982,12 @@ struct xgbe_prv_data {
|
||||
unsigned int desc_ded_count;
|
||||
unsigned int desc_sec_count;
|
||||
|
||||
struct msix_entry *msix_entries;
|
||||
int dev_irq;
|
||||
int ecc_irq;
|
||||
int i2c_irq;
|
||||
int channel_irq[XGBE_MAX_DMA_CHANNELS];
|
||||
|
||||
unsigned int per_channel_irq;
|
||||
unsigned int irq_shared;
|
||||
unsigned int irq_count;
|
||||
unsigned int channel_irq_count;
|
||||
unsigned int channel_irq_mode;
|
||||
|
||||
@@ -132,4 +132,5 @@ config PCI_HYPERV
|
||||
PCI devices from a PCI backend to support PCI driver domains.
|
||||
|
||||
source "drivers/pci/hotplug/Kconfig"
|
||||
source "drivers/pci/dwc/Kconfig"
|
||||
source "drivers/pci/host/Kconfig"
|
||||
|
||||
@@ -367,7 +367,7 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size)
|
||||
static int pci_vpd_wait(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_vpd *vpd = dev->vpd;
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(50);
|
||||
unsigned long timeout = jiffies + msecs_to_jiffies(125);
|
||||
unsigned long max_sleep = 16;
|
||||
u16 status;
|
||||
int ret;
|
||||
@@ -684,8 +684,9 @@ void pci_cfg_access_unlock(struct pci_dev *dev)
|
||||
WARN_ON(!dev->block_cfg_access);
|
||||
|
||||
dev->block_cfg_access = 0;
|
||||
wake_up_all(&pci_cfg_wait);
|
||||
raw_spin_unlock_irqrestore(&pci_lock, flags);
|
||||
|
||||
wake_up_all(&pci_cfg_wait);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_cfg_access_unlock);
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
menu "DesignWare PCI Core Support"
|
||||
|
||||
config PCIE_DW
|
||||
bool
|
||||
|
||||
config PCIE_DW_HOST
|
||||
bool
|
||||
depends on PCI
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIE_DW
|
||||
|
||||
config PCI_DRA7XX
|
||||
bool "TI DRA7xx PCIe controller"
|
||||
depends on PCI
|
||||
depends on OF && HAS_IOMEM && TI_PIPE3
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Enables support for the PCIe controller in the DRA7xx SoC. There
|
||||
are two instances of PCIe controller in DRA7xx. This controller can
|
||||
act both as EP and RC. This reuses the Designware core.
|
||||
|
||||
config PCIE_DW_PLAT
|
||||
bool "Platform bus based DesignWare PCIe Controller"
|
||||
depends on PCI
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIE_DW_HOST
|
||||
---help---
|
||||
This selects the DesignWare PCIe controller support. Select this if
|
||||
you have a PCIe controller on Platform bus.
|
||||
|
||||
If you have a controller with this interface, say Y or M here.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PCI_EXYNOS
|
||||
bool "Samsung Exynos PCIe controller"
|
||||
depends on PCI
|
||||
depends on SOC_EXYNOS5440
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
|
||||
config PCI_IMX6
|
||||
bool "Freescale i.MX6 PCIe controller"
|
||||
depends on PCI
|
||||
depends on SOC_IMX6Q
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
|
||||
config PCIE_SPEAR13XX
|
||||
bool "STMicroelectronics SPEAr PCIe controller"
|
||||
depends on PCI
|
||||
depends on ARCH_SPEAR13XX
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here if you want PCIe support on SPEAr13XX SoCs.
|
||||
|
||||
config PCI_KEYSTONE
|
||||
bool "TI Keystone PCIe controller"
|
||||
depends on PCI
|
||||
depends on ARCH_KEYSTONE
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here if you want to enable PCI controller support on Keystone
|
||||
SoCs. The PCI controller on Keystone is based on Designware hardware
|
||||
and therefore the driver re-uses the Designware core functions to
|
||||
implement the driver.
|
||||
|
||||
config PCI_LAYERSCAPE
|
||||
bool "Freescale Layerscape PCIe controller"
|
||||
depends on PCI
|
||||
depends on OF && (ARM || ARCH_LAYERSCAPE)
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select MFD_SYSCON
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here if you want PCIe controller support on Layerscape SoCs.
|
||||
|
||||
config PCI_HISI
|
||||
depends on OF && ARM64
|
||||
bool "HiSilicon Hip05 and Hip06 SoCs PCIe controllers"
|
||||
depends on PCI
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here if you want PCIe controller support on HiSilicon
|
||||
Hip05 and Hip06 SoCs
|
||||
|
||||
config PCIE_QCOM
|
||||
bool "Qualcomm PCIe controller"
|
||||
depends on PCI
|
||||
depends on ARCH_QCOM && OF
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here to enable PCIe controller support on Qualcomm SoCs. The
|
||||
PCIe controller uses the Designware core plus Qualcomm-specific
|
||||
hardware wrappers.
|
||||
|
||||
config PCIE_ARMADA_8K
|
||||
bool "Marvell Armada-8K PCIe controller"
|
||||
depends on PCI
|
||||
depends on ARCH_MVEBU
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here if you want to enable PCIe controller support on
|
||||
Armada-8K SoCs. The PCIe controller on Armada-8K is based on
|
||||
Designware hardware and therefore the driver re-uses the
|
||||
Designware core functions to implement the driver.
|
||||
|
||||
config PCIE_ARTPEC6
|
||||
bool "Axis ARTPEC-6 PCIe controller"
|
||||
depends on PCI
|
||||
depends on MACH_ARTPEC6
|
||||
depends on PCI_MSI_IRQ_DOMAIN
|
||||
select PCIEPORTBUS
|
||||
select PCIE_DW_HOST
|
||||
help
|
||||
Say Y here to enable PCIe controller support on Axis ARTPEC-6
|
||||
SoCs. This PCIe controller uses the DesignWare core.
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,24 @@
|
||||
obj-$(CONFIG_PCIE_DW) += pcie-designware.o
|
||||
obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
|
||||
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
|
||||
obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
|
||||
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
|
||||
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
|
||||
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
|
||||
obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
|
||||
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
|
||||
obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
|
||||
obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
|
||||
obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
|
||||
|
||||
# The following drivers are for devices that use the generic ACPI
|
||||
# pci_root.c driver but don't support standard ECAM config access.
|
||||
# They contain MCFG quirks to replace the generic ECAM accessors with
|
||||
# device-specific ones that are shared with the DT driver.
|
||||
|
||||
# The ACPI driver is generic and should not require driver-specific
|
||||
# config options to be enabled, so we always build these drivers on
|
||||
# ARM64 and use internal ifdefs to only build the pieces we need
|
||||
# depending on whether ACPI, the DT driver, or both are enabled.
|
||||
|
||||
obj-$(CONFIG_ARM64) += pcie-hisi.o
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user