Merge branches 'pci/host-aardvark', 'pci/host-altera', 'pci/host-artpec', 'pci/host...
authorBjorn Helgaas <bhelgaas@google.com>
Wed, 5 Oct 2016 18:59:14 +0000 (13:59 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 5 Oct 2016 18:59:14 +0000 (13:59 -0500)
* pci/host-aardvark:
  PCI: aardvark: Remove redundant dev_err call in advk_pcie_probe()

* pci/host-altera:
  PCI: altera: Remove redundant platform_get_resource() return value check
  PCI: altera: Move retrain from fixup to altera_pcie_host_init()
  PCI: altera: Rework config accessors for use without a struct pci_bus
  PCI: altera: Poll for link training status after retraining the link

* pci/host-artpec:
  PCI: artpec6: Drop __init from artpec6_add_pcie_port()

* pci/host-designware:
  PCI: designware: Remove redundant platform_get_resource() return value check
  PCI: designware: Exchange viewport of `MEMORYs' and `CFGs/IOs'
  PCI: designware: Keep viewport fixed for IO transaction if num_viewport > 2
  PCI: designware: Check LTSSM training bit before deciding link is up
  PCI: designware: Add iATU Unroll feature
  PCI: designware: Wait for iATU enable
  PCI: designware: Move link wait definitions to .c file
  PCI: designware: Return data directly from dw_pcie_readl_rc()

* pci/host-hv:
  PCI: hv: Handle hv_pci_generic_compl() error case
  PCI: hv: Handle vmbus_sendpacket() failure in hv_compose_msi_msg()
  PCI: hv: Remove the unused 'wrk' in struct hv_pcibus_device
  PCI: hv: Use pci_function_description[0] in struct definitions
  PCI: hv: Use zero-length array in struct pci_packet
  PCI: hv: Use list_move_tail() instead of list_del() + list_add_tail()

* pci/host-keystone:
  PCI: keystone: Propagate request_irq() failure

* pci/host-rcar:
  PCI: rcar: Try increasing PCIe link speed to 5 GT/s at boot
  PCI: rcar: Fix some checkpatch warnings
  PCI: rcar: Add multi-MSI support
  PCI: rcar: Don't disable/unprepare clocks on prepare/enable failure
  PCI: rcar: Consolidate register space lookup and ioremap

* pci/host-rockchip:
  PCI: rockchip: Fix wrong transmitted FTS count
  PCI: rockchip: Improve the deassert sequence of four reset pins
  PCI: rockchip: Increase the Max Credit update interval
  PCI: rockchip: Add Rockchip PCIe controller support
  dt-bindings: PCI: rockchip: Add DT bindings for Rockchip PCIe controller

* pci/host-tegra:
  PCI: tegra: Use of_device_get_match_data()
  PCI: tegra: Remove redundant _data suffix

* pci/host-xilinx:
  microblaze/PCI: Add multidomain support for procfs
  PCI: xilinx: Dispose of MSI virtual IRQ
  PCI: xilinx: Clear correct MSI set bit
  PCI: xilinx: Clear interrupt register for invalid interrupt
  PCI: xilinx: Keep both legacy and MSI interrupt domain references
  PCI: xilinx-nwl: Enable all MSI interrupts using MSI mask
  PCI: xilinx-nwl: Expand error logging

Conflicts:
drivers/pci/host/pcie-xilinx.c

1  2  3  4  5  6  7  8  9  10  11 
drivers/pci/host/pci-aardvark.c
drivers/pci/host/pci-exynos.c
drivers/pci/host/pci-tegra.c
drivers/pci/host/pcie-altera-msi.c
drivers/pci/host/pcie-altera.c
drivers/pci/host/pcie-designware.c
drivers/pci/host/pcie-rcar.c
drivers/pci/host/pcie-xilinx-nwl.c
drivers/pci/host/pcie-xilinx.c

@@@@@@@@@@@@ -848,7 -848,7 -848,7 -848,7 -848,7 -848,7 -848,7 -848,7 -848,7 -848,7 -848,7 +848,7 @@@@@@@@@@@@ static int advk_pcie_parse_request_of_p
                int err, res_valid = 0;
                struct device *dev = &pcie->pdev->dev;
                struct device_node *np = dev->of_node;
 ----------     struct resource_entry *win;
 ++++++++++     struct resource_entry *win, *tmp;
                resource_size_t iobase;
           
                INIT_LIST_HEAD(&pcie->resources);
                if (err)
                        goto out_release_res;
           
 ----------     resource_list_for_each_entry(win, &pcie->resources) {
 ++++++++++     resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
                        struct resource *res = win->res;
           
                        switch (resource_type(res)) {
                                                     lower_32_bits(res->start),
                                                     OB_PCIE_IO);
                                err = pci_remap_iospace(res, iobase);
 ----------                     if (err)
 ++++++++++                     if (err) {
                                        dev_warn(dev, "error %d: failed to map resource %pR\n",
                                                 err, res);
 ++++++++++                             resource_list_destroy_entry(win);
 ++++++++++                     }
                                break;
                        case IORESOURCE_MEM:
                                advk_pcie_set_ob_win(pcie, 0,
@@@@@@@@@@@@ -927,10 -925,8 -925,10 -925,10 -925,10 -925,10 -925,10 -925,10 -925,10 -925,10 -925,10 +927,8 @@@@@@@@@@@@ static int advk_pcie_probe(struct platf
           
                res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                pcie->base = devm_ioremap_resource(&pdev->dev, res);
- ---------     if (IS_ERR(pcie->base)) {
- ---------             dev_err(&pdev->dev, "Failed to map registers\n");
+ +++++++++     if (IS_ERR(pcie->base))
                        return PTR_ERR(pcie->base);
- ---------     }
           
                irq = platform_get_irq(pdev, 0);
                ret = devm_request_irq(&pdev->dev, irq, advk_pcie_irq_handler,
           #include <linux/gpio.h>
           #include <linux/interrupt.h>
           #include <linux/kernel.h>
 ----------#include <linux/module.h>
 ++++++++++#include <linux/init.h>
           #include <linux/of_gpio.h>
           #include <linux/pci.h>
           #include <linux/platform_device.h>
@@@@@@@@@@@@ -425,12 -425,12 -425,12 -425,12 -425,15 -425,12 -425,12 -425,12 -425,12 -425,12 -425,12 +425,15 @@@@@@@@@@@@ static void exynos_pcie_enable_interrup
                        exynos_pcie_msi_init(pp);
           }
           
---- ------static inline void exynos_pcie_readl_rc(struct pcie_port *pp,
---- ------                                     void __iomem *dbi_base, u32 *val)
++++ ++++++static inline u32 exynos_pcie_readl_rc(struct pcie_port *pp,
++++ ++++++                                    void __iomem *dbi_base)
           {
++++ ++++++     u32 val;
++++ ++++++
                exynos_pcie_sideband_dbi_r_mode(pp, true);
---- ------     *val = readl(dbi_base);
++++ ++++++     val = readl(dbi_base);
                exynos_pcie_sideband_dbi_r_mode(pp, false);
++++ ++++++     return val;
           }
           
           static inline void exynos_pcie_writel_rc(struct pcie_port *pp,
@@@@@@@@@@@@ -624,6 -624,7 -624,7 -624,7 -627,7 -624,7 -624,7 -624,7 -624,7 -624,7 -624,7 +627,6 @@@@@@@@@@@@ static const struct of_device_id exynos
                { .compatible = "samsung,exynos5440-pcie", },
                {},
           };
 ----------MODULE_DEVICE_TABLE(of, exynos_pcie_of_match);
           
           static struct platform_driver exynos_pcie_driver = {
                .remove         = __exit_p(exynos_pcie_remove),
@@@@@@@@@@@@ -640,3 -641,7 -641,7 -641,7 -644,7 -641,7 -641,7 -641,7 -641,7 -641,7 -641,7 +643,3 @@@@@@@@@@@@ static int __init exynos_pcie_init(void
                return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe);
           }
           subsys_initcall(exynos_pcie_init);
 ----------
 ----------MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
 ----------MODULE_DESCRIPTION("Samsung PCIe host controller driver");
 ----------MODULE_LICENSE("GPL v2");
@@@@@@@@@@@@ -240,7 -240,7 -240,7 -240,7 -240,7 -240,7 -240,7 -240,7 -240,7 -240,7 -240,7 +240,7 @@@@@@@@@@@@ struct tegra_msi 
           };
           
           /* used to differentiate between Tegra SoC generations */
--------- -struct tegra_pcie_soc_data {
+++++++++ +struct tegra_pcie_soc {
                unsigned int num_ports;
                unsigned int msi_base_shift;
                u32 pads_pll_ctl;
@@@@@@@@@@@@ -300,7 -300,7 -300,7 -300,7 -300,7 -300,7 -300,7 -300,7 -300,7 -300,7 -300,7 +300,7 @@@@@@@@@@@@ struct tegra_pcie 
                struct regulator_bulk_data *supplies;
                unsigned int num_supplies;
           
--------- -     const struct tegra_pcie_soc_data *soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc;
                struct dentry *debugfs;
           };
           
@@@@@@@@@@@@ -542,8 -542,8 -542,8 -542,8 -542,8 -542,8 -542,8 -542,8 -542,8 -542,8 -542,8 +542,8 @@@@@@@@@@@@ static void tegra_pcie_port_reset(struc
           
           static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
           {
--------- -     const struct tegra_pcie_soc_data *soc = port->pcie->soc_data;
                unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+++++++++ +     const struct tegra_pcie_soc *soc = port->pcie->soc;
                unsigned long value;
           
                /* enable reference clock */
           
           static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
           {
--------- -     const struct tegra_pcie_soc_data *soc = port->pcie->soc_data;
                unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+++++++++ +     const struct tegra_pcie_soc *soc = port->pcie->soc;
                unsigned long value;
           
                /* assert port reset */
@@@@@@@@@@@@ -621,11 -621,7 -621,7 -621,7 -621,7 -621,7 -621,7 -621,7 -621,7 -621,7 -621,7 +621,11 @@@@@@@@@@@@ static int tegra_pcie_setup(int nr, str
                if (err < 0)
                        return err;
           
 ----------     pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
 ++++++++++     err = pci_remap_iospace(&pcie->pio, pcie->io.start);
 ++++++++++     if (!err)
 ++++++++++             pci_add_resource_offset(&sys->resources, &pcie->pio,
 ++++++++++                                     sys->io_offset);
 ++++++++++
                pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
                pci_add_resource_offset(&sys->resources, &pcie->prefetch,
                                        sys->mem_offset);
                if (err < 0)
                        return err;
           
 ----------     pci_remap_iospace(&pcie->pio, pcie->io.start);
                return 1;
           }
           
@@@@@@@@@@@@ -777,7 -774,7 -774,7 -774,7 -774,7 -774,7 -774,7 -774,7 -774,7 -774,7 -774,7 +777,7 @@@@@@@@@@@@ static void tegra_pcie_setup_translatio
           
           static int tegra_pcie_pll_wait(struct tegra_pcie *pcie, unsigned long timeout)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                u32 value;
           
                timeout = jiffies + msecs_to_jiffies(timeout);
           
           static int tegra_pcie_phy_enable(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                u32 value;
                int err;
           
           
           static int tegra_pcie_phy_disable(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                u32 value;
           
                /* disable TX/RX data */
@@@@@@@@@@@@ -909,7 -906,7 -906,7 -906,7 -906,7 -906,7 -906,7 -906,7 -906,7 -906,7 -906,7 +909,7 @@@@@@@@@@@@ static int tegra_pcie_port_phy_power_of
           
           static int tegra_pcie_phy_power_on(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                struct tegra_pcie_port *port;
                int err;
           
@@@@@@@@@@@@ -977,7 -974,7 -974,7 -974,7 -974,7 -974,7 -974,7 -974,7 -974,7 -974,7 -974,7 +977,7 @@@@@@@@@@@@ static int tegra_pcie_phy_power_off(str
           
           static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                struct tegra_pcie_port *port;
                unsigned long value;
                int err;
@@@@@@@@@@@@ -1070,7 -1067,7 -1067,7 -1067,7 -1067,7 -1067,7 -1067,7 -1067,7 -1067,7 -1067,7 -1067,7 +1070,7 @@@@@@@@@@@@ static void tegra_pcie_power_off(struc
           
           static int tegra_pcie_power_on(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                int err;
           
                reset_control_assert(pcie->pcie_xrst);
           
           static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
           
                pcie->pex_clk = devm_clk_get(pcie->dev, "pex");
                if (IS_ERR(pcie->pex_clk))
@@@@@@@@@@@@ -1237,7 -1234,7 -1234,7 -1234,7 -1234,7 -1234,7 -1234,7 -1234,7 -1234,7 -1234,7 -1234,7 +1237,7 @@@@@@@@@@@@ static int tegra_pcie_port_get_phys(str
           
           static int tegra_pcie_phys_get(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                struct device_node *np = pcie->dev->of_node;
                struct tegra_pcie_port *port;
                int err;
@@@@@@@@@@@@ -1489,7 -1486,7 -1486,7 -1486,7 -1486,7 -1486,7 -1486,7 -1486,7 -1486,7 -1486,7 -1486,7 +1489,7 @@@@@@@@@@@@ static const struct irq_domain_ops msi_
           static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
           {
                struct platform_device *pdev = to_platform_device(pcie->dev);
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                struct tegra_msi *msi = &pcie->msi;
                unsigned long base;
                int err;
@@@@@@@@@@@@ -1802,8 -1799,8 -1799,8 -1799,8 -1799,8 -1799,8 -1799,8 -1799,8 -1799,8 -1799,8 -1799,8 +1802,8 @@@@@@@@@@@@ static int tegra_pcie_get_regulators(st
           
           static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
           {
--------- -     const struct tegra_pcie_soc_data *soc = pcie->soc_data;
                struct device_node *np = pcie->dev->of_node, *port;
+++++++++ +     const struct tegra_pcie_soc *soc = pcie->soc;
                struct of_pci_range_parser parser;
                struct of_pci_range range;
                u32 lanes = 0, mask = 0;
@@@@@@@@@@@@ -2046,7 -2043,7 -2043,7 -2043,7 -2043,7 -2043,7 -2043,7 -2043,7 -2043,7 -2043,7 -2043,7 +2046,7 @@@@@@@@@@@@ static int tegra_pcie_enable(struct teg
                return 0;
           }
           
--------- -static const struct tegra_pcie_soc_data tegra20_pcie_data = {
+++++++++ +static const struct tegra_pcie_soc tegra20_pcie = {
                .num_ports = 2,
                .msi_base_shift = 0,
                .pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
                .has_gen2 = false,
           };
           
--------- -static const struct tegra_pcie_soc_data tegra30_pcie_data = {
+++++++++ +static const struct tegra_pcie_soc tegra30_pcie = {
                .num_ports = 3,
                .msi_base_shift = 8,
                .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
                .has_gen2 = false,
           };
           
--------- -static const struct tegra_pcie_soc_data tegra124_pcie_data = {
+++++++++ +static const struct tegra_pcie_soc tegra124_pcie = {
                .num_ports = 2,
                .msi_base_shift = 8,
                .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
           };
           
           static const struct of_device_id tegra_pcie_of_match[] = {
--------- -     { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie_data },
--------- -     { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie_data },
--------- -     { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie_data },
+++++++++ +     { .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
+++++++++ +     { .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },
+++++++++ +     { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie },
                { },
           };
           
           
           static int tegra_pcie_probe(struct platform_device *pdev)
           {
--------- -     const struct of_device_id *match;
                struct tegra_pcie *pcie;
                int err;
           
--------- -     match = of_match_device(tegra_pcie_of_match, &pdev->dev);
--------- -     if (!match)
--------- -             return -ENODEV;
--------- -
                pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
                if (!pcie)
                        return -ENOMEM;
           
+++++++++ +     pcie->soc = of_device_get_match_data(&pdev->dev);
                INIT_LIST_HEAD(&pcie->buses);
                INIT_LIST_HEAD(&pcie->ports);
--------- -     pcie->soc_data = match->data;
                pcie->dev = &pdev->dev;
           
                err = tegra_pcie_parse_dt(pcie);
@@@@@@@@@@@@ -1,8 -1,4 -1,4 -1,4 -1,4 -1,4 -1,4 -1,4 -1,4 -1,4 -1,4 +1,8 @@@@@@@@@@@@
           /*
 ++++++++++ * Altera PCIe MSI support
 ++++++++++ *
 ++++++++++ * Author: Ley Foon Tan <lftan@altera.com>
 ++++++++++ *
            * Copyright Altera Corporation (C) 2013-2015. All rights reserved
            *
            * This program is free software; you can redistribute it and/or modify it
           
           #include <linux/interrupt.h>
           #include <linux/irqchip/chained_irq.h>
 ----------#include <linux/module.h>
 ++++++++++#include <linux/init.h>
           #include <linux/msi.h>
           #include <linux/of_address.h>
           #include <linux/of_irq.h>
@@@@@@@@@@@@ -241,11 -237,11 -237,6 -237,11 -237,11 -237,11 -237,11 -237,11 -237,11 -237,11 -237,11 +241,6 @@@@@@@@@@@@ static int altera_msi_probe(struct plat
                msi->pdev = pdev;
           
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
-- --------     if (!res) {
-- --------             dev_err(&pdev->dev, "no csr memory resource defined\n");
-- --------             return -ENODEV;
-- --------     }
-- --------
                msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
                if (IS_ERR(msi->csr_base)) {
                        dev_err(&pdev->dev, "failed to map csr memory\n");
           
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                                                   "vector_slave");
-- --------     if (!res) {
-- --------             dev_err(&pdev->dev, "no vector_slave memory resource defined\n");
-- --------             return -ENODEV;
-- --------     }
-- --------
                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");
@@@@@@@@@@@@ -312,3 -308,7 -298,7 -308,7 -308,7 -308,7 -308,7 -308,7 -308,7 -308,7 -308,7 +302,3 @@@@@@@@@@@@ static int __init altera_msi_init(void
                return platform_driver_register(&altera_msi_driver);
           }
           subsys_initcall(altera_msi_init);
 ----------
 ----------MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>");
 ----------MODULE_DESCRIPTION("Altera PCIe MSI support");
 ----------MODULE_LICENSE("GPL v2");
@@@@@@@@@@@@ -1,9 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 -1,6 +1,9 @@@@@@@@@@@@
           /*
            * Copyright Altera Corporation (C) 2013-2015. All rights reserved
            *
 ++++++++++ * Author: Ley Foon Tan <lftan@altera.com>
 ++++++++++ * Description: Altera PCIe host controller driver
 ++++++++++ *
            * This program is free software; you can redistribute it and/or modify it
            * under the terms and conditions of the GNU General Public License,
            * version 2, as published by the Free Software Foundation.
           #include <linux/delay.h>
           #include <linux/interrupt.h>
           #include <linux/irqchip/chained_irq.h>
 ----------#include <linux/module.h>
 ++++++++++#include <linux/init.h>
           #include <linux/of_address.h>
           #include <linux/of_irq.h>
           #include <linux/of_pci.h>
           #define RP_LTSSM_MASK                        0x1f
           #define LTSSM_L0                     0xf
           
++ ++++++++#define PCIE_CAP_OFFSET                      0x80
           /* TLP configuration type 0 and 1 */
           #define TLP_FMTTYPE_CFGRD0           0x04    /* Configuration Read Type 0 */
           #define TLP_FMTTYPE_CFGWR0           0x44    /* Configuration Write Type 0 */
           #define TLP_LOOP                     500
           #define RP_DEVFN                     0
           
-- --------#define LINK_UP_TIMEOUT                      5000
++ ++++++++#define LINK_UP_TIMEOUT                      HZ
++ ++++++++#define LINK_RETRAIN_TIMEOUT         HZ
           
           #define INTX_NUM                     4
           
@@@@@@@@@@@@ -102,38 -99,38 -101,6 -99,38 -99,38 -99,38 -99,38 -99,38 -99,38 -99,38 -99,38 +104,6 @@@@@@@@@@@@ static bool altera_pcie_link_is_up(stru
                return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
           }
           
-- --------static void altera_pcie_retrain(struct pci_dev *dev)
-- --------{
-- --------     u16 linkcap, linkstat;
-- --------     struct altera_pcie *pcie = dev->bus->sysdata;
-- --------     int timeout =  0;
-- --------
-- --------     if (!altera_pcie_link_is_up(pcie))
-- --------             return;
-- --------
-- --------     /*
-- --------      * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
-- --------      * current speed is 2.5 GB/s.
-- --------      */
-- --------     pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
-- --------
-- --------     if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
-- --------             return;
-- --------
-- --------     pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
-- --------     if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
-- --------             pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
-- --------                                      PCI_EXP_LNKCTL_RL);
-- --------             while (!altera_pcie_link_is_up(pcie)) {
-- --------                     timeout++;
-- --------                     if (timeout > LINK_UP_TIMEOUT)
-- --------                             break;
-- --------                     udelay(5);
-- --------             }
-- --------     }
-- --------}
-- --------DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain);
-- --------
           /*
            * Altera PCIe port uses BAR0 of RC's configuration space as the translation
            * from PCI bus to native BUS.  Entire DDR region is mapped into PCIe space
@@@@@@@@@@@@ -174,6 -171,13 -141,13 -171,13 -171,13 -171,13 -171,13 -171,13 -171,13 -171,13 -171,13 +144,6 @@@@@@@@@@@@ static bool altera_pcie_valid_config(st
                if (bus->number == pcie->root_bus_nr && dev > 0)
                        return false;
           
 ----------     /*
 ----------      * Do not read more than one device on the bus directly attached
 ----------      * to root port, root port can only attach to one downstream port.
 ----------      */
 ----------     if (bus->primary == pcie->root_bus_nr && dev > 0)
 ----------             return false;
 ----------
                 return true;
           }
           
@@@@@@@@@@@@ -297,22 -301,22 -271,14 -301,22 -301,22 -301,22 -301,22 -301,22 -301,22 -301,22 -301,22 +267,14 @@@@@@@@@@@@ static int tlp_cfg_dword_write(struct a
                return PCIBIOS_SUCCESSFUL;
           }
           
-- --------static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
-- --------                             int where, int size, u32 *value)
++ ++++++++static int _altera_pcie_cfg_read(struct altera_pcie *pcie, u8 busno,
++ ++++++++                              unsigned int devfn, int where, int size,
++ ++++++++                              u32 *value)
           {
-- --------     struct altera_pcie *pcie = bus->sysdata;
                int ret;
                u32 data;
                u8 byte_en;
           
-- --------     if (altera_pcie_hide_rc_bar(bus, devfn, where))
-- --------             return PCIBIOS_BAD_REGISTER_NUMBER;
-- --------
-- --------     if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
-- --------             *value = 0xffffffff;
-- --------             return PCIBIOS_DEVICE_NOT_FOUND;
-- --------     }
-- --------
                switch (size) {
                case 1:
                        byte_en = 1 << (where & 3);
                        break;
                }
           
-- --------     ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
++ ++++++++     ret = tlp_cfg_dword_read(pcie, busno, devfn,
                                         (where & ~DWORD_MASK), byte_en, &data);
                if (ret != PCIBIOS_SUCCESSFUL)
                        return ret;
                return PCIBIOS_SUCCESSFUL;
           }
           
-- --------static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
-- --------                              int where, int size, u32 value)
++ ++++++++static int _altera_pcie_cfg_write(struct altera_pcie *pcie, u8 busno,
++ ++++++++                               unsigned int devfn, int where, int size,
++ ++++++++                               u32 value)
           {
-- --------     struct altera_pcie *pcie = bus->sysdata;
                u32 data32;
                u32 shift = 8 * (where & 3);
                u8 byte_en;
           
-- --------     if (altera_pcie_hide_rc_bar(bus, devfn, where))
-- --------             return PCIBIOS_BAD_REGISTER_NUMBER;
-- --------
-- --------     if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
-- --------             return PCIBIOS_DEVICE_NOT_FOUND;
-- --------
                switch (size) {
                case 1:
                        data32 = (value & 0xff) << shift;
                        break;
                }
           
-- --------     return tlp_cfg_dword_write(pcie, bus->number, devfn,
-- --------             (where & ~DWORD_MASK), byte_en, data32);
++ ++++++++     return tlp_cfg_dword_write(pcie, busno, devfn, (where & ~DWORD_MASK),
++ ++++++++                                byte_en, data32);
++ ++++++++}
++ ++++++++
++ ++++++++static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
++ ++++++++                             int where, int size, u32 *value)
++ ++++++++{
++ ++++++++     struct altera_pcie *pcie = bus->sysdata;
++ ++++++++
++ ++++++++     if (altera_pcie_hide_rc_bar(bus, devfn, where))
++ ++++++++             return PCIBIOS_BAD_REGISTER_NUMBER;
++ ++++++++
++ ++++++++     if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
++ ++++++++             *value = 0xffffffff;
++ ++++++++             return PCIBIOS_DEVICE_NOT_FOUND;
++ ++++++++     }
++ ++++++++
++ ++++++++     return _altera_pcie_cfg_read(pcie, bus->number, devfn, where, size,
++ ++++++++                                  value);
++ ++++++++}
++ ++++++++
++ ++++++++static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
++ ++++++++                              int where, int size, u32 value)
++ ++++++++{
++ ++++++++     struct altera_pcie *pcie = bus->sysdata;
++ ++++++++
++ ++++++++     if (altera_pcie_hide_rc_bar(bus, devfn, where))
++ ++++++++             return PCIBIOS_BAD_REGISTER_NUMBER;
++ ++++++++
++ ++++++++     if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
++ ++++++++             return PCIBIOS_DEVICE_NOT_FOUND;
++ ++++++++
++ ++++++++     return _altera_pcie_cfg_write(pcie, bus->number, devfn, where, size,
++ ++++++++                                  value);
           }
           
           static struct pci_ops altera_pcie_ops = {
                .write = altera_pcie_cfg_write,
           };
           
++ ++++++++static int altera_read_cap_word(struct altera_pcie *pcie, u8 busno,
++ ++++++++                             unsigned int devfn, int offset, u16 *value)
++ ++++++++{
++ ++++++++     u32 data;
++ ++++++++     int ret;
++ ++++++++
++ ++++++++     ret = _altera_pcie_cfg_read(pcie, busno, devfn,
++ ++++++++                                 PCIE_CAP_OFFSET + offset, sizeof(*value),
++ ++++++++                                 &data);
++ ++++++++     *value = data;
++ ++++++++     return ret;
++ ++++++++}
++ ++++++++
++ ++++++++static int altera_write_cap_word(struct altera_pcie *pcie, u8 busno,
++ ++++++++                              unsigned int devfn, int offset, u16 value)
++ ++++++++{
++ ++++++++     return _altera_pcie_cfg_write(pcie, busno, devfn,
++ ++++++++                                   PCIE_CAP_OFFSET + offset, sizeof(value),
++ ++++++++                                   value);
++ ++++++++}
++ ++++++++
++ ++++++++static void altera_wait_link_retrain(struct altera_pcie *pcie)
++ ++++++++{
++ ++++++++     u16 reg16;
++ ++++++++     unsigned long start_jiffies;
++ ++++++++
++ ++++++++     /* Wait for link training end. */
++ ++++++++     start_jiffies = jiffies;
++ ++++++++     for (;;) {
++ ++++++++             altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
++ ++++++++                                  PCI_EXP_LNKSTA, &reg16);
++ ++++++++             if (!(reg16 & PCI_EXP_LNKSTA_LT))
++ ++++++++                     break;
++ ++++++++
++ ++++++++             if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) {
++ ++++++++                     dev_err(&pcie->pdev->dev, "link retrain timeout\n");
++ ++++++++                     break;
++ ++++++++             }
++ ++++++++             udelay(100);
++ ++++++++     }
++ ++++++++
++ ++++++++     /* Wait for link is up */
++ ++++++++     start_jiffies = jiffies;
++ ++++++++     for (;;) {
++ ++++++++             if (altera_pcie_link_is_up(pcie))
++ ++++++++                     break;
++ ++++++++
++ ++++++++             if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
++ ++++++++                     dev_err(&pcie->pdev->dev, "link up timeout\n");
++ ++++++++                     break;
++ ++++++++             }
++ ++++++++             udelay(100);
++ ++++++++     }
++ ++++++++}
++ ++++++++
++ ++++++++static void altera_pcie_retrain(struct altera_pcie *pcie)
++ ++++++++{
++ ++++++++     u16 linkcap, linkstat, linkctl;
++ ++++++++
++ ++++++++     if (!altera_pcie_link_is_up(pcie))
++ ++++++++             return;
++ ++++++++
++ ++++++++     /*
++ ++++++++      * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
++ ++++++++      * current speed is 2.5 GB/s.
++ ++++++++      */
++ ++++++++     altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKCAP,
++ ++++++++                          &linkcap);
++ ++++++++     if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
++ ++++++++             return;
++ ++++++++
++ ++++++++     altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKSTA,
++ ++++++++                          &linkstat);
++ ++++++++     if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
++ ++++++++             altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
++ ++++++++                                  PCI_EXP_LNKCTL, &linkctl);
++ ++++++++             linkctl |= PCI_EXP_LNKCTL_RL;
++ ++++++++             altera_write_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
++ ++++++++                                   PCI_EXP_LNKCTL, linkctl);
++ ++++++++
++ ++++++++             altera_wait_link_retrain(pcie);
++ ++++++++     }
++ ++++++++}
++ ++++++++
           static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
                                        irq_hw_number_t hwirq)
           {
@@@@@@@@@@@@ -504,6 -508,6 -580,11 -508,6 -508,6 -508,6 -508,6 -508,6 -508,6 -508,6 -508,6 +576,11 @@@@@@@@@@@@ static int altera_pcie_parse_dt(struct 
                return 0;
           }
           
++ ++++++++static void altera_pcie_host_init(struct altera_pcie *pcie)
++ ++++++++{
++ ++++++++     altera_pcie_retrain(pcie);
++ ++++++++}
++ ++++++++
           static int altera_pcie_probe(struct platform_device *pdev)
           {
                struct altera_pcie *pcie;
                cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
                /* enable all interrupts */
                cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
++ ++++++++     altera_pcie_host_init(pcie);
           
                bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
                                        pcie, &pcie->resources);
@@@@@@@@@@@@ -564,6 -568,7 -646,7 -568,7 -568,7 -568,7 -568,7 -568,7 -568,7 -568,7 -568,7 +642,6 @@@@@@@@@@@@ static const struct of_device_id altera
                { .compatible = "altr,pcie-root-port-1.0", },
                {},
           };
 ----------MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
           
           static struct platform_driver altera_pcie_driver = {
                .probe          = altera_pcie_probe,
@@@@@@@@@@@@ -578,4 -583,8 -661,8 -583,8 -583,8 -583,8 -583,8 -583,8 -583,8 -583,8 -583,8 +656,4 @@@@@@@@@@@@ static int altera_pcie_init(void
           {
                return platform_driver_register(&altera_pcie_driver);
           }
 ----------module_init(altera_pcie_init);
 ----------
 ----------MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>");
 ----------MODULE_DESCRIPTION("Altera PCIe host controller driver");
 ----------MODULE_LICENSE("GPL v2");
 ++++++++++device_initcall(altera_pcie_init);
           #include <linux/irq.h>
           #include <linux/irqdomain.h>
           #include <linux/kernel.h>
 ----------#include <linux/module.h>
           #include <linux/msi.h>
           #include <linux/of_address.h>
           #include <linux/of_pci.h>
           
           #include "pcie-designware.h"
           
---- ------/* Synopsis specific PCIE configuration registers */
++++ ++++++/* Parameters for the waiting for link up routine */
++++ ++++++#define LINK_WAIT_MAX_RETRIES                10
++++ ++++++#define LINK_WAIT_USLEEP_MIN         90000
++++ ++++++#define LINK_WAIT_USLEEP_MAX         100000
++++ ++++++
++++ ++++++/* Parameters for the waiting for iATU enabled routine */
++++ ++++++#define LINK_WAIT_MAX_IATU_RETRIES   5
++++ ++++++#define LINK_WAIT_IATU_MIN           9000
++++ ++++++#define LINK_WAIT_IATU_MAX           10000
++++ ++++++
++++ ++++++/* Synopsys-specific PCIe configuration registers */
           #define PCIE_PORT_LINK_CONTROL               0x710
           #define PORT_LINK_MODE_MASK          (0x3f << 16)
           #define PORT_LINK_MODE_1_LANES               (0x1 << 16)
           #define PCIE_ATU_VIEWPORT            0x900
           #define PCIE_ATU_REGION_INBOUND              (0x1 << 31)
           #define PCIE_ATU_REGION_OUTBOUND     (0x0 << 31)
++++ ++++++#define PCIE_ATU_REGION_INDEX2               (0x2 << 0)
           #define PCIE_ATU_REGION_INDEX1               (0x1 << 0)
           #define PCIE_ATU_REGION_INDEX0               (0x0 << 0)
           #define PCIE_ATU_CR1                 0x904
           #define PCIE_ATU_FUNC(x)             (((x) & 0x7) << 16)
           #define PCIE_ATU_UPPER_TARGET                0x91C
           
++++ ++++++/*
++++ ++++++ * iATU Unroll-specific register definitions
++++ ++++++ * From 4.80 core version the address translation will be made by unroll
++++ ++++++ */
++++ ++++++#define PCIE_ATU_UNR_REGION_CTRL1    0x00
++++ ++++++#define PCIE_ATU_UNR_REGION_CTRL2    0x04
++++ ++++++#define PCIE_ATU_UNR_LOWER_BASE              0x08
++++ ++++++#define PCIE_ATU_UNR_UPPER_BASE              0x0C
++++ ++++++#define PCIE_ATU_UNR_LIMIT           0x10
++++ ++++++#define PCIE_ATU_UNR_LOWER_TARGET    0x14
++++ ++++++#define PCIE_ATU_UNR_UPPER_TARGET    0x18
++++ ++++++
++++ ++++++/* Register address builder */
++++ ++++++#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region)  ((0x3 << 20) | (region << 9))
++++ ++++++
           /* PCIe Port Logic registers */
           #define PLR_OFFSET                   0x700
           #define PCIE_PHY_DEBUG_R1            (PLR_OFFSET + 0x2c)
---- ------#define PCIE_PHY_DEBUG_R1_LINK_UP    0x00000010
++++ ++++++#define PCIE_PHY_DEBUG_R1_LINK_UP    (0x1 << 4)
++++ ++++++#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING   (0x1 << 29)
           
           static struct pci_ops dw_pcie_ops;
           
@@@@@@@@@@@@ -114,12 -115,12 -115,12 -115,12 -142,12 -115,12 -115,12 -115,12 -115,12 -115,12 -115,12 +141,12 @@@@@@@@@@@@ int dw_pcie_cfg_write(void __iomem *add
                return PCIBIOS_SUCCESSFUL;
           }
           
---- ------static inline void dw_pcie_readl_rc(struct pcie_port *pp, u32 reg, u32 *val)
++++ ++++++static inline u32 dw_pcie_readl_rc(struct pcie_port *pp, u32 reg)
           {
                if (pp->ops->readl_rc)
---- ------             pp->ops->readl_rc(pp, pp->dbi_base + reg, val);
---- ------     else
---- ------             *val = readl(pp->dbi_base + reg);
++++ ++++++             return pp->ops->readl_rc(pp, pp->dbi_base + reg);
++++ ++++++
++++ ++++++     return readl(pp->dbi_base + reg);
           }
           
           static inline void dw_pcie_writel_rc(struct pcie_port *pp, u32 val, u32 reg)
                        writel(val, pp->dbi_base + reg);
           }
           
++++ ++++++static inline u32 dw_pcie_readl_unroll(struct pcie_port *pp, u32 index, u32 reg)
++++ ++++++{
++++ ++++++     u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
++++ ++++++
++++ ++++++     if (pp->ops->readl_rc)
++++ ++++++             return pp->ops->readl_rc(pp, pp->dbi_base + offset + reg);
++++ ++++++
++++ ++++++     return readl(pp->dbi_base + offset + reg);
++++ ++++++}
++++ ++++++
++++ ++++++static inline void dw_pcie_writel_unroll(struct pcie_port *pp, u32 index,
++++ ++++++                                      u32 val, u32 reg)
++++ ++++++{
++++ ++++++     u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
++++ ++++++
++++ ++++++     if (pp->ops->writel_rc)
++++ ++++++             pp->ops->writel_rc(pp, val, pp->dbi_base + offset + reg);
++++ ++++++     else
++++ ++++++             writel(val, pp->dbi_base + offset + reg);
++++ ++++++}
++++ ++++++
           static int dw_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
                                       u32 *val)
           {
@@@@@@@@@@@@ -151,24 -152,24 -152,24 -152,24 -200,57 -152,24 -152,24 -152,24 -152,24 -152,24 -152,24 +199,57 @@@@@@@@@@@@ static int dw_pcie_wr_own_conf(struct p
           static void dw_pcie_prog_outbound_atu(struct pcie_port *pp, int index,
                        int type, u64 cpu_addr, u64 pci_addr, u32 size)
           {
---- ------     u32 val;
---- ------
---- ------     dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
---- ------                       PCIE_ATU_VIEWPORT);
---- ------     dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr), PCIE_ATU_LOWER_BASE);
---- ------     dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr), PCIE_ATU_UPPER_BASE);
---- ------     dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
---- ------                       PCIE_ATU_LIMIT);
---- ------     dw_pcie_writel_rc(pp, lower_32_bits(pci_addr), PCIE_ATU_LOWER_TARGET);
---- ------     dw_pcie_writel_rc(pp, upper_32_bits(pci_addr), PCIE_ATU_UPPER_TARGET);
---- ------     dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
---- ------     dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
++++ ++++++     u32 retries, val;
++++ ++++++
++++ ++++++     if (pp->iatu_unroll_enabled) {
++++ ++++++             dw_pcie_writel_unroll(pp, index,
++++ ++++++                     lower_32_bits(cpu_addr), PCIE_ATU_UNR_LOWER_BASE);
++++ ++++++             dw_pcie_writel_unroll(pp, index,
++++ ++++++                     upper_32_bits(cpu_addr), PCIE_ATU_UNR_UPPER_BASE);
++++ ++++++             dw_pcie_writel_unroll(pp, index,
++++ ++++++                     lower_32_bits(cpu_addr + size - 1), PCIE_ATU_UNR_LIMIT);
++++ ++++++             dw_pcie_writel_unroll(pp, index,
++++ ++++++                     lower_32_bits(pci_addr), PCIE_ATU_UNR_LOWER_TARGET);
++++ ++++++             dw_pcie_writel_unroll(pp, index,
++++ ++++++                     upper_32_bits(pci_addr), PCIE_ATU_UNR_UPPER_TARGET);
++++ ++++++             dw_pcie_writel_unroll(pp, index,
++++ ++++++                     type, PCIE_ATU_UNR_REGION_CTRL1);
++++ ++++++             dw_pcie_writel_unroll(pp, index,
++++ ++++++                     PCIE_ATU_ENABLE, PCIE_ATU_UNR_REGION_CTRL2);
++++ ++++++     } else {
++++ ++++++             dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | index,
++++ ++++++                                             PCIE_ATU_VIEWPORT);
++++ ++++++             dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr),
++++ ++++++                                             PCIE_ATU_LOWER_BASE);
++++ ++++++             dw_pcie_writel_rc(pp, upper_32_bits(cpu_addr),
++++ ++++++                                             PCIE_ATU_UPPER_BASE);
++++ ++++++             dw_pcie_writel_rc(pp, lower_32_bits(cpu_addr + size - 1),
++++ ++++++                                             PCIE_ATU_LIMIT);
++++ ++++++             dw_pcie_writel_rc(pp, lower_32_bits(pci_addr),
++++ ++++++                                             PCIE_ATU_LOWER_TARGET);
++++ ++++++             dw_pcie_writel_rc(pp, upper_32_bits(pci_addr),
++++ ++++++                                             PCIE_ATU_UPPER_TARGET);
++++ ++++++             dw_pcie_writel_rc(pp, type, PCIE_ATU_CR1);
++++ ++++++             dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
++++ ++++++     }
           
                /*
                 * Make sure ATU enable takes effect before any subsequent config
                 * and I/O accesses.
                 */
