@@ -75,10 +75,41 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
if (err_reg) {
/* Identify the source from control status register */
err_src = __ffs(err_reg);
+
+ /* We DONOT expect err_src to go out of bounds */
+ BUG_ON(err_src > MAX_CLKDM_TARGETS);
+
l3_targ_inst = &l3_targ[i][err_src];
target_name = l3_targ_inst->name;
l3_targ_base = base + l3_targ_inst->offset;
+ /*
+ * If we do not know of a register offset to decode
+ * and clear, then mask.
+ */
+ if (target_name == L3_TARGET_NOT_SUPPORTED) {
+ u32 mask_val;
+ void __iomem *mask_reg;
+
+ /*
+ * Certain plaforms may have "undocumented"
+ * status pending on boot.. So dont generate
+ * a severe warning here.
+ */
+ dev_err(l3->dev,
+ "L3 %s error: target %d mod:%d %s\n",
+ inttype ? "debug" : "application",
+ err_src, i, "(unclearable)");
+
+ mask_reg = base + l3_flagmux[i] +
+ L3_FLAGMUX_MASK0 + (inttype << 3);
+ mask_val = readl_relaxed(mask_reg);
+ mask_val &= ~(1 << err_src);
+ writel_relaxed(mask_val, mask_reg);
+
+ break;
+ }
+
/* Read the stderrlog_main_source from clk domain */
l3_targ_stderr = l3_targ_base + L3_TARG_STDERRLOG_MAIN;
l3_targ_slvofslsb = l3_targ_base +
@@ -30,6 +30,11 @@
#define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c
#define L3_TARG_STDERRLOG_MSTADDR 0x68
#define L3_FLAGMUX_REGERR0 0xc
+#define L3_FLAGMUX_MASK0 0x8
+
+#define L3_TARGET_NOT_SUPPORTED NULL
+
+#define MAX_CLKDM_TARGETS 31
#define NUM_OF_L3_MASTERS (sizeof(l3_masters)/sizeof(l3_masters[0]))
@@ -61,7 +66,7 @@ static u32 l3_flagmux[L3_MODULES] = {
0X0200
};
-static struct l3_target_data l3_target_inst_data_clk1[] = {
+static struct l3_target_data l3_target_inst_data_clk1[MAX_CLKDM_TARGETS] = {
{0x100, "DMM1",},
{0x200, "DMM2",},
{0x300, "ABE",},
@@ -71,7 +76,7 @@ static struct l3_target_data l3_target_inst_data_clk1[] = {
{0x900, "L4WAKEUP",},
};
-static struct l3_target_data l3_target_inst_data_clk2[] = {
+static struct l3_target_data l3_target_inst_data_clk2[MAX_CLKDM_TARGETS] = {
{0x500, "CORTEXM3",},
{0x300, "DSS",},
{0x100, "GPMC",},
@@ -95,7 +100,7 @@ static struct l3_target_data l3_target_inst_data_clk2[] = {
{0x1700, "LLI",},
};
-static struct l3_target_data l3_target_inst_data_clk3[] = {
+static struct l3_target_data l3_target_inst_data_clk3[MAX_CLKDM_TARGETS] = {
{0x0100, "EMUSS",},
{0x0300, "DEBUG SOURCE",},
{0x0, "HOST CLK3",},