Merge branch 'remotes/lorenzo/pci/mediatek'
authorBjorn Helgaas <bhelgaas@google.com>
Tue, 4 May 2021 15:43:28 +0000 (10:43 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 4 May 2021 15:43:28 +0000 (10:43 -0500)
- Configure FC and FTS for functions other than 0 (Ryder Lee)

- Add missing MODULE_DEVICE_TABLE (Qiheng Lin)

- Add YAML schema for MediaTek (Jianjun Wang)

- Export pci_pio_to_address() for module use (Jianjun Wang)

- Add MediaTek MT8192 PCIe controller driver (Jianjun Wang)

- Add MediaTek MT8192 INTx support (Jianjun Wang)

- Add MediaTek MT8192 MSI support (Jianjun Wang)

- Add MediaTek MT8192 system power management support (Jianjun Wang)

* remotes/lorenzo/pci/mediatek:
  MAINTAINERS: Add Jianjun Wang as MediaTek PCI co-maintainer
  PCI: mediatek-gen3: Add system PM support
  PCI: mediatek-gen3: Add MSI support
  PCI: mediatek-gen3: Add INTx support
  PCI: mediatek-gen3: Add MediaTek Gen3 driver for MT8192
  PCI: Export pci_pio_to_address() for module use
  dt-bindings: PCI: mediatek-gen3: Add YAML schema
  PCI: mediatek: Add missing MODULE_DEVICE_TABLE
  PCI: mediatek: Configure FC and FTS for functions other than 0

54 files changed:
Documentation/devicetree/bindings/pci/ti,j721e-pci-ep.yaml
Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
arch/arm/mach-iop32x/n2100.c
arch/x86/pci/amd_bus.c
drivers/net/ethernet/broadcom/bnx2.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/falcon/efx.c
drivers/pci/ats.c
drivers/pci/controller/Makefile
drivers/pci/controller/cadence/pci-j721e.c
drivers/pci/controller/dwc/Kconfig
drivers/pci/controller/dwc/Makefile
drivers/pci/controller/dwc/pci-keystone.c
drivers/pci/controller/dwc/pci-layerscape-ep.c
drivers/pci/controller/dwc/pcie-designware-ep.c
drivers/pci/controller/dwc/pcie-designware-host.c
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/controller/dwc/pcie-designware.h
drivers/pci/controller/dwc/pcie-intel-gw.c
drivers/pci/controller/pci-thunder-ecam.c
drivers/pci/controller/pci-thunder-pem.c
drivers/pci/controller/pcie-altera-msi.c
drivers/pci/controller/pcie-brcmstb.c
drivers/pci/controller/pcie-iproc-msi.c
drivers/pci/endpoint/functions/pci-epf-ntb.c
drivers/pci/endpoint/functions/pci-epf-test.c
drivers/pci/endpoint/pci-epc-core.c
drivers/pci/endpoint/pci-epf-core.c
drivers/pci/hotplug/acpi_pcihp.c
drivers/pci/hotplug/acpiphp.h
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/hotplug/cpqphp_nvram.c
drivers/pci/hotplug/shpchp_hpc.c
drivers/pci/of.c
drivers/pci/pci-acpi.c
drivers/pci/pci-label.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aer.c
drivers/pci/pcie/pme.c
drivers/pci/pcie/rcec.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/pci/remove.c
drivers/pci/vpd.c
drivers/scsi/cxlflash/main.c
include/linux/pci.h
include/linux/pci_ids.h

index d06f0c4..aed437d 100644 (file)
@@ -16,12 +16,14 @@ allOf:
 properties:
   compatible:
     oneOf:
-      - description: PCIe EP controller in J7200
+      - const: ti,j721e-pcie-ep
+      - description: PCIe EP controller in AM64
         items:
-          - const: ti,j7200-pcie-ep
+          - const: ti,am64-pcie-ep
           - const: ti,j721e-pcie-ep
-      - description: PCIe EP controller in J721E
+      - description: PCIe EP controller in J7200
         items:
+          - const: ti,j7200-pcie-ep
           - const: ti,j721e-pcie-ep
 
   reg:
@@ -66,7 +68,6 @@ required:
   - power-domains
   - clocks
   - clock-names
-  - dma-coherent
   - max-functions
   - phys
   - phy-names
index 0880a61..cc90020 100644 (file)
@@ -16,12 +16,14 @@ allOf:
 properties:
   compatible:
     oneOf:
-      - description: PCIe controller in J7200
+      - const: ti,j721e-pcie-host
+      - description: PCIe controller in AM64
         items:
-          - const: ti,j7200-pcie-host
+          - const: ti,am64-pcie-host
           - const: ti,j721e-pcie-host
-      - description: PCIe controller in J721E
+      - description: PCIe controller in J7200
         items:
+          - const: ti,j7200-pcie-host
           - const: ti,j721e-pcie-host
 
   reg:
@@ -46,12 +48,17 @@ properties:
     maxItems: 1
 
   clocks:
-    maxItems: 1
-    description: clock-specifier to represent input to the PCIe
+    minItems: 1
+    maxItems: 2
+    description: |+
+      clock-specifier to represent input to the PCIe for 1 item.
+      2nd item if present represents reference clock to the connector.
 
   clock-names:
+    minItems: 1
     items:
       - const: fck
+      - const: pcie_refclk
 
   vendor-id:
     const: 0x104c
@@ -62,6 +69,8 @@ properties:
           - const: 0xb00d
       - items:
           - const: 0xb00f
+      - items:
+          - const: 0xb010
 
   msi-map: true
 
@@ -78,7 +87,6 @@ required:
   - vendor-id
   - device-id
   - msi-map
-  - dma-coherent
   - dma-ranges
   - ranges
   - reset-gpios
index 78b9a5e..bf99e71 100644 (file)
@@ -116,16 +116,16 @@ static struct hw_pci n2100_pci __initdata = {
 };
 
 /*
- * Both r8169 chips on the n2100 exhibit PCI parity problems.  Set
- * the ->broken_parity_status flag for both ports so that the r8169
- * driver knows it should ignore error interrupts.
+ * Both r8169 chips on the n2100 exhibit PCI parity problems.  Turn
+ * off parity reporting for both ports so we don't get error interrupts
+ * for them.
  */
 static void n2100_fixup_r8169(struct pci_dev *dev)
 {
        if (dev->bus->number == 0 &&
            (dev->devfn == PCI_DEVFN(1, 0) ||
             dev->devfn == PCI_DEVFN(2, 0)))
-               dev->broken_parity_status = 1;
+               pci_disable_parity(dev);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, PCI_ANY_ID, n2100_fixup_r8169);
 
index bfa50e6..ae744b6 100644 (file)
@@ -126,7 +126,7 @@ static int __init early_root_info_init(void)
                node = (reg >> 4) & 0x07;
                link = (reg >> 8) & 0x03;
 
-               info = alloc_pci_root_info(min_bus, max_bus, node, link);
+               alloc_pci_root_info(min_bus, max_bus, node, link);
        }
 
        /*
index 3e8a179..c098609 100644 (file)
@@ -8057,7 +8057,7 @@ bnx2_read_vpd_fw_ver(struct bnx2 *bp)
                data[i + 3] = data[i + BNX2_VPD_LEN];
        }
 
-       i = pci_vpd_find_tag(data, 0, BNX2_VPD_LEN, PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag(data, BNX2_VPD_LEN, PCI_VPD_LRDT_RO_DATA);
        if (i < 0)
                goto vpd_done;
 
index b652ed7..d267e45 100644 (file)
@@ -12207,8 +12207,7 @@ static void bnx2x_read_fwinfo(struct bnx2x *bp)
        /* VPD RO tag should be first tag after identifier string, hence
         * we should be able to find it in first BNX2X_VPD_LEN chars
         */
-       i = pci_vpd_find_tag(vpd_start, 0, BNX2X_VPD_LEN,
-                            PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag(vpd_start, BNX2X_VPD_LEN, PCI_VPD_LRDT_RO_DATA);
        if (i < 0)
                goto out_not_found;
 
index a680fd9..2bccdac 100644 (file)
@@ -12668,7 +12668,7 @@ static void bnxt_vpd_read_info(struct bnxt *bp)
                goto exit;
        }
 
