Merge branch 'pci/layerscape'
authorBjorn Helgaas <bhelgaas@google.com>
Wed, 24 Feb 2021 20:59:22 +0000 (14:59 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 24 Feb 2021 20:59:22 +0000 (14:59 -0600)
- Add Layerscape LX2160A rev2 endpoint mode support (Hou Zhiqiang)

- Convert layerscape to builtin_platform_driver() (Michael Walle)

* pci/layerscape:
  PCI: layerscape: Convert to builtin_platform_driver()
  PCI: layerscape: Add LX2160A rev2 EP mode support
  dt-bindings: PCI: layerscape: Add LX2160A rev2 compatible strings

33 files changed:
Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
MAINTAINERS
arch/s390/include/asm/facility.h
drivers/acpi/pci_root.c
drivers/gpu/drm/qxl/qxl_drv.c
drivers/net/wireless/intel/iwlwifi/fw/file.h
drivers/pci/Makefile
drivers/pci/controller/Kconfig
drivers/pci/controller/cadence/pci-j721e.c
drivers/pci/controller/cadence/pcie-cadence-host.c
drivers/pci/controller/cadence/pcie-cadence.h
drivers/pci/controller/dwc/pcie-al.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/pcie-brcmstb.c
drivers/pci/hotplug/acpiphp.h
drivers/pci/pci-bridge-emul.c
drivers/pci/pci.c
drivers/pci/pcie/Kconfig
drivers/pci/pcie/Makefile
drivers/pci/pcie/aer.c
drivers/pci/pcie/bw_notification.c [deleted file]
drivers/pci/pcie/err.c
drivers/pci/pcie/portdrv.h
drivers/pci/pcie/portdrv_pci.c
drivers/pci/search.c
drivers/pci/setup-res.c
drivers/pci/syscall.c
include/linux/acpi.h
include/linux/pci_ids.h
lib/logic_pio.c

index 807694b4f41f68b37aab27cb205299e7aa005631..f90557f6deb843b66d7144837f416acddfb9d9c1 100644 (file)
@@ -14,6 +14,7 @@ properties:
     items:
       - enum:
           - brcm,bcm2711-pcie # The Raspberry Pi 4
+          - brcm,bcm4908-pcie
           - brcm,bcm7211-pcie # Broadcom STB version of RPi4
           - brcm,bcm7278-pcie # Broadcom 7278 Arm
           - brcm,bcm7216-pcie # Broadcom 7216 Arm
@@ -63,15 +64,6 @@ properties:
 
   aspm-no-l0s: true
 
-  resets:
-    description: for "brcm,bcm7216-pcie", must be a valid reset
-      phandle pointing to the RESCAL reset controller provider node.
-    $ref: "/schemas/types.yaml#/definitions/phandle"
-
-  reset-names:
-    items:
-      - const: rescal
-
   brcm,scb-sizes:
     description: u64 giving the 64bit PCIe memory
       viewport size of a memory controller.  There may be up to
@@ -98,12 +90,39 @@ required:
 
 allOf:
   - $ref: /schemas/pci/pci-bus.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: brcm,bcm4908-pcie
+    then:
+      properties:
+        resets:
+          items:
+            - description: reset controller handling the PERST# signal
+
+        reset-names:
+          items:
+            - const: perst
+
+      required:
+        - resets
+        - reset-names
   - if:
       properties:
         compatible:
           contains:
             const: brcm,bcm7216-pcie
     then:
+      properties:
+        resets:
+          items:
+            - description: phandle pointing to the RESCAL reset controller
+
+        reset-names:
+          items:
+            - const: rescal
+
       required:
         - resets
         - reset-names
index cc1e6a5ee6e67357822317c7f71ea9171bdcefcb..52311efad03e79d3524deb1ee971a67e0a988f5e 100644 (file)
@@ -2603,7 +2603,7 @@ L:        linux-kernel@vger.kernel.org
 S:     Maintained
 F:     drivers/clk/keystone/
 
-ARM/TEXAS INSTRUMENT KEYSTONE ClOCKSOURCE
+ARM/TEXAS INSTRUMENT KEYSTONE CLOCKSOURCE
 M:     Santosh Shilimkar <ssantosh@kernel.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-kernel@vger.kernel.org
index 68c476b20b57e25691cf990766c89c1c113490e1..91b5d714d28f64afc1d2cf32cbbfb1b657038510 100644 (file)
@@ -44,7 +44,7 @@ static inline int __test_facility(unsigned long nr, void *facilities)
 }
 
 /*
- * The test_facility function uses the bit odering where the MSB is bit 0.
+ * The test_facility function uses the bit ordering where the MSB is bit 0.
  * That makes it easier to query facility bits with the bit number as
  * documented in the Principles of Operation.
  */
index 0bf072cef6cfd32057edece53d01b634357d95fe..dcd593766a643319d78d36f3759840397a3203c1 100644 (file)
@@ -56,8 +56,6 @@ static struct acpi_scan_handler pci_root_handler = {
        },
 };
 
-static DEFINE_MUTEX(osc_lock);
-
 /**
  * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
  * @handle:  the ACPI CA node in question.
@@ -223,12 +221,7 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
 
 static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
 {
-       acpi_status status;
-
-       mutex_lock(&osc_lock);
-       status = acpi_pci_query_osc(root, flags, NULL);
-       mutex_unlock(&osc_lock);
-       return status;
+       return acpi_pci_query_osc(root, flags, NULL);
 }
 
 struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
@@ -353,10 +346,10 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
  * _OSC bits the BIOS has granted control of, but its contents are meaningless
  * on failure.
  **/
-acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
+static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
 {
        struct acpi_pci_root *root;
-       acpi_status status = AE_OK;
+       acpi_status status;
        u32 ctrl, capbuf[3];
 
        if (!mask)
@@ -370,18 +363,16 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
        if (!root)
                return AE_NOT_EXIST;
 
-       mutex_lock(&osc_lock);
-
        *mask = ctrl | root->osc_control_set;
        /* No need to evaluate _OSC if the control was already granted. */
        if ((root->osc_control_set & ctrl) == ctrl)
-               goto out;
+               return AE_OK;
 
        /* Need to check the available controls bits before requesting them. */
        while (*mask) {
                status = acpi_pci_query_osc(root, root->osc_support_set, mask);
                if (ACPI_FAILURE(status))
-                       goto out;
+                       return status;
                if (ctrl == *mask)
                        break;
                decode_osc_control(root, "platform does not support",
@@ -392,21 +383,19 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
        if ((ctrl & req) != req) {
                decode_osc_control(root, "not requesting control; platform does not support",
                                   req & ~(ctrl));
-               status = AE_SUPPORT;
-               goto out;
+               return AE_SUPPORT;
        }
 
        capbuf[OSC_QUERY_DWORD] = 0;
        capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set;
        capbuf[OSC_CONTROL_DWORD] = ctrl;
        status = acpi_pci_run_osc(handle, capbuf, mask);
-       if (ACPI_SUCCESS(status))
-               root->osc_control_set = *mask;
-out:
-       mutex_unlock(&osc_lock);
-       return status;
+       if (ACPI_FAILURE(status))
+               return status;
+
+       root->osc_control_set = *mask;
+       return AE_OK;
 }
-EXPORT_SYMBOL(acpi_pci_osc_control_set);
 
 static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
                                 bool is_pcie)
@@ -452,9 +441,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
                if ((status == AE_NOT_FOUND) && !is_pcie)
                        return;
 
-               dev_info(&device->dev, "_OSC failed (%s)%s\n",
-                        acpi_format_exception(status),
-                        pcie_aspm_support_enabled() ? "; disabling ASPM" : "");
+               dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n",
+                        acpi_format_exception(status));
                return;
        }
 
@@ -510,7 +498,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
        } else {
                decode_osc_control(root, "OS requested", requested);
                decode_osc_control(root, "platform willing to grant", control);
-               dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n",
+               dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n",
                        acpi_format_exception(status));
 
                /*
index 6e7f16f4cec794dd0ec82f295dc0a203fd956eac..dab190a547cc80b0f9bf4d50ed890c520fd4f4c2 100644 (file)
@@ -141,7 +141,7 @@ static void qxl_drm_release(struct drm_device *dev)
 
        /*
         * TODO: qxl_device_fini() call should be in qxl_pci_remove(),
-        * reodering qxl_modeset_fini() + qxl_device_fini() calls is
+        * reordering qxl_modeset_fini() + qxl_device_fini() calls is
         * non-trivial though.
         */
        qxl_modeset_fini(qdev);