---- ------     dw_pcie_readl_rc(pp, PCIE_ATU_CR2, &val);
++++ ++++++     for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
++++ ++++++             if (pp->iatu_unroll_enabled)
++++ ++++++                     val = dw_pcie_readl_unroll(pp, index,
++++ ++++++                                                PCIE_ATU_UNR_REGION_CTRL2);
++++ ++++++             else
++++ ++++++                     val = dw_pcie_readl_rc(pp, PCIE_ATU_CR2);
++++ ++++++
++++ ++++++             if (val == PCIE_ATU_ENABLE)
++++ ++++++                     return;
++++ ++++++
++++ ++++++             usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
++++ ++++++     }
++++ ++++++     dev_err(pp->dev, "iATU is not being enabled\n");
           }
           
           static struct irq_chip dw_msi_irq_chip = {
@@@@@@@@@@@@ -411,7 -412,7 -412,7 -412,7 -493,8 -412,7 -412,7 -412,7 -412,7 -412,7 -412,7 +492,8 @@@@@@@@@@@@ int dw_pcie_link_up(struct pcie_port *p
                        return pp->ops->link_up(pp);
           
                val = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1);
---- ------     return val & PCIE_PHY_DEBUG_R1_LINK_UP;
++++ ++++++     return ((val & PCIE_PHY_DEBUG_R1_LINK_UP) &&
++++ ++++++             (!(val & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING)));
           }
           
           static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