-       i = pci_vpd_find_tag(vpd_data, 0, vpd_size, PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag(vpd_data, vpd_size, PCI_VPD_LRDT_RO_DATA);
        if (i < 0) {
                netdev_err(bp->dev, "VPD READ-Only not found\n");
                goto exit;
index d238192..b0e4964 100644 (file)
@@ -13016,7 +13016,7 @@ static int tg3_test_nvram(struct tg3 *tp)
        if (!buf)
                return -ENOMEM;
 
-       i = pci_vpd_find_tag((u8 *)buf, 0, len, PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag((u8 *)buf, len, PCI_VPD_LRDT_RO_DATA);
        if (i > 0) {
                j = pci_vpd_lrdt_size(&((u8 *)buf)[i]);
                if (j < 0)
@@ -15629,7 +15629,7 @@ static void tg3_read_vpd(struct tg3 *tp)
        if (!vpd_data)
                goto out_no_vpd;
 
-       i = pci_vpd_find_tag(vpd_data, 0, vpdlen, PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag(vpd_data, vpdlen, PCI_VPD_LRDT_RO_DATA);
        if (i < 0)
                goto out_not_found;
 
index 98829e4..ef5d10e 100644 (file)
@@ -2774,7 +2774,7 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
        if (id_len > ID_LEN)
                id_len = ID_LEN;
 
-       i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA);
+       i = pci_vpd_find_tag(vpd, VPD_LEN, PCI_VPD_LRDT_RO_DATA);
        if (i < 0) {
                dev_err(adapter->pdev_dev, "missing VPD-R section\n");
                ret = -EINVAL;
index f704da3..a6aff0d 100644 (file)
@@ -4358,20 +4358,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
        if (net_ratelimit())
                netdev_err(dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n",
                           pci_cmd, pci_status_errs);
-       /*
-        * The recovery sequence below admits a very elaborated explanation:
-        * - it seems to work;
-        * - I did not see what else could be done;
-        * - it makes iop3xx happy.
-        *
-        * Feel free to adjust to your needs.
-        */
-       if (pdev->broken_parity_status)
-               pci_cmd &= ~PCI_COMMAND_PARITY;
-       else
-               pci_cmd |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY;
-
-       pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
 
        rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 }
index 36c8625..c746ca7 100644 (file)
@@ -920,7 +920,7 @@ static void efx_probe_vpd_strings(struct efx_nic *efx)
        }
 
        /* Get the Read only section */
-       ro_start = pci_vpd_find_tag(vpd_data, 0, vpd_size, PCI_VPD_LRDT_RO_DATA);
+       ro_start = pci_vpd_find_tag(vpd_data, vpd_size, PCI_VPD_LRDT_RO_DATA);
        if (ro_start < 0) {
                netif_err(efx, drv, efx->net_dev, "VPD Read-only not found\n");
                return;
index f897999..5e7a57b 100644 (file)
@@ -2800,7 +2800,7 @@ static void ef4_probe_vpd_strings(struct ef4_nic *efx)
        }
 
        /* Get the Read only section */
-       ro_start = pci_vpd_find_tag(vpd_data, 0, vpd_size, PCI_VPD_LRDT_RO_DATA);
+       ro_start = pci_vpd_find_tag(vpd_data, vpd_size, PCI_VPD_LRDT_RO_DATA);
        if (ro_start < 0) {
                netif_err(efx, drv, efx->net_dev, "VPD Read-only not found\n");
                return;
index 0d37194..6d7d649 100644 (file)
@@ -480,7 +480,7 @@ EXPORT_SYMBOL_GPL(pci_pasid_features);
 #define PASID_NUMBER_SHIFT     8
 #define PASID_NUMBER_MASK      (0x1f << PASID_NUMBER_SHIFT)
 /**
- * pci_max_pasid - Get maximum number of PASIDs supported by device
+ * pci_max_pasids - Get maximum number of PASIDs supported by device
  * @pdev: PCI device structure
  *
  * Returns negative value when PASID capability is not present.
index 5799733..63e3880 100644 (file)
@@ -11,10 +11,13 @@ obj-$(CONFIG_PCIE_RCAR_HOST) += pcie-rcar.o pcie-rcar-host.o
 obj-$(CONFIG_PCIE_RCAR_EP) += pcie-rcar.o pcie-rcar-ep.o
 obj-$(CONFIG_PCI_HOST_COMMON) += pci-host-common.o
 obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
+obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
+obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
 obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o
 obj-$(CONFIG_PCIE_XILINX_CPM) += pcie-xilinx-cpm.o
 obj-$(CONFIG_PCI_V3_SEMI) += pci-v3-semi.o
+obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
 obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
 obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
@@ -48,8 +51,10 @@ obj-y                                += mobiveil/
 # ARM64 and use internal ifdefs to only build the pieces we need
 # depending on whether ACPI, the DT driver, or both are enabled.
 
-ifdef CONFIG_PCI
+ifdef CONFIG_ACPI
+ifdef CONFIG_PCI_QUIRKS
 obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
 obj-$(CONFIG_ARM64) += pci-thunder-pem.o
 obj-$(CONFIG_ARM64) += pci-xgene.o
 endif
+endif
index 849f1e4..35e6104 100644 (file)
@@ -1,11 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
-/**
+/*
  * pci-j721e - PCIe controller driver for TI's J721E SoCs
  *
  * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
  * Author: Kishon Vijay Abraham I <kishon@ti.com>
  */
 
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/io.h>
@@ -50,6 +51,7 @@ enum link_status {
 
 struct j721e_pcie {
        struct device           *dev;
+       struct clk              *refclk;
        u32                     mode;
        u32                     num_lanes;
        struct cdns_pcie        *cdns_pcie;
@@ -312,6 +314,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
        struct cdns_pcie_ep *ep;
        struct gpio_desc *gpiod;
        void __iomem *base;
+       struct clk *clk;
        u32 num_lanes;
        u32 mode;
        int ret;
@@ -411,6 +414,20 @@ static int j721e_pcie_probe(struct platform_device *pdev)
                        goto err_get_sync;
                }
 
+               clk = devm_clk_get_optional(dev, "pcie_refclk");
+               if (IS_ERR(clk)) {
+                       ret = PTR_ERR(clk);
+                       dev_err(dev, "failed to get pcie_refclk\n");
+                       goto err_pcie_setup;
+               }
+
+               ret = clk_prepare_enable(clk);
+               if (ret) {
+                       dev_err(dev, "failed to enable pcie_refclk\n");
+                       goto err_get_sync;
+               }
+               pcie->refclk = clk;
+
                /*
                 * "Power Sequencing and Reset Signal Timings" table in
                 * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 3.0
@@ -425,8 +442,10 @@ static int j721e_pcie_probe(struct platform_device *pdev)
                }
 
                ret = cdns_pcie_host_setup(rc);
-               if (ret < 0)
+               if (ret < 0) {
+                       clk_disable_unprepare(pcie->refclk);
                        goto err_pcie_setup;
+               }
 
                break;
        case PCI_MODE_EP:
@@ -479,6 +498,7 @@ static int j721e_pcie_remove(struct platform_device *pdev)
        struct cdns_pcie *cdns_pcie = pcie->cdns_pcie;
        struct device *dev = &pdev->dev;
 
+       clk_disable_unprepare(pcie->refclk);
        cdns_pcie_disable_phy(cdns_pcie);
        pm_runtime_put(dev);
        pm_runtime_disable(dev);
index 22c5529..f4b589f 100644 (file)
@@ -311,6 +311,7 @@ config PCIE_AL
        depends on OF && (ARM64 || COMPILE_TEST)
        depends on PCI_MSI_IRQ_DOMAIN
        select PCIE_DW_HOST
+       select PCI_ECAM
        help
          Say Y here to enable support of the Amazon's Annapurna Labs PCIe
          controller IP on Amazon SoCs. The PCIe controller uses the DesignWare
index a751553..ba7c42f 100644 (file)
@@ -31,7 +31,12 @@ obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
 # ARM64 and use internal ifdefs to only build the pieces we need
 # depending on whether ACPI, the DT driver, or both are enabled.
 
-ifdef CONFIG_PCI
+obj-$(CONFIG_PCIE_AL) += pcie-al.o
+obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
+
+ifdef CONFIG_ACPI
+ifdef CONFIG_PCI_QUIRKS
 obj-$(CONFIG_ARM64) += pcie-al.o
 obj-$(CONFIG_ARM64) += pcie-hisi.o
 endif
+endif
index 53aa35c..bde3b28 100644 (file)
@@ -346,8 +346,9 @@ static const struct irq_domain_ops ks_pcie_legacy_irq_domain_ops = {
 };
 
 /**
- * ks_pcie_set_dbi_mode() - Set DBI mode to access overlaid BAR mask
- * registers
+ * ks_pcie_set_dbi_mode() - Set DBI mode to access overlaid BAR mask registers
+ * @ks_pcie: A pointer to the keystone_pcie structure which holds the KeyStone
+ *          PCIe host controller driver information.
  *
  * Since modification of dbi_cs2 involves different clock domain, read the
  * status back to ensure the transition is complete.
@@ -367,6 +368,8 @@ static void ks_pcie_set_dbi_mode(struct keystone_pcie *ks_pcie)
 
 /**
  * ks_pcie_clear_dbi_mode() - Disable DBI mode
+ * @ks_pcie: A pointer to the keystone_pcie structure which holds the KeyStone
+ *          PCIe host controller driver information.
  *
  * Since modification of dbi_cs2 involves different clock domain, read the
  * status back to ensure the transition is complete.
@@ -449,6 +452,7 @@ static struct pci_ops ks_child_pcie_ops = {
 
 /**
  * ks_pcie_v3_65_add_bus() - keystone add_bus post initialization
+ * @bus: A pointer to the PCI bus structure.
  *
  * This sets BAR0 to enable inbound access for MSI_IRQ register
  */
@@ -488,6 +492,8 @@ static struct pci_ops ks_pcie_ops = {
 
 /**
  * ks_pcie_link_up() - Check if link up
+ * @pci: A pointer to the dw_pcie structure which holds the DesignWare PCIe host
+ *      controller driver information.
  */
 static int ks_pcie_link_up(struct dw_pcie *pci)
 {
@@ -605,7 +611,6 @@ static void ks_pcie_msi_irq_handler(struct irq_desc *desc)
 
 /**
  * ks_pcie_legacy_irq_handler() - Handle legacy interrupt
- * @irq: IRQ line for legacy interrupts
  * @desc: Pointer to irq descriptor
  *
  * Traverse through pending legacy interrupts and invoke handler for each. Also
@@ -798,7 +803,8 @@ static int __init ks_pcie_host_init(struct pcie_port *pp)
        int ret;
 
        pp->bridge->ops = &ks_pcie_ops;
-       pp->bridge->child_ops = &ks_child_pcie_ops;
+       if (!ks_pcie->is_am6)
+               pp->bridge->child_ops = &ks_child_pcie_ops;
 
        ret = ks_pcie_config_legacy_irq(ks_pcie);
        if (ret)
index 39fe2ed..39f4664 100644 (file)
@@ -154,7 +154,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
        pci->dev = dev;
        pci->ops = pcie->drvdata->dw_pcie_ops;
 
-       ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
+       ls_epc->bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4);
 
        pcie->pci = pci;
        pcie->ls_epc = ls_epc;
index 1c25d83..8d028a8 100644 (file)
@@ -705,6 +705,8 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
                }
        }
 
+       dw_pcie_iatu_detect(pci);
+
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
        if (!res)
                return -EINVAL;
index 7e55b2b..a608ae1 100644 (file)
@@ -398,9 +398,9 @@ int dw_pcie_host_init(struct pcie_port *pp)
                if (ret)
                        goto err_free_msi;
        }
+       dw_pcie_iatu_detect(pci);
 
        dw_pcie_setup_rc(pp);
-       dw_pcie_msi_init(pp);
 
        if (!dw_pcie_link_up(pci) && pci->ops && pci->ops->start_link) {
                ret = pci->ops->start_link(pci);
@@ -551,6 +551,8 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
                }
        }
 
+       dw_pcie_msi_init(pp);
+
        /* Setup RC BARs */
        dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004);
        dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000);
index 004cb86..a945f0c 100644 (file)
@@ -660,11 +660,9 @@ static void dw_pcie_iatu_detect_regions(struct dw_pcie *pci)
        pci->num_ob_windows = ob;
 }
 
-void dw_pcie_setup(struct dw_pcie *pci)
+void dw_pcie_iatu_detect(struct dw_pcie *pci)
 {
-       u32 val;
        struct device *dev = pci->dev;
-       struct device_node *np = dev->of_node;
        struct platform_device *pdev = to_platform_device(dev);
 
        if (pci->version >= 0x480A || (!pci->version &&
@@ -693,6 +691,13 @@ void dw_pcie_setup(struct dw_pcie *pci)
 
        dev_info(pci->dev, "Detected iATU regions: %u outbound, %u inbound",
                 pci->num_ob_windows, pci->num_ib_windows);
+}
+
+void dw_pcie_setup(struct dw_pcie *pci)
+{
+       u32 val;
+       struct device *dev = pci->dev;
+       struct device_node *np = dev->of_node;
 
        if (pci->link_gen > 0)
                dw_pcie_link_set_max_speed(pci, pci->link_gen);
index 7247c8b..7d6e9b7 100644 (file)
@@ -306,6 +306,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
 void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
                         enum dw_pcie_region_type type);
 void dw_pcie_setup(struct dw_pcie *pci);
+void dw_pcie_iatu_detect(struct dw_pcie *pci);
 
 static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
 {
index 0cedd1f..f89a7d2 100644 (file)
@@ -81,11 +81,6 @@ static void pcie_update_bits(void __iomem *base, u32 ofs, u32 mask, u32 val)
                writel(val, base + ofs);
 }
 
-static inline u32 pcie_app_rd(struct intel_pcie_port *lpp, u32 ofs)
-{
-       return readl(lpp->app_base + ofs);
-}
-
 static inline void pcie_app_wr(struct intel_pcie_port *lpp, u32 ofs, u32 val)
 {
        writel(val, lpp->app_base + ofs);
index f964fd2..ffd8465 100644 (file)
@@ -116,7 +116,7 @@ static int thunder_ecam_p2_config_read(struct pci_bus *bus, unsigned int devfn,
         * the config space access window.  Since we are working with
         * the high-order 32 bits, shift everything down by 32 bits.
         */
-       node_bits = (cfg->res.start >> 32) & (1 << 12);
+       node_bits = upper_32_bits(cfg->res.start) & (1 << 12);
 
        v |= node_bits;
        set_val(v, where, size, val);
index 1a3f70a..0660b9d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pci-acpi.h>
 #include <linux/pci-ecam.h>
 #include <linux/platform_device.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
 #include "../pci.h"
 
 #if defined(CONFIG_PCI_HOST_THUNDER_PEM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))
@@ -324,9 +325,9 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
         * structure here for the BAR.
         */
        bar4_start = res_pem->start + 0xf00000;
-       pem_pci->ea_entry[0] = (u32)bar4_start | 2;
-       pem_pci->ea_entry[1] = (u32)(res_pem->end - bar4_start) & ~3u;
-       pem_pci->ea_entry[2] = (u32)(bar4_start >> 32);
+       pem_pci->ea_entry[0] = lower_32_bits(bar4_start) | 2;
+       pem_pci->ea_entry[1] = lower_32_bits(res_pem->end - bar4_start) & ~3u;
+       pem_pci->ea_entry[2] = upper_32_bits(bar4_start);
 
        cfg->priv = pem_pci;
        return 0;
@@ -334,9 +335,9 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
 
-#define PEM_RES_BASE           0x87e0c0000000UL
-#define PEM_NODE_MASK          GENMASK(45, 44)
-#define PEM_INDX_MASK          GENMASK(26, 24)
+#define PEM_RES_BASE           0x87e0c0000000ULL
+#define PEM_NODE_MASK          GENMASK_ULL(45, 44)
+#define PEM_INDX_MASK          GENMASK_ULL(26, 24)
 #define PEM_MIN_DOM_IN_NODE    4
 #define PEM_MAX_DOM_IN_NODE    10
 
index 42691dd..98aa1dc 100644 (file)
@@ -236,10 +236,8 @@ static int altera_msi_probe(struct platform_device *pdev)
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                           "vector_slave");
        msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(msi->vector_base)) {
-               dev_err(&pdev->dev, "failed to map vector_slave memory\n");
+       if (IS_ERR(msi->vector_base))
                return PTR_ERR(msi->vector_base);
-       }
 
        msi->vector_phy = res->start;
 
index e330e68..69c9992 100644 (file)
@@ -1296,6 +1296,7 @@ static int brcm_pcie_probe(struct platform_device *pdev)
        pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION);
        if (pcie->type == BCM4908 && pcie->hw_rev >= BRCM_PCIE_HW_REV_3_20) {
                dev_err(pcie->dev, "hardware revision with unsupported PERST# setup\n");
+               ret = -ENODEV;
                goto fail;
        }
 
index 908475d..eede4e8 100644 (file)
@@ -271,7 +271,7 @@ static int iproc_msi_irq_domain_alloc(struct irq_domain *domain,
                                    NULL, NULL);
        }
 
-       return hwirq;
+       return 0;
 }
 
 static void iproc_msi_irq_domain_free(struct irq_domain *domain,
index 338148c..bce274d 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-/**
+/*
  * Endpoint Function Driver to implement Non-Transparent Bridge functionality
  *
  * Copyright (C) 2020 Texas Instruments
@@ -696,7 +696,8 @@ reset_handler:
 
 /**
  * epf_ntb_peer_spad_bar_clear() - Clear Peer Scratchpad BAR
- * @ntb: NTB device that facilitates communication between HOST1 and HOST2
+ * @ntb_epc: EPC associated with one of the HOST which holds peer's outbound
+ *          address.
  *
  *+-----------------+------->+------------------+        +-----------------+
  *|       BAR0      |        |  CONFIG REGION   |        |       BAR0      |
@@ -740,6 +741,7 @@ static void epf_ntb_peer_spad_bar_clear(struct epf_ntb_epc *ntb_epc)
 /**
  * epf_ntb_peer_spad_bar_set() - Set peer scratchpad BAR
  * @ntb: NTB device that facilitates communication between HOST1 and HOST2
+ * @type: PRIMARY interface or SECONDARY interface
  *
  *+-----------------+------->+------------------+        +-----------------+
  *|       BAR0      |        |  CONFIG REGION   |        |       BAR0      |
@@ -808,7 +810,8 @@ static int epf_ntb_peer_spad_bar_set(struct epf_ntb *ntb,
 
 /**
  * epf_ntb_config_sspad_bar_clear() - Clear Config + Self scratchpad BAR
- * @ntb: NTB device that facilitates communication between HOST1 and HOST2
+ * @ntb_epc: EPC associated with one of the HOST which holds peer's outbound
+ *          address.
  *
  * +-----------------+------->+------------------+        +-----------------+
  * |       BAR0      |        |  CONFIG REGION   |        |       BAR0      |
@@ -851,7 +854,8 @@ static void epf_ntb_config_sspad_bar_clear(struct epf_ntb_epc *ntb_epc)
 
 /**
  * epf_ntb_config_sspad_bar_set() - Set Config + Self scratchpad BAR
- * @ntb: NTB device that facilitates communication between HOST1 and HOST2
+ * @ntb_epc: EPC associated with one of the HOST which holds peer's outbound
+ *          address.
  *
  * +-----------------+------->+------------------+        +-----------------+
  * |       BAR0      |        |  CONFIG REGION   |        |       BAR0      |
@@ -1312,6 +1316,7 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb,
 
 /**
  * epf_ntb_alloc_peer_mem() - Allocate memory in peer's outbound address space
+ * @dev: The PCI device.
  * @ntb_epc: EPC associated with one of the HOST whose BAR holds peer's outbound
  *   address
  * @bar: BAR of @ntb_epc in for which memory has to be allocated (could be
@@ -1660,7 +1665,6 @@ static int epf_ntb_init_epc_bar_interface(struct epf_ntb *ntb,
  * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB
  * constructs (scratchpad region, doorbell, memorywindow)
  * @ntb: NTB device that facilitates communication between HOST1 and HOST2
- * @type: PRIMARY interface or SECONDARY interface
  *
  * Wrapper to epf_ntb_init_epc_bar_interface() to identify the free BARs
  * to be used for each of BAR_CONFIG, BAR_PEER_SPAD, BAR_DB_MW1, BAR_MW2,
@@ -2037,6 +2041,8 @@ static const struct config_item_type ntb_group_type = {
 /**
  * epf_ntb_add_cfs() - Add configfs directory specific to NTB
  * @epf: NTB endpoint function device
+ * @group: A pointer to the config_group structure referencing a group of
+ *        config_items of a specific type that belong to a specific sub-system.
  *
  * Add configfs directory specific to NTB. This directory will hold
  * NTB specific properties like db_count, spad_count, num_mws etc.,
index c0ac4e9..d2708ca 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
-/**
+/*
  * Test driver to test endpoint functionality
  *
  * Copyright (C) 2017 Texas Instruments
@@ -833,15 +833,18 @@ static int pci_epf_test_bind(struct pci_epf *epf)
                return -EINVAL;
 
        epc_features = pci_epc_get_features(epc, epf->func_no);
-       if (epc_features) {
-               linkup_notifier = epc_features->linkup_notifier;
-               core_init_notifier = epc_features->core_init_notifier;
-               test_reg_bar = pci_epc_get_first_free_bar(epc_features);
-               if (test_reg_bar < 0)
-                       return -EINVAL;
-               pci_epf_configure_bar(epf, epc_features);
+       if (!epc_features) {
+               dev_err(&epf->dev, "epc_features not implemented\n");
+               return -EOPNOTSUPP;
        }
 
+       linkup_notifier = epc_features->linkup_notifier;
+       core_init_notifier = epc_features->core_init_notifier;
+       test_reg_bar = pci_epc_get_first_free_bar(epc_features);
+       if (test_reg_bar < 0)
+               return -EINVAL;
+       pci_epf_configure_bar(epf, epc_features);
+
        epf_test->test_reg_bar = test_reg_bar;
        epf_test->epc_features = epc_features;
 
@@ -922,6 +925,7 @@ static int __init pci_epf_test_init(void)
 
        ret = pci_epf_register_driver(&test_driver);
        if (ret) {
+               destroy_workqueue(kpcitest_workqueue);
                pr_err("Failed to register pci epf test driver --> %d\n", ret);
                return ret;
        }
@@ -932,6 +936,8 @@ module_init(pci_epf_test_init);
 
 static void __exit pci_epf_test_exit(void)
 {
+       if (kpcitest_workqueue)
+               destroy_workqueue(kpcitest_workqueue);
        pci_epf_unregister_driver(&test_driver);
 }
 module_exit(pci_epf_test_exit);
index cc8f9eb..adec9be 100644 (file)
@@ -594,6 +594,8 @@ EXPORT_SYMBOL_GPL(pci_epc_add_epf);
  * pci_epc_remove_epf() - remove PCI endpoint function from endpoint controller
  * @epc: the EPC device from which the endpoint function should be removed
  * @epf: the endpoint function to be removed
+ * @type: identifies if the EPC is connected to the primary or secondary
+ *        interface of EPF
  *
  * Invoke to remove PCI endpoint function from the endpoint controller.
  */
index 7646c86..e9289d1 100644 (file)
@@ -113,7 +113,7 @@ EXPORT_SYMBOL_GPL(pci_epf_bind);
 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
                        enum pci_epc_interface_type type)
 {
-       struct device *dev = epf->epc->dev.parent;
+       struct device *dev;
        struct pci_epf_bar *epf_bar;
        struct pci_epc *epc;
 
index 2750a64..4fedebf 100644 (file)
@@ -157,7 +157,7 @@ static int pcihp_is_ejectable(acpi_handle handle)
 }
 
 /**
- * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot
+ * acpi_pci_check_ejectable - check if handle is ejectable ACPI PCI slot
  * @pbus: the PCI bus of the PCI slot corresponding to 'handle'
  * @handle: ACPI handle to check
  *
index a74b274..1f8ab43 100644 (file)
@@ -148,8 +148,7 @@ static inline struct acpiphp_root_context *to_acpiphp_root_context(struct acpi_h
  * ACPI has no generic method of setting/getting attention status
  * this allows for device specific driver registration
  */
-struct acpiphp_attention_info
-{
+struct acpiphp_attention_info {
        int (*set_attn)(struct hotplug_slot *slot, u8 status);
        int (*get_attn)(struct hotplug_slot *slot, u8 *status);
        struct module *owner;
index 3365c93..f031302 100644 (file)
@@ -533,6 +533,7 @@ static void enable_slot(struct acpiphp_slot *slot, bool bridge)
                        slot->flags &= ~SLOT_ENABLED;
                        continue;
                }
+               pci_dev_put(dev);
        }
 }
 
index 00cd2b4..7a65d42 100644 (file)
@@ -80,7 +80,7 @@ static u8 evbuffer[1024];
 static void __iomem *compaq_int15_entry_point;
 
 /* lock for ordering int15_bios_call() */
-static spinlock_t int15_lock;
+static DEFINE_SPINLOCK(int15_lock);
 
 
 /* This is a series of function that deals with
@@ -415,9 +415,6 @@ void compaq_nvram_init(void __iomem *rom_start)
                compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
 
        dbg("int15 entry  = %p\n", compaq_int15_entry_point);
-
-       /* initialize our int15 lock */
-       spin_lock_init(&int15_lock);
 }
 
 
index db04728..9e3b277 100644 (file)
@@ -174,11 +174,6 @@ static inline u8 shpc_readb(struct controller *ctrl, int reg)
        return readb(ctrl->creg + reg);
 }
 
