summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/system-coldfire.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-06-17 03:09:47 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-06-17 03:09:47 +0000
commitd4800fa3851d2d89c1be03ec99af81f277892579 (patch)
tree60c2beebe08192b2ba6a9c2db31e4409aa940b4e /firmware/target/coldfire/system-coldfire.c
parent7b605f04168400f3b1b2024600886045f0103c3a (diff)
downloadrockbox-d4800fa3851d2d89c1be03ec99af81f277892579.tar.gz
rockbox-d4800fa3851d2d89c1be03ec99af81f277892579.zip
Coldfire: Fix the modification of IMR. Interrupts must be masked at the core level at at least the level of the interrupt being masked. Not following the datasheet and relying strictly on and/or_l causes unhandled 'Levelx' exceptions (showing itself quite often in PCM mixer work which more greatly stresses PCM lockout).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30009 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/coldfire/system-coldfire.c')
-rw-r--r--firmware/target/coldfire/system-coldfire.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c
index 61a5da98cd..1fbd00825a 100644
--- a/firmware/target/coldfire/system-coldfire.c
+++ b/firmware/target/coldfire/system-coldfire.c
@@ -268,7 +268,7 @@ void system_init(void)
268 will do. */ 268 will do. */
269 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); 269 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
270 270
271 IMR = 0x3ffff; 271 coldfire_imr_mod(0x3ffff, 0x3ffff);
272 INTPRI1 = 0; 272 INTPRI1 = 0;
273 INTPRI2 = 0; 273 INTPRI2 = 0;
274 INTPRI3 = 0; 274 INTPRI3 = 0;
@@ -365,6 +365,16 @@ void coldfire_set_pllcr_audio_bits(long bits)
365 PLLCR = (PLLCR & ~0x70400000) | (bits & 0x70400000); 365 PLLCR = (PLLCR & ~0x70400000) | (bits & 0x70400000);
366} 366}
367 367
368/* Safely modify the interrupt mask register as the core interrupt level is
369 required to be at least as high as the level interrupt being
370 masked/unmasked */
371void coldfire_imr_mod(unsigned long bits, unsigned long mask)
372{
373 unsigned long oldlevel = set_irq_level(DISABLE_INTERRUPTS);
374 IMR = (IMR & ~mask) | (bits & mask);
375 restore_irq(oldlevel);
376}
377
368/* Set DATAINCONTROL without disturbing FIFO reset state */ 378/* Set DATAINCONTROL without disturbing FIFO reset state */
369void coldfire_set_dataincontrol(unsigned long value) 379void coldfire_set_dataincontrol(unsigned long value)
370{ 380{