@@@@@@@@@@@@ -427,6 -428,6 -428,6 -428,6 -510,17 -428,6 -428,6 -428,6 -428,6 -428,6 -428,6 +509,17 @@@@@@@@@@@@ static const struct irq_domain_ops msi_
                .map = dw_pcie_msi_map,
           };
           
++++ ++++++static u8 dw_pcie_iatu_unroll_enabled(struct pcie_port *pp)
++++ ++++++{
++++ ++++++     u32 val;
++++ ++++++
++++ ++++++     val = dw_pcie_readl_rc(pp, PCIE_ATU_VIEWPORT);
++++ ++++++     if (val == 0xffffffff)
++++ ++++++             return 1;
++++ ++++++
++++ ++++++     return 0;
++++ ++++++}
++++ ++++++
           int dw_pcie_host_init(struct pcie_port *pp)
           {
                struct device_node *np = pp->dev->of_node;
                struct resource *cfg_res;
                int i, ret;
                LIST_HEAD(res);
 ----------     struct resource_entry *win;
 ++++++++++     struct resource_entry *win, *tmp;
           
                cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
                if (cfg_res) {
                        goto error;
           
                /* Get the I/O and memory ranges from DT */
 ----------     resource_list_for_each_entry(win, &res) {
 ++++++++++     resource_list_for_each_entry_safe(win, tmp, &res) {
                        switch (resource_type(win->res)) {
                        case IORESOURCE_IO:
 ----------                     pp->io = win->res;
 ----------                     pp->io->name = "I/O";
 ----------                     pp->io_size = resource_size(pp->io);
 ----------                     pp->io_bus_addr = pp->io->start - win->offset;
 ----------                     ret = pci_remap_iospace(pp->io, pp->io_base);
 ----------                     if (ret)
 ++++++++++                     ret = pci_remap_iospace(win->res, pp->io_base);
 ++++++++++                     if (ret) {
                                        dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
 ----------                                      ret, pp->io);
 ++++++++++                                      ret, win->res);
 ++++++++++                             resource_list_destroy_entry(win);
 ++++++++++                     } else {
 ++++++++++                             pp->io = win->res;
 ++++++++++                             pp->io->name = "I/O";
 ++++++++++                             pp->io_size = resource_size(pp->io);
 ++++++++++                             pp->io_bus_addr = pp->io->start - win->offset;
 ++++++++++                     }
                                break;
                        case IORESOURCE_MEM:
                                pp->mem = win->res;
                if (ret)
                        pp->lanes = 0;
           
++++ ++++++     ret = of_property_read_u32(np, "num-viewport", &pp->num_viewport);
++++ ++++++     if (ret)
++++ ++++++             pp->num_viewport = 2;
++++ ++++++
                if (IS_ENABLED(CONFIG_PCI_MSI)) {
                        if (!pp->ops->msi_host_init) {
                                pp->irq_domain = irq_domain_add_linear(pp->dev->of_node,
                        }
                }
           
++++ ++++++     pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp);
++++ ++++++
                if (pp->ops->host_init)
                        pp->ops->host_init(pp);
           
@@@@@@@@@@@@ -611,13 -609,13 -609,13 -609,13 -708,14 -609,13 -609,13 -609,13 -609,13 -609,13 -609,13 +710,14 @@@@@@@@@@@@ static int dw_pcie_rd_other_conf(struc
                        va_cfg_base = pp->va_cfg1_base;
                }
           
---- ------     dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
++++ ++++++     dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
                                          type, cpu_addr,
                                          busdev, cfg_size);
                ret = dw_pcie_cfg_read(va_cfg_base + where, size, val);
---- ------     dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
---- ------                               PCIE_ATU_TYPE_IO, pp->io_base,
---- ------                               pp->io_bus_addr, pp->io_size);
++++ ++++++     if (pp->num_viewport <= 2)
++++ ++++++             dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
++++ ++++++                                       PCIE_ATU_TYPE_IO, pp->io_base,
++++ ++++++                                       pp->io_bus_addr, pp->io_size);
           
                return ret;
           }