-static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val)
-{
-       writeb(val, ctrl->creg + reg);
-}
-
 static inline u16 shpc_readw(struct controller *ctrl, int reg)
 {
        return readw(ctrl->creg + reg);
index 5ea472a..da5b414 100644 (file)
@@ -190,10 +190,18 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
 EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
 
 /**
- * This function will try to obtain the host bridge domain number by
- * finding a property called "linux,pci-domain" of the given device node.
+ * of_get_pci_domain_nr - Find the host bridge domain number
+ *                       of the given device node.
+ * @node: Device tree node with the domain information.
  *
- * @node: device tree node with the domain information
+ * This function will try to obtain the host bridge domain number by finding
+ * a property called "linux,pci-domain" of the given device node.
+ *
+ * Return:
+ * * > 0       - On success, an associated domain number.
+ * * -EINVAL   - The property "linux,pci-domain" does not exist.
+ * * -ENODATA  - The linux,pci-domain" property does not have value.
+ * * -EOVERFLOW        - Invalid "linux,pci-domain" property value.
  *
  * Returns the associated domain number from DT in the range [0-0xffff], or
  * a negative value if the required property is not found.
@@ -585,10 +593,16 @@ int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge)
 #endif /* CONFIG_PCI */
 
 /**
+ * of_pci_get_max_link_speed - Find the maximum link speed of the given device node.
+ * @node: Device tree node with the maximum link speed information.
+ *
  * This function will try to find the limitation of link speed by finding
  * a property called "max-link-speed" of the given device node.
  *
- * @node: device tree node with the max link speed information
+ * Return:
+ * * > 0       - On success, a maximum link speed.
+ * * -EINVAL   - Invalid "max-link-speed" property value, or failure to access
+ *               the property of the device tree node.
  *
  * Returns the associated max link speed from DT, or a negative value if the
  * required property is not found or is invalid.
index 53502a7..36bc23e 100644 (file)
@@ -1021,7 +1021,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 
        if (!error)
                pci_dbg(dev, "power state changed by ACPI to %s\n",
-                        acpi_power_state_string(state_conv[state]));
+                       acpi_power_state_string(adev->power.state));
 
        return error;
 }
index 781e45c..c32f3b7 100644 (file)
 #include <linux/pci-acpi.h>
 #include "pci.h"
 
+static bool device_has_acpi_name(struct device *dev)
+{
+#ifdef CONFIG_ACPI
+       acpi_handle handle = ACPI_HANDLE(dev);
+
+       if (!handle)
+               return false;
+
+       return acpi_check_dsm(handle, &pci_acpi_dsm_guid, 0x2,
+                             1 << DSM_PCI_DEVICE_NAME);
+#else
+       return false;
+#endif
+}
+
 #ifdef CONFIG_DMI
 enum smbios_attr_enum {
        SMBIOS_ATTR_NONE = 0,
@@ -45,13 +60,9 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf,
 {
        const struct dmi_device *dmi;
        struct dmi_dev_onboard *donboard;
-       int domain_nr;
-       int bus;
-       int devfn;
-
-       domain_nr = pci_domain_nr(pdev->bus);
-       bus = pdev->bus->number;
-       devfn = pdev->devfn;
+       int domain_nr = pci_domain_nr(pdev->bus);
+       int bus = pdev->bus->number;
+       int devfn = pdev->devfn;
 
        dmi = NULL;
        while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEV_ONBOARD,
@@ -62,13 +73,11 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf,
                                donboard->devfn == devfn) {
                        if (buf) {
                                if (attribute == SMBIOS_ATTR_INSTANCE_SHOW)
-                                       return scnprintf(buf, PAGE_SIZE,
-                                                        "%d\n",
-                                                        donboard->instance);
+                                       return sysfs_emit(buf, "%d\n",
+                                                         donboard->instance);
                                else if (attribute == SMBIOS_ATTR_LABEL_SHOW)
-                                       return scnprintf(buf, PAGE_SIZE,
-                                                        "%s\n",
-                                                        dmi->name);
+                                       return sysfs_emit(buf, "%s\n",
+                                                         dmi->name);
                        }
                        return strlen(dmi->name);
                }
@@ -76,78 +85,52 @@ static size_t find_smbios_instance_string(struct pci_dev *pdev, char *buf,
        return 0;
 }
 
-static umode_t smbios_instance_string_exist(struct kobject *kobj,
-                                           struct attribute *attr, int n)
+static ssize_t smbios_label_show(struct device *dev,
+                                struct device_attribute *attr, char *buf)
 {
-       struct device *dev;
-       struct pci_dev *pdev;
-
-       dev = kobj_to_dev(kobj);
-       pdev = to_pci_dev(dev);
-
-       return find_smbios_instance_string(pdev, NULL, SMBIOS_ATTR_NONE) ?
-                                          S_IRUGO : 0;
-}
-
-static ssize_t smbioslabel_show(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       struct pci_dev *pdev;
-       pdev = to_pci_dev(dev);
+       struct pci_dev *pdev = to_pci_dev(dev);
 
        return find_smbios_instance_string(pdev, buf,
                                           SMBIOS_ATTR_LABEL_SHOW);
 }
+static struct device_attribute dev_attr_smbios_label = __ATTR(label, 0444,
+                                                   smbios_label_show, NULL);
 
-static ssize_t smbiosinstance_show(struct device *dev,
-                                  struct device_attribute *attr, char *buf)
+static ssize_t index_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
-       struct pci_dev *pdev;
-       pdev = to_pci_dev(dev);
+       struct pci_dev *pdev = to_pci_dev(dev);
 
        return find_smbios_instance_string(pdev, buf,
                                           SMBIOS_ATTR_INSTANCE_SHOW);
 }
+static DEVICE_ATTR_RO(index);
 
-static struct device_attribute smbios_attr_label = {
-       .attr = {.name = "label", .mode = 0444},
-       .show = smbioslabel_show,
-};
-
-static struct device_attribute smbios_attr_instance = {
-       .attr = {.name = "index", .mode = 0444},
-       .show = smbiosinstance_show,
-};
-
-static struct attribute *smbios_attributes[] = {
-       &smbios_attr_label.attr,
-       &smbios_attr_instance.attr,
+static struct attribute *smbios_attrs[] = {
+       &dev_attr_smbios_label.attr,
+       &dev_attr_index.attr,
        NULL,
 };
 
-static const struct attribute_group smbios_attr_group = {
-       .attrs = smbios_attributes,
-       .is_visible = smbios_instance_string_exist,
-};
-
-static int pci_create_smbiosname_file(struct pci_dev *pdev)
+static umode_t smbios_attr_is_visible(struct kobject *kobj, struct attribute *a,
+                                     int n)
 {
-       return sysfs_create_group(&pdev->dev.kobj, &smbios_attr_group);
-}
+       struct device *dev = kobj_to_dev(kobj);
+       struct pci_dev *pdev = to_pci_dev(dev);
 
-static void pci_remove_smbiosname_file(struct pci_dev *pdev)
-{
-       sysfs_remove_group(&pdev->dev.kobj, &smbios_attr_group);
-}
-#else
-static inline int pci_create_smbiosname_file(struct pci_dev *pdev)
-{
-       return -1;
-}
+       if (device_has_acpi_name(dev))
+               return 0;
 
-static inline void pci_remove_smbiosname_file(struct pci_dev *pdev)
-{
+       if (!find_smbios_instance_string(pdev, NULL, SMBIOS_ATTR_NONE))
+               return 0;
+
+       return a->mode;
 }
+
+const struct attribute_group pci_dev_smbios_attr_group = {
+       .attrs = smbios_attrs,
+       .is_visible = smbios_attr_is_visible,
+};
 #endif
 
 #ifdef CONFIG_ACPI
@@ -169,11 +152,10 @@ static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
 static int dsm_get_label(struct device *dev, char *buf,
                         enum acpi_attr_enum attr)
 {
-       acpi_handle handle;
+       acpi_handle handle = ACPI_HANDLE(dev);
        union acpi_object *obj, *tmp;
        int len = -1;
 
-       handle = ACPI_HANDLE(dev);
        if (!handle)
                return -1;
 
@@ -209,103 +191,39 @@ static int dsm_get_label(struct device *dev, char *buf,
        return len;
 }
 
-static bool device_has_dsm(struct device *dev)
-{
-       acpi_handle handle;
-
-       handle = ACPI_HANDLE(dev);
-       if (!handle)
-               return false;
-
-       return !!acpi_check_dsm(handle, &pci_acpi_dsm_guid, 0x2,
-                               1 << DSM_PCI_DEVICE_NAME);
-}
-
-static umode_t acpi_index_string_exist(struct kobject *kobj,
-                                      struct attribute *attr, int n)
-{
-       struct device *dev;
-
-       dev = kobj_to_dev(kobj);
-
-       if (device_has_dsm(dev))
-               return S_IRUGO;
-
-       return 0;
-}
-
-static ssize_t acpilabel_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+static ssize_t label_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
        return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW);
 }
+static DEVICE_ATTR_RO(label);
 
-static ssize_t acpiindex_show(struct device *dev,
+static ssize_t acpi_index_show(struct device *dev,
                              struct device_attribute *attr, char *buf)
 {
        return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW);
 }
+static DEVICE_ATTR_RO(acpi_index);
 
-static struct device_attribute acpi_attr_label = {
-       .attr = {.name = "label", .mode = 0444},
-       .show = acpilabel_show,
-};
-
-static struct device_attribute acpi_attr_index = {
-       .attr = {.name = "acpi_index", .mode = 0444},
-       .show = acpiindex_show,
-};
-
-static struct attribute *acpi_attributes[] = {
-       &acpi_attr_label.attr,
-       &acpi_attr_index.attr,
+static struct attribute *acpi_attrs[] = {
+       &dev_attr_label.attr,
+       &dev_attr_acpi_index.attr,
        NULL,
 };
 
-static const struct attribute_group acpi_attr_group = {
-       .attrs = acpi_attributes,
-       .is_visible = acpi_index_string_exist,
-};
-
-static int pci_create_acpi_index_label_files(struct pci_dev *pdev)
+static umode_t acpi_attr_is_visible(struct kobject *kobj, struct attribute *a,
+                                   int n)
 {
-       return sysfs_create_group(&pdev->dev.kobj, &acpi_attr_group);
-}
+       struct device *dev = kobj_to_dev(kobj);
 
-static int pci_remove_acpi_index_label_files(struct pci_dev *pdev)
-{
-       sysfs_remove_group(&pdev->dev.kobj, &acpi_attr_group);
-       return 0;
-}
-#else
-static inline int pci_create_acpi_index_label_files(struct pci_dev *pdev)
-{
-       return -1;
-}
+       if (!device_has_acpi_name(dev))
+               return 0;
 
-static inline int pci_remove_acpi_index_label_files(struct pci_dev *pdev)
-{
-       return -1;
+       return a->mode;
 }
 
-static inline bool device_has_dsm(struct device *dev)
-{
-       return false;
-}
+const struct attribute_group pci_dev_acpi_attr_group = {
+       .attrs = acpi_attrs,
+       .is_visible = acpi_attr_is_visible,
+};
 #endif
-
-void pci_create_firmware_label_files(struct pci_dev *pdev)
-{
-       if (device_has_dsm(&pdev->dev))
-               pci_create_acpi_index_label_files(pdev);
-       else
-               pci_create_smbiosname_file(pdev);
-}
-
-void pci_remove_firmware_label_files(struct pci_dev *pdev)
-{
-       if (device_has_dsm(&pdev->dev))
-               pci_remove_acpi_index_label_files(pdev);
-       else
-               pci_remove_smbiosname_file(pdev);
-}
index f8afd54..e216d71 100644 (file)
@@ -39,7 +39,7 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf)                            \
        struct pci_dev *pdev;                                           \
                                                                        \
        pdev = to_pci_dev(dev);                                         \
-       return sprintf(buf, format_string, pdev->field);                \
+       return sysfs_emit(buf, format_string, pdev->field);             \
 }                                                                      \
 static DEVICE_ATTR_RO(field)
 
@@ -56,7 +56,7 @@ static ssize_t broken_parity_status_show(struct device *dev,
                                         char *buf)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       return sprintf(buf, "%u\n", pdev->broken_parity_status);
+       return sysfs_emit(buf, "%u\n", pdev->broken_parity_status);
 }
 
 static ssize_t broken_parity_status_store(struct device *dev,
@@ -129,7 +129,7 @@ static ssize_t power_state_show(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
 
-       return sprintf(buf, "%s\n", pci_power_name(pdev->current_state));
+       return sysfs_emit(buf, "%s\n", pci_power_name(pdev->current_state));
 }
 static DEVICE_ATTR_RO(power_state);
 
@@ -138,10 +138,10 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
                             char *buf)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
-       char *str = buf;
        int i;
        int max;
        resource_size_t start, end;
+       size_t len = 0;
 
        if (pci_dev->subordinate)
                max = DEVICE_COUNT_RESOURCE;
@@ -151,12 +151,12 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
        for (i = 0; i < max; i++) {
                struct resource *res =  &pci_dev->resource[i];
                pci_resource_to_user(pci_dev, i, res, &start, &end);
-               str += sprintf(str, "0x%016llx 0x%016llx 0x%016llx\n",
-                              (unsigned long long)start,
-                              (unsigned long long)end,
-                              (unsigned long long)res->flags);
+               len += sysfs_emit_at(buf, len, "0x%016llx 0x%016llx 0x%016llx\n",
+                                    (unsigned long long)start,
+                                    (unsigned long long)end,
+                                    (unsigned long long)res->flags);
        }
-       return (str - buf);
+       return len;
 }
 static DEVICE_ATTR_RO(resource);
 
@@ -165,8 +165,8 @@ static ssize_t max_link_speed_show(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
 
-       return sprintf(buf, "%s\n",
-                      pci_speed_string(pcie_get_speed_cap(pdev)));
+       return sysfs_emit(buf, "%s\n",
+                         pci_speed_string(pcie_get_speed_cap(pdev)));
 }
 static DEVICE_ATTR_RO(max_link_speed);
 
@@ -175,7 +175,7 @@ static ssize_t max_link_width_show(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
 
-       return sprintf(buf, "%u\n", pcie_get_width_cap(pdev));
+       return sysfs_emit(buf, "%u\n", pcie_get_width_cap(pdev));
 }
 static DEVICE_ATTR_RO(max_link_width);
 
@@ -193,7 +193,7 @@ static ssize_t current_link_speed_show(struct device *dev,
 
        speed = pcie_link_speed[linkstat & PCI_EXP_LNKSTA_CLS];
 
-       return sprintf(buf, "%s\n", pci_speed_string(speed));
+       return sysfs_emit(buf, "%s\n", pci_speed_string(speed));
 }
 static DEVICE_ATTR_RO(current_link_speed);
 
@@ -208,7 +208,7 @@ static ssize_t current_link_width_show(struct device *dev,
        if (err)
                return -EINVAL;
 
-       return sprintf(buf, "%u\n",
+       return sysfs_emit(buf, "%u\n",
                (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT);
 }
 static DEVICE_ATTR_RO(current_link_width);
@@ -225,7 +225,7 @@ static ssize_t secondary_bus_number_show(struct device *dev,
        if (err)
                return -EINVAL;
 
-       return sprintf(buf, "%u\n", sec_bus);
+       return sysfs_emit(buf, "%u\n", sec_bus);
 }
 static DEVICE_ATTR_RO(secondary_bus_number);
 
@@ -241,7 +241,7 @@ static ssize_t subordinate_bus_number_show(struct device *dev,
        if (err)
                return -EINVAL;
 
-       return sprintf(buf, "%u\n", sub_bus);
+       return sysfs_emit(buf, "%u\n", sub_bus);
 }
 static DEVICE_ATTR_RO(subordinate_bus_number);
 
@@ -251,7 +251,7 @@ static ssize_t ari_enabled_show(struct device *dev,
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
 
-       return sprintf(buf, "%u\n", pci_ari_enabled(pci_dev->bus));
+       return sysfs_emit(buf, "%u\n", pci_ari_enabled(pci_dev->bus));
 }
 static DEVICE_ATTR_RO(ari_enabled);
 
@@ -260,11 +260,11 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
 
-       return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n",
-                      pci_dev->vendor, pci_dev->device,
-                      pci_dev->subsystem_vendor, pci_dev->subsystem_device,
-                      (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
-                      (u8)(pci_dev->class));
+       return sysfs_emit(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02X\n",
+                         pci_dev->vendor, pci_dev->device,
+                         pci_dev->subsystem_vendor, pci_dev->subsystem_device,
+                         (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
+                         (u8)(pci_dev->class));
 }
 static DEVICE_ATTR_RO(modalias);
 
@@ -302,7 +302,7 @@ static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
        struct pci_dev *pdev;
 
        pdev = to_pci_dev(dev);
-       return sprintf(buf, "%u\n", atomic_read(&pdev->enable_cnt));
+       return sysfs_emit(buf, "%u\n", atomic_read(&pdev->enable_cnt));
 }
 static DEVICE_ATTR_RW(enable);
 
@@ -338,7 +338,7 @@ static ssize_t numa_node_store(struct device *dev,
 static ssize_t numa_node_show(struct device *dev, struct device_attribute *attr,
                              char *buf)
 {
-       return sprintf(buf, "%d\n", dev->numa_node);
+       return sysfs_emit(buf, "%d\n", dev->numa_node);
 }
 static DEVICE_ATTR_RW(numa_node);
 #endif
@@ -348,7 +348,7 @@ static ssize_t dma_mask_bits_show(struct device *dev,
 {
        struct pci_dev *pdev = to_pci_dev(dev);
 
-       return sprintf(buf, "%d\n", fls64(pdev->dma_mask));
+       return sysfs_emit(buf, "%d\n", fls64(pdev->dma_mask));
 }
 static DEVICE_ATTR_RO(dma_mask_bits);
 
@@ -356,7 +356,7 @@ static ssize_t consistent_dma_mask_bits_show(struct device *dev,
                                             struct device_attribute *attr,
                                             char *buf)
 {
-       return sprintf(buf, "%d\n", fls64(dev->coherent_dma_mask));
+       return sysfs_emit(buf, "%d\n", fls64(dev->coherent_dma_mask));
 }
 static DEVICE_ATTR_RO(consistent_dma_mask_bits);
 
@@ -366,9 +366,9 @@ static ssize_t msi_bus_show(struct device *dev, struct device_attribute *attr,
        struct pci_dev *pdev = to_pci_dev(dev);
        struct pci_bus *subordinate = pdev->subordinate;
 
-       return sprintf(buf, "%u\n", subordinate ?
-                      !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)
-                          : !pdev->no_msi);
+       return sysfs_emit(buf, "%u\n", subordinate ?
+                         !(subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+                           : !pdev->no_msi);
 }
 
 static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
@@ -523,7 +523,7 @@ static ssize_t d3cold_allowed_show(struct device *dev,
                                   struct device_attribute *attr, char *buf)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       return sprintf(buf, "%u\n", pdev->d3cold_allowed);
+       return sysfs_emit(buf, "%u\n", pdev->d3cold_allowed);
 }
 static DEVICE_ATTR_RW(d3cold_allowed);
 #endif
@@ -537,7 +537,7 @@ static ssize_t devspec_show(struct device *dev,
 
        if (np == NULL)
                return 0;
-       return sprintf(buf, "%pOF", np);
+       return sysfs_emit(buf, "%pOF", np);
 }
 static DEVICE_ATTR_RO(devspec);
 #endif
@@ -583,7 +583,7 @@ static ssize_t driver_override_show(struct device *dev,
        ssize_t len;
 
        device_lock(dev);
-       len = scnprintf(buf, PAGE_SIZE, "%s\n", pdev->driver_override);
+       len = sysfs_emit(buf, "%s\n", pdev->driver_override);
        device_unlock(dev);
        return len;
 }
@@ -658,11 +658,11 @@ static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
        struct pci_dev *vga_dev = vga_default_device();
 
        if (vga_dev)
-               return sprintf(buf, "%u\n", (pdev == vga_dev));
+               return sysfs_emit(buf, "%u\n", (pdev == vga_dev));
 
-       return sprintf(buf, "%u\n",
-               !!(pdev->resource[PCI_ROM_RESOURCE].flags &
-                  IORESOURCE_ROM_SHADOW));
+       return sysfs_emit(buf, "%u\n",
+                         !!(pdev->resource[PCI_ROM_RESOURCE].flags &
+                            IORESOURCE_ROM_SHADOW));
 }
 static DEVICE_ATTR_RO(boot_vga);
 
@@ -808,6 +808,29 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
 
        return count;
 }
+static BIN_ATTR(config, 0644, pci_read_config, pci_write_config, 0);
+
+static struct bin_attribute *pci_dev_config_attrs[] = {
+       &bin_attr_config,
+       NULL,
+};
+
+static umode_t pci_dev_config_attr_is_visible(struct kobject *kobj,
+                                             struct bin_attribute *a, int n)
+{
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+
+       a->size = PCI_CFG_SPACE_SIZE;
+       if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
+               a->size = PCI_CFG_SPACE_EXP_SIZE;
+
+       return a->attr.mode;
+}
+
+static const struct attribute_group pci_dev_config_attr_group = {
+       .bin_attrs = pci_dev_config_attrs,
+       .is_bin_visible = pci_dev_config_attr_is_visible,
+};
 
 #ifdef HAVE_PCI_LEGACY
 /**
@@ -1283,25 +1306,32 @@ static ssize_t pci_read_rom(struct file *filp, struct kobject *kobj,
 
        return count;
 }
+static BIN_ATTR(rom, 0600, pci_read_rom, pci_write_rom, 0);
 
-static const struct bin_attribute pci_config_attr = {
-       .attr = {
-               .name = "config",
-               .mode = 0644,
-       },
-       .size = PCI_CFG_SPACE_SIZE,
-       .read = pci_read_config,
-       .write = pci_write_config,
+static struct bin_attribute *pci_dev_rom_attrs[] = {
+       &bin_attr_rom,
+       NULL,
 };
 
-static const struct bin_attribute pcie_config_attr = {
-       .attr = {
-               .name = "config",
-               .mode = 0644,
-       },
-       .size = PCI_CFG_SPACE_EXP_SIZE,
-       .read = pci_read_config,
-       .write = pci_write_config,
+static umode_t pci_dev_rom_attr_is_visible(struct kobject *kobj,
+                                          struct bin_attribute *a, int n)
+{
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+       size_t rom_size;
+
+       /* If the device has a ROM, try to expose it in sysfs. */
+       rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+       if (!rom_size)
+               return 0;
+
+       a->size = rom_size;
+
+       return a->attr.mode;
+}
+
+static const struct attribute_group pci_dev_rom_attr_group = {
+       .bin_attrs = pci_dev_rom_attrs,
+       .is_bin_visible = pci_dev_rom_attr_is_visible,
 };
 
 static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
