提交 26f8b7ed 编写于 作者: L Linus Torvalds

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
  ...
...@@ -23,6 +23,9 @@ PCIe Designware Controller ...@@ -23,6 +23,9 @@ PCIe Designware Controller
interrupt-map-mask, interrupt-map-mask,
interrupt-map : as specified in ../designware-pcie.txt 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: Example:
axi { axi {
compatible = "simple-bus"; compatible = "simple-bus";
......
...@@ -242,12 +242,7 @@ pci_restore_srm_config(void) ...@@ -242,12 +242,7 @@ pci_restore_srm_config(void)
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
struct pci_dev *dev = bus->self; struct pci_dev *dev;
if (pci_has_flag(PCI_PROBE_ONLY) && dev &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pci_read_bridge_bases(bus);
}
list_for_each_entry(dev, &bus->devices, bus_list) { list_for_each_entry(dev, &bus->devices, bus_list) {
pdev_save_srm_config(dev); pdev_save_srm_config(dev);
......
...@@ -693,3 +693,7 @@ ...@@ -693,3 +693,7 @@
}; };
}; };
}; };
&pcie1 {
gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
};
...@@ -211,7 +211,7 @@ ...@@ -211,7 +211,7 @@
#address-cells = <1>; #address-cells = <1>;
ranges = <0x51000000 0x51000000 0x3000 ranges = <0x51000000 0x51000000 0x3000
0x0 0x20000000 0x10000000>; 0x0 0x20000000 0x10000000>;
pcie@51000000 { pcie1: pcie@51000000 {
compatible = "ti,dra7-pcie"; compatible = "ti,dra7-pcie";
reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>; reg = <0x51000000 0x2000>, <0x51002000 0x14c>, <0x1000 0x2000>;
reg-names = "rc_dbics", "ti_conf", "config"; reg-names = "rc_dbics", "ti_conf", "config";
......
...@@ -19,9 +19,7 @@ struct pci_bus; ...@@ -19,9 +19,7 @@ struct pci_bus;
struct device; struct device;
struct hw_pci { struct hw_pci {
#ifdef CONFIG_PCI_MSI
struct msi_controller *msi_ctrl; struct msi_controller *msi_ctrl;
#endif
struct pci_ops *ops; struct pci_ops *ops;
int nr_controllers; int nr_controllers;
void **private_data; void **private_data;
...@@ -42,9 +40,6 @@ struct hw_pci { ...@@ -42,9 +40,6 @@ struct hw_pci {
* Per-controller structure * Per-controller structure
*/ */
struct pci_sys_data { struct pci_sys_data {
#ifdef CONFIG_PCI_MSI
struct msi_controller *msi_ctrl;
#endif
struct list_head node; struct list_head node;
int busnr; /* primary bus number */ int busnr; /* primary bus number */
u64 mem_offset; /* bus->cpu memory mapping offset */ u64 mem_offset; /* bus->cpu memory mapping offset */
......
...@@ -18,15 +18,6 @@ ...@@ -18,15 +18,6 @@
static int debug_pci; 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 * We can't use pci_get_device() here since we are
* called from interrupt context. * called from interrupt context.
...@@ -459,12 +450,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, ...@@ -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++) { for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL); sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
if (!sys) if (WARN(!sys, "PCI: unable to allocate sys data!"))
panic("PCI: unable to allocate sys data!"); break;
#ifdef CONFIG_PCI_MSI
sys->msi_ctrl = hw->msi_ctrl;
#endif
sys->busnr = busnr; sys->busnr = busnr;
sys->swizzle = hw->swizzle; sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq; sys->map_irq = hw->map_irq;
...@@ -486,11 +474,14 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw, ...@@ -486,11 +474,14 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
if (hw->scan) if (hw->scan)
sys->bus = hw->scan(nr, sys); sys->bus = hw->scan(nr, sys);
else else
sys->bus = pci_scan_root_bus(parent, sys->busnr, sys->bus = pci_scan_root_bus_msi(parent,
hw->ops, sys, &sys->resources); sys->busnr, hw->ops, sys,
&sys->resources, hw->msi_ctrl);
if (!sys->bus) if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
panic("PCI: unable to scan bus!"); kfree(sys);
break;
}
busnr = sys->bus->busn_res.end + 1; busnr = sys->bus->busn_res.end + 1;
...@@ -521,6 +512,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw) ...@@ -521,6 +512,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
struct pci_bus *bus = sys->bus; struct pci_bus *bus = sys->bus;
if (!pci_has_flag(PCI_PROBE_ONLY)) { if (!pci_has_flag(PCI_PROBE_ONLY)) {
struct pci_bus *child;
/* /*
* Size the bridge windows. * Size the bridge windows.
*/ */
...@@ -530,25 +523,15 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw) ...@@ -530,25 +523,15 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
* Assign resources. * Assign resources.
*/ */
pci_bus_assign_resources(bus); pci_bus_assign_resources(bus);
}
list_for_each_entry(child, &bus->children, node)
pcie_bus_configure_settings(child);
}
/* /*
* Tell drivers about devices found. * Tell drivers about devices found.
*/ */
pci_bus_add_devices(bus); 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);
}
}
} }
#ifndef CONFIG_PCI_HOST_ITE8152 #ifndef CONFIG_PCI_HOST_ITE8152
......
...@@ -490,7 +490,8 @@ ...@@ -490,7 +490,8 @@
0xe0 0xd0000000 0x0 0x00040000>; /* PCI config space */ 0xe0 0xd0000000 0x0 0x00040000>; /* PCI config space */
reg-names = "csr", "cfg"; reg-names = "csr", "cfg";
ranges = <0x01000000 0x00 0x00000000 0xe0 0x10000000 0x00 0x00010000 /* io */ 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 dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map-mask = <0x0 0x0 0x0 0x7>;
...@@ -513,8 +514,9 @@ ...@@ -513,8 +514,9 @@
reg = < 0x00 0x1f2c0000 0x0 0x00010000 /* Controller registers */ reg = < 0x00 0x1f2c0000 0x0 0x00010000 /* Controller registers */
0xd0 0xd0000000 0x0 0x00040000>; /* PCI config space */ 0xd0 0xd0000000 0x0 0x00040000>; /* PCI config space */
reg-names = "csr", "cfg"; reg-names = "csr", "cfg";
ranges = <0x01000000 0x0 0x00000000 0xd0 0x10000000 0x00 0x00010000 /* io */ ranges = <0x01000000 0x00 0x00000000 0xd0 0x10000000 0x00 0x00010000 /* io */
0x02000000 0x0 0x80000000 0xd1 0x80000000 0x00 0x80000000>; /* mem */ 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 dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map-mask = <0x0 0x0 0x0 0x7>;
...@@ -537,8 +539,9 @@ ...@@ -537,8 +539,9 @@
reg = < 0x00 0x1f2d0000 0x0 0x00010000 /* Controller registers */ reg = < 0x00 0x1f2d0000 0x0 0x00010000 /* Controller registers */
0x90 0xd0000000 0x0 0x00040000>; /* PCI config space */ 0x90 0xd0000000 0x0 0x00040000>; /* PCI config space */
reg-names = "csr", "cfg"; reg-names = "csr", "cfg";
ranges = <0x01000000 0x0 0x00000000 0x90 0x10000000 0x0 0x00010000 /* io */ ranges = <0x01000000 0x00 0x00000000 0x90 0x10000000 0x00 0x00010000 /* io */
0x02000000 0x0 0x80000000 0x91 0x80000000 0x0 0x80000000>; /* mem */ 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 dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map-mask = <0x0 0x0 0x0 0x7>;
...@@ -561,8 +564,9 @@ ...@@ -561,8 +564,9 @@
reg = < 0x00 0x1f500000 0x0 0x00010000 /* Controller registers */ reg = < 0x00 0x1f500000 0x0 0x00010000 /* Controller registers */
0xa0 0xd0000000 0x0 0x00040000>; /* PCI config space */ 0xa0 0xd0000000 0x0 0x00040000>; /* PCI config space */
reg-names = "csr", "cfg"; reg-names = "csr", "cfg";
ranges = <0x01000000 0x0 0x00000000 0xa0 0x10000000 0x0 0x00010000 /* io */ ranges = <0x01000000 0x00 0x00000000 0xa0 0x10000000 0x00 0x00010000 /* io */
0x02000000 0x0 0x80000000 0xa1 0x80000000 0x0 0x80000000>; /* mem */ 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 dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map-mask = <0x0 0x0 0x0 0x7>;
...@@ -585,8 +589,9 @@ ...@@ -585,8 +589,9 @@
reg = < 0x00 0x1f510000 0x0 0x00010000 /* Controller registers */ reg = < 0x00 0x1f510000 0x0 0x00010000 /* Controller registers */
0xc0 0xd0000000 0x0 0x00200000>; /* PCI config space */ 0xc0 0xd0000000 0x0 0x00200000>; /* PCI config space */
reg-names = "csr", "cfg"; reg-names = "csr", "cfg";
ranges = <0x01000000 0x0 0x00000000 0xc0 0x10000000 0x0 0x00010000 /* io */ ranges = <0x01000000 0x00 0x00000000 0xc0 0x10000000 0x00 0x00010000 /* io */
0x02000000 0x0 0x80000000 0xc1 0x80000000 0x0 0x80000000>; /* mem */ 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 dma-ranges = <0x42000000 0x80 0x00000000 0x80 0x00000000 0x00 0x80000000
0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>; 0x42000000 0x00 0x00000000 0x00 0x00000000 0x80 0x00000000>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>; interrupt-map-mask = <0x0 0x0 0x0 0x7>;
......
...@@ -175,14 +175,6 @@ static void __init pcibios_assign_resources(void) ...@@ -175,14 +175,6 @@ static void __init pcibios_assign_resources(void)
if (!r->start && r->end) if (!r->start && r->end)
pci_assign_resource(dev, idx); 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 @@ ...@@ -14,14 +14,6 @@
#define DBG(x...) #define DBG(x...)
#endif #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; extern unsigned int __nongpreldata pci_probe;
/* pci-frv.c */ /* pci-frv.c */
......
...@@ -294,8 +294,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) ...@@ -294,8 +294,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number); printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
#endif #endif
pci_read_bridge_bases(bus);
if (bus->number == 0) { if (bus->number == 0) {
struct pci_dev *dev; struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) { list_for_each_entry(dev, &bus->devices, bus_list) {
......
...@@ -533,10 +533,9 @@ void pcibios_fixup_bus(struct pci_bus *b) ...@@ -533,10 +533,9 @@ void pcibios_fixup_bus(struct pci_bus *b)
{ {
struct pci_dev *dev; struct pci_dev *dev;
if (b->self) { if (b->self)
pci_read_bridge_bases(b);
pcibios_fixup_bridge_resources(b->self); pcibios_fixup_bridge_resources(b->self);
}
list_for_each_entry(dev, &b->devices, bus_list) list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev); pcibios_fixup_device_resources(dev);
platform_pci_fixup_bus(b); platform_pci_fixup_bus(b);
......
...@@ -863,14 +863,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus) ...@@ -863,14 +863,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus)
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
/* When called from the generic PCI probe, read PCI<->PCI bridge /* Fixup the bus */
* 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 */
pcibios_setup_bus_self(bus); pcibios_setup_bus_self(bus);
/* Now fixup devices on that bus */ /* Now fixup devices on that bus */
......
...@@ -311,12 +311,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) ...@@ -311,12 +311,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
void pcibios_fixup_bus(struct pci_bus *bus) 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); EXPORT_SYMBOL(PCIBIOS_MIN_IO);
......
...@@ -183,18 +183,16 @@ static int __init pcibios_assign_resources(void) ...@@ -183,18 +183,16 @@ static int __init pcibios_assign_resources(void)
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
struct resource *r; struct resource *r;
if (!(pci_probe & PCI_ASSIGN_ROMS)) { /* Try to use BIOS settings for ROMs, otherwise let
/* Try to use BIOS settings for ROMs, otherwise let pci_assign_unassigned_resources() allocate the new
pci_assign_unassigned_resources() allocate the new addresses. */
addresses. */ for_each_pci_dev(dev) {
for_each_pci_dev(dev) { r = &dev->resource[PCI_ROM_RESOURCE];
r = &dev->resource[PCI_ROM_RESOURCE]; if (!r->flags || !r->start)
if (!r->flags || !r->start) continue;
continue; if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) {
if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) { r->end -= r->start;
r->end -= r->start; r->start = 0;
r->start = 0;
}
} }
} }
......
...@@ -20,13 +20,6 @@ ...@@ -20,13 +20,6 @@
#define DBG(x...) #define DBG(x...)
#endif #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; extern unsigned int pci_probe;
/* pci-asb2305.c */ /* pci-asb2305.c */
......
...@@ -324,7 +324,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) ...@@ -324,7 +324,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
struct pci_dev *dev; struct pci_dev *dev;
if (bus->self) { if (bus->self) {
pci_read_bridge_bases(bus);
pcibios_fixup_bridge_resources(bus->self); pcibios_fixup_bridge_resources(bus->self);
} }
......
...@@ -1044,13 +1044,7 @@ void pcibios_set_master(struct pci_dev *dev) ...@@ -1044,13 +1044,7 @@ void pcibios_set_master(struct pci_dev *dev)
void pcibios_fixup_bus(struct pci_bus *bus) void pcibios_fixup_bus(struct pci_bus *bus)
{ {
/* When called from the generic PCI probe, read PCI<->PCI bridge /* Fixup the bus */
* 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 */
pcibios_setup_bus_self(bus); pcibios_setup_bus_self(bus);
/* Now fixup devices on that bus */ /* Now fixup devices on that bus */
......
...@@ -126,7 +126,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, ...@@ -126,7 +126,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
{ {
struct pci_dev *dev; struct pci_dev *dev;
const char *type; const char *type;
struct pci_slot *slot;
dev = pci_alloc_dev(bus); dev = pci_alloc_dev(bus);
if (!dev) if (!dev)
...@@ -145,10 +144,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, ...@@ -145,10 +144,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
dev->needs_freset = 0; /* pcie fundamental reset required */ dev->needs_freset = 0; /* pcie fundamental reset required */
set_pcie_port_type(dev); set_pcie_port_type(dev);
list_for_each_entry(slot, &dev->bus->slots, list) pci_dev_assign_slot(dev);
if (PCI_SLOT(dev->devfn) == slot->number)
dev->slot = slot;
dev->vendor = get_int_prop(node, "vendor-id", 0xffff); dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
dev->device = get_int_prop(node, "device-id", 0xffff); dev->device = get_int_prop(node, "device-id", 0xffff);
dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0); dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
......
...@@ -11,14 +11,6 @@ ...@@ -11,14 +11,6 @@
#include <asm/io.h> #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 0x100 /* PCI Control Register */
#define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */ #define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
#define SH4_PCICR_FTO 0x00000400 /* TRDY/IRDY Enable */ #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, ...@@ -249,7 +249,6 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
struct pci_bus *bus, int devfn) struct pci_bus *bus, int devfn)
{ {
struct dev_archdata *sd; struct dev_archdata *sd;
struct pci_slot *slot;
struct platform_device *op; struct platform_device *op;
struct pci_dev *dev; struct pci_dev *dev;
const char *type; const char *type;
...@@ -290,10 +289,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, ...@@ -290,10 +289,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
dev->multifunction = 0; /* maybe a lie? */ dev->multifunction = 0; /* maybe a lie? */
set_pcie_port_type(dev); set_pcie_port_type(dev);
list_for_each_entry(slot, &dev->bus->slots, list) pci_dev_assign_slot(dev);
if (PCI_SLOT(dev->devfn) == slot->number)
dev->slot = slot;
dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
dev->device = of_getintprop_default(node, "device-id", 0xffff); dev->device = of_getintprop_default(node, "device-id", 0xffff);
dev->subsystem_vendor = dev->subsystem_vendor =
......
...@@ -93,8 +93,6 @@ extern raw_spinlock_t pci_config_lock; ...@@ -93,8 +93,6 @@ extern raw_spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev); extern int (*pcibios_enable_irq)(struct pci_dev *dev);
extern void (*pcibios_disable_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 { struct pci_raw_ops {
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val); int reg, int len, u32 *val);
......
...@@ -166,7 +166,6 @@ void pcibios_fixup_bus(struct pci_bus *b) ...@@ -166,7 +166,6 @@ void pcibios_fixup_bus(struct pci_bus *b)
{ {
struct pci_dev *dev; struct pci_dev *dev;
pci_read_bridge_bases(b);
list_for_each_entry(dev, &b->devices, bus_list) list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev); pcibios_fixup_device_resources(dev);
} }
...@@ -673,24 +672,22 @@ int pcibios_add_device(struct pci_dev *dev) ...@@ -673,24 +672,22 @@ int pcibios_add_device(struct pci_dev *dev)
return 0; return 0;
} }
int pcibios_enable_device(struct pci_dev *dev, int mask) int pcibios_alloc_irq(struct pci_dev *dev)
{ {
int err; return pcibios_enable_irq(dev);
if ((err = pci_enable_resources(dev, mask)) < 0)
return err;
if (!pci_dev_msi_enabled(dev))
return pcibios_enable_irq(dev);
return 0;
} }
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); 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) int pci_ext_cfg_avail(void)
{ {
if (raw_pci_ext_ops) if (raw_pci_ext_ops)
......
...@@ -62,19 +62,6 @@ static void pci_fixup_umc_ide(struct pci_dev *d) ...@@ -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); 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) static void pci_fixup_latency(struct pci_dev *d)
{ {
/* /*
......
...@@ -211,7 +211,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) ...@@ -211,7 +211,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
struct irq_alloc_info info; struct irq_alloc_info info;
int polarity; int polarity;
if (dev->irq_managed && dev->irq > 0) if (pci_has_managed_irq(dev))
return 0; return 0;
if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER) 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) ...@@ -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) static void intel_mid_pci_irq_disable(struct pci_dev *dev)
{ {
if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed && if (pci_has_managed_irq(dev)) {
dev->irq > 0) {
mp_unmap_irq(dev->irq); mp_unmap_irq(dev->irq);
dev->irq_managed = 0; 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) ...@@ -1202,7 +1202,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
struct pci_dev *temp_dev; struct pci_dev *temp_dev;
int irq; int irq;
if (dev->irq_managed && dev->irq > 0) if (pci_has_managed_irq(dev))
return 0; return 0;
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
...@@ -1230,8 +1230,7 @@ static int pirq_enable_irq(struct pci_dev *dev) ...@@ -1230,8 +1230,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
} }
dev = temp_dev; dev = temp_dev;
if (irq >= 0) { if (irq >= 0) {
dev->irq_managed = 1; pci_set_managed_irq(dev, irq);
dev->irq = irq;
dev_info(&dev->dev, "PCI->APIC IRQ transform: " dev_info(&dev->dev, "PCI->APIC IRQ transform: "
"INT %c -> IRQ %d\n", 'A' + pin - 1, irq); "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
return 0; return 0;
...@@ -1257,24 +1256,10 @@ static int pirq_enable_irq(struct pci_dev *dev) ...@@ -1257,24 +1256,10 @@ static int pirq_enable_irq(struct pci_dev *dev)
return 0; 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) static void pirq_disable_irq(struct pci_dev *dev)
{ {
if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) && if (io_apic_assign_pci_irqs && pci_has_managed_irq(dev)) {
dev->irq_managed && dev->irq) {
mp_unmap_irq(dev->irq); mp_unmap_irq(dev->irq);
dev->irq = 0; pci_reset_managed_irq(dev);
dev->irq_managed = 0;
} }
} }
...@@ -210,10 +210,6 @@ subsys_initcall(pcibios_init); ...@@ -210,10 +210,6 @@ subsys_initcall(pcibios_init);
void pcibios_fixup_bus(struct pci_bus *bus) 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) void pcibios_set_master(struct pci_dev *dev)
......
...@@ -412,7 +412,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -412,7 +412,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
return 0; return 0;
} }
if (dev->irq_managed && dev->irq > 0) if (pci_has_managed_irq(dev))
return 0; return 0;
entry = acpi_pci_irq_lookup(dev, pin); entry = acpi_pci_irq_lookup(dev, pin);
...@@ -457,8 +457,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -457,8 +457,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
kfree(entry); kfree(entry);
return rc; return rc;
} }
dev->irq = rc; pci_set_managed_irq(dev, rc);
dev->irq_managed = 1;
if (link) if (link)
snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link); snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
...@@ -481,17 +480,9 @@ void acpi_pci_irq_disable(struct pci_dev *dev) ...@@ -481,17 +480,9 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
u8 pin; u8 pin;
pin = dev->pin; pin = dev->pin;
if (!pin || !dev->irq_managed || dev->irq <= 0) if (!pin || !pci_has_managed_irq(dev))
return; 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); entry = acpi_pci_irq_lookup(dev, pin);
if (!entry) if (!entry)
return; return;
...@@ -511,6 +502,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) ...@@ -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)); dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
if (gsi >= 0) { if (gsi >= 0) {
acpi_unregister_gsi(gsi); 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[] = { ...@@ -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 */ /* JMicron 362B and 362C have an AHCI function with IDE class code */
{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr }, { PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr }, { PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
/* May need to update quirk_jmicron_async_suspend() for additions */
/* ATI */ /* ATI */
{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ { 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) ...@@ -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) else if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
ahci_pci_bar = AHCI_PCI_BAR_CAVIUM; 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 */ /* acquire resources */
rc = pcim_enable_device(pdev); rc = pcim_enable_device(pdev);
if (rc) if (rc)
......
...@@ -143,18 +143,6 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i ...@@ -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 }; 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); return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
} }
......
...@@ -408,6 +408,10 @@ struct device_domain_info { ...@@ -408,6 +408,10 @@ struct device_domain_info {
struct list_head global; /* link to global list */ struct list_head global; /* link to global list */
u8 bus; /* PCI bus number */ u8 bus; /* PCI bus number */
u8 devfn; /* PCI devfn 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 device *dev; /* it's NULL for PCIe-to-PCI bridge */
struct intel_iommu *iommu; /* IOMMU used by this device */ struct intel_iommu *iommu; /* IOMMU used by this device */
struct dmar_domain *domain; /* pointer to domain */ struct dmar_domain *domain; /* pointer to domain */
...@@ -1391,19 +1395,26 @@ iommu_support_dev_iotlb (struct dmar_domain *domain, struct intel_iommu *iommu, ...@@ -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) static void iommu_enable_dev_iotlb(struct device_domain_info *info)
{ {
struct pci_dev *pdev;
if (!info || !dev_is_pci(info->dev)) if (!info || !dev_is_pci(info->dev))
return; 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) static void iommu_disable_dev_iotlb(struct device_domain_info *info)
{ {
if (!info->dev || !dev_is_pci(info->dev) || if (!info->ats.enabled)
!pci_ats_enabled(to_pci_dev(info->dev)))
return; return;
pci_disable_ats(to_pci_dev(info->dev)); pci_disable_ats(to_pci_dev(info->dev));
info->ats.enabled = 0;
} }
static void iommu_flush_dev_iotlb(struct dmar_domain *domain, static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
...@@ -1415,16 +1426,11 @@ 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); spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(info, &domain->devices, link) { list_for_each_entry(info, &domain->devices, link) {
struct pci_dev *pdev; if (!info->ats.enabled)
if (!info->dev || !dev_is_pci(info->dev))
continue;
pdev = to_pci_dev(info->dev);
if (!pci_ats_enabled(pdev))
continue; continue;
sid = info->bus << 8 | info->devfn; 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); qi_flush_dev_iotlb(info->iommu, sid, qdep, addr, mask);
} }
spin_unlock_irqrestore(&device_domain_lock, flags); spin_unlock_irqrestore(&device_domain_lock, flags);
...@@ -2275,6 +2281,8 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu, ...@@ -2275,6 +2281,8 @@ static struct dmar_domain *dmar_insert_dev_info(struct intel_iommu *iommu,
info->bus = bus; info->bus = bus;
info->devfn = devfn; info->devfn = devfn;
info->ats.enabled = 0;
info->ats.qdep = 0;
info->dev = dev; info->dev = dev;
info->domain = domain; info->domain = domain;
info->iommu = iommu; info->iommu = iommu;
......
...@@ -560,9 +560,6 @@ dino_fixup_bus(struct pci_bus *bus) ...@@ -560,9 +560,6 @@ dino_fixup_bus(struct pci_bus *bus)
} else if (bus->parent) { } else if (bus->parent) {
int i; int i;
pci_read_bridge_bases(bus);
for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
if((bus->self->resource[i].flags & if((bus->self->resource[i].flags &
(IORESOURCE_IO | IORESOURCE_MEM)) == 0) (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
......
...@@ -693,7 +693,6 @@ lba_fixup_bus(struct pci_bus *bus) ...@@ -693,7 +693,6 @@ lba_fixup_bus(struct pci_bus *bus)
if (bus->parent) { if (bus->parent) {
int i; int i;
/* PCI-PCI Bridge */ /* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
pci_claim_bridge_resource(bus->self, i); pci_claim_bridge_resource(bus->self, i);
} else { } else {
......
...@@ -33,6 +33,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o ...@@ -33,6 +33,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o
# #
obj-$(CONFIG_ALPHA) += setup-irq.o obj-$(CONFIG_ALPHA) += setup-irq.o
obj-$(CONFIG_ARM) += setup-irq.o obj-$(CONFIG_ARM) += setup-irq.o
obj-$(CONFIG_ARM64) += setup-irq.o
obj-$(CONFIG_UNICORE32) += setup-irq.o obj-$(CONFIG_UNICORE32) += setup-irq.o
obj-$(CONFIG_SUPERH) += setup-irq.o obj-$(CONFIG_SUPERH) += setup-irq.o
obj-$(CONFIG_MIPS) += setup-irq.o obj-$(CONFIG_MIPS) += setup-irq.o
......
...@@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = { ...@@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {
.release = pci_vpd_pci22_release, .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) int pci_vpd_pci22_init(struct pci_dev *dev)
{ {
struct pci_vpd_pci22 *vpd; struct pci_vpd_pci22 *vpd;
...@@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev) ...@@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
cap = pci_find_capability(dev, PCI_CAP_ID_VPD); cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
if (!cap) if (!cap)
return -ENODEV; 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); vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
if (!vpd) if (!vpd)
return -ENOMEM; return -ENOMEM;
vpd->base.len = PCI_VPD_PCI22_SIZE; 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); mutex_init(&vpd->lock);
vpd->cap = cap; vpd->cap = cap;
vpd->busy = false; vpd->busy = false;
...@@ -531,6 +590,14 @@ static inline int pcie_cap_version(const struct pci_dev *dev) ...@@ -531,6 +590,14 @@ static inline int pcie_cap_version(const struct pci_dev *dev)
return pcie_caps_reg(dev) & PCI_EXP_FLAGS_VERS; 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) bool pcie_cap_has_lnkctl(const struct pci_dev *dev)
{ {
int type = pci_pcie_type(dev); int type = pci_pcie_type(dev);
...@@ -546,10 +613,7 @@ bool pcie_cap_has_lnkctl(const struct pci_dev *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) static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev)
{ {
int type = pci_pcie_type(dev); return pcie_downstream_port(dev) &&
return (type == PCI_EXP_TYPE_ROOT_PORT ||
type == PCI_EXP_TYPE_DOWNSTREAM) &&
pcie_caps_reg(dev) & PCI_EXP_FLAGS_SLOT; 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) ...@@ -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, * State bit in the Slot Status register of Downstream Ports,
* which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8)
*/ */
if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && if (pci_is_pcie(dev) && pcie_downstream_port(dev) &&
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { pos == PCI_EXP_SLTSTA)
*val = PCI_EXP_SLTSTA_PDS; *val = PCI_EXP_SLTSTA_PDS;
}
return 0; return 0;
} }
...@@ -657,10 +720,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) ...@@ -657,10 +720,9 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val)
return ret; return ret;
} }
if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && if (pci_is_pcie(dev) && pcie_downstream_port(dev) &&
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { pos == PCI_EXP_SLTSTA)
*val = PCI_EXP_SLTSTA_PDS; *val = PCI_EXP_SLTSTA_PDS;
}
return 0; return 0;
} }
......
...@@ -17,34 +17,15 @@ ...@@ -17,34 +17,15 @@
#include "pci.h" #include "pci.h"
static int ats_alloc_one(struct pci_dev *dev, int ps) void pci_ats_init(struct pci_dev *dev)
{ {
int pos; int pos;
u16 cap;
struct pci_ats *ats;
pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS); pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
if (!pos) 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) dev->ats_cap = pos;
{
kfree(dev->ats);
dev->ats = NULL;
} }
/** /**
...@@ -56,43 +37,36 @@ static void ats_free_one(struct pci_dev *dev) ...@@ -56,43 +37,36 @@ static void ats_free_one(struct pci_dev *dev)
*/ */
int pci_enable_ats(struct pci_dev *dev, int ps) int pci_enable_ats(struct pci_dev *dev, int ps)
{ {
int rc;
u16 ctrl; u16 ctrl;
struct pci_dev *pdev;
BUG_ON(dev->ats && dev->ats->is_enabled); if (!dev->ats_cap)
if (ps < PCI_ATS_MIN_STU)
return -EINVAL; return -EINVAL;
if (dev->is_physfn || dev->is_virtfn) { if (WARN_ON(dev->ats_enabled))
struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn; return -EBUSY;
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) { if (ps < PCI_ATS_MIN_STU)
rc = ats_alloc_one(dev, ps); return -EINVAL;
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; ctrl = PCI_ATS_CTRL_ENABLE;
if (!dev->is_virtfn) if (dev->is_virtfn) {
ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU); pdev = pci_physfn(dev);
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl); 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; return 0;
} }
EXPORT_SYMBOL_GPL(pci_enable_ats); EXPORT_SYMBOL_GPL(pci_enable_ats);
...@@ -103,28 +77,25 @@ EXPORT_SYMBOL_GPL(pci_enable_ats); ...@@ -103,28 +77,25 @@ EXPORT_SYMBOL_GPL(pci_enable_ats);
*/ */
void pci_disable_ats(struct pci_dev *dev) void pci_disable_ats(struct pci_dev *dev)
{ {
struct pci_dev *pdev;
u16 ctrl; 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);
dev->ats->is_enabled = 0;
if (dev->is_physfn || dev->is_virtfn) { if (atomic_read(&dev->ats_ref_cnt))
struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn; return; /* VFs still enabled */
mutex_lock(&pdev->sriov->lock); if (dev->is_virtfn) {
pdev->ats->ref_cnt--; pdev = pci_physfn(dev);
if (!pdev->ats->ref_cnt) atomic_dec(&pdev->ats_ref_cnt);
ats_free_one(pdev);
mutex_unlock(&pdev->sriov->lock);
} }
if (!dev->is_physfn) pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, &ctrl);
ats_free_one(dev); 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); EXPORT_SYMBOL_GPL(pci_disable_ats);
...@@ -132,16 +103,13 @@ void pci_restore_ats_state(struct pci_dev *dev) ...@@ -132,16 +103,13 @@ void pci_restore_ats_state(struct pci_dev *dev)
{ {
u16 ctrl; u16 ctrl;
if (!pci_ats_enabled(dev)) if (!dev->ats_enabled)
return; return;
if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS))
BUG();
ctrl = PCI_ATS_CTRL_ENABLE; ctrl = PCI_ATS_CTRL_ENABLE;
if (!dev->is_virtfn) if (!dev->is_virtfn)
ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU); ctrl |= PCI_ATS_CTRL_STU(dev->ats_stu - PCI_ATS_MIN_STU);
pci_write_config_word(dev, dev->ats_cap + PCI_ATS_CTRL, ctrl);
pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
} }
EXPORT_SYMBOL_GPL(pci_restore_ats_state); EXPORT_SYMBOL_GPL(pci_restore_ats_state);
...@@ -159,23 +127,16 @@ 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 pci_ats_queue_depth(struct pci_dev *dev)
{ {
int pos;
u16 cap; u16 cap;
if (!dev->ats_cap)
return -EINVAL;
if (dev->is_virtfn) if (dev->is_virtfn)
return 0; return 0;
if (dev->ats) pci_read_config_word(dev, dev->ats_cap + PCI_ATS_CAP, &cap);
return dev->ats->qdep; return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) : PCI_ATS_MAX_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;
} }
EXPORT_SYMBOL_GPL(pci_ats_queue_depth); EXPORT_SYMBOL_GPL(pci_ats_queue_depth);
......
...@@ -53,7 +53,7 @@ config PCI_RCAR_GEN2_PCIE ...@@ -53,7 +53,7 @@ config PCI_RCAR_GEN2_PCIE
config PCI_HOST_GENERIC config PCI_HOST_GENERIC
bool "Generic PCI host controller" bool "Generic PCI host controller"
depends on ARM && OF depends on (ARM || ARM64) && OF
help help
Say Y here if you want to support a simple generic PCI host Say Y here if you want to support a simple generic PCI host
controller, such as the one emulated by kvmtool. controller, such as the one emulated by kvmtool.
...@@ -135,7 +135,7 @@ config PCIE_IPROC_PLATFORM ...@@ -135,7 +135,7 @@ config PCIE_IPROC_PLATFORM
through the generic platform bus interface through the generic platform bus interface
config PCIE_IPROC_BCMA 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) depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
select PCIE_IPROC select PCIE_IPROC
select BCMA select BCMA
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -83,6 +84,17 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset, ...@@ -83,6 +84,17 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
writel(value, pcie->base + 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) static int dra7xx_pcie_link_up(struct pcie_port *pp)
{ {
struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(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, ...@@ -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_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
irq_set_chip_data(irq, domain->host_data); irq_set_chip_data(irq, domain->host_data);
set_irq_flags(irq, IRQF_VALID);
return 0; return 0;
} }
...@@ -325,6 +336,9 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) ...@@ -325,6 +336,9 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
char name[10]; char name[10];
int gpio_sel;
enum of_gpio_flags flags;
unsigned long gpio_flags;
dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
if (!dra7xx) if (!dra7xx)
...@@ -382,9 +396,25 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) ...@@ -382,9 +396,25 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
pm_runtime_enable(dev); pm_runtime_enable(dev);
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
if (IS_ERR_VALUE(ret)) { if (ret < 0) {
dev_err(dev, "pm_runtime_get_sync failed\n"); 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); reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD);
...@@ -395,12 +425,14 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev) ...@@ -395,12 +425,14 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
ret = dra7xx_add_pcie_port(dra7xx, pdev); ret = dra7xx_add_pcie_port(dra7xx, pdev);
if (ret < 0) if (ret < 0)
goto err_add_port; goto err_gpio;
return 0; return 0;
err_add_port: err_gpio:
pm_runtime_put(dev); pm_runtime_put(dev);
err_get_sync:
pm_runtime_disable(dev); pm_runtime_disable(dev);
err_phy: err_phy:
...@@ -431,6 +463,85 @@ static int __exit dra7xx_pcie_remove(struct platform_device *pdev) ...@@ -431,6 +463,85 @@ static int __exit dra7xx_pcie_remove(struct platform_device *pdev)
return 0; 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[] = { static const struct of_device_id of_dra7xx_pcie_match[] = {
{ .compatible = "ti,dra7-pcie", }, { .compatible = "ti,dra7-pcie", },
{}, {},
...@@ -442,6 +553,7 @@ static struct platform_driver dra7xx_pcie_driver = { ...@@ -442,6 +553,7 @@ static struct platform_driver dra7xx_pcie_driver = {
.driver = { .driver = {
.name = "dra7-pcie", .name = "dra7-pcie",
.of_match_table = of_dra7xx_pcie_match, .of_match_table = of_dra7xx_pcie_match,
.pm = &dra7xx_pcie_pm_ops,
}, },
}; };
......
...@@ -38,7 +38,16 @@ struct gen_pci_cfg_windows { ...@@ -38,7 +38,16 @@ struct gen_pci_cfg_windows {
const struct gen_pci_cfg_bus_ops *ops; 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 { struct gen_pci {
#ifdef CONFIG_ARM
struct pci_sys_data sys;
#endif
struct pci_host_bridge host; struct pci_host_bridge host;
struct gen_pci_cfg_windows cfg; struct gen_pci_cfg_windows cfg;
struct list_head resources; struct list_head resources;
...@@ -48,8 +57,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus, ...@@ -48,8 +57,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
unsigned int devfn, unsigned int devfn,
int where) int where)
{ {
struct pci_sys_data *sys = bus->sysdata; struct gen_pci *pci = bus->sysdata;
struct gen_pci *pci = sys->private_data;
resource_size_t idx = bus->number - pci->cfg.bus_range->start; resource_size_t idx = bus->number - pci->cfg.bus_range->start;
return pci->cfg.win[idx] + ((devfn << 8) | where); 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, ...@@ -64,8 +72,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,
unsigned int devfn, unsigned int devfn,
int where) int where)
{ {
struct pci_sys_data *sys = bus->sysdata; struct gen_pci *pci = bus->sysdata;
struct gen_pci *pci = sys->private_data;
resource_size_t idx = bus->number - pci->cfg.bus_range->start; resource_size_t idx = bus->number - pci->cfg.bus_range->start;
return pci->cfg.win[idx] + ((devfn << 12) | where); return pci->cfg.win[idx] + ((devfn << 12) | where);
...@@ -198,13 +205,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci) ...@@ -198,13 +205,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
return 0; 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) static int gen_pci_probe(struct platform_device *pdev)
{ {
int err; int err;
...@@ -214,13 +214,7 @@ static int gen_pci_probe(struct platform_device *pdev) ...@@ -214,13 +214,7 @@ static int gen_pci_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
struct hw_pci hw = { struct pci_bus *bus, *child;
.nr_controllers = 1,
.private_data = (void **)&pci,
.setup = gen_pci_setup,
.map_irq = of_irq_parse_and_map_pci,
.ops = &gen_pci_ops,
};
if (!pci) if (!pci)
return -ENOMEM; return -ENOMEM;
...@@ -258,7 +252,27 @@ static int gen_pci_probe(struct platform_device *pdev) ...@@ -258,7 +252,27 @@ static int gen_pci_probe(struct platform_device *pdev)
return err; 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; return 0;
} }
......
...@@ -117,11 +117,7 @@ static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr) ...@@ -117,11 +117,7 @@ static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
val = addr << PCIE_PHY_CTRL_DATA_LOC; val = addr << PCIE_PHY_CTRL_DATA_LOC;
writel(val, dbi_base + PCIE_PHY_CTRL); writel(val, dbi_base + PCIE_PHY_CTRL);
ret = pcie_phy_poll_ack(dbi_base, 0); return pcie_phy_poll_ack(dbi_base, 0);
if (ret)
return ret;
return 0;
} }
/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */ /* 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) ...@@ -148,11 +144,7 @@ static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
/* deassert Read signal */ /* deassert Read signal */
writel(0x00, dbi_base + PCIE_PHY_CTRL); writel(0x00, dbi_base + PCIE_PHY_CTRL);
ret = pcie_phy_poll_ack(dbi_base, 0); return pcie_phy_poll_ack(dbi_base, 0);
if (ret)
return ret;
return 0;
} }
static int pcie_phy_write(void __iomem *dbi_base, int addr, int data) 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, ...@@ -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, irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip,
handle_level_irq); handle_level_irq);
irq_set_chip_data(irq, domain->host_data); irq_set_chip_data(irq, domain->host_data);
set_irq_flags(irq, IRQF_VALID);
return 0; return 0;
} }
...@@ -277,7 +276,6 @@ static int ks_dw_pcie_init_legacy_irq_map(struct irq_domain *d, ...@@ -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, irq_set_chip_and_handler(irq, &ks_dw_pcie_legacy_irq_chip,
handle_level_irq); handle_level_irq);
irq_set_chip_data(irq, d->host_data); irq_set_chip_data(irq, d->host_data);
set_irq_flags(irq, IRQF_VALID);
return 0; return 0;
} }
......
...@@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie) ...@@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
return; return;
pcie->msi = of_pci_find_msi_chip_by_node(msi_node); pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
of_node_put(msi_node);
if (pcie->msi) if (pcie->msi)
pcie->msi->dev = &pcie->pdev->dev; pcie->msi->dev = &pcie->pdev->dev;
......
...@@ -1248,7 +1248,6 @@ static int tegra_msi_map(struct irq_domain *domain, unsigned int irq, ...@@ -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_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq);
irq_set_chip_data(irq, domain->host_data); irq_set_chip_data(irq, domain->host_data);
set_irq_flags(irq, IRQF_VALID);
tegra_cpuidle_pcie_irqs_in_use(); tegra_cpuidle_pcie_irqs_in_use();
......
...@@ -223,7 +223,6 @@ static int xgene_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -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, irq_domain_set_info(domain, virq, msi_irq,
&xgene_msi_bottom_irq_chip, domain->host_data, &xgene_msi_bottom_irq_chip, domain->host_data,
handle_simple_irq, NULL, NULL); handle_simple_irq, NULL, NULL);
set_irq_flags(virq, IRQF_VALID);
return 0; return 0;
} }
...@@ -582,7 +581,6 @@ static int xgene_msi_probe(struct platform_device *pdev) ...@@ -582,7 +581,6 @@ static int xgene_msi_probe(struct platform_device *pdev)
static struct platform_driver xgene_msi_driver = { static struct platform_driver xgene_msi_driver = {
.driver = { .driver = {
.name = "xgene-msi", .name = "xgene-msi",
.owner = THIS_MODULE,
.of_match_table = xgene_msi_match_table, .of_match_table = xgene_msi_match_table,
}, },
.probe = xgene_msi_probe, .probe = xgene_msi_probe,
......
...@@ -321,8 +321,16 @@ static int xgene_pcie_map_ranges(struct xgene_pcie_port *port, ...@@ -321,8 +321,16 @@ static int xgene_pcie_map_ranges(struct xgene_pcie_port *port,
return ret; return ret;
break; break;
case IORESOURCE_MEM: case IORESOURCE_MEM:
xgene_pcie_setup_ob_reg(port, res, OMR1BARL, res->start, if (res->flags & IORESOURCE_PREFETCH)
res->start - window->offset); 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; break;
case IORESOURCE_BUS: case IORESOURCE_BUS:
break; break;
...@@ -514,6 +522,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus) ...@@ -514,6 +522,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
if (!bus->msi) if (!bus->msi)
return -ENODEV; return -ENODEV;
of_node_put(msi_node);
bus->msi->dev = &bus->dev; bus->msi->dev = &bus->dev;
return 0; return 0;
} }
......
...@@ -350,7 +350,6 @@ static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq, ...@@ -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_and_handler(irq, &dw_msi_irq_chip, handle_simple_irq);
irq_set_chip_data(irq, domain->host_data); irq_set_chip_data(irq, domain->host_data);
set_irq_flags(irq, IRQF_VALID);
return 0; return 0;
} }
...@@ -388,7 +387,7 @@ int dw_pcie_host_init(struct pcie_port *pp) ...@@ -388,7 +387,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
addrp = of_get_address(np, index, NULL, NULL); addrp = of_get_address(np, index, NULL, NULL);
pp->cfg0_mod_base = of_read_number(addrp, ns); pp->cfg0_mod_base = of_read_number(addrp, ns);
pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; 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"); dev_err(pp->dev, "missing *config* reg space\n");
} }
...@@ -526,7 +525,6 @@ int dw_pcie_host_init(struct pcie_port *pp) ...@@ -526,7 +525,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
dw_pcie_msi_chip.dev = pp->dev; dw_pcie_msi_chip.dev = pp->dev;
dw_pci.msi_ctrl = &dw_pcie_msi_chip;
#endif #endif
dw_pci.nr_controllers = 1; dw_pci.nr_controllers = 1;
...@@ -708,8 +706,15 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) ...@@ -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); struct pcie_port *pp = sys_to_pcie(sys);
pp->root_bus_nr = sys->busnr; 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) if (!bus)
return NULL; return NULL;
......
...@@ -58,9 +58,17 @@ ...@@ -58,9 +58,17 @@
#define SYS_RC_INTX_EN 0x330 #define SYS_RC_INTX_EN 0x330
#define SYS_RC_INTX_MASK 0xf #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, ...@@ -71,8 +79,7 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
unsigned int devfn, unsigned int devfn,
int where) int where)
{ {
struct pci_sys_data *sys = bus->sysdata; struct iproc_pcie *pcie = iproc_data(bus);
struct iproc_pcie *pcie = sys_to_pcie(sys);
unsigned slot = PCI_SLOT(devfn); unsigned slot = PCI_SLOT(devfn);
unsigned fn = PCI_FUNC(devfn); unsigned fn = PCI_FUNC(devfn);
unsigned busno = bus->number; unsigned busno = bus->number;
...@@ -186,32 +193,34 @@ static void iproc_pcie_enable(struct iproc_pcie *pcie) ...@@ -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 iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
{ {
int ret; int ret;
void *sysdata;
struct pci_bus *bus; struct pci_bus *bus;
if (!pcie || !pcie->dev || !pcie->base) if (!pcie || !pcie->dev || !pcie->base)
return -EINVAL; return -EINVAL;
if (pcie->phy) { ret = phy_init(pcie->phy);
ret = phy_init(pcie->phy); if (ret) {
if (ret) { dev_err(pcie->dev, "unable to initialize PCIe PHY\n");
dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); return ret;
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_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); iproc_pcie_reset(pcie);
#ifdef CONFIG_ARM
pcie->sysdata.private_data = pcie; pcie->sysdata.private_data = pcie;
sysdata = &pcie->sysdata;
#else
sysdata = pcie;
#endif
bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res);
&pcie->sysdata, res);
if (!bus) { if (!bus) {
dev_err(pcie->dev, "unable to create PCI root bus\n"); dev_err(pcie->dev, "unable to create PCI root bus\n");
ret = -ENOMEM; ret = -ENOMEM;
...@@ -229,7 +238,9 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) ...@@ -229,7 +238,9 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
pci_scan_child_bus(bus); pci_scan_child_bus(bus);
pci_assign_unassigned_bus_resources(bus); pci_assign_unassigned_bus_resources(bus);
#ifdef CONFIG_ARM
pci_fixup_irqs(pci_common_swizzle, pcie->map_irq); pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
#endif
pci_bus_add_devices(bus); pci_bus_add_devices(bus);
return 0; return 0;
...@@ -239,12 +250,9 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) ...@@ -239,12 +250,9 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
pci_remove_root_bus(bus); pci_remove_root_bus(bus);
err_power_off_phy: err_power_off_phy:
if (pcie->phy) phy_power_off(pcie->phy);
phy_power_off(pcie->phy);
err_exit_phy: err_exit_phy:
if (pcie->phy) phy_exit(pcie->phy);
phy_exit(pcie->phy);
return ret; return ret;
} }
EXPORT_SYMBOL(iproc_pcie_setup); EXPORT_SYMBOL(iproc_pcie_setup);
...@@ -254,10 +262,8 @@ int iproc_pcie_remove(struct iproc_pcie *pcie) ...@@ -254,10 +262,8 @@ int iproc_pcie_remove(struct iproc_pcie *pcie)
pci_stop_root_bus(pcie->root_bus); pci_stop_root_bus(pcie->root_bus);
pci_remove_root_bus(pcie->root_bus); pci_remove_root_bus(pcie->root_bus);
if (pcie->phy) { phy_power_off(pcie->phy);
phy_power_off(pcie->phy); phy_exit(pcie->phy);
phy_exit(pcie->phy);
}
return 0; return 0;
} }
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* @dev: pointer to device data structure * @dev: pointer to device data structure
* @base: PCIe host controller I/O register base * @base: PCIe host controller I/O register base
* @resources: linked list of all PCI resources * @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 * @root_bus: pointer to root bus
* @phy: optional PHY device that controls the Serdes * @phy: optional PHY device that controls the Serdes
* @irqs: interrupt IDs * @irqs: interrupt IDs
...@@ -29,7 +29,9 @@ ...@@ -29,7 +29,9 @@
struct iproc_pcie { struct iproc_pcie {
struct device *dev; struct device *dev;
void __iomem *base; void __iomem *base;
#ifdef CONFIG_ARM
struct pci_sys_data sysdata; struct pci_sys_data sysdata;
#endif
struct pci_bus *root_bus; struct pci_bus *root_bus;
struct phy *phy; struct phy *phy;
int irqs[IPROC_PCIE_MAX_NUM_IRQS]; int irqs[IPROC_PCIE_MAX_NUM_IRQS];
......
...@@ -664,7 +664,6 @@ static int rcar_msi_map(struct irq_domain *domain, unsigned int irq, ...@@ -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_and_handler(irq, &rcar_msi_irq_chip, handle_simple_irq);
irq_set_chip_data(irq, domain->host_data); irq_set_chip_data(irq, domain->host_data);
set_irq_flags(irq, IRQF_VALID);
return 0; return 0;
} }
......
...@@ -223,8 +223,7 @@ static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg) ...@@ -223,8 +223,7 @@ static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)
status = readl(&app_reg->int_sts); status = readl(&app_reg->int_sts);
if (status & MSI_CTRL_INT) { if (status & MSI_CTRL_INT) {
if (!IS_ENABLED(CONFIG_PCI_MSI)) BUG_ON(!IS_ENABLED(CONFIG_PCI_MSI));
BUG();
dw_handle_msi_irq(pp); dw_handle_msi_irq(pp);
} }
......
...@@ -338,7 +338,6 @@ static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq, ...@@ -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_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq);
irq_set_chip_data(irq, domain->host_data); irq_set_chip_data(irq, domain->host_data);
set_irq_flags(irq, IRQF_VALID);
return 0; return 0;
} }
...@@ -377,7 +376,6 @@ static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq, ...@@ -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_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
irq_set_chip_data(irq, domain->host_data); irq_set_chip_data(irq, domain->host_data);
set_irq_flags(irq, IRQF_VALID);
return 0; return 0;
} }
...@@ -449,14 +447,17 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) ...@@ -449,14 +447,17 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/* Clear interrupt FIFO register 1 */ if (!(val & XILINX_PCIE_RPIFR1_MSI_INTR)) {
pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, /* Clear interrupt FIFO register 1 */
XILINX_PCIE_REG_RPIFR1); pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK,
XILINX_PCIE_REG_RPIFR1);
/* Handle INTx Interrupt */ /* Handle INTx Interrupt */
val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >> val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1; XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1;
generic_handle_irq(irq_find_mapping(port->irq_domain, val)); generic_handle_irq(irq_find_mapping(port->irq_domain,
val));
}
} }
if (status & XILINX_PCIE_INTR_MSI) { 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) ...@@ -647,9 +648,15 @@ static struct pci_bus *xilinx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
struct pci_bus *bus; struct pci_bus *bus;
port->root_busno = sys->busnr; 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; return bus;
} }
...@@ -847,7 +854,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev) ...@@ -847,7 +854,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
xilinx_pcie_msi_chip.dev = port->dev; xilinx_pcie_msi_chip.dev = port->dev;
hw.msi_ctrl = &xilinx_pcie_msi_chip;
#endif #endif
pci_common_init_dev(dev, &hw); pci_common_init_dev(dev, &hw);
......
...@@ -83,12 +83,12 @@ GET_STATUS(attention_status, u8) ...@@ -83,12 +83,12 @@ GET_STATUS(attention_status, u8)
GET_STATUS(latch_status, u8) GET_STATUS(latch_status, u8)
GET_STATUS(adapter_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; int retval;
u8 value; u8 value;
retval = get_power_status(slot->hotplug, &value); retval = get_power_status(pci_slot->hotplug, &value);
if (retval) if (retval)
return retval; return retval;
...@@ -140,22 +140,22 @@ static struct pci_slot_attribute hotplug_slot_attr_power = { ...@@ -140,22 +140,22 @@ static struct pci_slot_attribute hotplug_slot_attr_power = {
.store = power_write_file .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; int retval;
u8 value; u8 value;
retval = get_attention_status(slot->hotplug, &value); retval = get_attention_status(pci_slot->hotplug, &value);
if (retval) if (retval)
return retval; return retval;
return sprintf(buf, "%d\n", value); 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) size_t count)
{ {
struct hotplug_slot_ops *ops = slot->hotplug->ops; struct hotplug_slot_ops *ops = pci_slot->hotplug->ops;
unsigned long lattention; unsigned long lattention;
u8 attention; u8 attention;
int retval = 0; int retval = 0;
...@@ -169,7 +169,7 @@ static ssize_t attention_write_file(struct pci_slot *slot, const char *buf, ...@@ -169,7 +169,7 @@ static ssize_t attention_write_file(struct pci_slot *slot, const char *buf,
goto exit; goto exit;
} }
if (ops->set_attention_status) 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); module_put(ops->owner);
exit: exit:
...@@ -184,12 +184,12 @@ static struct pci_slot_attribute hotplug_slot_attr_attention = { ...@@ -184,12 +184,12 @@ static struct pci_slot_attribute hotplug_slot_attr_attention = {
.store = attention_write_file .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; int retval;
u8 value; u8 value;
retval = get_latch_status(slot->hotplug, &value); retval = get_latch_status(pci_slot->hotplug, &value);
if (retval) if (retval)
return retval; return retval;
...@@ -201,12 +201,12 @@ static struct pci_slot_attribute hotplug_slot_attr_latch = { ...@@ -201,12 +201,12 @@ static struct pci_slot_attribute hotplug_slot_attr_latch = {
.show = latch_read_file, .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; int retval;
u8 value; u8 value;
retval = get_adapter_status(slot->hotplug, &value); retval = get_adapter_status(pci_slot->hotplug, &value);
if (retval) if (retval)
return retval; return retval;
...@@ -307,43 +307,43 @@ static bool has_test_file(struct pci_slot *pci_slot) ...@@ -307,43 +307,43 @@ static bool has_test_file(struct pci_slot *pci_slot)
return false; return false;
} }
static int fs_add_slot(struct pci_slot *slot) static int fs_add_slot(struct pci_slot *pci_slot)
{ {
int retval = 0; int retval = 0;
/* Create symbolic link to the hotplug driver module */ /* 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)) { if (has_power_file(pci_slot)) {
retval = sysfs_create_file(&slot->kobj, retval = sysfs_create_file(&pci_slot->kobj,
&hotplug_slot_attr_power.attr); &hotplug_slot_attr_power.attr);
if (retval) if (retval)
goto exit_power; goto exit_power;
} }
if (has_attention_file(slot)) { if (has_attention_file(pci_slot)) {
retval = sysfs_create_file(&slot->kobj, retval = sysfs_create_file(&pci_slot->kobj,
&hotplug_slot_attr_attention.attr); &hotplug_slot_attr_attention.attr);
if (retval) if (retval)
goto exit_attention; goto exit_attention;
} }
if (has_latch_file(slot)) { if (has_latch_file(pci_slot)) {
retval = sysfs_create_file(&slot->kobj, retval = sysfs_create_file(&pci_slot->kobj,
&hotplug_slot_attr_latch.attr); &hotplug_slot_attr_latch.attr);
if (retval) if (retval)
goto exit_latch; goto exit_latch;
} }
if (has_adapter_file(slot)) { if (has_adapter_file(pci_slot)) {
retval = sysfs_create_file(&slot->kobj, retval = sysfs_create_file(&pci_slot->kobj,
&hotplug_slot_attr_presence.attr); &hotplug_slot_attr_presence.attr);
if (retval) if (retval)
goto exit_adapter; goto exit_adapter;
} }
if (has_test_file(slot)) { if (has_test_file(pci_slot)) {
retval = sysfs_create_file(&slot->kobj, retval = sysfs_create_file(&pci_slot->kobj,
&hotplug_slot_attr_test.attr); &hotplug_slot_attr_test.attr);
if (retval) if (retval)
goto exit_test; goto exit_test;
...@@ -352,45 +352,45 @@ static int fs_add_slot(struct pci_slot *slot) ...@@ -352,45 +352,45 @@ static int fs_add_slot(struct pci_slot *slot)
goto exit; goto exit;
exit_test: exit_test:
if (has_adapter_file(slot)) if (has_adapter_file(pci_slot))
sysfs_remove_file(&slot->kobj, sysfs_remove_file(&pci_slot->kobj,
&hotplug_slot_attr_presence.attr); &hotplug_slot_attr_presence.attr);
exit_adapter: exit_adapter:
if (has_latch_file(slot)) if (has_latch_file(pci_slot))
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);
exit_latch: exit_latch:
if (has_attention_file(slot)) if (has_attention_file(pci_slot))
sysfs_remove_file(&slot->kobj, sysfs_remove_file(&pci_slot->kobj,
&hotplug_slot_attr_attention.attr); &hotplug_slot_attr_attention.attr);
exit_attention: exit_attention:
if (has_power_file(slot)) if (has_power_file(pci_slot))
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr);
exit_power: exit_power:
pci_hp_remove_module_link(slot); pci_hp_remove_module_link(pci_slot);
exit: exit:
return retval; 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)) if (has_power_file(pci_slot))
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_power.attr);
if (has_attention_file(slot)) if (has_attention_file(pci_slot))
sysfs_remove_file(&slot->kobj, sysfs_remove_file(&pci_slot->kobj,
&hotplug_slot_attr_attention.attr); &hotplug_slot_attr_attention.attr);
if (has_latch_file(slot)) if (has_latch_file(pci_slot))
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); sysfs_remove_file(&pci_slot->kobj, &hotplug_slot_attr_latch.attr);
if (has_adapter_file(slot)) if (has_adapter_file(pci_slot))
sysfs_remove_file(&slot->kobj, sysfs_remove_file(&pci_slot->kobj,
&hotplug_slot_attr_presence.attr); &hotplug_slot_attr_presence.attr);
if (has_test_file(slot)) if (has_test_file(pci_slot))
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); 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) static struct hotplug_slot *get_slot_from_name(const char *name)
...@@ -467,37 +467,37 @@ EXPORT_SYMBOL_GPL(__pci_hp_register); ...@@ -467,37 +467,37 @@ EXPORT_SYMBOL_GPL(__pci_hp_register);
/** /**
* pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem * 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 * The @slot must have been registered with the pci hotplug subsystem
* previously with a call to pci_hp_register(). * previously with a call to pci_hp_register().
* *
* Returns 0 if successful, anything else for an error. * 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 hotplug_slot *temp;
struct pci_slot *slot; struct pci_slot *pci_slot;
if (!hotplug) if (!slot)
return -ENODEV; return -ENODEV;
mutex_lock(&pci_hp_mutex); mutex_lock(&pci_hp_mutex);
temp = get_slot_from_name(hotplug_slot_name(hotplug)); temp = get_slot_from_name(hotplug_slot_name(slot));
if (temp != hotplug) { if (temp != slot) {
mutex_unlock(&pci_hp_mutex); mutex_unlock(&pci_hp_mutex);
return -ENODEV; return -ENODEV;
} }
list_del(&hotplug->slot_list); list_del(&slot->slot_list);
slot = hotplug->pci_slot; pci_slot = slot->pci_slot;
fs_remove_slot(slot); fs_remove_slot(pci_slot);
dbg("Removed slot %s from the list\n", hotplug_slot_name(hotplug)); dbg("Removed slot %s from the list\n", hotplug_slot_name(slot));
hotplug->release(hotplug); slot->release(slot);
slot->hotplug = NULL; pci_slot->hotplug = NULL;
pci_destroy_slot(slot); pci_destroy_slot(pci_slot);
mutex_unlock(&pci_hp_mutex); mutex_unlock(&pci_hp_mutex);
return 0; return 0;
...@@ -506,7 +506,7 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister); ...@@ -506,7 +506,7 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);
/** /**
* pci_hp_change_slot_info - changes the slot's information structure in the core * 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 * @info: pointer to the info copy into the slot's info structure
* *
* @slot must have been registered with the pci * @slot must have been registered with the pci
...@@ -514,13 +514,13 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister); ...@@ -514,13 +514,13 @@ EXPORT_SYMBOL_GPL(pci_hp_deregister);
* *
* Returns 0 if successful, anything else for an error. * 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) struct hotplug_slot_info *info)
{ {
if (!hotplug || !info) if (!slot || !info)
return -ENODEV; return -ENODEV;
memcpy(hotplug->info, info, sizeof(struct hotplug_slot_info)); memcpy(slot->info, info, sizeof(struct hotplug_slot_info));
return 0; return 0;
} }
......
...@@ -101,18 +101,12 @@ struct controller { ...@@ -101,18 +101,12 @@ struct controller {
unsigned int power_fault_detected; unsigned int power_fault_detected;
}; };
#define INT_BUTTON_IGNORE 0
#define INT_PRESENCE_ON 1 #define INT_PRESENCE_ON 1
#define INT_PRESENCE_OFF 2 #define INT_PRESENCE_OFF 2
#define INT_SWITCH_CLOSE 3 #define INT_POWER_FAULT 3
#define INT_SWITCH_OPEN 4 #define INT_BUTTON_PRESS 4
#define INT_POWER_FAULT 5 #define INT_LINK_UP 5
#define INT_POWER_FAULT_CLEAR 6 #define INT_LINK_DOWN 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 STATIC_STATE 0 #define STATIC_STATE 0
#define BLINKINGON_STATE 1 #define BLINKINGON_STATE 1
......
...@@ -109,21 +109,23 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout) ...@@ -109,21 +109,23 @@ static int pcie_poll_cmd(struct controller *ctrl, int timeout)
struct pci_dev *pdev = ctrl_dev(ctrl); struct pci_dev *pdev = ctrl_dev(ctrl);
u16 slot_status; u16 slot_status;
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); while (true) {
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;
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); 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) { if (slot_status & PCI_EXP_SLTSTA_CC) {
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, pcie_capability_write_word(pdev, PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_CC); PCI_EXP_SLTSTA_CC);
return 1; return 1;
} }
if (timeout < 0)
break;
msleep(10);
timeout -= 10;
} }
return 0; /* timeout */ return 0; /* timeout */
} }
...@@ -190,6 +192,11 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd, ...@@ -190,6 +192,11 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
pcie_wait_cmd(ctrl); pcie_wait_cmd(ctrl);
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_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 &= ~mask;
slot_ctrl |= (cmd & mask); slot_ctrl |= (cmd & mask);
ctrl->cmd_busy = 1; ctrl->cmd_busy = 1;
...@@ -205,6 +212,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd, ...@@ -205,6 +212,7 @@ static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
if (wait) if (wait)
pcie_wait_cmd(ctrl); pcie_wait_cmd(ctrl);
out:
mutex_unlock(&ctrl->ctrl_lock); mutex_unlock(&ctrl->ctrl_lock);
} }
...@@ -535,7 +543,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) ...@@ -535,7 +543,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
struct pci_dev *dev; struct pci_dev *dev;
struct slot *slot = ctrl->slot; struct slot *slot = ctrl->slot;
u16 detected, intr_loc; u16 detected, intr_loc;
u8 open, present; u8 present;
bool link; bool link;
/* /*
...@@ -546,9 +554,14 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) ...@@ -546,9 +554,14 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
intr_loc = 0; intr_loc = 0;
do { do {
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &detected); 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 | 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); PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC);
detected &= ~intr_loc; detected &= ~intr_loc;
intr_loc |= detected; intr_loc |= detected;
...@@ -581,15 +594,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) ...@@ -581,15 +594,6 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
if (!(intr_loc & ~PCI_EXP_SLTSTA_CC)) if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))
return IRQ_HANDLED; 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 */ /* Check Attention Button Pressed */
if (intr_loc & PCI_EXP_SLTSTA_ABP) { if (intr_loc & PCI_EXP_SLTSTA_ABP) {
ctrl_info(ctrl, "Button pressed on Slot(%s)\n", ctrl_info(ctrl, "Button pressed on Slot(%s)\n",
...@@ -649,13 +653,11 @@ void pcie_enable_notification(struct controller *ctrl) ...@@ -649,13 +653,11 @@ void pcie_enable_notification(struct controller *ctrl)
cmd |= PCI_EXP_SLTCTL_ABPE; cmd |= PCI_EXP_SLTCTL_ABPE;
else else
cmd |= PCI_EXP_SLTCTL_PDCE; cmd |= PCI_EXP_SLTCTL_PDCE;
if (MRL_SENS(ctrl))
cmd |= PCI_EXP_SLTCTL_MRLSCE;
if (!pciehp_poll_mode) if (!pciehp_poll_mode)
cmd |= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE; cmd |= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE;
mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | 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_HPIE | PCI_EXP_SLTCTL_CCIE |
PCI_EXP_SLTCTL_DLLSCE); PCI_EXP_SLTCTL_DLLSCE);
......
...@@ -77,24 +77,9 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev) ...@@ -77,24 +77,9 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
/* Arch hooks */ /* 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) 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; int err;
if (!chip || !chip->setup_irq) if (!chip || !chip->setup_irq)
...@@ -665,6 +650,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec) ...@@ -665,6 +650,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
pci_msi_set_enable(dev, 1); pci_msi_set_enable(dev, 1);
dev->msi_enabled = 1; dev->msi_enabled = 1;
pcibios_free_irq(dev);
dev->irq = entry->irq; dev->irq = entry->irq;
return 0; return 0;
} }
...@@ -792,9 +778,9 @@ static int msix_capability_init(struct pci_dev *dev, ...@@ -792,9 +778,9 @@ static int msix_capability_init(struct pci_dev *dev,
/* Set MSI-X enabled bits and unmask the function */ /* Set MSI-X enabled bits and unmask the function */
pci_intx_for_msi(dev, 0); pci_intx_for_msi(dev, 0);
dev->msix_enabled = 1; dev->msix_enabled = 1;
pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
pcibios_free_irq(dev);
return 0; return 0;
out_avail: out_avail:
...@@ -909,6 +895,7 @@ void pci_msi_shutdown(struct pci_dev *dev) ...@@ -909,6 +895,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
/* Restore dev->irq to its default pin-assertion irq */ /* Restore dev->irq to its default pin-assertion irq */
dev->irq = desc->msi_attrib.default_irq; dev->irq = desc->msi_attrib.default_irq;
pcibios_alloc_irq(dev);
} }
void pci_disable_msi(struct pci_dev *dev) void pci_disable_msi(struct pci_dev *dev)
...@@ -1009,6 +996,7 @@ void pci_msix_shutdown(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_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
pci_intx_for_msi(dev, 1); pci_intx_for_msi(dev, 1);
dev->msix_enabled = 0; dev->msix_enabled = 0;
pcibios_alloc_irq(dev);
} }
void pci_disable_msix(struct pci_dev *dev) void pci_disable_msix(struct pci_dev *dev)
......
...@@ -594,7 +594,7 @@ static struct acpi_device *acpi_pci_find_companion(struct device *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 * pci_acpi_optimize_delay - optimize PCI D3 and D3cold delay from ACPI
* @pdev: the PCI device whose delay is to be updated * @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 * 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. * 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) ...@@ -388,18 +388,31 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
return error; 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) static int pci_device_probe(struct device *dev)
{ {
int error = 0; int error;
struct pci_driver *drv; struct pci_dev *pci_dev = to_pci_dev(dev);
struct pci_dev *pci_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); pci_dev_get(pci_dev);
error = __pci_device_probe(drv, pci_dev); error = __pci_device_probe(drv, pci_dev);
if (error) if (error) {
pcibios_free_irq(pci_dev);
pci_dev_put(pci_dev); pci_dev_put(pci_dev);
}
return error; return error;
} }
...@@ -415,6 +428,7 @@ static int pci_device_remove(struct device *dev) ...@@ -415,6 +428,7 @@ static int pci_device_remove(struct device *dev)
drv->remove(pci_dev); drv->remove(pci_dev);
pm_runtime_put_noidle(dev); pm_runtime_put_noidle(dev);
} }
pcibios_free_irq(pci_dev);
pci_dev->driver = NULL; pci_dev->driver = NULL;
} }
......
...@@ -81,7 +81,7 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; ...@@ -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_io_size = DEFAULT_HOTPLUG_IO_SIZE;
unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_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 * 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) ...@@ -140,7 +140,6 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
EXPORT_SYMBOL_GPL(pci_ioremap_bar); EXPORT_SYMBOL_GPL(pci_ioremap_bar);
#endif #endif
#define PCI_FIND_CAP_TTL 48
static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn, static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
u8 pos, int cap, int *ttl) u8 pos, int cap, int *ttl)
...@@ -196,8 +195,6 @@ static int __pci_bus_find_cap_start(struct pci_bus *bus, ...@@ -196,8 +195,6 @@ static int __pci_bus_find_cap_start(struct pci_bus *bus,
return PCI_CAPABILITY_LIST; return PCI_CAPABILITY_LIST;
case PCI_HEADER_TYPE_CARDBUS: case PCI_HEADER_TYPE_CARDBUS:
return PCI_CB_CAPABILITY_LIST; return PCI_CB_CAPABILITY_LIST;
default:
return 0;
} }
return 0; return 0;
...@@ -972,7 +969,7 @@ static int pci_save_pcix_state(struct pci_dev *dev) ...@@ -972,7 +969,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
struct pci_cap_saved_state *save_state; struct pci_cap_saved_state *save_state;
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (pos <= 0) if (!pos)
return 0; return 0;
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX); 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) ...@@ -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); save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
if (!save_state || pos <= 0) if (!save_state || !pos)
return; return;
cap = (u16 *)&save_state->cap.data[0]; cap = (u16 *)&save_state->cap.data[0];
...@@ -1092,6 +1089,9 @@ void pci_restore_state(struct pci_dev *dev) ...@@ -1092,6 +1089,9 @@ void pci_restore_state(struct pci_dev *dev)
pci_restore_pcix_state(dev); pci_restore_pcix_state(dev);
pci_restore_msi_state(dev); pci_restore_msi_state(dev);
/* Restore ACS and IOV configuration state */
pci_enable_acs(dev);
pci_restore_iov_state(dev); pci_restore_iov_state(dev);
dev->state_saved = false; dev->state_saved = false;
...@@ -2159,7 +2159,7 @@ static int _pci_add_cap_save_buffer(struct pci_dev *dev, u16 cap, ...@@ -2159,7 +2159,7 @@ static int _pci_add_cap_save_buffer(struct pci_dev *dev, u16 cap,
else else
pos = pci_find_capability(dev, cap); pos = pci_find_capability(dev, cap);
if (pos <= 0) if (!pos)
return 0; return 0;
save_state = kzalloc(sizeof(*save_state) + size, GFP_KERNEL); save_state = kzalloc(sizeof(*save_state) + size, GFP_KERNEL);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#define PCI_CFG_SPACE_SIZE 256 #define PCI_CFG_SPACE_SIZE 256
#define PCI_CFG_SPACE_EXP_SIZE 4096 #define PCI_CFG_SPACE_EXP_SIZE 4096
#define PCI_FIND_CAP_TTL 48
extern const unsigned char pcie_link_speed[]; extern const unsigned char pcie_link_speed[];
bool pcie_cap_has_lnkctl(const struct pci_dev *dev); bool pcie_cap_has_lnkctl(const struct pci_dev *dev);
......
...@@ -448,7 +448,7 @@ static int resume_iter(struct device *dev, void *data) ...@@ -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 * @dev: PCI Express port to handle
*/ */
int pcie_port_device_resume(struct device *dev) 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) ...@@ -826,6 +826,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
child->bridge_ctl = bctl; child->bridge_ctl = bctl;
} }
/* Read and initialize bridge resources */
pci_read_bridge_bases(child);
cmax = pci_scan_child_bus(child); cmax = pci_scan_child_bus(child);
if (cmax > subordinate) if (cmax > subordinate)
dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n", 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) ...@@ -886,6 +889,9 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
if (!is_cardbus) { if (!is_cardbus) {
child->bridge_ctl = bctl; child->bridge_ctl = bctl;
/* Read and initialize bridge resources */
pci_read_bridge_bases(child);
max = pci_scan_child_bus(child); max = pci_scan_child_bus(child);
} else { } else {
/* /*
...@@ -1138,7 +1144,6 @@ int pci_setup_device(struct pci_dev *dev) ...@@ -1138,7 +1144,6 @@ int pci_setup_device(struct pci_dev *dev)
{ {
u32 class; u32 class;
u8 hdr_type; u8 hdr_type;
struct pci_slot *slot;
int pos = 0; int pos = 0;
struct pci_bus_region region; struct pci_bus_region region;
struct resource *res; struct resource *res;
...@@ -1154,10 +1159,7 @@ int pci_setup_device(struct pci_dev *dev) ...@@ -1154,10 +1159,7 @@ int pci_setup_device(struct pci_dev *dev)
dev->error_state = pci_channel_io_normal; dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev); set_pcie_port_type(dev);
list_for_each_entry(slot, &dev->bus->slots, list) pci_dev_assign_slot(dev);
if (PCI_SLOT(dev->devfn) == slot->number)
dev->slot = slot;
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
set this higher, assuming the system even supports it. */ set this higher, assuming the system even supports it. */
dev->dma_mask = 0xffffffff; dev->dma_mask = 0xffffffff;
...@@ -1273,13 +1275,51 @@ int pci_setup_device(struct pci_dev *dev) ...@@ -1273,13 +1275,51 @@ int pci_setup_device(struct pci_dev *dev)
bad: bad:
dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n", dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n",
dev->class, dev->hdr_type); 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... */ /* We found a fine healthy device, go go go... */
return 0; 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 = { static struct hpp_type0 pci_default_type0 = {
.revision = 1, .revision = 1,
.cache_line_size = 8, .cache_line_size = 8,
...@@ -1401,6 +1441,8 @@ static void pci_configure_device(struct pci_dev *dev) ...@@ -1401,6 +1441,8 @@ static void pci_configure_device(struct pci_dev *dev)
struct hotplug_params hpp; struct hotplug_params hpp;
int ret; int ret;
pci_configure_mps(dev);
memset(&hpp, 0, sizeof(hpp)); memset(&hpp, 0, sizeof(hpp));
ret = pci_get_hp_params(dev, &hpp); ret = pci_get_hp_params(dev, &hpp);
if (ret) if (ret)
...@@ -1545,6 +1587,9 @@ static void pci_init_capabilities(struct pci_dev *dev) ...@@ -1545,6 +1587,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Single Root I/O Virtualization */ /* Single Root I/O Virtualization */
pci_iov_init(dev); pci_iov_init(dev);
/* Address Translation Services */
pci_ats_init(dev);
/* Enable ACS P2P upstream forwarding */ /* Enable ACS P2P upstream forwarding */
pci_enable_acs(dev); pci_enable_acs(dev);
} }
...@@ -1796,22 +1841,6 @@ static void pcie_write_mrrs(struct pci_dev *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"); 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) static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
{ {
int mps, orig_mps; int mps, orig_mps;
...@@ -1819,10 +1848,9 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data) ...@@ -1819,10 +1848,9 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
if (!pci_is_pcie(dev)) if (!pci_is_pcie(dev))
return 0; return 0;
if (pcie_bus_config == PCIE_BUS_TUNE_OFF) { if (pcie_bus_config == PCIE_BUS_TUNE_OFF ||
pcie_bus_detect_mps(dev); pcie_bus_config == PCIE_BUS_DEFAULT)
return 0; return 0;
}
mps = 128 << *(u8 *)data; mps = 128 << *(u8 *)data;
orig_mps = pcie_get_mps(dev); orig_mps = pcie_get_mps(dev);
...@@ -2101,8 +2129,9 @@ void pci_bus_release_busn_res(struct pci_bus *b) ...@@ -2101,8 +2129,9 @@ void pci_bus_release_busn_res(struct pci_bus *b)
res, ret ? "can not be" : "is"); res, ret ? "can not be" : "is");
} }
struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata, struct list_head *resources) struct pci_ops *ops, void *sysdata,
struct list_head *resources, struct msi_controller *msi)
{ {
struct resource_entry *window; struct resource_entry *window;
bool found = false; bool found = false;
...@@ -2119,6 +2148,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus, ...@@ -2119,6 +2148,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
if (!b) if (!b)
return NULL; return NULL;
b->msi = msi;
if (!found) { if (!found) {
dev_info(&b->dev, dev_info(&b->dev,
"No busn resource found for root bus, will use [bus %02x-ff]\n", "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, ...@@ -2133,6 +2164,13 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
return b; 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); EXPORT_SYMBOL(pci_scan_root_bus);
struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, 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_ ...@@ -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 * VIA Apollo KT133 needs PCI latency patch
* Made according to a windows driver based patch by George E. Breese * Made according to a windows driver based patch by George E. Breese
* see PCI Latency Adjust on http://www.viahardware.com/download/viatweak.shtm * 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 * Also see http://www.au-ja.org/review-kt133a-1-en.phtml for
* the info on which Mr Breese based his work. * 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_ ...@@ -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) static void quirk_amd_nl_class(struct pci_dev *pdev)
{ {
/* u32 class = pdev->class;
* Use 'USB Device' (0x0c03fe) instead of PCI header provided
*/ /* Use "USB Device (not host controller)" class */
pdev->class = 0x0c03fe; 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, DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB,
quirk_amd_nl_class); quirk_amd_nl_class);
...@@ -1569,6 +1570,18 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB3 ...@@ -1569,6 +1570,18 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB3
#endif #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 #ifdef CONFIG_X86_IO_APIC
static void quirk_alder_ioapic(struct pci_dev *pdev) static void quirk_alder_ioapic(struct pci_dev *pdev)
{ {
...@@ -1894,6 +1907,15 @@ static void quirk_netmos(struct pci_dev *dev) ...@@ -1894,6 +1907,15 @@ static void quirk_netmos(struct pci_dev *dev)
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); 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) static void quirk_e100_interrupt(struct pci_dev *dev)
{ {
u16 command, pmcsr; u16 command, pmcsr;
...@@ -1986,14 +2008,18 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); ...@@ -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) 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. * they don't get their resources remapped. Fix that here.
*/ */
if (class)
return;
if (dev->class == PCI_CLASS_NOT_DEFINED) { dev->class = PCI_CLASS_STORAGE_SCSI << 8;
dev_info(&dev->dev, "NCR 53c810 rev 1 detected; setting PCI class\n"); dev_info(&dev->dev, "NCR 53c810 rev 1 PCI class overridden (%#08x -> %#08x)\n",
dev->class = PCI_CLASS_STORAGE_SCSI; class, dev->class);
}
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); 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); ...@@ -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 */ * return 1 if a HT MSI capability is found and enabled */
static int msi_ht_cap_enabled(struct pci_dev *dev) 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); pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
while (pos && ttl--) { while (pos && ttl--) {
...@@ -2300,7 +2326,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, ...@@ -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 */ /* Force enable MSI mapping capability on HT bridges */
static void ht_enable_msi_mapping(struct pci_dev *dev) 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); pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
while (pos && ttl--) { while (pos && ttl--) {
...@@ -2379,7 +2405,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, ...@@ -2379,7 +2405,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
static int ht_check_msi_mapping(struct pci_dev *dev) static int ht_check_msi_mapping(struct pci_dev *dev)
{ {
int pos, ttl = 48; int pos, ttl = PCI_FIND_CAP_TTL;
int found = 0; int found = 0;
/* check if there is HT MSI cap or enabled on this device */ /* check if there is HT MSI cap or enabled on this device */
...@@ -2504,7 +2530,7 @@ static void nv_ht_enable_msi_mapping(struct pci_dev *dev) ...@@ -2504,7 +2530,7 @@ static void nv_ht_enable_msi_mapping(struct pci_dev *dev)
static void ht_disable_msi_mapping(struct pci_dev *dev) 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); pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
while (pos && ttl--) { while (pos && ttl--) {
...@@ -2829,12 +2855,15 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); ...@@ -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) 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 */ /* 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 << 8;
dev->class = PCI_CLASS_MULTIMEDIA_VIDEO; dev_info(&dev->dev, "PCI class overridden (%#08x -> %#08x)\n",
class, dev->class);
} }
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800, 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 /* Some PCIe devices do not work reliably with the claimed maximum
* payload size supported. * payload size supported.
...@@ -2862,7 +2891,8 @@ static void quirk_intel_mc_errata(struct pci_dev *dev) ...@@ -2862,7 +2891,8 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)
int err; int err;
u16 rcc; 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; return;
/* Intel errata specifies bits to change but does not say what they are. /* 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); ...@@ -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, 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, 0x8c02, quirk_remove_d3_delay);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, 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 * Some devices may pass our check in pci_intx_mask_supported if
* PCI_COMMAND_INTX_DISABLE works though they actually do not properly * PCI_COMMAND_INTX_DISABLE works though they actually do not properly
...@@ -3326,28 +3365,6 @@ fs_initcall_sync(pci_apply_final_quirks); ...@@ -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 * reset a single function if other methods (e.g. FLR, PM D0->D3) are
* not available. * 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) 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[] = { ...@@ -3506,8 +3523,6 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
reset_ivb_igd }, reset_ivb_igd },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_M2_VGA,
reset_ivb_igd }, reset_ivb_igd },
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
reset_intel_generic_dev },
{ PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
reset_chelsio_generic_dev }, reset_chelsio_generic_dev },
{ 0 } { 0 }
...@@ -3654,6 +3669,28 @@ DECLARE_PCI_FIXUP_HEADER(0x1283, 0x8892, quirk_use_pcie_bridge_dma_alias); ...@@ -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 */ /* Intel 82801, https://bugzilla.kernel.org/show_bug.cgi?id=44881#c49 */
DECLARE_PCI_FIXUP_HEADER(0x8086, 0x244e, quirk_use_pcie_bridge_dma_alias); 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 * 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 * in any system where they are found in the southbridge with an AMD
...@@ -3848,6 +3885,9 @@ static const struct pci_dev_acs_enabled { ...@@ -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, 0x105F, pci_quirk_mf_endpoint_acs },
{ PCI_VENDOR_ID_INTEL, 0x1060, 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 }, { 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 */ /* Intel PCH root ports */
{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs }, { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
{ 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */ { 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
struct kset *pci_slots_kset; struct kset *pci_slots_kset;
EXPORT_SYMBOL_GPL(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, static ssize_t pci_slot_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf) struct attribute *attr, char *buf)
...@@ -106,9 +107,11 @@ static void pci_slot_release(struct kobject *kobj) ...@@ -106,9 +107,11 @@ static void pci_slot_release(struct kobject *kobj)
dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n", dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
slot->number, pci_slot_name(slot)); slot->number, pci_slot_name(slot));
down_read(&pci_bus_sem);
list_for_each_entry(dev, &slot->bus->devices, bus_list) list_for_each_entry(dev, &slot->bus->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot->number) if (PCI_SLOT(dev->devfn) == slot->number)
dev->slot = NULL; dev->slot = NULL;
up_read(&pci_bus_sem);
list_del(&slot->list); list_del(&slot->list);
...@@ -191,12 +194,22 @@ static int rename_slot(struct pci_slot *slot, const char *name) ...@@ -191,12 +194,22 @@ static int rename_slot(struct pci_slot *slot, const char *name)
return result; 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) static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)
{ {
struct pci_slot *slot; 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) list_for_each_entry(slot, &parent->slots, list)
if (slot->number == slot_nr) { if (slot->number == slot_nr) {
kobject_get(&slot->kobj); kobject_get(&slot->kobj);
...@@ -253,7 +266,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, ...@@ -253,7 +266,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
int err = 0; int err = 0;
char *slot_name = NULL; char *slot_name = NULL;
down_write(&pci_bus_sem); mutex_lock(&pci_slot_mutex);
if (slot_nr == -1) if (slot_nr == -1)
goto placeholder; goto placeholder;
...@@ -301,16 +314,18 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, ...@@ -301,16 +314,18 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
INIT_LIST_HEAD(&slot->list); INIT_LIST_HEAD(&slot->list);
list_add(&slot->list, &parent->slots); list_add(&slot->list, &parent->slots);
down_read(&pci_bus_sem);
list_for_each_entry(dev, &parent->devices, bus_list) list_for_each_entry(dev, &parent->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot_nr) if (PCI_SLOT(dev->devfn) == slot_nr)
dev->slot = slot; dev->slot = slot;
up_read(&pci_bus_sem);
dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n", dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
slot_nr, pci_slot_name(slot)); slot_nr, pci_slot_name(slot));
out: out:
kfree(slot_name); kfree(slot_name);
up_write(&pci_bus_sem); mutex_unlock(&pci_slot_mutex);
return slot; return slot;
err: err:
kfree(slot); kfree(slot);
...@@ -332,9 +347,9 @@ void pci_destroy_slot(struct pci_slot *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", dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
slot->number, atomic_read(&slot->kobj.kref.refcount) - 1); slot->number, atomic_read(&slot->kobj.kref.refcount) - 1);
down_write(&pci_bus_sem); mutex_lock(&pci_slot_mutex);
kobject_put(&slot->kobj); kobject_put(&slot->kobj);
up_write(&pci_bus_sem); mutex_unlock(&pci_slot_mutex);
} }
EXPORT_SYMBOL_GPL(pci_destroy_slot); EXPORT_SYMBOL_GPL(pci_destroy_slot);
......
...@@ -3,55 +3,6 @@ ...@@ -3,55 +3,6 @@
#include <linux/pci.h> #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 #ifdef CONFIG_PCI_PRI
int pci_enable_pri(struct pci_dev *pdev, u32 reqs); int pci_enable_pri(struct pci_dev *pdev, u32 reqs);
......
...@@ -180,6 +180,8 @@ enum pci_dev_flags { ...@@ -180,6 +180,8 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6), PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1 << 6),
/* Do not use PM reset even if device advertises NoSoftRst- */ /* Do not use PM reset even if device advertises NoSoftRst- */
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7), 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 { enum pci_irq_reroute_variant {
...@@ -343,6 +345,7 @@ struct pci_dev { ...@@ -343,6 +345,7 @@ struct pci_dev {
unsigned int msi_enabled:1; unsigned int msi_enabled:1;
unsigned int msix_enabled:1; unsigned int msix_enabled:1;
unsigned int ari_enabled:1; /* ARI forwarding */ unsigned int ari_enabled:1; /* ARI forwarding */
unsigned int ats_enabled:1; /* Address Translation Service */
unsigned int is_managed:1; unsigned int is_managed:1;
unsigned int needs_freset:1; /* Dev requires fundamental reset */ unsigned int needs_freset:1; /* Dev requires fundamental reset */
unsigned int state_saved:1; unsigned int state_saved:1;
...@@ -375,7 +378,9 @@ struct pci_dev { ...@@ -375,7 +378,9 @@ struct pci_dev {
struct pci_sriov *sriov; /* SR-IOV capability related */ struct pci_sriov *sriov; /* SR-IOV capability related */
struct pci_dev *physfn; /* the PF this VF is associated with */ 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 #endif
phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */ 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 */ size_t romlen; /* Length of ROM if it's not from the BAR */
...@@ -446,7 +451,8 @@ struct pci_bus { ...@@ -446,7 +451,8 @@ struct pci_bus {
struct list_head children; /* list of child buses */ struct list_head children; /* list of child buses */
struct list_head devices; /* list of devices on this bus */ struct list_head devices; /* list of devices on this bus */
struct pci_dev *self; /* bridge device as seen by parent */ 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 resource *resource[PCI_BRIDGE_RESOURCE_NUM];
struct list_head resources; /* address space routed to this bus */ struct list_head resources; /* address space routed to this bus */
struct resource busn_res; /* bus numbers routed to this bus */ struct resource busn_res; /* bus numbers routed to this bus */
...@@ -738,10 +744,11 @@ struct pci_driver { ...@@ -738,10 +744,11 @@ struct pci_driver {
void pcie_bus_configure_settings(struct pci_bus *bus); void pcie_bus_configure_settings(struct pci_bus *bus);
enum pcie_bus_config_types { enum pcie_bus_config_types {
PCIE_BUS_TUNE_OFF, PCIE_BUS_TUNE_OFF, /* don't touch MPS at all */
PCIE_BUS_SAFE, PCIE_BUS_DEFAULT, /* ensure MPS matches upstream bridge */
PCIE_BUS_PERFORMANCE, PCIE_BUS_SAFE, /* use largest MPS boot-time devices support */
PCIE_BUS_PEER2PEER, 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; 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, ...@@ -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_insert_busn_res(struct pci_bus *b, int bus, int busmax);
int pci_bus_update_busn_res_end(struct pci_bus *b, 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); 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_bus *pci_scan_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata, struct pci_ops *ops, void *sysdata,
struct list_head *resources); struct list_head *resources);
...@@ -797,6 +808,11 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, ...@@ -797,6 +808,11 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
const char *name, const char *name,
struct hotplug_slot *hotplug); struct hotplug_slot *hotplug);
void pci_destroy_slot(struct pci_slot *slot); 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); int pci_scan_slot(struct pci_bus *bus, int devfn);
struct pci_dev *pci_scan_single_device(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); 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) ...@@ -963,6 +979,23 @@ static inline int pci_is_managed(struct pci_dev *pdev)
return pdev->is_managed; 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); void pci_disable_device(struct pci_dev *dev);
extern unsigned int pcibios_max_latency; extern unsigned int pcibios_max_latency;
...@@ -1295,6 +1328,19 @@ int ht_create_irq(struct pci_dev *dev, int idx); ...@@ -1295,6 +1328,19 @@ int ht_create_irq(struct pci_dev *dev, int idx);
void ht_destroy_irq(unsigned int irq); void ht_destroy_irq(unsigned int irq);
#endif /* CONFIG_HT_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); void pci_cfg_access_lock(struct pci_dev *dev);
bool pci_cfg_access_trylock(struct pci_dev *dev); bool pci_cfg_access_trylock(struct pci_dev *dev);
void pci_cfg_access_unlock(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, ...@@ -1646,6 +1692,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev,
int pcibios_add_device(struct pci_dev *dev); int pcibios_add_device(struct pci_dev *dev);
void pcibios_release_device(struct pci_dev *dev); void pcibios_release_device(struct pci_dev *dev);
void pcibios_penalize_isa_irq(int irq, int active); 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 #ifdef CONFIG_HIBERNATE_CALLBACKS
extern struct dev_pm_ops pcibios_pm_ops; extern struct dev_pm_ops pcibios_pm_ops;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册