index 597bc88479ba32c89390c940ac224a999146b2f7..04fbfe5cbeb03159b8bbceec4ea2a78efeb0d483 100644 (file)
@@ -866,7 +866,7 @@ struct iwl_fw_dbg_trigger_time_event {
  * tx_bar: tid bitmap to configure on what tid the trigger should occur
  *     when a BAR is send (for an Rx BlocAck session).
  * frame_timeout: tid bitmap to configure on what tid the trigger should occur
- *     when a frame times out in the reodering buffer.
+ *     when a frame times out in the reordering buffer.
  */
 struct iwl_fw_dbg_trigger_ba {
        __le16 rx_ba_start;
index 11cc79411e2d6b32f3c1ae7031a2c7600890ecbc..d62c4ac4ae1b3553eec9c582030ebb0b2fcae788 100644 (file)
@@ -36,4 +36,4 @@ obj-$(CONFIG_PCI_ENDPOINT)    += endpoint/
 obj-y                          += controller/
 obj-y                          += switch/
 
-ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
+subdir-ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
index 64e2f5e379aa390229e2557ac15d09dc6b4fc402..d44c70bb88f6eda1908162fd275a0b71b28990d4 100644 (file)
@@ -273,7 +273,7 @@ config VMD
 
 config PCIE_BRCMSTB
        tristate "Broadcom Brcmstb PCIe host controller"
-       depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
+       depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCM4908 || COMPILE_TEST
        depends on OF
        depends on PCI_MSI_IRQ_DOMAIN
        default ARCH_BRCMSTB
index dac1ac8a7615958dbdbdbdafb97408064dca7ff6..849f1e416ea573e3749ad4ae0d6e5cef6160ba55 100644 (file)
@@ -64,6 +64,7 @@ enum j721e_pcie_mode {
 
 struct j721e_pcie_data {
        enum j721e_pcie_mode    mode;
+       bool quirk_retrain_flag;
 };
 
 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset)
@@ -280,6 +281,7 @@ static struct pci_ops cdns_ti_pcie_host_ops = {
 
 static const struct j721e_pcie_data j721e_pcie_rc_data = {
        .mode = PCI_MODE_RC,
+       .quirk_retrain_flag = true,
 };
 
 static const struct j721e_pcie_data j721e_pcie_ep_data = {
@@ -388,6 +390,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 
                bridge->ops = &cdns_ti_pcie_host_ops;
                rc = pci_host_bridge_priv(bridge);
+               rc->quirk_retrain_flag = data->quirk_retrain_flag;
 
                cdns_pcie = &rc->pcie;
                cdns_pcie->dev = dev;
index 811c1cb2e8deb5211ade382daae684df50f11d00..73dcf8cf98fbf43efeeb6e54001ee25bb1b757bb 100644 (file)
@@ -77,6 +77,68 @@ static struct pci_ops cdns_pcie_host_ops = {
        .write          = pci_generic_config_write,
 };
 
+static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
+{
+       struct device *dev = pcie->dev;
+       int retries;
+
+       /* Check if the link is up or not */
+       for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+               if (cdns_pcie_link_up(pcie)) {
+                       dev_info(dev, "Link up\n");
+                       return 0;
+               }
+               usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+       }
+
+       return -ETIMEDOUT;
+}
+
+static int cdns_pcie_retrain(struct cdns_pcie *pcie)
+{
+       u32 lnk_cap_sls, pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
+       u16 lnk_stat, lnk_ctl;
+       int ret = 0;
+
+       /*
+        * Set retrain bit if current speed is 2.5 GB/s,
+        * but the PCIe root port support is > 2.5 GB/s.
+        */
+
+       lnk_cap_sls = cdns_pcie_readl(pcie, (CDNS_PCIE_RP_BASE + pcie_cap_off +
+                                            PCI_EXP_LNKCAP));
+       if ((lnk_cap_sls & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
+               return ret;
+
+       lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
+       if ((lnk_stat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
+               lnk_ctl = cdns_pcie_rp_readw(pcie,
+                                            pcie_cap_off + PCI_EXP_LNKCTL);
+               lnk_ctl |= PCI_EXP_LNKCTL_RL;
+               cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
+                                   lnk_ctl);
+
+               ret = cdns_pcie_host_wait_for_link(pcie);
+       }
+       return ret;
+}
+
+static int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc)
+{
+       struct cdns_pcie *pcie = &rc->pcie;
+       int ret;
+
+       ret = cdns_pcie_host_wait_for_link(pcie);
+
+       /*
+        * Retrain link for Gen2 training defect
+        * if quirk flag is set.
+        */
+       if (!ret && rc->quirk_retrain_flag)
+               ret = cdns_pcie_retrain(pcie);
+
+       return ret;
+}
 
 static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
 {
@@ -321,9 +383,10 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc)
 
        resource_list_for_each_entry(entry, &bridge->dma_ranges) {
                err = cdns_pcie_host_bar_config(rc, entry);
-               if (err)
+               if (err) {
                        dev_err(dev, "Fail to configure IB using dma-ranges\n");
-               return err;
+                       return err;
+               }
        }
 
        return 0;
@@ -398,23 +461,6 @@ static int cdns_pcie_host_init(struct device *dev,
        return cdns_pcie_host_init_address_translation(rc);
 }
 
-static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
-{
-       struct device *dev = pcie->dev;
-       int retries;
-
-       /* Check if the link is up or not */
-       for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
-               if (cdns_pcie_link_up(pcie)) {
-                       dev_info(dev, "Link up\n");
-                       return 0;
-               }
-               usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
-       }
-
-       return -ETIMEDOUT;
-}
-
 int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
 {
        struct device *dev = rc->pcie.dev;
@@ -457,7 +503,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
                return ret;
        }
 
-       ret = cdns_pcie_host_wait_for_link(pcie);
+       ret = cdns_pcie_host_start_link(rc);
        if (ret)
                dev_dbg(dev, "PCIe link never came up\n");
 
index 30eba6cafe2c1e1c608c85e70389acecd245680b..254d2570f8c91bbe495e59bcf0f11a4c4e021a65 100644 (file)
  * Root Port Registers (PCI configuration space for the root port function)
  */
 #define CDNS_PCIE_RP_BASE      0x00200000
-
+#define CDNS_PCIE_RP_CAP_OFFSET 0xc0
 
 /*
  * Address Translation Registers
@@ -291,6 +291,7 @@ struct cdns_pcie {
  * @device_id: PCI device ID
  * @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and        RP_NO_BAR if it's free or
  *                available
+ * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2
  */
 struct cdns_pcie_rc {
        struct cdns_pcie        pcie;
@@ -299,6 +300,7 @@ struct cdns_pcie_rc {
        u32                     vendor_id;
        u32                     device_id;
        bool                    avail_ib_bar[CDNS_PCIE_RP_MAX_IB];
+       bool                    quirk_retrain_flag;
 };
 
 /**
@@ -414,6 +416,13 @@ static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie,
        cdns_pcie_write_sz(addr, 0x2, value);
 }
 
+static inline u16 cdns_pcie_rp_readw(struct cdns_pcie *pcie, u32 reg)
+{
+       void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
+
+       return cdns_pcie_read_sz(addr, 0x2);
+}
+
 /* Endpoint Function register access */
 static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
                                          u32 reg, u8 value)
index abf37aa68e514ab3f8e6707a83fb0405f6778b16..e8afa50129a8f205879bc137113a0e273b588e65 100644 (file)
@@ -314,9 +314,6 @@ static const struct dw_pcie_host_ops al_pcie_host_ops = {
        .host_init = al_pcie_host_init,
 };
 
-static const struct dw_pcie_ops dw_pcie_ops = {
-};
-
 static int al_pcie_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -334,7 +331,6 @@ static int al_pcie_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        pci->dev = dev;
-       pci->ops = &dw_pcie_ops;
        pci->pp.ops = &al_pcie_host_ops;
 
        al_pcie->pci = pci;
index bcd1cd9ba8c80b20073ec23883939240f42bcc7d..1c25d8337151006f70b048b81585b4a1bd620f4d 100644 (file)
@@ -434,10 +434,8 @@ static void dw_pcie_ep_stop(struct pci_epc *epc)
        struct dw_pcie_ep *ep = epc_get_drvdata(epc);
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
-       if (!pci->ops->stop_link)
-               return;
-
-       pci->ops->stop_link(pci);
+       if (pci->ops && pci->ops->stop_link)
+               pci->ops->stop_link(pci);
 }
 
 static int dw_pcie_ep_start(struct pci_epc *epc)
@@ -445,7 +443,7 @@ static int dw_pcie_ep_start(struct pci_epc *epc)
        struct dw_pcie_ep *ep = epc_get_drvdata(epc);
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
 
-       if (!pci->ops->start_link)
+       if (!pci->ops || !pci->ops->start_link)
                return -EINVAL;
 
        return pci->ops->start_link(pci);
index 8a84c005f32bdc6edac1638efb028108e32050d7..0f0d8f47759695c35ac0ea94e654c39f08d7ad70 100644 (file)
@@ -305,8 +305,13 @@ int dw_pcie_host_init(struct pcie_port *pp)
        if (cfg_res) {
                pp->cfg0_size = resource_size(cfg_res);
                pp->cfg0_base = cfg_res->start;
-       } else if (!pp->va_cfg0_base) {
+
+               pp->va_cfg0_base = devm_pci_remap_cfg_resource(dev, cfg_res);
+               if (IS_ERR(pp->va_cfg0_base))
+                       return PTR_ERR(pp->va_cfg0_base);
+       } else {
                dev_err(dev, "Missing *config* reg space\n");
+               return -ENODEV;
        }
 
        if (!pci->dbi_base) {
@@ -322,38 +327,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
        pp->bridge = bridge;
 
-       /* Get the I/O and memory ranges from DT */
-       resource_list_for_each_entry(win, &bridge->windows) {
-               switch (resource_type(win->res)) {
-               case IORESOURCE_IO:
-                       pp->io_size = resource_size(win->res);
-                       pp->io_bus_addr = win->res->start - win->offset;
-                       pp->io_base = pci_pio_to_address(win->res->start);
-                       break;
-               case 0:
-                       dev_err(dev, "Missing *config* reg space\n");
-                       pp->cfg0_size = resource_size(win->res);
-                       pp->cfg0_base = win->res->start;
-                       if (!pci->dbi_base) {
-                               pci->dbi_base = devm_pci_remap_cfgspace(dev,
-                                                               pp->cfg0_base,
-                                                               pp->cfg0_size);
-                               if (!pci->dbi_base) {
-                                       dev_err(dev, "Error with ioremap\n");
-                                       return -ENOMEM;
-                               }
-                       }
-                       break;
-               }
-       }
-
-       if (!pp->va_cfg0_base) {
-               pp->va_cfg0_base = devm_pci_remap_cfgspace(dev,
-                                       pp->cfg0_base, pp->cfg0_size);
-               if (!pp->va_cfg0_base) {
-                       dev_err(dev, "Error with ioremap in function\n");
-                       return -ENOMEM;
-               }
+       /* Get the I/O range from DT */
+       win = resource_list_first_type(&bridge->windows, IORESOURCE_IO);
+       if (win) {
+               pp->io_size = resource_size(win->res);
+               pp->io_bus_addr = win->res->start - win->offset;
+               pp->io_base = pci_pio_to_address(win->res->start);
        }
 
        if (pci->link_gen < 1)
@@ -425,7 +404,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
        dw_pcie_setup_rc(pp);
        dw_pcie_msi_init(pp);
 
-       if (!dw_pcie_link_up(pci) && pci->ops->start_link) {
+       if (!dw_pcie_link_up(pci) && pci->ops && pci->ops->start_link) {
                ret = pci->ops->start_link(pci);
                if (ret)
                        goto err_free_msi;
index 645fa18923751db2477956522d49d9120edeeb16..004cb860e2667a59ea2bee42a4046a0cbb152b76 100644 (file)
@@ -141,7 +141,7 @@ u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size)
        int ret;
        u32 val;
 
-       if (pci->ops->read_dbi)
+       if (pci->ops && pci->ops->read_dbi)
                return pci->ops->read_dbi(pci, pci->dbi_base, reg, size);
 
        ret = dw_pcie_read(pci->dbi_base + reg, size, &val);
@@ -156,7 +156,7 @@ void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val)
 {
        int ret;
 
-       if (pci->ops->write_dbi) {
+       if (pci->ops && pci->ops->write_dbi) {
                pci->ops->write_dbi(pci, pci->dbi_base, reg, size, val);
                return;
        }
@@ -171,7 +171,7 @@ void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val)
 {
        int ret;
 
-       if (pci->ops->write_dbi2) {
+       if (pci->ops && pci->ops->write_dbi2) {
                pci->ops->write_dbi2(pci, pci->dbi_base2, reg, size, val);
                return;
        }
@@ -186,7 +186,7 @@ static u32 dw_pcie_readl_atu(struct dw_pcie *pci, u32 reg)
        int ret;
        u32 val;
 
-       if (pci->ops->read_dbi)
+       if (pci->ops && pci->ops->read_dbi)
                return pci->ops->read_dbi(pci, pci->atu_base, reg, 4);
 
        ret = dw_pcie_read(pci->atu_base + reg, 4, &val);
@@ -200,7 +200,7 @@ static void dw_pcie_writel_atu(struct dw_pcie *pci, u32 reg, u32 val)
 {
        int ret;
 
-       if (pci->ops->write_dbi) {
+       if (pci->ops && pci->ops->write_dbi) {
                pci->ops->write_dbi(pci, pci->atu_base, reg, 4, val);
                return;
        }
@@ -225,6 +225,47 @@ static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg,
        dw_pcie_writel_atu(pci, offset + reg, val);
 }
 
+static inline u32 dw_pcie_enable_ecrc(u32 val)
+{
+       /*
+        * DesignWare core version 4.90A has a design issue where the 'TD'
+        * bit in the Control register-1 of the ATU outbound region acts
+        * like an override for the ECRC setting, i.e., the presence of TLP
+        * Digest (ECRC) in the outgoing TLPs is solely determined by this
+        * bit. This is contrary to the PCIe spec which says that the
+        * enablement of the ECRC is solely determined by the AER
+        * registers.
+        *
+        * Because of this, even when the ECRC is enabled through AER
+        * registers, the transactions going through ATU won't have TLP
+        * Digest as there is no way the PCI core AER code could program
+        * the TD bit which is specific to the DesignWare core.
+        *
+        * The best way to handle this scenario is to program the TD bit
+        * always. It affects only the traffic from root port to downstream
+        * devices.
+        *
+        * At this point,
+        * When ECRC is enabled in AER registers, everything works normally
+        * When ECRC is NOT enabled in AER registers, then,
+        * on Root Port:- TLP Digest (DWord size) gets appended to each packet
+        *                even through it is not required. Since downstream
+        *                TLPs are mostly for configuration accesses and BAR
+        *                accesses, they are not in critical path and won't
+        *                have much negative effect on the performance.
+        * on End Point:- TLP Digest is received for some/all the packets coming
+        *                from the root port. TLP Digest is ignored because,
+        *                as per the PCIe Spec r5.0 v1.0 section 2.2.3
+        *                "TLP Digest Rules", when an endpoint receives TLP
+        *                Digest when its ECRC check functionality is disabled
+        *                in AER registers, received TLP Digest is just ignored.
+        * Since there is no issue or error reported either side, best way to
+        * handle the scenario is to program TD bit by default.
+        */
+
+       return val | PCIE_ATU_TD;
+}
+
 static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,
                                             int index, int type,
                                             u64 cpu_addr, u64 pci_addr,
@@ -248,6 +289,8 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, u8 func_no,
        val = type | PCIE_ATU_FUNC_NUM(func_no);
        val = upper_32_bits(size - 1) ?
                val | PCIE_ATU_INCREASE_REGION_SIZE : val;
+       if (pci->version == 0x490A)
+               val = dw_pcie_enable_ecrc(val);
        dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, val);
        dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
                                 PCIE_ATU_ENABLE);
@@ -273,7 +316,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
 {
        u32 retries, val;
 
-       if (pci->ops->cpu_addr_fixup)
+       if (pci->ops && pci->ops->cpu_addr_fixup)
                cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
 
        if (pci->iatu_unroll_enabled) {
@@ -290,12 +333,19 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no,
                           upper_32_bits(cpu_addr));
        dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
                           lower_32_bits(cpu_addr + size - 1));
+       if (pci->version >= 0x460A)
+               dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_LIMIT,
+                                  upper_32_bits(cpu_addr + size - 1));
        dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
                           lower_32_bits(pci_addr));
        dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
                           upper_32_bits(pci_addr));
-       dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type |
-                          PCIE_ATU_FUNC_NUM(func_no));
+       val = type | PCIE_ATU_FUNC_NUM(func_no);
+       val = ((upper_32_bits(size - 1)) && (pci->version >= 0x460A)) ?
+               val | PCIE_ATU_INCREASE_REGION_SIZE : val;
+       if (pci->version == 0x490A)
+               val = dw_pcie_enable_ecrc(val);
+       dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, val);
        dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
 
        /*
@@ -321,7 +371,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
 
 void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
                                  int type, u64 cpu_addr, u64 pci_addr,
-                                 u32 size)
+                                 u64 size)
 {
        __dw_pcie_prog_outbound_atu(pci, func_no, index, type,
                                    cpu_addr, pci_addr, size);
@@ -481,7 +531,7 @@ int dw_pcie_link_up(struct dw_pcie *pci)
 {
        u32 val;
 
-       if (pci->ops->link_up)
+       if (pci->ops && pci->ops->link_up)
                return pci->ops->link_up(pci);
 
        val = readl(pci->dbi_base + PCIE_PORT_DEBUG1);
index 0207840756c47fc0fae42175b3729df0f2afde38..7247c8b01f048f208c4ce88626a40a275a0d0934 100644 (file)
@@ -86,6 +86,7 @@
 #define PCIE_ATU_TYPE_IO               0x2
 #define PCIE_ATU_TYPE_CFG0             0x4
 #define PCIE_ATU_TYPE_CFG1             0x5
+#define PCIE_ATU_TD                    BIT(8)
 #define PCIE_ATU_FUNC_NUM(pf)           ((pf) << 20)
 #define PCIE_ATU_CR2                   0x908
 #define PCIE_ATU_ENABLE                        BIT(31)
 #define PCIE_ATU_DEV(x)                        FIELD_PREP(GENMASK(23, 19), x)
 #define PCIE_ATU_FUNC(x)               FIELD_PREP(GENMASK(18, 16), x)
 #define PCIE_ATU_UPPER_TARGET          0x91C
+#define PCIE_ATU_UPPER_LIMIT           0x924
 
 #define PCIE_MISC_CONTROL_1_OFF                0x8BC
 #define PCIE_DBI_RO_WR_EN              BIT(0)
@@ -297,7 +299,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
                               u64 size);
 void dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index,
                                  int type, u64 cpu_addr, u64 pci_addr,
-                                 u32 size);
+                                 u64 size);
 int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index,
                             int bar, u64 cpu_addr,
                             enum dw_pcie_as_type as_type);
index d41257f43a8f30627a33ef19a88fa5f10a79102c..0d21c83bc3be4c34c2828c899010f4ef7da1fccf 100644 (file)
@@ -97,6 +97,7 @@
 
 #define PCIE_MISC_REVISION                             0x406c
 #define  BRCM_PCIE_HW_REV_33                           0x0303
+#define  BRCM_PCIE_HW_REV_3_20                         0x0320
 
 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT               0x4070
 #define  PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK   0xfff00000
 struct brcm_pcie;
 static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val);
+static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val);
 
@@ -203,6 +205,7 @@ enum {
 
 enum pcie_type {
        GENERIC,
+       BCM4908,
        BCM7278,
        BCM2711,
 };
@@ -227,6 +230,13 @@ static const struct pcie_cfg_data generic_cfg = {
        .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,
 };
 
+static const struct pcie_cfg_data bcm4908_cfg = {
+       .offsets        = pcie_offsets,
+       .type           = BCM4908,
+       .perst_set      = brcm_pcie_perst_set_4908,
+       .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,
+};
+
 static const int pcie_offset_bcm7278[] = {
        [RGR1_SW_INIT_1] = 0xc010,
        [EXT_CFG_INDEX] = 0x9000,
@@ -279,6 +289,7 @@ struct brcm_pcie {
        const int               *reg_offsets;
        enum pcie_type          type;
        struct reset_control    *rescal;
+       struct reset_control    *perst_reset;
        int                     num_memc;
        u64                     memc_size[PCIE_BRCM_MAX_MEMC];
        u32                     hw_rev;
@@ -735,6 +746,17 @@ static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32
        writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie));
 }
 
+static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val)
+{
+       if (WARN_ONCE(!pcie->perst_reset, "missing PERST# reset controller\n"))
+               return;
+
+       if (val)
+               reset_control_assert(pcie->perst_reset);
+       else
+               reset_control_deassert(pcie->perst_reset);
+}
+
 static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val)
 {
        u32 tmp;
@@ -1194,6 +1216,7 @@ static int brcm_pcie_remove(struct platform_device *pdev)
 
 static const struct of_device_id brcm_pcie_match[] = {
        { .compatible = "brcm,bcm2711-pcie", .data = &bcm2711_cfg },
+       { .compatible = "brcm,bcm4908-pcie", .data = &bcm4908_cfg },
        { .compatible = "brcm,bcm7211-pcie", .data = &generic_cfg },
        { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg },
        { .compatible = "brcm,bcm7216-pcie", .data = &bcm7278_cfg },
@@ -1250,6 +1273,11 @@ static int brcm_pcie_probe(struct platform_device *pdev)
                clk_disable_unprepare(pcie->clk);
                return PTR_ERR(pcie->rescal);
        }
+       pcie->perst_reset = devm_reset_control_get_optional_exclusive(&pdev->dev, "perst");
+       if (IS_ERR(pcie->perst_reset)) {
+               clk_disable_unprepare(pcie->clk);
+               return PTR_ERR(pcie->perst_reset);
+       }
 
        ret = reset_control_deassert(pcie->rescal);
        if (ret)
@@ -1267,6 +1295,10 @@ static int brcm_pcie_probe(struct platform_device *pdev)
                goto fail;
 
        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");
+               goto fail;
+       }
 
        msi_np = of_parse_phandle(pcie->np, "msi-parent", 0);
        if (pci_msi_enabled() && msi_np == pcie->np) {
index a2094c07af6a3b1d4b5d091e2b0b2ad14e832a42..a74b274a8c458a0881fdd072b428f255ca5bac18 100644 (file)
@@ -176,9 +176,6 @@ int acpiphp_unregister_attention(struct acpiphp_attention_info *info);
 int acpiphp_register_hotplug_slot(struct acpiphp_slot *slot, unsigned int sun);
 void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
 
-/* acpiphp_glue.c */
-typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
-
 int acpiphp_enable_slot(struct acpiphp_slot *slot);
 int acpiphp_disable_slot(struct acpiphp_slot *slot);
 u8 acpiphp_get_power_status(struct acpiphp_slot *slot);
index 139869d50eb2657a37a26e7f78e25c7c82c113a5..fdaf86a888b73771eddd1704323a8fa9eb4a0399 100644 (file)
@@ -21,8 +21,9 @@
 #include "pci-bridge-emul.h"
 
 #define PCI_BRIDGE_CONF_END    PCI_STD_HEADER_SIZEOF
+#define PCI_CAP_PCIE_SIZEOF    (PCI_EXP_SLTSTA2 + 2)
 #define PCI_CAP_PCIE_START     PCI_BRIDGE_CONF_END
-#define PCI_CAP_PCIE_END       (PCI_CAP_PCIE_START + PCI_EXP_SLTSTA2 + 2)
+#define PCI_CAP_PCIE_END       (PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF)
 
 /**
  * struct pci_bridge_reg_behavior - register bits behaviors
@@ -46,7 +47,8 @@ struct pci_bridge_reg_behavior {
        u32 w1c;
 };
 
-static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
+static const
+struct pci_bridge_reg_behavior pci_regs_behavior[PCI_STD_HEADER_SIZEOF / 4] = {
        [PCI_VENDOR_ID / 4] = { .ro = ~0 },
        [PCI_COMMAND / 4] = {
                .rw = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
@@ -164,7 +166,8 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
        },
 };
 
-static const struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = {
+static const
+struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] = {
        [PCI_CAP_LIST_ID / 4] = {
                /*
                 * Capability ID, Next Capability Pointer and
@@ -260,6 +263,8 @@ static const struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = {
 int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
                         unsigned int flags)
 {
+       BUILD_BUG_ON(sizeof(bridge->conf) != PCI_BRIDGE_CONF_END);
+
        bridge->conf.class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16);
        bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
        bridge->conf.cache_line_size = 0x10;
index b9fecc25d21316f8d7c1076d2d126305c58db82c..50b55a1e3d766883f19cb8e7dc33984c269f58b6 100644 (file)
@@ -4029,6 +4029,10 @@ int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
        ret = logic_pio_register_range(range);
        if (ret)
                kfree(range);
+
+       /* Ignore duplicates due to deferred probing */
+       if (ret == -EEXIST)
+               ret = 0;
 #endif
 
        return ret;
index 3946555a60422b1a665c9ce7034ff05a00e296cf..45a2ef702b45b500f974cfd45ab915068e9e24c5 100644 (file)
@@ -133,14 +133,6 @@ config PCIE_PTM
          This is only useful if you have devices that support PTM, but it
          is safe to enable even if you don't.
 
-config PCIE_BW
-       bool "PCI Express Bandwidth Change Notification"
-       depends on PCIEPORTBUS
-       help
-         This enables PCI Express Bandwidth Change Notification.  If
-         you know link width or rate changes occur only to correct
-         unreliable links, you may answer Y.
-
 config PCIE_EDR
        bool "PCI Express Error Disconnect Recover support"
        depends on PCIE_DPC && ACPI
index d9697892fa3e9380b0d925b6255abce22c6a6414..b2980db88cc0926648eec25e82063280b1575953 100644 (file)
@@ -12,5 +12,4 @@ obj-$(CONFIG_PCIEAER_INJECT)  += aer_inject.o
 obj-$(CONFIG_PCIE_PME)         += pme.o
 obj-$(CONFIG_PCIE_DPC)         += dpc.o
 obj-$(CONFIG_PCIE_PTM)         += ptm.o
-obj-$(CONFIG_PCIE_BW)          += bw_notification.o
 obj-$(CONFIG_PCIE_EDR)         += edr.o
index 77b0f2c45bc0e06004984b84f529b261e076ab27..ba22388342d1dfdb28d49b9a157cbc0ad51d525b 100644 (file)
@@ -1388,7 +1388,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
        if (type == PCI_EXP_TYPE_RC_END)
                root = dev->rcec;
        else
-               root = dev;
+               root = pcie_find_root_port(dev);
 
        /*
         * If the platform retained control of AER, an RCiEP may not have
@@ -1414,7 +1414,8 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
                }
        } else {
                rc = pci_bus_error_reset(dev);
-               pci_info(dev, "Root Port link has been reset (%d)\n", rc);
+               pci_info(dev, "%s Port link has been reset (%d)\n",
+                       pci_is_root_bus(dev->bus) ? "Root" : "Downstream", rc);
        }
 
        if ((host->native_aer || pcie_ports_native) && aer) {
diff --git a/drivers/pci/pcie/bw_notification.c b/drivers/pci/pcie/bw_notification.c
deleted file mode 100644 (file)
index 565d23c..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * PCI Express Link Bandwidth Notification services driver
- * Author: Alexandru Gagniuc <mr.nuke.me@gmail.com>
- *
- * Copyright (C) 2019, Dell Inc
- *
- * The PCIe Link Bandwidth Notification provides a way to notify the
- * operating system when the link width or data rate changes.  This
- * capability is required for all root ports and downstream ports
- * supporting links wider than x1 and/or multiple link speeds.
- *
- * This service port driver hooks into the bandwidth notification interrupt
- * and warns when links become degraded in operation.
- */
-
-#define dev_fmt(fmt) "bw_notification: " fmt
-
-#include "../pci.h"
-#include "portdrv.h"
-
-static bool pcie_link_bandwidth_notification_supported(struct pci_dev *dev)
-{
-       int ret;
-       u32 lnk_cap;
-
-       ret = pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnk_cap);
-       return (ret == PCIBIOS_SUCCESSFUL) && (lnk_cap & PCI_EXP_LNKCAP_LBNC);
-}
-
-static void pcie_enable_link_bandwidth_notification(struct pci_dev *dev)
-{
-       u16 lnk_ctl;
-
-       pcie_capability_write_word(dev, PCI_EXP_LNKSTA, PCI_EXP_LNKSTA_LBMS);
-
-       pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &lnk_ctl);
-       lnk_ctl |= PCI_EXP_LNKCTL_LBMIE;
-       pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl);
-}
-
-static void pcie_disable_link_bandwidth_notification(struct pci_dev *dev)
-{
-       u16 lnk_ctl;
-
-       pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &lnk_ctl);
-       lnk_ctl &= ~PCI_EXP_LNKCTL_LBMIE;
-       pcie_capability_write_word(dev, PCI_EXP_LNKCTL, lnk_ctl);
-}
-
-static irqreturn_t pcie_bw_notification_irq(int irq, void *context)
-{
-       struct pcie_device *srv = context;
-       struct pci_dev *port = srv->port;
-       u16 link_status, events;
-       int ret;
-
-       ret = pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status);
-       events = link_status & PCI_EXP_LNKSTA_LBMS;
-
-       if (ret != PCIBIOS_SUCCESSFUL || !events)
-               return IRQ_NONE;
-
-       pcie_capability_write_word(port, PCI_EXP_LNKSTA, events);
-       pcie_update_link_speed(port->subordinate, link_status);
-       return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t pcie_bw_notification_handler(int irq, void *context)
-{
-       struct pcie_device *srv = context;
-       struct pci_dev *port = srv->port;
-       struct pci_dev *dev;
-
-       /*
-        * Print status from downstream devices, not this root port or
-        * downstream switch port.
-        */
-       down_read(&pci_bus_sem);
-       list_for_each_entry(dev, &port->subordinate->devices, bus_list)
-               pcie_report_downtraining(dev);
-       up_read(&pci_bus_sem);
-
-       return IRQ_HANDLED;
-}
-
-static int pcie_bandwidth_notification_probe(struct pcie_device *srv)
-{
-       int ret;
-
-       /* Single-width or single-speed ports do not have to support this. */
-       if (!pcie_link_bandwidth_notification_supported(srv->port))
-               return -ENODEV;
-
-       ret = request_threaded_irq(srv->irq, pcie_bw_notification_irq,
-                                  pcie_bw_notification_handler,
-                                  IRQF_SHARED, "PCIe BW notif", srv);
-       if (ret)
-               return ret;
-
-       pcie_enable_link_bandwidth_notification(srv->port);
-       pci_info(srv->port, "enabled with IRQ %d\n", srv->irq);
-
-       return 0;
-}
-
-static void pcie_bandwidth_notification_remove(struct pcie_device *srv)
-{
-       pcie_disable_link_bandwidth_notification(srv->port);
-       free_irq(srv->irq, srv);
-}
-
-static int pcie_bandwidth_notification_suspend(struct pcie_device *srv)
-{
-       pcie_disable_link_bandwidth_notification(srv->port);
-       return 0;
-}
-
-static int pcie_bandwidth_notification_resume(struct pcie_device *srv)
-{
-       pcie_enable_link_bandwidth_notification(srv->port);
-       return 0;
-}
-
-static struct pcie_port_service_driver pcie_bandwidth_notification_driver = {
-       .name           = "pcie_bw_notification",
-       .port_type      = PCIE_ANY_PORT,
-       .service        = PCIE_PORT_SERVICE_BWNOTIF,
-       .probe          = pcie_bandwidth_notification_probe,
-       .suspend        = pcie_bandwidth_notification_suspend,
-       .resume         = pcie_bandwidth_notification_resume,
-       .remove         = pcie_bandwidth_notification_remove,
-};
-
-int __init pcie_bandwidth_notification_init(void)
-{
-       return pcie_port_service_register(&pcie_bandwidth_notification_driver);
-}
index 510f31f0ef6d04c7dc18fe8fd2374a9af820e745..b576aa890c76ba2a486a809a39f5ed5c0a351f38 100644 (file)
@@ -198,8 +198,7 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
        pci_dbg(bridge, "broadcast error_detected message\n");
        if (state == pci_channel_io_frozen) {
                pci_walk_bridge(bridge, report_frozen_detected, &status);
-               status = reset_subordinates(bridge);
-               if (status != PCI_ERS_RESULT_RECOVERED) {
+               if (reset_subordinates(bridge) != PCI_ERS_RESULT_RECOVERED) {
                        pci_warn(bridge, "subordinate device reset failed\n");
                        goto failed;
                }
@@ -231,15 +230,14 @@ pci_ers_result_t pcie_do_recovery(struct pci_dev *dev,
        pci_walk_bridge(bridge, report_resume, &status);
 
        /*
-        * If we have native control of AER, clear error status in the Root
-        * Port or Downstream Port that signaled the error.  If the
-        * platform retained control of AER, it is responsible for clearing
-        * this status.  In that case, the signaling device may not even be
-        * visible to the OS.
+        * If we have native control of AER, clear error status in the device
+        * that detected the error.  If the platform retained control of AER,
+        * it is responsible for clearing this status.  In that case, the
+        * signaling device may not even be visible to the OS.
         */
        if (host->native_aer || pcie_ports_native) {
-               pcie_clear_device_status(bridge);
-               pci_aer_clear_nonfatal_status(bridge);
+               pcie_clear_device_status(dev);
+               pci_aer_clear_nonfatal_status(dev);
        }
        pci_info(bridge, "device recovery successful\n");
        return status;
index af7cf237432aca71c45bb4ce412e311872551817..2ff5724b8f13f06aed1d879d6286944679d9a568 100644 (file)
@@ -53,12 +53,6 @@ int pcie_dpc_init(void);
 static inline int pcie_dpc_init(void) { return 0; }
 #endif
 
-#ifdef CONFIG_PCIE_BW
-int pcie_bandwidth_notification_init(void);
-#else
-static inline int pcie_bandwidth_notification_init(void) { return 0; }
-#endif
-
 /* Port Type */
 #define PCIE_ANY_PORT                  (~0)
 
index 0b250bc5f40507e16fe8f02af583ca721142272e..c7ff1eea225abe8a53f8bdea6398ea715d8d187d 100644 (file)
@@ -153,7 +153,8 @@ static void pcie_portdrv_remove(struct pci_dev *dev)
 static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
                                        pci_channel_state_t error)
 {
-       /* Root Port has no impact. Always recovers. */
+       if (error == pci_channel_io_frozen)
+               return PCI_ERS_RESULT_NEED_RESET;
        return PCI_ERS_RESULT_CAN_RECOVER;
 }
 
@@ -255,7 +256,6 @@ static void __init pcie_init_services(void)
        pcie_pme_init();
        pcie_dpc_init();
        pcie_hp_init();
-       pcie_bandwidth_notification_init();
 }
 
 static int __init pcie_portdrv_init(void)
index 2061672954ee3cc9dac6a588f8056f775de3997d..b4c138a6ec025db184f12b1c5ff91a204a13361e 100644 (file)
@@ -168,7 +168,6 @@ struct pci_bus *pci_find_next_bus(const struct pci_bus *from)
        struct list_head *n;
        struct pci_bus *b = NULL;
 
-       WARN_ON(in_interrupt());
        down_read(&pci_bus_sem);
        n = from ? from->node.next : pci_root_buses.next;
        if (n != &pci_root_buses)
@@ -196,7 +195,6 @@ struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn)
 {
        struct pci_dev *dev;
 
-       WARN_ON(in_interrupt());
        down_read(&pci_bus_sem);
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -274,7 +272,6 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
        struct device *dev_start = NULL;
        struct pci_dev *pdev = NULL;
 
-       WARN_ON(in_interrupt());
        if (from)
                dev_start = &from->dev;
        dev = bus_find_device(&pci_bus_type, dev_start, (void *)id,
@@ -381,7 +378,6 @@ int pci_dev_present(const struct pci_device_id *ids)
 {
        struct pci_dev *found = NULL;
 
-       WARN_ON(in_interrupt());
        while (ids->vendor || ids->subvendor || ids->class_mask) {
                found = pci_get_dev_by_id(ids, NULL);
                if (found) {
index 43eda101fcf407ca30ddb04681ab059faa1b1581..7f1acb3918d0c3c8e5304a6848a22ffd02886257 100644 (file)
@@ -410,10 +410,16 @@ EXPORT_SYMBOL(pci_release_resource);
 int pci_resize_resource(struct pci_dev *dev, int resno, int size)
 {
        struct resource *res = dev->resource + resno;
+       struct pci_host_bridge *host;
        int old, ret;
        u32 sizes;
        u16 cmd;
 
+       /* Check if we must preserve the firmware's resource assignment */
+       host = pci_find_host_bridge(dev->bus);
+       if (host->preserve_config)
+               return -ENOTSUPP;
+
        /* Make sure the resource isn't assigned before resizing it. */
        if (!(res->flags & IORESOURCE_UNSET))
                return -EBUSY;
index 31e39558d49d81e98b48a62d57f4563e5ae9a213..8b003c890b87b02389e4659ff08fbd9569fad96e 100644 (file)
@@ -20,7 +20,7 @@ SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn,
        u16 word;
        u32 dword;
        long err;
-       long cfg_ret;
+       int cfg_ret;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
@@ -46,7 +46,7 @@ SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn,
        }
 
        err = -EIO;
-       if (cfg_ret != PCIBIOS_SUCCESSFUL)
+       if (cfg_ret)
                goto error;
 
        switch (len) {
@@ -105,7 +105,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
                if (err)
                        break;
                err = pci_user_write_config_byte(dev, off, byte);
-               if (err != PCIBIOS_SUCCESSFUL)
+               if (err)
                        err = -EIO;
                break;
 
@@ -114,7 +114,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
                if (err)
                        break;
                err = pci_user_write_config_word(dev, off, word);
-               if (err != PCIBIOS_SUCCESSFUL)
+               if (err)
                        err = -EIO;
                break;
 
@@ -123,7 +123,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
                if (err)
                        break;
                err = pci_user_write_config_dword(dev, off, dword);
-               if (err != PCIBIOS_SUCCESSFUL)
+               if (err)
                        err = -EIO;
                break;
 
index 053bf05fb1f7606e23fb7949c8f0132a82a9c10e..4703daafcce9e0140daeabf89ebb53a7d3545f85 100644 (file)
@@ -581,9 +581,6 @@ extern bool osc_pc_lpi_support_confirmed;
 #define ACPI_GSB_ACCESS_ATTRIB_RAW_BYTES       0x0000000E
 #define ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS     0x0000000F
 
-extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
-                                            u32 *mask, u32 req);
-
 /* Enable _OST when all relevant hotplug operations are enabled */
 #if defined(CONFIG_ACPI_HOTPLUG_CPU) &&                        \
        defined(CONFIG_ACPI_HOTPLUG_MEMORY) &&          \
index d8156a5dbee84b36e1e583aba8f77bcabff6cdb7..aae07d512ca65b478d90960d759a11dbeab1089c 100644 (file)
 
 #define PCI_VENDOR_ID_REDHAT           0x1b36
 
+#define PCI_VENDOR_ID_SILICOM_DENMARK  0x1c2c
+
 #define PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS    0x1c36
 
 #define PCI_VENDOR_ID_CIRCUITCO                0x1cc8
index f32fe481b4922bc1329b6e12e90ece534214d120..07b4b9a1f54b6bf5ead2ee0fc2f4aa40c460ea2c 100644 (file)
@@ -28,6 +28,8 @@ static DEFINE_MUTEX(io_range_mutex);
  * @new_range: pointer to the IO range to be registered.
  *
  * Returns 0 on success, the error code in case of failure.
+ * If the range already exists, -EEXIST will be returned, which should be
+ * considered a success.
  *
  * Register a new IO range node in the IO range list.
  */
@@ -51,6 +53,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
        list_for_each_entry(range, &io_range_list, list) {
                if (range->fwnode == new_range->fwnode) {
                        /* range already there */
+                       ret = -EEXIST;
                        goto end_register;
                }
                if (range->flags == LOGIC_PIO_CPU_MMIO &&