@@ -1325,102 +1355,35 @@ static ssize_t reset_store(struct device *dev, struct device_attribute *attr,
 
        return count;
 }
+static DEVICE_ATTR_WO(reset);
 
-static DEVICE_ATTR(reset, 0200, NULL, reset_store);
+static struct attribute *pci_dev_reset_attrs[] = {
+       &dev_attr_reset.attr,
+       NULL,
+};
 
-static int pci_create_capabilities_sysfs(struct pci_dev *dev)
+static umode_t pci_dev_reset_attr_is_visible(struct kobject *kobj,
+                                            struct attribute *a, int n)
 {
-       int retval;
-
-       pcie_vpd_create_sysfs_dev_files(dev);
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
 
-       if (dev->reset_fn) {
-               retval = device_create_file(&dev->dev, &dev_attr_reset);
-               if (retval)
-                       goto error;
-       }
-       return 0;
+       if (!pdev->reset_fn)
+               return 0;
 
-error:
-       pcie_vpd_remove_sysfs_dev_files(dev);
-       return retval;
+       return a->mode;
 }
 
+static const struct attribute_group pci_dev_reset_attr_group = {
+       .attrs = pci_dev_reset_attrs,
+       .is_visible = pci_dev_reset_attr_is_visible,
+};
+
 int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
 {
-       int retval;
-       int rom_size;
-       struct bin_attribute *attr;
-
        if (!sysfs_initialized)
                return -EACCES;
 
-       if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
-               retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
-       else
-               retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
-       if (retval)
-               goto err;
-
-       retval = pci_create_resource_files(pdev);
-       if (retval)
-               goto err_config_file;
-
-       /* If the device has a ROM, try to expose it in sysfs. */
-       rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
-       if (rom_size) {
-               attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
-               if (!attr) {
-                       retval = -ENOMEM;
-                       goto err_resource_files;
-               }
-               sysfs_bin_attr_init(attr);
-               attr->size = rom_size;
-               attr->attr.name = "rom";
-               attr->attr.mode = 0600;
-               attr->read = pci_read_rom;
-               attr->write = pci_write_rom;
-               retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
-               if (retval) {
-                       kfree(attr);
-                       goto err_resource_files;
-               }
-               pdev->rom_attr = attr;
-       }
-
-       /* add sysfs entries for various capabilities */
-       retval = pci_create_capabilities_sysfs(pdev);
-       if (retval)
-               goto err_rom_file;
-
-       pci_create_firmware_label_files(pdev);
-
-       return 0;
-
-err_rom_file:
-       if (pdev->rom_attr) {
-               sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
-               kfree(pdev->rom_attr);
-               pdev->rom_attr = NULL;
-       }
-err_resource_files:
-       pci_remove_resource_files(pdev);
-err_config_file:
-       if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
-       else
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-err:
-       return retval;
-}
-
-static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
-{
-       pcie_vpd_remove_sysfs_dev_files(dev);
-       if (dev->reset_fn) {
-               device_remove_file(&dev->dev, &dev_attr_reset);
-               dev->reset_fn = 0;
-       }
+       return pci_create_resource_files(pdev);
 }
 
 /**
@@ -1434,22 +1397,7 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
        if (!sysfs_initialized)
                return;
 
-       pci_remove_capabilities_sysfs(pdev);
-
-       if (pdev->cfg_size > PCI_CFG_SPACE_SIZE)
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
-       else
-               sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
-
        pci_remove_resource_files(pdev);
-
-       if (pdev->rom_attr) {
-               sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
-               kfree(pdev->rom_attr);
-               pdev->rom_attr = NULL;
-       }
-
-       pci_remove_firmware_label_files(pdev);
 }
 
 static int __init pci_sysfs_init(void)
@@ -1540,6 +1488,16 @@ static const struct attribute_group pci_dev_group = {
 
 const struct attribute_group *pci_dev_groups[] = {
        &pci_dev_group,
+       &pci_dev_config_attr_group,
+       &pci_dev_rom_attr_group,
+       &pci_dev_reset_attr_group,
+       &pci_dev_vpd_attr_group,
+#ifdef CONFIG_DMI
+       &pci_dev_smbios_attr_group,
+#endif
+#ifdef CONFIG_ACPI
+       &pci_dev_acpi_attr_group,
+#endif
        NULL,
 };
 
index 09f1714..3123a4f 100644 (file)
@@ -4454,6 +4454,23 @@ void pci_clear_mwi(struct pci_dev *dev)
 }
 EXPORT_SYMBOL(pci_clear_mwi);
 
+/**
+ * pci_disable_parity - disable parity checking for device
+ * @dev: the PCI device to operate on
+ *
+ * Disable parity checking for device @dev
+ */
+void pci_disable_parity(struct pci_dev *dev)
+{
+       u16 cmd;
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       if (cmd & PCI_COMMAND_PARITY) {
+               cmd &= ~PCI_COMMAND_PARITY;
+               pci_write_config_word(dev, PCI_COMMAND, cmd);
+       }
+}
+
 /**
  * pci_intx - enables/disables PCI INTx for device dev
  * @pdev: the PCI device to operate on
index ef7c466..4c13e2f 100644 (file)
@@ -21,16 +21,10 @@ bool pcie_cap_has_rtctl(const struct pci_dev *dev);
 
 int pci_create_sysfs_dev_files(struct pci_dev *pdev);
 void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
-#if !defined(CONFIG_DMI) && !defined(CONFIG_ACPI)
-static inline void pci_create_firmware_label_files(struct pci_dev *pdev)
-{ return; }
-static inline void pci_remove_firmware_label_files(struct pci_dev *pdev)
-{ return; }
-#else
-void pci_create_firmware_label_files(struct pci_dev *pdev);
-void pci_remove_firmware_label_files(struct pci_dev *pdev);
-#endif
 void pci_cleanup_rom(struct pci_dev *dev);
+#ifdef CONFIG_DMI
+extern const struct attribute_group pci_dev_smbios_attr_group;
+#endif
 
 enum pci_mmap_api {
        PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
@@ -141,10 +135,9 @@ static inline bool pcie_downstream_port(const struct pci_dev *dev)
               type == PCI_EXP_TYPE_PCIE_BRIDGE;
 }
 
-int pci_vpd_init(struct pci_dev *dev);
+void pci_vpd_init(struct pci_dev *dev);
 void pci_vpd_release(struct pci_dev *dev);
-void pcie_vpd_create_sysfs_dev_files(struct pci_dev *dev);
-void pcie_vpd_remove_sysfs_dev_files(struct pci_dev *dev);
+extern const struct attribute_group pci_dev_vpd_attr_group;
 
 /* PCI Virtual Channel */
 int pci_save_vc_state(struct pci_dev *dev);
