Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / drivers / pci / controller / dwc / pcie-tegra194.c
index 3ec7b29..9049769 100644 (file)
@@ -497,19 +497,19 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
        struct tegra_pcie_dw *pcie = arg;
        struct dw_pcie_ep *ep = &pcie->pci.ep;
        int spurious = 1;
-       u32 val, tmp;
+       u32 status_l0, status_l1, link_status;
 
-       val = appl_readl(pcie, APPL_INTR_STATUS_L0);
-       if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
-               val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
-               appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
+       status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0);
+       if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
+               status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
+               appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0);
 
-               if (val & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE)
+               if (status_l1 & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE)
                        pex_ep_event_hot_rst_done(pcie);
 
-               if (val & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) {
-                       tmp = appl_readl(pcie, APPL_LINK_STATUS);
-                       if (tmp & APPL_LINK_STATUS_RDLH_LINK_UP) {
+               if (status_l1 & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED) {
+                       link_status = appl_readl(pcie, APPL_LINK_STATUS);
+                       if (link_status & APPL_LINK_STATUS_RDLH_LINK_UP) {
                                dev_dbg(pcie->dev, "Link is up with Host\n");
                                dw_pcie_ep_linkup(ep);
                        }
@@ -518,11 +518,11 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
                spurious = 0;
        }
 
-       if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) {
-               val = appl_readl(pcie, APPL_INTR_STATUS_L1_15);
-               appl_writel(pcie, val, APPL_INTR_STATUS_L1_15);
+       if (status_l0 & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT) {
+               status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_15);
+               appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_15);
 
-               if (val & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED)
+               if (status_l1 & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED)
                        return IRQ_WAKE_THREAD;
 
                spurious = 0;
@@ -530,8 +530,8 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
 
        if (spurious) {
                dev_warn(pcie->dev, "Random interrupt (STATUS = 0x%08X)\n",
-                        val);
-               appl_writel(pcie, val, APPL_INTR_STATUS_L0);
+                        status_l0);
+               appl_writel(pcie, status_l0, APPL_INTR_STATUS_L0);
        }
 
        return IRQ_HANDLED;
@@ -1493,6 +1493,16 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)
                return;
        }
 
+       /*
+        * PCIe controller exits from L2 only if reset is applied, so
+        * controller doesn't handle interrupts. But in cases where
+        * L2 entry fails, PERST# is asserted which can trigger surprise
+        * link down AER. However this function call happens in
+        * suspend_noirq(), so AER interrupt will not be processed.
+        * Disable all interrupts to avoid such a scenario.
+        */
+       appl_writel(pcie, 0x0, APPL_INTR_EN_L0_0);
+
        if (tegra_pcie_try_link_l2(pcie)) {
                dev_info(pcie->dev, "Link didn't transition to L2 state\n");
                /*
@@ -1763,7 +1773,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
        val = (ep->msi_mem_phys & MSIX_ADDR_MATCH_LOW_OFF_MASK);
        val |= MSIX_ADDR_MATCH_LOW_OFF_EN;
        dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_LOW_OFF, val);
-       val = (lower_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);
+       val = (upper_32_bits(ep->msi_mem_phys) & MSIX_ADDR_MATCH_HIGH_OFF_MASK);
        dw_pcie_writel_dbi(pci, MSIX_ADDR_MATCH_HIGH_OFF, val);
 
        ret = dw_pcie_ep_init_complete(ep);
@@ -1935,13 +1945,6 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,
                return ret;
        }
 
-       name = devm_kasprintf(dev, GFP_KERNEL, "tegra_pcie_%u_ep_work",
-                             pcie->cid);
-       if (!name) {
-               dev_err(dev, "Failed to create PCIe EP work thread string\n");
-               return -ENOMEM;
-       }
-
        pm_runtime_enable(dev);
 
        ret = dw_pcie_ep_init(ep);
@@ -2236,6 +2239,11 @@ static int tegra_pcie_dw_resume_early(struct device *dev)
        struct tegra_pcie_dw *pcie = dev_get_drvdata(dev);
        u32 val;
 
+       if (pcie->mode == DW_PCIE_EP_TYPE) {
+               dev_err(dev, "Suspend is not supported in EP mode");
+               return -ENOTSUPP;
+       }
+
        if (!pcie->link_state)
                return 0;