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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user