@@ -624,6 +617,12 @@ static inline int pci_dev_specific_reset(struct pci_dev *dev, int probe)
 #if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64)
 int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment,
                          struct resource *res);
+#else
+static inline int acpi_get_rc_resources(struct device *dev, const char *hid,
+                                       u16 segment, struct resource *res)
+{
+       return -ENODEV;
+}
 #endif
 
 int pci_rebar_get_current_size(struct pci_dev *pdev, int bar);
@@ -696,6 +695,7 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL
 
 #ifdef CONFIG_ACPI
 int pci_acpi_program_hp_params(struct pci_dev *dev);
+extern const struct attribute_group pci_dev_acpi_attr_group;
 #else
 static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
 {
index ba22388..ec943ce 100644 (file)
@@ -129,7 +129,7 @@ static const char * const ecrc_policy_str[] = {
 };
 
 /**
- * enable_ercr_checking - enable PCIe ECRC checking for a device
+ * enable_ecrc_checking - enable PCIe ECRC checking for a device
  * @dev: the PCI device
  *
  * Returns 0 on success, or negative on failure.
@@ -153,7 +153,7 @@ static int enable_ecrc_checking(struct pci_dev *dev)
 }
 
 /**
- * disable_ercr_checking - disables PCIe ECRC checking for a device
+ * disable_ecrc_checking - disables PCIe ECRC checking for a device
  * @dev: the PCI device
  *
  * Returns 0 on success, or negative on failure.
@@ -1442,7 +1442,7 @@ static struct pcie_port_service_driver aerdriver = {
 };
 
 /**
- * aer_service_init - register AER root service driver
+ * pcie_aer_init - register AER root service driver
  *
  * Invoked when AER root service driver is loaded.
  */
index 3fc0848..1d0dd77 100644 (file)
@@ -463,7 +463,7 @@ static struct pcie_port_service_driver pcie_pme_driver = {
 };
 
 /**
- * pcie_pme_service_init - Register the PCIe PME service driver.
+ * pcie_pme_init - Register the PCIe PME service driver.
  */
 int __init pcie_pme_init(void)
 {
index 2c5c552..d0bcd14 100644 (file)
@@ -32,7 +32,7 @@ static bool rcec_assoc_rciep(struct pci_dev *rcec, struct pci_dev *rciep)
 
        /* Same bus, so check bitmap */
        for_each_set_bit(devn, &bitmap, 32)
-               if (devn == rciep->devfn)
+               if (devn == PCI_SLOT(rciep->devfn))
                        return true;
 
        return false;
index 953f15a..be51670 100644 (file)
@@ -2353,6 +2353,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
        pci_set_of_node(dev);
 
        if (pci_setup_device(dev)) {
+               pci_release_of_node(dev);
                pci_bus_put(dev->bus);
                kfree(dev);
                return NULL;
index 653660e..af43b34 100644 (file)
@@ -206,16 +206,11 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
                                PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on);
 
 /*
- * The Mellanox Tavor device gives false positive parity errors.  Mark this
- * device with a broken_parity_status to allow PCI scanning code to "skip"
- * this now blacklisted device.
+ * The Mellanox Tavor device gives false positive parity errors.  Disable
+ * parity error reporting.
  */
-static void quirk_mellanox_tavor(struct pci_dev *dev)
-{
-       dev->broken_parity_status = 1;  /* This device gives false positives */
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR, quirk_mellanox_tavor);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE, quirk_mellanox_tavor);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR, pci_disable_parity);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE, pci_disable_parity);
 
 /*
  * Deal with broken BIOSes that neglect to enable passive release,
@@ -3922,6 +3917,7 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
                reset_ivb_igd },
        { PCI_VENDOR_ID_SAMSUNG, 0xa804, nvme_disable_and_flr },
        { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr },
+       { PCI_VENDOR_ID_INTEL, 0x0a54, delay_250ms_after_flr },
        { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
                reset_chelsio_generic_dev },
        { 0 }
index 95dec03..dd12c2f 100644 (file)
@@ -19,6 +19,8 @@ static void pci_stop_dev(struct pci_dev *dev)
        pci_pme_active(dev, false);
 
        if (pci_dev_is_added(dev)) {
+               dev->reset_fn = 0;
+
                device_release_driver(&dev->dev);
                pci_proc_detach_device(dev);
                pci_remove_sysfs_dev_files(dev);
index 7915d10..26bf7c8 100644 (file)
 struct pci_vpd_ops {
        ssize_t (*read)(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
        ssize_t (*write)(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
-       int (*set_size)(struct pci_dev *dev, size_t len);
 };
 
 struct pci_vpd {
        const struct pci_vpd_ops *ops;
-       struct bin_attribute *attr;     /* Descriptor for sysfs VPD entry */
        struct mutex    lock;
        unsigned int    len;
        u16             flag;
