Merge branch 'pci/controller/dwc'
authorBjorn Helgaas <bhelgaas@google.com>
Mon, 15 Jan 2024 18:10:37 +0000 (12:10 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 15 Jan 2024 18:10:37 +0000 (12:10 -0600)
- Convert fu740 CONFIG_PCIE_FU740 dependency from SOC_SIFIVE to ARCH_SIFIVE
  (Conor Dooley)

- Align iATU mapping for endpoint MSI-X (Niklas Cassel)

- Drop "host_" prefix from struct dw_pcie_host_ops members (Yoshihiro
  Shimoda)

- Drop "ep_" prefix from struct dw_pcie_ep_ops members (Yoshihiro Shimoda)

- Rename struct dw_pcie_ep_ops.func_conf_select() to .get_dbi_offset() to
  be more descriptive (Yoshihiro Shimoda)

- Add Endpoint DBI accessors to encapsulate offset lookups (Yoshihiro
  Shimoda)

- Cast iproc and rcar-gen4 of_device_get_match_data() results to uintptr_t
  to avoid clang "cast to smaller integer type" warnings (Justin Stitt,
  Yoshihiro Shimoda)

* pci/controller/dwc:
  PCI: rcar-gen4: Fix -Wvoid-pointer-to-enum-cast error
  PCI: iproc: Fix -Wvoid-pointer-to-enum-cast warning
  PCI: dwc: Add dw_pcie_ep_{read,write}_dbi[2] helpers
  PCI: dwc: Rename .func_conf_select to .get_dbi_offset in struct dw_pcie_ep_ops
  PCI: dwc: Rename .ep_init to .init in struct dw_pcie_ep_ops
  PCI: dwc: Drop host prefix from struct dw_pcie_host_ops members
  PCI: dwc: endpoint: Fix dw_pcie_ep_raise_msix_irq() alignment support
  PCI: dwc: Convert SOC_SIFIVE to ARCH_SIFIVE

32 files changed:
Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
Documentation/devicetree/bindings/pci/ti,j721e-pci-ep.yaml
Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
Documentation/driver-api/pci/p2pdma.rst
arch/powerpc/sysdev/fsl_pci.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/early-quirks.c
arch/x86/pci/acpi.c
arch/x86/pci/mmconfig-shared.c
arch/x86/pci/mmconfig_32.c
arch/x86/pci/mmconfig_64.c
arch/x86/pci/pcbios.c
drivers/pci/controller/cadence/Kconfig
drivers/pci/controller/cadence/pci-j721e.c
drivers/pci/controller/dwc/pcie-intel-gw.c
drivers/pci/controller/dwc/pcie-keembay.c
drivers/pci/controller/pci-host-common.c
drivers/pci/controller/pci-host-generic.c
drivers/pci/controller/pcie-brcmstb.c
drivers/pci/iov.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aer.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/pci/switch/switchtec.c
drivers/scsi/lpfc/lpfc_sli.c
include/linux/aer.h
include/linux/pci-ecam.h
include/linux/pci.h

index 7e15aae7d69e9780dc2fc7adfa28b0ebec0acaaa..22491f7f88521c853c1ed8e91c5f9d5db2d095ef 100644 (file)
@@ -64,6 +64,24 @@ properties:
 
   aspm-no-l0s: true
 
+  brcm,clkreq-mode:
+    description: A string that determines the operating
+      clkreq mode of the PCIe RC HW with respect to controlling the refclk
+      signal.  There are three different modes -- "safe", which drives the
+      refclk signal unconditionally and will work for all devices but does
+      not provide any power savings; "no-l1ss" -- which provides Clock
+      Power Management, L0s, and L1, but cannot provide L1 substate (L1SS)
+      power savings. If the downstream device connected to the RC is L1SS
+      capable AND the OS enables L1SS, all PCIe traffic may abruptly halt,
+      potentially hanging the system; "default" -- which provides L0s, L1,
+      and L1SS, but not compliant to provide Clock Power Management;
+      specifically, may not be able to meet the T_CLRon max timing of 400ns
+      as specified in "Dynamic Clock Control", section 3.2.5.2.2 PCI
+      Express Mini CEM 2.1 specification.  This situation is atypical and
+      should happen only with older devices.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [ safe, no-l1ss, default ]
+
   brcm,scb-sizes:
     description: u64 giving the 64bit PCIe memory
       viewport size of a memory controller.  There may be up to
index 62292185fe2e460d167a629669bc78496fc6be46..97f2579ea9082229c03a094d74d25da4e54eb8e4 100644 (file)
@@ -10,13 +10,11 @@ title: TI J721E PCI EP (PCIe Wrapper)
 maintainers:
   - Kishon Vijay Abraham I <kishon@ti.com>
 
-allOf:
-  - $ref: cdns-pcie-ep.yaml#
-
 properties:
   compatible:
     oneOf:
       - const: ti,j721e-pcie-ep
+      - const: ti,j784s4-pcie-ep
       - description: PCIe EP controller in AM64
         items:
           - const: ti,am64-pcie-ep
@@ -65,6 +63,41 @@ properties:
     items:
       - const: link_state
 
+allOf:
+  - $ref: cdns-pcie-ep.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - ti,am64-pcie-ep
+    then:
+      properties:
+        num-lanes:
+          const: 1
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - ti,j7200-pcie-ep
+            - ti,j721e-pcie-ep
+    then:
+      properties:
+        num-lanes:
+          minimum: 1
+          maximum: 2
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - ti,j784s4-pcie-ep
+    then:
+      properties:
+        num-lanes:
+          minimum: 1
+          maximum: 4
+
 required:
   - compatible
   - reg
index a2c5eaea57f503f27392b7424bda35fb43d27950..b7a534cef24d314d20d9e725575301dcb499a782 100644 (file)
@@ -10,13 +10,11 @@ title: TI J721E PCI Host (PCIe Wrapper)
 maintainers:
   - Kishon Vijay Abraham I <kishon@ti.com>
 
-allOf:
-  - $ref: cdns-pcie-host.yaml#
-
 properties:
   compatible:
     oneOf:
       - const: ti,j721e-pcie-host
+      - const: ti,j784s4-pcie-host
       - description: PCIe controller in AM64
         items:
           - const: ti,am64-pcie-host
@@ -94,6 +92,41 @@ properties:
       interrupts:
         maxItems: 1
 
+allOf:
+  - $ref: cdns-pcie-host.yaml#
+  - if:
+      properties:
+        compatible:
+          enum:
+            - ti,am64-pcie-host
+    then:
+      properties:
+        num-lanes:
+          const: 1
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - ti,j7200-pcie-host
+            - ti,j721e-pcie-host
+    then:
+      properties:
+        num-lanes:
+          minimum: 1
+          maximum: 2
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - ti,j784s4-pcie-host
+    then:
+      properties:
+        num-lanes:
+          minimum: 1
+          maximum: 4
+
 required:
   - compatible
   - reg
index 44deb52beeb4766ae736c9a2645ce2be09857cc1..d0b241628cf13d4002735de4b9b5141cf90e0bde 100644 (file)
@@ -83,19 +83,9 @@ this to include other types of resources like doorbells.
 Client Drivers
 --------------
 
-A client driver typically only has to conditionally change its DMA map
-routine to use the mapping function :c:func:`pci_p2pdma_map_sg()` instead
-of the usual :c:func:`dma_map_sg()` function. Memory mapped in this
-way does not need to be unmapped.
-
-The client may also, optionally, make use of
-:c:func:`is_pci_p2pdma_page()` to determine when to use the P2P mapping
-functions and when to use the regular mapping functions. In some
-situations, it may be more appropriate to use a flag to indicate a
-given request is P2P memory and map appropriately. It is important to
-ensure that struct pages that back P2P memory stay out of code that
-does not have support for them as other code may treat the pages as
-regular memory which may not be appropriate.
+A client driver only has to use the mapping API :c:func:`dma_map_sg()`
+and :c:func:`dma_unmap_sg()` functions as usual, and the implementation
+will do the right thing for the P2P capable memory.
 
 
 Orchestrator Drivers
index 3868483fbe292d5455a853cafd2da1df31eec7d4..ef7707ea0db7bc0b356470f0763d05d4e3c1d469 100644 (file)
@@ -54,7 +54,7 @@ static void quirk_fsl_pcie_early(struct pci_dev *dev)
 
        /* if we aren't in host mode don't bother */
        pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
-       if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
+       if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
                return;
 
        dev->class = PCI_CLASS_BRIDGE_PCI_NORMAL;
@@ -581,7 +581,7 @@ static int fsl_add_bridge(struct platform_device *pdev, int is_primary)
                hose->ops = &fsl_indirect_pcie_ops;
                /* For PCIE read HEADER_TYPE to identify controller mode */
                early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type);
-               if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
+               if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
                        goto no_bridge;
 
        } else {
index 4feaa670d5783b8fe9bb226d0635c09bb15939da..89c0c8a3fc7e6c0c84ce98541d6cd1430ab91b41 100644 (file)
@@ -259,10 +259,9 @@ static u32 __init search_agp_bridge(u32 *order, int *valid_agp)
                                                        order);
                                }
 
-                               /* No multi-function device? */
                                type = read_pci_config_byte(bus, slot, func,
                                                               PCI_HEADER_TYPE);
-                               if (!(type & 0x80))
+                               if (!(type & PCI_HEADER_TYPE_MFD))
                                        break;
                        }
                }
index a6c1867fc7aa3ea0eb9b24fc1992c90119d2febb..59f4aefc6bc1625fe0a8e3cb43f8f62ad5a89eab 100644 (file)
@@ -779,13 +779,13 @@ static int __init check_dev_quirk(int num, int slot, int func)
        type = read_pci_config_byte(num, slot, func,
                                    PCI_HEADER_TYPE);
 
