Commit 2100b595b756db29a0b71de49c3bf73ae76c679b

Authored by Afzal Mohammed
Committed by Nishanth Menon
1 parent e4be3f3a04

bus: omap_l3_noc: ignore masked out unclearable targets

Errors that cannot be cleared (determined by reading REGERR register)
are currently handled by masking it. Documentation states that REGERR
"Checks which application/debug error sources are active" - it does not
indicate that this is "interrupt status" - masked out status represented
eventually in the irq line to MPU.
For example:

Lets say module 0 bit 8(0x100) was unclearable, we do the mask it from
generating further errors. However in the following cases:
a) bit 9 of Module 0
OR
b) any bit of Module 1+
occur, the interrupt handler wrongly assumes that the raw interrupt
status of module 0 bit 8 is the root cause of the interrupt, and
returns. This causes unhandled interrupt and resultant infinite
interrupts.

Fix this scenario by storing the events we masked out and masking raw
status with masked ones before identifying and handling the error.

Reported-by: Vaibhav Hiremath <hvaibhav@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Tested-by: Vaibhav Hiremath <hvaibhav@gmail.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Tested-by: Sekhar Nori <nsekhar@ti.com>

Showing 2 changed files with 13 additions and 0 deletions Side-by-side Diff

drivers/bus/omap_l3_noc.c
... ... @@ -169,6 +169,9 @@
169 169 err_reg = readl_relaxed(base + flag_mux->offset +
170 170 L3_FLAGMUX_REGERR0 + (inttype << 3));
171 171  
  172 + err_reg &= ~(inttype ? flag_mux->mask_app_bits :
  173 + flag_mux->mask_dbg_bits);
  174 +
172 175 /* Get the corresponding error and analyse */
173 176 if (err_reg) {
174 177 /* Identify the source from control status register */
... ... @@ -193,6 +196,12 @@
193 196 mask_val = readl_relaxed(mask_reg);
194 197 mask_val &= ~(1 << err_src);
195 198 writel_relaxed(mask_val, mask_reg);
  199 +
  200 + /* Mark these bits as to be ignored */
  201 + if (inttype)
  202 + flag_mux->mask_app_bits |= 1 << err_src;
  203 + else
  204 + flag_mux->mask_dbg_bits |= 1 << err_src;
196 205 }
197 206  
198 207 /* Error found so break the for loop */
drivers/bus/omap_l3_noc.h
... ... @@ -66,11 +66,15 @@
66 66 * target data. unsupported ones are marked with
67 67 * L3_TARGET_NOT_SUPPORTED
68 68 * @num_targ_data: number of entries in target data
  69 + * @mask_app_bits: ignore these from raw application irq status
  70 + * @mask_dbg_bits: ignore these from raw debug irq status
69 71 */
70 72 struct l3_flagmux_data {
71 73 u32 offset;
72 74 struct l3_target_data *l3_targ;
73 75 u8 num_targ_data;
  76 + u32 mask_app_bits;
  77 + u32 mask_dbg_bits;
74 78 };
75 79  
76 80