@@@@@@@@@@@@ -648,13 -646,13 -646,13 -646,13 -746,14 -646,13 -646,13 -646,13 -646,13 -646,13 -646,13 +748,14 @@@@@@@@@@@@ static int dw_pcie_wr_other_conf(struc
                        va_cfg_base = pp->va_cfg1_base;
                }
           
---- ------     dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
++++ ++++++     dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
                                          type, cpu_addr,
                                          busdev, cfg_size);
                ret = dw_pcie_cfg_write(va_cfg_base + where, size, val);
---- ------     dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
---- ------                               PCIE_ATU_TYPE_IO, pp->io_base,
---- ------                               pp->io_bus_addr, pp->io_size);
++++ ++++++     if (pp->num_viewport <= 2)
++++ ++++++             dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
++++ ++++++                                       PCIE_ATU_TYPE_IO, pp->io_base,
++++ ++++++                                       pp->io_bus_addr, pp->io_size);
           
                return ret;
           }
@@@@@@@@@@@@ -672,6 -670,13 -670,13 -670,13 -771,13 -670,13 -670,13 -670,13 -670,13 -670,13 -670,13 +773,6 @@@@@@@@@@@@ static int dw_pcie_valid_config(struct 
                if (bus->number == pp->root_bus_nr && dev > 0)
                        return 0;
           
 ----------     /*
 ----------      * do not read more than one device on the bus directly attached
 ----------      * to RC's (Virtual Bridge's) DS side.
 ----------      */
 ----------     if (bus->primary == pp->root_bus_nr && dev > 0)
 ----------             return 0;
 ----------
                return 1;
           }
           