-       if ((type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
+       if ((type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
                sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS);
                if (sec > num)
                        early_pci_scan_bus(sec);
        }
 
-       if (!(type & 0x80))
+       if (!(type & PCI_HEADER_TYPE_MFD))
                return -1;
 
        return 0;
index ea2eb2ec90e2bc96368090bb0478a2c8f591df0e..55c4b07ec1f6319bb781071453d034c9efa9ed65 100644 (file)
@@ -283,6 +283,9 @@ static int setup_mcfg_map(struct acpi_pci_root_info *ci)
        info->mcfg_added = false;
        seg = info->sd.domain;
 
+       dev_dbg(dev, "%s(%04x %pR ECAM %pa)\n", __func__, seg,
+               &root->secondary, &root->mcfg_addr);
+
        /* return success if MMCFG is not in use */
        if (raw_pci_ext_ops && raw_pci_ext_ops != &pci_mmcfg)
                return 0;
index 4b3efaa82ab7c14a747cea8dbe50ad6645cf1981..0cc9520666efbbe0c61a53aff2467ac5afb433f6 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * mmconfig-shared.c - Low-level direct PCI config space access via
- *                     MMCONFIG - common code between i386 and x86-64.
+ * Low-level direct PCI config space access via ECAM - common code between
+ * i386 and x86-64.
  *
  * This code does:
  * - known chipset handling
@@ -11,6 +11,8 @@
  * themselves.
  */
 
+#define pr_fmt(fmt) "PCI: " fmt
+
 #include <linux/acpi.h>
 #include <linux/efi.h>
 #include <linux/pci.h>
@@ -24,9 +26,7 @@
 #include <asm/pci_x86.h>
 #include <asm/acpi.h>
 
-#define PREFIX "PCI: "
-
-/* Indicate if the mmcfg resources have been placed into the resource table. */
+/* Indicate if the ECAM resources have been placed into the resource table */
 static bool pci_mmcfg_running_state;
 static bool pci_mmcfg_arch_init_failed;
 static DEFINE_MUTEX(pci_mmcfg_lock);
@@ -90,7 +90,7 @@ static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
        res->end = addr + PCI_MMCFG_BUS_OFFSET(end + 1) - 1;
        res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
        snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
-                "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
+                "PCI ECAM %04x [bus %02x-%02x]", segment, start, end);
        res->name = new->name;
 
        return new;
@@ -102,16 +102,15 @@ struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
        struct pci_mmcfg_region *new;
 
        new = pci_mmconfig_alloc(segment, start, end, addr);
-       if (new) {
-               mutex_lock(&pci_mmcfg_lock);
-               list_add_sorted(new);
-               mutex_unlock(&pci_mmcfg_lock);
+       if (!new)
+               return NULL;
 
-               pr_info(PREFIX
-                      "MMCONFIG for domain %04x [bus %02x-%02x] at %pR "
-                      "(base %#lx)\n",
-                      segment, start, end, &new->res, (unsigned long)addr);
-       }
+       mutex_lock(&pci_mmcfg_lock);
+       list_add_sorted(new);
+       mutex_unlock(&pci_mmcfg_lock);
+
+       pr_info("ECAM %pR (base %#lx) for domain %04x [bus %02x-%02x]\n",
+               &new->res, (unsigned long)addr, segment, start, end);
 
        return new;
 }
@@ -205,7 +204,7 @@ static const char *__init pci_mmcfg_amd_fam10h(void)
        msr <<= 32;
        msr |= low;
 
-       /* mmconfig is not enable */
+       /* ECAM is not enabled */
        if (!(msr & FAM10H_MMIO_CONF_ENABLE))
                return NULL;
 
@@ -367,7 +366,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
                        name = pci_mmcfg_probes[i].probe();
 
                if (name)
-                       pr_info(PREFIX "%s with MMCONFIG support\n", name);
+                       pr_info("%s with ECAM support\n", name);
        }
 
        /* some end_bus_number is crazy, fix it */
@@ -443,9 +442,11 @@ static bool is_acpi_reserved(u64 start, u64 end, enum e820_type not_used)
        return mcfg_res.flags;
 }
 
-static bool is_efi_mmio(u64 start, u64 end, enum e820_type not_used)
+static bool is_efi_mmio(struct resource *res)
 {
 #ifdef CONFIG_EFI
+       u64 start = res->start;
+       u64 end = res->start + resource_size(res);
        efi_memory_desc_t *md;
        u64 size, mmio_start, mmio_end;
 
@@ -455,11 +456,6 @@ static bool is_efi_mmio(u64 start, u64 end, enum e820_type not_used)
                        mmio_start = md->phys_addr;
                        mmio_end = mmio_start + size;
 
-                       /*
-                        * N.B. Caller supplies (start, start + size),
-                        * so to match, mmio_end is the first address
-                        * *past* the EFI_MEMORY_MAPPED_IO area.
-                        */
                        if (mmio_start <= start && end <= mmio_end)
                                return true;
                }
@@ -490,11 +486,10 @@ static bool __ref is_mmconf_reserved(check_reserved_t is_reserved,
                return false;
 
        if (dev)
-               dev_info(dev, "MMCONFIG at %pR reserved as %s\n",
+               dev_info(dev, "ECAM %pR reserved as %s\n",
                         &cfg->res, method);
        else
-               pr_info(PREFIX "MMCONFIG at %pR reserved as %s\n",
-                      &cfg->res, method);
+               pr_info("ECAM %pR reserved as %s\n", &cfg->res, method);
 
        if (old_size != size) {
                /* update end_bus */
@@ -503,47 +498,51 @@ static bool __ref is_mmconf_reserved(check_reserved_t is_reserved,
                cfg->res.end = cfg->res.start +
                    PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
                snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
-                        "PCI MMCONFIG %04x [bus %02x-%02x]",
+                        "PCI ECAM %04x [bus %02x-%02x]",
                         cfg->segment, cfg->start_bus, cfg->end_bus);
 
                if (dev)
-                       dev_info(dev,
-                               "MMCONFIG "
-                               "at %pR (base %#lx) (size reduced!)\n",
-                               &cfg->res, (unsigned long) cfg->address);
+                       dev_info(dev, "ECAM %pR (base %#lx) (size reduced!)\n",
+                                &cfg->res, (unsigned long) cfg->address);
                else
-                       pr_info(PREFIX
-                               "MMCONFIG for %04x [bus%02x-%02x] "
-                               "at %pR (base %#lx) (size reduced!)\n",
-                               cfg->segment, cfg->start_bus, cfg->end_bus,
-                               &cfg->res, (unsigned long) cfg->address);
+                       pr_info("ECAM %pR (base %#lx) for %04x [bus%02x-%02x] (size reduced!)\n",
+                               &cfg->res, (unsigned long) cfg->address,
+                               cfg->segment, cfg->start_bus, cfg->end_bus);
        }
 
        return true;
 }
 
-static bool __ref
-pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int early)
+static bool __ref pci_mmcfg_reserved(struct device *dev,
+                                    struct pci_mmcfg_region *cfg, int early)
 {
+       struct resource *conflict;
+
        if (!early && !acpi_disabled) {
                if (is_mmconf_reserved(is_acpi_reserved, cfg, dev,
                                       "ACPI motherboard resource"))
                        return true;
 
                if (dev)
-                       dev_info(dev, FW_INFO
-                                "MMCONFIG at %pR not reserved in "
-                                "ACPI motherboard resources\n",
+                       dev_info(dev, FW_INFO "ECAM %pR not reserved in ACPI motherboard resources\n",
                                 &cfg->res);
                else
-                       pr_info(FW_INFO PREFIX
-                              "MMCONFIG at %pR not reserved in "
-                              "ACPI motherboard resources\n",
-                              &cfg->res);
-
-               if (is_mmconf_reserved(is_efi_mmio, cfg, dev,
-                                      "EfiMemoryMappedIO"))
+                       pr_info(FW_INFO "ECAM %pR not reserved in ACPI motherboard resources\n",
+                               &cfg->res);
+
+               if (is_efi_mmio(&cfg->res)) {
+                       pr_info("ECAM %pR is EfiMemoryMappedIO; assuming valid\n",
+                               &cfg->res);
+                       conflict = insert_resource_conflict(&iomem_resource,
+                                                           &cfg->res);
+                       if (conflict)
+                               pr_warn("ECAM %pR conflicts with %s %pR\n",
+                                       &cfg->res, conflict->name, conflict);
+                       else
+                               pr_info("ECAM %pR reserved to work around lack of ACPI motherboard _CRS\n",
+                                       &cfg->res);
                        return true;
+               }
        }
 
        /*
@@ -569,30 +568,31 @@ static void __init pci_mmcfg_reject_broken(int early)
        struct pci_mmcfg_region *cfg;
 
        list_for_each_entry(cfg, &pci_mmcfg_list, list) {
-               if (pci_mmcfg_check_reserved(NULL, cfg, early) == 0) {
-                       pr_info(PREFIX "not using MMCONFIG\n");
+               if (!pci_mmcfg_reserved(NULL, cfg, early)) {
+                       pr_info("not using ECAM (%pR not reserved)\n",
+                               &cfg->res);
                        free_all_mmcfg();
                        return;
                }
        }
 }
 
-static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
-                                       struct acpi_mcfg_allocation *cfg)
+static bool __init acpi_mcfg_valid_entry(struct acpi_table_mcfg *mcfg,
+                                        struct acpi_mcfg_allocation *cfg)
 {
        if (cfg->address < 0xFFFFFFFF)
-               return 0;
+               return true;
 
        if (!strncmp(mcfg->header.oem_id, "SGI", 3))
-               return 0;
+               return true;
 
        if ((mcfg->header.revision >= 1) && (dmi_get_bios_year() >= 2010))
-               return 0;
+               return true;
 
-       pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
-              "is above 4GB, ignored\n", cfg->pci_segment,
-              cfg->start_bus_number, cfg->end_bus_number, cfg->address);
-       return -EINVAL;
+       pr_err("ECAM at %#llx for %04x [bus %02x-%02x] is above 4GB, ignored\n",
+              cfg->address, cfg->pci_segment, cfg->start_bus_number,
+              cfg->end_bus_number);
+       return false;
 }
 
 static int __init pci_parse_mcfg(struct acpi_table_header *header)
@@ -616,21 +616,21 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)
                i -= sizeof(struct acpi_mcfg_allocation);
        }
        if (entries == 0) {
-               pr_err(PREFIX "MMCONFIG has no entries\n");
+               pr_err("MCFG has no entries\n");
                return -ENODEV;
        }
 
        cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
        for (i = 0; i < entries; i++) {
                cfg = &cfg_table[i];
-               if (acpi_mcfg_check_entry(mcfg, cfg)) {
+               if (!acpi_mcfg_valid_entry(mcfg, cfg)) {
                        free_all_mmcfg();
                        return -ENODEV;
                }
 
                if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
                                   cfg->end_bus_number, cfg->address) == NULL) {
-                       pr_warn(PREFIX "no memory for MCFG entries\n");
+                       pr_warn("no memory for MCFG entries\n");
                        free_all_mmcfg();
                        return -ENOMEM;
                }
@@ -667,6 +667,8 @@ static int pci_mmcfg_for_each_region(int (*func)(__u64 start, __u64 size,
 
 static void __init __pci_mmcfg_init(int early)
 {
+       pr_debug("%s(%s)\n", __func__, early ? "early" : "late");
+
        pci_mmcfg_reject_broken(early);
        if (list_empty(&pci_mmcfg_list))
                return;
@@ -693,6 +695,8 @@ static int __initdata known_bridge;
 
 void __init pci_mmcfg_early_init(void)
 {
+       pr_debug("%s() pci_probe %#x\n", __func__, pci_probe);
+
        if (pci_probe & PCI_PROBE_MMCONF) {
                if (pci_mmcfg_check_hostbridge())
                        known_bridge = 1;
@@ -706,14 +710,16 @@ void __init pci_mmcfg_early_init(void)
 
 void __init pci_mmcfg_late_init(void)
 {
-       /* MMCONFIG disabled */
+       pr_debug("%s() pci_probe %#x\n", __func__, pci_probe);
+
+       /* ECAM disabled */
        if ((pci_probe & PCI_PROBE_MMCONF) == 0)
                return;
 
        if (known_bridge)
                return;
 
-       /* MMCONFIG hasn't been enabled yet, try again */
+       /* ECAM hasn't been enabled yet, try again */
        if (pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF) {
                acpi_table_parse(ACPI_SIG_MCFG, pci_parse_mcfg);
                __pci_mmcfg_init(0);
@@ -726,7 +732,9 @@ static int __init pci_mmcfg_late_insert_resources(void)
 
        pci_mmcfg_running_state = true;
 
-       /* If we are not using MMCONFIG, don't insert the resources. */
+       pr_debug("%s() pci_probe %#x\n", __func__, pci_probe);
+
+       /* If we are not using ECAM, don't insert the resources. */
        if ((pci_probe & PCI_PROBE_MMCONF) == 0)
                return 1;
 
@@ -735,21 +743,24 @@ static int __init pci_mmcfg_late_insert_resources(void)
         * marked so it won't cause request errors when __request_region is
         * called.
         */
-       list_for_each_entry(cfg, &pci_mmcfg_list, list)
-               if (!cfg->res.parent)
+       list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+               if (!cfg->res.parent) {
+                       pr_debug("%s() insert %pR\n", __func__, &cfg->res);
                        insert_resource(&iomem_resource, &cfg->res);
+               }
+       }
 
        return 0;
 }
 
 /*
- * Perform MMCONFIG resource insertion after PCI initialization to allow for
+ * Perform ECAM resource insertion after PCI initialization to allow for
  * misprogrammed MCFG tables that state larger sizes but actually conflict
  * with other system resources.
  */
 late_initcall(pci_mmcfg_late_insert_resources);
 
-/* Add MMCFG information for host bridges */
+/* Add ECAM information for host bridges */
 int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
                        phys_addr_t addr)
 {
@@ -757,6 +768,8 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
        struct resource *tmp = NULL;
        struct pci_mmcfg_region *cfg;
 
+       dev_dbg(dev, "%s(%04x [bus %02x-%02x])\n", __func__, seg, start, end);
+
        if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed)
                return -ENODEV;
 
