aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bus
diff options
context:
space:
mode:
authorAfzal Mohammed <afzal@ti.com>2014-04-25 18:38:11 -0400
committerNishanth Menon <nm@ti.com>2014-05-05 15:34:03 -0400
commit2100b595b756db29a0b71de49c3bf73ae76c679b (patch)
treeb32849d21bbb6f5f8d4997457b8a1109387d0b04 /drivers/bus
parente4be3f3a040432398225d3634d44fc21f4807b7a (diff)
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>
Diffstat (limited to 'drivers/bus')
-rw-r--r--drivers/bus/omap_l3_noc.c9
-rw-r--r--drivers/bus/omap_l3_noc.h4
2 files changed, 13 insertions, 0 deletions
diff --git a/drivers/bus/omap_l3_noc.c b/drivers/bus/omap_l3_noc.c
index 0691e6d9c1e4..00e4fed4a39b 100644
--- a/drivers/bus/omap_l3_noc.c
+++ b/drivers/bus/omap_l3_noc.c
@@ -169,6 +169,9 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
169 err_reg = readl_relaxed(base + flag_mux->offset + 169 err_reg = readl_relaxed(base + flag_mux->offset +
170 L3_FLAGMUX_REGERR0 + (inttype << 3)); 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 /* Get the corresponding error and analyse */ 175 /* Get the corresponding error and analyse */
173 if (err_reg) { 176 if (err_reg) {
174 /* Identify the source from control status register */ 177 /* Identify the source from control status register */
@@ -193,6 +196,12 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
193 mask_val = readl_relaxed(mask_reg); 196 mask_val = readl_relaxed(mask_reg);
194 mask_val &= ~(1 << err_src); 197 mask_val &= ~(1 << err_src);
195 writel_relaxed(mask_val, mask_reg); 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 /* Error found so break the for loop */ 207 /* Error found so break the for loop */
diff --git a/drivers/bus/omap_l3_noc.h b/drivers/bus/omap_l3_noc.h
index ea2f51c984f1..4e18307470f6 100644
--- a/drivers/bus/omap_l3_noc.h
+++ b/drivers/bus/omap_l3_noc.h
@@ -66,11 +66,15 @@ struct l3_target_data {
66 * target data. unsupported ones are marked with 66 * target data. unsupported ones are marked with
67 * L3_TARGET_NOT_SUPPORTED 67 * L3_TARGET_NOT_SUPPORTED
68 * @num_targ_data: number of entries in target data 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 */
70struct l3_flagmux_data { 72struct l3_flagmux_data {
71 u32 offset; 73 u32 offset;
72 struct l3_target_data *l3_targ; 74 struct l3_target_data *l3_targ;
73 u8 num_targ_data; 75 u8 num_targ_data;
76 u32 mask_app_bits;
77 u32 mask_dbg_bits;
74}; 78};
75 79
76 80