@@ -30,6 +28,11 @@ struct pci_vpd {
        unsigned int    valid:1;
 };
 
+static struct pci_dev *pci_get_func0_dev(struct pci_dev *dev)
+{
+       return pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+}
+
 /**
  * pci_read_vpd - Read one entry from Vital Product Data
  * @dev:       pci device struct
@@ -60,19 +63,6 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void
 }
 EXPORT_SYMBOL(pci_write_vpd);
 
-/**
- * pci_set_vpd_size - Set size of Vital Product Data space
- * @dev:       pci device struct
- * @len:       size of vpd space
- */
-int pci_set_vpd_size(struct pci_dev *dev, size_t len)
-{
-       if (!dev->vpd || !dev->vpd->ops)
-               return -ENODEV;
-       return dev->vpd->ops->set_size(dev, len);
-}
-EXPORT_SYMBOL(pci_set_vpd_size);
-
 #define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1)
 
 /**
@@ -85,10 +75,14 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size)
        size_t off = 0;
        unsigned char header[1+2];      /* 1 byte tag, 2 bytes length */
 
-       while (off < old_size &&
-              pci_read_vpd(dev, off, 1, header) == 1) {
+       while (off < old_size && pci_read_vpd(dev, off, 1, header) == 1) {
                unsigned char tag;
 
+               if (!header[0] && !off) {
+                       pci_info(dev, "Invalid VPD tag 00, assume missing optional VPD EPROM\n");
+                       return 0;
+               }
+
                if (header[0] & PCI_VPD_LRDT) {
                        /* Large Resource Data Type Tag */
                        tag = pci_vpd_lrdt_tag(header);
@@ -297,30 +291,15 @@ out:
        return ret ? ret : count;
 }
 
-static int pci_vpd_set_size(struct pci_dev *dev, size_t len)
-{
-       struct pci_vpd *vpd = dev->vpd;
-
-       if (len == 0 || len > PCI_VPD_MAX_SIZE)
-               return -EIO;
-
-       vpd->valid = 1;
-       vpd->len = len;
-
-       return 0;
-}
-
 static const struct pci_vpd_ops pci_vpd_ops = {
        .read = pci_vpd_read,
        .write = pci_vpd_write,
-       .set_size = pci_vpd_set_size,
 };
 
 static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
                               void *arg)
 {
-       struct pci_dev *tdev = pci_get_slot(dev->bus,
-                                           PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+       struct pci_dev *tdev = pci_get_func0_dev(dev);
        ssize_t ret;
 
        if (!tdev)
@@ -334,8 +313,7 @@ static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
 static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
                                const void *arg)
 {
-       struct pci_dev *tdev = pci_get_slot(dev->bus,
-                                           PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+       struct pci_dev *tdev = pci_get_func0_dev(dev);
        ssize_t ret;
 
        if (!tdev)
@@ -346,38 +324,23 @@ static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
        return ret;
 }
 
-static int pci_vpd_f0_set_size(struct pci_dev *dev, size_t len)
-{
-       struct pci_dev *tdev = pci_get_slot(dev->bus,
-                                           PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
-       int ret;
-
-       if (!tdev)
-               return -ENODEV;
-
-       ret = pci_set_vpd_size(tdev, len);
-       pci_dev_put(tdev);
-       return ret;
-}
-
 static const struct pci_vpd_ops pci_vpd_f0_ops = {
        .read = pci_vpd_f0_read,
        .write = pci_vpd_f0_write,
-       .set_size = pci_vpd_f0_set_size,
 };
 
-int pci_vpd_init(struct pci_dev *dev)
+void pci_vpd_init(struct pci_dev *dev)
 {
        struct pci_vpd *vpd;
        u8 cap;
 
        cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
        if (!cap)
-               return -ENODEV;
+               return;
 
        vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
        if (!vpd)
-               return -ENOMEM;
+               return;
 
        vpd->len = PCI_VPD_MAX_SIZE;
        if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0)
@@ -389,7 +352,6 @@ int pci_vpd_init(struct pci_dev *dev)
        vpd->busy = 0;
        vpd->valid = 0;
        dev->vpd = vpd;
-       return 0;
 }
 
 void pci_vpd_release(struct pci_dev *dev)
@@ -397,102 +359,56 @@ void pci_vpd_release(struct pci_dev *dev)
        kfree(dev->vpd);
 }
 
-static ssize_t read_vpd_attr(struct file *filp, struct kobject *kobj,
-                            struct bin_attribute *bin_attr, char *buf,
-                            loff_t off, size_t count)
+static ssize_t vpd_read(struct file *filp, struct kobject *kobj,
+                       struct bin_attribute *bin_attr, char *buf, loff_t off,
+                       size_t count)
 {
        struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
 
-       if (bin_attr->size > 0) {
-               if (off > bin_attr->size)
-                       count = 0;
-               else if (count > bin_attr->size - off)
-                       count = bin_attr->size - off;
-       }
-
        return pci_read_vpd(dev, off, count, buf);
 }
 
-static ssize_t write_vpd_attr(struct file *filp, struct kobject *kobj,
-                             struct bin_attribute *bin_attr, char *buf,
-                             loff_t off, size_t count)
+static ssize_t vpd_write(struct file *filp, struct kobject *kobj,
+                        struct bin_attribute *bin_attr, char *buf, loff_t off,
+                        size_t count)
 {
        struct pci_dev *dev = to_pci_dev(kobj_to_dev(kobj));
 
-       if (bin_attr->size > 0) {
-               if (off > bin_attr->size)
-                       count = 0;
-               else if (count > bin_attr->size - off)
-                       count = bin_attr->size - off;
-       }
-
        return pci_write_vpd(dev, off, count, buf);
 }
+static BIN_ATTR(vpd, 0600, vpd_read, vpd_write, 0);
 
-void pcie_vpd_create_sysfs_dev_files(struct pci_dev *dev)
-{
-       int retval;
-       struct bin_attribute *attr;
-
-       if (!dev->vpd)
-               return;
+static struct bin_attribute *vpd_attrs[] = {
+       &bin_attr_vpd,
+       NULL,
+};
 
-       attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
-       if (!attr)
-               return;
+static umode_t vpd_attr_is_visible(struct kobject *kobj,
+                                  struct bin_attribute *a, int n)
+{
+       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
 
-       sysfs_bin_attr_init(attr);
-       attr->size = 0;
-       attr->attr.name = "vpd";
-       attr->attr.mode = S_IRUSR | S_IWUSR;
-       attr->read = read_vpd_attr;
-       attr->write = write_vpd_attr;
-       retval = sysfs_create_bin_file(&dev->dev.kobj, attr);
-       if (retval) {
-               kfree(attr);
-               return;
-       }
+       if (!pdev->vpd)
+               return 0;
 
-       dev->vpd->attr = attr;
+       return a->attr.mode;
 }
 
-void pcie_vpd_remove_sysfs_dev_files(struct pci_dev *dev)
-{
-       if (dev->vpd && dev->vpd->attr) {
-               sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
-               kfree(dev->vpd->attr);
-       }
-}
+const struct attribute_group pci_dev_vpd_attr_group = {
+       .bin_attrs = vpd_attrs,
+       .is_bin_visible = vpd_attr_is_visible,
+};
 
-int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt)
+int pci_vpd_find_tag(const u8 *buf, unsigned int len, u8 rdt)
 {
-       int i;
+       int i = 0;
 
-       for (i = off; i < len; ) {
-               u8 val = buf[i];
-
-               if (val & PCI_VPD_LRDT) {
-                       /* Don't return success of the tag isn't complete */
-                       if (i + PCI_VPD_LRDT_TAG_SIZE > len)
-                               break;
-
-                       if (val == rdt)
-                               return i;
-
-                       i += PCI_VPD_LRDT_TAG_SIZE +
-                            pci_vpd_lrdt_size(&buf[i]);
-               } else {
-                       u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK;
-
-                       if (tag == rdt)
-                               return i;
-
-                       if (tag == PCI_VPD_SRDT_END)
-                               break;
+       /* look for LRDT tags only, end tag is the only SRDT tag */
+       while (i + PCI_VPD_LRDT_TAG_SIZE <= len && buf[i] & PCI_VPD_LRDT) {
+               if (buf[i] == rdt)
+                       return i;
 
-                       i += PCI_VPD_SRDT_TAG_SIZE +
-                            pci_vpd_srdt_size(&buf[i]);
-               }
+               i += PCI_VPD_LRDT_TAG_SIZE + pci_vpd_lrdt_size(buf + i);
        }
 
        return -ENOENT;
@@ -530,7 +446,7 @@ static void quirk_f0_vpd_link(struct pci_dev *dev)
        if (!PCI_FUNC(dev->devfn))
                return;
 
-       f0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+       f0 = pci_get_func0_dev(dev);
        if (!f0)
                return;
 
@@ -570,7 +486,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005d, quirk_blacklist_vpd);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005f, quirk_blacklist_vpd);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, PCI_ANY_ID,
                quirk_blacklist_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QLOGIC, 0x2261, quirk_blacklist_vpd);
 /*
  * The Amazon Annapurna Labs 0x0031 device id is reused for other non Root Port
  * device types, so the quirk is registered for the PCI_CLASS_BRIDGE_PCI class.
@@ -578,51 +493,16 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QLOGIC, 0x2261, quirk_blacklist_vpd);
 DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031,
                              PCI_CLASS_BRIDGE_PCI, 8, quirk_blacklist_vpd);
 
-/*
- * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the
- * VPD end tag will hang the device.  This problem was initially
- * observed when a vpd entry was created in sysfs
- * ('/sys/bus/pci/devices/<id>/vpd').   A read to this sysfs entry
- * will dump 32k of data.  Reading a full 32k will cause an access
- * beyond the VPD end tag causing the device to hang.  Once the device
- * is hung, the bnx2 driver will not be able to reset the device.
- * We believe that it is legal to read beyond the end tag and
- * therefore the solution is to limit the read/write length.
- */
-static void quirk_brcm_570x_limit_vpd(struct pci_dev *dev)
+static void pci_vpd_set_size(struct pci_dev *dev, size_t len)
 {
-       /*
-        * Only disable the VPD capability for 5706, 5706S, 5708,
-        * 5708S and 5709 rev. A
-        */
-       if ((dev->device == PCI_DEVICE_ID_NX2_5706) ||
-           (dev->device == PCI_DEVICE_ID_NX2_5706S) ||
-           (dev->device == PCI_DEVICE_ID_NX2_5708) ||
-           (dev->device == PCI_DEVICE_ID_NX2_5708S) ||
-           ((dev->device == PCI_DEVICE_ID_NX2_5709) &&
-            (dev->revision & 0xf0) == 0x0)) {
-               if (dev->vpd)
-                       dev->vpd->len = 0x80;
-       }
+       struct pci_vpd *vpd = dev->vpd;
+
+       if (!vpd || len == 0 || len > PCI_VPD_MAX_SIZE)
+               return;
+
+       vpd->valid = 1;
+       vpd->len = len;
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
-                       PCI_DEVICE_ID_NX2_5706,
-                       quirk_brcm_570x_limit_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
-                       PCI_DEVICE_ID_NX2_5706S,
-                       quirk_brcm_570x_limit_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
-                       PCI_DEVICE_ID_NX2_5708,
-                       quirk_brcm_570x_limit_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
-                       PCI_DEVICE_ID_NX2_5708S,
-                       quirk_brcm_570x_limit_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
-                       PCI_DEVICE_ID_NX2_5709,
-                       quirk_brcm_570x_limit_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
-                       PCI_DEVICE_ID_NX2_5709S,
-                       quirk_brcm_570x_limit_vpd);
 
 static void quirk_chelsio_extend_vpd(struct pci_dev *dev)
 {
@@ -642,9 +522,9 @@ static void quirk_chelsio_extend_vpd(struct pci_dev *dev)
         * limits.
         */
        if (chip == 0x0 && prod >= 0x20)
-               pci_set_vpd_size(dev, 8192);
+               pci_vpd_set_size(dev, 8192);
        else if (chip >= 0x4 && func < 0x8)
-               pci_set_vpd_size(dev, 2048);
+               pci_vpd_set_size(dev, 2048);
 }
 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
index e72440d..ae0963c 100644 (file)
@@ -1649,8 +1649,7 @@ static int read_vpd(struct cxlflash_cfg *cfg, u64 wwpn[])
        }
 
        /* Get the read only section offset */