@@ -767,15 +780,17 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
        cfg = pci_mmconfig_lookup(seg, start);
        if (cfg) {
                if (cfg->end_bus < end)
-                       dev_info(dev, FW_INFO
-                                "MMCONFIG for "
-                                "domain %04x [bus %02x-%02x] "
-                                "only partially covers this bridge\n",
-                                 cfg->segment, cfg->start_bus, cfg->end_bus);
+                       dev_info(dev, FW_INFO "ECAM %pR for domain %04x [bus %02x-%02x] only partially covers this bridge\n",
+                                &cfg->res, cfg->segment, cfg->start_bus,
+                                cfg->end_bus);
                mutex_unlock(&pci_mmcfg_lock);
                return -EEXIST;
        }
 
+       /*
+        * Don't move earlier; we must return -EEXIST, not -EINVAL, if
+        * pci_mmconfig_lookup() finds something
+        */
        if (!addr) {
                mutex_unlock(&pci_mmcfg_lock);
                return -EINVAL;
@@ -784,10 +799,10 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
        rc = -EBUSY;
        cfg = pci_mmconfig_alloc(seg, start, end, addr);
        if (cfg == NULL) {
-               dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
+               dev_warn(dev, "fail to add ECAM (out of memory)\n");
                rc = -ENOMEM;
-       } else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) {
-               dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n",
+       } else if (!pci_mmcfg_reserved(dev, cfg, 0)) {
+               dev_warn(dev, FW_BUG "ECAM %pR isn't reserved\n",
                         &cfg->res);
        } else {
                /* Insert resource if it's not in boot stage */
@@ -796,16 +811,13 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
                                                       &cfg->res);
 
                if (tmp) {
-                       dev_warn(dev,
-                                "MMCONFIG %pR conflicts with "
-                                "%s %pR\n",
+                       dev_warn(dev, "ECAM %pR conflicts with %s %pR\n",
                                 &cfg->res, tmp->name, tmp);
                } else if (pci_mmcfg_arch_map(cfg)) {
-                       dev_warn(dev, "fail to map MMCONFIG %pR.\n",
-                                &cfg->res);
+                       dev_warn(dev, "fail to map ECAM %pR\n", &cfg->res);
                } else {
                        list_add_sorted(cfg);
-                       dev_info(dev, "MMCONFIG at %pR (base %#lx)\n",
+                       dev_info(dev, "ECAM %pR (base %#lx)\n",
                                 &cfg->res, (unsigned long)addr);
                        cfg = NULL;
                        rc = 0;
@@ -823,7 +835,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
        return rc;
 }
 
-/* Delete MMCFG information for host bridges */
+/* Delete ECAM information for host bridges */
 int pci_mmconfig_delete(u16 seg, u8 start, u8 end)
 {
        struct pci_mmcfg_region *cfg;
index bfa7898753220b9548cd87eba7afaf565ae76a3e..f9ef97c593cf1ad13babeeab6ee4a9db0b614ba0 100644 (file)
@@ -131,7 +131,7 @@ const struct pci_raw_ops pci_mmcfg = {
 
 int __init pci_mmcfg_arch_init(void)
 {
-       printk(KERN_INFO "PCI: Using MMCONFIG for extended config space\n");
+       printk(KERN_INFO "PCI: Using ECAM for extended config space\n");
        raw_pci_ext_ops = &pci_mmcfg;
        return 1;
 }
index 0c7b6e66c64484d2bfa402033e70a3f5c901a485..cb5aa79a759e1ce9e5c1e5b77c3463afd5a05d30 100644 (file)
@@ -6,6 +6,8 @@
  * space mapped. This allows lockless config space operation.
  */
 
+#define pr_fmt(fmt) "PCI: " fmt
+
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
@@ -14,8 +16,6 @@
 #include <asm/e820/api.h>
 #include <asm/pci_x86.h>
 
-#define PREFIX "PCI: "
-
 static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
        struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
@@ -111,6 +111,25 @@ static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
        return addr;
 }
 
+int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
+{
+       cfg->virt = mcfg_ioremap(cfg);
+       if (!cfg->virt) {
+               pr_err("can't map ECAM at %pR\n", &cfg->res);
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
+{
+       if (cfg && cfg->virt) {
+               iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
+               cfg->virt = NULL;
+       }
+}
+
 int __init pci_mmcfg_arch_init(void)
 {
        struct pci_mmcfg_region *cfg;
@@ -133,22 +152,3 @@ void __init pci_mmcfg_arch_free(void)
        list_for_each_entry(cfg, &pci_mmcfg_list, list)
                pci_mmcfg_arch_unmap(cfg);
 }
-
-int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
-{
-       cfg->virt = mcfg_ioremap(cfg);
-       if (!cfg->virt) {
-               pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res);
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
-{
-       if (cfg && cfg->virt) {
-               iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
-               cfg->virt = NULL;
-       }
-}
index 4f15280732edb9983422e0b4a8ce5ede8fa138bb..244c643bb0b5f8bbbbc85c0ff1fe1874d23fce07 100644 (file)
@@ -3,6 +3,8 @@
  * BIOS32 and PCI BIOS handling.
  */
 
+#include <linux/bits.h>
+#include <linux/bitfield.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #define PCIBIOS_HW_TYPE1_SPEC          0x10
 #define PCIBIOS_HW_TYPE2_SPEC          0x20
 
+/*
+ * Returned in EAX:
+ * - AH: return code
+ */
+#define PCIBIOS_RETURN_CODE                    GENMASK(15, 8)
+
 int pcibios_enabled;
 
+static u8 pcibios_get_return_code(u32 eax)
+{
+       return FIELD_GET(PCIBIOS_RETURN_CODE, eax);
+}
+
 /* According to the BIOS specification at:
  * http://members.datafast.net.au/dft0802/specs/bios21.pdf, we could
  * restrict the x zone to some pages and make it ro. But this may be
@@ -154,7 +167,7 @@ static int __init check_pcibios(void)
                        : "memory");
                local_irq_restore(flags);
 
-               status = (eax >> 8) & 0xff;
+               status = pcibios_get_return_code(eax);
                hw_mech = eax & 0xff;
                major_ver = (ebx >> 8) & 0xff;
                minor_ver = ebx & 0xff;
@@ -227,7 +240,7 @@ static int pci_bios_read(unsigned int seg, unsigned int bus,
 
        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
-       return (int)((result & 0xff00) >> 8);
+       return pcibios_get_return_code(result);
 }
 
 static int pci_bios_write(unsigned int seg, unsigned int bus,
@@ -269,7 +282,7 @@ static int pci_bios_write(unsigned int seg, unsigned int bus,
 
        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 
-       return (int)((result & 0xff00) >> 8);
+       return pcibios_get_return_code(result);
 }
 
 
@@ -385,9 +398,10 @@ struct irq_routing_table * pcibios_get_irq_routing_table(void)
                  "m" (opt)
                : "memory");
        DBG("OK  ret=%d, size=%d, map=%x\n", ret, opt.size, map);
-       if (ret & 0xff00)
-               printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff);
-       else if (opt.size) {
+       ret = pcibios_get_return_code(ret);
+       if (ret) {
+               printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", ret);
+       } else if (opt.size) {
                rt = kmalloc(sizeof(struct irq_routing_table) + opt.size, GFP_KERNEL);
                if (rt) {
                        memset(rt, 0, sizeof(struct irq_routing_table));
@@ -415,7 +429,7 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
                  "b" ((dev->bus->number << 8) | dev->devfn),
                  "c" ((irq << 8) | (pin + 10)),
                  "S" (&pci_indirect));
-       return !(ret & 0xff00);
+       return pcibios_get_return_code(ret) == PCIBIOS_SUCCESSFUL;
 }
 EXPORT_SYMBOL(pcibios_set_irq_routing);
 
index 291d127113632040ae7991998129973a8ddb1a9c..1d5a70c9055ed600696958d5a438731fccf7a187 100644 (file)
@@ -47,6 +47,7 @@ config PCI_J721E
 
 config PCI_J721E_HOST
        bool "TI J721E PCIe controller (host mode)"
+       depends on ARCH_K3 || COMPILE_TEST
        depends on OF
        select PCIE_CADENCE_HOST
        select PCI_J721E
@@ -57,6 +58,7 @@ config PCI_J721E_HOST
 
 config PCI_J721E_EP
        bool "TI J721E PCIe controller (endpoint mode)"
+       depends on ARCH_K3 || COMPILE_TEST
        depends on OF
        depends on PCI_ENDPOINT
        select PCIE_CADENCE_EP
index 2c87e7728a653b4e6fab5fb14dbc8873b502defb..85718246016b733ee4c8e52ab6c6be2c6f13e93f 100644 (file)
@@ -42,18 +42,16 @@ enum link_status {
 };
 
 #define J721E_MODE_RC                  BIT(7)
-#define LANE_COUNT_MASK                        BIT(8)
 #define LANE_COUNT(n)                  ((n) << 8)
 
 #define GENERATION_SEL_MASK            GENMASK(1, 0)
 
-#define MAX_LANES                      2
-
 struct j721e_pcie {
        struct cdns_pcie        *cdns_pcie;
        struct clk              *refclk;
        u32                     mode;
        u32                     num_lanes;
+       u32                     max_lanes;
        void __iomem            *user_cfg_base;
        void __iomem            *intd_cfg_base;
        u32                     linkdown_irq_regfield;
@@ -71,6 +69,7 @@ struct j721e_pcie_data {
        unsigned int            quirk_disable_flr:1;
        u32                     linkdown_irq_regfield;
        unsigned int            byte_access_allowed:1;
+       unsigned int            max_lanes;
 };
 
 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
@@ -206,11 +205,15 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
 {
        struct device *dev = pcie->cdns_pcie->dev;
        u32 lanes = pcie->num_lanes;
+       u32 mask = BIT(8);
        u32 val = 0;
        int ret;
 
+       if (pcie->max_lanes == 4)
+               mask = GENMASK(9, 8);
+
        val = LANE_COUNT(lanes - 1);
-       ret = regmap_update_bits(syscon, offset, LANE_COUNT_MASK, val);
+       ret = regmap_update_bits(syscon, offset, mask, val);
        if (ret)
                dev_err(dev, "failed to set link count\n");
 
@@ -290,11 +293,13 @@ static const struct j721e_pcie_data j721e_pcie_rc_data = {
        .quirk_retrain_flag = true,
        .byte_access_allowed = false,
        .linkdown_irq_regfield = LINK_DOWN,
+       .max_lanes = 2,
 };
 
 static const struct j721e_pcie_data j721e_pcie_ep_data = {
        .mode = PCI_MODE_EP,
        .linkdown_irq_regfield = LINK_DOWN,
+       .max_lanes = 2,
 };
 
 static const struct j721e_pcie_data j7200_pcie_rc_data = {
@@ -302,23 +307,41 @@ static const struct j721e_pcie_data j7200_pcie_rc_data = {
        .quirk_detect_quiet_flag = true,
        .linkdown_irq_regfield = J7200_LINK_DOWN,
        .byte_access_allowed = true,
+       .max_lanes = 2,
 };
 
 static const struct j721e_pcie_data j7200_pcie_ep_data = {
        .mode = PCI_MODE_EP,
        .quirk_detect_quiet_flag = true,
        .quirk_disable_flr = true,
+       .max_lanes = 2,
 };
 
 static const struct j721e_pcie_data am64_pcie_rc_data = {
        .mode = PCI_MODE_RC,
        .linkdown_irq_regfield = J7200_LINK_DOWN,
        .byte_access_allowed = true,
+       .max_lanes = 1,
 };
 
 static const struct j721e_pcie_data am64_pcie_ep_data = {
        .mode = PCI_MODE_EP,
        .linkdown_irq_regfield = J7200_LINK_DOWN,
+       .max_lanes = 1,
+};
+
+static const struct j721e_pcie_data j784s4_pcie_rc_data = {
+       .mode = PCI_MODE_RC,
+       .quirk_retrain_flag = true,
+       .byte_access_allowed = false,
+       .linkdown_irq_regfield = LINK_DOWN,
+       .max_lanes = 4,
+};
+
+static const struct j721e_pcie_data j784s4_pcie_ep_data = {
+       .mode = PCI_MODE_EP,
+       .linkdown_irq_regfield = LINK_DOWN,
+       .max_lanes = 4,
 };
 
 static const struct of_device_id of_j721e_pcie_match[] = {
@@ -346,6 +369,14 @@ static const struct of_device_id of_j721e_pcie_match[] = {
                .compatible = "ti,am64-pcie-ep",
                .data = &am64_pcie_ep_data,
        },
+       {
+               .compatible = "ti,j784s4-pcie-host",
+               .data = &j784s4_pcie_rc_data,
+       },
+       {
+               .compatible = "ti,j784s4-pcie-ep",
+               .data = &j784s4_pcie_ep_data,
+       },
        {},
 };
 
@@ -432,9 +463,13 @@ static int j721e_pcie_probe(struct platform_device *pdev)
        pcie->user_cfg_base = base;
 
        ret = of_property_read_u32(node, "num-lanes", &num_lanes);
-       if (ret || num_lanes > MAX_LANES)
+       if (ret || num_lanes > data->max_lanes) {
+               dev_warn(dev, "num-lanes property not provided or invalid, setting num-lanes to 1\n");
                num_lanes = 1;
+       }
+
        pcie->num_lanes = num_lanes;
+       pcie->max_lanes = data->max_lanes;
 
        if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)))
                return -EINVAL;
index be52e9db44af6a3ca3e010714e3a58f2259f6d0c..acbe4f6d3291d829636093746fa2c339668334b9 100644 (file)
@@ -391,7 +391,7 @@ static const struct dw_pcie_ops intel_pcie_ops = {
 };
 
 static const struct dw_pcie_host_ops intel_pcie_dw_ops = {
-       .init =         intel_pcie_rc_init,
+       .init = intel_pcie_rc_init,
 };
 
 static int intel_pcie_probe(struct platform_device *pdev)
index 3c38e047d5eddc14285659adca654ee19b7fe0f6..60776b1fac758184b10391bcb051bb536d90d375 100644 (file)
@@ -325,7 +325,7 @@ keembay_pcie_get_features(struct dw_pcie_ep *ep)
 }
 
 static const struct dw_pcie_ep_ops keembay_pcie_ep_ops = {
-       .init   = keembay_pcie_ep_init,
+       .init           = keembay_pcie_ep_init,
        .raise_irq      = keembay_pcie_ep_raise_irq,
        .get_features   = keembay_pcie_get_features,
 };
index 6be3266cd7b5b2f803c60a71686ce8ffbf20be6d..45b71806182d2b8f9ae7cd876465684f6418abca 100644 (file)
@@ -85,7 +85,7 @@ int pci_host_common_probe(struct platform_device *pdev)
 }
 EXPORT_SYMBOL_GPL(pci_host_common_probe);
 
-int pci_host_common_remove(struct platform_device *pdev)
+void pci_host_common_remove(struct platform_device *pdev)
 {
        struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
 
@@ -93,8 +93,6 @@ int pci_host_common_remove(struct platform_device *pdev)
        pci_stop_root_bus(bridge->bus);
        pci_remove_root_bus(bridge->bus);
        pci_unlock_rescan_remove();
-
-       return 0;
 }
 EXPORT_SYMBOL_GPL(pci_host_common_remove);
 
index 63865aeb636b88d3f39e28095cb219dbc4522358..41cb6a057f6e4578c6f3460e80c8aaa677e9c0a4 100644 (file)
@@ -82,7 +82,7 @@ static struct platform_driver gen_pci_driver = {
                .of_match_table = gen_pci_of_match,
        },
        .probe = pci_host_common_probe,
-       .remove = pci_host_common_remove,
+       .remove_new = pci_host_common_remove,
 };
 module_platform_driver(gen_pci_driver);
 
index f9dd6622fe109566fc292e9d2d935691c5b8cc23..5b0730c3891b84226896b6865ddb50a5bd377c11 100644 (file)
@@ -48,6 +48,9 @@
 #define PCIE_RC_CFG_PRIV1_LINK_CAPABILITY                      0x04dc
 #define  PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK   0xc00
 
+#define PCIE_RC_CFG_PRIV1_ROOT_CAP                     0x4f8
+#define  PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK     0xf8
+
 #define PCIE_RC_DL_MDIO_ADDR                           0x1100
 #define PCIE_RC_DL_MDIO_WR_DATA                                0x1104
 #define PCIE_RC_DL_MDIO_RD_DATA                                0x1108
 
 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG                                 0x4204
 #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK       0x2
+#define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK               0x200000
 #define  PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK               0x08000000
 #define  PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK         0x00800000
-
+#define  PCIE_CLKREQ_MASK \
+         (PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK | \
+          PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK)
 
 #define PCIE_INTR2_CPU_BASE            0x4300
 #define PCIE_MSI_INTR2_BASE            0x4500
@@ -1028,13 +1034,89 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
        return 0;
 }
 
+/*
+ * This extends the timeout period for an access to an internal bus.  This
+ * access timeout may occur during L1SS sleep periods, even without the
+ * presence of a PCIe access.
+ */
+static void brcm_extend_rbus_timeout(struct brcm_pcie *pcie)
+{
+       /* TIMEOUT register is two registers before RGR1_SW_INIT_1 */
+       const unsigned int REG_OFFSET = PCIE_RGR1_SW_INIT_1(pcie) - 8;
+       u32 timeout_us = 4000000; /* 4 seconds, our setting for L1SS */
+
+       /* Each unit in timeout register is 1/216,000,000 seconds */
+       writel(216 * timeout_us, pcie->base + REG_OFFSET);
+}
+
+static void brcm_config_clkreq(struct brcm_pcie *pcie)
+{
+       static const char err_msg[] = "invalid 'brcm,clkreq-mode' DT string\n";
+       const char *mode = "default";
+       u32 clkreq_cntl;
+       int ret, tmp;
+
+       ret = of_property_read_string(pcie->np, "brcm,clkreq-mode", &mode);
+       if (ret && ret != -EINVAL) {
+               dev_err(pcie->dev, err_msg);
+               mode = "safe";
+       }
+
+       /* Start out assuming safe mode (both mode bits cleared) */
+       clkreq_cntl = readl(pcie->base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
+       clkreq_cntl &= ~PCIE_CLKREQ_MASK;
+
+       if (strcmp(mode, "no-l1ss") == 0) {
+               /*
+                * "no-l1ss" -- Provides Clock Power Management, L0s, and
+                * L1, but cannot provide L1 substate (L1SS) power
+                * savings. If the downstream device connected to the RC is
+                * L1SS capable AND the OS enables L1SS, all PCIe traffic
+                * may abruptly halt, potentially hanging the system.
+                */
+               clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
+               /*
+                * We want to un-advertise L1 substates because if the OS
+                * tries to configure the controller into using L1 substate
+                * power savings it may fail or hang when the RC HW is in
+                * "no-l1ss" mode.
+                */
+               tmp = readl(pcie->base + PCIE_RC_CFG_PRIV1_ROOT_CAP);
+               u32p_replace_bits(&tmp, 2, PCIE_RC_CFG_PRIV1_ROOT_CAP_L1SS_MODE_MASK);
+               writel(tmp, pcie->base + PCIE_RC_CFG_PRIV1_ROOT_CAP);
+
+       } else if (strcmp(mode, "default") == 0) {
+               /*
+                * "default" -- Provides L0s, L1, and L1SS, but not
+                * compliant to provide Clock Power Management;
+                * specifically, may not be able to meet the Tclron max
+                * timing of 400ns as specified in "Dynamic Clock Control",
+                * section 3.2.5.2.2 of the PCIe spec.  This situation is
+                * atypical and should happen only with older devices.
+                */
+               clkreq_cntl |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK;
+               brcm_extend_rbus_timeout(pcie);
+
+       } else {
+               /*
+                * "safe" -- No power savings; refclk is driven by RC
+                * unconditionally.
+                */
+               if (strcmp(mode, "safe") != 0)
+                       dev_err(pcie->dev, err_msg);
+               mode = "safe";
+       }
+       writel(clkreq_cntl, pcie->base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
+
+       dev_info(pcie->dev, "clkreq-mode set to %s\n", mode);
+}
+
 static int brcm_pcie_start_link(struct brcm_pcie *pcie)
 {
        struct device *dev = pcie->dev;
        void __iomem *base = pcie->base;
        u16 nlw, cls, lnksta;
        bool ssc_good = false;
-       u32 tmp;
        int ret, i;
 
        /* Unassert the fundamental reset */
@@ -1059,6 +1141,8 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
                return -ENODEV;
        }
 
+       brcm_config_clkreq(pcie);
+
        if (pcie->gen)
                brcm_pcie_set_gen(pcie, pcie->gen);
 
@@ -1077,14 +1161,6 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
                 pci_speed_string(pcie_link_speed[cls]), nlw,
                 ssc_good ? "(SSC)" : "(!SSC)");
 
-       /*
-        * Refclk from RC should be gated with CLKREQ# input when ASPM L0s,L1
-        * is enabled => setting the CLKREQ_DEBUG_ENABLE field to 1.
-        */
-       tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
-       tmp |= PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK;
-       writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG);
-
        return 0;
 }
 
index 25dbe85c4217585505510aeb19cadb7f7f491bdb..aaa33e8dc4c97734b5b1a678418de69426e2f05f 100644 (file)
@@ -745,6 +745,7 @@ static int sriov_init(struct pci_dev *dev, int pos)
        u16 ctrl, total;
        struct pci_sriov *iov;
        struct resource *res;
+       const char *res_name;
        struct pci_dev *pdev;
 
        pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl);
@@ -785,6 +786,8 @@ found:
        nres = 0;
        for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
                res = &dev->resource[i + PCI_IOV_RESOURCES];
+               res_name = pci_resource_name(dev, i + PCI_IOV_RESOURCES);
+
                /*
                 * If it is already FIXED, don't change it, something
                 * (perhaps EA or header fixups) wants it this way.
@@ -802,8 +805,8 @@ found:
                }
                iov->barsz[i] = resource_size(res);
                res->end = res->start + resource_size(res) * total - 1;
-               pci_info(dev, "VF(n) BAR%d space: %pR (contains BAR%d for %d VFs)\n",
-                        i, res, i, total);
+               pci_info(dev, "%s %pR: contains BAR %d for %d VFs\n",
+                        res_name, res, i, total);
                i += bar64;
                nres++;
        }
index 55bc3576a98562807522e233223119f047822056..101af94af2d4065f93137710639cd4bcd05ed560 100644 (file)
@@ -850,6 +850,66 @@ struct resource *pci_find_resource(struct pci_dev *dev, struct resource *res)
 }
 EXPORT_SYMBOL(pci_find_resource);
 
+/**
+ * pci_resource_name - Return the name of the PCI resource
+ * @dev: PCI device to query
+ * @i: index of the resource
+ *
+ * Return the standard PCI resource (BAR) name according to their index.
+ */
+const char *pci_resource_name(struct pci_dev *dev, unsigned int i)
+{
+       static const char * const bar_name[] = {
+               "BAR 0",
+               "BAR 1",
+               "BAR 2",
+               "BAR 3",
+               "BAR 4",
+               "BAR 5",
+               "ROM",
+#ifdef CONFIG_PCI_IOV
+               "VF BAR 0",
+               "VF BAR 1",
+               "VF BAR 2",
+               "VF BAR 3",
+               "VF BAR 4",
+               "VF BAR 5",
+#endif
+               "bridge window",        /* "io" included in %pR */
+               "bridge window",        /* "mem" included in %pR */
+               "bridge window",        /* "mem pref" included in %pR */
+       };
+       static const char * const cardbus_name[] = {
+               "BAR 1",
+               "unknown",
+               "unknown",
+               "unknown",
+               "unknown",
+               "unknown",
+#ifdef CONFIG_PCI_IOV
+               "unknown",
+               "unknown",
+               "unknown",
+               "unknown",
+               "unknown",
+               "unknown",
+#endif
+               "CardBus bridge window 0",      /* I/O */
+               "CardBus bridge window 1",      /* I/O */
+               "CardBus bridge window 0",      /* mem */
+               "CardBus bridge window 1",      /* mem */
+       };
+
+       if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS &&
+           i < ARRAY_SIZE(cardbus_name))
+               return cardbus_name[i];
+
+       if (i < ARRAY_SIZE(bar_name))
+               return bar_name[i];
+
+       return "unknown";
+}
+
 /**
  * pci_wait_for_pending - wait for @mask bit(s) to clear in status word @pos
  * @dev: the PCI device to operate on
@@ -3290,6 +3350,7 @@ static struct resource *pci_ea_get_resource(struct pci_dev *dev, u8 bei,
 static int pci_ea_read(struct pci_dev *dev, int offset)
 {
        struct resource *res;
+       const char *res_name;
        int ent_size, ent_offset = offset;
        resource_size_t start, end;
        unsigned long flags;
@@ -3319,6 +3380,7 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
                goto out;
 
        res = pci_ea_get_resource(dev, bei, prop);
+       res_name = pci_resource_name(dev, bei);
        if (!res) {
                pci_err(dev, "Unsupported EA entry BEI: %u\n", bei);
                goto out;
@@ -3392,16 +3454,16 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
        res->flags = flags;
 
        if (bei <= PCI_EA_BEI_BAR5)
-               pci_info(dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
-                          bei, res, prop);
+               pci_info(dev, "%s %pR: from Enhanced Allocation, properties %#02x\n",
+                        res_name, res, prop);
        else if (bei == PCI_EA_BEI_ROM)
-               pci_info(dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n",
-                          res, prop);
+               pci_info(dev, "%s %pR: from Enhanced Allocation, properties %#02x\n",
+                        res_name, res, prop);
        else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5)
-               pci_info(dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
-                          bei - PCI_EA_BEI_VF_BAR0, res, prop);
+               pci_info(dev, "%s %pR: from Enhanced Allocation, properties %#02x\n",
+                        res_name, res, prop);
        else
-               pci_info(dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n",
+               pci_info(dev, "BEI %d %pR: from Enhanced Allocation, properties %#02x\n",
                           bei, res, prop);
 
 out:
@@ -6689,14 +6751,15 @@ static void pci_request_resource_alignment(struct pci_dev *dev, int bar,
                                           resource_size_t align, bool resize)
 {
        struct resource *r = &dev->resource[bar];
+       const char *r_name = pci_resource_name(dev, bar);
        resource_size_t size;
 
        if (!(r->flags & IORESOURCE_MEM))
                return;
 
        if (r->flags & IORESOURCE_PCI_FIXED) {
-               pci_info(dev, "BAR%d %pR: ignoring requested alignment %#llx\n",
-                        bar, r, (unsigned long long)align);
+               pci_info(dev, "%s %pR: ignoring requested alignment %#llx\n",
+                        r_name, r, (unsigned long long)align);
                return;
        }
 
@@ -6732,8 +6795,8 @@ static void pci_request_resource_alignment(struct pci_dev *dev, int bar,
         * devices and we use the second.
         */
 
-       pci_info(dev, "BAR%d %pR: requesting alignment to %#llx\n",
-                bar, r, (unsigned long long)align);
+       pci_info(dev, "%s %pR: requesting alignment to %#llx\n",
+                r_name, r, (unsigned long long)align);
 
        if (resize) {
                r->start = 0;
index 5ecbcf0411793e2242121d00ee776b3cd8f5d294..251a1c9627da735a2c37aed229b78cdb5c5070d2 100644 (file)
@@ -255,6 +255,8 @@ void __pci_bus_assign_resources(const struct pci_bus *bus,
                                struct list_head *fail_head);
 bool pci_bus_clip_resource(struct pci_dev *dev, int idx);
 
+const char *pci_resource_name(struct pci_dev *dev, unsigned int i);
+
 void pci_reassigndev_resource_alignment(struct pci_dev *dev);
 void pci_disable_bridge_window(struct pci_dev *dev);
 struct pci_bus *pci_bus_get(struct pci_bus *bus);
@@ -272,7 +274,7 @@ void pci_bus_put(struct pci_bus *bus);
 
 /* PCIe speed to Mb/s reduced by encoding overhead */
 #define PCIE_SPEED2MBS_ENC(speed) \
-       ((speed) == PCIE_SPEED_64_0GT ? 64000*128/130 : \
+       ((speed) == PCIE_SPEED_64_0GT ? 64000*1/1 : \
         (speed) == PCIE_SPEED_32_0GT ? 32000*128/130 : \
         (speed) == PCIE_SPEED_16_0GT ? 16000*128/130 : \
         (speed) == PCIE_SPEED_8_0GT  ?  8000*128/130 : \
index 42a3bd35a3e118d8eb656d1d24b9f0fa0f4afaf7..05fc30bb5134d9ae31e681375d843b0f49738c30 100644 (file)
@@ -41,8 +41,8 @@
 #define AER_MAX_TYPEOF_UNCOR_ERRS      27      /* as per PCI_ERR_UNCOR_STATUS*/
 
 struct aer_err_source {
-       unsigned int status;
-       unsigned int id;
+       u32 status;                     /* PCI_ERR_ROOT_STATUS */
+       u32 id;                         /* PCI_ERR_ROOT_ERR_SRC */
 };
 
 struct aer_rpc {
@@ -435,10 +435,10 @@ void pci_aer_exit(struct pci_dev *dev)
 /*
  * AER error strings
  */
-static const char *aer_error_severity_string[] = {
-       "Uncorrected (Non-Fatal)",
-       "Uncorrected (Fatal)",
-       "Corrected"
+static const char * const aer_error_severity_string[] = {
+       "Uncorrectable (Non-Fatal)",
+       "Uncorrectable (Fatal)",
+       "Correctable"
 };
 
 static const char *aer_error_layer[] = {
@@ -740,7 +740,7 @@ static void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
        u8 bus = info->id >> 8;
        u8 devfn = info->id & 0xff;
 
-       pci_info(dev, "%s%s error received: %04x:%02x:%02x.%d\n",
+       pci_info(dev, "%s%s error message received from %04x:%02x:%02x.%d\n",
                 info->multi_error_valid ? "Multiple " : "",
                 aer_error_severity_string[info->severity],
                 pci_domain_nr(dev->bus), bus, PCI_SLOT(devfn),
@@ -929,7 +929,12 @@ static bool find_source_device(struct pci_dev *parent,
                pci_walk_bus(parent->subordinate, find_device_iter, e_info);
 
        if (!e_info->error_dev_num) {
-               pci_info(parent, "can't find device of ID%04x\n", e_info->id);
+               u8 bus = e_info->id >> 8;
+               u8 devfn = e_info->id & 0xff;
+
+               pci_info(parent, "found no error details for %04x:%02x:%02x.%d\n",
+                        pci_domain_nr(parent->bus), bus, PCI_SLOT(devfn),
+                        PCI_FUNC(devfn));
                return false;
        }
        return true;
index ed6b7f48736ad8b3c1a0cd83b2c0d213bffce4f5..b7335be56008f76ce0da493b56b40a35928af756 100644 (file)
@@ -180,6 +180,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
        u64 l64, sz64, mask64;
        u16 orig_cmd;
        struct pci_bus_region region, inverted_region;
+       const char *res_name = pci_resource_name(dev, res - dev->resource);
 
        mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
@@ -254,8 +255,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
        sz64 = pci_size(l64, sz64, mask64);
        if (!sz64) {
-               pci_info(dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
-                        pos);
+               pci_info(dev, FW_BUG "%s: invalid; can't size\n", res_name);
                goto fail;
        }
 
@@ -265,8 +265,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                        res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
                        res->start = 0;
                        res->end = 0;
-                       pci_err(dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
-                               pos, (unsigned long long)sz64);
+                       pci_err(dev, "%s: can't handle BAR larger than 4GB (size %#010llx)\n",
+                               res_name, (unsigned long long)sz64);
                        goto out;
                }
 
@@ -275,8 +275,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                        res->flags |= IORESOURCE_UNSET;
                        res->start = 0;
                        res->end = sz64 - 1;
-                       pci_info(dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
-                                pos, (unsigned long long)l64);
+                       pci_info(dev, "%s: can't handle BAR above 4GB (bus address %#010llx)\n",
+                                res_name, (unsigned long long)l64);
                        goto out;
                }
        }
@@ -302,8 +302,8 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                res->flags |= IORESOURCE_UNSET;
                res->start = 0;
                res->end = region.end - region.start;
-               pci_info(dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
-                        pos, (unsigned long long)region.start);
+               pci_info(dev, "%s: initial BAR value %#010llx invalid\n",
+                        res_name, (unsigned long long)region.start);
        }
 
        goto out;
@@ -313,7 +313,7 @@ fail:
        res->flags = 0;
 out:
        if (res->flags)
-               pci_info(dev, "reg 0x%x: %pR\n", pos, res);
+               pci_info(dev, "%s %pR\n", res_name, res);
 
        return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
 }
@@ -344,64 +344,12 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
        }
 }
 
-static void pci_read_bridge_windows(struct pci_dev *bridge)
+static void pci_read_bridge_io(struct pci_dev *dev, struct resource *res,
+                              bool log)
 {
-       u16 io;
-       u32 pmem, tmp;
-
-       pci_read_config_word(bridge, PCI_IO_BASE, &io);
-       if (!io) {
-               pci_write_config_word(bridge, PCI_IO_BASE, 0xe0f0);
-               pci_read_config_word(bridge, PCI_IO_BASE, &io);
-               pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
-       }
-       if (io)
-               bridge->io_window = 1;
-
-       /*
-        * DECchip 21050 pass 2 errata: the bridge may miss an address
-        * disconnect boundary by one PCI data phase.  Workaround: do not
-        * use prefetching on this device.
-        */
-       if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
-               return;
-
-       pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
-       if (!pmem) {
-               pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
-                                              0xffe0fff0);
-               pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
-               pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
-       }
-       if (!pmem)
-               return;
-
-       bridge->pref_window = 1;
-
-       if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
-
-               /*
-                * Bridge claims to have a 64-bit prefetchable memory
-                * window; verify that the upper bits are actually
-                * writable.
-                */
-               pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &pmem);
-               pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
-                                      0xffffffff);
-               pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
-               pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, pmem);
-               if (tmp)
-                       bridge->pref_64_window = 1;
-       }
-}
-
-static void pci_read_bridge_io(struct pci_bus *child)
-{
-       struct pci_dev *dev = child->self;
        u8 io_base_lo, io_limit_lo;
        unsigned long io_mask, io_granularity, base, limit;
        struct pci_bus_region region;
-       struct resource *res;
 
        io_mask = PCI_IO_RANGE_MASK;
        io_granularity = 0x1000;
@@ -411,7 +359,6 @@ static void pci_read_bridge_io(struct pci_bus *child)
                io_granularity = 0x400;
        }
 
