diff options
Diffstat (limited to 'firmware/target')
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 |
111 | static void lcd_tick(void) | 111 | static 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 | ||
144 | static inline void lcd_block_tick(void) | 144 | static 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 | ||
158 | static void lcd_unblock_and_update(void) | 158 | static 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 */ |
224 | void pcm_play_lock(void) | 224 | void 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 | ||
235 | void pcm_play_unlock(void) | 235 | void 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 | ||
246 | static void play_start_pcm(void) | 246 | static 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 */ |
374 | void pcm_rec_lock(void) | 374 | void 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 | ||
384 | void pcm_rec_unlock(void) | 384 | void 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 | ||
56 | void power_off(void) | 56 | void 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) | |||
113 | static void do_set_mem_timings(void) ICODE_ATTR; | 113 | static void do_set_mem_timings(void) ICODE_ATTR; |
114 | static void do_set_mem_timings(void) | 114 | static 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 | ||
136 | static void emc_set_mem_timings(void) | 136 | static 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 | ||
67 | void pcm_apply_settings(void) | 67 | void 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 */ |
76 | void pcm_play_lock(void) | 76 | void 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 | ||
84 | void pcm_play_unlock(void) | 84 | void 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 | ||
92 | void pcm_play_dma_init(void) | 92 | void 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 | ||
77 | static 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 | |||
88 | static 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 | ||
114 | static inline int set_interrupt_status(int status, int mask) | 96 | static 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 | ||
112 | static 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 | |||
123 | static 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 | |||
146 | static 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 | |||
165 | static 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 @@ | |||
28 | void _backlight_on(void) | 28 | void _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 | ||
37 | void _backlight_off(void) | 37 | void _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 | ||
99 | static void dsp_load(const struct dsp_section *im) | 99 | static 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 | ||
39 | void audio_input_mux(int source, unsigned flags) | 39 | void 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 | ||
38 | void audio_input_mux(int source, unsigned flags) | 38 | void 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 | ||
34 | void _backlight_on(void) | 34 | void _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 | ||
42 | void _backlight_off(void) | 42 | void _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 | ||
50 | void _remote_backlight_on(void) | 50 | void _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) | |||
44 | void ide_power_enable(bool on) | 44 | void 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 | ||
52 | bool ide_powered(void) | 52 | bool 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 | ||
95 | void pcf50606_reset_timeout(void) | 95 | void 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 | ||
38 | void audio_input_mux(int source, unsigned flags) | 38 | void 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 | ||
47 | void _backlight_off(void) | 47 | void _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) | |||
66 | void _backlight_set_brightness(int val) | 66 | void _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 | ||
75 | void _remote_backlight_on(void) | 75 | void _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 | */ |
135 | int ds2411_read_id(struct ds2411_id *id) | 135 | int 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) | |||
44 | void ide_power_enable(bool on) | 44 | void 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 | ||
52 | bool ide_powered(void) | 52 | bool 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 | ||
47 | void audio_input_mux(int source, unsigned flags) | 47 | void 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 | ||
48 | unsigned short adc_scan(int channel) | 48 | unsigned 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 | ||
35 | unsigned short adc_scan(int channel) | 35 | unsigned 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) | |||
51 | void _backlight_set_brightness(int val) | 51 | void _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 | ||
60 | void _remote_backlight_on(void) | 60 | void _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 | ||
181 | void pcm_play_dma_init(void) | 181 | void 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 */ | ||
93 | static 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 */ | ||
103 | static 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 | |||
113 | static 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 | ||
125 | static 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 | |||
91 | static inline uint16_t swap16(uint16_t value) | 132 | static 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 | ||
102 | void power_off(void) | 102 | void 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 | ||
67 | void power_off(void) | 67 | void 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 | ||
80 | void power_off(void) | 80 | void 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 | ||
96 | void power_off(void) | 96 | void 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 | ||
361 | void system_reboot (void) | 361 | void 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 | ||
62 | static 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 | |||
60 | static inline uint16_t swap16(uint16_t value) | 78 | static inline uint16_t swap16(uint16_t value) |
61 | /* | 79 | /* |
62 | result[15..8] = value[ 7..0]; | 80 | result[15..8] = value[ 7..0]; |