summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/debug_menu.c15
-rw-r--r--apps/main.c6
-rw-r--r--apps/plugins/wavplay.c4
-rw-r--r--apps/plugins/wavrecord.c4
-rw-r--r--bootloader/iaudio_coldfire.c2
-rw-r--r--bootloader/iriver_h1x0.c2
-rw-r--r--bootloader/iriver_h300.c6
-rwxr-xr-xbootloader/mrobe500.c4
-rw-r--r--firmware/drivers/audio/uda1380.c4
-rw-r--r--firmware/drivers/button.c4
-rw-r--r--firmware/drivers/rtc/rtc_pcf50606.c8
-rw-r--r--firmware/kernel.c96
-rw-r--r--firmware/mp3_playback.c4
-rw-r--r--firmware/mpeg.c12
-rw-r--r--firmware/rolo.c6
-rw-r--r--firmware/target/arm/i2c-pp.c12
-rw-r--r--firmware/target/arm/ipod/backlight-nano_video.c8
-rw-r--r--firmware/target/arm/ipod/video/lcd-video.c10
-rw-r--r--firmware/target/arm/pcm-pp.c16
-rw-r--r--firmware/target/arm/pnx0101/iriver-ifp7xx/power-ifp7xx.c5
-rw-r--r--firmware/target/arm/pnx0101/system-pnx0101.c4
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c12
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c4
-rw-r--r--firmware/target/arm/system-arm.h97
-rw-r--r--firmware/target/arm/tatung/tpj1022/backlight-tpj1022.c8
-rw-r--r--firmware/target/arm/tms320dm320/dsp-dm320.c4
-rw-r--r--firmware/target/arm/tms320dm320/timer-dm320.c4
-rw-r--r--firmware/target/coldfire/iaudio/adc-iaudio.c4
-rw-r--r--firmware/target/coldfire/iaudio/m3/audio-m3.c2
-rw-r--r--firmware/target/coldfire/iaudio/m5/audio-m5.c2
-rw-r--r--firmware/target/coldfire/iaudio/m5/backlight-m5.c8
-rw-r--r--firmware/target/coldfire/iaudio/m5/power-m5.c8
-rw-r--r--firmware/target/coldfire/iaudio/pcf50606-iaudio.c4
-rw-r--r--firmware/target/coldfire/iaudio/x5/audio-x5.c2
-rw-r--r--firmware/target/coldfire/iaudio/x5/backlight-x5.c12
-rw-r--r--firmware/target/coldfire/iaudio/x5/ds2411-x5.c4
-rw-r--r--firmware/target/coldfire/iaudio/x5/power-x5.c8
-rw-r--r--firmware/target/coldfire/iriver/audio-iriver.c2
-rw-r--r--firmware/target/coldfire/iriver/h100/adc-h100.c4
-rw-r--r--firmware/target/coldfire/iriver/h100/power-h100.c3
-rw-r--r--firmware/target/coldfire/iriver/h100/spdif-h100.c2
-rw-r--r--firmware/target/coldfire/iriver/h300/adc-h300.c4
-rw-r--r--firmware/target/coldfire/iriver/h300/backlight-h300.c4
-rw-r--r--firmware/target/coldfire/iriver/h300/power-h300.c3
-rw-r--r--firmware/target/coldfire/iriver/lcd-remote-iriver.c4
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c4
-rw-r--r--firmware/target/coldfire/system-coldfire.c2
-rw-r--r--firmware/target/coldfire/system-target.h49
-rw-r--r--firmware/target/sh/archos/fm_v2/power-fm_v2.c5
-rw-r--r--firmware/target/sh/archos/ondio/power-ondio.c5
-rw-r--r--firmware/target/sh/archos/player/power-player.c5
-rw-r--r--firmware/target/sh/archos/recorder/power-recorder.c5
-rw-r--r--firmware/target/sh/system-sh.c2
-rw-r--r--firmware/target/sh/system-target.h20
-rw-r--r--firmware/test/i2c/main.c2
-rw-r--r--firmware/test/kernel/main.c2
-rw-r--r--firmware/thread.c82
-rw-r--r--firmware/usb.c4
-rw-r--r--flash/bootbox/main.c2
-rw-r--r--uisimulator/sdl/system-sdl.h13
-rw-r--r--uisimulator/sdl/thread-sdl.c16
61 files changed, 381 insertions, 278 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index fc509ce236..d21dc032a8 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -417,7 +417,7 @@ static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
417 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */ 417 not_id = flash[1]; /* should be 'A' (0x41) and 'R' (0x52) from the "ARCH" marker */
418 418
419 /* disable interrupts, prevent any stray flash access */ 419 /* disable interrupts, prevent any stray flash access */
420 old_level = set_irq_level(HIGHEST_IRQ_LEVEL); 420 old_level = disable_irq_save();
421 421
422 flash[addr1] = 0xAA; /* enter command mode */ 422 flash[addr1] = 0xAA; /* enter command mode */
423 flash[addr2] = 0x55; 423 flash[addr2] = 0x55;
@@ -432,7 +432,7 @@ static bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device,
432 /* Atmel wants 20ms pause here */ 432 /* Atmel wants 20ms pause here */
433 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */ 433 /* sleep(HZ/50); no sleeping possible while interrupts are disabled */
434 434
435 set_irq_level(old_level); /* enable interrupts again */ 435 restore_irq(old_level); /* enable interrupts again */
436 436
437 /* I assume success if the obtained values are different from 437 /* I assume success if the obtained values are different from
438 the normal flash content. This is not perfectly bulletproof, they 438 the normal flash content. This is not perfectly bulletproof, they
@@ -2066,9 +2066,12 @@ static bool dbg_save_roms(void)
2066 char buf[EEPROM_SIZE]; 2066 char buf[EEPROM_SIZE];
2067 int err; 2067 int err;
2068 2068
2069 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); 2069 old_irq_level = disable_irq_save();
2070 2070
2071 err = eeprom_24cxx_read(0, buf, sizeof buf); 2071 err = eeprom_24cxx_read(0, buf, sizeof buf);
2072
2073 restore_irq(old_irq_level);
2074
2072 if (err) 2075 if (err)
2073 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err); 2076 gui_syncsplash(HZ*3, "Eeprom read failure (%d)",err);
2074 else 2077 else
@@ -2076,8 +2079,6 @@ static bool dbg_save_roms(void)
2076 write(fd, buf, sizeof buf); 2079 write(fd, buf, sizeof buf);
2077 } 2080 }
2078 2081
2079 set_irq_level(old_irq_level);
2080
2081 close(fd); 2082 close(fd);
2082 } 2083 }
2083#endif 2084#endif
@@ -2248,7 +2249,7 @@ static bool dbg_write_eeprom(void)
2248 2249
2249 if(rc == EEPROM_SIZE) 2250 if(rc == EEPROM_SIZE)
2250 { 2251 {
2251 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); 2252 old_irq_level = disable_irq_save();
2252 2253
2253 err = eeprom_24cxx_write(0, buf, sizeof buf); 2254 err = eeprom_24cxx_write(0, buf, sizeof buf);
2254 if (err) 2255 if (err)
@@ -2256,7 +2257,7 @@ static bool dbg_write_eeprom(void)
2256 else 2257 else
2257 gui_syncsplash(HZ*3, "Eeprom written successfully"); 2258 gui_syncsplash(HZ*3, "Eeprom written successfully");
2258 2259
2259 set_irq_level(old_irq_level); 2260 restore_irq(old_irq_level);
2260 } 2261 }
2261 else 2262 else
2262 { 2263 {
diff --git a/apps/main.c b/apps/main.c
index a3a2241f44..3f83850df7 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -272,7 +272,7 @@ static void init(void)
272{ 272{
273 kernel_init(); 273 kernel_init();
274 buffer_init(); 274 buffer_init();
275 set_irq_level(0); 275 enable_irq();
276 lcd_init(); 276 lcd_init();
277#ifdef HAVE_REMOTE_LCD 277#ifdef HAVE_REMOTE_LCD
278 lcd_remote_init(); 278 lcd_remote_init();
@@ -360,9 +360,9 @@ static void init(void)
360 360
361 power_init(); 361 power_init();
362 362
363 set_irq_level(0); 363 enable_irq();
364#ifdef CPU_ARM 364#ifdef CPU_ARM
365 set_fiq_status(FIQ_ENABLED); 365 enable_fiq();
366#endif 366#endif
367 lcd_init(); 367 lcd_init();
368#ifdef HAVE_REMOTE_LCD 368#ifdef HAVE_REMOTE_LCD
diff --git a/apps/plugins/wavplay.c b/apps/plugins/wavplay.c
index 6a969f187b..bf06787dd9 100644
--- a/apps/plugins/wavplay.c
+++ b/apps/plugins/wavplay.c
@@ -3345,7 +3345,7 @@ void dma_end_isr(void)
3345 3345
3346void demand_irq_enable(bool on) 3346void demand_irq_enable(bool on)
3347{ 3347{
3348 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 3348 int oldlevel = disable_irq_save();
3349 3349
3350 if(on) 3350 if(on)
3351 { 3351 {
@@ -3357,7 +3357,7 @@ void demand_irq_enable(bool on)
3357 IPRA &= 0xfff0; 3357 IPRA &= 0xfff0;
3358 } 3358 }
3359 3359
3360 set_irq_level(oldlevel); 3360 restore_irq(oldlevel);
3361} 3361}
3362 3362
3363static inline int available(void) 3363static inline int available(void)
diff --git a/apps/plugins/wavrecord.c b/apps/plugins/wavrecord.c
index ee557633a4..b509212239 100644
--- a/apps/plugins/wavrecord.c
+++ b/apps/plugins/wavrecord.c
@@ -3415,7 +3415,7 @@ void rec_tick(void)
3415 3415
3416void rec_tick_enable(bool on) 3416void rec_tick_enable(bool on)
3417{ 3417{
3418 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 3418 int oldlevel = disable_irq_save();
3419 3419
3420 if(on) 3420 if(on)
3421 { 3421 {
@@ -3431,7 +3431,7 @@ void rec_tick_enable(bool on)
3431 IPRB = (IPRB & 0xff0f) | 0x0080; /* Reenable IRQ6 */ 3431 IPRB = (IPRB & 0xff0f) | 0x0080; /* Reenable IRQ6 */
3432 } 3432 }
3433 3433
3434 set_irq_level(oldlevel); 3434 restore_irq(oldlevel);
3435} 3435}
3436 3436
3437void hijack_interrupts(bool on) 3437void hijack_interrupts(bool on)
diff --git a/bootloader/iaudio_coldfire.c b/bootloader/iaudio_coldfire.c
index 0f3798d783..c1076e98cc 100644
--- a/bootloader/iaudio_coldfire.c
+++ b/bootloader/iaudio_coldfire.c
@@ -164,7 +164,7 @@ void main(void)
164 set_cpu_frequency(CPUFREQ_NORMAL); 164 set_cpu_frequency(CPUFREQ_NORMAL);
165 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); 165 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
166 166
167 set_irq_level(0); 167 enable_irq();
168 lcd_init(); 168 lcd_init();
169#ifdef HAVE_REMOTE_LCD 169#ifdef HAVE_REMOTE_LCD
170 lcd_remote_init(); 170 lcd_remote_init();
diff --git a/bootloader/iriver_h1x0.c b/bootloader/iriver_h1x0.c
index 6b3527be7a..4be92eb4ac 100644
--- a/bootloader/iriver_h1x0.c
+++ b/bootloader/iriver_h1x0.c
@@ -435,7 +435,7 @@ void main(void)
435 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); 435 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
436#endif 436#endif
437#endif 437#endif
438 set_irq_level(0); 438 enable_irq();
439 439
440#ifdef HAVE_EEPROM_SETTINGS 440#ifdef HAVE_EEPROM_SETTINGS
441 initialize_eeprom(); 441 initialize_eeprom();
diff --git a/bootloader/iriver_h300.c b/bootloader/iriver_h300.c
index 1840966aa1..3349be4c2b 100644
--- a/bootloader/iriver_h300.c
+++ b/bootloader/iriver_h300.c
@@ -175,10 +175,10 @@ void main(void)
175 } 175 }
176 176
177 /* get rid of a nasty humming sound during boot */ 177 /* get rid of a nasty humming sound during boot */
178 mask = set_irq_level(HIGHEST_IRQ_LEVEL); 178 mask = disable_irq_save();
179 pcf50606_write(0x3b, 0x00); /* GPOOD2 high Z */ 179 pcf50606_write(0x3b, 0x00); /* GPOOD2 high Z */
180 pcf50606_write(0x3b, 0x07); /* GPOOD2 low */ 180 pcf50606_write(0x3b, 0x07); /* GPOOD2 low */
181 set_irq_level(mask); 181 restore_irq(mask);
182 182
183 /* Start with the main backlight OFF. */ 183 /* Start with the main backlight OFF. */
184 _backlight_init(); 184 _backlight_init();
@@ -192,7 +192,7 @@ void main(void)
192 /* Set up waitstates for the peripherals */ 192 /* Set up waitstates for the peripherals */
193 set_cpu_frequency(0); /* PLL off */ 193 set_cpu_frequency(0); /* PLL off */
194 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); 194 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
195 set_irq_level(0); 195 enable_irq();
196 196
197 isp1362_init(); 197 isp1362_init();
198 198
diff --git a/bootloader/mrobe500.c b/bootloader/mrobe500.c
index 1dbe7b8edb..e6dc58118d 100755
--- a/bootloader/mrobe500.c
+++ b/bootloader/mrobe500.c
@@ -174,8 +174,8 @@ void main(void)
174 system_init(); 174 system_init();
175 kernel_init(); 175 kernel_init();
176 176
177 set_irq_level(0); 177 enable_irq();
178 set_fiq_status(FIQ_ENABLED); 178 enable_fiq();
179 179
180 adc_init(); 180 adc_init();
181 button_init(); 181 button_init();
diff --git a/firmware/drivers/audio/uda1380.c b/firmware/drivers/audio/uda1380.c
index ce69ef6b80..f6a7c730cb 100644
--- a/firmware/drivers/audio/uda1380.c
+++ b/firmware/drivers/audio/uda1380.c
@@ -203,10 +203,10 @@ void audiohw_enable_output(bool enable)
203static void reset(void) 203static void reset(void)
204{ 204{
205#ifdef IRIVER_H300_SERIES 205#ifdef IRIVER_H300_SERIES
206 int mask = set_irq_level(HIGHEST_IRQ_LEVEL); 206 int mask = disable_irq_save();
207 pcf50606_write(0x3b, 0x00); /* GPOOD2 high Z */ 207 pcf50606_write(0x3b, 0x00); /* GPOOD2 high Z */
208 pcf50606_write(0x3b, 0x07); /* GPOOD2 low */ 208 pcf50606_write(0x3b, 0x07); /* GPOOD2 low */
209 set_irq_level(mask); 209 restore_irq(mask);
210#else 210#else
211 /* RESET signal */ 211 /* RESET signal */
212 or_l(1<<29, &GPIO_OUT); 212 or_l(1<<29, &GPIO_OUT);
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index b9473bec24..d38306b3ca 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -465,10 +465,10 @@ void button_set_flip(bool flip)
465 if (flip != flipped) /* not the current setting */ 465 if (flip != flipped) /* not the current setting */
466 { 466 {
467 /* avoid race condition with the button_tick() */ 467 /* avoid race condition with the button_tick() */
468 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 468 int oldlevel = disable_irq_save();
469 lastbtn = button_flip(lastbtn); 469 lastbtn = button_flip(lastbtn);
470 flipped = flip; 470 flipped = flip;
471 set_irq_level(oldlevel); 471 restore_irq(oldlevel);
472 } 472 }
473} 473}
474#endif /* HAVE_LCD_BITMAP */ 474#endif /* HAVE_LCD_BITMAP */
diff --git a/firmware/drivers/rtc/rtc_pcf50606.c b/firmware/drivers/rtc/rtc_pcf50606.c
index 25b0c704c0..9b4de44d3f 100644
--- a/firmware/drivers/rtc/rtc_pcf50606.c
+++ b/firmware/drivers/rtc/rtc_pcf50606.c
@@ -30,21 +30,21 @@ void rtc_init(void)
30 30
31int rtc_read_datetime(unsigned char* buf) { 31int rtc_read_datetime(unsigned char* buf) {
32 int rc; 32 int rc;
33 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 33 int oldlevel = disable_irq_save();
34 34
35 rc = pcf50606_read_multiple(0x0a, buf, 7); 35 rc = pcf50606_read_multiple(0x0a, buf, 7);
36 36
37 set_irq_level(oldlevel); 37 restore_irq(oldlevel);
38 return rc; 38 return rc;
39} 39}
40 40
41int rtc_write_datetime(unsigned char* buf) { 41int rtc_write_datetime(unsigned char* buf) {
42 int rc; 42 int rc;
43 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 43 int oldlevel = disable_irq_save();
44 44
45 rc = pcf50606_write_multiple(0x0a, buf, 7); 45 rc = pcf50606_write_multiple(0x0a, buf, 7);
46 46
47 set_irq_level(oldlevel); 47 restore_irq(oldlevel);
48 48
49 return rc; 49 return rc;
50} 50}
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 47c0d58a95..be0cfb56a4 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -270,7 +270,7 @@ void tick_start(unsigned int interval_in_ms)
270int tick_add_task(void (*f)(void)) 270int tick_add_task(void (*f)(void))
271{ 271{
272 int i; 272 int i;
273 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 273 int oldlevel = disable_irq_save();
274 274
275 /* Add a task if there is room */ 275 /* Add a task if there is room */
276 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 276 for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
@@ -278,11 +278,11 @@ int tick_add_task(void (*f)(void))
278 if(tick_funcs[i] == NULL) 278 if(tick_funcs[i] == NULL)
279 { 279 {
280 tick_funcs[i] = f; 280 tick_funcs[i] = f;
281 set_irq_level(oldlevel); 281 restore_irq(oldlevel);
282 return 0; 282 return 0;
283 } 283 }
284 } 284 }
285 set_irq_level(oldlevel); 285 restore_irq(oldlevel);
286 panicf("Error! tick_add_task(): out of tasks"); 286 panicf("Error! tick_add_task(): out of tasks");
287 return -1; 287 return -1;
288} 288}
@@ -290,7 +290,7 @@ int tick_add_task(void (*f)(void))
290int tick_remove_task(void (*f)(void)) 290int tick_remove_task(void (*f)(void))
291{ 291{
292 int i; 292 int i;
293 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 293 int oldlevel = disable_irq_save();
294 294
295 /* Remove a task if it is there */ 295 /* Remove a task if it is there */
296 for(i = 0;i < MAX_NUM_TICK_TASKS;i++) 296 for(i = 0;i < MAX_NUM_TICK_TASKS;i++)
@@ -298,12 +298,12 @@ int tick_remove_task(void (*f)(void))
298 if(tick_funcs[i] == f) 298 if(tick_funcs[i] == f)
299 { 299 {
300 tick_funcs[i] = NULL; 300 tick_funcs[i] = NULL;
301 set_irq_level(oldlevel); 301 restore_irq(oldlevel);
302 return 0; 302 return 0;
303 } 303 }
304 } 304 }
305 305
306 set_irq_level(oldlevel); 306 restore_irq(oldlevel);
307 return -1; 307 return -1;
308} 308}
309 309
@@ -341,7 +341,7 @@ static void timeout_tick(void)
341/* Cancels a timeout callback - can be called from the ISR */ 341/* Cancels a timeout callback - can be called from the ISR */
342void timeout_cancel(struct timeout *tmo) 342void timeout_cancel(struct timeout *tmo)
343{ 343{
344 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 344 int oldlevel = disable_irq_save();
345 345
346 if (tmo_list != NULL) 346 if (tmo_list != NULL)
347 { 347 {
@@ -368,7 +368,7 @@ void timeout_cancel(struct timeout *tmo)
368 /* not in list or tmo == NULL */ 368 /* not in list or tmo == NULL */
369 } 369 }
370 370
371 set_irq_level(oldlevel); 371 restore_irq(oldlevel);
372} 372}
373 373
374/* Adds a timeout callback - calling with an active timeout resets the 374/* Adds a timeout callback - calling with an active timeout resets the
@@ -382,7 +382,7 @@ void timeout_register(struct timeout *tmo, timeout_cb_type callback,
382 if (tmo == NULL) 382 if (tmo == NULL)
383 return; 383 return;
384 384
385 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 385 oldlevel = disable_irq_save();
386 386
387 /* see if this one is already registered */ 387 /* see if this one is already registered */
388 curr = tmo_list; 388 curr = tmo_list;
@@ -404,7 +404,7 @@ void timeout_register(struct timeout *tmo, timeout_cb_type callback,
404 tmo->data = data; 404 tmo->data = data;
405 *(long *)&tmo->expires = current_tick + ticks; 405 *(long *)&tmo->expires = current_tick + ticks;
406 406
407 set_irq_level(oldlevel); 407 restore_irq(oldlevel);
408} 408}
409 409
410#endif /* INCLUDE_TIMEOUT_API */ 410#endif /* INCLUDE_TIMEOUT_API */
@@ -433,7 +433,7 @@ void sleep(int ticks)
433 while (TIME_BEFORE(USEC_TIMER, stop)) 433 while (TIME_BEFORE(USEC_TIMER, stop))
434 switch_thread(); 434 switch_thread();
435#else 435#else
436 set_irq_level(HIGHEST_IRQ_LEVEL); 436 disable_irq();
437 sleep_thread(ticks); 437 sleep_thread(ticks);
438 switch_thread(); 438 switch_thread();
439#endif 439#endif
@@ -537,7 +537,7 @@ void queue_enable_queue_send(struct event_queue *q,
537 struct queue_sender_list *send, 537 struct queue_sender_list *send,
538 struct thread_entry *owner) 538 struct thread_entry *owner)
539{ 539{
540 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 540 int oldlevel = disable_irq_save();
541 corelock_lock(&q->cl); 541 corelock_lock(&q->cl);
542 542
543 if(send != NULL && q->send == NULL) 543 if(send != NULL && q->send == NULL)
@@ -554,7 +554,7 @@ void queue_enable_queue_send(struct event_queue *q,
554 } 554 }
555 555
556 corelock_unlock(&q->cl); 556 corelock_unlock(&q->cl);
557 set_irq_level(oldlevel); 557 restore_irq(oldlevel);
558 558
559 (void)owner; 559 (void)owner;
560} 560}
@@ -618,7 +618,7 @@ static inline void queue_do_fetch_sender(struct queue_sender_list *send,
618/* Queue must not be available for use during this call */ 618/* Queue must not be available for use during this call */
619void queue_init(struct event_queue *q, bool register_queue) 619void queue_init(struct event_queue *q, bool register_queue)
620{ 620{
621 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 621 int oldlevel = disable_irq_save();
622 622
623 if(register_queue) 623 if(register_queue)
624 { 624 {
@@ -645,7 +645,7 @@ void queue_init(struct event_queue *q, bool register_queue)
645 corelock_unlock(&all_queues.cl); 645 corelock_unlock(&all_queues.cl);
646 } 646 }
647 647
648 set_irq_level(oldlevel); 648 restore_irq(oldlevel);
649} 649}
650 650
651/* Queue must not be available for use during this call */ 651/* Queue must not be available for use during this call */
@@ -654,7 +654,7 @@ void queue_delete(struct event_queue *q)
654 int oldlevel; 654 int oldlevel;
655 int i; 655 int i;
656 656
657 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 657 oldlevel = disable_irq_save();
658 corelock_lock(&all_queues.cl); 658 corelock_lock(&all_queues.cl);
659 corelock_lock(&q->cl); 659 corelock_lock(&q->cl);
660 660
@@ -697,7 +697,7 @@ void queue_delete(struct event_queue *q)
697 q->write = 0; 697 q->write = 0;
698 698
699 corelock_unlock(&q->cl); 699 corelock_unlock(&q->cl);
700 set_irq_level(oldlevel); 700 restore_irq(oldlevel);
701} 701}
702 702
703/* NOTE: multiple threads waiting on a queue head cannot have a well- 703/* NOTE: multiple threads waiting on a queue head cannot have a well-
@@ -714,7 +714,7 @@ void queue_wait(struct event_queue *q, struct queue_event *ev)
714 "queue_wait->wrong thread\n"); 714 "queue_wait->wrong thread\n");
715#endif 715#endif
716 716
717 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 717 oldlevel = disable_irq_save();
718 corelock_lock(&q->cl); 718 corelock_lock(&q->cl);
719 719
720 /* auto-reply */ 720 /* auto-reply */
@@ -734,7 +734,7 @@ void queue_wait(struct event_queue *q, struct queue_event *ev)
734 corelock_unlock(&q->cl); 734 corelock_unlock(&q->cl);
735 switch_thread(); 735 switch_thread();
736 736
737 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 737 oldlevel = disable_irq_save();
738 corelock_lock(&q->cl); 738 corelock_lock(&q->cl);
739 } 739 }
740 /* A message that woke us could now be gone */ 740 /* A message that woke us could now be gone */
@@ -748,7 +748,7 @@ void queue_wait(struct event_queue *q, struct queue_event *ev)
748 queue_do_fetch_sender(q->send, rd); 748 queue_do_fetch_sender(q->send, rd);
749 749
750 corelock_unlock(&q->cl); 750 corelock_unlock(&q->cl);
751 set_irq_level(oldlevel); 751 restore_irq(oldlevel);
752} 752}
753 753
754void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks) 754void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks)
@@ -761,7 +761,7 @@ void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks)
761 "queue_wait_w_tmo->wrong thread\n"); 761 "queue_wait_w_tmo->wrong thread\n");
762#endif 762#endif
763 763
764 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 764 oldlevel = disable_irq_save();
765 corelock_lock(&q->cl); 765 corelock_lock(&q->cl);
766 766
767 /* Auto-reply */ 767 /* Auto-reply */
@@ -779,7 +779,7 @@ void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks)
779 779
780 switch_thread(); 780 switch_thread();
781 781
782 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 782 oldlevel = disable_irq_save();
783 corelock_lock(&q->cl); 783 corelock_lock(&q->cl);
784 } 784 }
785 785
@@ -798,7 +798,7 @@ void queue_wait_w_tmo(struct event_queue *q, struct queue_event *ev, int ticks)
798 } 798 }
799 799
800 corelock_unlock(&q->cl); 800 corelock_unlock(&q->cl);
801 set_irq_level(oldlevel); 801 restore_irq(oldlevel);
802} 802}
803 803
804void queue_post(struct event_queue *q, long id, intptr_t data) 804void queue_post(struct event_queue *q, long id, intptr_t data)
@@ -806,7 +806,7 @@ void queue_post(struct event_queue *q, long id, intptr_t data)
806 int oldlevel; 806 int oldlevel;
807 unsigned int wr; 807 unsigned int wr;
808 808
809 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 809 oldlevel = disable_irq_save();
810 corelock_lock(&q->cl); 810 corelock_lock(&q->cl);
811 811
812 wr = q->write++ & QUEUE_LENGTH_MASK; 812 wr = q->write++ & QUEUE_LENGTH_MASK;
@@ -821,7 +821,7 @@ void queue_post(struct event_queue *q, long id, intptr_t data)
821 wakeup_thread(&q->queue); 821 wakeup_thread(&q->queue);
822 822
823 corelock_unlock(&q->cl); 823 corelock_unlock(&q->cl);
824 set_irq_level(oldlevel); 824 restore_irq(oldlevel);
825} 825}
826 826
827#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME 827#ifdef HAVE_EXTENDED_MESSAGING_AND_NAME
@@ -832,7 +832,7 @@ intptr_t queue_send(struct event_queue *q, long id, intptr_t data)
832 int oldlevel; 832 int oldlevel;
833 unsigned int wr; 833 unsigned int wr;
834 834
835 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 835 oldlevel = disable_irq_save();
836 corelock_lock(&q->cl); 836 corelock_lock(&q->cl);
837 837
838 wr = q->write++ & QUEUE_LENGTH_MASK; 838 wr = q->write++ & QUEUE_LENGTH_MASK;
@@ -875,7 +875,7 @@ intptr_t queue_send(struct event_queue *q, long id, intptr_t data)
875 wakeup_thread(&q->queue); 875 wakeup_thread(&q->queue);
876 876
877 corelock_unlock(&q->cl); 877 corelock_unlock(&q->cl);
878 set_irq_level(oldlevel); 878 restore_irq(oldlevel);
879 879
880 return 0; 880 return 0;
881} 881}
@@ -887,7 +887,7 @@ bool queue_in_queue_send(struct event_queue *q)
887 bool in_send; 887 bool in_send;
888 888
889#if NUM_CORES > 1 889#if NUM_CORES > 1
890 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 890 int oldlevel = disable_irq_save();
891 corelock_lock(&q->cl); 891 corelock_lock(&q->cl);
892#endif 892#endif
893 893
@@ -895,7 +895,7 @@ bool queue_in_queue_send(struct event_queue *q)
895 895
896#if NUM_CORES > 1 896#if NUM_CORES > 1
897 corelock_unlock(&q->cl); 897 corelock_unlock(&q->cl);
898 set_irq_level(oldlevel); 898 restore_irq(oldlevel);
899#endif 899#endif
900 900
901 return in_send; 901 return in_send;
@@ -907,7 +907,7 @@ void queue_reply(struct event_queue *q, intptr_t retval)
907{ 907{
908 if(q->send && q->send->curr_sender) 908 if(q->send && q->send->curr_sender)
909 { 909 {
910 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 910 int oldlevel = disable_irq_save();
911 corelock_lock(&q->cl); 911 corelock_lock(&q->cl);
912 /* Double-check locking */ 912 /* Double-check locking */
913 IF_COP( if(q->send && q->send->curr_sender) ) 913 IF_COP( if(q->send && q->send->curr_sender) )
@@ -916,7 +916,7 @@ void queue_reply(struct event_queue *q, intptr_t retval)
916 } 916 }
917 917
918 corelock_unlock(&q->cl); 918 corelock_unlock(&q->cl);
919 set_irq_level(oldlevel); 919 restore_irq(oldlevel);
920 } 920 }
921} 921}
922 922
@@ -927,7 +927,7 @@ bool queue_peek(struct event_queue *q, struct queue_event *ev)
927 927
928 bool have_msg = false; 928 bool have_msg = false;
929 929
930 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 930 int oldlevel = disable_irq_save();
931 corelock_lock(&q->cl); 931 corelock_lock(&q->cl);
932 932
933 if(q->read != q->write) 933 if(q->read != q->write)
@@ -937,7 +937,7 @@ bool queue_peek(struct event_queue *q, struct queue_event *ev)
937 } 937 }
938 938
939 corelock_unlock(&q->cl); 939 corelock_unlock(&q->cl);
940 set_irq_level(oldlevel); 940 restore_irq(oldlevel);
941 941
942 return have_msg; 942 return have_msg;
943} 943}
@@ -956,7 +956,7 @@ void queue_clear(struct event_queue* q)
956{ 956{
957 int oldlevel; 957 int oldlevel;
958 958
959 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 959 oldlevel = disable_irq_save();
960 corelock_lock(&q->cl); 960 corelock_lock(&q->cl);
961 961
962 /* Release all threads waiting in the queue for a reply - 962 /* Release all threads waiting in the queue for a reply -
@@ -967,14 +967,14 @@ void queue_clear(struct event_queue* q)
967 q->write = 0; 967 q->write = 0;
968 968
969 corelock_unlock(&q->cl); 969 corelock_unlock(&q->cl);
970 set_irq_level(oldlevel); 970 restore_irq(oldlevel);
971} 971}
972 972
973void queue_remove_from_head(struct event_queue *q, long id) 973void queue_remove_from_head(struct event_queue *q, long id)
974{ 974{
975 int oldlevel; 975 int oldlevel;
976 976
977 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 977 oldlevel = disable_irq_save();
978 corelock_lock(&q->cl); 978 corelock_lock(&q->cl);
979 979
980 while(q->read != q->write) 980 while(q->read != q->write)
@@ -993,7 +993,7 @@ void queue_remove_from_head(struct event_queue *q, long id)
993 } 993 }
994 994
995 corelock_unlock(&q->cl); 995 corelock_unlock(&q->cl);
996 set_irq_level(oldlevel); 996 restore_irq(oldlevel);
997} 997}
998 998
999/** 999/**
@@ -1012,7 +1012,7 @@ int queue_broadcast(long id, intptr_t data)
1012 int i; 1012 int i;
1013 1013
1014#if NUM_CORES > 1 1014#if NUM_CORES > 1
1015 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 1015 int oldlevel = disable_irq_save();
1016 corelock_lock(&all_queues.cl); 1016 corelock_lock(&all_queues.cl);
1017#endif 1017#endif
1018 1018
@@ -1023,7 +1023,7 @@ int queue_broadcast(long id, intptr_t data)
1023 1023
1024#if NUM_CORES > 1 1024#if NUM_CORES > 1
1025 corelock_unlock(&all_queues.cl); 1025 corelock_unlock(&all_queues.cl);
1026 set_irq_level(oldlevel); 1026 restore_irq(oldlevel);
1027#endif 1027#endif
1028 1028
1029 return i; 1029 return i;
@@ -1079,7 +1079,7 @@ void mutex_lock(struct mutex *m)
1079 IF_PRIO( current->blocker = &m->blocker; ) 1079 IF_PRIO( current->blocker = &m->blocker; )
1080 current->bqp = &m->queue; 1080 current->bqp = &m->queue;
1081 1081
1082 set_irq_level(HIGHEST_IRQ_LEVEL); 1082 disable_irq();
1083 block_thread(current); 1083 block_thread(current);
1084 1084
1085 corelock_unlock(&m->cl); 1085 corelock_unlock(&m->cl);
@@ -1118,13 +1118,13 @@ void mutex_unlock(struct mutex *m)
1118 } 1118 }
1119 else 1119 else
1120 { 1120 {
1121 const int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 1121 const int oldlevel = disable_irq_save();
1122 /* Tranfer of owning thread is handled in the wakeup protocol 1122 /* Tranfer of owning thread is handled in the wakeup protocol
1123 * if priorities are enabled otherwise just set it from the 1123 * if priorities are enabled otherwise just set it from the
1124 * queue head. */ 1124 * queue head. */
1125 IFN_PRIO( MUTEX_SET_THREAD(m, m->queue); ) 1125 IFN_PRIO( MUTEX_SET_THREAD(m, m->queue); )
1126 IF_PRIO( unsigned int result = ) wakeup_thread(&m->queue); 1126 IF_PRIO( unsigned int result = ) wakeup_thread(&m->queue);
1127 set_irq_level(oldlevel); 1127 restore_irq(oldlevel);
1128 1128
1129 corelock_unlock(&m->cl); 1129 corelock_unlock(&m->cl);
1130 1130
@@ -1219,7 +1219,7 @@ void semaphore_wait(struct semaphore *s)
1219 IF_COP( current->obj_cl = &s->cl; ) 1219 IF_COP( current->obj_cl = &s->cl; )
1220 current->bqp = &s->queue; 1220 current->bqp = &s->queue;
1221 1221
1222 set_irq_level(HIGHEST_IRQ_LEVEL); 1222 disable_irq();
1223 block_thread(current); 1223 block_thread(current);
1224 1224
1225 corelock_unlock(&s->cl); 1225 corelock_unlock(&s->cl);
@@ -1239,9 +1239,9 @@ void semaphore_release(struct semaphore *s)
1239 /* there should be threads in this queue */ 1239 /* there should be threads in this queue */
1240 KERNEL_ASSERT(s->queue != NULL, "semaphore->wakeup\n"); 1240 KERNEL_ASSERT(s->queue != NULL, "semaphore->wakeup\n");
1241 /* a thread was queued - wake it up */ 1241 /* a thread was queued - wake it up */
1242 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 1242 int oldlevel = disable_irq_save();
1243 IF_PRIO( result = ) wakeup_thread(&s->queue); 1243 IF_PRIO( result = ) wakeup_thread(&s->queue);
1244 set_irq_level(oldlevel); 1244 restore_irq(oldlevel);
1245 } 1245 }
1246 1246
1247 corelock_unlock(&s->cl); 1247 corelock_unlock(&s->cl);
@@ -1298,7 +1298,7 @@ void event_wait(struct event *e, unsigned int for_state)
1298 IF_COP( current->obj_cl = &e->cl; ) 1298 IF_COP( current->obj_cl = &e->cl; )
1299 current->bqp = &e->queues[for_state]; 1299 current->bqp = &e->queues[for_state];
1300 1300
1301 set_irq_level(HIGHEST_IRQ_LEVEL); 1301 disable_irq();
1302 block_thread(current); 1302 block_thread(current);
1303 1303
1304 corelock_unlock(&e->cl); 1304 corelock_unlock(&e->cl);
@@ -1323,7 +1323,7 @@ void event_set_state(struct event *e, unsigned int state)
1323 1323
1324 IF_PRIO( result = THREAD_OK; ) 1324 IF_PRIO( result = THREAD_OK; )
1325 1325
1326 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 1326 oldlevel = disable_irq_save();
1327 1327
1328 if(state == STATE_SIGNALED) 1328 if(state == STATE_SIGNALED)
1329 { 1329 {
@@ -1357,7 +1357,7 @@ void event_set_state(struct event *e, unsigned int state)
1357 thread_queue_wake(&e->queues[STATE_NONSIGNALED]); 1357 thread_queue_wake(&e->queues[STATE_NONSIGNALED]);
1358 } 1358 }
1359 1359
1360 set_irq_level(oldlevel); 1360 restore_irq(oldlevel);
1361 1361
1362 corelock_unlock(&e->cl); 1362 corelock_unlock(&e->cl);
1363 1363
diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c
index b2b7205318..ed71be290c 100644
--- a/firmware/mp3_playback.c
+++ b/firmware/mp3_playback.c
@@ -134,7 +134,7 @@ static void postpone_dma_tick(void)
134#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) 134#if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
135void demand_irq_enable(bool on) 135void demand_irq_enable(bool on)
136{ 136{
137 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 137 int oldlevel = disable_irq_save();
138 138
139 if(on) 139 if(on)
140 { 140 {
@@ -144,7 +144,7 @@ void demand_irq_enable(bool on)
144 else 144 else
145 IPRA &= 0xfff0; 145 IPRA &= 0xfff0;
146 146
147 set_irq_level(oldlevel); 147 restore_irq(oldlevel);
148} 148}
149#endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */ 149#endif /* #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
150 150
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index 273f630799..11cbcdcb68 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -1767,9 +1767,9 @@ static void mpeg_thread(void)
1767 DEBUGF("New audiobuf_read address: %x (%x)\n", 1767 DEBUGF("New audiobuf_read address: %x (%x)\n",
1768 audiobuf+audiobuf_read, audiobuf_read); 1768 audiobuf+audiobuf_read, audiobuf_read);
1769 1769
1770 level = set_irq_level(HIGHEST_IRQ_LEVEL); 1770 level = disable_irq_save();
1771 num_rec_bytes = get_unsaved_space(); 1771 num_rec_bytes = get_unsaved_space();
1772 set_irq_level(level); 1772 restore_irq(level);
1773 } 1773 }
1774 else 1774 else
1775 { 1775 {
@@ -1860,11 +1860,11 @@ static void mpeg_thread(void)
1860 pause_start_time = record_start_time; 1860 pause_start_time = record_start_time;
1861 1861
1862 /* capture all values at one point */ 1862 /* capture all values at one point */
1863 level = set_irq_level(HIGHEST_IRQ_LEVEL); 1863 level = disable_irq_save();
1864 save_endpos = audiobuf_write; 1864 save_endpos = audiobuf_write;
1865 last_rec_bytes = num_rec_bytes; 1865 last_rec_bytes = num_rec_bytes;
1866 num_rec_bytes = 0; 1866 num_rec_bytes = 0;
1867 set_irq_level(level); 1867 restore_irq(level);
1868 1868
1869 if (amount_to_save >= 1800) 1869 if (amount_to_save >= 1800)
1870 { 1870 {
@@ -1883,9 +1883,9 @@ static void mpeg_thread(void)
1883 save_endpos -= audiobuflen; 1883 save_endpos -= audiobuflen;
1884 1884
1885 last_rec_bytes += offset - 1800; 1885 last_rec_bytes += offset - 1800;
1886 level = set_irq_level(HIGHEST_IRQ_LEVEL); 1886 level = disable_irq_save();
1887 num_rec_bytes += 1800 - offset; 1887 num_rec_bytes += 1800 - offset;
1888 set_irq_level(level); 1888 restore_irq(level);
1889 } 1889 }
1890 1890
1891 saving_status = NEW_FILE; 1891 saving_status = NEW_FILE;
diff --git a/firmware/rolo.c b/firmware/rolo.c
index eac45e10ce..30eba91316 100644
--- a/firmware/rolo.c
+++ b/firmware/rolo.c
@@ -271,7 +271,11 @@ int rolo_load(const char* filename)
271#endif 271#endif
272 adc_close(); 272 adc_close();
273 273
274 set_irq_level(HIGHEST_IRQ_LEVEL); 274#ifdef CPU_ARM
275 disable_fiq();
276#endif
277 set_irq_level(DISABLE_INTERRUPTS);
278
275#elif CONFIG_CPU == SH7034 279#elif CONFIG_CPU == SH7034
276 /* Read file length from header and compare to real file length */ 280 /* Read file length from header and compare to real file length */
277 lseek(fd, FIRMWARE_OFFSET_FILE_LENGTH, SEEK_SET); 281 lseek(fd, FIRMWARE_OFFSET_FILE_LENGTH, SEEK_SET);
diff --git a/firmware/target/arm/i2c-pp.c b/firmware/target/arm/i2c-pp.c
index 1cfbfaeff1..450effc32d 100644
--- a/firmware/target/arm/i2c-pp.c
+++ b/firmware/target/arm/i2c-pp.c
@@ -60,7 +60,7 @@ static int pp_i2c_read_byte(unsigned int addr, unsigned int *data)
60 60
61 { 61 {
62 unsigned int byte; 62 unsigned int byte;
63 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); 63 int old_irq_level = disable_irq_save();
64 64
65 /* clear top 15 bits, left shift 1, or in 0x1 for a read */ 65 /* clear top 15 bits, left shift 1, or in 0x1 for a read */
66 I2C_ADDR = ((addr << 17) >> 16) | 0x1 ; 66 I2C_ADDR = ((addr << 17) >> 16) | 0x1 ;
@@ -69,19 +69,19 @@ static int pp_i2c_read_byte(unsigned int addr, unsigned int *data)
69 69
70 I2C_CTRL |= I2C_SEND; 70 I2C_CTRL |= I2C_SEND;
71 71
72 set_irq_level(old_irq_level); 72 restore_irq(old_irq_level);
73 if (pp_i2c_wait_not_busy() < 0) 73 if (pp_i2c_wait_not_busy() < 0)
74 { 74 {
75 return -1; 75 return -1;
76 } 76 }
77 old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); 77 old_irq_level = disable_irq_save();
78 78
79 byte = I2C_DATA(0); 79 byte = I2C_DATA(0);
80 80
81 if (data) 81 if (data)
82 *data = byte; 82 *data = byte;
83 83
84 set_irq_level(old_irq_level); 84 restore_irq(old_irq_level);
85 } 85 }
86 86
87 return 0; 87 return 0;
@@ -102,7 +102,7 @@ static int pp_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char
102 } 102 }
103 103
104 { 104 {
105 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); 105 int old_irq_level = disable_irq_save();
106 106
107 /* clear top 15 bits, left shift 1 */ 107 /* clear top 15 bits, left shift 1 */
108 I2C_ADDR = (addr << 17) >> 16; 108 I2C_ADDR = (addr << 17) >> 16;
@@ -118,7 +118,7 @@ static int pp_i2c_send_bytes(unsigned int addr, unsigned int len, unsigned char
118 118
119 I2C_CTRL |= I2C_SEND; 119 I2C_CTRL |= I2C_SEND;
120 120
121 set_irq_level(old_irq_level); 121 restore_irq(old_irq_level);
122 } 122 }
123 123
124 return 0x0; 124 return 0x0;
diff --git a/firmware/target/arm/ipod/backlight-nano_video.c b/firmware/target/arm/ipod/backlight-nano_video.c
index 6d77e2bd03..647bab9ac6 100644
--- a/firmware/target/arm/ipod/backlight-nano_video.c
+++ b/firmware/target/arm/ipod/backlight-nano_video.c
@@ -43,11 +43,11 @@ void _backlight_set_brightness(int val)
43 { 43 {
44 do 44 do
45 { 45 {
46 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 46 oldlevel = disable_irq_save();
47 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80); 47 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
48 udelay(10); 48 udelay(10);
49 GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80); 49 GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
50 set_irq_level(oldlevel); 50 restore_irq(oldlevel);
51 udelay(10); 51 udelay(10);
52 } 52 }
53 while (++current_dim < val); 53 while (++current_dim < val);
@@ -56,11 +56,11 @@ void _backlight_set_brightness(int val)
56 { 56 {
57 do 57 do
58 { 58 {
59 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 59 oldlevel = disable_irq_save();
60 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80); 60 GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
61 udelay(200); 61 udelay(200);
62 GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80); 62 GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL, 0x80);
63 set_irq_level(oldlevel); 63 restore_irq(oldlevel);
64 udelay(10); 64 udelay(10);
65 } 65 }
66 while (--current_dim > val); 66 while (--current_dim > val);
diff --git a/firmware/target/arm/ipod/video/lcd-video.c b/firmware/target/arm/ipod/video/lcd-video.c
index d0c82e905c..0e1b072917 100644
--- a/firmware/target/arm/ipod/video/lcd-video.c
+++ b/firmware/target/arm/ipod/video/lcd-video.c
@@ -110,7 +110,7 @@ static void bcm_setup_rect(unsigned x, unsigned y,
110#ifndef BOOTLOADER 110#ifndef BOOTLOADER
111static void lcd_tick(void) 111static void lcd_tick(void)
112{ 112{
113 /* No set_irq_level - already in interrupt context */ 113 /* No core level interrupt mask - already in interrupt context */
114#if NUM_CORES > 1 114#if NUM_CORES > 1
115 corelock_lock(&lcd_state.cl); 115 corelock_lock(&lcd_state.cl);
116#endif 116#endif
@@ -143,7 +143,7 @@ static void lcd_tick(void)
143 143
144static inline void lcd_block_tick(void) 144static inline void lcd_block_tick(void)
145{ 145{
146 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 146 int oldlevel = disable_irq_save();
147 147
148#if NUM_CORES > 1 148#if NUM_CORES > 1
149 corelock_lock(&lcd_state.cl); 149 corelock_lock(&lcd_state.cl);
@@ -152,14 +152,14 @@ static inline void lcd_block_tick(void)
152#else 152#else
153 lcd_state.blocked = true; 153 lcd_state.blocked = true;
154#endif 154#endif
155 set_irq_level(oldlevel); 155 restore_irq(oldlevel);
156} 156}
157 157
158static void lcd_unblock_and_update(void) 158static void lcd_unblock_and_update(void)
159{ 159{
160 unsigned data; 160 unsigned data;
161 bool bcm_is_busy; 161 bool bcm_is_busy;
162 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 162 int oldlevel = disable_irq_save();
163 163
164#if NUM_CORES > 1 164#if NUM_CORES > 1
165 corelock_lock(&lcd_state.cl); 165 corelock_lock(&lcd_state.cl);
@@ -184,7 +184,7 @@ static void lcd_unblock_and_update(void)
184#if NUM_CORES > 1 184#if NUM_CORES > 1
185 corelock_unlock(&lcd_state.cl); 185 corelock_unlock(&lcd_state.cl);
186#endif 186#endif
187 set_irq_level(oldlevel); 187 restore_irq(oldlevel);
188} 188}
189 189
190#else /* BOOTLOADER */ 190#else /* BOOTLOADER */
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c
index 5a9d3b3670..433e6e1e4f 100644
--- a/firmware/target/arm/pcm-pp.c
+++ b/firmware/target/arm/pcm-pp.c
@@ -223,24 +223,24 @@ void fiq_playback(void)
223 will require other measures */ 223 will require other measures */
224void pcm_play_lock(void) 224void pcm_play_lock(void)
225{ 225{
226 int status = set_fiq_status(FIQ_DISABLED); 226 int status = disable_fiq_save();
227 227
228 if (++dma_play_data.locked == 1) { 228 if (++dma_play_data.locked == 1) {
229 IIS_IRQTX_REG &= ~IIS_IRQTX; 229 IIS_IRQTX_REG &= ~IIS_IRQTX;
230 } 230 }
231 231
232 set_fiq_status(status); 232 restore_fiq(status);
233} 233}
234 234
235void pcm_play_unlock(void) 235void pcm_play_unlock(void)
236{ 236{
237 int status = set_fiq_status(FIQ_DISABLED); 237 int status = disable_fiq_save();
238 238
239 if (--dma_play_data.locked == 0 && dma_play_data.state != 0) { 239 if (--dma_play_data.locked == 0 && dma_play_data.state != 0) {
240 IIS_IRQTX_REG |= IIS_IRQTX; 240 IIS_IRQTX_REG |= IIS_IRQTX;
241 } 241 }
242 242
243 set_fiq_status(status); 243 restore_fiq(status);
244} 244}
245 245
246static void play_start_pcm(void) 246static void play_start_pcm(void)
@@ -373,22 +373,22 @@ static struct dma_data dma_rec_data NOCACHEBSS_ATTR =
373 will require other measures */ 373 will require other measures */
374void pcm_rec_lock(void) 374void pcm_rec_lock(void)
375{ 375{
376 int status = set_fiq_status(FIQ_DISABLED); 376 int status = disable_fiq_save();
377 377
378 if (++dma_rec_data.locked == 1) 378 if (++dma_rec_data.locked == 1)
379 IIS_IRQRX_REG &= ~IIS_IRQRX; 379 IIS_IRQRX_REG &= ~IIS_IRQRX;
380 380
381 set_fiq_status(status); 381 restore_fiq(status);
382} 382}
383 383
384void pcm_rec_unlock(void) 384void pcm_rec_unlock(void)
385{ 385{
386 int status = set_fiq_status(FIQ_DISABLED); 386 int status = disable_fiq_save();
387 387
388 if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0) 388 if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0)
389 IIS_IRQRX_REG |= IIS_IRQRX; 389 IIS_IRQRX_REG |= IIS_IRQRX;
390 390
391 set_fiq_status(status); 391 restore_fiq(status);
392} 392}
393 393
394/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ 394/* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */
diff --git a/firmware/target/arm/pnx0101/iriver-ifp7xx/power-ifp7xx.c b/firmware/target/arm/pnx0101/iriver-ifp7xx/power-ifp7xx.c
index b219244510..4494742bb8 100644
--- a/firmware/target/arm/pnx0101/iriver-ifp7xx/power-ifp7xx.c
+++ b/firmware/target/arm/pnx0101/iriver-ifp7xx/power-ifp7xx.c
@@ -55,11 +55,10 @@ bool ide_powered(void)
55 55
56void power_off(void) 56void power_off(void)
57{ 57{
58 set_irq_level(HIGHEST_IRQ_LEVEL); 58 disable_interrupt(IRQ_FIQ_STATUS);
59 GPIO1_CLR = 1 << 16; 59 GPIO1_CLR = 1 << 16;
60 GPIO2_SET = 1; 60 GPIO2_SET = 1;
61 while(1) 61 while(1);
62 yield();
63} 62}
64 63
65#else 64#else
diff --git a/firmware/target/arm/pnx0101/system-pnx0101.c b/firmware/target/arm/pnx0101/system-pnx0101.c
index da94f397ca..bedcff04ea 100644
--- a/firmware/target/arm/pnx0101/system-pnx0101.c
+++ b/firmware/target/arm/pnx0101/system-pnx0101.c
@@ -113,7 +113,7 @@ static inline void *noncached(void *p)
113static void do_set_mem_timings(void) ICODE_ATTR; 113static void do_set_mem_timings(void) ICODE_ATTR;
114static void do_set_mem_timings(void) 114static void do_set_mem_timings(void)
115{ 115{
116 int old_irq = set_irq_level(HIGHEST_IRQ_LEVEL); 116 int old_irq = disable_irq_save();
117 while ((EMC.status & 3) != 0); 117 while ((EMC.status & 3) != 0);
118 EMC.control = 5; 118 EMC.control = 5;
119 EMCSTATIC0.waitrd = 6; 119 EMCSTATIC0.waitrd = 6;
@@ -130,7 +130,7 @@ static void do_set_mem_timings(void)
130 EMCSTATIC1.config = 0x80081; 130 EMCSTATIC1.config = 0x80081;
131#endif 131#endif
132 EMC.control = 1; 132 EMC.control = 1;
133 set_irq_level(old_irq); 133 restore_irq(old_irq);
134} 134}
135 135
136static void emc_set_mem_timings(void) 136static void emc_set_mem_timings(void)
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
index 7f25cb6a15..00be543bb6 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
@@ -66,27 +66,27 @@ static void _pcm_apply_settings(void)
66 66
67void pcm_apply_settings(void) 67void pcm_apply_settings(void)
68{ 68{
69 int oldstatus = set_fiq_status(FIQ_DISABLED); 69 int status = disable_fiq_save();
70 _pcm_apply_settings(); 70 _pcm_apply_settings();
71 set_fiq_status(oldstatus); 71 restore_fiq(status);
72} 72}
73 73
74/* For the locks, DMA interrupt must be disabled because the handler 74/* For the locks, DMA interrupt must be disabled because the handler
75 manipulates INTMSK and the operation is not atomic */ 75 manipulates INTMSK and the operation is not atomic */
76void pcm_play_lock(void) 76void pcm_play_lock(void)
77{ 77{
78 int status = set_fiq_status(FIQ_DISABLED); 78 int status = disable_fiq_save();
79 if (++dma_play_lock.locked == 1) 79 if (++dma_play_lock.locked == 1)
80 INTMSK |= (1<<19); /* Mask the DMA interrupt */ 80 INTMSK |= (1<<19); /* Mask the DMA interrupt */
81 set_fiq_status(status); 81 restore_fiq(status);
82} 82}
83 83
84void pcm_play_unlock(void) 84void pcm_play_unlock(void)
85{ 85{
86 int status = set_fiq_status(FIQ_DISABLED); 86 int status = disable_fiq_save();
87 if (--dma_play_lock.locked == 0) 87 if (--dma_play_lock.locked == 0)
88 INTMSK &= ~dma_play_lock.state; /* Unmask the DMA interrupt if enabled */ 88 INTMSK &= ~dma_play_lock.state; /* Unmask the DMA interrupt if enabled */
89 set_fiq_status(status); 89 restore_fiq(status);
90} 90}
91 91
92void pcm_play_dma_init(void) 92void pcm_play_dma_init(void)
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
index 7df20f7149..b59e95806d 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/timer-meg-fx.c
@@ -66,7 +66,7 @@ bool __timer_set(long cycles, bool start)
66 pfn_unregister = NULL; 66 pfn_unregister = NULL;
67 } 67 }
68 68
69 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 69 oldlevel = disable_irq_save();
70 70
71 TCMPB0 = 0; 71 TCMPB0 = 0;
72 TCNTB0 = (unsigned int)cycles / prescaler; 72 TCNTB0 = (unsigned int)cycles / prescaler;
@@ -77,7 +77,7 @@ bool __timer_set(long cycles, bool start)
77 TCFG0 = (TCFG0 & ~0xff) | (prescaler - 1); 77 TCFG0 = (TCFG0 & ~0xff) | (prescaler - 1);
78 TCFG1 = (TCFG1 & ~0xf) | divider; 78 TCFG1 = (TCFG1 & ~0xf) | divider;
79 79
80 set_irq_level(oldlevel); 80 restore_irq(oldlevel);
81 81
82 retval = true; 82 retval = true;
83 } 83 }
diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h
index 774cdbcff4..3f1dfb16c8 100644
--- a/firmware/target/arm/system-arm.h
+++ b/firmware/target/arm/system-arm.h
@@ -74,27 +74,7 @@ static inline uint32_t swap_odd_even32(uint32_t value)
74 return value; 74 return value;
75} 75}
76 76
77static inline void enable_fiq(void) 77/* Core-level interrupt masking */
78{
79 /* Clear FIQ disable bit */
80 asm volatile (
81 "mrs r0, cpsr \n"\
82 "bic r0, r0, #0x40 \n"\
83 "msr cpsr_c, r0 "
84 : : : "r0"
85 );
86}
87
88static inline void disable_fiq(void)
89{
90 /* Set FIQ disable bit */
91 asm volatile (
92 "mrs r0, cpsr \n"\
93 "orr r0, r0, #0x40 \n"\
94 "msr cpsr_c, r0 "
95 : : : "r0"
96 );
97}
98 78
99/* This one returns the old status */ 79/* This one returns the old status */
100#define IRQ_ENABLED 0x00 80#define IRQ_ENABLED 0x00
@@ -108,8 +88,10 @@ static inline void disable_fiq(void)
108#define IRQ_FIQ_STATUS 0xc0 88#define IRQ_FIQ_STATUS 0xc0
109#define HIGHEST_IRQ_LEVEL IRQ_DISABLED 89#define HIGHEST_IRQ_LEVEL IRQ_DISABLED
110 90
111#define set_irq_level(status) set_interrupt_status((status), IRQ_STATUS) 91#define set_irq_level(status) \
112#define set_fiq_status(status) set_interrupt_status((status), FIQ_STATUS) 92 set_interrupt_status((status), IRQ_STATUS)
93#define set_fiq_status(status) \
94 set_interrupt_status((status), FIQ_STATUS)
113 95
114static inline int set_interrupt_status(int status, int mask) 96static inline int set_interrupt_status(int status, int mask)
115{ 97{
@@ -122,10 +104,75 @@ static inline int set_interrupt_status(int status, int mask)
122 "orr %0, %0, %2 \n" 104 "orr %0, %0, %2 \n"
123 "msr cpsr_c, %0 \n" 105 "msr cpsr_c, %0 \n"
124 : "=&r,r"(cpsr), "=&r,r"(oldstatus) 106 : "=&r,r"(cpsr), "=&r,r"(oldstatus)
125 : "r,i"(status & mask), [mask]"i,i"(mask) 107 : "r,i"(status & mask), [mask]"i,i"(mask));
126 );
127 108
128 return oldstatus; 109 return oldstatus;
129} 110}
130 111
112static inline void enable_interrupt(int mask)
113{
114 /* Clear I and/or F disable bit */
115 int tmp;
116 asm volatile (
117 "mrs %0, cpsr \n"
118 "bic %0, %0, %1 \n"
119 "msr cpsr_c, %0 \n"
120 : "=&r"(tmp) : "i"(mask));
121}
122
123static inline void disable_interrupt(int mask)
124{
125 /* Set I and/or F disable bit */
126 int tmp;
127 asm volatile (
128 "mrs %0, cpsr \n"
129 "orr %0, %0, %1 \n"
130 "msr cpsr_c, %0 \n"
131 : "=&r"(tmp) : "i"(mask));
132}
133
134#define disable_irq(void) \
135 disable_interrupt(IRQ_STATUS)
136
137#define enable_irq(void) \
138 enable_interrupt(IRQ_STATUS)
139
140#define disable_fiq(void) \
141 disable_interrupt(FIQ_STATUS)
142
143#define enable_fiq(void) \
144 enable_interrupt(FIQ_STATUS)
145
146static inline int disable_interrupt_save(int mask)
147{
148 /* Set I and/or F disable bit and return old cpsr value */
149 int cpsr, tmp;
150 asm volatile (
151 "mrs %1, cpsr \n"
152 "orr %0, %1, %2 \n"
153 "msr cpsr_c, %0 \n"
154 : "=&r"(tmp), "=&r"(cpsr)
155 : "i"(mask));
156 return cpsr;
157}
158
159#define disable_irq_save() \
160 disable_interrupt_save(IRQ_STATUS)
161
162#define disable_fiq_save() \
163 disable_interrupt_save(FIQ_STATUS)
164
165static inline void restore_interrupt(int cpsr)
166{
167 /* Set cpsr_c from value returned by disable_interrupt_save
168 * or set_interrupt_status */
169 asm volatile ("msr cpsr_c, %0" : : "r"(cpsr));
170}
171
172#define restore_irq(cpsr) \
173 restore_interrupt(cpsr)
174
175#define restore_fiq(cpsr) \
176 restore_interrupt(cpsr)
177
131#endif /* SYSTEM_ARM_H */ 178#endif /* SYSTEM_ARM_H */
diff --git a/firmware/target/arm/tatung/tpj1022/backlight-tpj1022.c b/firmware/target/arm/tatung/tpj1022/backlight-tpj1022.c
index 933ad5e930..a466cd93dd 100644
--- a/firmware/target/arm/tatung/tpj1022/backlight-tpj1022.c
+++ b/firmware/target/arm/tatung/tpj1022/backlight-tpj1022.c
@@ -28,17 +28,17 @@
28void _backlight_on(void) 28void _backlight_on(void)
29{ 29{
30#if 0 30#if 0
31 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 31 int level = disable_irq_save();
32 pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */ 32 pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */
33 set_irq_level(level); 33 restore_irq(level);
34#endif 34#endif
35} 35}
36 36
37void _backlight_off(void) 37void _backlight_off(void)
38{ 38{
39#if 0 39#if 0
40 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 40 int level = disable_irq_save();
41 pcf50606_write(0x38, 0x80); /* Backlight OFF, GPO1INV=1, GPO1ACT=000 */ 41 pcf50606_write(0x38, 0x80); /* Backlight OFF, GPO1INV=1, GPO1ACT=000 */
42 set_irq_level(level); 42 restore_irq(level);
43#endif 43#endif
44} 44}
diff --git a/firmware/target/arm/tms320dm320/dsp-dm320.c b/firmware/target/arm/tms320dm320/dsp-dm320.c
index f2ca954b24..e082cf7e4d 100644
--- a/firmware/target/arm/tms320dm320/dsp-dm320.c
+++ b/firmware/target/arm/tms320dm320/dsp-dm320.c
@@ -85,7 +85,7 @@ void dsp_wake(void)
85{ 85{
86 /* If this is called concurrently, we may overlap setting and resetting the 86 /* If this is called concurrently, we may overlap setting and resetting the
87 bit, which causes lost interrupts to the DSP. */ 87 bit, which causes lost interrupts to the DSP. */
88 int old_level = set_irq_level(IRQ_DISABLED); 88 int old_level = disable_irq_save();
89 89
90 /* The first time you INT0 the DSP, the ROM loader will branch to your RST 90 /* The first time you INT0 the DSP, the ROM loader will branch to your RST
91 handler. Subsequent times, your INT0 handler will get executed. */ 91 handler. Subsequent times, your INT0 handler will get executed. */
@@ -93,7 +93,7 @@ void dsp_wake(void)
93 nop; nop; 93 nop; nop;
94 IO_DSPC_HPIB_CONTROL |= 1 << 7; 94 IO_DSPC_HPIB_CONTROL |= 1 << 7;
95 95
96 set_irq_level(old_level); 96 restore_irq(old_level);
97} 97}
98 98
99static void dsp_load(const struct dsp_section *im) 99static void dsp_load(const struct dsp_section *im)
diff --git a/firmware/target/arm/tms320dm320/timer-dm320.c b/firmware/target/arm/tms320dm320/timer-dm320.c
index 482fef9f12..e1e051d3a5 100644
--- a/firmware/target/arm/tms320dm320/timer-dm320.c
+++ b/firmware/target/arm/tms320dm320/timer-dm320.c
@@ -48,7 +48,7 @@ bool __timer_set(long cycles, bool start)
48 pfn_unregister = NULL; 48 pfn_unregister = NULL;
49 } 49 }
50 50
51 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 51 oldlevel = disable_irq_save();
52 52
53 /* Increase prescale values starting from 0 to make the cycle count fit */ 53 /* Increase prescale values starting from 0 to make the cycle count fit */
54 while(divider>65535 && prescaler<1024) 54 while(divider>65535 && prescaler<1024)
@@ -60,7 +60,7 @@ bool __timer_set(long cycles, bool start)
60 IO_TIMER0_TMPRSCL = prescaler; 60 IO_TIMER0_TMPRSCL = prescaler;
61 IO_TIMER0_TMDIV = divider; 61 IO_TIMER0_TMDIV = divider;
62 62
63 set_irq_level(oldlevel); 63 restore_irq(oldlevel);
64 64
65 return true; 65 return true;
66} 66}
diff --git a/firmware/target/coldfire/iaudio/adc-iaudio.c b/firmware/target/coldfire/iaudio/adc-iaudio.c
index 1895cacfe9..5a2de24692 100644
--- a/firmware/target/coldfire/iaudio/adc-iaudio.c
+++ b/firmware/target/coldfire/iaudio/adc-iaudio.c
@@ -44,7 +44,7 @@ unsigned short adc_scan(int channel)
44 int level; 44 int level;
45 int data; 45 int data;
46 46
47 level = set_irq_level(HIGHEST_IRQ_LEVEL); 47 level = disable_irq_save();
48 48
49 pcf50606_write(0x2f, adcc2_parms[channel]); 49 pcf50606_write(0x2f, adcc2_parms[channel]);
50 data = pcf50606_read(0x30); 50 data = pcf50606_read(0x30);
@@ -52,7 +52,7 @@ unsigned short adc_scan(int channel)
52 if (channel == ADC_BATTERY) 52 if (channel == ADC_BATTERY)
53 data = get_10bit_voltage(data); 53 data = get_10bit_voltage(data);
54 54
55 set_irq_level(level); 55 restore_irq(level);
56 56
57 return (unsigned short)data; 57 return (unsigned short)data;
58} 58}
diff --git a/firmware/target/coldfire/iaudio/m3/audio-m3.c b/firmware/target/coldfire/iaudio/m3/audio-m3.c
index 4edae48744..da8c43c405 100644
--- a/firmware/target/coldfire/iaudio/m3/audio-m3.c
+++ b/firmware/target/coldfire/iaudio/m3/audio-m3.c
@@ -33,7 +33,7 @@ void audio_set_output_source(int source)
33 txsrc = (4 << 8); /* recording, iis1RcvData */ 33 txsrc = (4 << 8); /* recording, iis1RcvData */
34 34
35 IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc; 35 IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc;
36 set_irq_level(level); 36 restore_irq(level);
37} /* audio_set_output_source */ 37} /* audio_set_output_source */
38 38
39void audio_input_mux(int source, unsigned flags) 39void audio_input_mux(int source, unsigned flags)
diff --git a/firmware/target/coldfire/iaudio/m5/audio-m5.c b/firmware/target/coldfire/iaudio/m5/audio-m5.c
index 87a7c35574..024621be64 100644
--- a/firmware/target/coldfire/iaudio/m5/audio-m5.c
+++ b/firmware/target/coldfire/iaudio/m5/audio-m5.c
@@ -32,7 +32,7 @@ void audio_set_output_source(int source)
32 txsrc = (4 << 8); /* recording, iis1RcvData */ 32 txsrc = (4 << 8); /* recording, iis1RcvData */
33 33
34 IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc; 34 IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc;
35 set_irq_level(level); 35 restore_irq(level);
36} /* audio_set_output_source */ 36} /* audio_set_output_source */
37 37
38void audio_input_mux(int source, unsigned flags) 38void audio_input_mux(int source, unsigned flags)
diff --git a/firmware/target/coldfire/iaudio/m5/backlight-m5.c b/firmware/target/coldfire/iaudio/m5/backlight-m5.c
index 19bc5bfcae..3461a330ec 100644
--- a/firmware/target/coldfire/iaudio/m5/backlight-m5.c
+++ b/firmware/target/coldfire/iaudio/m5/backlight-m5.c
@@ -33,18 +33,18 @@ bool _backlight_init(void)
33 33
34void _backlight_on(void) 34void _backlight_on(void)
35{ 35{
36 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 36 int level = disable_irq_save();
37 37
38 pcf50606_write(0x39, 0x07); 38 pcf50606_write(0x39, 0x07);
39 set_irq_level(level); 39 restore_irq(level);
40} 40}
41 41
42void _backlight_off(void) 42void _backlight_off(void)
43{ 43{
44 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 44 int level = disable_irq_save();
45 45
46 pcf50606_write(0x39, 0x00); 46 pcf50606_write(0x39, 0x00);
47 set_irq_level(level); 47 restore_irq(level);
48} 48}
49 49
50void _remote_backlight_on(void) 50void _remote_backlight_on(void)
diff --git a/firmware/target/coldfire/iaudio/m5/power-m5.c b/firmware/target/coldfire/iaudio/m5/power-m5.c
index 939cae02f2..18401af49f 100644
--- a/firmware/target/coldfire/iaudio/m5/power-m5.c
+++ b/firmware/target/coldfire/iaudio/m5/power-m5.c
@@ -44,16 +44,16 @@ bool charger_inserted(void)
44void ide_power_enable(bool on) 44void ide_power_enable(bool on)
45{ 45{
46 /* GPOOD3 */ 46 /* GPOOD3 */
47 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 47 int level = disable_irq_save();
48 pcf50606_write(0x3c, on ? 0x07 : 0x00); 48 pcf50606_write(0x3c, on ? 0x07 : 0x00);
49 set_irq_level(level); 49 restore_irq(level);
50} 50}
51 51
52bool ide_powered(void) 52bool ide_powered(void)
53{ 53{
54 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 54 int level = disable_irq_save();
55 int value = pcf50606_read(0x3c); 55 int value = pcf50606_read(0x3c);
56 set_irq_level(level); 56 restore_irq(level);
57 return (value & 0x07) != 0; 57 return (value & 0x07) != 0;
58} 58}
59 59
diff --git a/firmware/target/coldfire/iaudio/pcf50606-iaudio.c b/firmware/target/coldfire/iaudio/pcf50606-iaudio.c
index 0614355b5d..14b45e78b5 100644
--- a/firmware/target/coldfire/iaudio/pcf50606-iaudio.c
+++ b/firmware/target/coldfire/iaudio/pcf50606-iaudio.c
@@ -94,9 +94,9 @@ void pcf50606_init(void)
94 94
95void pcf50606_reset_timeout(void) 95void pcf50606_reset_timeout(void)
96{ 96{
97 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 97 int level = disable_irq_save();
98 pcf50606_write(0x08, pcf50606_read(0x08) | 0x02); /* OOCC1 - TOTRST=1 */ 98 pcf50606_write(0x08, pcf50606_read(0x08) | 0x02); /* OOCC1 - TOTRST=1 */
99 set_irq_level(level); 99 restore_irq(level);
100} 100}
101 101
102/* Handles interrupts generated by the pcf50606 */ 102/* Handles interrupts generated by the pcf50606 */
diff --git a/firmware/target/coldfire/iaudio/x5/audio-x5.c b/firmware/target/coldfire/iaudio/x5/audio-x5.c
index 594ff3b574..0ae5f6023a 100644
--- a/firmware/target/coldfire/iaudio/x5/audio-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/audio-x5.c
@@ -32,7 +32,7 @@ void audio_set_output_source(int source)
32 txsrc = (4 << 8); /* recording, iis1RcvData */ 32 txsrc = (4 << 8); /* recording, iis1RcvData */
33 33
34 IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc; 34 IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc;
35 set_irq_level(level); 35 restore_irq(level);
36} /* audio_set_output_source */ 36} /* audio_set_output_source */
37 37
38void audio_input_mux(int source, unsigned flags) 38void audio_input_mux(int source, unsigned flags)
diff --git a/firmware/target/coldfire/iaudio/x5/backlight-x5.c b/firmware/target/coldfire/iaudio/x5/backlight-x5.c
index ebb28fbf2b..13ccad5adf 100644
--- a/firmware/target/coldfire/iaudio/x5/backlight-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/backlight-x5.c
@@ -39,16 +39,16 @@ void _backlight_on(void)
39#ifndef BOOTLOADER 39#ifndef BOOTLOADER
40 _lcd_sleep_timer = 0; /* LCD should be awake already */ 40 _lcd_sleep_timer = 0; /* LCD should be awake already */
41#endif 41#endif
42 level = set_irq_level(HIGHEST_IRQ_LEVEL); 42 level = disable_irq_save();
43 pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */ 43 pcf50606_write(0x38, 0xb0); /* Backlight ON, GPO1INV=1, GPO1ACT=011 */
44 set_irq_level(level); 44 restore_irq(level);
45} 45}
46 46
47void _backlight_off(void) 47void _backlight_off(void)
48{ 48{
49 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 49 int level = disable_irq_save();
50 pcf50606_write(0x38, 0x80); /* Backlight OFF, GPO1INV=1, GPO1ACT=000 */ 50 pcf50606_write(0x38, 0x80); /* Backlight OFF, GPO1INV=1, GPO1ACT=000 */
51 set_irq_level(level); 51 restore_irq(level);
52 lcd_enable(false); 52 lcd_enable(false);
53#ifndef BOOTLOADER 53#ifndef BOOTLOADER
54 /* Start LCD sleep countdown */ 54 /* Start LCD sleep countdown */
@@ -66,10 +66,10 @@ void _backlight_off(void)
66void _backlight_set_brightness(int val) 66void _backlight_set_brightness(int val)
67{ 67{
68 /* disable IRQs while bitbanging */ 68 /* disable IRQs while bitbanging */
69 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); 69 int old_irq_level = disable_irq_save();
70 pcf50606_write(0x35, (val << 1) | 0x01); /* 512Hz, Enable PWM */ 70 pcf50606_write(0x35, (val << 1) | 0x01); /* 512Hz, Enable PWM */
71 /* enable IRQs again */ 71 /* enable IRQs again */
72 set_irq_level(old_irq_level); 72 restore_irq(old_irq_level);
73} 73}
74 74
75void _remote_backlight_on(void) 75void _remote_backlight_on(void)
diff --git a/firmware/target/coldfire/iaudio/x5/ds2411-x5.c b/firmware/target/coldfire/iaudio/x5/ds2411-x5.c
index dc5a188ae1..a9bf20f727 100644
--- a/firmware/target/coldfire/iaudio/x5/ds2411-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/ds2411-x5.c
@@ -134,7 +134,7 @@ static unsigned char ds2411_read_byte(void)
134 */ 134 */
135int ds2411_read_id(struct ds2411_id *id) 135int ds2411_read_id(struct ds2411_id *id)
136{ 136{
137 int level = set_irq_level(DISABLE_INTERRUPTS); /* Timing sensitive */ 137 int level = disable_irq_save(); /* Timing sensitive */
138 int i; 138 int i;
139 unsigned char crc; 139 unsigned char crc;
140 140
@@ -208,7 +208,7 @@ int ds2411_read_id(struct ds2411_id *id)
208 i = DS2411_NO_PRESENCE; 208 i = DS2411_NO_PRESENCE;
209 } 209 }
210 210
211 set_irq_level(level); 211 restore_irq(level);
212 212
213 return i; 213 return i;
214} /* ds2411_read_id */ 214} /* ds2411_read_id */
diff --git a/firmware/target/coldfire/iaudio/x5/power-x5.c b/firmware/target/coldfire/iaudio/x5/power-x5.c
index 068b25f577..f5193aa559 100644
--- a/firmware/target/coldfire/iaudio/x5/power-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/power-x5.c
@@ -44,16 +44,16 @@ bool charger_inserted(void)
44void ide_power_enable(bool on) 44void ide_power_enable(bool on)
45{ 45{
46 /* GPOOD3 */ 46 /* GPOOD3 */
47 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 47 int level = disable_irq_save();
48 pcf50606_write(0x3c, on ? 0x07 : 0x00); 48 pcf50606_write(0x3c, on ? 0x07 : 0x00);
49 set_irq_level(level); 49 restore_irq(level);
50} 50}
51 51
52bool ide_powered(void) 52bool ide_powered(void)
53{ 53{
54 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 54 int level = disable_irq_save();
55 int value = pcf50606_read(0x3c); 55 int value = pcf50606_read(0x3c);
56 set_irq_level(level); 56 restore_irq(level);
57 return (value & 0x07) != 0; 57 return (value & 0x07) != 0;
58} 58}
59 59
diff --git a/firmware/target/coldfire/iriver/audio-iriver.c b/firmware/target/coldfire/iriver/audio-iriver.c
index 4d22e7c987..51917b1338 100644
--- a/firmware/target/coldfire/iriver/audio-iriver.c
+++ b/firmware/target/coldfire/iriver/audio-iriver.c
@@ -41,7 +41,7 @@ void audio_set_output_source(int source)
41 41
42 IIS2CONFIG = (IIS2CONFIG & ~(7 << 8)) | (txsrc_select[source+1] << 8); 42 IIS2CONFIG = (IIS2CONFIG & ~(7 << 8)) | (txsrc_select[source+1] << 8);
43 43
44 set_irq_level(level); 44 restore_irq(level);
45} /* audio_set_output_source */ 45} /* audio_set_output_source */
46 46
47void audio_input_mux(int source, unsigned flags) 47void audio_input_mux(int source, unsigned flags)
diff --git a/firmware/target/coldfire/iriver/h100/adc-h100.c b/firmware/target/coldfire/iriver/h100/adc-h100.c
index 40fcc8925d..7ea7618b09 100644
--- a/firmware/target/coldfire/iriver/h100/adc-h100.c
+++ b/firmware/target/coldfire/iriver/h100/adc-h100.c
@@ -47,7 +47,7 @@
47 47
48unsigned short adc_scan(int channel) 48unsigned short adc_scan(int channel)
49{ 49{
50 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 50 int level = disable_irq_save();
51 unsigned char data = 0; 51 unsigned char data = 0;
52 int i; 52 int i;
53 53
@@ -97,7 +97,7 @@ unsigned short adc_scan(int channel)
97 97
98 CS_HI; 98 CS_HI;
99 99
100 set_irq_level(level); 100 restore_irq(level);
101 return data; 101 return data;
102} 102}
103 103
diff --git a/firmware/target/coldfire/iriver/h100/power-h100.c b/firmware/target/coldfire/iriver/h100/power-h100.c
index 5dc8618cc6..7ecf961842 100644
--- a/firmware/target/coldfire/iriver/h100/power-h100.c
+++ b/firmware/target/coldfire/iriver/h100/power-h100.c
@@ -115,8 +115,7 @@ void power_off(void)
115 set_irq_level(DISABLE_INTERRUPTS); 115 set_irq_level(DISABLE_INTERRUPTS);
116 and_l(~0x00080000, &GPIO1_OUT); 116 and_l(~0x00080000, &GPIO1_OUT);
117 asm("halt"); 117 asm("halt");
118 while(1) 118 while(1);
119 yield();
120} 119}
121 120
122#endif /* SIMULATOR */ 121#endif /* SIMULATOR */
diff --git a/firmware/target/coldfire/iriver/h100/spdif-h100.c b/firmware/target/coldfire/iriver/h100/spdif-h100.c
index beede3fdce..380622422c 100644
--- a/firmware/target/coldfire/iriver/h100/spdif-h100.c
+++ b/firmware/target/coldfire/iriver/h100/spdif-h100.c
@@ -99,7 +99,7 @@ void spdif_set_output_source(int source, bool src_on)
99 PDOR3 = 0; /* A write to the FIFO kick-starts playback */ 99 PDOR3 = 0; /* A write to the FIFO kick-starts playback */
100 } 100 }
101 101
102 set_irq_level(level); 102 restore_irq(level);
103} /* spdif_set_output_source */ 103} /* spdif_set_output_source */
104 104
105/* Return the last set S/PDIF audio source */ 105/* Return the last set S/PDIF audio source */
diff --git a/firmware/target/coldfire/iriver/h300/adc-h300.c b/firmware/target/coldfire/iriver/h300/adc-h300.c
index b13d0c73cc..efe5a9d746 100644
--- a/firmware/target/coldfire/iriver/h300/adc-h300.c
+++ b/firmware/target/coldfire/iriver/h300/adc-h300.c
@@ -34,7 +34,7 @@ static int adcc2_parms[] =
34 34
35unsigned short adc_scan(int channel) 35unsigned short adc_scan(int channel)
36{ 36{
37 int level = set_irq_level(HIGHEST_IRQ_LEVEL); 37 int level = disable_irq_save();
38 unsigned data; 38 unsigned data;
39 39
40 pcf50606_write(0x2f, adcc2_parms[channel]); 40 pcf50606_write(0x2f, adcc2_parms[channel]);
@@ -43,6 +43,6 @@ unsigned short adc_scan(int channel)
43 if (channel == ADC_BATTERY) 43 if (channel == ADC_BATTERY)
44 data = (data << 2) | (pcf50606_read(0x31) & 0x03); 44 data = (data << 2) | (pcf50606_read(0x31) & 0x03);
45 45
46 set_irq_level(level); 46 restore_irq(level);
47 return data; 47 return data;
48} 48}
diff --git a/firmware/target/coldfire/iriver/h300/backlight-h300.c b/firmware/target/coldfire/iriver/h300/backlight-h300.c
index c0d441ad3f..f042ee5524 100644
--- a/firmware/target/coldfire/iriver/h300/backlight-h300.c
+++ b/firmware/target/coldfire/iriver/h300/backlight-h300.c
@@ -51,10 +51,10 @@ void _backlight_off(void)
51void _backlight_set_brightness(int val) 51void _backlight_set_brightness(int val)
52{ 52{
53 /* disable IRQs while bitbanging */ 53 /* disable IRQs while bitbanging */
54 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); 54 int old_irq_level = disable_irq_save();
55 pcf50606_write(0x35, (val << 1) | 0x01); /* 512Hz, Enable PWM */ 55 pcf50606_write(0x35, (val << 1) | 0x01); /* 512Hz, Enable PWM */
56 /* enable IRQs again */ 56 /* enable IRQs again */
57 set_irq_level(old_irq_level); 57 restore_irq(old_irq_level);
58} 58}
59 59
60void _remote_backlight_on(void) 60void _remote_backlight_on(void)
diff --git a/firmware/target/coldfire/iriver/h300/power-h300.c b/firmware/target/coldfire/iriver/h300/power-h300.c
index 21c723da8e..a06763e555 100644
--- a/firmware/target/coldfire/iriver/h300/power-h300.c
+++ b/firmware/target/coldfire/iriver/h300/power-h300.c
@@ -86,8 +86,7 @@ void power_off(void)
86 set_irq_level(DISABLE_INTERRUPTS); 86 set_irq_level(DISABLE_INTERRUPTS);
87 and_l(~0x00080000, &GPIO1_OUT); 87 and_l(~0x00080000, &GPIO1_OUT);
88 asm("halt"); 88 asm("halt");
89 while(1) 89 while(1);
90 yield();
91} 90}
92 91
93#endif /* SIMULATOR */ 92#endif /* SIMULATOR */
diff --git a/firmware/target/coldfire/iriver/lcd-remote-iriver.c b/firmware/target/coldfire/iriver/lcd-remote-iriver.c
index cab7cc4104..2fe5d6c3c1 100644
--- a/firmware/target/coldfire/iriver/lcd-remote-iriver.c
+++ b/firmware/target/coldfire/iriver/lcd-remote-iriver.c
@@ -478,9 +478,9 @@ static void remote_tick(void)
478 if (!(countdown % 8)) 478 if (!(countdown % 8))
479 { 479 {
480 /* Determine which type of remote it is */ 480 /* Determine which type of remote it is */
481 level = set_irq_level(HIGHEST_IRQ_LEVEL); 481 level = disable_irq_save();
482 val = adc_scan(ADC_REMOTEDETECT); 482 val = adc_scan(ADC_REMOTEDETECT);
483 set_irq_level(level); 483 restore_irq(level);
484 484
485 if (val < ADCVAL_H100_LCD_REMOTE_HOLD) 485 if (val < ADCVAL_H100_LCD_REMOTE_HOLD)
486 { 486 {
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c
index 105ad51de6..2614946543 100644
--- a/firmware/target/coldfire/pcm-coldfire.c
+++ b/firmware/target/coldfire/pcm-coldfire.c
@@ -158,7 +158,7 @@ void _pcm_apply_settings_irq_lock(bool clear_reset)
158{ 158{
159 int level = set_irq_level(DMA_IRQ_LEVEL); 159 int level = set_irq_level(DMA_IRQ_LEVEL);
160 _pcm_apply_settings(clear_reset); 160 _pcm_apply_settings(clear_reset);
161 set_irq_level(level); 161 restore_irq(level);
162} 162}
163 163
164/* This clears the reset bit to enable monitoring immediately if monitoring 164/* This clears the reset bit to enable monitoring immediately if monitoring
@@ -175,7 +175,7 @@ void pcm_apply_settings(void)
175 if (_pcm_apply_settings(!pbm || kick) && kick) 175 if (_pcm_apply_settings(!pbm || kick) && kick)
176 PDOR3 = 0; /* Kick FIFO out of reset by writing to it */ 176 PDOR3 = 0; /* Kick FIFO out of reset by writing to it */
177 177
178 set_irq_level(level); 178 restore_irq(level);
179} /* pcm_apply_settings */ 179} /* pcm_apply_settings */
180 180
181void pcm_play_dma_init(void) 181void pcm_play_dma_init(void)
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c
index 60f7ab12ad..67c684f95a 100644
--- a/firmware/target/coldfire/system-coldfire.c
+++ b/firmware/target/coldfire/system-coldfire.c
@@ -351,5 +351,5 @@ void coldfire_set_dataincontrol(unsigned long value)
351 /* Have to be atomic against recording stop initiated by DMA1 */ 351 /* Have to be atomic against recording stop initiated by DMA1 */
352 int level = set_irq_level(DMA_IRQ_LEVEL); 352 int level = set_irq_level(DMA_IRQ_LEVEL);
353 DATAINCONTROL = (DATAINCONTROL & (1 << 9)) | value; 353 DATAINCONTROL = (DATAINCONTROL & (1 << 9)) | value;
354 set_irq_level(level); 354 restore_irq(level);
355} 355}
diff --git a/firmware/target/coldfire/system-target.h b/firmware/target/coldfire/system-target.h
index 8e3a2a3d5a..14b3207c0c 100644
--- a/firmware/target/coldfire/system-target.h
+++ b/firmware/target/coldfire/system-target.h
@@ -81,13 +81,54 @@ static inline int set_irq_level(int level)
81{ 81{
82 int oldlevel; 82 int oldlevel;
83 /* Read the old level and set the new one */ 83 /* Read the old level and set the new one */
84 asm volatile ("move.w %%sr, %0 \n" 84
85 "bset.l #13, %1 \n" /* Keep supervisor state set */ 85 /* Not volatile - can be removed if oldlevel isn't used */
86 "move.w %1, %%sr \n" 86 asm ("move.w %%sr, %0" : "=d"(oldlevel));
87 : "=d"(oldlevel), "+d"(level)); 87 /* Keep supervisor state set */
88 asm volatile ("move.w %0, %%sr \n" : : "d"(level | 0x2000));
89 return oldlevel;
90}
91
92/* Enable all interrupts */
93static inline void enable_irq(void)
94{
95 int tmp;
96 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
97 asm volatile ("move.w %1, %0 \n"
98 "move.w %0, %%sr \n"
99 : "=&d"(tmp) : "i"(0x2000));
100}
101
102/* Disable interrupts up to HIGHEST_IRQ_LEVEL */
103static inline void disable_irq(void)
104{
105 int tmp;
106 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
107 asm volatile ("move.w %1, %0 \n"
108 "move.w %0, %%sr \n"
109 : "=&d"(tmp)
110 : "i"(0x2000 | HIGHEST_IRQ_LEVEL));
111}
112
113static inline int disable_irq_save(void)
114{
115 int oldlevel, tmp;
116 /* Using move.w over the compiler's move.l saves 2 bytes per instance */
117 asm volatile ("move.w %%sr, %1 \n"
118 "move.w %2, %0 \n"
119 "move.w %0, %%sr \n"
120 : "=&d"(tmp), "=d"(oldlevel)
121 : "i"(0x2000 | HIGHEST_IRQ_LEVEL));
88 return oldlevel; 122 return oldlevel;
89} 123}
90 124
125static inline void restore_irq(int oldlevel)
126{
127 /* Restore the sr value returned by disable_irq_save or
128 * set_irq_level */
129 asm volatile ("move.w %0, %%sr" : : "d"(oldlevel));
130}
131
91static inline uint16_t swap16(uint16_t value) 132static inline uint16_t swap16(uint16_t value)
92 /* 133 /*
93 result[15..8] = value[ 7..0]; 134 result[15..8] = value[ 7..0];
diff --git a/firmware/target/sh/archos/fm_v2/power-fm_v2.c b/firmware/target/sh/archos/fm_v2/power-fm_v2.c
index 94a36339bb..ac23348d42 100644
--- a/firmware/target/sh/archos/fm_v2/power-fm_v2.c
+++ b/firmware/target/sh/archos/fm_v2/power-fm_v2.c
@@ -101,9 +101,8 @@ bool ide_powered(void)
101 101
102void power_off(void) 102void power_off(void)
103{ 103{
104 set_irq_level(HIGHEST_IRQ_LEVEL); 104 disable_irq();
105 and_b(~0x20, &PBDRL); 105 and_b(~0x20, &PBDRL);
106 or_b(0x20, &PBIORL); 106 or_b(0x20, &PBIORL);
107 while(1) 107 while(1);
108 yield();
109} 108}
diff --git a/firmware/target/sh/archos/ondio/power-ondio.c b/firmware/target/sh/archos/ondio/power-ondio.c
index 156516afeb..87f365791b 100644
--- a/firmware/target/sh/archos/ondio/power-ondio.c
+++ b/firmware/target/sh/archos/ondio/power-ondio.c
@@ -66,13 +66,12 @@ void power_init(void)
66 66
67void power_off(void) 67void power_off(void)
68{ 68{
69 set_irq_level(HIGHEST_IRQ_LEVEL); 69 disable_irq();
70#ifdef HAVE_BACKLIGHT 70#ifdef HAVE_BACKLIGHT
71 /* Switch off the light on backlight-modded Ondios */ 71 /* Switch off the light on backlight-modded Ondios */
72 _backlight_off(); 72 _backlight_off();
73#endif 73#endif
74 and_b(~0x20, &PBDRL); 74 and_b(~0x20, &PBDRL);
75 or_b(0x20, &PBIORL); 75 or_b(0x20, &PBIORL);
76 while(1) 76 while(1);
77 yield();
78} 77}
diff --git a/firmware/target/sh/archos/player/power-player.c b/firmware/target/sh/archos/player/power-player.c
index 7d9d0d7d16..b2f51b9280 100644
--- a/firmware/target/sh/archos/player/power-player.c
+++ b/firmware/target/sh/archos/player/power-player.c
@@ -79,9 +79,8 @@ bool ide_powered(void)
79 79
80void power_off(void) 80void power_off(void)
81{ 81{
82 set_irq_level(HIGHEST_IRQ_LEVEL); 82 disable_irq();
83 and_b(~0x08, &PADRH); 83 and_b(~0x08, &PADRH);
84 or_b(0x08, &PAIORH); 84 or_b(0x08, &PAIORH);
85 while(1) 85 while(1);
86 yield();
87} 86}
diff --git a/firmware/target/sh/archos/recorder/power-recorder.c b/firmware/target/sh/archos/recorder/power-recorder.c
index 2af8df1bb6..1804bcb660 100644
--- a/firmware/target/sh/archos/recorder/power-recorder.c
+++ b/firmware/target/sh/archos/recorder/power-recorder.c
@@ -95,9 +95,8 @@ bool ide_powered(void)
95 95
96void power_off(void) 96void power_off(void)
97{ 97{
98 set_irq_level(HIGHEST_IRQ_LEVEL); 98 disable_irq();
99 and_b(~0x10, &PBDRL); 99 and_b(~0x10, &PBDRL);
100 or_b(0x10, &PBIORL); 100 or_b(0x10, &PBIORL);
101 while(1) 101 while(1);
102 yield();
103} 102}
diff --git a/firmware/target/sh/system-sh.c b/firmware/target/sh/system-sh.c
index eec3ec18e4..f763e0ff53 100644
--- a/firmware/target/sh/system-sh.c
+++ b/firmware/target/sh/system-sh.c
@@ -360,7 +360,7 @@ void system_init(void)
360 360
361void system_reboot (void) 361void system_reboot (void)
362{ 362{
363 set_irq_level(HIGHEST_IRQ_LEVEL); 363 disable_irq();
364 364
365 asm volatile ("ldc\t%0,vbr" : : "r"(0)); 365 asm volatile ("ldc\t%0,vbr" : : "r"(0));
366 366
diff --git a/firmware/target/sh/system-target.h b/firmware/target/sh/system-target.h
index 7fb8fecb6b..d641076694 100644
--- a/firmware/target/sh/system-target.h
+++ b/firmware/target/sh/system-target.h
@@ -52,11 +52,29 @@ static inline int set_irq_level(int level)
52{ 52{
53 int i; 53 int i;
54 /* Read the old level and set the new one */ 54 /* Read the old level and set the new one */
55 asm volatile ("stc sr, %0" : "=r" (i)); 55
56 /* Not volatile - will be optimized away if the return value isn't used */
57 asm ("stc sr, %0" : "=r" (i));
56 asm volatile ("ldc %0, sr" : : "r" (level)); 58 asm volatile ("ldc %0, sr" : : "r" (level));
57 return i; 59 return i;
58} 60}
59 61
62static inline void enable_irq(void)
63{
64 int i;
65 asm volatile ("mov %1, %0 \n" /* Save a constant load from RAM */
66 "ldc %0, sr \n" : "=&r"(i) : "i"(0));
67}
68
69#define disable_irq() \
70 ((void)set_irq_level(HIGHEST_IRQ_LEVEL))
71
72#define disable_irq_save() \
73 set_irq_level(HIGHEST_IRQ_LEVEL)
74
75#define restore_irq(i) \
76 ((void)set_irq_level(i))
77
60static inline uint16_t swap16(uint16_t value) 78static inline uint16_t swap16(uint16_t value)
61 /* 79 /*
62 result[15..8] = value[ 7..0]; 80 result[15..8] = value[ 7..0];
diff --git a/firmware/test/i2c/main.c b/firmware/test/i2c/main.c
index 0d54da5dea..e094a0b32e 100644
--- a/firmware/test/i2c/main.c
+++ b/firmware/test/i2c/main.c
@@ -542,7 +542,7 @@ int main(void)
542 542
543 543
544 544
545 set_irq_level(0); 545 enable_irq();
546 546
547 547
548 548
diff --git a/firmware/test/kernel/main.c b/firmware/test/kernel/main.c
index 99642c867d..cc0d93a6b4 100644
--- a/firmware/test/kernel/main.c
+++ b/firmware/test/kernel/main.c
@@ -59,7 +59,7 @@ int main(void)
59 59
60 kernel_init(); 60 kernel_init();
61 61
62 set_irq_level(0); 62 enable_irq();
63 63
64 tick_add_task(testfunc); 64 tick_add_task(testfunc);
65 65
diff --git a/firmware/thread.c b/firmware/thread.c
index 259a66a652..2ac7f6efc3 100644
--- a/firmware/thread.c
+++ b/firmware/thread.c
@@ -399,7 +399,7 @@ static inline void core_sleep(void)
399{ 399{
400 PROC_CTL(CURRENT_CORE) = PROC_SLEEP; 400 PROC_CTL(CURRENT_CORE) = PROC_SLEEP;
401 nop; nop; nop; 401 nop; nop; nop;
402 set_irq_level(IRQ_ENABLED); 402 enable_irq();
403} 403}
404#else 404#else
405static inline void core_sleep(unsigned int core) 405static inline void core_sleep(unsigned int core)
@@ -421,9 +421,6 @@ static inline void core_sleep(unsigned int core)
421 "ldr r1, [%[mbx], #0] \n" 421 "ldr r1, [%[mbx], #0] \n"
422 "tst r1, r0, lsr #2 \n" 422 "tst r1, r0, lsr #2 \n"
423 "bne 1b \n" 423 "bne 1b \n"
424 "mrs r1, cpsr \n" /* Enable IRQ */
425 "bic r1, r1, #0x80 \n"
426 "msr cpsr_c, r1 \n"
427 : 424 :
428 : [ctl]"r"(&PROC_CTL(CPU)), [mbx]"r"(MBX_BASE), [c]"r"(core) 425 : [ctl]"r"(&PROC_CTL(CPU)), [mbx]"r"(MBX_BASE), [c]"r"(core)
429 : "r0", "r1"); 426 : "r0", "r1");
@@ -443,10 +440,8 @@ static inline void core_sleep(unsigned int core)
443 440
444 /* Wait for other processor to finish wake procedure */ 441 /* Wait for other processor to finish wake procedure */
445 while (MBX_MSG_STAT & (0x1 << core)); 442 while (MBX_MSG_STAT & (0x1 << core));
446
447 /* Enable IRQ */
448 set_irq_level(IRQ_ENABLED);
449#endif /* ASM/C selection */ 443#endif /* ASM/C selection */
444 enable_irq();
450} 445}
451#endif /* NUM_CORES */ 446#endif /* NUM_CORES */
452#elif CONFIG_CPU == PP5002 447#elif CONFIG_CPU == PP5002
@@ -465,13 +460,11 @@ static inline void core_sleep(void)
465 "nop \n" /* nop's needed because of pipeline */ 460 "nop \n" /* nop's needed because of pipeline */
466 "nop \n" 461 "nop \n"
467 "nop \n" 462 "nop \n"
468 "mrs r0, cpsr \n" /* Enable IRQ */
469 "bic r0, r0, #0x80 \n"
470 "msr cpsr_c, r0 \n"
471 : 463 :
472 : [ctl]"r"(&PROC_CTL(CURRENT_CORE)) 464 : [ctl]"r"(&PROC_CTL(CURRENT_CORE))
473 : "r0" 465 : "r0"
474 ); 466 );
467 enable_irq();
475} 468}
476#else 469#else
477/* PP5002 has no mailboxes - emulate using bytes */ 470/* PP5002 has no mailboxes - emulate using bytes */
@@ -503,9 +496,6 @@ static inline void core_sleep(unsigned int core)
503 "ldrb r0, [%[sem], #0] \n" 496 "ldrb r0, [%[sem], #0] \n"
504 "cmp r0, #0 \n" 497 "cmp r0, #0 \n"
505 "bne 1b \n" 498 "bne 1b \n"
506 "mrs r0, cpsr \n" /* Enable IRQ */
507 "bic r0, r0, #0x80 \n"
508 "msr cpsr_c, r0 \n"
509 : 499 :
510 : [sem]"r"(&core_semaphores[core]), [c]"r"(core), 500 : [sem]"r"(&core_semaphores[core]), [c]"r"(core),
511 [ctl]"r"(&PROC_CTL(CPU)) 501 [ctl]"r"(&PROC_CTL(CPU))
@@ -530,8 +520,8 @@ static inline void core_sleep(unsigned int core)
530 while (core_semaphores[core].intend_wake != 0); 520 while (core_semaphores[core].intend_wake != 0);
531 521
532 /* Enable IRQ */ 522 /* Enable IRQ */
533 set_irq_level(IRQ_ENABLED);
534#endif /* ASM/C selection */ 523#endif /* ASM/C selection */
524 enable_irq();
535} 525}
536#endif /* NUM_CORES */ 526#endif /* NUM_CORES */
537#endif /* PP CPU type */ 527#endif /* PP CPU type */
@@ -578,7 +568,7 @@ void core_wake(unsigned int othercore)
578 : "r1", "r2", "r3"); 568 : "r1", "r2", "r3");
579#else /* C version for reference */ 569#else /* C version for reference */
580 /* Disable interrupts - avoid reentrancy from the tick */ 570 /* Disable interrupts - avoid reentrancy from the tick */
581 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 571 int oldlevel = disable_irq_save();
582 572
583 /* Signal intent to wake other processor - set stay awake */ 573 /* Signal intent to wake other processor - set stay awake */
584 MBX_MSG_SET = 0x11 << othercore; 574 MBX_MSG_SET = 0x11 << othercore;
@@ -593,7 +583,7 @@ void core_wake(unsigned int othercore)
593 583
594 /* Done with wake procedure */ 584 /* Done with wake procedure */
595 MBX_MSG_CLR = 0x1 << othercore; 585 MBX_MSG_CLR = 0x1 << othercore;
596 set_irq_level(oldlevel); 586 restore_irq(oldlevel);
597#endif /* ASM/C selection */ 587#endif /* ASM/C selection */
598} 588}
599#elif CONFIG_CPU == PP5002 589#elif CONFIG_CPU == PP5002
@@ -631,7 +621,7 @@ void core_wake(unsigned int othercore)
631 ); 621 );
632#else /* C version for reference */ 622#else /* C version for reference */
633 /* Disable interrupts - avoid reentrancy from the tick */ 623 /* Disable interrupts - avoid reentrancy from the tick */
634 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 624 int oldlevel = disable_irq_save();
635 625
636 /* Signal intent to wake other processor - set stay awake */ 626 /* Signal intent to wake other processor - set stay awake */
637 core_semaphores[othercore].intend_wake = 1; 627 core_semaphores[othercore].intend_wake = 1;
@@ -647,7 +637,7 @@ void core_wake(unsigned int othercore)
647 637
648 /* Done with wake procedure */ 638 /* Done with wake procedure */
649 core_semaphores[othercore].intend_wake = 0; 639 core_semaphores[othercore].intend_wake = 0;
650 set_irq_level(oldlevel); 640 restore_irq(oldlevel);
651#endif /* ASM/C selection */ 641#endif /* ASM/C selection */
652} 642}
653#endif /* CPU type */ 643#endif /* CPU type */
@@ -775,7 +765,7 @@ static inline void core_sleep(void)
775static inline void core_sleep(void) 765static inline void core_sleep(void)
776{ 766{
777 #warning TODO: Implement core_sleep 767 #warning TODO: Implement core_sleep
778 set_irq_level(IRQ_ENABLED); 768 enable_irq();
779} 769}
780#elif defined(CPU_TCC780X) 770#elif defined(CPU_TCC780X)
781static inline void core_sleep(void) 771static inline void core_sleep(void)
@@ -784,11 +774,9 @@ static inline void core_sleep(void)
784 asm volatile ( 774 asm volatile (
785 "mov r0, #0 \n" 775 "mov r0, #0 \n"
786 "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */ 776 "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */
787 "mrs r0, cpsr \n" /* Unmask IRQ at core level */
788 "bic r0, r0, #0x80 \n"
789 "msr cpsr_c, r0 \n"
790 : : : "r0" 777 : : : "r0"
791 ); 778 );
779 enable_irq();
792} 780}
793#elif CONFIG_CPU == IMX31L 781#elif CONFIG_CPU == IMX31L
794static inline void core_sleep(void) 782static inline void core_sleep(void)
@@ -796,17 +784,15 @@ static inline void core_sleep(void)
796 asm volatile ( 784 asm volatile (
797 "mov r0, #0 \n" 785 "mov r0, #0 \n"
798 "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */ 786 "mcr p15, 0, r0, c7, c0, 4 \n" /* Wait for interrupt */
799 "mrs r0, cpsr \n" /* Unmask IRQ at core level */
800 "bic r0, r0, #0x80 \n"
801 "msr cpsr_c, r0 \n"
802 : : : "r0" 787 : : : "r0"
803 ); 788 );
789 enable_irq();
804} 790}
805#else 791#else
806static inline void core_sleep(void) 792static inline void core_sleep(void)
807{ 793{
808 #warning core_sleep not implemented, battery life will be decreased 794 #warning core_sleep not implemented, battery life will be decreased
809 set_irq_level(0); 795 enable_irq();
810} 796}
811#endif /* CONFIG_CPU == */ 797#endif /* CONFIG_CPU == */
812 798
@@ -1706,14 +1692,14 @@ void check_tmo_threads(void)
1706 while (next != NULL) 1692 while (next != NULL)
1707 { 1693 {
1708 /* Check sleeping threads. Allow interrupts between checks. */ 1694 /* Check sleeping threads. Allow interrupts between checks. */
1709 set_irq_level(0); 1695 enable_irq();
1710 1696
1711 struct thread_entry *curr = next; 1697 struct thread_entry *curr = next;
1712 1698
1713 next = curr->tmo.next; 1699 next = curr->tmo.next;
1714 1700
1715 /* Lock thread slot against explicit wakeup */ 1701 /* Lock thread slot against explicit wakeup */
1716 set_irq_level(HIGHEST_IRQ_LEVEL); 1702 disable_irq();
1717 LOCK_THREAD(curr); 1703 LOCK_THREAD(curr);
1718 1704
1719 unsigned state = curr->state; 1705 unsigned state = curr->state;
@@ -1956,7 +1942,7 @@ void switch_thread(void)
1956 check_tmo_threads(); 1942 check_tmo_threads();
1957 } 1943 }
1958 1944
1959 set_irq_level(HIGHEST_IRQ_LEVEL); 1945 disable_irq();
1960 RTR_LOCK(core); 1946 RTR_LOCK(core);
1961 1947
1962 thread = cores[core].running; 1948 thread = cores[core].running;
@@ -2018,7 +2004,7 @@ void switch_thread(void)
2018#endif /* HAVE_PRIORITY_SCHEDULING */ 2004#endif /* HAVE_PRIORITY_SCHEDULING */
2019 2005
2020 RTR_UNLOCK(core); 2006 RTR_UNLOCK(core);
2021 set_irq_level(0); 2007 enable_irq();
2022 break; 2008 break;
2023 } 2009 }
2024 } 2010 }
@@ -2212,7 +2198,7 @@ unsigned int thread_queue_wake(struct thread_entry **list)
2212static struct thread_entry * find_empty_thread_slot(void) 2198static struct thread_entry * find_empty_thread_slot(void)
2213{ 2199{
2214 /* Any slot could be on an interrupt-accessible list */ 2200 /* Any slot could be on an interrupt-accessible list */
2215 IF_COP( int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); ) 2201 IF_COP( int oldlevel = disable_irq_save(); )
2216 struct thread_entry *thread = NULL; 2202 struct thread_entry *thread = NULL;
2217 int n; 2203 int n;
2218 2204
@@ -2233,7 +2219,7 @@ static struct thread_entry * find_empty_thread_slot(void)
2233 UNLOCK_THREAD(t); 2219 UNLOCK_THREAD(t);
2234 } 2220 }
2235 2221
2236 IF_COP( set_irq_level(oldlevel); ) /* Reenable interrups - this slot is 2222 IF_COP( restore_irq(oldlevel); ) /* Reenable interrups - this slot is
2237 not accesible to them yet */ 2223 not accesible to them yet */
2238 return thread; 2224 return thread;
2239} 2225}
@@ -2247,7 +2233,7 @@ static struct thread_entry * find_empty_thread_slot(void)
2247void core_idle(void) 2233void core_idle(void)
2248{ 2234{
2249 IF_COP( const unsigned int core = CURRENT_CORE; ) 2235 IF_COP( const unsigned int core = CURRENT_CORE; )
2250 set_irq_level(HIGHEST_IRQ_LEVEL); 2236 disable_irq();
2251 core_sleep(IF_COP(core)); 2237 core_sleep(IF_COP(core));
2252} 2238}
2253 2239
@@ -2277,7 +2263,7 @@ struct thread_entry*
2277 return NULL; 2263 return NULL;
2278 } 2264 }
2279 2265
2280 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 2266 oldlevel = disable_irq_save();
2281 2267
2282 /* Munge the stack to make it easy to spot stack overflows */ 2268 /* Munge the stack to make it easy to spot stack overflows */
2283 stackptr = ALIGN_UP((uintptr_t)stack, sizeof (uintptr_t)); 2269 stackptr = ALIGN_UP((uintptr_t)stack, sizeof (uintptr_t));
@@ -2338,7 +2324,7 @@ struct thread_entry*
2338 2324
2339 UNLOCK_THREAD(thread); 2325 UNLOCK_THREAD(thread);
2340 2326
2341 set_irq_level(oldlevel); 2327 restore_irq(oldlevel);
2342 2328
2343 return thread; 2329 return thread;
2344} 2330}
@@ -2394,7 +2380,7 @@ void thread_wait(struct thread_entry *thread)
2394 IF_COP( current->obj_cl = &thread->waiter_cl; ) 2380 IF_COP( current->obj_cl = &thread->waiter_cl; )
2395 current->bqp = &thread->queue; 2381 current->bqp = &thread->queue;
2396 2382
2397 set_irq_level(HIGHEST_IRQ_LEVEL); 2383 disable_irq();
2398 block_thread(current); 2384 block_thread(current);
2399 2385
2400 corelock_unlock(&thread->waiter_cl); 2386 corelock_unlock(&thread->waiter_cl);
@@ -2418,7 +2404,7 @@ void thread_exit(void)
2418 /* Cancel CPU boost if any */ 2404 /* Cancel CPU boost if any */
2419 cancel_cpu_boost(); 2405 cancel_cpu_boost();
2420 2406
2421 set_irq_level(HIGHEST_IRQ_LEVEL); 2407 disable_irq();
2422 2408
2423 corelock_lock(&current->waiter_cl); 2409 corelock_lock(&current->waiter_cl);
2424 LOCK_THREAD(current); 2410 LOCK_THREAD(current);
@@ -2503,7 +2489,7 @@ void remove_thread(struct thread_entry *thread)
2503 if (thread == current) 2489 if (thread == current)
2504 thread_exit(); /* Current thread - do normal exit */ 2490 thread_exit(); /* Current thread - do normal exit */
2505 2491
2506 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 2492 oldlevel = disable_irq_save();
2507 2493
2508 corelock_lock(&thread->waiter_cl); 2494 corelock_lock(&thread->waiter_cl);
2509 LOCK_THREAD(thread); 2495 LOCK_THREAD(thread);
@@ -2521,7 +2507,7 @@ void remove_thread(struct thread_entry *thread)
2521 /* Thread being killed - become a waiter */ 2507 /* Thread being killed - become a waiter */
2522 UNLOCK_THREAD(thread); 2508 UNLOCK_THREAD(thread);
2523 corelock_unlock(&thread->waiter_cl); 2509 corelock_unlock(&thread->waiter_cl);
2524 set_irq_level(oldlevel); 2510 restore_irq(oldlevel);
2525 thread_wait(thread); 2511 thread_wait(thread);
2526 return; 2512 return;
2527 } 2513 }
@@ -2543,11 +2529,11 @@ void remove_thread(struct thread_entry *thread)
2543 corelock_unlock(&thread->waiter_cl); 2529 corelock_unlock(&thread->waiter_cl);
2544 2530
2545 UNLOCK_THREAD(thread); 2531 UNLOCK_THREAD(thread);
2546 set_irq_level(oldlevel); 2532 restore_irq(oldlevel);
2547 2533
2548 old_core = switch_core(new_core); 2534 old_core = switch_core(new_core);
2549 2535
2550 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 2536 oldlevel = disable_irq_save();
2551 2537
2552 corelock_lock(&thread->waiter_cl); 2538 corelock_lock(&thread->waiter_cl);
2553 LOCK_THREAD(thread); 2539 LOCK_THREAD(thread);
@@ -2643,7 +2629,7 @@ thread_killed: /* Thread was already killed */
2643 /* Removal complete - safe to unlock and reenable interrupts */ 2629 /* Removal complete - safe to unlock and reenable interrupts */
2644 corelock_unlock(&thread->waiter_cl); 2630 corelock_unlock(&thread->waiter_cl);
2645 UNLOCK_THREAD(thread); 2631 UNLOCK_THREAD(thread);
2646 set_irq_level(oldlevel); 2632 restore_irq(oldlevel);
2647 2633
2648#if NUM_CORES > 1 2634#if NUM_CORES > 1
2649 if (old_core < NUM_CORES) 2635 if (old_core < NUM_CORES)
@@ -2675,7 +2661,7 @@ int thread_set_priority(struct thread_entry *thread, int priority)
2675 2661
2676 /* Thread could be on any list and therefore on an interrupt accessible 2662 /* Thread could be on any list and therefore on an interrupt accessible
2677 one - disable interrupts */ 2663 one - disable interrupts */
2678 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 2664 int oldlevel = disable_irq_save();
2679 2665
2680 LOCK_THREAD(thread); 2666 LOCK_THREAD(thread);
2681 2667
@@ -2788,7 +2774,7 @@ int thread_set_priority(struct thread_entry *thread, int priority)
2788 2774
2789 UNLOCK_THREAD(thread); 2775 UNLOCK_THREAD(thread);
2790 2776
2791 set_irq_level(oldlevel); 2777 restore_irq(oldlevel);
2792 2778
2793 return old_base_priority; 2779 return old_base_priority;
2794} 2780}
@@ -2815,14 +2801,14 @@ int thread_get_priority(struct thread_entry *thread)
2815 */ 2801 */
2816void thread_thaw(struct thread_entry *thread) 2802void thread_thaw(struct thread_entry *thread)
2817{ 2803{
2818 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 2804 int oldlevel = disable_irq_save();
2819 LOCK_THREAD(thread); 2805 LOCK_THREAD(thread);
2820 2806
2821 if (thread->state == STATE_FROZEN) 2807 if (thread->state == STATE_FROZEN)
2822 core_schedule_wakeup(thread); 2808 core_schedule_wakeup(thread);
2823 2809
2824 UNLOCK_THREAD(thread); 2810 UNLOCK_THREAD(thread);
2825 set_irq_level(oldlevel); 2811 restore_irq(oldlevel);
2826} 2812}
2827 2813
2828/*--------------------------------------------------------------------------- 2814/*---------------------------------------------------------------------------
@@ -2850,14 +2836,14 @@ unsigned int switch_core(unsigned int new_core)
2850 return core; 2836 return core;
2851 } 2837 }
2852 2838
2853 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 2839 int oldlevel = disable_irq_save();
2854 LOCK_THREAD(current); 2840 LOCK_THREAD(current);
2855 2841
2856 if (current->name == THREAD_DESTRUCT) 2842 if (current->name == THREAD_DESTRUCT)
2857 { 2843 {
2858 /* Thread being killed - deactivate and let process complete */ 2844 /* Thread being killed - deactivate and let process complete */
2859 UNLOCK_THREAD(current); 2845 UNLOCK_THREAD(current);
2860 set_irq_level(oldlevel); 2846 restore_irq(oldlevel);
2861 thread_wait(current); 2847 thread_wait(current);
2862 /* Should never be reached */ 2848 /* Should never be reached */
2863 THREAD_PANICF("switch_core->D:*R", current); 2849 THREAD_PANICF("switch_core->D:*R", current);
diff --git a/firmware/usb.c b/firmware/usb.c
index 2971ab7041..c33b62f244 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -568,10 +568,10 @@ bool usb_charging_enable(bool on)
568#ifdef IRIVER_H300_SERIES 568#ifdef IRIVER_H300_SERIES
569 int irqlevel; 569 int irqlevel;
570 logf("usb_charging_enable(%s)\n", on ? "on" : "off" ); 570 logf("usb_charging_enable(%s)\n", on ? "on" : "off" );
571 irqlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 571 irqlevel = disable_irq_save();
572 pcf50606_set_usb_charging(on); 572 pcf50606_set_usb_charging(on);
573 rc = on; 573 rc = on;
574 (void)set_irq_level(irqlevel); 574 restore_irq(irqlevel);
575#else 575#else
576 /* TODO: implement it for other targets... */ 576 /* TODO: implement it for other targets... */
577 (void)on; 577 (void)on;
diff --git a/flash/bootbox/main.c b/flash/bootbox/main.c
index 5cc4bb66ae..1f459b7bcb 100644
--- a/flash/bootbox/main.c
+++ b/flash/bootbox/main.c
@@ -156,7 +156,7 @@ void main(void)
156 buffer_init(); 156 buffer_init();
157 lcd_init(); 157 lcd_init();
158 show_logo(); 158 show_logo();
159 set_irq_level(0); 159 enable_irq();
160 adc_init(); 160 adc_init();
161 usb_init(); 161 usb_init();
162 button_init(); 162 button_init();
diff --git a/uisimulator/sdl/system-sdl.h b/uisimulator/sdl/system-sdl.h
index c5e7d40560..08f702d01e 100644
--- a/uisimulator/sdl/system-sdl.h
+++ b/uisimulator/sdl/system-sdl.h
@@ -24,6 +24,19 @@
24#define HIGHEST_IRQ_LEVEL 1 24#define HIGHEST_IRQ_LEVEL 1
25 25
26int set_irq_level(int level); 26int set_irq_level(int level);
27
28#define disable_irq() \
29 ((void)set_irq_level(HIGHEST_IRQ_LEVEL))
30
31#define enable_irq() \
32 ((void)set_irq_level(0))
33
34#define disable_irq_save() \
35 set_irq_level(HIGHEST_IRQ_LEVEL)
36
37#define restore_irq(level) \
38 ((void)set_irq_level(level))
39
27void sim_enter_irq_handler(void); 40void sim_enter_irq_handler(void);
28void sim_exit_irq_handler(void); 41void sim_exit_irq_handler(void);
29bool sim_kernel_init(void); 42bool sim_kernel_init(void);
diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c
index 78a66f72a7..5aae9a4bf8 100644
--- a/uisimulator/sdl/thread-sdl.c
+++ b/uisimulator/sdl/thread-sdl.c
@@ -246,7 +246,7 @@ void switch_thread(void)
246{ 246{
247 struct thread_entry *current = cores[CURRENT_CORE].running; 247 struct thread_entry *current = cores[CURRENT_CORE].running;
248 248
249 set_irq_level(0); 249 enable_irq();
250 250
251 switch (current->state) 251 switch (current->state)
252 { 252 {
@@ -266,9 +266,9 @@ void switch_thread(void)
266 SDL_SemWait(current->context.s); 266 SDL_SemWait(current->context.s);
267 SDL_LockMutex(m); 267 SDL_LockMutex(m);
268 268
269 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 269 oldlevel = disable_irq_save();
270 current->state = STATE_RUNNING; 270 current->state = STATE_RUNNING;
271 set_irq_level(oldlevel); 271 restore_irq(oldlevel);
272 break; 272 break;
273 } /* STATE_BLOCKED: */ 273 } /* STATE_BLOCKED: */
274 274
@@ -280,7 +280,7 @@ void switch_thread(void)
280 result = SDL_SemWaitTimeout(current->context.s, current->tmo_tick); 280 result = SDL_SemWaitTimeout(current->context.s, current->tmo_tick);
281 SDL_LockMutex(m); 281 SDL_LockMutex(m);
282 282
283 oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 283 oldlevel = disable_irq_save();
284 284
285 if (current->state == STATE_BLOCKED_W_TMO) 285 if (current->state == STATE_BLOCKED_W_TMO)
286 { 286 {
@@ -303,7 +303,7 @@ void switch_thread(void)
303 SDL_SemTryWait(current->context.s); 303 SDL_SemTryWait(current->context.s);
304 } 304 }
305 305
306 set_irq_level(oldlevel); 306 restore_irq(oldlevel);
307 break; 307 break;
308 } /* STATE_BLOCKED_W_TMO: */ 308 } /* STATE_BLOCKED_W_TMO: */
309 309
@@ -505,7 +505,7 @@ void remove_thread(struct thread_entry *thread)
505 SDL_Thread *t; 505 SDL_Thread *t;
506 SDL_sem *s; 506 SDL_sem *s;
507 507
508 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 508 int oldlevel = disable_irq_save();
509 509
510 if (thread == NULL) 510 if (thread == NULL)
511 { 511 {
@@ -547,12 +547,12 @@ void remove_thread(struct thread_entry *thread)
547 { 547 {
548 /* Do a graceful exit - perform the longjmp back into the thread 548 /* Do a graceful exit - perform the longjmp back into the thread
549 function to return */ 549 function to return */
550 set_irq_level(oldlevel); 550 restore_irq(oldlevel);
551 longjmp(thread_jmpbufs[current - threads], 1); 551 longjmp(thread_jmpbufs[current - threads], 1);
552 } 552 }
553 553
554 SDL_KillThread(t); 554 SDL_KillThread(t);
555 set_irq_level(oldlevel); 555 restore_irq(oldlevel);
556} 556}
557 557
558void thread_exit(void) 558void thread_exit(void)