@@@@@@@@@@@@ -715,7 -720,7 -720,7 -720,7 -821,7 -720,7 -720,7 -720,7 -720,7 -720,7 -720,7 +816,7 @@@@@@@@@@@@ void dw_pcie_setup_rc(struct pcie_port 
                u32 val;
           
                /* set the number of lanes */
---- ------     dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
++++ ++++++     val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL);
                val &= ~PORT_LINK_MODE_MASK;
                switch (pp->lanes) {
                case 1:
                dw_pcie_writel_rc(pp, val, PCIE_PORT_LINK_CONTROL);
           
                /* set link width speed control register */
---- ------     dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, &val);
++++ ++++++     val = dw_pcie_readl_rc(pp, PCIE_LINK_WIDTH_SPEED_CONTROL);
                val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
                switch (pp->lanes) {
                case 1:
                dw_pcie_writel_rc(pp, 0x00000000, PCI_BASE_ADDRESS_1);
           
                /* setup interrupt pins */
---- ------     dw_pcie_readl_rc(pp, PCI_INTERRUPT_LINE, &val);
++++ ++++++     val = dw_pcie_readl_rc(pp, PCI_INTERRUPT_LINE);
                val &= 0xffff00ff;
                val |= 0x00000100;
                dw_pcie_writel_rc(pp, val, PCI_INTERRUPT_LINE);
           
                /* setup bus numbers */
---- ------     dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS, &val);
++++ ++++++     val = dw_pcie_readl_rc(pp, PCI_PRIMARY_BUS);
                val &= 0xff000000;
                val |= 0x00010100;
                dw_pcie_writel_rc(pp, val, PCI_PRIMARY_BUS);
           
                /* setup command register */
---- ------     dw_pcie_readl_rc(pp, PCI_COMMAND, &val);
++++ ++++++     val = dw_pcie_readl_rc(pp, PCI_COMMAND);
                val &= 0xffff0000;
                val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
                        PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
                 * uses its own address translation component rather than ATU, so
                 * we should not program the ATU here.
                 */
---- ------     if (!pp->ops->rd_other_conf)
---- ------             dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
++++ ++++++     if (!pp->ops->rd_other_conf) {
++++ ++++++             dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
                                                  PCIE_ATU_TYPE_MEM, pp->mem_base,
                                                  pp->mem_bus_addr, pp->mem_size);
++++ ++++++             if (pp->num_viewport > 2)
++++ ++++++                     dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX2,
++++ ++++++                                               PCIE_ATU_TYPE_IO, pp->io_base,
++++ ++++++                                               pp->io_bus_addr, pp->io_size);
++++ ++++++     }
           
                dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
           
                val |= PORT_LOGIC_SPEED_CHANGE;
                dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
           }
 ----------
 ----------MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
 ----------MODULE_DESCRIPTION("Designware PCIe host controller driver");
 ----------MODULE_LICENSE("GPL v2");
           #define IDSETR1                      0x011004
           #define TLCTLR                       0x011048
           #define MACSR                        0x011054
+++++++ +++#define  SPCHGFIN            (1 << 4)
+++++++ +++#define  SPCHGFAIL           (1 << 6)
+++++++ +++#define  SPCHGSUC            (1 << 7)
+++++++ +++#define  LINK_SPEED          (0xf << 16)
+++++++ +++#define  LINK_SPEED_2_5GTS   (1 << 16)
+++++++ +++#define  LINK_SPEED_5_0GTS   (2 << 16)
           #define MACCTLR                      0x011058
+++++++ +++#define  SPEED_CHANGE                (1 << 24)
           #define  SCRAMBLE_DISABLE    (1 << 27)
+++++++ +++#define MACS2R                       0x011078
+++++++ +++#define MACCGSPSETR          0x011084
+++++++ +++#define  SPCNGRSN            (1 << 31)
           
           /* R-Car H1 PHY */
           #define H1_PCIEPHYADRR               0x04000c
@@@@@@@@@@@@ -385,11 -385,11 -385,11 -385,11 -385,11 -385,11 -385,11 -395,67 -385,11 -385,11 -385,11 +395,67 @@@@@@@@@@@@ static int rcar_pcie_setup(struct list_
                return 1;
           }
           