-       res = child->resource[0];
        pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
        pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
        base = (io_base_lo & io_mask) << 8;
@@ -431,19 +378,18 @@ static void pci_read_bridge_io(struct pci_bus *child)
                region.start = base;
                region.end = limit + io_granularity - 1;
                pcibios_bus_to_resource(dev->bus, res, &region);
-               pci_info(dev, "  bridge window %pR\n", res);
+               if (log)
+                       pci_info(dev, "  bridge window %pR\n", res);
        }
 }
 
-static void pci_read_bridge_mmio(struct pci_bus *child)
+static void pci_read_bridge_mmio(struct pci_dev *dev, struct resource *res,
+                                bool log)
 {
-       struct pci_dev *dev = child->self;
        u16 mem_base_lo, mem_limit_lo;
        unsigned long base, limit;
        struct pci_bus_region region;
-       struct resource *res;
 
-       res = child->resource[1];
        pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
        pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
        base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
@@ -453,20 +399,19 @@ static void pci_read_bridge_mmio(struct pci_bus *child)
                region.start = base;
                region.end = limit + 0xfffff;
                pcibios_bus_to_resource(dev->bus, res, &region);
-               pci_info(dev, "  bridge window %pR\n", res);
+               if (log)
+                       pci_info(dev, "  bridge window %pR\n", res);
        }
 }
 
