Merge tag 'pci-v4.3-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Sep 2015 00:14:39 +0000 (17:14 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Sep 2015 00:14:39 +0000 (17:14 -0700)
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
  ...

64 files changed:
Documentation/devicetree/bindings/pci/ti-pci.txt
arch/alpha/kernel/pci.c
arch/arm/boot/dts/am57xx-beagle-x15.dts
arch/arm/boot/dts/dra7.dtsi
arch/arm/include/asm/mach/pci.h
arch/arm/kernel/bios32.c
arch/arm64/boot/dts/apm/apm-storm.dtsi
arch/frv/mb93090-mb00/pci-frv.c
arch/frv/mb93090-mb00/pci-frv.h
arch/frv/mb93090-mb00/pci-vdk.c
arch/ia64/pci/pci.c
arch/microblaze/pci/pci-common.c
arch/mips/pci/pci.c
arch/mn10300/unit-asb2305/pci-asb2305.c
arch/mn10300/unit-asb2305/pci-asb2305.h
arch/mn10300/unit-asb2305/pci.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_of_scan.c
arch/sh/drivers/pci/pci-sh4.h
arch/sparc/kernel/pci.c
arch/x86/include/asm/pci_x86.h
arch/x86/pci/common.c
arch/x86/pci/fixup.c
arch/x86/pci/intel_mid_pci.c
arch/x86/pci/irq.c
arch/xtensa/kernel/pci.c
drivers/acpi/pci_irq.c
drivers/ata/ahci.c
drivers/ata/pata_jmicron.c
drivers/iommu/intel-iommu.c
drivers/parisc/dino.c
drivers/parisc/lba_pci.c
drivers/pci/Makefile
drivers/pci/access.c
drivers/pci/ats.c
drivers/pci/host/Kconfig
drivers/pci/host/pci-dra7xx.c
drivers/pci/host/pci-host-generic.c
drivers/pci/host/pci-imx6.c
drivers/pci/host/pci-keystone-dw.c
drivers/pci/host/pci-mvebu.c
drivers/pci/host/pci-tegra.c
drivers/pci/host/pci-xgene-msi.c
drivers/pci/host/pci-xgene.c
drivers/pci/host/pcie-designware.c
drivers/pci/host/pcie-iproc.c
drivers/pci/host/pcie-iproc.h
drivers/pci/host/pcie-rcar.c
drivers/pci/host/pcie-spear13xx.c
drivers/pci/host/pcie-xilinx.c
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/msi.c
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/portdrv_core.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/slot.c
include/linux/pci-ats.h
include/linux/pci.h

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