Skip to content

Commit 4bcffe9

Browse files
SherrySun5suryasaimadhu
authored andcommitted
EDAC/synopsys: Re-enable the error interrupts on v3 hw
zynqmp_get_error_info() writes 0 to the ECC_CLR_OFST register after an interrupt for a {un-,}correctable error is raised, which disables the error interrupts. Then the interrupt handler will be called only once. Therefore, re-enable the error interrupt line at the end of intr_handler() for v3.x Synopsys EDAC DDR. Fixes: f7824de ("EDAC/synopsys: Add support for version 3 of the Synopsys EDAC DDR") Signed-off-by: Sherry Sun <sherry.sun@nxp.com> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Shubhrajyoti Datta <Shubhrajyoti.datta@xilinx.com> Acked-by: Michal Simek <michal.simek@xilinx.com> Cc: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20220427015137.8406-3-sherry.sun@nxp.com
1 parent be76cea commit 4bcffe9

File tree

1 file changed

+25
-22
lines changed

1 file changed

+25
-22
lines changed

drivers/edac/synopsys_edac.c

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,28 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
514514
memset(p, 0, sizeof(*p));
515515
}
516516

517+
static void enable_intr(struct synps_edac_priv *priv)
518+
{
519+
/* Enable UE/CE Interrupts */
520+
if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
521+
writel(DDR_UE_MASK | DDR_CE_MASK,
522+
priv->baseaddr + ECC_CLR_OFST);
523+
else
524+
writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
525+
priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
526+
527+
}
528+
529+
static void disable_intr(struct synps_edac_priv *priv)
530+
{
531+
/* Disable UE/CE Interrupts */
532+
if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
533+
writel(0x0, priv->baseaddr + ECC_CLR_OFST);
534+
else
535+
writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
536+
priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
537+
}
538+
517539
/**
518540
* intr_handler - Interrupt Handler for ECC interrupts.
519541
* @irq: IRQ number.
@@ -555,6 +577,9 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
555577
/* v3.0 of the controller does not have this register */
556578
if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
557579
writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
580+
else
581+
enable_intr(priv);
582+
558583
return IRQ_HANDLED;
559584
}
560585

@@ -837,28 +862,6 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
837862
init_csrows(mci);
838863
}
839864

840-
static void enable_intr(struct synps_edac_priv *priv)
841-
{
842-
/* Enable UE/CE Interrupts */
843-
if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
844-
writel(DDR_UE_MASK | DDR_CE_MASK,
845-
priv->baseaddr + ECC_CLR_OFST);
846-
else
847-
writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
848-
priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
849-
850-
}
851-
852-
static void disable_intr(struct synps_edac_priv *priv)
853-
{
854-
/* Disable UE/CE Interrupts */
855-
if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
856-
writel(0x0, priv->baseaddr + ECC_CLR_OFST);
857-
else
858-
writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
859-
priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
860-
}
861-
862865
static int setup_irq(struct mem_ctl_info *mci,
863866
struct platform_device *pdev)
864867
{

0 commit comments

Comments
 (0)