-static void pci_read_bridge_mmio_pref(struct pci_bus *child)
+static void pci_read_bridge_mmio_pref(struct pci_dev *dev, struct resource *res,
+                                     bool log)
 {
-       struct pci_dev *dev = child->self;
        u16 mem_base_lo, mem_limit_lo;
        u64 base64, limit64;
        pci_bus_addr_t base, limit;
        struct pci_bus_region region;
-       struct resource *res;
 
-       res = child->resource[2];
        pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
        pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
        base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
@@ -506,10 +451,77 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
                region.start = base;
                region.end = limit + 0xfffff;
                pcibios_bus_to_resource(dev->bus, res, &region);
-               pci_info(dev, "  bridge window %pR\n", res);
+               if (log)
+                       pci_info(dev, "  bridge window %pR\n", res);
        }
 }
 
+static void pci_read_bridge_windows(struct pci_dev *bridge)
+{
+       u32 buses;
+       u16 io;
+       u32 pmem, tmp;
+       struct resource res;
+
+       pci_read_config_dword(bridge, PCI_PRIMARY_BUS, &buses);
+       res.flags = IORESOURCE_BUS;
+       res.start = (buses >> 8) & 0xff;
+       res.end = (buses >> 16) & 0xff;
+       pci_info(bridge, "PCI bridge to %pR%s\n", &res,
+                bridge->transparent ? " (subtractive decode)" : "");
+
+       pci_read_config_word(bridge, PCI_IO_BASE, &io);
+       if (!io) {
+               pci_write_config_word(bridge, PCI_IO_BASE, 0xe0f0);
+               pci_read_config_word(bridge, PCI_IO_BASE, &io);
+               pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
+       }
+       if (io) {
+               bridge->io_window = 1;
+               pci_read_bridge_io(bridge, &res, true);
+       }
+
+       pci_read_bridge_mmio(bridge, &res, true);
+
+       /*
+        * DECchip 21050 pass 2 errata: the bridge may miss an address
+        * disconnect boundary by one PCI data phase.  Workaround: do not
+        * use prefetching on this device.
+        */
+       if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
+               return;
+
+       pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
+       if (!pmem) {
+               pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
+                                              0xffe0fff0);
+               pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
+               pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
+       }
+       if (!pmem)
+               return;
+
+       bridge->pref_window = 1;
+
+       if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
+
+               /*
+                * Bridge claims to have a 64-bit prefetchable memory
+                * window; verify that the upper bits are actually
+                * writable.
+                */
+               pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &pmem);
+               pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
+                                      0xffffffff);
+               pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
+               pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, pmem);
+               if (tmp)
+                       bridge->pref_64_window = 1;
+       }
+
+       pci_read_bridge_mmio_pref(bridge, &res, true);
+}
+
 void pci_read_bridge_bases(struct pci_bus *child)
 {
        struct pci_dev *dev = child->self;
@@ -527,9 +539,9 @@ void pci_read_bridge_bases(struct pci_bus *child)
        for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
                child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
 
-       pci_read_bridge_io(child);
-       pci_read_bridge_mmio(child);
-       pci_read_bridge_mmio_pref(child);
+       pci_read_bridge_io(child->self, child->resource[0], false);
+       pci_read_bridge_mmio(child->self, child->resource[1], false);
+       pci_read_bridge_mmio_pref(child->self, child->resource[2], false);
 
        if (dev->transparent) {
                pci_bus_for_each_resource(child->parent, res) {
@@ -1817,6 +1829,43 @@ static void early_dump_pci_device(struct pci_dev *pdev)
                       value, 256, false);
 }
 
+static const char *pci_type_str(struct pci_dev *dev)
+{
+       static const char * const str[] = {
+               "PCIe Endpoint",
+               "PCIe Legacy Endpoint",
+               "PCIe unknown",
+               "PCIe unknown",
+               "PCIe Root Port",
+               "PCIe Switch Upstream Port",
+               "PCIe Switch Downstream Port",
+               "PCIe to PCI/PCI-X bridge",
+               "PCI/PCI-X to PCIe bridge",
+               "PCIe Root Complex Integrated Endpoint",
+               "PCIe Root Complex Event Collector",
+       };
+       int type;
+
+       if (pci_is_pcie(dev)) {
+               type = pci_pcie_type(dev);
+               if (type < ARRAY_SIZE(str))
+                       return str[type];
+
+               return "PCIe unknown";
+       }
+
+       switch (dev->hdr_type) {
+       case PCI_HEADER_TYPE_NORMAL:
+               return "conventional PCI endpoint";
+       case PCI_HEADER_TYPE_BRIDGE:
+               return "conventional PCI bridge";
+       case PCI_HEADER_TYPE_CARDBUS:
+               return "CardBus bridge";
+       default:
+               return "conventional PCI";
+       }
+}
+
 /**
  * pci_setup_device - Fill in class and map information of a device
  * @dev: the device structure to fill
@@ -1887,8 +1936,9 @@ int pci_setup_device(struct pci_dev *dev)
 
        pci_set_removable(dev);
 
-       pci_info(dev, "[%04x:%04x] type %02x class %#08x\n",
-                dev->vendor, dev->device, dev->hdr_type, dev->class);
+       pci_info(dev, "[%04x:%04x] type %02x class %#08x %s\n",
+                dev->vendor, dev->device, dev->hdr_type, dev->class,
+                pci_type_str(dev));
 
        /* Device class may be changed after fixup */
        class = dev->class >> 8;
@@ -1929,14 +1979,14 @@ int pci_setup_device(struct pci_dev *dev)
                                res = &dev->resource[0];
                                res->flags = LEGACY_IO_RESOURCE;
                                pcibios_bus_to_resource(dev->bus, res, &region);
-                               pci_info(dev, "legacy IDE quirk: reg 0x10: %pR\n",
+                               pci_info(dev, "BAR 0 %pR: legacy IDE quirk\n",
                                         res);
                                region.start = 0x3F6;
                                region.end = 0x3F6;
                                res = &dev->resource[1];
                                res->flags = LEGACY_IO_RESOURCE;
                                pcibios_bus_to_resource(dev->bus, res, &region);
-                               pci_info(dev, "legacy IDE quirk: reg 0x14: %pR\n",
+                               pci_info(dev, "BAR 1 %pR: legacy IDE quirk\n",
                                         res);
                        }
                        if ((progif & 4) == 0) {
@@ -1945,14 +1995,14 @@ int pci_setup_device(struct pci_dev *dev)
                                res = &dev->resource[2];
                                res->flags = LEGACY_IO_RESOURCE;
                                pcibios_bus_to_resource(dev->bus, res, &region);
-                               pci_info(dev, "legacy IDE quirk: reg 0x18: %pR\n",
+                               pci_info(dev, "BAR 2 %pR: legacy IDE quirk\n",
                                         res);
                                region.start = 0x376;
                                region.end = 0x376;
                                res = &dev->resource[3];
                                res->flags = LEGACY_IO_RESOURCE;
                                pcibios_bus_to_resource(dev->bus, res, &region);
-                               pci_info(dev, "legacy IDE quirk: reg 0x1c: %pR\n",
+                               pci_info(dev, "BAR 3 %pR: legacy IDE quirk\n",
                                         res);
                        }
                }
index ea476252280abb348655f99a8e8e4a88371f6138..e4bf0ed46393128b21c5aca3d6231f3dba845f5c 100644 (file)
@@ -570,13 +570,14 @@ static void quirk_extend_bar_to_page(struct pci_dev *dev)
 
        for (i = 0; i < PCI_STD_NUM_BARS; i++) {
                struct resource *r = &dev->resource[i];
+               const char *r_name = pci_resource_name(dev, i);
 
                if (r->flags & IORESOURCE_MEM && resource_size(r) < PAGE_SIZE) {
                        r->end = PAGE_SIZE - 1;
                        r->start = 0;
                        r->flags |= IORESOURCE_UNSET;
-                       pci_info(dev, "expanded BAR %d to page size: %pR\n",
-                                i, r);
+                       pci_info(dev, "%s %pR: expanded to page size\n",
+                                r_name, r);
                }
        }
 }
@@ -605,6 +606,7 @@ static void quirk_io(struct pci_dev *dev, int pos, unsigned int size,
        u32 region;
        struct pci_bus_region bus_region;
        struct resource *res = dev->resource + pos;
+       const char *res_name = pci_resource_name(dev, pos);
 
        pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (pos << 2), &region);
 
@@ -622,8 +624,7 @@ static void quirk_io(struct pci_dev *dev, int pos, unsigned int size,
        bus_region.end = region + size - 1;
        pcibios_bus_to_resource(dev->bus, res, &bus_region);
 
-       pci_info(dev, FW_BUG "%s quirk: reg 0x%x: %pR\n",
-                name, PCI_BASE_ADDRESS_0 + (pos << 2), res);
+       pci_info(dev, FW_BUG "%s %pR: %s quirk\n", res_name, res, name);
 }
 
 /*
@@ -670,6 +671,12 @@ static void quirk_io_region(struct pci_dev *dev, int port,
        bus_region.end = region + size - 1;
        pcibios_bus_to_resource(dev->bus, res, &bus_region);
 
+       /*
+        * "res" is typically a bridge window resource that's not being
+        * used for a bridge window, so it's just a place to stash this
+        * non-standard resource.  Printing "nr" or pci_resource_name() of
+        * it doesn't really make sense.
+        */
        if (!pci_claim_resource(dev, nr))
                pci_info(dev, "quirk: %pR claimed by %s\n", res, name);
 }
@@ -702,10 +709,13 @@ static void quirk_amd_dwc_class(struct pci_dev *pdev)
 {
        u32 class = pdev->class;
 
-       /* Use "USB Device (not host controller)" class */
-       pdev->class = PCI_CLASS_SERIAL_USB_DEVICE;
-       pci_info(pdev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n",
-                class, pdev->class);
+       if (class != PCI_CLASS_SERIAL_USB_DEVICE) {
+               /* Use "USB Device (not host controller)" class */
+               pdev->class = PCI_CLASS_SERIAL_USB_DEVICE;
+               pci_info(pdev,
+                       "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_dwc_class);
@@ -4699,17 +4709,21 @@ static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags)
  * But the implementation could block peer-to-peer transactions between them
  * and provide ACS-like functionality.
  */
-static int  pci_quirk_zhaoxin_pcie_ports_acs(struct pci_dev *dev, u16 acs_flags)
+static int pci_quirk_zhaoxin_pcie_ports_acs(struct pci_dev *dev, u16 acs_flags)
 {
        if (!pci_is_pcie(dev) ||
            ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) &&
             (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)))
                return -ENOTTY;
 
+       /*
+        * Future Zhaoxin Root Ports and Switch Downstream Ports will
+        * implement ACS capability in accordance with the PCIe Spec.
+        */
        switch (dev->device) {
        case 0x0710 ... 0x071e:
        case 0x0721:
-       case 0x0723 ... 0x0732:
+       case 0x0723 ... 0x0752:
                return pci_acs_ctrl_enabled(acs_flags,
                        PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF);
        }
index fd74f1c99dbae766ab67e3cd9d3550b4452b495e..909e6a7c3cc31b46e7d68c8cff2edbfd4b2420d6 100644 (file)
@@ -213,6 +213,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
                                      struct list_head *head)
 {
        struct resource *res;
+       const char *res_name;
        struct pci_dev_resource *add_res, *tmp;
        struct pci_dev_resource *dev_res;
        resource_size_t add_size, align;
@@ -222,6 +223,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
                bool found_match = false;
 
                res = add_res->res;
+
                /* Skip resource that has been reset */
                if (!res->flags)
                        goto out;
@@ -237,6 +239,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
                        continue;
 
                idx = res - &add_res->dev->resource[0];
+               res_name = pci_resource_name(add_res->dev, idx);
                add_size = add_res->add_size;
                align = add_res->min_align;
                if (!resource_size(res)) {
@@ -249,9 +252,9 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
                                 (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN);
                        if (pci_reassign_resource(add_res->dev, idx,
                                                  add_size, align))
-                               pci_info(add_res->dev, "failed to add %llx res[%d]=%pR\n",
-                                        (unsigned long long) add_size, idx,
-                                        res);
+                               pci_info(add_res->dev, "%s %pR: failed to add %llx\n",
+                                        res_name, res,
+                                        (unsigned long long) add_size);
                }
 out:
                list_del(&add_res->list);
@@ -571,6 +574,7 @@ EXPORT_SYMBOL(pci_setup_cardbus);
 static void pci_setup_bridge_io(struct pci_dev *bridge)
 {
        struct resource *res;
+       const char *res_name;
        struct pci_bus_region region;
        unsigned long io_mask;
        u8 io_base_lo, io_limit_lo;
@@ -583,6 +587,7 @@ static void pci_setup_bridge_io(struct pci_dev *bridge)
 
        /* Set up the top and bottom of the PCI I/O segment for this bus */
        res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
+       res_name = pci_resource_name(bridge, PCI_BRIDGE_IO_WINDOW);
        pcibios_resource_to_bus(bridge->bus, &region, res);
        if (res->flags & IORESOURCE_IO) {
                pci_read_config_word(bridge, PCI_IO_BASE, &l);
@@ -591,7 +596,7 @@ static void pci_setup_bridge_io(struct pci_dev *bridge)
                l = ((u16) io_limit_lo << 8) | io_base_lo;
                /* Set up upper 16 bits of I/O base/limit */
                io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
-               pci_info(bridge, "  bridge window %pR\n", res);
+               pci_info(bridge, "  %s %pR\n", res_name, res);
        } else {
                /* Clear upper 16 bits of I/O base/limit */
                io_upper16 = 0;
@@ -608,16 +613,18 @@ static void pci_setup_bridge_io(struct pci_dev *bridge)
 static void pci_setup_bridge_mmio(struct pci_dev *bridge)
 {
        struct resource *res;
+       const char *res_name;
        struct pci_bus_region region;
        u32 l;
 
        /* Set up the top and bottom of the PCI Memory segment for this bus */
        res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
+       res_name = pci_resource_name(bridge, PCI_BRIDGE_MEM_WINDOW);
        pcibios_resource_to_bus(bridge->bus, &region, res);
        if (res->flags & IORESOURCE_MEM) {
                l = (region.start >> 16) & 0xfff0;
                l |= region.end & 0xfff00000;
-               pci_info(bridge, "  bridge window %pR\n", res);
+               pci_info(bridge, "  %s %pR\n", res_name, res);
        } else {
                l = 0x0000fff0;
        }
@@ -627,6 +634,7 @@ static void pci_setup_bridge_mmio(struct pci_dev *bridge)
 static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge)
 {
        struct resource *res;
+       const char *res_name;
        struct pci_bus_region region;
        u32 l, bu, lu;
 
@@ -640,6 +648,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge)
        /* Set up PREF base/limit */
        bu = lu = 0;
        res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+       res_name = pci_resource_name(bridge, PCI_BRIDGE_PREF_MEM_WINDOW);
        pcibios_resource_to_bus(bridge->bus, &region, res);
        if (res->flags & IORESOURCE_PREFETCH) {
                l = (region.start >> 16) & 0xfff0;
@@ -648,7 +657,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge)
                        bu = upper_32_bits(region.start);
                        lu = upper_32_bits(region.end);
                }
-               pci_info(bridge, "  bridge window %pR\n", res);
+               pci_info(bridge, "  %s %pR\n", res_name, res);
        } else {
                l = 0x0000fff0;
        }
@@ -1013,6 +1022,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
                int i;
 
                pci_dev_for_each_resource(dev, r, i) {
+                       const char *r_name = pci_resource_name(dev, i);
                        resource_size_t r_size;
 
                        if (r->parent || (r->flags & IORESOURCE_PCI_FIXED) ||
@@ -1043,8 +1053,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
                        if (order < 0)
                                order = 0;
                        if (order >= ARRAY_SIZE(aligns)) {
-                               pci_warn(dev, "disabling BAR %d: %pR (bad alignment %#llx)\n",
-                                        i, r, (unsigned long long) align);
+                               pci_warn(dev, "%s %pR: disabling; bad alignment %#llx\n",
+                                        r_name, r, (unsigned long long) align);
                                r->flags = 0;
                                continue;
                        }
@@ -2235,6 +2245,7 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
                for (i = PCI_BRIDGE_RESOURCES; i < PCI_BRIDGE_RESOURCE_END;
                     i++) {
                        struct resource *res = &bridge->resource[i];
+                       const char *res_name = pci_resource_name(bridge, i);
 
                        if ((res->flags ^ type) & PCI_RES_TYPE_MASK)
                                continue;
@@ -2247,8 +2258,7 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
                        if (ret)
                                goto cleanup;
 
-                       pci_info(bridge, "BAR %d: releasing %pR\n",
-                                i, res);
+                       pci_info(bridge, "%s %pR: releasing\n", res_name, res);
 
                        if (res->parent)
                                release_resource(res);
index ceaa69491f5efe7f06af3ee8b1fe7d0a9cce38f6..c6d933ddfd46491c60bc2e9501bf5ac7610cbcd8 100644 (file)
@@ -30,6 +30,7 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
        u32 new, check, mask;
        int reg;
        struct resource *res = dev->resource + resno;
+       const char *res_name = pci_resource_name(dev, resno);
 
        /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
        if (dev->is_virtfn)
@@ -104,8 +105,8 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
        pci_read_config_dword(dev, reg, &check);
 
        if ((new ^ check) & mask) {
-               pci_err(dev, "BAR %d: error updating (%#010x != %#010x)\n",
-                       resno, new, check);
+               pci_err(dev, "%s: error updating (%#010x != %#010x)\n",
+                       res_name, new, check);
        }
 
        if (res->flags & IORESOURCE_MEM_64) {
@@ -113,8 +114,8 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
                pci_write_config_dword(dev, reg + 4, new);
                pci_read_config_dword(dev, reg + 4, &check);
                if (check != new) {
-                       pci_err(dev, "BAR %d: error updating (high %#010x != %#010x)\n",
-                               resno, new, check);
+                       pci_err(dev, "%s: error updating (high %#010x != %#010x)\n",
+                               res_name, new, check);
                }
        }
 
@@ -135,11 +136,12 @@ void pci_update_resource(struct pci_dev *dev, int resno)
 int pci_claim_resource(struct pci_dev *dev, int resource)
 {
        struct resource *res = &dev->resource[resource];
+       const char *res_name = pci_resource_name(dev, resource);
        struct resource *root, *conflict;
 
        if (res->flags & IORESOURCE_UNSET) {
-               pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
-                        resource, res);
+               pci_info(dev, "%s %pR: can't claim; no address assigned\n",
+                        res_name, res);
                return -EINVAL;
        }
 
@@ -153,16 +155,16 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
 
        root = pci_find_parent_resource(dev, res);
        if (!root) {
-               pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
-                        resource, res);
+               pci_info(dev, "%s %pR: can't claim; no compatible bridge window\n",
+                        res_name, res);
                res->flags |= IORESOURCE_UNSET;
                return -EINVAL;
        }
 
        conflict = request_resource_conflict(root, res);
        if (conflict) {
-               pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
-                        resource, res, conflict->name, conflict);
+               pci_info(dev, "%s %pR: can't claim; address conflict with %s %pR\n",
+                        res_name, res, conflict->name, conflict);
                res->flags |= IORESOURCE_UNSET;
                return -EBUSY;
        }
@@ -201,6 +203,7 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
 {
        struct resource *root, *conflict;
        resource_size_t fw_addr, start, end;
+       const char *res_name = pci_resource_name(dev, resno);
 
        fw_addr = pcibios_retrieve_fw_addr(dev, resno);
        if (!fw_addr)
@@ -231,12 +234,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
                        root = &iomem_resource;
        }
 
-       pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
-                resno, res);
+       pci_info(dev, "%s: trying firmware assignment %pR\n", res_name, res);
        conflict = request_resource_conflict(root, res);
        if (conflict) {
-               pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
-                        resno, res, conflict->name, conflict);
+               pci_info(dev, "%s %pR: conflicts with %s %pR\n", res_name, res,
+                        conflict->name, conflict);
                res->start = start;
                res->end = end;
                res->flags |= IORESOURCE_UNSET;
@@ -325,6 +327,7 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno,
 int pci_assign_resource(struct pci_dev *dev, int resno)
 {
        struct resource *res = dev->resource + resno;
+       const char *res_name = pci_resource_name(dev, resno);
        resource_size_t align, size;
        int ret;
 
@@ -334,8 +337,8 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
        res->flags |= IORESOURCE_UNSET;
        align = pci_resource_alignment(dev, res);
        if (!align) {
-               pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
-                        resno, res);
+               pci_info(dev, "%s %pR: can't assign; bogus alignment\n",
+                        res_name, res);
                return -EINVAL;
        }
 
@@ -348,18 +351,18 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
         * working, which is better than just leaving it disabled.
         */
        if (ret < 0) {
-               pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
+               pci_info(dev, "%s %pR: can't assign; no space\n", res_name, res);
                ret = pci_revert_fw_address(res, dev, resno, size);
        }
 
        if (ret < 0) {
-               pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
+               pci_info(dev, "%s %pR: failed to assign\n", res_name, res);
                return ret;
        }
 
        res->flags &= ~IORESOURCE_UNSET;
        res->flags &= ~IORESOURCE_STARTALIGN;
-       pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
+       pci_info(dev, "%s %pR: assigned\n", res_name, res);
        if (resno < PCI_BRIDGE_RESOURCES)
                pci_update_resource(dev, resno);
 
@@ -367,10 +370,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 }
 EXPORT_SYMBOL(pci_assign_resource);
 
-int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
-                       resource_size_t min_align)
+int pci_reassign_resource(struct pci_dev *dev, int resno,
+                         resource_size_t addsize, resource_size_t min_align)
 {
        struct resource *res = dev->resource + resno;
+       const char *res_name = pci_resource_name(dev, resno);
        unsigned long flags;
        resource_size_t new_size;
        int ret;
@@ -381,8 +385,8 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
        flags = res->flags;
        res->flags |= IORESOURCE_UNSET;
        if (!res->parent) {
-               pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
-                        resno, res);
+               pci_info(dev, "%s %pR: can't reassign; unassigned resource\n",
+                        res_name, res);
                return -EINVAL;
        }
 
