summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-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
39 files changed, 230 insertions, 131 deletions
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];