mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 17:24:17 +08:00
Merge branch 'remotes/lorenzo/pci/tegra194'
- Fix handling BME_CHGED event (Om Prakash Singh) - Fix MSI-X programming (Om Prakash Singh) - Disable interrupts before entering L2 (Om Prakash Singh) - Don't allow suspend when Tegra PCIe is in EP mode (Om Prakash Singh) * remotes/lorenzo/pci/tegra194: PCI: tegra194: Cleanup unused code PCI: tegra194: Don't allow suspend when Tegra PCIe is in EP mode PCI: tegra194: Disable interrupts before entering L2 PCI: tegra194: Fix MSI-X programming PCI: tegra194: Fix handling BME_CHGED event
This commit is contained in:
commit
4a4547db56
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user