@@ -391,15 +395,15 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
        ret = _pci_assign_resource(dev, resno, new_size, min_align);
        if (ret) {
                res->flags = flags;
-               pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
-                        resno, res, (unsigned long long) addsize);
+               pci_info(dev, "%s %pR: failed to expand by %#llx\n",
+                        res_name, res, (unsigned long long) addsize);
                return ret;
        }
 
        res->flags &= ~IORESOURCE_UNSET;
        res->flags &= ~IORESOURCE_STARTALIGN;
-       pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
-                resno, res, (unsigned long long) addsize);
+       pci_info(dev, "%s %pR: reassigned; expanded by %#llx\n",
+                res_name, res, (unsigned long long) addsize);
        if (resno < PCI_BRIDGE_RESOURCES)
                pci_update_resource(dev, resno);
 
@@ -409,8 +413,9 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
 void pci_release_resource(struct pci_dev *dev, int resno)
 {
        struct resource *res = dev->resource + resno;
+       const char *res_name = pci_resource_name(dev, resno);
 
-       pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
+       pci_info(dev, "%s %pR: releasing\n", res_name, res);
 
        if (!res->parent)
                return;
@@ -480,6 +485,7 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
        u16 cmd, old_cmd;
        int i;
        struct resource *r;
+       const char *r_name;
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        old_cmd = cmd;
@@ -488,6 +494,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
                if (!(mask & (1 << i)))
                        continue;
 
+               r_name = pci_resource_name(dev, i);
+
                if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
                        continue;
                if ((i == PCI_ROM_RESOURCE) &&
@@ -495,14 +503,14 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
                        continue;
 
                if (r->flags & IORESOURCE_UNSET) {
-                       pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
-                               i, r);
+                       pci_err(dev, "%s %pR: not assigned; can't enable device\n",
+                               r_name, r);
                        return -EINVAL;
                }
 
                if (!r->parent) {
-                       pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
-                               i, r);
+                       pci_err(dev, "%s %pR: not claimed; can't enable device\n",
+                               r_name, r);
                        return -EINVAL;
                }
 
