@@ -497,19 +497,19 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
497
497
struct tegra_pcie_dw * pcie = arg ;
498
498
struct dw_pcie_ep * ep = & pcie -> pci .ep ;
499
499
int spurious = 1 ;
500
- u32 val , tmp ;
500
+ u32 status_l0 , status_l1 , link_status ;
501
501
502
- val = appl_readl (pcie , APPL_INTR_STATUS_L0 );
503
- if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT ) {
504
- val = appl_readl (pcie , APPL_INTR_STATUS_L1_0_0 );
505
- appl_writel (pcie , val , APPL_INTR_STATUS_L1_0_0 );
502
+ status_l0 = appl_readl (pcie , APPL_INTR_STATUS_L0 );
503
+ if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT ) {
504
+ status_l1 = appl_readl (pcie , APPL_INTR_STATUS_L1_0_0 );
505
+ appl_writel (pcie , status_l1 , APPL_INTR_STATUS_L1_0_0 );
506
506
507
- if (val & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE )
507
+ if (status_l1 & APPL_INTR_STATUS_L1_0_0_HOT_RESET_DONE )
508
508
pex_ep_event_hot_rst_done (pcie );
509
509
510
- if (val & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED ) {
511
- tmp = appl_readl (pcie , APPL_LINK_STATUS );
512
- if (tmp & APPL_LINK_STATUS_RDLH_LINK_UP ) {
510
+ if (status_l1 & APPL_INTR_STATUS_L1_0_0_RDLH_LINK_UP_CHGED ) {
511
+ link_status = appl_readl (pcie , APPL_LINK_STATUS );
512
+ if (link_status & APPL_LINK_STATUS_RDLH_LINK_UP ) {
513
513
dev_dbg (pcie -> dev , "Link is up with Host\n" );
514
514
dw_pcie_ep_linkup (ep );
515
515
}
@@ -518,20 +518,20 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)
518
518
spurious = 0 ;
519
519
}
520
520
521
- if (val & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT ) {
522
- val = appl_readl (pcie , APPL_INTR_STATUS_L1_15 );
523
- appl_writel (pcie , val , APPL_INTR_STATUS_L1_15 );
521
+ if (status_l0 & APPL_INTR_STATUS_L0_PCI_CMD_EN_INT ) {
522
+ status_l1 = appl_readl (pcie , APPL_INTR_STATUS_L1_15 );
523
+ appl_writel (pcie , status_l1 , APPL_INTR_STATUS_L1_15 );
524
524
525
- if (val & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED )
525
+ if (status_l1 & APPL_INTR_STATUS_L1_15_CFG_BME_CHGED )
526
526
return IRQ_WAKE_THREAD ;
527
527
528
528
spurious = 0 ;
529
529
}
530
530
531
531
if (spurious ) {
532
532
dev_warn (pcie -> dev , "Random interrupt (STATUS = 0x%08X)\n" ,
533
- val );
534
- appl_writel (pcie , val , APPL_INTR_STATUS_L0 );
533
+ status_l0 );
534
+ appl_writel (pcie , status_l0 , APPL_INTR_STATUS_L0 );
535
535
}
536
536
537
537
return IRQ_HANDLED ;
@@ -1493,6 +1493,16 @@ static void tegra_pcie_dw_pme_turnoff(struct tegra_pcie_dw *pcie)
1493
1493
return ;
1494
1494
}
1495
1495
1496
+ /*
1497
+ * PCIe controller exits from L2 only if reset is applied, so
1498
+ * controller doesn't handle interrupts. But in cases where
1499
+ * L2 entry fails, PERST# is asserted which can trigger surprise
1500
+ * link down AER. However this function call happens in
1501
+ * suspend_noirq(), so AER interrupt will not be processed.
1502
+ * Disable all interrupts to avoid such a scenario.
1503
+ */
1504
+ appl_writel (pcie , 0x0 , APPL_INTR_EN_L0_0 );
1505
+
1496
1506
if (tegra_pcie_try_link_l2 (pcie )) {
1497
1507
dev_info (pcie -> dev , "Link didn't transition to L2 state\n" );
1498
1508
/*
@@ -1763,7 +1773,7 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)
1763
1773
val = (ep -> msi_mem_phys & MSIX_ADDR_MATCH_LOW_OFF_MASK );
1764
1774
val |= MSIX_ADDR_MATCH_LOW_OFF_EN ;
1765
1775
dw_pcie_writel_dbi (pci , MSIX_ADDR_MATCH_LOW_OFF , val );
1766
- val = (lower_32_bits (ep -> msi_mem_phys ) & MSIX_ADDR_MATCH_HIGH_OFF_MASK );
1776
+ val = (upper_32_bits (ep -> msi_mem_phys ) & MSIX_ADDR_MATCH_HIGH_OFF_MASK );
1767
1777
dw_pcie_writel_dbi (pci , MSIX_ADDR_MATCH_HIGH_OFF , val );
1768
1778
1769
1779
ret = dw_pcie_ep_init_complete (ep );
@@ -1935,13 +1945,6 @@ static int tegra_pcie_config_ep(struct tegra_pcie_dw *pcie,
1935
1945
return ret ;
1936
1946
}
1937
1947
1938
- name = devm_kasprintf (dev , GFP_KERNEL , "tegra_pcie_%u_ep_work" ,
1939
- pcie -> cid );
1940
- if (!name ) {
1941
- dev_err (dev , "Failed to create PCIe EP work thread string\n" );
1942
- return - ENOMEM ;
1943
- }
1944
-
1945
1948
pm_runtime_enable (dev );
1946
1949
1947
1950
ret = dw_pcie_ep_init (ep );
@@ -2236,6 +2239,11 @@ static int tegra_pcie_dw_resume_early(struct device *dev)
2236
2239
struct tegra_pcie_dw * pcie = dev_get_drvdata (dev );
2237
2240
u32 val ;
2238
2241
2242
+ if (pcie -> mode == DW_PCIE_EP_TYPE ) {
2243
+ dev_err (dev , "Suspend is not supported in EP mode" );
2244
+ return - ENOTSUPP ;
2245
+ }
2246
+
2239
2247
if (!pcie -> link_state )
2240
2248
return 0 ;
2241
2249
0 commit comments