-       ro_start = pci_vpd_find_tag(vpd_data, 0, vpd_size,
-                                   PCI_VPD_LRDT_RO_DATA);
+       ro_start = pci_vpd_find_tag(vpd_data, vpd_size, PCI_VPD_LRDT_RO_DATA);
        if (unlikely(ro_start < 0)) {
                dev_err(dev, "%s: VPD Read-only data not found\n", __func__);
                rc = -ENODEV;
index 86c799c..ce17dbc 100644 (file)
@@ -458,7 +458,6 @@ struct pci_dev {
 
        u32             saved_config_space[16]; /* Config space saved at suspend time */
        struct hlist_head saved_cap_space;
-       struct bin_attribute *rom_attr;         /* Attribute descriptor for sysfs ROM entry */
        int             rom_attr_enabled;       /* Display of ROM attribute enabled? */
        struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
        struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
@@ -1201,6 +1200,7 @@ int __must_check pci_set_mwi(struct pci_dev *dev);
 int __must_check pcim_set_mwi(struct pci_dev *dev);
 int pci_try_set_mwi(struct pci_dev *dev);
 void pci_clear_mwi(struct pci_dev *dev);
+void pci_disable_parity(struct pci_dev *dev);
 void pci_intx(struct pci_dev *dev, int enable);
 bool pci_check_and_mask_intx(struct pci_dev *dev);
 bool pci_check_and_unmask_intx(struct pci_dev *dev);
@@ -1302,7 +1302,6 @@ void pci_unlock_rescan_remove(void);
 /* Vital Product Data routines */
 ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
 ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
-int pci_set_vpd_size(struct pci_dev *dev, size_t len);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx);
@@ -2311,14 +2310,13 @@ static inline u8 pci_vpd_info_field_size(const u8 *info_field)
 /**
  * pci_vpd_find_tag - Locates the Resource Data Type tag provided
  * @buf: Pointer to buffered vpd data
- * @off: The offset into the buffer at which to begin the search
  * @len: The length of the vpd buffer
  * @rdt: The Resource Data Type to search for
  *
  * Returns the index where the Resource Data Type was found or
  * -ENOENT otherwise.
  */
-int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt);
+int pci_vpd_find_tag(const u8 *buf, unsigned int len, u8 rdt);
 
 /**
  * pci_vpd_find_info_keyword - Locates an information field keyword in the VPD
index a76ccb6..8a18517 100644 (file)
 #define PCI_DEVICE_ID_EXAR_XR17V358    0x0358
 
 #define PCI_VENDOR_ID_MICROGATE                0x13c0
-#define PCI_DEVICE_ID_MICROGATE_USC    0x0010
-#define PCI_DEVICE_ID_MICROGATE_SCA    0x0030
 
 #define PCI_VENDOR_ID_3WARE            0x13C1
 #define PCI_DEVICE_ID_3WARE_1000       0x1000