index 5b921387eca61a7444f20ec3ae9b531c01fdb6c4..1804794d0e686f22febe508c58aa340f03eecd23 100644 (file)
@@ -1308,13 +1308,6 @@ static void stdev_release(struct device *dev)
 {
        struct switchtec_dev *stdev = to_stdev(dev);
 
-       if (stdev->dma_mrpc) {
-               iowrite32(0, &stdev->mmio_mrpc->dma_en);
-               flush_wc_buf(stdev);
-               writeq(0, &stdev->mmio_mrpc->dma_addr);
-               dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc),
-                               stdev->dma_mrpc, stdev->dma_mrpc_dma_addr);
-       }
        kfree(stdev);
 }
 
@@ -1358,7 +1351,7 @@ static struct switchtec_dev *stdev_create(struct pci_dev *pdev)
                return ERR_PTR(-ENOMEM);
 
        stdev->alive = true;
-       stdev->pdev = pdev;
+       stdev->pdev = pci_dev_get(pdev);
        INIT_LIST_HEAD(&stdev->mrpc_queue);
        mutex_init(&stdev->mrpc_mutex);
        stdev->mrpc_busy = 0;
@@ -1391,6 +1384,7 @@ static struct switchtec_dev *stdev_create(struct pci_dev *pdev)
        return stdev;
 
 err_put:
