diff options
Diffstat (limited to 'arch/blackfin/mach-common/interrupt.S')
-rw-r--r-- | arch/blackfin/mach-common/interrupt.S | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index 0069c2dd4625..9c46680186e4 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S | |||
@@ -145,6 +145,14 @@ __common_int_entry: | |||
145 | 145 | ||
146 | /* interrupt routine for ivhw - 5 */ | 146 | /* interrupt routine for ivhw - 5 */ |
147 | ENTRY(_evt_ivhw) | 147 | ENTRY(_evt_ivhw) |
148 | /* In case a single action kicks off multiple memory transactions, (like | ||
149 | * a cache line fetch, - this can cause multiple hardware errors, let's | ||
150 | * catch them all. First - make sure all the actions are complete, and | ||
151 | * the core sees the hardware errors. | ||
152 | */ | ||
153 | SSYNC; | ||
154 | SSYNC; | ||
155 | |||
148 | SAVE_ALL_SYS | 156 | SAVE_ALL_SYS |
149 | #ifdef CONFIG_FRAME_POINTER | 157 | #ifdef CONFIG_FRAME_POINTER |
150 | fp = 0; | 158 | fp = 0; |
@@ -159,6 +167,25 @@ ENTRY(_evt_ivhw) | |||
159 | 1: | 167 | 1: |
160 | #endif | 168 | #endif |
161 | 169 | ||
170 | /* Handle all stacked hardware errors | ||
171 | * To make sure we don't hang forever, only do it 10 times | ||
172 | */ | ||
173 | R0 = 0; | ||
174 | R2 = 10; | ||
175 | 1: | ||
176 | P0.L = LO(ILAT); | ||
177 | P0.H = HI(ILAT); | ||
178 | R1 = [P0]; | ||
179 | CC = BITTST(R1, EVT_IVHW_P); | ||
180 | IF ! CC JUMP 2f; | ||
181 | /* OK a hardware error is pending - clear it */ | ||
182 | R1 = EVT_IVHW_P; | ||
183 | [P0] = R1; | ||
184 | R0 += 1; | ||
185 | CC = R1 == R2; | ||
186 | if CC JUMP 2f; | ||
187 | JUMP 1b; | ||
188 | 2: | ||
162 | # We are going to dump something out, so make sure we print IPEND properly | 189 | # We are going to dump something out, so make sure we print IPEND properly |
163 | p2.l = lo(IPEND); | 190 | p2.l = lo(IPEND); |
164 | p2.h = hi(IPEND); | 191 | p2.h = hi(IPEND); |