+++++++ +++static void rcar_pcie_force_speedup(struct rcar_pcie *pcie)
+++++++ +++{
+++++++ +++     unsigned int timeout = 1000;
+++++++ +++     u32 macsr;
+++++++ +++
+++++++ +++     if ((rcar_pci_read_reg(pcie, MACS2R) & LINK_SPEED) != LINK_SPEED_5_0GTS)
+++++++ +++             return;
+++++++ +++
+++++++ +++     if (rcar_pci_read_reg(pcie, MACCTLR) & SPEED_CHANGE) {
+++++++ +++             dev_err(pcie->dev, "Speed change already in progress\n");
+++++++ +++             return;
+++++++ +++     }
+++++++ +++
+++++++ +++     macsr = rcar_pci_read_reg(pcie, MACSR);
+++++++ +++     if ((macsr & LINK_SPEED) == LINK_SPEED_5_0GTS)
+++++++ +++             goto done;
+++++++ +++
+++++++ +++     /* Set target link speed to 5.0 GT/s */
+++++++ +++     rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
+++++++ +++                PCI_EXP_LNKSTA_CLS_5_0GB);
+++++++ +++
+++++++ +++     /* Set speed change reason as intentional factor */
+++++++ +++     rcar_rmw32(pcie, MACCGSPSETR, SPCNGRSN, 0);
+++++++ +++
+++++++ +++     /* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */
+++++++ +++     if (macsr & (SPCHGFIN | SPCHGSUC | SPCHGFAIL))
+++++++ +++             rcar_pci_write_reg(pcie, macsr, MACSR);
+++++++ +++
+++++++ +++     /* Start link speed change */
+++++++ +++     rcar_rmw32(pcie, MACCTLR, SPEED_CHANGE, SPEED_CHANGE);
+++++++ +++
+++++++ +++     while (timeout--) {
+++++++ +++             macsr = rcar_pci_read_reg(pcie, MACSR);
+++++++ +++             if (macsr & SPCHGFIN) {
+++++++ +++                     /* Clear the interrupt bits */
+++++++ +++                     rcar_pci_write_reg(pcie, macsr, MACSR);
+++++++ +++
+++++++ +++                     if (macsr & SPCHGFAIL)
+++++++ +++                             dev_err(pcie->dev, "Speed change failed\n");
+++++++ +++
+++++++ +++                     goto done;
+++++++ +++             }
+++++++ +++
+++++++ +++             msleep(1);
+++++++ +++     };
+++++++ +++
+++++++ +++     dev_err(pcie->dev, "Speed change timed out\n");
+++++++ +++
+++++++ +++done:
+++++++ +++     dev_info(pcie->dev, "Current link speed is %s GT/s\n",
+++++++ +++              (macsr & LINK_SPEED) == LINK_SPEED_5_0GTS ? "5" : "2.5");
+++++++ +++}
+++++++ +++
           static int rcar_pcie_enable(struct rcar_pcie *pcie)
           {
                struct pci_bus *bus, *child;
                LIST_HEAD(res);
           
+++++++ +++     /* Try setting 5 GT/s link speed */
+++++++ +++     rcar_pcie_force_speedup(pcie);
+++++++ +++
                rcar_pcie_setup(&res, pcie);
           
                pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
@@@@@@@@@@@@ -608,6 -608,6 -608,6 -608,6 -608,6 -608,6 -608,6 -674,18 -608,6 -608,6 -608,6 +674,18 @@@@@@@@@@@@ static int rcar_msi_alloc(struct rcar_m
                return msi;
           }
           
+++++++ +++static int rcar_msi_alloc_region(struct rcar_msi *chip, int no_irqs)
+++++++ +++{
+++++++ +++     int msi;
+++++++ +++
+++++++ +++     mutex_lock(&chip->lock);
+++++++ +++     msi = bitmap_find_free_region(chip->used, INT_PCI_MSI_NR,
+++++++ +++                                   order_base_2(no_irqs));
+++++++ +++     mutex_unlock(&chip->lock);
+++++++ +++
+++++++ +++     return msi;
+++++++ +++}
+++++++ +++
           static void rcar_msi_free(struct rcar_msi *chip, unsigned long irq)
           {
                mutex_lock(&chip->lock);
@@@@@@@@@@@@ -665,7 -665,7 -665,7 -665,7 -665,7 -665,7 -665,7 -743,7 -665,7 -665,7 -665,7 +743,7 @@@@@@@@@@@@ static int rcar_msi_setup_irq(struct ms
                if (hwirq < 0)
                        return hwirq;
           
------- ---     irq = irq_create_mapping(msi->domain, hwirq);
+++++++ +++     irq = irq_find_mapping(msi->domain, hwirq);
                if (!irq) {
                        rcar_msi_free(msi, hwirq);
                        return -EINVAL;
                return 0;
           }
           
+++++++ +++static int rcar_msi_setup_irqs(struct msi_controller *chip,
+++++++ +++                            struct pci_dev *pdev, int nvec, int type)
+++++++ +++{
+++++++ +++     struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
+++++++ +++     struct rcar_msi *msi = to_rcar_msi(chip);
+++++++ +++     struct msi_desc *desc;
+++++++ +++     struct msi_msg msg;
+++++++ +++     unsigned int irq;
+++++++ +++     int hwirq;
+++++++ +++     int i;
+++++++ +++
+++++++ +++     /* MSI-X interrupts are not supported */
+++++++ +++     if (type == PCI_CAP_ID_MSIX)
+++++++ +++             return -EINVAL;
+++++++ +++
+++++++ +++     WARN_ON(!list_is_singular(&pdev->dev.msi_list));
+++++++ +++     desc = list_entry(pdev->dev.msi_list.next, struct msi_desc, list);
+++++++ +++
+++++++ +++     hwirq = rcar_msi_alloc_region(msi, nvec);
+++++++ +++     if (hwirq < 0)
+++++++ +++             return -ENOSPC;
+++++++ +++
+++++++ +++     irq = irq_find_mapping(msi->domain, hwirq);
+++++++ +++     if (!irq)
+++++++ +++             return -ENOSPC;
+++++++ +++
+++++++ +++     for (i = 0; i < nvec; i++) {
+++++++ +++             /*
+++++++ +++              * irq_create_mapping() called from rcar_pcie_probe() pre-
+++++++ +++              * allocates descs,  so there is no need to allocate descs here.
+++++++ +++              * We can therefore assume that if irq_find_mapping() above
+++++++ +++              * returns non-zero, then the descs are also successfully
+++++++ +++              * allocated.
+++++++ +++              */
+++++++ +++             if (irq_set_msi_desc_off(irq, i, desc)) {
+++++++ +++                     /* TODO: clear */
+++++++ +++                     return -EINVAL;
+++++++ +++             }
+++++++ +++     }
+++++++ +++
+++++++ +++     desc->nvec_used = nvec;
+++++++ +++     desc->msi_attrib.multiple = order_base_2(nvec);
+++++++ +++
+++++++ +++     msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE;
+++++++ +++     msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR);
+++++++ +++     msg.data = hwirq;
+++++++ +++
+++++++ +++     pci_write_msi_msg(irq, &msg);
+++++++ +++
+++++++ +++     return 0;
+++++++ +++}
+++++++ +++
           static void rcar_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
           {
                struct rcar_msi *msi = to_rcar_msi(chip);
@@@@@@@@@@@@ -716,12 -716,12 -716,12 -716,12 -716,12 -716,12 -716,12 -846,13 -716,12 -716,12 -716,12 +846,13 @@@@@@@@@@@@ static int rcar_pcie_enable_msi(struct 
                struct platform_device *pdev = to_platform_device(pcie->dev);
                struct rcar_msi *msi = &pcie->msi;
                unsigned long base;
------- ---     int err;
+++++++ +++     int err, i;
           
                mutex_init(&msi->lock);
           
                msi->chip.dev = pcie->dev;
                msi->chip.setup_irq = rcar_msi_setup_irq;
+++++++ +++     msi->chip.setup_irqs = rcar_msi_setup_irqs;
                msi->chip.teardown_irq = rcar_msi_teardown_irq;
           
                msi->domain = irq_domain_add_linear(pcie->dev->of_node, INT_PCI_MSI_NR,
                        return -ENOMEM;
                }
           
+++++++ +++     for (i = 0; i < INT_PCI_MSI_NR; i++)
+++++++ +++             irq_create_mapping(msi->domain, i);
+++++++ +++
                /* Two irqs are for MSI, but they are also used for non-MSI irqs */
                err = devm_request_irq(&pdev->dev, msi->irq1, rcar_pcie_msi_irq,
                                       IRQF_SHARED | IRQF_NO_THREAD,
@@@@@@@@@@@@ -775,6 -775,6 -775,6 -775,6 -775,6 -775,6 -775,6 -909,10 -775,6 -775,6 -775,6 +909,10 @@@@@@@@@@@@ static int rcar_pcie_get_resources(stru
                if (err)
                        return err;
           
+++++++ +++     pcie->base = devm_ioremap_resource(&pdev->dev, &res);
+++++++ +++     if (IS_ERR(pcie->base))
+++++++ +++             return PTR_ERR(pcie->base);
+++++++ +++
                pcie->clk = devm_clk_get(&pdev->dev, "pcie");
                if (IS_ERR(pcie->clk)) {
                        dev_err(pcie->dev, "cannot get platform clock\n");
                }
                err = clk_prepare_enable(pcie->clk);
                if (err)
------- ---             goto fail_clk;
+++++++ +++             return err;
           
                pcie->bus_clk = devm_clk_get(&pdev->dev, "pcie_bus");
                if (IS_ERR(pcie->bus_clk)) {
                }
                err = clk_prepare_enable(pcie->bus_clk);
                if (err)
------- ---             goto err_map_reg;
+++++++ +++             goto fail_clk;
           
                i = irq_of_parse_and_map(pdev->dev.of_node, 0);
                if (!i) {
                }
                pcie->msi.irq2 = i;
           
------- ---     pcie->base = devm_ioremap_resource(&pdev->dev, &res);
------- ---     if (IS_ERR(pcie->base)) {
------- ---             err = PTR_ERR(pcie->base);
------- ---             goto err_map_reg;
------- ---     }
------- ---
                return 0;
           
           err_map_reg:
@@@@@@@@@@@@ -865,12 -865,12 -865,12 -865,12 -865,12 -865,12 -865,12 -997,16 -865,12 -865,12 -865,12 +997,16 @@@@@@@@@@@@ static int rcar_pcie_inbound_ranges(str
                         * Set up 64-bit inbound regions as the range parser doesn't
                         * distinguish between 32 and 64-bit types.
                         */
------- ---             rcar_pci_write_reg(pcie, lower_32_bits(pci_addr), PCIEPRAR(idx));
+++++++ +++             rcar_pci_write_reg(pcie, lower_32_bits(pci_addr),
+++++++ +++                                PCIEPRAR(idx));
                        rcar_pci_write_reg(pcie, lower_32_bits(cpu_addr), PCIELAR(idx));
------- ---             rcar_pci_write_reg(pcie, lower_32_bits(mask) | flags, PCIELAMR(idx));
+++++++ +++             rcar_pci_write_reg(pcie, lower_32_bits(mask) | flags,
+++++++ +++                                PCIELAMR(idx));
           
------- ---             rcar_pci_write_reg(pcie, upper_32_bits(pci_addr), PCIEPRAR(idx+1));
------- ---             rcar_pci_write_reg(pcie, upper_32_bits(cpu_addr), PCIELAR(idx+1));
+++++++ +++             rcar_pci_write_reg(pcie, upper_32_bits(pci_addr),
+++++++ +++                                PCIEPRAR(idx + 1));
+++++++ +++             rcar_pci_write_reg(pcie, upper_32_bits(cpu_addr),
+++++++ +++                                PCIELAR(idx + 1));
                        rcar_pci_write_reg(pcie, 0, PCIELAMR(idx + 1));
           
                        pci_addr += size;
@@@@@@@@@@@@ -919,6 -919,6 -919,6 -919,6 -919,6 -919,6 -919,6 -1055,7 -919,6 -919,6 -919,6 +1055,7 @@@@@@@@@@@@ static int rcar_pcie_parse_map_dma_rang
                /* Get the dma-ranges from DT */
                for_each_of_pci_range(&parser, &range) {
                        u64 end = range.cpu_addr + range.size - 1;
+++++++ +++
                        dev_dbg(pcie->dev, "0x%08x 0x%016llx..0x%016llx -> 0x%016llx\n",
                                range.flags, range.cpu_addr, end, range.pci_addr);
           
           
           static const struct of_device_id rcar_pcie_of_match[] = {
                { .compatible = "renesas,pcie-r8a7779", .data = rcar_pcie_hw_init_h1 },
------- ---     { .compatible = "renesas,pcie-rcar-gen2", .data = rcar_pcie_hw_init_gen2 },
------- ---     { .compatible = "renesas,pcie-r8a7790", .data = rcar_pcie_hw_init_gen2 },
------- ---     { .compatible = "renesas,pcie-r8a7791", .data = rcar_pcie_hw_init_gen2 },
+++++++ +++     { .compatible = "renesas,pcie-rcar-gen2",
+++++++ +++       .data = rcar_pcie_hw_init_gen2 },
+++++++ +++     { .compatible = "renesas,pcie-r8a7790",
+++++++ +++       .data = rcar_pcie_hw_init_gen2 },
+++++++ +++     { .compatible = "renesas,pcie-r8a7791",
+++++++ +++       .data = rcar_pcie_hw_init_gen2 },
                { .compatible = "renesas,pcie-r8a7795", .data = rcar_pcie_hw_init },
                {},
           };
@@@@@@@@@@@@ -945,9 -945,9 -945,9 -945,9 -945,9 -945,9 -945,9 -1085,10 -945,9 -945,9 -945,9 +1085,10 @@@@@@@@@@@@ static int rcar_pcie_parse_request_of_p
                struct device *dev = pci->dev;
                struct device_node *np = dev->of_node;
                resource_size_t iobase;
 ----------     struct resource_entry *win;
 ++++++++++     struct resource_entry *win, *tmp;
           
------- ---     err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase);
+++++++ +++     err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources,
+++++++ +++                                            &iobase);
                if (err)
                        return err;
           
                if (err)
                        goto out_release_res;
           
 ----------     resource_list_for_each_entry(win, &pci->resources) {
 ++++++++++     resource_list_for_each_entry_safe(win, tmp, &pci->resources) {
                        struct resource *res = win->res;
           
                        if (resource_type(res) == IORESOURCE_IO) {
                                err = pci_remap_iospace(res, iobase);
 ----------                     if (err)
 ++++++++++                     if (err) {
                                        dev_warn(dev, "error %d: failed to map resource %pR\n",
                                                 err, res);
 ++++++++++
 ++++++++++                             resource_list_destroy_entry(win);
 ++++++++++                     }
                        }
                }
           
@@@@@@@@@@@@ -1001,8 -998,8 -998,8 -998,8 -998,8 -998,8 -998,8 -1139,8 -998,8 -998,8 -998,8 +1142,8 @@@@@@@@@@@@ static int rcar_pcie_probe(struct platf
                        return err;
                }
           
------- ---      err = rcar_pcie_parse_map_dma_ranges(pcie, pdev->dev.of_node);
------- ---      if (err)
+++++++ +++     err = rcar_pcie_parse_map_dma_ranges(pcie, pdev->dev.of_node);
+++++++ +++     if (err)
                        return err;
           
                of_id = of_match_device(rcar_pcie_of_match, pcie->dev);
           #include <linux/irq.h>
           #include <linux/irqdomain.h>
           #include <linux/kernel.h>
 ----------#include <linux/module.h>
 ++++++++++#include <linux/init.h>
           #include <linux/msi.h>
           #include <linux/of_address.h>
           #include <linux/of_pci.h>
           #define MSGF_MISC_SR_MASTER_ERR              BIT(5)
           #define MSGF_MISC_SR_I_ADDR_ERR              BIT(6)
           #define MSGF_MISC_SR_E_ADDR_ERR              BIT(7)
---------- #define MSGF_MISC_SR_UR_DETECT          BIT(20)
---------- 
---------- #define MSGF_MISC_SR_PCIE_CORE               GENMASK(18, 16)
---------- #define MSGF_MISC_SR_PCIE_CORE_ERR   GENMASK(31, 22)
++++++++++ #define MSGF_MISC_SR_FATAL_AER               BIT(16)
++++++++++ #define MSGF_MISC_SR_NON_FATAL_AER   BIT(17)
++++++++++ #define MSGF_MISC_SR_CORR_AER                BIT(18)
++++++++++ #define MSGF_MISC_SR_UR_DETECT               BIT(20)
++++++++++ #define MSGF_MISC_SR_NON_FATAL_DEV   BIT(22)
++++++++++ #define MSGF_MISC_SR_FATAL_DEV               BIT(23)
++++++++++ #define MSGF_MISC_SR_LINK_DOWN               BIT(24)
++++++++++ #define MSGF_MSIC_SR_LINK_AUTO_BWIDTH        BIT(25)
++++++++++ #define MSGF_MSIC_SR_LINK_BWIDTH     BIT(26)
           
           #define MSGF_MISC_SR_MASKALL         (MSGF_MISC_SR_RXMSG_AVAIL | \
                                                MSGF_MISC_SR_RXMSG_OVER | \
                                                MSGF_MISC_SR_MASTER_ERR | \
                                                MSGF_MISC_SR_I_ADDR_ERR | \
                                                MSGF_MISC_SR_E_ADDR_ERR | \
++++++++++                                      MSGF_MISC_SR_FATAL_AER | \
++++++++++                                      MSGF_MISC_SR_NON_FATAL_AER | \
++++++++++                                      MSGF_MISC_SR_CORR_AER | \
                                                MSGF_MISC_SR_UR_DETECT | \
----------                                      MSGF_MISC_SR_PCIE_CORE | \
----------                                      MSGF_MISC_SR_PCIE_CORE_ERR)
++++++++++                                      MSGF_MISC_SR_NON_FATAL_DEV | \
++++++++++                                      MSGF_MISC_SR_FATAL_DEV | \
++++++++++                                      MSGF_MISC_SR_LINK_DOWN | \
++++++++++                                      MSGF_MSIC_SR_LINK_AUTO_BWIDTH | \
++++++++++                                      MSGF_MSIC_SR_LINK_BWIDTH)
           
           /* Legacy interrupt status mask bits */
           #define MSGF_LEG_SR_INTA             BIT(0)
                                                MSGF_LEG_SR_INTC | MSGF_LEG_SR_INTD)
           
           /* MSI interrupt status mask bits */
---------- #define MSGF_MSI_SR_LO_MASK          BIT(0)
---------- #define MSGF_MSI_SR_HI_MASK          BIT(0)
++++++++++ #define MSGF_MSI_SR_LO_MASK          GENMASK(31, 0)
++++++++++ #define MSGF_MSI_SR_HI_MASK          GENMASK(31, 0)
           
           #define MSII_PRESENT                 BIT(0)
           #define MSII_ENABLE                  BIT(0)
@@@@@@@@@@@@ -291,8 -291,8 -291,8 -291,8 -291,8 -291,8 -291,8 -291,8 -291,8 -291,8 -302,29 +302,29 @@@@@@@@@@@@ static irqreturn_t nwl_pcie_misc_handle
                        dev_err(pcie->dev,
                                "In Misc Egress address translation error\n");
           
----------      if (misc_stat & MSGF_MISC_SR_PCIE_CORE_ERR)
----------              dev_err(pcie->dev, "PCIe Core error\n");
++++++++++      if (misc_stat & MSGF_MISC_SR_FATAL_AER)
++++++++++              dev_err(pcie->dev, "Fatal Error in AER Capability\n");
++++++++++ 
++++++++++      if (misc_stat & MSGF_MISC_SR_NON_FATAL_AER)
++++++++++              dev_err(pcie->dev, "Non-Fatal Error in AER Capability\n");
++++++++++ 
++++++++++      if (misc_stat & MSGF_MISC_SR_CORR_AER)
++++++++++              dev_err(pcie->dev, "Correctable Error in AER Capability\n");
++++++++++ 
++++++++++      if (misc_stat & MSGF_MISC_SR_UR_DETECT)
++++++++++              dev_err(pcie->dev, "Unsupported request Detected\n");
++++++++++ 
++++++++++      if (misc_stat & MSGF_MISC_SR_NON_FATAL_DEV)
++++++++++              dev_err(pcie->dev, "Non-Fatal Error Detected\n");
++++++++++ 
++++++++++      if (misc_stat & MSGF_MISC_SR_FATAL_DEV)
++++++++++              dev_err(pcie->dev, "Fatal Error Detected\n");
++++++++++ 
++++++++++      if (misc_stat & MSGF_MSIC_SR_LINK_AUTO_BWIDTH)
++++++++++              dev_info(pcie->dev, "Link Autonomous Bandwidth Management Status bit set\n");
++++++++++ 
++++++++++      if (misc_stat & MSGF_MSIC_SR_LINK_BWIDTH)
++++++++++              dev_info(pcie->dev, "Link Bandwidth Management Status bit set\n");
           
                /* Clear misc interrupt status */
                nwl_bridge_writel(pcie, misc_stat, MSGF_MISC_STATUS);
@@@@@@@@@@@@ -459,6 -459,40 -459,40 -459,40 -459,40 -459,40 -459,40 -459,40 -459,40 -459,40 -491,40 +491,6 @@@@@@@@@@@@ static const struct irq_domain_ops dev_
                .free   = nwl_irq_domain_free,
           };
           
 ----------static void nwl_msi_free_irq_domain(struct nwl_pcie *pcie)
 ----------{
 ----------     struct nwl_msi *msi = &pcie->msi;
 ----------
 ----------     if (msi->irq_msi0)
 ----------             irq_set_chained_handler_and_data(msi->irq_msi0, NULL, NULL);
 ----------     if (msi->irq_msi1)
 ----------             irq_set_chained_handler_and_data(msi->irq_msi1, NULL, NULL);
 ----------
 ----------     if (msi->msi_domain)
 ----------             irq_domain_remove(msi->msi_domain);
 ----------     if (msi->dev_domain)
 ----------             irq_domain_remove(msi->dev_domain);
 ----------
 ----------     kfree(msi->bitmap);
 ----------     msi->bitmap = NULL;
 ----------}
 ----------
 ----------static void nwl_pcie_free_irq_domain(struct nwl_pcie *pcie)
 ----------{
 ----------     int i;
 ----------     u32 irq;
 ----------
 ----------     for (i = 0; i < INTX_NUM; i++) {
 ----------             irq = irq_find_mapping(pcie->legacy_irq_domain, i + 1);
 ----------             if (irq > 0)
 ----------                     irq_dispose_mapping(irq);
 ----------     }
 ----------     if (pcie->legacy_irq_domain)
 ----------             irq_domain_remove(pcie->legacy_irq_domain);
 ----------
 ----------     nwl_msi_free_irq_domain(pcie);
 ----------}
 ----------
           static int nwl_pcie_init_msi_irq_domain(struct nwl_pcie *pcie)
           {
           #ifdef CONFIG_PCI_MSI
                return err;
           }
           
 ----------static int nwl_pcie_remove(struct platform_device *pdev)
 ----------{
 ----------     struct nwl_pcie *pcie = platform_get_drvdata(pdev);
 ----------
 ----------     nwl_pcie_free_irq_domain(pcie);
 ----------     platform_set_drvdata(pdev, NULL);
 ----------     return 0;
 ----------}
 ----------
           static struct platform_driver nwl_pcie_driver = {
                .driver = {
                        .name = "nwl-pcie",
 ++++++++++             .suppress_bind_attrs = true,
                        .of_match_table = nwl_pcie_of_match,
                },
                .probe = nwl_pcie_probe,
 ----------     .remove = nwl_pcie_remove,
           };
 ----------module_platform_driver(nwl_pcie_driver);
 ----------
 ----------MODULE_AUTHOR("Xilinx, Inc");
 ----------MODULE_DESCRIPTION("NWL PCIe driver");
 ----------MODULE_LICENSE("GPL");
 ++++++++++builtin_platform_driver(nwl_pcie_driver);
           #include <linux/irq.h>
           #include <linux/irqdomain.h>
           #include <linux/kernel.h>
 ----------#include <linux/module.h>
 ++++++++++#include <linux/init.h>
           #include <linux/msi.h>
           #include <linux/of_address.h>
           #include <linux/of_pci.h>
            * @msi_pages: MSI pages
            * @root_busno: Root Bus number
            * @dev: Device pointer
----------  * @irq_domain: IRQ domain pointer
++++++++++  * @msi_domain: MSI IRQ domain pointer
++++++++++  * @leg_domain: Legacy IRQ domain pointer
            * @resources: Bus Resources
            */
           struct xilinx_pcie_port {
                unsigned long msi_pages;
                u8 root_busno;
                struct device *dev;
----------      struct irq_domain *irq_domain;
++++++++++      struct irq_domain *msi_domain;
++++++++++      struct irq_domain *leg_domain;
                struct list_head resources;
           };
           
@@@@@@@@@@@@ -168,6 -168,13 -168,13 -168,13 -168,13 -168,13 -168,13 -168,13 -168,13 -168,13 -170,13 +170,6 @@@@@@@@@@@@ static bool xilinx_pcie_valid_device(st
                if (bus->number == port->root_busno && devfn > 0)
                        return false;
           
 ----------     /*
 ----------      * Do not read more than one device on the bus directly attached
 ----------      * to RC.
 ----------      */
 ----------     if (bus->primary == port->root_busno && devfn > 0)
 ----------             return false;
 ----------
                return true;
           }
           
@@@@@@@@@@@@ -212,13 -219,13 -219,13 -219,13 -219,13 -219,13 -219,13 -219,13 -219,13 -219,13 -221,15 +214,15 @@@@@@@@@@@@ static void xilinx_pcie_destroy_msi(uns
           {
                struct msi_desc *msi;
                struct xilinx_pcie_port *port;
++++++++++      struct irq_data *d = irq_get_irq_data(irq);
++++++++++      irq_hw_number_t hwirq = irqd_to_hwirq(d);
           
----------      if (!test_bit(irq, msi_irq_in_use)) {
++++++++++      if (!test_bit(hwirq, msi_irq_in_use)) {
                        msi = irq_get_msi_desc(irq);
                        port = msi_desc_to_pci_sysdata(msi);
                        dev_err(port->dev, "Trying to free unused MSI#%d\n", irq);
                } else {
----------              clear_bit(irq, msi_irq_in_use);
++++++++++              clear_bit(hwirq, msi_irq_in_use);
                }
           }
           
@@@@@@@@@@@@ -250,6 -257,6 -257,6 -257,6 -257,6 -257,6 -257,6 -257,6 -257,6 -257,6 -261,7 +254,7 @@@@@@@@@@@@ static void xilinx_msi_teardown_irq(str
                                            unsigned int irq)
           {
                xilinx_pcie_destroy_msi(irq);
++++++++++      irq_dispose_mapping(irq);
           }
           
           /**
@@@@@@@@@@@@ -274,7 -281,7 -281,7 -281,7 -281,7 -281,7 -281,7 -281,7 -281,7 -281,7 -286,7 +279,7 @@@@@@@@@@@@ static int xilinx_pcie_msi_setup_irq(st
                if (hwirq < 0)
                        return hwirq;
           
----------      irq = irq_create_mapping(port->irq_domain, hwirq);
++++++++++      irq = irq_create_mapping(port->msi_domain, hwirq);
                if (!irq)
                        return -EINVAL;
           
@@@@@@@@@@@@ -425,7 -432,7 -432,7 -432,7 -432,7 -432,7 -432,7 -432,7 -432,7 -432,7 -437,7 +430,7 @@@@@@@@@@@@ static irqreturn_t xilinx_pcie_intr_han
                        /* Check whether interrupt valid */
                        if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) {
                                dev_warn(port->dev, "RP Intr FIFO1 read error\n");
----------                      return IRQ_HANDLED;
++++++++++                      goto error;
                        }
           
                        if (!(val & XILINX_PCIE_RPIFR1_MSI_INTR)) {
                                /* Handle INTx Interrupt */
                                val = ((val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
                                        XILINX_PCIE_RPIFR1_INTR_SHIFT) + 1;
----------                      generic_handle_irq(irq_find_mapping(port->irq_domain,
++++++++++                      generic_handle_irq(irq_find_mapping(port->leg_domain,
                                                                    val));
                        }
                }
           
                        if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) {
                                dev_warn(port->dev, "RP Intr FIFO1 read error\n");
----------                      return IRQ_HANDLED;
++++++++++                      goto error;
                        }
           
                        if (val & XILINX_PCIE_RPIFR1_MSI_INTR) {
                if (status & XILINX_PCIE_INTR_MST_ERRP)
                        dev_warn(port->dev, "Master error poison\n");
           
++++++++++ error:
                /* Clear the Interrupt Decode register */
                pcie_write(port, status, XILINX_PCIE_REG_IDR);
           
                return IRQ_HANDLED;
           }
           
 ----------/**
 ---------- * xilinx_pcie_free_irq_domain - Free IRQ domain
 ---------- * @port: PCIe port information
 ---------- */
 ----------static void xilinx_pcie_free_irq_domain(struct xilinx_pcie_port *port)
 ----------{
 ----------     int i;
 ----------     u32 irq, num_irqs;
 ----------
 ----------     /* Free IRQ Domain */
 ----------     if (IS_ENABLED(CONFIG_PCI_MSI)) {
 ----------
 ----------             free_pages(port->msi_pages, 0);
 ----------
 ----------             num_irqs = XILINX_NUM_MSI_IRQS;
 ----------     } else {
 ----------             /* INTx */
 ----------             num_irqs = 4;
 ----------     }
 ----------
 ----------     for (i = 0; i < num_irqs; i++) {
 ---------              irq = irq_find_mapping(port->irq_domain, i);
          -             irq = irq_find_mapping(port->leg_domain, i);
 ----------             if (irq > 0)
 ----------                     irq_dispose_mapping(irq);
 ----------     }
 --------- 
 ---------      irq_domain_remove(port->irq_domain);
          -     if (port->leg_domain)
          -             irq_domain_remove(port->leg_domain);
          -     if (port->msi_domain)
          -             irq_domain_remove(port->msi_domain);
 ----------}
 ----------
           /**
            * xilinx_pcie_init_irq_domain - Initialize IRQ domain
            * @port: PCIe port information
@@@@@@@@@@@@ -517,21 -553,21 -553,21 -553,21 -553,21 -553,21 -553,21 -553,21 -553,21 -553,21 -561,21 +523,21 @@@@@@@@@@@@ static int xilinx_pcie_init_irq_domain(
                        return -ENODEV;
                }
           
----------      port->irq_domain = irq_domain_add_linear(pcie_intc_node, 4,
++++++++++      port->leg_domain = irq_domain_add_linear(pcie_intc_node, 4,
                                                         &intx_domain_ops,
                                                         port);
----------      if (!port->irq_domain) {
++++++++++      if (!port->leg_domain) {
                        dev_err(dev, "Failed to get a INTx IRQ domain\n");
                        return -ENODEV;
                }
           
                /* Setup MSI */
                if (IS_ENABLED(CONFIG_PCI_MSI)) {
----------              port->irq_domain = irq_domain_add_linear(node,
++++++++++              port->msi_domain = irq_domain_add_linear(node,
                                                                 XILINX_NUM_MSI_IRQS,
                                                                 &msi_domain_ops,
                                                                 &xilinx_pcie_msi_chip);
----------              if (!port->irq_domain) {
++++++++++              if (!port->msi_domain) {
                                dev_err(dev, "Failed to get a MSI IRQ domain\n");
                                return -ENODEV;
                        }
                return err;
           }
           
 ----------/**
 ---------- * xilinx_pcie_remove - Remove function
 ---------- * @pdev: Platform device pointer
 ---------- *
 ---------- * Return: '0' always
 ---------- */
 ----------static int xilinx_pcie_remove(struct platform_device *pdev)
 ----------{
 ----------     struct xilinx_pcie_port *port = platform_get_drvdata(pdev);
 ----------
 ----------     xilinx_pcie_free_irq_domain(port);
 ----------
 ----------     return 0;
 ----------}
 ----------
           static struct of_device_id xilinx_pcie_of_match[] = {
                { .compatible = "xlnx,axi-pcie-host-1.00.a", },
                {}
@@@@@@@@@@@@ -700,5 -751,10 -751,10 -751,10 -751,10 -751,10 -751,10 -751,10 -751,10 -751,10 -759,10 +706,5 @@@@@@@@@@@@ static struct platform_driver xilinx_pc
                        .suppress_bind_attrs = true,
                },
                .probe = xilinx_pcie_probe,
 ----------     .remove = xilinx_pcie_remove,
           };
 ----------module_platform_driver(xilinx_pcie_driver);
 ----------
 ----------MODULE_AUTHOR("Xilinx Inc");
 ----------MODULE_DESCRIPTION("Xilinx AXI PCIe driver");
 ----------MODULE_LICENSE("GPL v2");
 ++++++++++builtin_platform_driver(xilinx_pcie_driver);