+       pci_dev_put(stdev->pdev);
        put_device(&stdev->dev);
        return ERR_PTR(rc);
 }
@@ -1644,6 +1638,18 @@ static int switchtec_init_pci(struct switchtec_dev *stdev,
        return 0;
 }
 
+static void switchtec_exit_pci(struct switchtec_dev *stdev)
+{
+       if (stdev->dma_mrpc) {
+               iowrite32(0, &stdev->mmio_mrpc->dma_en);
+               flush_wc_buf(stdev);
+               writeq(0, &stdev->mmio_mrpc->dma_addr);
+               dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc),
+                                 stdev->dma_mrpc, stdev->dma_mrpc_dma_addr);
+               stdev->dma_mrpc = NULL;
+       }
+}
+
 static int switchtec_pci_probe(struct pci_dev *pdev,
                               const struct pci_device_id *id)
 {
@@ -1703,6 +1709,9 @@ static void switchtec_pci_remove(struct pci_dev *pdev)
        ida_free(&switchtec_minor_ida, MINOR(stdev->dev.devt));
        dev_info(&stdev->dev, "unregistered.\n");
        stdev_kill(stdev);
+       switchtec_exit_pci(stdev);
+       pci_dev_put(stdev->pdev);
+       stdev->pdev = NULL;
        put_device(&stdev->dev);
 }
 
index 9386e7b447506915110a8ba0299538bad1438ad0..4ac6afd3c2fe9782db7a752e4fa97b5fcf463e91 100644 (file)
@@ -4875,7 +4875,7 @@ void lpfc_reset_barrier(struct lpfc_hba *phba)
        lockdep_assert_held(&phba->hbalock);
 
        pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
-       if (hdrtype != 0x80 ||
+       if (hdrtype != PCI_HEADER_TYPE_MFD ||
            (FC_JEDEC_ID(phba->vpd.rev.biuRev) != HELIOS_JEDEC_ID &&
             FC_JEDEC_ID(phba->vpd.rev.biuRev) != THOR_JEDEC_ID))
                return;
index f6ea2f57d8089688870aed9a962cc742ff44da58..ae0fae70d4bd2c15a7109ba89dcfd5974177a930 100644 (file)
 struct pci_dev;
 
 struct aer_header_log_regs {
-       unsigned int dw0;
-       unsigned int dw1;
-       unsigned int dw2;
-       unsigned int dw3;
+       u32 dw0;
+       u32 dw1;
+       u32 dw2;
+       u32 dw3;
 };
 
 struct aer_capability_regs {
index 6b1301e2498e9e163c6e9a0525e49afa226bffea..3a4860bd27586587cb23e7d6f84f63efcf6f2fc6 100644 (file)
@@ -93,6 +93,6 @@ extern const struct pci_ecam_ops loongson_pci_ecam_ops; /* Loongson PCIe */
 #if IS_ENABLED(CONFIG_PCI_HOST_COMMON)
 /* for DT-based PCI controllers that support ECAM */
 int pci_host_common_probe(struct platform_device *pdev);
-int pci_host_common_remove(struct platform_device *pdev);
+void pci_host_common_remove(struct platform_device *pdev);
 #endif
 #endif
index 60ca768bc8679f4ff135f2d0364e46b5e7ab4fb9..4ebecc7896ef91993a7b8016d3bcab363a4eeb54 100644 (file)
@@ -2127,14 +2127,14 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
        (pci_resource_end((dev), (bar)) ?                               \
         resource_size(pci_resource_n((dev), (bar))) : 0)
 
-#define __pci_dev_for_each_res0(dev, res, ...)                         \
-       for (unsigned int __b = 0;                                      \
-            res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES;   \
+#define __pci_dev_for_each_res0(dev, res, ...)                           \
+       for (unsigned int __b = 0;                                        \
+            __b < PCI_NUM_RESOURCES && (res = pci_resource_n(dev, __b)); \
             __b++)
 
-#define __pci_dev_for_each_res1(dev, res, __b)                         \
-       for (__b = 0;                                                   \
-            res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES;   \
+#define __pci_dev_for_each_res1(dev, res, __b)                           \
+       for (__b = 0;                                                     \
+            __b < PCI_NUM_RESOURCES && (res = pci_resource_n(dev, __b)); \
             __b++)
 
 #define pci_dev_for_each_resource(dev, res, ...)                       \