@@ -104,6 +104,9 @@
#define PCIE_MSG_PM_PME_MASK BIT(7)
#define PCIE_ISR0_MASK_REG (CONTROL_BASE_ADDR + 0x44)
#define PCIE_ISR0_MSI_INT_PENDING BIT(24)
+#define PCIE_ISR0_CORR_ERR BIT(11)
+#define PCIE_ISR0_NFAT_ERR BIT(12)
+#define PCIE_ISR0_FAT_ERR BIT(13)
#define PCIE_ISR0_INTX_ASSERT(val) BIT(16 + (val))
#define PCIE_ISR0_INTX_DEASSERT(val) BIT(20 + (val))
#define PCIE_ISR0_ALL_MASK GENMASK(26, 0)
@@ -416,6 +419,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
reg &= ~PCIE_ISR0_MSI_INT_PENDING;
advk_writel(pcie, reg, PCIE_ISR0_MASK_REG);
+ /* Unmask bits for ERR interrupt */
+ reg = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+ reg &= ~(PCIE_ISR0_FAT_ERR | PCIE_ISR0_NFAT_ERR | PCIE_ISR0_CORR_ERR);
+ advk_writel(pcie, reg, PCIE_ISR0_MASK_REG);
+
/* Enable summary interrupt for GIC SPI source */
reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK);
advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG);
@@ -1195,6 +1203,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
{
u32 isr0_val, isr0_mask, isr0_status;
u32 isr1_val, isr1_mask, isr1_status;
+ u32 err_bits;
int i, virq;
isr0_val = advk_readl(pcie, PCIE_ISR0_REG);
@@ -1205,9 +1214,22 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
+ err_bits = isr0_status & (PCIE_ISR0_FAT_ERR | PCIE_ISR0_NFAT_ERR | PCIE_ISR0_CORR_ERR);
+
if (!isr0_status && !isr1_status)
return;
+ /* Process ERR interrupt */
+ if (err_bits) {
+ advk_writel(pcie, err_bits, PCIE_ISR0_REG);
+ /* Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use PCIe interrupt 0 */
+ virq = irq_find_mapping(pcie->irq_domain, 0);
+ if (virq)
+ generic_handle_irq(virq);
+ else
+ dev_err(&pcie->pdev->dev, "unexpected ERR IRQ\n");
+ }
+
/* Process MSI interrupts */
if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
advk_pcie_handle_msi(pcie);