PCI changes for the v4.3 merge window:
Enumeration Allocate ATS struct during enumeration (Bjorn Helgaas) Embed ATS info directly into struct pci_dev (Bjorn Helgaas) Reduce size of ATS structure elements (Bjorn Helgaas) Stop caching ATS Invalidate Queue Depth (Bjorn Helgaas) iommu/vt-d: Cache PCI ATS state and Invalidate Queue Depth (Bjorn Helgaas) Move MPS configuration check to pci_configure_device() (Bjorn Helgaas) Set MPS to match upstream bridge (Keith Busch) ARM/PCI: Set MPS before pci_bus_add_devices() (Murali Karicheri) Add pci_scan_root_bus_msi() (Lorenzo Pieralisi) ARM/PCI, designware, xilinx: Use pci_scan_root_bus_msi() (Lorenzo Pieralisi) Resource management Call pci_read_bridge_bases() from core instead of arch code (Lorenzo Pieralisi) PCI device hotplug pciehp: Remove unused interrupt events (Bjorn Helgaas) pciehp: Remove ignored MRL sensor interrupt events (Bjorn Helgaas) pciehp: Handle invalid data when reading from non-existent devices (Jarod Wilson) pciehp: Simplify pcie_poll_cmd() (Yijing Wang) Use "slot" and "pci_slot" for struct hotplug_slot and struct pci_slot (Yijing Wang) Protect pci_bus->slots with pci_slot_mutex, not pci_bus_sem (Yijing Wang) Hold pci_slot_mutex while searching bus->slots list (Yijing Wang) Power management Disable async suspend/resume for JMicron multi-function SATA/AHCI (Zhang Rui) Virtualization Add ACS quirks for Intel I219-LM/V (Alex Williamson) Restore ACS configuration as part of pci_restore_state() (Alexander Duyck) MSI Add pcibios_alloc_irq() and pcibios_free_irq() (Jiang Liu) x86: Implement pcibios_alloc_irq() and pcibios_free_irq() (Jiang Liu) Add helpers to manage pci_dev->irq and pci_dev->irq_managed (Jiang Liu) Free legacy IRQ when enabling MSI/MSI-X (Jiang Liu) ARM/PCI: Remove msi_controller from struct pci_sys_data (Lorenzo Pieralisi) Remove unused pcibios_msi_controller() hook (Lorenzo Pieralisi) Generic host bridge driver Remove dependency on ARM-specific struct hw_pci (Jayachandran C) Build setup-irq.o for arm64 (Jayachandran C) Add arm64 support (Jayachandran C) APM X-Gene host bridge driver Add APM X-Gene PCIe 64-bit prefetchable window (Duc Dang) Add support for a 64-bit prefetchable memory window (Duc Dang) Drop owner assignment from platform_driver (Krzysztof Kozlowski) Broadcom iProc host bridge driver Allow BCMA bus driver to be built as module (Hauke Mehrtens) Delete unnecessary checks before phy calls (Markus Elfring) Add arm64 support (Ray Jui) Synopsys DesignWare host bridge driver Don't complain missing *config* reg space if va_cfg0 is set (Murali Karicheri) TI DRA7xx host bridge driver Disable pm_runtime on get_sync failure (Kishon Vijay Abraham I) Add PM support (Kishon Vijay Abraham I) Clear MSE bit during suspend so clocks will idle (Kishon Vijay Abraham I) Add support to make GPIO drive PERST# line (Kishon Vijay Abraham I) Xilinx AXI host bridge driver Check for MSI interrupt flag before handling as INTx (Russell Joyce) Miscellaneous Fix Intersil/Techwell TW686[4589] AV capture class code (Krzysztof Hałasa) Use PCI_CLASS_SERIAL_USB instead of bare number (Bjorn Helgaas) Fix generic NCR 53c810 class code quirk (Bjorn Helgaas) Fix TI816X class code quirk (Bjorn Helgaas) Remove unused "pci_probe" flags (Bjorn Helgaas) Host bridge driver code simplifications (Fabio Estevam) Add dev_flags bit to access VPD through function 0 (Mark Rustad) Add VPD function 0 quirk for Intel Ethernet devices (Mark Rustad) Kill off set_irq_flags() usage (Rob Herring) Remove Intel Cherrytrail D3 delays (Srinidhi Kasagar) Clean up pci_find_capability() (Wei Yang) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJV5FE/AAoJEFmIoMA60/r8I2QP/R9b9MrvH2i9tN98/lTDl7g3 czE58ZM1d4kMYtW3Pm/DrYI6y6RprAaB4ZEp5rHxlFLqBPZEQwWodA19NkjECcb6 g5qKWOdIWA4T6Jaab6a/yCmAFa0jni7iAmmTYqca9o3Xj7tFovxDxqPSYkh+rer0 v+1sAr/4HXSiN339KR6teEF3VZqLFp6ewMydQlVS+R7kAOHHYQDqoo9WF6JnIoL5 PO3Kbmr1WN3fZY3s98yLq1x6XmLrLlmGdJI+2r+KewO4r/05CL6wTVP/oTMi+Eti dueseeISlOTcTAUhk87Vap23uJPeB/rJbYoFdCr7+0AkZGe/U/E2dpZm2wyMcCvq OrATuFymgzIuJm5uUPsdH4lzsX97U9BcDccracfC38rYnP5u3bqHCjw8HJzANR7p VYbFBzc5ZCCUYtQAjyrKt2820AvTFo+Bu+z75IsJO8LQQgv/zGtQQ8grIQeAjH+l sAe3xOTwzZnq6Obl4qb/GElHmIGUbQ1X4Dx1mliiijKMKkhYHOA0iFnB/OBILmEZ wHzKU8chWcI9lip0aaX8q9i/qovdVUt2+rdo/N40l7YY66x4jkNgQQXZX+FSKk6H stTvEBQgK28EKCHDxMsgzTGIqllSyk4DnRMA7ij1hRWqdUbGk7wOPTvm9QSwNDWe SokuWzAQD9YeMRGdsYjZ =DX1r -----END PGP SIGNATURE----- Merge tag 'pci-v4.3-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI updates from Bjorn Helgaas: "PCI changes for the v4.3 merge window: Enumeration: - Allocate ATS struct during enumeration (Bjorn Helgaas) - Embed ATS info directly into struct pci_dev (Bjorn Helgaas) - Reduce size of ATS structure elements (Bjorn Helgaas) - Stop caching ATS Invalidate Queue Depth (Bjorn Helgaas) - iommu/vt-d: Cache PCI ATS state and Invalidate Queue Depth (Bjorn Helgaas) - Move MPS configuration check to pci_configure_device() (Bjorn Helgaas) - Set MPS to match upstream bridge (Keith Busch) - ARM/PCI: Set MPS before pci_bus_add_devices() (Murali Karicheri) - Add pci_scan_root_bus_msi() (Lorenzo Pieralisi) - ARM/PCI, designware, xilinx: Use pci_scan_root_bus_msi() (Lorenzo Pieralisi) Resource management: - Call pci_read_bridge_bases() from core instead of arch code (Lorenzo Pieralisi) PCI device hotplug: - pciehp: Remove unused interrupt events (Bjorn Helgaas) - pciehp: Remove ignored MRL sensor interrupt events (Bjorn Helgaas) - pciehp: Handle invalid data when reading from non-existent devices (Jarod Wilson) - pciehp: Simplify pcie_poll_cmd() (Yijing Wang) - Use "slot" and "pci_slot" for struct hotplug_slot and struct pci_slot (Yijing Wang) - Protect pci_bus->slots with pci_slot_mutex, not pci_bus_sem (Yijing Wang) - Hold pci_slot_mutex while searching bus->slots list (Yijing Wang) Power management: - Disable async suspend/resume for JMicron multi-function SATA/AHCI (Zhang Rui) Virtualization: - Add ACS quirks for Intel I219-LM/V (Alex Williamson) - Restore ACS configuration as part of pci_restore_state() (Alexander Duyck) MSI: - Add pcibios_alloc_irq() and pcibios_free_irq() (Jiang Liu) - x86: Implement pcibios_alloc_irq() and pcibios_free_irq() (Jiang Liu) - Add helpers to manage pci_dev->irq and pci_dev->irq_managed (Jiang Liu) - Free legacy IRQ when enabling MSI/MSI-X (Jiang Liu) - ARM/PCI: Remove msi_controller from struct pci_sys_data (Lorenzo Pieralisi) - Remove unused pcibios_msi_controller() hook (Lorenzo Pieralisi) Generic host bridge driver: - Remove dependency on ARM-specific struct hw_pci (Jayachandran C) - Build setup-irq.o for arm64 (Jayachandran C) - Add arm64 support (Jayachandran C) APM X-Gene host bridge driver: - Add APM X-Gene PCIe 64-bit prefetchable window (Duc Dang) - Add support for a 64-bit prefetchable memory window (Duc Dang) - Drop owner assignment from platform_driver (Krzysztof Kozlowski) Broadcom iProc host bridge driver: - Allow BCMA bus driver to be built as module (Hauke Mehrtens) - Delete unnecessary checks before phy calls (Markus Elfring) - Add arm64 support (Ray Jui) Synopsys DesignWare host bridge driver: - Don't complain missing *config* reg space if va_cfg0 is set (Murali Karicheri) TI DRA7xx host bridge driver: - Disable pm_runtime on get_sync failure (Kishon Vijay Abraham I) - Add PM support (Kishon Vijay Abraham I) - Clear MSE bit during suspend so clocks will idle (Kishon Vijay Abraham I) - Add support to make GPIO drive PERST# line (Kishon Vijay Abraham I) Xilinx AXI host bridge driver: - Check for MSI interrupt flag before handling as INTx (Russell Joyce) Miscellaneous: - Fix Intersil/Techwell TW686[4589] AV capture class code (Krzysztof Hałasa) - Use PCI_CLASS_SERIAL_USB instead of bare number (Bjorn Helgaas) - Fix generic NCR 53c810 class code quirk (Bjorn Helgaas) - Fix TI816X class code quirk (Bjorn Helgaas) - Remove unused "pci_probe" flags (Bjorn Helgaas) - Host bridge driver code simplifications (Fabio Estevam) - Add dev_flags bit to access VPD through function 0 (Mark Rustad) - Add VPD function 0 quirk for Intel Ethernet devices (Mark Rustad) - Kill off set_irq_flags() usage (Rob Herring) - Remove Intel Cherrytrail D3 delays (Srinidhi Kasagar) - Clean up pci_find_capability() (Wei Yang)" * tag 'pci-v4.3-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (72 commits) PCI: Disable async suspend/resume for JMicron multi-function SATA/AHCI PCI: Set MPS to match upstream bridge PCI: Move MPS configuration check to pci_configure_device() PCI: Drop references acquired by of_parse_phandle() PCI/MSI: Remove unused pcibios_msi_controller() hook ARM/PCI: Remove msi_controller from struct pci_sys_data ARM/PCI, designware, xilinx: Use pci_scan_root_bus_msi() PCI: Add pci_scan_root_bus_msi() ARM/PCI: Replace panic with WARN messages on failures PCI: generic: Add arm64 support PCI: Build setup-irq.o for arm64 PCI: generic: Remove dependency on ARM-specific struct hw_pci PCI: imx6: Simplify a trivial if-return sequence PCI: spear: Use BUG_ON() instead of condition followed by BUG() PCI: dra7xx: Remove unneeded use of IS_ERR_VALUE() PCI: Remove pci_ats_enabled() PCI: Stop caching ATS Invalidate Queue Depth PCI: Move ATS declarations to linux/pci.h so they're all together PCI: Clean up ATS error handling PCI: Use pci_physfn() rather than looking up physfn by hand ...
This commit is contained in:
commit
26f8b7edc9
|
@ -23,6 +23,9 @@ PCIe Designware Controller
|
|||
interrupt-map-mask,
|
||||
interrupt-map : as specified in ../designware-pcie.txt
|
||||
|
||||
Optional Property:
|
||||
- gpios : Should be added if a gpio line is required to drive PERST# line
|
||||
|
||||
Example:
|
||||
axi {
|
||||
compatible = "simple-bus";
|
||||
|
|
|
@ -242,12 +242,7 @@ pci_restore_srm_config(void)
|
|||
|
||||
void pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev = bus->self;
|
||||
|
||||
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
pci_read_bridge_bases(bus);
|
||||
}
|
||||
struct pci_dev *dev;
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pdev_save_srm_config(dev);
|
||||
|
|
|
@ -693,3 +693,7 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pcie1 {
|
||||
gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
|
|
@ -211,7 +211,7 @@
|
|||
#address-cells = <1>;
|
||||
ranges = <0x51000000 0x51000000 0x3000
|
||||
0x0 0x20000000 0x10000000>;
|
||||
pcie@51000000 {
|
||||
pcie1: pcie@51000000 {
|
||||
compatible = "ti,dra7-pcie";
|
||||
reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>;
|
||||
reg-names = "rc_dbics", "ti_conf", "config";
|
||||
|
|
|
@ -19,9 +19,7 @@ struct pci_bus;
|
|||
struct device;
|
||||
|
||||
struct hw_pci {
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
struct msi_controller *msi_ctrl;
|
||||
#endif
|
||||
struct pci_ops *ops;
|
||||
int nr_controllers;
|
||||
void **private_data;
|
||||
|
@ -42,9 +40,6 @@ struct hw_pci {
|
|||
* Per-controller structure
|
||||
*/
|
||||
struct pci_sys_data {
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
struct msi_controller *msi_ctrl;
|
||||
#endif
|
||||
struct list_head node;
|
||||
int busnr; /* primary bus number */
|
||||
u64 mem_offset; /* bus->cpu memory mapping offset */
|
||||
|
|
|
@ -18,15 +18,6 @@
|
|||
|
||||
static int debug_pci;
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_sys_data *sysdata = dev->bus->sysdata;
|
||||
|
||||
return sysdata->msi_ctrl;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We can't use pci_get_device() here since we are
|
||||
* called from interrupt context.
|
||||
|
@ -459,12 +450,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
|
|||
|
||||
for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
|
||||
sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
|
||||
if (!sys)
|
||||
panic("PCI: unable to allocate sys data!");
|
||||
if (WARN(!sys, "PCI: unable to allocate sys data!"))
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
sys->msi_ctrl = hw->msi_ctrl;
|
||||
#endif
|
||||
sys->busnr = busnr;
|
||||
sys->swizzle = hw->swizzle;
|
||||
sys->map_irq = hw->map_irq;
|
||||
|
@ -486,11 +474,14 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
|
|||
if (hw->scan)
|
||||
sys->bus = hw->scan(nr, sys);
|
||||
else
|
||||
sys->bus = pci_scan_root_bus(parent, sys->busnr,
|
||||
hw->ops, sys, &sys->resources);
|
||||
sys->bus = pci_scan_root_bus_msi(parent,
|
||||
sys->busnr, hw->ops, sys,
|
||||
&sys->resources, hw->msi_ctrl);
|
||||
|
||||
if (!sys->bus)
|
||||
panic("PCI: unable to scan bus!");
|
||||
if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
|
||||
kfree(sys);
|
||||
break;
|
||||
}
|
||||
|
||||
busnr = sys->bus->busn_res.end + 1;
|
||||
|
||||
|
@ -521,6 +512,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
|
|||
struct pci_bus *bus = sys->bus;
|
||||
|
||||
if (!pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
struct pci_bus *child;
|
||||
|
||||
/*
|
||||
* Size the bridge windows.
|
||||
*/
|
||||
|
@ -530,24 +523,14 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
|
|||
* Assign resources.
|
||||
*/
|
||||
pci_bus_assign_resources(bus);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell drivers about devices found.
|
||||
*/
|
||||
pci_bus_add_devices(bus);
|
||||
}
|
||||
|
||||
list_for_each_entry(sys, &head, node) {
|
||||
struct pci_bus *bus = sys->bus;
|
||||
|
||||
/* Configure PCI Express settings */
|
||||
if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
struct pci_bus *child;
|
||||
|
||||
list_for_each_entry(child, &bus->children, node)
|
||||
pcie_bus_configure_settings(child);
|
||||
}
|
||||
/*
|
||||
* Tell drivers about devices found.
|
||||
*/
|
||||
pci_bus_add_devices(bus);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -490,7 +490,8 @@
|
|||
0xe0 0xd0000000 0x0 0x00040000>; /* PCI config space */
|
||||
reg-names = "csr", "cfg";
|
||||
ranges = <0x01000000 0x00 0x00000000 0xe0 0x10000000 0x00 0x00010000 /* io */
|
||||
0x02000000 0x00 0x80000000 0xe1 0x80000000 0x00 0x80000000>; /* mem */
|
||||
0x02000000 0x00 0x80000000 0xe1 0x80000000 0x00 0x80000000 /* mem */
|
||||
0x43000000 0xf0 0x00000000 0xf0 0x00000000 0x10 0x00000000>; /* mem */
|
||||
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
|
||||
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
|
@ -513,8 +514,9 @@
|
|||
reg = < 0x00 0x1f2c0000 0x0 0x00010000 /* Controller registers */
|
||||
0xd0 0xd0000000 0x0 0x00040000>; /* PCI config space */
|
||||
reg-names = "csr", "cfg";
|
||||
ranges = <0x01000000 0x0 0x00000000 0xd0 0x10000000 0x00 0x00010000 /* io */
|
||||
0x02000000 0x0 0x80000000 0xd1 0x80000000 0x00 0x80000000>; /* mem */
|
||||
ranges = <0x01000000 0x00 0x00000000 0xd0 0x10000000 0x00 0x00010000 /* io */
|
||||
0x02000000 0x00 0x80000000 0xd1 0x80000000 0x00 0x80000000 /* mem */
|
||||
0x43000000 0xd8 0x00000000 0xd8 0x00000000 0x08 0x00000000>; /* mem */
|
||||
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
|
||||
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
|
@ -537,8 +539,9 @@
|
|||
reg = < 0x00 0x1f2d0000 0x0 0x00010000 /* Controller registers */
|
||||
0x90 0xd0000000 0x0 0x00040000>; /* PCI config space */
|
||||
reg-names = "csr", "cfg";
|
||||
ranges = <0x01000000 0x0 0x00000000 0x90 0x10000000 0x0 0x00010000 /* io */
|
||||
0x02000000 0x0 0x80000000 0x91 0x80000000 0x0 0x80000000>; /* mem */
|
||||
ranges = <0x01000000 0x00 0x00000000 0x90 0x10000000 0x00 0x00010000 /* io */
|
||||
0x02000000 0x00 0x80000000 0x91 0x80000000 0x00 0x80000000 /* mem */
|
||||
0x43000000 0x94 0x00000000 0x94 0x00000000 0x04 0x00000000>; /* mem */
|
||||
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
|
||||
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
|
@ -561,8 +564,9 @@
|
|||
reg = < 0x00 0x1f500000 0x0 0x00010000 /* Controller registers */
|
||||
0xa0 0xd0000000 0x0 0x00040000>; /* PCI config space */
|
||||
reg-names = "csr", "cfg";
|
||||
ranges = <0x01000000 0x0 0x00000000 0xa0 0x10000000 0x0 0x00010000 /* io */
|
||||
0x02000000 0x0 0x80000000 0xa1 0x80000000 0x0 0x80000000>; /* mem */
|
||||
ranges = <0x01000000 0x00 0x00000000 0xa0 0x10000000 0x00 0x00010000 /* io */
|
||||
0x02000000 0x00 0x80000000 0xa1 0x80000000 0x00 0x80000000 /* mem */
|
||||
0x43000000 0xb0 0x00000000 0xb0 0x00000000 0x10 0x00000000>; /* mem */
|
||||
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
|
||||
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
|
@ -585,8 +589,9 @@
|
|||
reg = < 0x00 0x1f510000 0x0 0x00010000 /* Controller registers */
|
||||
0xc0 0xd0000000 0x0 0x00200000>; /* PCI config space */
|
||||
reg-names = "csr", "cfg";
|
||||
ranges = <0x01000000 0x0 0x00000000 0xc0 0x10000000 0x0 0x00010000 /* io */
|
||||
0x02000000 0x0 0x80000000 0xc1 0x80000000 0x0 0x80000000>; /* mem */
|
||||
ranges = <0x01000000 0x00 0x00000000 0xc0 0x10000000 0x00 0x00010000 /* io */
|
||||
0x02000000 0x00 0x80000000 0xc1 0x80000000 0x00 0x80000000 /* mem */
|
||||
0x43000000 0xc8 0x00000000 0xc8 0x00000000 0x08 0x00000000>; /* mem */
|
||||
dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
|
||||
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
|
||||
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
|
||||
|
|
|
@ -175,14 +175,6 @@ static void __init pcibios_assign_resources(void)
|
|||
if (!r->start && r->end)
|
||||
pci_assign_resource(dev, idx);
|
||||
}
|
||||
|
||||
if (pci_probe & PCI_ASSIGN_ROMS) {
|
||||
r = &dev->resource[PCI_ROM_RESOURCE];
|
||||
r->end -= r->start;
|
||||
r->start = 0;
|
||||
if (r->end)
|
||||
pci_assign_resource(dev, PCI_ROM_RESOURCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,6 @@
|
|||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define PCI_PROBE_BIOS 0x0001
|
||||
#define PCI_PROBE_CONF1 0x0002
|
||||
#define PCI_PROBE_CONF2 0x0004
|
||||
#define PCI_NO_CHECKS 0x0400
|
||||
#define PCI_ASSIGN_ROMS 0x1000
|
||||
#define PCI_BIOS_IRQ_SCAN 0x2000
|
||||
#define PCI_ASSIGN_ALL_BUSSES 0x4000
|
||||
|
||||
extern unsigned int __nongpreldata pci_probe;
|
||||
|
||||
/* pci-frv.c */
|
||||
|
|
|
@ -294,8 +294,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
|
||||
#endif
|
||||
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
if (bus->number == 0) {
|
||||
struct pci_dev *dev;
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
|
|
|
@ -533,10 +533,9 @@ void pcibios_fixup_bus(struct pci_bus *b)
|
|||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
if (b->self) {
|
||||
pci_read_bridge_bases(b);
|
||||
if (b->self)
|
||||
pcibios_fixup_bridge_resources(b->self);
|
||||
}
|
||||
|
||||
list_for_each_entry(dev, &b->devices, bus_list)
|
||||
pcibios_fixup_device_resources(dev);
|
||||
platform_pci_fixup_bus(b);
|
||||
|
|
|
@ -863,14 +863,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
|
|||
|
||||
void pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
/* When called from the generic PCI probe, read PCI<->PCI bridge
|
||||
* bases. This is -not- called when generating the PCI tree from
|
||||
* the OF device-tree.
|
||||
*/
|
||||
if (bus->self != NULL)
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
/* Now fixup the bus bus */
|
||||
/* Fixup the bus */
|
||||
pcibios_setup_bus_self(bus);
|
||||
|
||||
/* Now fixup devices on that bus */
|
||||
|
|
|
@ -311,12 +311,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
|
|||
|
||||
void pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev = bus->self;
|
||||
|
||||
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
|
||||
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
|
||||
pci_read_bridge_bases(bus);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(PCIBIOS_MIN_IO);
|
||||
|
|
|
@ -183,18 +183,16 @@ static int __init pcibios_assign_resources(void)
|
|||
struct pci_dev *dev = NULL;
|
||||
struct resource *r;
|
||||
|
||||
if (!(pci_probe & PCI_ASSIGN_ROMS)) {
|
||||
/* Try to use BIOS settings for ROMs, otherwise let
|
||||
pci_assign_unassigned_resources() allocate the new
|
||||
addresses. */
|
||||
for_each_pci_dev(dev) {
|
||||
r = &dev->resource[PCI_ROM_RESOURCE];
|
||||
if (!r->flags || !r->start)
|
||||
continue;
|
||||
if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) {
|
||||
r->end -= r->start;
|
||||
r->start = 0;
|
||||
}
|
||||
/* Try to use BIOS settings for ROMs, otherwise let
|
||||
pci_assign_unassigned_resources() allocate the new
|
||||
addresses. */
|
||||
for_each_pci_dev(dev) {
|
||||
r = &dev->resource[PCI_ROM_RESOURCE];
|
||||
if (!r->flags || !r->start)
|
||||
continue;
|
||||
if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) {
|
||||
r->end -= r->start;
|
||||
r->start = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,6 @@
|
|||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define PCI_PROBE_BIOS 1
|
||||
#define PCI_PROBE_CONF1 2
|
||||
#define PCI_PROBE_CONF2 4
|
||||
#define PCI_NO_CHECKS 0x400
|
||||
#define PCI_ASSIGN_ROMS 0x1000
|
||||
#define PCI_BIOS_IRQ_SCAN 0x2000
|
||||
|
||||
extern unsigned int pci_probe;
|
||||
|
||||
/* pci-asb2305.c */
|
||||
|
|
|
@ -324,7 +324,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
|
|||
struct pci_dev *dev;
|
||||
|
||||
if (bus->self) {
|
||||
pci_read_bridge_bases(bus);
|
||||
pcibios_fixup_bridge_resources(bus->self);
|
||||
}
|
||||
|
||||
|
|
|
@ -1044,13 +1044,7 @@ void pcibios_set_master(struct pci_dev *dev)
|
|||
|
||||
void pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
/* When called from the generic PCI probe, read PCI<->PCI bridge
|
||||
* bases. This is -not- called when generating the PCI tree from
|
||||
* the OF device-tree.
|
||||
*/
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
/* Now fixup the bus bus */
|
||||
/* Fixup the bus */
|
||||
pcibios_setup_bus_self(bus);
|
||||
|
||||
/* Now fixup devices on that bus */
|
||||
|
|
|
@ -126,7 +126,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
|
|||
{
|
||||
struct pci_dev *dev;
|
||||
const char *type;
|
||||
struct pci_slot *slot;
|
||||
|
||||
dev = pci_alloc_dev(bus);
|
||||
if (!dev)
|
||||
|
@ -145,10 +144,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
|
|||
dev->needs_freset = 0; /* pcie fundamental reset required */
|
||||
set_pcie_port_type(dev);
|
||||
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
|
||||
pci_dev_assign_slot(dev);
|
||||
dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
|
||||
dev->device = get_int_prop(node, "device-id", 0xffff);
|
||||
dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
|
||||
|
|
|
@ -11,14 +11,6 @@
|
|||
|
||||
#include <asm/io.h>
|
||||
|
||||
/* startup values */
|
||||
#define PCI_PROBE_BIOS 1
|
||||
#define PCI_PROBE_CONF1 2
|
||||
#define PCI_PROBE_CONF2 4
|
||||
#define PCI_NO_CHECKS 0x400
|
||||
#define PCI_ASSIGN_ROMS 0x1000
|
||||
#define PCI_BIOS_IRQ_SCAN 0x2000
|
||||
|
||||
#define SH4_PCICR 0x100 /* PCI Control Register */
|
||||
#define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
|
||||
#define SH4_PCICR_FTO 0x00000400 /* TRDY/IRDY Enable */
|
||||
|
|
|
@ -249,7 +249,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
|
|||
struct pci_bus *bus, int devfn)
|
||||
{
|
||||
struct dev_archdata *sd;
|
||||
struct pci_slot *slot;
|
||||
struct platform_device *op;
|
||||
struct pci_dev *dev;
|
||||
const char *type;
|
||||
|
@ -290,10 +289,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
|
|||
dev->multifunction = 0; /* maybe a lie? */
|
||||
set_pcie_port_type(dev);
|
||||
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
|
||||
pci_dev_assign_slot(dev);
|
||||
dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
|
||||
dev->device = of_getintprop_default(node, "device-id", 0xffff);
|
||||
dev->subsystem_vendor =
|
||||
|
|
|
@ -93,8 +93,6 @@ extern raw_spinlock_t pci_config_lock;
|
|||
extern int (*pcibios_enable_irq)(struct pci_dev *dev);
|
||||
extern void (*pcibios_disable_irq)(struct pci_dev *dev);
|
||||
|
||||
extern bool mp_should_keep_irq(struct device *dev);
|
||||
|
||||
struct pci_raw_ops {
|
||||
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
|
||||
int reg, int len, u32 *val);
|
||||
|
|
|
@ -166,7 +166,6 @@ void pcibios_fixup_bus(struct pci_bus *b)
|
|||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
pci_read_bridge_bases(b);
|
||||
list_for_each_entry(dev, &b->devices, bus_list)
|
||||
pcibios_fixup_device_resources(dev);
|
||||
}
|
||||
|
@ -673,24 +672,22 @@ int pcibios_add_device(struct pci_dev *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
int pcibios_alloc_irq(struct pci_dev *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = pci_enable_resources(dev, mask)) < 0)
|
||||
return err;
|
||||
|
||||
if (!pci_dev_msi_enabled(dev))
|
||||
return pcibios_enable_irq(dev);
|
||||
return 0;
|
||||
return pcibios_enable_irq(dev);
|
||||
}
|
||||
|
||||
void pcibios_disable_device (struct pci_dev *dev)
|
||||
void pcibios_free_irq(struct pci_dev *dev)
|
||||
{
|
||||
if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
|
||||
if (pcibios_disable_irq)
|
||||
pcibios_disable_irq(dev);
|
||||
}
|
||||
|
||||
int pcibios_enable_device(struct pci_dev *dev, int mask)
|
||||
{
|
||||
return pci_enable_resources(dev, mask);
|
||||
}
|
||||
|
||||
int pci_ext_cfg_avail(void)
|
||||
{
|
||||
if (raw_pci_ext_ops)
|
||||
|
|
|
@ -62,19 +62,6 @@ static void pci_fixup_umc_ide(struct pci_dev *d)
|
|||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide);
|
||||
|
||||
static void pci_fixup_ncr53c810(struct pci_dev *d)
|
||||
{
|
||||
/*
|
||||
* NCR 53C810 returns class code 0 (at least on some systems).
|
||||
* Fix class to be PCI_CLASS_STORAGE_SCSI
|
||||
*/
|
||||
if (!d->class) {
|
||||
dev_warn(&d->dev, "Fixing NCR 53C810 class code\n");
|
||||
d->class = PCI_CLASS_STORAGE_SCSI << 8;
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810);
|
||||
|
||||
static void pci_fixup_latency(struct pci_dev *d)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -211,7 +211,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
|
|||
struct irq_alloc_info info;
|
||||
int polarity;
|
||||
|
||||
if (dev->irq_managed && dev->irq > 0)
|
||||
if (pci_has_managed_irq(dev))
|
||||
return 0;
|
||||
|
||||
if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER)
|
||||
|
@ -234,10 +234,13 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
|
|||
|
||||
static void intel_mid_pci_irq_disable(struct pci_dev *dev)
|
||||
{
|
||||
if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
|
||||
dev->irq > 0) {
|
||||
if (pci_has_managed_irq(dev)) {
|
||||
mp_unmap_irq(dev->irq);
|
||||
dev->irq_managed = 0;
|
||||
/*
|
||||
* Don't reset dev->irq here, otherwise
|
||||
* intel_mid_pci_irq_enable() will fail on next call.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1202,7 +1202,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
|||
struct pci_dev *temp_dev;
|
||||
int irq;
|
||||
|
||||
if (dev->irq_managed && dev->irq > 0)
|
||||
if (pci_has_managed_irq(dev))
|
||||
return 0;
|
||||
|
||||
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
|
||||
|
@ -1230,8 +1230,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
|||
}
|
||||
dev = temp_dev;
|
||||
if (irq >= 0) {
|
||||
dev->irq_managed = 1;
|
||||
dev->irq = irq;
|
||||
pci_set_managed_irq(dev, irq);
|
||||
dev_info(&dev->dev, "PCI->APIC IRQ transform: "
|
||||
"INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
|
||||
return 0;
|
||||
|
@ -1257,24 +1256,10 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool mp_should_keep_irq(struct device *dev)
|
||||
{
|
||||
if (dev->power.is_prepared)
|
||||
return true;
|
||||
#ifdef CONFIG_PM
|
||||
if (dev->power.runtime_status == RPM_SUSPENDING)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void pirq_disable_irq(struct pci_dev *dev)
|
||||
{
|
||||
if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
|
||||
dev->irq_managed && dev->irq) {
|
||||
if (io_apic_assign_pci_irqs && pci_has_managed_irq(dev)) {
|
||||
mp_unmap_irq(dev->irq);
|
||||
dev->irq = 0;
|
||||
dev->irq_managed = 0;
|
||||
pci_reset_managed_irq(dev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,10 +210,6 @@ subsys_initcall(pcibios_init);
|
|||
|
||||
void pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
if (bus->parent) {
|
||||
/* This is a subordinate bridge */
|
||||
pci_read_bridge_bases(bus);
|
||||
}
|
||||
}
|
||||
|
||||
void pcibios_set_master(struct pci_dev *dev)
|
||||
|
|
|
@ -412,7 +412,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (dev->irq_managed && dev->irq > 0)
|
||||
if (pci_has_managed_irq(dev))
|
||||
return 0;
|
||||
|
||||
entry = acpi_pci_irq_lookup(dev, pin);
|
||||
|
@ -457,8 +457,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
|
|||
kfree(entry);
|
||||
return rc;
|
||||
}
|
||||
dev->irq = rc;
|
||||
dev->irq_managed = 1;
|
||||
pci_set_managed_irq(dev, rc);
|
||||
|
||||
if (link)
|
||||
snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
|
||||
|
@ -481,17 +480,9 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
|
|||
u8 pin;
|
||||
|
||||
pin = dev->pin;
|
||||
if (!pin || !dev->irq_managed || dev->irq <= 0)
|
||||
if (!pin || !pci_has_managed_irq(dev))
|
||||
return;
|
||||
|
||||
/* Keep IOAPIC pin configuration when suspending */
|
||||
if (dev->dev.power.is_prepared)
|
||||
return;
|
||||
#ifdef CONFIG_PM
|
||||
if (dev->dev.power.runtime_status == RPM_SUSPENDING)
|
||||
return;
|
||||
#endif
|
||||
|
||||
entry = acpi_pci_irq_lookup(dev, pin);
|
||||
if (!entry)
|
||||
return;
|
||||
|
@ -511,6 +502,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
|
|||
dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
|
||||
if (gsi >= 0) {
|
||||
acpi_unregister_gsi(gsi);
|
||||
dev->irq_managed = 0;
|
||||
pci_reset_managed_irq(dev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -351,6 +351,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
|
|||
/* JMicron 362B and 362C have an AHCI function with IDE class code */
|
||||
{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
|
||||
{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
|
||||
/* May need to update quirk_jmicron_async_suspend() for additions */
|
||||
|
||||
/* ATI */
|
||||
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
|
||||
|
@ -1451,18 +1452,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
else if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
|
||||
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
|
||||
|
||||
/*
|
||||
* The JMicron chip 361/363 contains one SATA controller and one
|
||||
* PATA controller,for powering on these both controllers, we must
|
||||
* follow the sequence one by one, otherwise one of them can not be
|
||||
* powered on successfully, so here we disable the async suspend
|
||||
* method for these chips.
|
||||
*/
|
||||
if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
|
||||
(pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
|
||||
pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
|
||||
device_disable_async_suspend(&pdev->dev);
|
||||
|
||||
/* acquire resources */
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc)
|
||||
|
|
|
@ -143,18 +143,6 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
|
|||
};
|
||||
const struct ata_port_info *ppi[] = { &info, NULL };
|
||||
|
||||
/*
|
||||
* The JMicron chip 361/363 contains one SATA controller and one
|
||||
* PATA controller,for powering on these both controllers, we must
|
||||
* follow the sequence one by one, otherwise one of them can not be
|
||||
* powered on successfully, so here we disable the async suspend
|
||||
* method for these chips.
|
||||
*/
|
||||
if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
|
||||
(pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
|
||||
pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
|
||||
device_disable_async_suspend(&pdev->dev);
|
||||
|
||||
return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -408,6 +408,10 @@ struct device_domain_info {
|
|||
struct list_head global; /* link to global list */
|
||||
u8 bus; /* PCI bus number */
|
||||
u8 devfn; /* PCI devfn number */
|
||||
struct {
|
||||
u8 enabled:1;
|
||||
u8 qdep;
|
||||
} ats; /* ATS state */
|
||||
struct device *dev; /* it's NULL for PCIe-to-PCI bridge */
|
||||
struct intel_iommu *iommu; /* IOMMU used by this device */
|
||||
struct dmar_domain *domain; /* pointer to domain */
|
||||
|
@ -1391,19 +1395,26 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu,
|
|||
|
||||
static void iommu_enable_dev_iotlb(struct device_domain_info *info)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (!info || !dev_is_pci(info->dev))
|
||||
return;
|
||||
|
||||
pci_enable_ats(to_pci_dev(info->dev), VTD_PAGE_SHIFT);
|
||||
pdev = to_pci_dev(info->dev);
|
||||
if (pci_enable_ats(pdev, VTD_PAGE_SHIFT))
|
||||
return;
|
||||
|
||||
info->ats.enabled = 1;
|
||||
info->ats.qdep = pci_ats_queue_depth(pdev);
|
||||
}
|
||||
|
||||
static void iommu_disable_dev_iotlb(struct device_domain_info *info)
|
||||
{
|
||||
if (!info->dev || !dev_is_pci(info->dev) ||
|
||||
!pci_ats_enabled(to_pci_dev(info->dev)))
|
||||
if (!info->ats.enabled)
|
||||
return;
|
||||
|
||||
pci_disable_ats(to_pci_dev(info->dev));
|
||||
info->ats.enabled = 0;
|
||||
}
|
||||
|
||||
static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
|
||||
|
@ -1415,16 +1426,11 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
|
|||
|
||||
spin_lock_irqsave(&device_domain_lock, flags);
|
||||
list_for_each_entry(info, &domain->devices, link) {
|
||||
struct pci_dev *pdev;
|
||||
if (!info->dev || !dev_is_pci(info->dev))
|
||||
continue;
|
||||
|
||||
pdev = to_pci_dev(info->dev);
|
||||
if (!pci_ats_enabled(pdev))
|
||||
if (!info->ats.enabled)
|
||||
continue;
|
||||
|
||||
sid = info->bus << 8 | info->devfn;
|
||||
qdep = pci_ats_queue_depth(pdev);
|
||||
qdep = info->ats.qdep;
|
||||
qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
|
||||
}
|
||||
spin_unlock_irqrestore(&device_domain_lock, flags);
|
||||
|
@ -2275,6 +2281,8 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
|
|||
|
||||
info->bus = bus;
|
||||
info->devfn = devfn;
|
||||
info->ats.enabled = 0;
|
||||
info->ats.qdep = 0;
|
||||
info->dev = dev;
|
||||
info->domain = domain;
|
||||
info->iommu = iommu;
|
||||
|
|
|
@ -560,9 +560,6 @@ dino_fixup_bus(struct pci_bus *bus)
|
|||
} else if (bus->parent) {
|
||||
int i;
|
||||
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
|
||||
for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
|
||||
if((bus->self->resource[i].flags &
|
||||
(IORESOURCE_IO | IORESOURCE_MEM)) == 0)
|
||||
|
|
|
@ -693,7 +693,6 @@ lba_fixup_bus(struct pci_bus *bus)
|
|||
if (bus->parent) {
|
||||
int i;
|
||||
/* PCI-PCI Bridge */
|
||||
pci_read_bridge_bases(bus);
|
||||
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
|
||||
pci_claim_bridge_resource(bus->self, i);
|
||||
} else {
|
||||
|
|
|
@ -33,6 +33,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o
|
|||
#
|
||||
obj-$(CONFIG_ALPHA) += setup-irq.o
|
||||
obj-$(CONFIG_ARM) += setup-irq.o
|
||||
obj-$(CONFIG_ARM64) += setup-irq.o
|
||||
obj-$(CONFIG_UNICORE32) += setup-irq.o
|
||||
obj-$(CONFIG_SUPERH) += setup-irq.o
|
||||
obj-$(CONFIG_MIPS) += setup-irq.o
|
||||
|
|
|
@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {
|
|||
.release = pci_vpd_pci22_release,
|
||||
};
|
||||
|
||||
static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
|
||||
void *arg)
|
||||
{
|
||||
struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn));
|
||||
ssize_t ret;
|
||||
|
||||
if (!tdev)
|
||||
return -ENODEV;
|
||||
|
||||
ret = pci_read_vpd(tdev, pos, count, arg);
|
||||
pci_dev_put(tdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
|
||||
const void *arg)
|
||||
{
|
||||
struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn));
|
||||
ssize_t ret;
|
||||
|
||||
if (!tdev)
|
||||
return -ENODEV;
|
||||
|
||||
ret = pci_write_vpd(tdev, pos, count, arg);
|
||||
pci_dev_put(tdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pci_vpd_ops pci_vpd_f0_ops = {
|
||||
.read = pci_vpd_f0_read,
|
||||
.write = pci_vpd_f0_write,
|
||||
.release = pci_vpd_pci22_release,
|
||||
};
|
||||
|
||||
static int pci_vpd_f0_dev_check(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn));
|
||||
int ret = 0;
|
||||
|
||||
if (!tdev)
|
||||
return -ENODEV;
|
||||
if (!tdev->vpd || !tdev->multifunction ||
|
||||
dev->class != tdev->class || dev->vendor != tdev->vendor ||
|
||||
dev->device != tdev->device)
|
||||
ret = -ENODEV;
|
||||
|
||||
pci_dev_put(tdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pci_vpd_pci22_init(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_vpd_pci22 *vpd;
|
||||
|
@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
|
|||
cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
|
||||
if (!cap)
|
||||
return -ENODEV;
|
||||
if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) {
|
||||
int ret = pci_vpd_f0_dev_check(dev);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
|
||||
if (!vpd)
|
||||
return -ENOMEM;
|
||||
|
||||
vpd->base.len = PCI_VPD_PCI22_SIZE;
|
||||
vpd->base.ops = &pci_vpd_pci22_ops;
|
||||
if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0)
|
||||
vpd->base.ops = &pci_vpd_f0_ops;
|
||||
else
|
||||
vpd->base.ops = &pci_vpd_pci22_ops;
|
||||
mutex_init(&vpd->lock);
|
||||
vpd->cap = cap;
|
||||
vpd->busy = false;
|
||||
|
@ -531,6 +590,14 @@ static inline int pcie_cap_version(const struct pci_dev *dev)
|
|||
return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS;
|
||||
}
|
||||
|
||||
static bool pcie_downstream_port(const struct pci_dev *dev)
|
||||
{
|
||||
int type = pci_pcie_type(dev);
|
||||
|
||||
return type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
type == PCI_EXP_TYPE_DOWNSTREAM;
|
||||
}
|
||||
|
||||
bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
|
||||
{
|
||||
int type = pci_pcie_type(dev);
|
||||
|
@ -546,10 +613,7 @@ bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
|
|||
|
||||
static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
|
||||
{
|
||||
int type = pci_pcie_type(dev);
|
||||
|
||||
return (type == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
type == PCI_EXP_TYPE_DOWNSTREAM) &&
|
||||
return pcie_downstream_port(dev) &&
|
||||
pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT;
|
||||
}
|
||||
|
||||
|
@ -628,10 +692,9 @@ int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val)
|
|||
* State bit in the Slot Status register of Downstream Ports,
|
||||
* which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8)
|
||||
*/
|
||||
if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA &&
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
|
||||
if (pci_is_pcie(dev) && pcie_downstream_port(dev) &&
|
||||
pos == PCI_EXP_SLTSTA)
|
||||
*val = PCI_EXP_SLTSTA_PDS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -657,10 +720,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL &&
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) {
|
||||
if (pci_is_pcie(dev) && pcie_downstream_port(dev) &&
|
||||
pos == PCI_EXP_SLTSTA)
|
||||
*val = PCI_EXP_SLTSTA_PDS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,34 +17,15 @@
|
|||
|
||||
#include "pci.h"
|
||||
|
||||
static int ats_alloc_one(struct pci_dev *dev, int ps)
|
||||
void pci_ats_init(struct pci_dev *dev)
|
||||
{
|
||||
int pos;
|
||||
u16 cap;
|
||||
struct pci_ats *ats;
|
||||
|
||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
|
||||
if (!pos)
|
||||
return -ENODEV;
|
||||
return;
|
||||
|
||||
ats = kzalloc(sizeof(*ats), GFP_KERNEL);
|
||||
if (!ats)
|
||||
return -ENOMEM;
|
||||
|
||||
ats->pos = pos;
|
||||
ats->stu = ps;
|
||||
pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
|
||||
ats->qdep = PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
|
||||
PCI_ATS_MAX_QDEP;
|
||||
dev->ats = ats;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ats_free_one(struct pci_dev *dev)
|
||||
{
|
||||
kfree(dev->ats);
|
||||
dev->ats = NULL;
|
||||
dev->ats_cap = pos;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,43 +37,36 @@ static void ats_free_one(struct pci_dev *dev)
|
|||
*/
|
||||
int pci_enable_ats(struct pci_dev *dev, int ps)
|
||||
{
|
||||
int rc;
|
||||
u16 ctrl;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
BUG_ON(dev->ats && dev->ats->is_enabled);
|
||||
if (!dev->ats_cap)
|
||||
return -EINVAL;
|
||||
|
||||
if (WARN_ON(dev->ats_enabled))
|
||||
return -EBUSY;
|
||||
|
||||
if (ps < PCI_ATS_MIN_STU)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->is_physfn || dev->is_virtfn) {
|
||||
struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
|
||||
|
||||
mutex_lock(&pdev->sriov->lock);
|
||||
if (pdev->ats)
|
||||
rc = pdev->ats->stu == ps ? 0 : -EINVAL;
|
||||
else
|
||||
rc = ats_alloc_one(pdev, ps);
|
||||
|
||||
if (!rc)
|
||||
pdev->ats->ref_cnt++;
|
||||
mutex_unlock(&pdev->sriov->lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!dev->is_physfn) {
|
||||
rc = ats_alloc_one(dev, ps);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that enabling ATS on a VF fails unless it's already enabled
|
||||
* with the same STU on the PF.
|
||||
*/
|
||||
ctrl = PCI_ATS_CTRL_ENABLE;
|
||||
if (!dev->is_virtfn)
|
||||
ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU);
|
||||
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
|
||||
if (dev->is_virtfn) {
|
||||
pdev = pci_physfn(dev);
|
||||
if (pdev->ats_stu != ps)
|
||||
return -EINVAL;
|
||||
|
||||
dev->ats->is_enabled = 1;
|
||||
atomic_inc(&pdev->ats_ref_cnt); /* count enabled VFs */
|
||||
} else {
|
||||
dev->ats_stu = ps;
|
||||
ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU);
|
||||
}
|
||||
pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
|
||||
|
||||
dev->ats_enabled = 1;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_enable_ats);
|
||||
|
@ -103,28 +77,25 @@ EXPORT_SYMBOL_GPL(pci_enable_ats);
|
|||
*/
|
||||
void pci_disable_ats(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
u16 ctrl;
|
||||
|
||||
BUG_ON(!dev->ats || !dev->ats->is_enabled);
|
||||
if (WARN_ON(!dev->ats_enabled))
|
||||
return;
|
||||
|
||||
pci_read_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, &ctrl);
|
||||
ctrl &= ~PCI_ATS_CTRL_ENABLE;
|
||||
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
|
||||
if (atomic_read(&dev->ats_ref_cnt))
|
||||
return; /* VFs still enabled */
|
||||
|
||||
dev->ats->is_enabled = 0;
|
||||
|
||||
if (dev->is_physfn || dev->is_virtfn) {
|
||||
struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
|
||||
|
||||
mutex_lock(&pdev->sriov->lock);
|
||||
pdev->ats->ref_cnt--;
|
||||
if (!pdev->ats->ref_cnt)
|
||||
ats_free_one(pdev);
|
||||
mutex_unlock(&pdev->sriov->lock);
|
||||
if (dev->is_virtfn) {
|
||||
pdev = pci_physfn(dev);
|
||||
atomic_dec(&pdev->ats_ref_cnt);
|
||||
}
|
||||
|
||||
if (!dev->is_physfn)
|
||||
ats_free_one(dev);
|
||||
pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, &ctrl);
|
||||
ctrl &= ~PCI_ATS_CTRL_ENABLE;
|
||||
pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
|
||||
|
||||
dev->ats_enabled = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_disable_ats);
|
||||
|
||||
|
@ -132,16 +103,13 @@ void pci_restore_ats_state(struct pci_dev *dev)
|
|||
{
|
||||
u16 ctrl;
|
||||
|
||||
if (!pci_ats_enabled(dev))
|
||||
if (!dev->ats_enabled)
|
||||
return;
|
||||
if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS))
|
||||
BUG();
|
||||
|
||||
ctrl = PCI_ATS_CTRL_ENABLE;
|
||||
if (!dev->is_virtfn)
|
||||
ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU);
|
||||
|
||||
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
|
||||
ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU);
|
||||
pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_restore_ats_state);
|
||||
|
||||
|
@ -159,23 +127,16 @@ EXPORT_SYMBOL_GPL(pci_restore_ats_state);
|
|||
*/
|
||||
int pci_ats_queue_depth(struct pci_dev *dev)
|
||||
{
|
||||
int pos;
|
||||
u16 cap;
|
||||
|
||||
if (!dev->ats_cap)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->is_virtfn)
|
||||
return 0;
|
||||
|
||||
if (dev->ats)
|
||||
return dev->ats->qdep;
|
||||
|
||||
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
|
||||
if (!pos)
|
||||
return -ENODEV;
|
||||
|
||||
pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
|
||||
|
||||
return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
|
||||
PCI_ATS_MAX_QDEP;
|
||||
pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CAP, &cap);
|
||||
return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) : PCI_ATS_MAX_QDEP;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_ats_queue_depth);
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ config PCI_RCAR_GEN2_PCIE
|
|||
|
||||
config PCI_HOST_GENERIC
|
||||
bool "Generic PCI host controller"
|
||||
depends on ARM && OF
|
||||
depends on (ARM || ARM64) && OF
|
||||
help
|
||||
Say Y here if you want to support a simple generic PCI host
|
||||
controller, such as the one emulated by kvmtool.
|
||||
|
@ -135,7 +135,7 @@ config PCIE_IPROC_PLATFORM
|
|||
through the generic platform bus interface
|
||||
|
||||
config PCIE_IPROC_BCMA
|
||||
bool "Broadcom iProc PCIe BCMA bus driver"
|
||||
tristate "Broadcom iProc PCIe BCMA bus driver"
|
||||
depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
|
||||
select PCIE_IPROC
|
||||
select BCMA
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/irqdomain.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
@ -83,6 +84,17 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
|
|||
writel(value, pcie->base + offset);
|
||||
}
|
||||
|
||||
static inline u32 dra7xx_pcie_readl_rc(struct pcie_port *pp, u32 offset)
|
||||
{
|
||||
return readl(pp->dbi_base + offset);
|
||||
}
|
||||
|
||||
static inline void dra7xx_pcie_writel_rc(struct pcie_port *pp, u32 offset,
|
||||
u32 value)
|
||||
{
|
||||
writel(value, pp->dbi_base + offset);
|
||||
}
|
||||
|
||||
static int dra7xx_pcie_link_up(struct pcie_port *pp)
|
||||
{
|
||||
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
|
||||
|
@ -155,7 +167,6 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -325,6 +336,9 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
char name[10];
|
||||
int gpio_sel;
|
||||
enum of_gpio_flags flags;
|
||||
unsigned long gpio_flags;
|
||||
|
||||
dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
|
||||
if (!dra7xx)
|
||||
|
@ -382,9 +396,25 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_enable(dev);
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (IS_ERR_VALUE(ret)) {
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "pm_runtime_get_sync failed\n");
|
||||
goto err_phy;
|
||||
goto err_get_sync;
|
||||
}
|
||||
|
||||
gpio_sel = of_get_gpio_flags(dev->of_node, 0, &flags);
|
||||
if (gpio_is_valid(gpio_sel)) {
|
||||
gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ?
|
||||
GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
|
||||
ret = devm_gpio_request_one(dev, gpio_sel, gpio_flags,
|
||||
"pcie_reset");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "gpio%d request failed, ret %d\n",
|
||||
gpio_sel, ret);
|
||||
goto err_gpio;
|
||||
}
|
||||
} else if (gpio_sel == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto err_gpio;
|
||||
}
|
||||
|
||||
reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD);
|
||||
|
@ -395,12 +425,14 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
|
|||
|
||||
ret = dra7xx_add_pcie_port(dra7xx, pdev);
|
||||
if (ret < 0)
|
||||
goto err_add_port;
|
||||
goto err_gpio;
|
||||
|
||||
return 0;
|
||||
|
||||
err_add_port:
|
||||
err_gpio:
|
||||
pm_runtime_put(dev);
|
||||
|
||||
err_get_sync:
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
err_phy:
|
||||
|
@ -431,6 +463,85 @@ static int __exit dra7xx_pcie_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int dra7xx_pcie_suspend(struct device *dev)
|
||||
{
|
||||
struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
|
||||
struct pcie_port *pp = &dra7xx->pp;
|
||||
u32 val;
|
||||
|
||||
/* clear MSE */
|
||||
val = dra7xx_pcie_readl_rc(pp, PCI_COMMAND);
|
||||
val &= ~PCI_COMMAND_MEMORY;
|
||||
dra7xx_pcie_writel_rc(pp, PCI_COMMAND, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dra7xx_pcie_resume(struct device *dev)
|
||||
{
|
||||
struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
|
||||
struct pcie_port *pp = &dra7xx->pp;
|
||||
u32 val;
|
||||
|
||||
/* set MSE */
|
||||
val = dra7xx_pcie_readl_rc(pp, PCI_COMMAND);
|
||||
val |= PCI_COMMAND_MEMORY;
|
||||
dra7xx_pcie_writel_rc(pp, PCI_COMMAND, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dra7xx_pcie_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
|
||||
int count = dra7xx->phy_count;
|
||||
|
||||
while (count--) {
|
||||
phy_power_off(dra7xx->phy[count]);
|
||||
phy_exit(dra7xx->phy[count]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dra7xx_pcie_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
|
||||
int phy_count = dra7xx->phy_count;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < phy_count; i++) {
|
||||
ret = phy_init(dra7xx->phy[i]);
|
||||
if (ret < 0)
|
||||
goto err_phy;
|
||||
|
||||
ret = phy_power_on(dra7xx->phy[i]);
|
||||
if (ret < 0) {
|
||||
phy_exit(dra7xx->phy[i]);
|
||||
goto err_phy;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_phy:
|
||||
while (--i >= 0) {
|
||||
phy_power_off(dra7xx->phy[i]);
|
||||
phy_exit(dra7xx->phy[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
|
||||
SET_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend, dra7xx_pcie_resume)
|
||||
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(dra7xx_pcie_suspend_noirq,
|
||||
dra7xx_pcie_resume_noirq)
|
||||
};
|
||||
|
||||
static const struct of_device_id of_dra7xx_pcie_match[] = {
|
||||
{ .compatible = "ti,dra7-pcie", },
|
||||
{},
|
||||
|
@ -442,6 +553,7 @@ static struct platform_driver dra7xx_pcie_driver = {
|
|||
.driver = {
|
||||
.name = "dra7-pcie",
|
||||
.of_match_table = of_dra7xx_pcie_match,
|
||||
.pm = &dra7xx_pcie_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -38,7 +38,16 @@ struct gen_pci_cfg_windows {
|
|||
const struct gen_pci_cfg_bus_ops *ops;
|
||||
};
|
||||
|
||||
/*
|
||||
* ARM pcibios functions expect the ARM struct pci_sys_data as the PCI
|
||||
* sysdata. Add pci_sys_data as the first element in struct gen_pci so
|
||||
* that when we use a gen_pci pointer as sysdata, it is also a pointer to
|
||||
* a struct pci_sys_data.
|
||||
*/
|
||||
struct gen_pci {
|
||||
#ifdef CONFIG_ARM
|
||||
struct pci_sys_data sys;
|
||||
#endif
|
||||
struct pci_host_bridge host;
|
||||
struct gen_pci_cfg_windows cfg;
|
||||
struct list_head resources;
|
||||
|
@ -48,8 +57,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
|
|||
unsigned int devfn,
|
||||
int where)
|
||||
{
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
struct gen_pci *pci = sys->private_data;
|
||||
struct gen_pci *pci = bus->sysdata;
|
||||
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
|
||||
|
||||
return pci->cfg.win[idx] + ((devfn << 8) | where);
|
||||
|
@ -64,8 +72,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,
|
|||
unsigned int devfn,
|
||||
int where)
|
||||
{
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
struct gen_pci *pci = sys->private_data;
|
||||
struct gen_pci *pci = bus->sysdata;
|
||||
resource_size_t idx = bus->number - pci->cfg.bus_range->start;
|
||||
|
||||
return pci->cfg.win[idx] + ((devfn << 12) | where);
|
||||
|
@ -198,13 +205,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gen_pci_setup(int nr, struct pci_sys_data *sys)
|
||||
{
|
||||
struct gen_pci *pci = sys->private_data;
|
||||
list_splice_init(&pci->resources, &sys->resources);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gen_pci_probe(struct platform_device *pdev)
|
||||
{
|
||||
int err;
|
||||
|
@ -214,13 +214,7 @@ static int gen_pci_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
|
||||
struct hw_pci hw = {
|
||||
.nr_controllers = 1,
|
||||
.private_data = (void **)&pci,
|
||||
.setup = gen_pci_setup,
|
||||
.map_irq = of_irq_parse_and_map_pci,
|
||||
.ops = &gen_pci_ops,
|
||||
};
|
||||
struct pci_bus *bus, *child;
|
||||
|
||||
if (!pci)
|
||||
return -ENOMEM;
|
||||
|
@ -258,7 +252,27 @@ static int gen_pci_probe(struct platform_device *pdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
pci_common_init_dev(dev, &hw);
|
||||
/* Do not reassign resources if probe only */
|
||||
if (!pci_has_flag(PCI_PROBE_ONLY))
|
||||
pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
|
||||
|
||||
bus = pci_scan_root_bus(dev, 0, &gen_pci_ops, pci, &pci->resources);
|
||||
if (!bus) {
|
||||
dev_err(dev, "Scanning rootbus failed");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
|
||||
|
||||
if (!pci_has_flag(PCI_PROBE_ONLY)) {
|
||||
pci_bus_size_bridges(bus);
|
||||
pci_bus_assign_resources(bus);
|
||||
|
||||
list_for_each_entry(child, &bus->children, node)
|
||||
pcie_bus_configure_settings(child);
|
||||
}
|
||||
|
||||
pci_bus_add_devices(bus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,11 +117,7 @@ static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
|
|||
val = addr << PCIE_PHY_CTRL_DATA_LOC;
|
||||
writel(val, dbi_base + PCIE_PHY_CTRL);
|
||||
|
||||
ret = pcie_phy_poll_ack(dbi_base, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
return pcie_phy_poll_ack(dbi_base, 0);
|
||||
}
|
||||
|
||||
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
|
||||
|
@ -148,11 +144,7 @@ static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
|
|||
/* deassert Read signal */
|
||||
writel(0x00, dbi_base + PCIE_PHY_CTRL);
|
||||
|
||||
ret = pcie_phy_poll_ack(dbi_base, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
return pcie_phy_poll_ack(dbi_base, 0);
|
||||
}
|
||||
|
||||
static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
|
||||
|
|
|
@ -196,7 +196,6 @@ static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip,
|
||||
handle_level_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -277,7 +276,6 @@ static int ks_dw_pcie_init_legacy_irq_map(struct irq_domain *d,
|
|||
irq_set_chip_and_handler(irq, &ks_dw_pcie_legacy_irq_chip,
|
||||
handle_level_irq);
|
||||
irq_set_chip_data(irq, d->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
|
|||
return;
|
||||
|
||||
pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
|
||||
of_node_put(msi_node);
|
||||
|
||||
if (pcie->msi)
|
||||
pcie->msi->dev = &pcie->pdev->dev;
|
||||
|
|
|
@ -1248,7 +1248,6 @@ static int tegra_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
tegra_cpuidle_pcie_irqs_in_use();
|
||||
|
||||
|
|
|
@ -223,7 +223,6 @@ static int xgene_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
|||
irq_domain_set_info(domain, virq, msi_irq,
|
||||
&xgene_msi_bottom_irq_chip, domain->host_data,
|
||||
handle_simple_irq, NULL, NULL);
|
||||
set_irq_flags(virq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -582,7 +581,6 @@ error:
|
|||
static struct platform_driver xgene_msi_driver = {
|
||||
.driver = {
|
||||
.name = "xgene-msi",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = xgene_msi_match_table,
|
||||
},
|
||||
.probe = xgene_msi_probe,
|
||||
|
|
|
@ -321,8 +321,16 @@ static int xgene_pcie_map_ranges(struct xgene_pcie_port *port,
|
|||
return ret;
|
||||
break;
|
||||
case IORESOURCE_MEM:
|
||||
xgene_pcie_setup_ob_reg(port, res, OMR1BARL, res->start,
|
||||
res->start - window->offset);
|
||||
if (res->flags & IORESOURCE_PREFETCH)
|
||||
xgene_pcie_setup_ob_reg(port, res, OMR2BARL,
|
||||
res->start,
|
||||
res->start -
|
||||
window->offset);
|
||||
else
|
||||
xgene_pcie_setup_ob_reg(port, res, OMR1BARL,
|
||||
res->start,
|
||||
res->start -
|
||||
window->offset);
|
||||
break;
|
||||
case IORESOURCE_BUS:
|
||||
break;
|
||||
|
@ -514,6 +522,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
|
|||
if (!bus->msi)
|
||||
return -ENODEV;
|
||||
|
||||
of_node_put(msi_node);
|
||||
bus->msi->dev = &bus->dev;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -350,7 +350,6 @@ static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &dw_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -388,7 +387,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
|||
addrp = of_get_address(np, index, NULL, NULL);
|
||||
pp->cfg0_mod_base = of_read_number(addrp, ns);
|
||||
pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
|
||||
} else {
|
||||
} else if (!pp->va_cfg0_base) {
|
||||
dev_err(pp->dev, "missing *config* reg space\n");
|
||||
}
|
||||
|
||||
|
@ -526,7 +525,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
|||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
dw_pcie_msi_chip.dev = pp->dev;
|
||||
dw_pci.msi_ctrl = &dw_pcie_msi_chip;
|
||||
#endif
|
||||
|
||||
dw_pci.nr_controllers = 1;
|
||||
|
@ -708,8 +706,15 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
struct pcie_port *pp = sys_to_pcie(sys);
|
||||
|
||||
pp->root_bus_nr = sys->busnr;
|
||||
bus = pci_scan_root_bus(pp->dev, sys->busnr,
|
||||
&dw_pcie_ops, sys, &sys->resources);
|
||||
|
||||
if (IS_ENABLED(CONFIG_PCI_MSI))
|
||||
bus = pci_scan_root_bus_msi(pp->dev, sys->busnr, &dw_pcie_ops,
|
||||
sys, &sys->resources,
|
||||
&dw_pcie_msi_chip);
|
||||
else
|
||||
bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
|
||||
sys, &sys->resources);
|
||||
|
||||
if (!bus)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -58,9 +58,17 @@
|
|||
#define SYS_RC_INTX_EN 0x330
|
||||
#define SYS_RC_INTX_MASK 0xf
|
||||
|
||||
static inline struct iproc_pcie *sys_to_pcie(struct pci_sys_data *sys)
|
||||
static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
|
||||
{
|
||||
return sys->private_data;
|
||||
struct iproc_pcie *pcie;
|
||||
#ifdef CONFIG_ARM
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
|
||||
pcie = sys->private_data;
|
||||
#else
|
||||
pcie = bus->sysdata;
|
||||
#endif
|
||||
return pcie;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,8 +79,7 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
|
|||
unsigned int devfn,
|
||||
int where)
|
||||
{
|
||||
struct pci_sys_data *sys = bus->sysdata;
|
||||
struct iproc_pcie *pcie = sys_to_pcie(sys);
|
||||
struct iproc_pcie *pcie = iproc_data(bus);
|
||||
unsigned slot = PCI_SLOT(devfn);
|
||||
unsigned fn = PCI_FUNC(devfn);
|
||||
unsigned busno = bus->number;
|
||||
|
@ -186,32 +193,34 @@ static void iproc_pcie_enable(struct iproc_pcie *pcie)
|
|||
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
|
||||
{
|
||||
int ret;
|
||||
void *sysdata;
|
||||
struct pci_bus *bus;
|
||||
|
||||
if (!pcie || !pcie->dev || !pcie->base)
|
||||
return -EINVAL;
|
||||
|
||||
if (pcie->phy) {
|
||||
ret = phy_init(pcie->phy);
|
||||
if (ret) {
|
||||
dev_err(pcie->dev, "unable to initialize PCIe PHY\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = phy_power_on(pcie->phy);
|
||||
if (ret) {
|
||||
dev_err(pcie->dev, "unable to power on PCIe PHY\n");
|
||||
goto err_exit_phy;
|
||||
}
|
||||
ret = phy_init(pcie->phy);
|
||||
if (ret) {
|
||||
dev_err(pcie->dev, "unable to initialize PCIe PHY\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = phy_power_on(pcie->phy);
|
||||
if (ret) {
|
||||
dev_err(pcie->dev, "unable to power on PCIe PHY\n");
|
||||
goto err_exit_phy;
|
||||
}
|
||||
|
||||
iproc_pcie_reset(pcie);
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
pcie->sysdata.private_data = pcie;
|
||||
sysdata = &pcie->sysdata;
|
||||
#else
|
||||
sysdata = pcie;
|
||||
#endif
|
||||
|
||||
bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops,
|
||||
&pcie->sysdata, res);
|
||||
bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res);
|
||||
if (!bus) {
|
||||
dev_err(pcie->dev, "unable to create PCI root bus\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -229,7 +238,9 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
|
|||
|
||||
pci_scan_child_bus(bus);
|
||||
pci_assign_unassigned_bus_resources(bus);
|
||||
#ifdef CONFIG_ARM
|
||||
pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
|
||||
#endif
|
||||
pci_bus_add_devices(bus);
|
||||
|
||||
return 0;
|
||||
|
@ -239,12 +250,9 @@ err_rm_root_bus:
|
|||
pci_remove_root_bus(bus);
|
||||
|
||||
err_power_off_phy:
|
||||
if (pcie->phy)
|
||||
phy_power_off(pcie->phy);
|
||||
phy_power_off(pcie->phy);
|
||||
err_exit_phy:
|
||||
if (pcie->phy)
|
||||
phy_exit(pcie->phy);
|
||||
|
||||
phy_exit(pcie->phy);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(iproc_pcie_setup);
|
||||
|
@ -254,10 +262,8 @@ int iproc_pcie_remove(struct iproc_pcie *pcie)
|
|||
pci_stop_root_bus(pcie->root_bus);
|
||||
pci_remove_root_bus(pcie->root_bus);
|
||||
|
||||
if (pcie->phy) {
|
||||
phy_power_off(pcie->phy);
|
||||
phy_exit(pcie->phy);
|
||||
}
|
||||
phy_power_off(pcie->phy);
|
||||
phy_exit(pcie->phy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* @dev: pointer to device data structure
|
||||
* @base: PCIe host controller I/O register base
|
||||
* @resources: linked list of all PCI resources
|
||||
* @sysdata: Per PCI controller data
|
||||
* @sysdata: Per PCI controller data (ARM-specific)
|
||||
* @root_bus: pointer to root bus
|
||||
* @phy: optional PHY device that controls the Serdes
|
||||
* @irqs: interrupt IDs
|
||||
|
@ -29,7 +29,9 @@
|
|||
struct iproc_pcie {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
#ifdef CONFIG_ARM
|
||||
struct pci_sys_data sysdata;
|
||||
#endif
|
||||
struct pci_bus *root_bus;
|
||||
struct phy *phy;
|
||||
int irqs[IPROC_PCIE_MAX_NUM_IRQS];
|
||||
|
|
|
@ -664,7 +664,6 @@ static int rcar_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &rcar_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -223,8 +223,7 @@ static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)
|
|||
status = readl(&app_reg->int_sts);
|
||||
|
||||
if (status & MSI_CTRL_INT) {
|
||||
if (!IS_ENABLED(CONFIG_PCI_MSI))
|
||||
BUG();
|
||||
BUG_ON(!IS_ENABLED(CONFIG_PCI_MSI));
|
||||
dw_handle_msi_irq(pp);
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,6 @@ static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -377,7 +376,6 @@ static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
|
|||
{
|
||||
irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
|
||||
irq_set_chip_data(irq, domain->host_data);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -449,14 +447,17 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Clear interrupt FIFO register 1 */
|
||||
pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK,
|
||||
XILINX_PCIE_REG_RPIFR1);
|
||||
if (!(val & XILINX_PCIE_RPIFR1_MSI_INTR)) {
|
||||
/* Clear interrupt FIFO register 1 */
|
||||
pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK,
|
||||
XILINX_PCIE_REG_RPIFR1);
|
||||
|
||||
/* Handle INTx Interrupt */
|
||||
val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
|
||||
XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1;
|
||||
generic_handle_irq(irq_find_mapping(port->irq_domain, val));
|
||||
/* Handle INTx Interrupt */
|
||||
val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
|
||||
XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1;
|
||||
generic_handle_irq(irq_find_mapping(port->irq_domain,
|
||||
val));
|
||||
}
|
||||
}
|
||||
|
||||
if (status & XILINX_PCIE_INTR_MSI) {
|
||||
|
@ -647,9 +648,15 @@ static struct pci_bus *xilinx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
struct pci_bus *bus;
|
||||
|
||||
port->root_busno = sys->busnr;
|
||||
bus = pci_scan_root_bus(port->dev, sys->busnr, &xilinx_pcie_ops,
|
||||
sys, &sys->resources);
|
||||
|
||||
if (IS_ENABLED(CONFIG_PCI_MSI))
|
||||
bus = pci_scan_root_bus_msi(port->dev, sys->busnr,
|
||||
&xilinx_pcie_ops, sys,
|
||||
&sys->resources,
|
||||
&xilinx_pcie_msi_chip);
|
||||
else
|
||||
bus = pci_scan_root_bus(port->dev, sys->busnr,
|
||||
&xilinx_pcie_ops, sys, &sys->resources);
|
||||
return bus;
|
||||
}
|
||||
|
||||
|
@ -847,7 +854,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
|
|||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
xilinx_pcie_msi_chip.dev = port->dev;
|
||||
hw.msi_ctrl = &xilinx_pcie_msi_chip;
|
||||
#endif
|
||||
pci_common_init_dev(dev, &hw);
|
||||
|
||||
|
|
|
@ -83,12 +83,12 @@ GET_STATUS(attention_status, u8)
|
|||
GET_STATUS(latch_status, u8)
|
||||
GET_STATUS(adapter_status, u8)
|
||||
|
||||
static ssize_t power_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t power_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_power_status(slot->hotplug, &value);
|
||||
retval = get_power_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -140,22 +140,22 @@ static struct pci_slot_attribute hotplug_slot_attr_power = {
|
|||
.store = power_write_file
|
||||
};
|
||||
|
||||
static ssize_t attention_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t attention_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_attention_status(slot->hotplug, &value);
|
||||
retval = get_attention_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return sprintf(buf, "%d\n", value);
|
||||
}
|
||||
|
||||
static ssize_t attention_write_file(struct pci_slot *slot, const char *buf,
|
||||
static ssize_t attention_write_file(struct pci_slot *pci_slot, const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct hotplug_slot_ops *ops = slot->hotplug->ops;
|
||||
struct hotplug_slot_ops *ops = pci_slot->hotplug->ops;
|
||||
unsigned long lattention;
|
||||
u8 attention;
|
||||
int retval = 0;
|
||||
|
@ -169,7 +169,7 @@ static ssize_t attention_write_file(struct pci_slot *slot, const char *buf,
|
|||
goto exit;
|
||||
}
|
||||
if (ops->set_attention_status)
|
||||
retval = ops->set_attention_status(slot->hotplug, attention);
|
||||
retval = ops->set_attention_status(pci_slot->hotplug, attention);
|
||||
module_put(ops->owner);
|
||||
|
||||
exit:
|
||||
|
@ -184,12 +184,12 @@ static struct pci_slot_attribute hotplug_slot_attr_attention = {
|
|||
.store = attention_write_file
|
||||
};
|
||||
|
||||
static ssize_t latch_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t latch_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_latch_status(slot->hotplug, &value);
|
||||
retval = get_latch_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -201,12 +201,12 @@ static struct pci_slot_attribute hotplug_slot_attr_latch = {
|
|||
.show = latch_read_file,
|
||||
};
|
||||
|
||||
static ssize_t presence_read_file(struct pci_slot *slot, char *buf)
|
||||
static ssize_t presence_read_file(struct pci_slot *pci_slot, char *buf)
|
||||
{
|
||||
int retval;
|
||||
u8 value;
|
||||
|
||||
retval = get_adapter_status(slot->hotplug, &value);
|
||||
retval = get_adapter_status(pci_slot->hotplug, &value);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -307,43 +307,43 @@ static bool has_test_file(struct pci_slot *pci_slot)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int fs_add_slot(struct pci_slot *slot)
|
||||
static int fs_add_slot(struct pci_slot *pci_slot)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
/* Create symbolic link to the hotplug driver module */
|
||||
pci_hp_create_module_link(slot);
|
||||
pci_hp_create_module_link(pci_slot);
|
||||
|
||||
if (has_power_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_power_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_power.attr);
|
||||
if (retval)
|
||||
goto exit_power;
|
||||
}
|
||||
|
||||
if (has_attention_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_attention_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_attention.attr);
|
||||
if (retval)
|
||||
goto exit_attention;
|
||||
}
|
||||
|
||||
if (has_latch_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_latch_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_latch.attr);
|
||||
if (retval)
|
||||
goto exit_latch;
|
||||
}
|
||||
|
||||
if (has_adapter_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_adapter_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_presence.attr);
|
||||
if (retval)
|
||||
goto exit_adapter;
|
||||
}
|
||||
|
||||
if (has_test_file(slot)) {
|
||||
retval = sysfs_create_file(&slot->kobj,
|
||||
if (has_test_file(pci_slot)) {
|
||||
retval = sysfs_create_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_test.attr);
|
||||
if (retval)
|
||||
goto exit_test;
|
||||
|
@ -352,45 +352,45 @@ static int fs_add_slot(struct pci_slot *slot)
|
|||
goto exit;
|
||||
|
||||
exit_test:
|
||||
if (has_adapter_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_adapter_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_presence.attr);
|
||||
exit_adapter:
|
||||
if (has_latch_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
if (has_latch_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
exit_latch:
|
||||
if (has_attention_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_attention_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_attention.attr);
|
||||
exit_attention:
|
||||
if (has_power_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
if (has_power_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
exit_power:
|
||||
pci_hp_remove_module_link(slot);
|
||||
pci_hp_remove_module_link(pci_slot);
|
||||
exit:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void fs_remove_slot(struct pci_slot *slot)
|
||||
static void fs_remove_slot(struct pci_slot *pci_slot)
|
||||
{
|
||||
if (has_power_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
if (has_power_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr);
|
||||
|
||||
if (has_attention_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_attention_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_attention.attr);
|
||||
|
||||
if (has_latch_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
if (has_latch_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);
|
||||
|
||||
if (has_adapter_file(slot))
|
||||
sysfs_remove_file(&slot->kobj,
|
||||
if (has_adapter_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj,
|
||||
&hotplug_slot_attr_presence.attr);
|
||||
|
||||
if (has_test_file(slot))
|
||||
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
|
||||
if (has_test_file(pci_slot))
|
||||
sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_test.attr);
|
||||
|
||||
pci_hp_remove_module_link(slot);
|
||||
pci_hp_remove_module_link(pci_slot);
|
||||
}
|
||||
|
||||
static struct hotplug_slot *get_slot_from_name(const char *name)
|
||||
|
@ -467,37 +467,37 @@ EXPORT_SYMBOL_GPL(__pci_hp_register);
|
|||
|
||||
/**
|
||||
* pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
|
||||
* @hotplug: pointer to the &struct hotplug_slot to deregister
|
||||
* @slot: pointer to the &struct hotplug_slot to deregister
|
||||
*
|
||||
* The @slot must have been registered with the pci hotplug subsystem
|
||||
* previously with a call to pci_hp_register().
|
||||
*
|
||||
* Returns 0 if successful, anything else for an error.
|
||||
*/
|
||||
int pci_hp_deregister(struct hotplug_slot *hotplug)
|
||||
int pci_hp_deregister(struct hotplug_slot *slot)
|
||||
{
|
||||
struct hotplug_slot *temp;
|
||||
struct pci_slot *slot;
|
||||
struct pci_slot *pci_slot;
|
||||
|
||||
if (!hotplug)
|
||||
if (!slot)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&pci_hp_mutex);
|
||||
temp = get_slot_from_name(hotplug_slot_name(hotplug));
|
||||
if (temp != hotplug) {
|
||||
temp = get_slot_from_name(hotplug_slot_name(slot));
|
||||
if (temp != slot) {
|
||||
mutex_unlock(&pci_hp_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
list_del(&hotplug->slot_list);
|
||||
list_del(&slot->slot_list);
|
||||
|
||||
slot = hotplug->pci_slot;
|
||||
fs_remove_slot(slot);
|
||||
dbg("Removed slot %s from the list\n", hotplug_slot_name(hotplug));
|
||||
pci_slot = slot->pci_slot;
|
||||
fs_remove_slot(pci_slot);
|
||||
dbg("Removed slot %s from the list\n", hotplug_slot_name(slot));
|
||||
|
||||
hotplug->release(hotplug);
|
||||
slot->hotplug = NULL;
|
||||
pci_destroy_slot(slot);
|
||||
slot->release(slot);
|
||||
pci_slot->hotplug = NULL;
|
||||
pci_destroy_slot(pci_slot);
|
||||
mutex_unlock(&pci_hp_mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -506,7 +506,7 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);
|
|||
|
||||
/**
|
||||
* pci_hp_change_slot_info - changes the slot's information structure in the core
|
||||
* @hotplug: pointer to the slot whose info has changed
|
||||
* @slot: pointer to the slot whose info has changed
|
||||
* @info: pointer to the info copy into the slot's info structure
|
||||
*
|
||||
* @slot must have been registered with the pci
|
||||
|
@ -514,13 +514,13 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);
|
|||
*
|
||||
* Returns 0 if successful, anything else for an error.
|
||||
*/
|
||||
int pci_hp_change_slot_info(struct hotplug_slot *hotplug,
|
||||
int pci_hp_change_slot_info(struct hotplug_slot *slot,
|
||||
struct hotplug_slot_info *info)
|
||||
{
|
||||
if (!hotplug || !info)
|
||||
if (!slot || !info)
|
||||
return -ENODEV;
|
||||
|
||||
memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info));
|
||||
memcpy(slot->info, info, sizeof(struct hotplug_slot_info));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -101,18 +101,12 @@ struct controller {
|
|||
unsigned int power_fault_detected;
|
||||
};
|
||||
|
||||
#define INT_BUTTON_IGNORE 0
|
||||
#define INT_PRESENCE_ON 1
|
||||
#define INT_PRESENCE_OFF 2
|
||||
#define INT_SWITCH_CLOSE 3
|
||||
#define INT_SWITCH_OPEN 4
|
||||
#define INT_POWER_FAULT 5
|
||||
#define INT_POWER_FAULT_CLEAR 6
|
||||
#define INT_BUTTON_PRESS 7
|
||||
#define INT_BUTTON_RELEASE 8
|
||||
#define INT_BUTTON_CANCEL 9
|
||||
#define INT_LINK_UP 10
|
||||
#define INT_LINK_DOWN 11
|
||||
#define INT_POWER_FAULT 3
|
||||
#define INT_BUTTON_PRESS 4
|
||||
#define INT_LINK_UP 5
|
||||
#define INT_LINK_DOWN 6
|
||||
|
||||
#define STATIC_STATE 0
|
||||
#define BLINKINGON_STATE 1
|
||||
|
|
|
@ -109,21 +109,23 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout)
|
|||
struct pci_dev *pdev = ctrl_dev(ctrl);
|
||||
u16 slot_status;
|
||||
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
|
||||
if (slot_status & PCI_EXP_SLTSTA_CC) {
|
||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
|
||||
PCI_EXP_SLTSTA_CC);
|
||||
return 1;
|
||||
}
|
||||
while (timeout > 0) {
|
||||
msleep(10);
|
||||
timeout -= 10;
|
||||
while (true) {
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
|
||||
if (slot_status == (u16) ~0) {
|
||||
ctrl_info(ctrl, "%s: no response from device\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (slot_status & PCI_EXP_SLTSTA_CC) {
|
||||
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
|
||||
PCI_EXP_SLTSTA_CC);
|
||||
return 1;
|
||||
}
|
||||
if (timeout < 0)
|
||||
break;
|
||||
msleep(10);
|
||||
timeout -= 10;
|
||||
}
|
||||
return 0; /* timeout */
|
||||
}
|
||||
|
@ -190,6 +192,11 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
|
|||
pcie_wait_cmd(ctrl);
|
||||
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
|
||||
if (slot_ctrl == (u16) ~0) {
|
||||
ctrl_info(ctrl, "%s: no response from device\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
slot_ctrl &= ~mask;
|
||||
slot_ctrl |= (cmd & mask);
|
||||
ctrl->cmd_busy = 1;
|
||||
|
@ -205,6 +212,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
|
|||
if (wait)
|
||||
pcie_wait_cmd(ctrl);
|
||||
|
||||
out:
|
||||
mutex_unlock(&ctrl->ctrl_lock);
|
||||
}
|
||||
|
||||
|
@ -535,7 +543,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||
struct pci_dev *dev;
|
||||
struct slot *slot = ctrl->slot;
|
||||
u16 detected, intr_loc;
|
||||
u8 open, present;
|
||||
u8 present;
|
||||
bool link;
|
||||
|
||||
/*
|
||||
|
@ -546,9 +554,14 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||
intr_loc = 0;
|
||||
do {
|
||||
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &detected);
|
||||
if (detected == (u16) ~0) {
|
||||
ctrl_info(ctrl, "%s: no response from device\n",
|
||||
__func__);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
|
||||
PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
|
||||
PCI_EXP_SLTSTA_PDC |
|
||||
PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);
|
||||
detected &= ~intr_loc;
|
||||
intr_loc |= detected;
|
||||
|
@ -581,15 +594,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
|
|||
if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
/* Check MRL Sensor Changed */
|
||||
if (intr_loc & PCI_EXP_SLTSTA_MRLSC) {
|
||||
pciehp_get_latch_status(slot, &open);
|
||||
ctrl_info(ctrl, "Latch %s on Slot(%s)\n",
|
||||
open ? "open" : "close", slot_name(slot));
|
||||
pciehp_queue_interrupt_event(slot, open ? INT_SWITCH_OPEN :
|
||||
INT_SWITCH_CLOSE);
|
||||
}
|
||||
|
||||
/* Check Attention Button Pressed */
|
||||
if (intr_loc & PCI_EXP_SLTSTA_ABP) {
|
||||
ctrl_info(ctrl, "Button pressed on Slot(%s)\n",
|
||||
|
@ -649,13 +653,11 @@ void pcie_enable_notification(struct controller *ctrl)
|
|||
cmd |= PCI_EXP_SLTCTL_ABPE;
|
||||
else
|
||||
cmd |= PCI_EXP_SLTCTL_PDCE;
|
||||
if (MRL_SENS(ctrl))
|
||||
cmd |= PCI_EXP_SLTCTL_MRLSCE;
|
||||
if (!pciehp_poll_mode)
|
||||
cmd |= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE;
|
||||
|
||||
mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |
|
||||
PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |
|
||||
PCI_EXP_SLTCTL_PFDE |
|
||||
PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
|
||||
PCI_EXP_SLTCTL_DLLSCE);
|
||||
|
||||
|
|
|
@ -77,24 +77,9 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
|
|||
|
||||
/* Arch hooks */
|
||||
|
||||
struct msi_controller * __weak pcibios_msi_controller(struct pci_dev *dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct msi_controller *pci_msi_controller(struct pci_dev *dev)
|
||||
{
|
||||
struct msi_controller *msi_ctrl = dev->bus->msi;
|
||||
|
||||
if (msi_ctrl)
|
||||
return msi_ctrl;
|
||||
|
||||
return pcibios_msi_controller(dev);
|
||||
}
|
||||
|
||||
int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
|
||||
{
|
||||
struct msi_controller *chip = pci_msi_controller(dev);
|
||||
struct msi_controller *chip = dev->bus->msi;
|
||||
int err;
|
||||
|
||||
if (!chip || !chip->setup_irq)
|
||||
|
@ -665,6 +650,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
|
|||
pci_msi_set_enable(dev, 1);
|
||||
dev->msi_enabled = 1;
|
||||
|
||||
pcibios_free_irq(dev);
|
||||
dev->irq = entry->irq;
|
||||
return 0;
|
||||
}
|
||||
|
@ -792,9 +778,9 @@ static int msix_capability_init(struct pci_dev *dev,
|
|||
/* Set MSI-X enabled bits and unmask the function */
|
||||
pci_intx_for_msi(dev, 0);
|
||||
dev->msix_enabled = 1;
|
||||
|
||||
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
|
||||
|
||||
pcibios_free_irq(dev);
|
||||
return 0;
|
||||
|
||||
out_avail:
|
||||
|
@ -909,6 +895,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
|
|||
|
||||
/* Restore dev->irq to its default pin-assertion irq */
|
||||
dev->irq = desc->msi_attrib.default_irq;
|
||||
pcibios_alloc_irq(dev);
|
||||
}
|
||||
|
||||
void pci_disable_msi(struct pci_dev *dev)
|
||||
|
@ -1009,6 +996,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
|
|||
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
|
||||
pci_intx_for_msi(dev, 1);
|
||||
dev->msix_enabled = 0;
|
||||
pcibios_alloc_irq(dev);
|
||||
}
|
||||
|
||||
void pci_disable_msix(struct pci_dev *dev)
|
||||
|
|
|
@ -594,7 +594,7 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev)
|
|||
/**
|
||||
* pci_acpi_optimize_delay - optimize PCI D3 and D3cold delay from ACPI
|
||||
* @pdev: the PCI device whose delay is to be updated
|
||||
* @adev: the companion ACPI device of this PCI device
|
||||
* @handle: ACPI handle of this device
|
||||
*
|
||||
* Update the d3_delay and d3cold_delay of a PCI device from the ACPI _DSM
|
||||
* control method of either the device itself or the PCI host bridge.
|
||||
|
|
|
@ -388,18 +388,31 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
|
|||
return error;
|
||||
}
|
||||
|
||||
int __weak pcibios_alloc_irq(struct pci_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __weak pcibios_free_irq(struct pci_dev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int pci_device_probe(struct device *dev)
|
||||
{
|
||||
int error = 0;
|
||||
struct pci_driver *drv;
|
||||
struct pci_dev *pci_dev;
|
||||
int error;
|
||||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct pci_driver *drv = to_pci_driver(dev->driver);
|
||||
|
||||
error = pcibios_alloc_irq(pci_dev);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
drv = to_pci_driver(dev->driver);
|
||||
pci_dev = to_pci_dev(dev);
|
||||
pci_dev_get(pci_dev);
|
||||
error = __pci_device_probe(drv, pci_dev);
|
||||
if (error)
|
||||
if (error) {
|
||||
pcibios_free_irq(pci_dev);
|
||||
pci_dev_put(pci_dev);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -415,6 +428,7 @@ static int pci_device_remove(struct device *dev)
|
|||
drv->remove(pci_dev);
|
||||
pm_runtime_put_noidle(dev);
|
||||
}
|
||||
pcibios_free_irq(pci_dev);
|
||||
pci_dev->driver = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
|
|||
unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE;
|
||||
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
|
||||
|
||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
|
||||
enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
|
||||
|
||||
/*
|
||||
* The default CLS is used if arch didn't set CLS explicitly and not
|
||||
|
@ -140,7 +140,6 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
|
|||
EXPORT_SYMBOL_GPL(pci_ioremap_bar);
|
||||
#endif
|
||||
|
||||
#define PCI_FIND_CAP_TTL 48
|
||||
|
||||
static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
|
||||
u8 pos, int cap, int *ttl)
|
||||
|
@ -196,8 +195,6 @@ static int __pci_bus_find_cap_start(struct pci_bus *bus,
|
|||
return PCI_CAPABILITY_LIST;
|
||||
case PCI_HEADER_TYPE_CARDBUS:
|
||||
return PCI_CB_CAPABILITY_LIST;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -972,7 +969,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
|
|||
struct pci_cap_saved_state *save_state;
|
||||
|
||||
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
||||
if (pos <= 0)
|
||||
if (!pos)
|
||||
return 0;
|
||||
|
||||
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
|
||||
|
@ -995,7 +992,7 @@ static void pci_restore_pcix_state(struct pci_dev *dev)
|
|||
|
||||
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
|
||||
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
|
||||
if (!save_state || pos <= 0)
|
||||
if (!save_state || !pos)
|
||||
return;
|
||||
cap = (u16 *)&save_state->cap.data[0];
|
||||
|
||||
|
@ -1092,6 +1089,9 @@ void pci_restore_state(struct pci_dev *dev)
|
|||
|
||||
pci_restore_pcix_state(dev);
|
||||
pci_restore_msi_state(dev);
|
||||
|
||||
/* Restore ACS and IOV configuration state */
|
||||
pci_enable_acs(dev);
|
||||
pci_restore_iov_state(dev);
|
||||
|
||||
dev->state_saved = false;
|
||||
|
@ -2159,7 +2159,7 @@ static int _pci_add_cap_save_buffer(struct pci_dev *dev, u16 cap,
|
|||
else
|
||||
pos = pci_find_capability(dev, cap);
|
||||
|
||||
if (pos <= 0)
|
||||
if (!pos)
|
||||
return 0;
|
||||
|
||||
save_state = kzalloc(sizeof(*save_state) + size, GFP_KERNEL);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#define PCI_CFG_SPACE_SIZE 256
|
||||
#define PCI_CFG_SPACE_EXP_SIZE 4096
|
||||
|
||||
#define PCI_FIND_CAP_TTL 48
|
||||
|
||||
extern const unsigned char pcie_link_speed[];
|
||||
|
||||
bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
|
||||
|
|
|
@ -448,7 +448,7 @@ static int resume_iter(struct device *dev, void *data)
|
|||
}
|
||||
|
||||
/**
|
||||
* pcie_port_device_suspend - resume port services associated with a PCIe port
|
||||
* pcie_port_device_resume - resume port services associated with a PCIe port
|
||||
* @dev: PCI Express port to handle
|
||||
*/
|
||||
int pcie_port_device_resume(struct device *dev)
|
||||
|
|
|
@ -826,6 +826,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|||
child->bridge_ctl = bctl;
|
||||
}
|
||||
|
||||
/* Read and initialize bridge resources */
|
||||
pci_read_bridge_bases(child);
|
||||
|
||||
cmax = pci_scan_child_bus(child);
|
||||
if (cmax > subordinate)
|
||||
dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
|
||||
|
@ -886,6 +889,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|||
|
||||
if (!is_cardbus) {
|
||||
child->bridge_ctl = bctl;
|
||||
|
||||
/* Read and initialize bridge resources */
|
||||
pci_read_bridge_bases(child);
|
||||
max = pci_scan_child_bus(child);
|
||||
} else {
|
||||
/*
|
||||
|
@ -1138,7 +1144,6 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
{
|
||||
u32 class;
|
||||
u8 hdr_type;
|
||||
struct pci_slot *slot;
|
||||
int pos = 0;
|
||||
struct pci_bus_region region;
|
||||
struct resource *res;
|
||||
|
@ -1154,10 +1159,7 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
dev->error_state = pci_channel_io_normal;
|
||||
set_pcie_port_type(dev);
|
||||
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
|
||||
pci_dev_assign_slot(dev);
|
||||
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
|
||||
set this higher, assuming the system even supports it. */
|
||||
dev->dma_mask = 0xffffffff;
|
||||
|
@ -1273,13 +1275,51 @@ int pci_setup_device(struct pci_dev *dev)
|
|||
bad:
|
||||
dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n",
|
||||
dev->class, dev->hdr_type);
|
||||
dev->class = PCI_CLASS_NOT_DEFINED;
|
||||
dev->class = PCI_CLASS_NOT_DEFINED << 8;
|
||||
}
|
||||
|
||||
/* We found a fine healthy device, go go go... */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pci_configure_mps(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *bridge = pci_upstream_bridge(dev);
|
||||
int mps, p_mps, rc;
|
||||
|
||||
if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge))
|
||||
return;
|
||||
|
||||
mps = pcie_get_mps(dev);
|
||||
p_mps = pcie_get_mps(bridge);
|
||||
|
||||
if (mps == p_mps)
|
||||
return;
|
||||
|
||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
|
||||
dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
|
||||
mps, pci_name(bridge), p_mps);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fancier MPS configuration is done later by
|
||||
* pcie_bus_configure_settings()
|
||||
*/
|
||||
if (pcie_bus_config != PCIE_BUS_DEFAULT)
|
||||
return;
|
||||
|
||||
rc = pcie_set_mps(dev, p_mps);
|
||||
if (rc) {
|
||||
dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
|
||||
p_mps);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_info(&dev->dev, "Max Payload Size set to %d (was %d, max %d)\n",
|
||||
p_mps, mps, 128 << dev->pcie_mpss);
|
||||
}
|
||||
|
||||
static struct hpp_type0 pci_default_type0 = {
|
||||
.revision = 1,
|
||||
.cache_line_size = 8,
|
||||
|
@ -1401,6 +1441,8 @@ static void pci_configure_device(struct pci_dev *dev)
|
|||
struct hotplug_params hpp;
|
||||
int ret;
|
||||
|
||||
pci_configure_mps(dev);
|
||||
|
||||
memset(&hpp, 0, sizeof(hpp));
|
||||
ret = pci_get_hp_params(dev, &hpp);
|
||||
if (ret)
|
||||
|
@ -1545,6 +1587,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
|
|||
/* Single Root I/O Virtualization */
|
||||
pci_iov_init(dev);
|
||||
|
||||
/* Address Translation Services */
|
||||
pci_ats_init(dev);
|
||||
|
||||
/* Enable ACS P2P upstream forwarding */
|
||||
pci_enable_acs(dev);
|
||||
}
|
||||
|
@ -1796,22 +1841,6 @@ static void pcie_write_mrrs(struct pci_dev *dev)
|
|||
dev_err(&dev->dev, "MRRS was unable to be configured with a safe value. If problems are experienced, try running with pci=pcie_bus_safe\n");
|
||||
}
|
||||
|
||||
static void pcie_bus_detect_mps(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *bridge = dev->bus->self;
|
||||
int mps, p_mps;
|
||||
|
||||
if (!bridge)
|
||||
return;
|
||||
|
||||
mps = pcie_get_mps(dev);
|
||||
p_mps = pcie_get_mps(bridge);
|
||||
|
||||
if (mps != p_mps)
|
||||
dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
|
||||
mps, pci_name(bridge), p_mps);
|
||||
}
|
||||
|
||||
static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
||||
{
|
||||
int mps, orig_mps;
|
||||
|
@ -1819,10 +1848,9 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
|||
if (!pci_is_pcie(dev))
|
||||
return 0;
|
||||
|
||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
|
||||
pcie_bus_detect_mps(dev);
|
||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
|
||||
pcie_bus_config == PCIE_BUS_DEFAULT)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mps = 128 << *(u8 *)data;
|
||||
orig_mps = pcie_get_mps(dev);
|
||||
|
@ -2101,8 +2129,9 @@ void pci_bus_release_busn_res(struct pci_bus *b)
|
|||
res, ret ? "can not be" : "is");
|
||||
}
|
||||
|
||||
struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata, struct list_head *resources)
|
||||
struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata,
|
||||
struct list_head *resources, struct msi_controller *msi)
|
||||
{
|
||||
struct resource_entry *window;
|
||||
bool found = false;
|
||||
|
@ -2119,6 +2148,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
|
|||
if (!b)
|
||||
return NULL;
|
||||
|
||||
b->msi = msi;
|
||||
|
||||
if (!found) {
|
||||
dev_info(&b->dev,
|
||||
"No busn resource found for root bus, will use [bus %02x-ff]\n",
|
||||
|
@ -2133,6 +2164,13 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
|
|||
|
||||
return b;
|
||||
}
|
||||
|
||||
struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata, struct list_head *resources)
|
||||
{
|
||||
return pci_scan_root_bus_msi(parent, bus, ops, sysdata, resources,
|
||||
NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_scan_root_bus);
|
||||
|
||||
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
|
||||
|
|
|
@ -163,7 +163,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quirk_
|
|||
* VIA Apollo KT133 needs PCI latency patch
|
||||
* Made according to a windows driver based patch by George E. Breese
|
||||
* see PCI Latency Adjust on http://www.viahardware.com/download/viatweak.shtm
|
||||
* and http://www.georgebreese.com/net/software/#PCI
|
||||
* Also see http://www.au-ja.org/review-kt133a-1-en.phtml for
|
||||
* the info on which Mr Breese based his work.
|
||||
*
|
||||
|
@ -424,10 +423,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, quirk_ati_
|
|||
*/
|
||||
static void quirk_amd_nl_class(struct pci_dev *pdev)
|
||||
{
|
||||
/*
|
||||
* Use 'USB Device' (0x0c03fe) instead of PCI header provided
|
||||
*/
|
||||
pdev->class = 0x0c03fe;
|
||||
u32 class = pdev->class;
|
||||
|
||||
/* Use "USB Device (not host controller)" class */
|
||||
pdev->class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe;
|
||||
dev_info(&pdev->dev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n",
|
||||
class, pdev->class);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB,
|
||||
quirk_amd_nl_class);
|
||||
|
@ -1569,6 +1570,18 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB3
|
|||
|
||||
#endif
|
||||
|
||||
static void quirk_jmicron_async_suspend(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->multifunction) {
|
||||
device_disable_async_suspend(&dev->dev);
|
||||
dev_info(&dev->dev, "async suspend disabled to avoid multi-function power-on ordering issue\n");
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, 8, quirk_jmicron_async_suspend);
|
||||
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0, quirk_jmicron_async_suspend);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x2362, quirk_jmicron_async_suspend);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, 0x236f, quirk_jmicron_async_suspend);
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
static void quirk_alder_ioapic(struct pci_dev *pdev)
|
||||
{
|
||||
|
@ -1894,6 +1907,15 @@ static void quirk_netmos(struct pci_dev *dev)
|
|||
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
|
||||
PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
|
||||
|
||||
static void quirk_f0_vpd_link(struct pci_dev *dev)
|
||||
{
|
||||
if (!dev->multifunction || !PCI_FUNC(dev->devfn))
|
||||
return;
|
||||
dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
|
||||
PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
|
||||
|
||||
static void quirk_e100_interrupt(struct pci_dev *dev)
|
||||
{
|
||||
u16 command, pmcsr;
|
||||
|
@ -1986,14 +2008,18 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
|
|||
|
||||
static void fixup_rev1_53c810(struct pci_dev *dev)
|
||||
{
|
||||
/* rev 1 ncr53c810 chips don't set the class at all which means
|
||||
u32 class = dev->class;
|
||||
|
||||
/*
|
||||
* rev 1 ncr53c810 chips don't set the class at all which means
|
||||
* they don't get their resources remapped. Fix that here.
|
||||
*/
|
||||
if (class)
|
||||
return;
|
||||
|
||||
if (dev->class == PCI_CLASS_NOT_DEFINED) {
|
||||
dev_info(&dev->dev, "NCR 53c810 rev 1 detected; setting PCI class\n");
|
||||
dev->class = PCI_CLASS_STORAGE_SCSI;
|
||||
}
|
||||
dev->class = PCI_CLASS_STORAGE_SCSI << 8;
|
||||
dev_info(&dev->dev, "NCR 53c810 rev 1 PCI class overridden (%#08x -> %#08x)\n",
|
||||
class, dev->class);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
|
||||
|
||||
|
@ -2241,7 +2267,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, quirk_amd_780_apc_msi);
|
|||
* return 1 if a HT MSI capability is found and enabled */
|
||||
static int msi_ht_cap_enabled(struct pci_dev *dev)
|
||||
{
|
||||
int pos, ttl = 48;
|
||||
int pos, ttl = PCI_FIND_CAP_TTL;
|
||||
|
||||
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
|
||||
while (pos && ttl--) {
|
||||
|
@ -2300,7 +2326,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
|
|||
/* Force enable MSI mapping capability on HT bridges */
|
||||
static void ht_enable_msi_mapping(struct pci_dev *dev)
|
||||
{
|
||||
int pos, ttl = 48;
|
||||
int pos, ttl = PCI_FIND_CAP_TTL;
|
||||
|
||||
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
|
||||
while (pos && ttl--) {
|
||||
|
@ -2379,7 +2405,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
|
|||
|
||||
static int ht_check_msi_mapping(struct pci_dev *dev)
|
||||
{
|
||||
int pos, ttl = 48;
|
||||
int pos, ttl = PCI_FIND_CAP_TTL;
|
||||
int found = 0;
|
||||
|
||||
/* check if there is HT MSI cap or enabled on this device */
|
||||
|
@ -2504,7 +2530,7 @@ out:
|
|||
|
||||
static void ht_disable_msi_mapping(struct pci_dev *dev)
|
||||
{
|
||||
int pos, ttl = 48;
|
||||
int pos, ttl = PCI_FIND_CAP_TTL;
|
||||
|
||||
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
|
||||
while (pos && ttl--) {
|
||||
|
@ -2829,12 +2855,15 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
|
|||
|
||||
static void fixup_ti816x_class(struct pci_dev *dev)
|
||||
{
|
||||
u32 class = dev->class;
|
||||
|
||||
/* TI 816x devices do not have class code set when in PCIe boot mode */
|
||||
dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n");
|
||||
dev->class = PCI_CLASS_MULTIMEDIA_VIDEO;
|
||||
dev->class = PCI_CLASS_MULTIMEDIA_VIDEO << 8;
|
||||
dev_info(&dev->dev, "PCI class overridden (%#08x -> %#08x)\n",
|
||||
class, dev->class);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800,
|
||||
PCI_CLASS_NOT_DEFINED, 0, fixup_ti816x_class);
|
||||
PCI_CLASS_NOT_DEFINED, 8, fixup_ti816x_class);
|
||||
|
||||
/* Some PCIe devices do not work reliably with the claimed maximum
|
||||
* payload size supported.
|
||||
|
@ -2862,7 +2891,8 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)
|
|||
int err;
|
||||
u16 rcc;
|
||||
|
||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF)
|
||||
if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
|
||||
pcie_bus_config == PCIE_BUS_DEFAULT)
|
||||
return;
|
||||
|
||||
/* Intel errata specifies bits to change but does not say what they are.
|
||||
|
@ -3028,7 +3058,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay);
|
|||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay);
|
||||
|
||||
/* Intel Cherrytrail devices do not need 10ms d3_delay */
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay);
|
||||
/*
|
||||
* Some devices may pass our check in pci_intx_mask_supported if
|
||||
* PCI_COMMAND_INTX_DISABLE works though they actually do not properly
|
||||
|
@ -3326,28 +3365,6 @@ fs_initcall_sync(pci_apply_final_quirks);
|
|||
* reset a single function if other methods (e.g. FLR, PM D0->D3) are
|
||||
* not available.
|
||||
*/
|
||||
static int reset_intel_generic_dev(struct pci_dev *dev, int probe)
|
||||
{
|
||||
int pos;
|
||||
|
||||
/* only implement PCI_CLASS_SERIAL_USB at present */
|
||||
if (dev->class == PCI_CLASS_SERIAL_USB) {
|
||||
pos = pci_find_capability(dev, PCI_CAP_ID_VNDR);
|
||||
if (!pos)
|
||||
return -ENOTTY;
|
||||
|
||||
if (probe)
|
||||
return 0;
|
||||
|
||||
pci_write_config_byte(dev, pos + 0x4, 1);
|
||||
msleep(100);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return -ENOTTY;
|
||||
}
|
||||
}
|
||||
|
||||
static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
|
||||
{
|
||||
/*
|
||||
|
@ -3506,8 +3523,6 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
|
|||
reset_ivb_igd },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA,
|
||||
reset_ivb_igd },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
|
||||
reset_intel_generic_dev },
|
||||
{ PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
|
||||
reset_chelsio_generic_dev },
|
||||
{ 0 }
|
||||
|
@ -3654,6 +3669,28 @@ DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias);
|
|||
/* Intel 82801, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c49 */
|
||||
DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias);
|
||||
|
||||
/*
|
||||
* Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero)
|
||||
* class code. Fix it.
|
||||
*/
|
||||
static void quirk_tw686x_class(struct pci_dev *pdev)
|
||||
{
|
||||
u32 class = pdev->class;
|
||||
|
||||
/* Use "Multimedia controller" class */
|
||||
pdev->class = (PCI_CLASS_MULTIMEDIA_OTHER << 8) | 0x01;
|
||||
dev_info(&pdev->dev, "TW686x PCI class overridden (%#08x -> %#08x)\n",
|
||||
class, pdev->class);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6864, PCI_CLASS_NOT_DEFINED, 8,
|
||||
quirk_tw686x_class);
|
||||
DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6865, PCI_CLASS_NOT_DEFINED, 8,
|
||||
quirk_tw686x_class);
|
||||
DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6868, PCI_CLASS_NOT_DEFINED, 8,
|
||||
quirk_tw686x_class);
|
||||
DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6869, PCI_CLASS_NOT_DEFINED, 8,
|
||||
quirk_tw686x_class);
|
||||
|
||||
/*
|
||||
* AMD has indicated that the devices below do not support peer-to-peer
|
||||
* in any system where they are found in the southbridge with an AMD
|
||||
|
@ -3848,6 +3885,9 @@ static const struct pci_dev_acs_enabled {
|
|||
{ PCI_VENDOR_ID_INTEL, 0x105F, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, 0x1060, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, 0x10D9, pci_quirk_mf_endpoint_acs },
|
||||
/* I219 */
|
||||
{ PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs },
|
||||
{ PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs },
|
||||
/* Intel PCH root ports */
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
|
||||
{ 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
struct kset *pci_slots_kset;
|
||||
EXPORT_SYMBOL_GPL(pci_slots_kset);
|
||||
static DEFINE_MUTEX(pci_slot_mutex);
|
||||
|
||||
static ssize_t pci_slot_attr_show(struct kobject *kobj,
|
||||
struct attribute *attr, char *buf)
|
||||
|
@ -106,9 +107,11 @@ static void pci_slot_release(struct kobject *kobj)
|
|||
dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
|
||||
slot->number, pci_slot_name(slot));
|
||||
|
||||
down_read(&pci_bus_sem);
|
||||
list_for_each_entry(dev, &slot->bus->devices, bus_list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = NULL;
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
list_del(&slot->list);
|
||||
|
||||
|
@ -191,12 +194,22 @@ static int rename_slot(struct pci_slot *slot, const char *name)
|
|||
return result;
|
||||
}
|
||||
|
||||
void pci_dev_assign_slot(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_slot *slot;
|
||||
|
||||
mutex_lock(&pci_slot_mutex);
|
||||
list_for_each_entry(slot, &dev->bus->slots, list)
|
||||
if (PCI_SLOT(dev->devfn) == slot->number)
|
||||
dev->slot = slot;
|
||||
mutex_unlock(&pci_slot_mutex);
|
||||
}
|
||||
|
||||
static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)
|
||||
{
|
||||
struct pci_slot *slot;
|
||||
/*
|
||||
* We already hold pci_bus_sem so don't worry
|
||||
*/
|
||||
|
||||
/* We already hold pci_slot_mutex */
|
||||
list_for_each_entry(slot, &parent->slots, list)
|
||||
if (slot->number == slot_nr) {
|
||||
kobject_get(&slot->kobj);
|
||||
|
@ -253,7 +266,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
|
|||
int err = 0;
|
||||
char *slot_name = NULL;
|
||||
|
||||
down_write(&pci_bus_sem);
|
||||
mutex_lock(&pci_slot_mutex);
|
||||
|
||||
if (slot_nr == -1)
|
||||
goto placeholder;
|
||||
|
@ -301,16 +314,18 @@ placeholder:
|
|||
INIT_LIST_HEAD(&slot->list);
|
||||
list_add(&slot->list, &parent->slots);
|
||||
|
||||
down_read(&pci_bus_sem);
|
||||
list_for_each_entry(dev, &parent->devices, bus_list)
|
||||
if (PCI_SLOT(dev->devfn) == slot_nr)
|
||||
dev->slot = slot;
|
||||
up_read(&pci_bus_sem);
|
||||
|
||||
dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
|
||||
slot_nr, pci_slot_name(slot));
|
||||
|
||||
out:
|
||||
kfree(slot_name);
|
||||
up_write(&pci_bus_sem);
|
||||
mutex_unlock(&pci_slot_mutex);
|
||||
return slot;
|
||||
err:
|
||||
kfree(slot);
|
||||
|
@ -332,9 +347,9 @@ void pci_destroy_slot(struct pci_slot *slot)
|
|||
dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
|
||||
slot->number, atomic_read(&slot->kobj.kref.refcount) - 1);
|
||||
|
||||
down_write(&pci_bus_sem);
|
||||
mutex_lock(&pci_slot_mutex);
|
||||
kobject_put(&slot->kobj);
|
||||
up_write(&pci_bus_sem);
|
||||
mutex_unlock(&pci_slot_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_destroy_slot);
|
||||
|
||||
|
|
|
@ -3,55 +3,6 @@
|
|||
|
||||
#include <linux/pci.h>
|
||||
|
||||
/* Address Translation Service */
|
||||
struct pci_ats {
|
||||
int pos; /* capability position */
|
||||
int stu; /* Smallest Translation Unit */
|
||||
int qdep; /* Invalidate Queue Depth */
|
||||
int ref_cnt; /* Physical Function reference count */
|
||||
unsigned int is_enabled:1; /* Enable bit is set */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI_ATS
|
||||
|
||||
int pci_enable_ats(struct pci_dev *dev, int ps);
|
||||
void pci_disable_ats(struct pci_dev *dev);
|
||||
int pci_ats_queue_depth(struct pci_dev *dev);
|
||||
|
||||
/**
|
||||
* pci_ats_enabled - query the ATS status
|
||||
* @dev: the PCI device
|
||||
*
|
||||
* Returns 1 if ATS capability is enabled, or 0 if not.
|
||||
*/
|
||||
static inline int pci_ats_enabled(struct pci_dev *dev)
|
||||
{
|
||||
return dev->ats && dev->ats->is_enabled;
|
||||
}
|
||||
|
||||
#else /* CONFIG_PCI_ATS */
|
||||
|
||||
static inline int pci_enable_ats(struct pci_dev *dev, int ps)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void pci_disable_ats(struct pci_dev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int pci_ats_queue_depth(struct pci_dev *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int pci_ats_enabled(struct pci_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PCI_ATS */
|
||||
|
||||
#ifdef CONFIG_PCI_PRI
|
||||
|
||||
int pci_enable_pri(struct pci_dev *pdev, u32 reqs);
|
||||
|
|
|
@ -180,6 +180,8 @@ enum pci_dev_flags {
|
|||
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6),
|
||||
/* Do not use PM reset even if device advertises NoSoftRst- */
|
||||
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7),
|
||||
/* Get VPD from function 0 VPD */
|
||||
PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8),
|
||||
};
|
||||
|
||||
enum pci_irq_reroute_variant {
|
||||
|
@ -343,6 +345,7 @@ struct pci_dev {
|
|||
unsigned int msi_enabled:1;
|
||||
unsigned int msix_enabled:1;
|
||||
unsigned int ari_enabled:1; /* ARI forwarding */
|
||||
unsigned int ats_enabled:1; /* Address Translation Service */
|
||||
unsigned int is_managed:1;
|
||||
unsigned int needs_freset:1; /* Dev requires fundamental reset */
|
||||
unsigned int state_saved:1;
|
||||
|
@ -375,7 +378,9 @@ struct pci_dev {
|
|||
struct pci_sriov *sriov; /* SR-IOV capability related */
|
||||
struct pci_dev *physfn; /* the PF this VF is associated with */
|
||||
};
|
||||
struct pci_ats *ats; /* Address Translation Service */
|
||||
u16 ats_cap; /* ATS Capability offset */
|
||||
u8 ats_stu; /* ATS Smallest Translation Unit */
|
||||
atomic_t ats_ref_cnt; /* number of VFs with ATS enabled */
|
||||
#endif
|
||||
phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
|
||||
size_t romlen; /* Length of ROM if it's not from the BAR */
|
||||
|
@ -446,7 +451,8 @@ struct pci_bus {
|
|||
struct list_head children; /* list of child buses */
|
||||
struct list_head devices; /* list of devices on this bus */
|
||||
struct pci_dev *self; /* bridge device as seen by parent */
|
||||
struct list_head slots; /* list of slots on this bus */
|
||||
struct list_head slots; /* list of slots on this bus;
|
||||
protected by pci_slot_mutex */
|
||||
struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
|
||||
struct list_head resources; /* address space routed to this bus */
|
||||
struct resource busn_res; /* bus numbers routed to this bus */
|
||||
|
@ -738,10 +744,11 @@ struct pci_driver {
|
|||
void pcie_bus_configure_settings(struct pci_bus *bus);
|
||||
|
||||
enum pcie_bus_config_types {
|
||||
PCIE_BUS_TUNE_OFF,
|
||||
PCIE_BUS_SAFE,
|
||||
PCIE_BUS_PERFORMANCE,
|
||||
PCIE_BUS_PEER2PEER,
|
||||
PCIE_BUS_TUNE_OFF, /* don't touch MPS at all */
|
||||
PCIE_BUS_DEFAULT, /* ensure MPS matches upstream bridge */
|
||||
PCIE_BUS_SAFE, /* use largest MPS boot-time devices support */
|
||||
PCIE_BUS_PERFORMANCE, /* use MPS and MRRS for best performance */
|
||||
PCIE_BUS_PEER2PEER, /* set MPS = 128 for all devices */
|
||||
};
|
||||
|
||||
extern enum pcie_bus_config_types pcie_bus_config;
|
||||
|
@ -787,6 +794,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
|||
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
|
||||
int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
|
||||
void pci_bus_release_busn_res(struct pci_bus *b);
|
||||
struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata,
|
||||
struct list_head *resources,
|
||||
struct msi_controller *msi);
|
||||
struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata,
|
||||
struct list_head *resources);
|
||||
|
@ -797,6 +808,11 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
|
|||
const char *name,
|
||||
struct hotplug_slot *hotplug);
|
||||
void pci_destroy_slot(struct pci_slot *slot);
|
||||
#ifdef CONFIG_SYSFS
|
||||
void pci_dev_assign_slot(struct pci_dev *dev);
|
||||
#else
|
||||
static inline void pci_dev_assign_slot(struct pci_dev *dev) { }
|
||||
#endif
|
||||
int pci_scan_slot(struct pci_bus *bus, int devfn);
|
||||
struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn);
|
||||
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
|
||||
|
@ -963,6 +979,23 @@ static inline int pci_is_managed(struct pci_dev *pdev)
|
|||
return pdev->is_managed;
|
||||
}
|
||||
|
||||
static inline void pci_set_managed_irq(struct pci_dev *pdev, unsigned int irq)
|
||||
{
|
||||
pdev->irq = irq;
|
||||
pdev->irq_managed = 1;
|
||||
}
|
||||
|
||||
static inline void pci_reset_managed_irq(struct pci_dev *pdev)
|
||||
{
|
||||
pdev->irq = 0;
|
||||
pdev->irq_managed = 0;
|
||||
}
|
||||
|
||||
static inline bool pci_has_managed_irq(struct pci_dev *pdev)
|
||||
{
|
||||
return pdev->irq_managed && pdev->irq > 0;
|
||||
}
|
||||
|
||||
void pci_disable_device(struct pci_dev *dev);
|
||||
|
||||
extern unsigned int pcibios_max_latency;
|
||||
|
@ -1295,6 +1328,19 @@ int ht_create_irq(struct pci_dev *dev, int idx);
|
|||
void ht_destroy_irq(unsigned int irq);
|
||||
#endif /* CONFIG_HT_IRQ */
|
||||
|
||||
#ifdef CONFIG_PCI_ATS
|
||||
/* Address Translation Service */
|
||||
void pci_ats_init(struct pci_dev *dev);
|
||||
int pci_enable_ats(struct pci_dev *dev, int ps);
|
||||
void pci_disable_ats(struct pci_dev *dev);
|
||||
int pci_ats_queue_depth(struct pci_dev *dev);
|
||||
#else
|
||||
static inline void pci_ats_init(struct pci_dev *d) { }
|
||||
static inline int pci_enable_ats(struct pci_dev *d, int ps) { return -ENODEV; }
|
||||
static inline void pci_disable_ats(struct pci_dev *d) { }
|
||||
static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
|
||||
#endif
|
||||
|
||||
void pci_cfg_access_lock(struct pci_dev *dev);
|
||||
bool pci_cfg_access_trylock(struct pci_dev *dev);
|
||||
void pci_cfg_access_unlock(struct pci_dev *dev);
|
||||
|
@ -1646,6 +1692,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
|
|||
int pcibios_add_device(struct pci_dev *dev);
|
||||
void pcibios_release_device(struct pci_dev *dev);
|
||||
void pcibios_penalize_isa_irq(int irq, int active);
|
||||
int pcibios_alloc_irq(struct pci_dev *dev);
|
||||
void pcibios_free_irq(struct pci_dev *dev);
|
||||
|
||||
#ifdef CONFIG_HIBERNATE_CALLBACKS
|
||||
extern struct dev_pm_ops pcibios_pm_ops;
|
||||
|
|
Loading…
Reference in New Issue