summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs.h6
-rw-r--r--apps/codecs/mpa.c4
-rw-r--r--apps/codecs/spc.c17
-rw-r--r--apps/plugin.h6
-rw-r--r--firmware/export/config.h4
-rw-r--r--firmware/export/kernel.h20
-rw-r--r--firmware/export/thread.h4
-rw-r--r--firmware/kernel.c166
-rw-r--r--firmware/target/arm/as3525/ascodec-as3525.c27
-rw-r--r--firmware/target/arm/as3525/ascodec-target.h2
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c12
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c16
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525.c24
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525.h2
-rw-r--r--firmware/target/arm/as3525/usb-drv-as3525v2.c22
-rw-r--r--firmware/target/arm/imx31/ata-imx31.c12
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c8
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/headphone-gigabeat-s.c8
-rw-r--r--firmware/target/arm/imx31/i2c-imx31.c8
-rw-r--r--firmware/target/arm/imx31/mc13783-imx31.c20
-rw-r--r--firmware/target/arm/ipod/button-clickwheel.c8
-rw-r--r--firmware/target/arm/ipod/video/lcd-video.c8
-rw-r--r--firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c10
-rw-r--r--firmware/target/arm/s3c2440/i2c-s3c2440.c8
-rw-r--r--firmware/target/arm/s3c2440/sd-s3c2440.c10
-rw-r--r--firmware/target/arm/s5l8700/adc-s5l8700.c8
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c8
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c8
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c35
-rw-r--r--firmware/target/arm/system-arm.h22
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c14
-rw-r--r--firmware/target/arm/usb-drv-arc.c14
-rw-r--r--firmware/target/arm/usb-s3c6400x.c14
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c10
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c12
-rw-r--r--firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/usb-jz4740.c8
38 files changed, 292 insertions, 309 deletions
diff --git a/apps/codecs.h b/apps/codecs.h
index 8a40791106..028e3614ff 100644
--- a/apps/codecs.h
+++ b/apps/codecs.h
@@ -75,12 +75,12 @@
75#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */ 75#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
76 76
77/* increase this every time the api struct changes */ 77/* increase this every time the api struct changes */
78#define CODEC_API_VERSION 38 78#define CODEC_API_VERSION 39
79 79
80/* update this to latest version if a change to the api struct breaks 80/* update this to latest version if a change to the api struct breaks
81 backwards compatibility (and please take the opportunity to sort in any 81 backwards compatibility (and please take the opportunity to sort in any
82 new function which are "waiting" at the end of the function table) */ 82 new function which are "waiting" at the end of the function table) */
83#define CODEC_MIN_API_VERSION 38 83#define CODEC_MIN_API_VERSION 39
84 84
85/* codec return codes */ 85/* codec return codes */
86enum codec_status { 86enum codec_status {
@@ -166,7 +166,7 @@ struct codec_api {
166 void (*thread_thaw)(unsigned int thread_id); 166 void (*thread_thaw)(unsigned int thread_id);
167 void (*thread_wait)(unsigned int thread_id); 167 void (*thread_wait)(unsigned int thread_id);
168 void (*semaphore_init)(struct semaphore *s, int max, int start); 168 void (*semaphore_init)(struct semaphore *s, int max, int start);
169 void (*semaphore_wait)(struct semaphore *s); 169 int (*semaphore_wait)(struct semaphore *s, int timeout);
170 void (*semaphore_release)(struct semaphore *s); 170 void (*semaphore_release)(struct semaphore *s);
171#endif /* NUM_CORES */ 171#endif /* NUM_CORES */
172 172
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c
index d3da63b430..4d6c52f2b3 100644
--- a/apps/codecs/mpa.c
+++ b/apps/codecs/mpa.c
@@ -211,7 +211,7 @@ static void mad_synth_thread(void)
211{ 211{
212 while(1) { 212 while(1) {
213 ci->semaphore_release(&synth_done_sem); 213 ci->semaphore_release(&synth_done_sem);
214 ci->semaphore_wait(&synth_pending_sem); 214 ci->semaphore_wait(&synth_pending_sem, TIMEOUT_BLOCK);
215 215
216 if(die) 216 if(die)
217 break; 217 break;
@@ -224,7 +224,7 @@ static void mad_synth_thread(void)
224 * synthesized */ 224 * synthesized */
225static inline void mad_synth_thread_wait_pcm(void) 225static inline void mad_synth_thread_wait_pcm(void)
226{ 226{
227 ci->semaphore_wait(&synth_done_sem); 227 ci->semaphore_wait(&synth_done_sem, TIMEOUT_BLOCK);
228} 228}
229 229
230/* increment the done semaphore - used after a wait for idle to preserve the 230/* increment the done semaphore - used after a wait for idle to preserve the
diff --git a/apps/codecs/spc.c b/apps/codecs/spc.c
index d4ed741f7e..4db2878964 100644
--- a/apps/codecs/spc.c
+++ b/apps/codecs/spc.c
@@ -244,7 +244,7 @@ static inline void samples_release_wrbuf(void)
244 244
245static inline struct sample_queue_chunk * samples_get_wrbuf(void) 245static inline struct sample_queue_chunk * samples_get_wrbuf(void)
246{ 246{
247 ci->semaphore_wait(&sample_queue.emu_sem_tail); 247 ci->semaphore_wait(&sample_queue.emu_sem_tail, TIMEOUT_BLOCK);
248 return &sample_queue.wav_chunk[sample_queue.tail & WAV_CHUNK_MASK]; 248 return &sample_queue.wav_chunk[sample_queue.tail & WAV_CHUNK_MASK];
249} 249}
250 250
@@ -259,7 +259,7 @@ static inline void samples_release_rdbuf(void)
259 259
260static inline int32_t * samples_get_rdbuf(void) 260static inline int32_t * samples_get_rdbuf(void)
261{ 261{
262 ci->semaphore_wait(&sample_queue.emu_sem_head); 262 ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_BLOCK);
263 263
264 if (ci->stop_codec || ci->new_track) 264 if (ci->stop_codec || ci->new_track)
265 { 265 {
@@ -275,7 +275,7 @@ static intptr_t emu_thread_send_msg(long id, intptr_t data)
275{ 275{
276 struct sample_queue_chunk *chunk; 276 struct sample_queue_chunk *chunk;
277 /* Grab an audio output buffer */ 277 /* Grab an audio output buffer */
278 ci->semaphore_wait(&sample_queue.emu_sem_head); 278 ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_BLOCK);
279 chunk = &sample_queue.wav_chunk[sample_queue.head & WAV_CHUNK_MASK]; 279 chunk = &sample_queue.wav_chunk[sample_queue.head & WAV_CHUNK_MASK];
280 /* Place a message in it instead of audio */ 280 /* Place a message in it instead of audio */
281 chunk->id = id; 281 chunk->id = id;
@@ -285,7 +285,7 @@ static intptr_t emu_thread_send_msg(long id, intptr_t data)
285 285
286 if (id != SPC_EMU_QUIT) { 286 if (id != SPC_EMU_QUIT) {
287 /* Wait for a response */ 287 /* Wait for a response */
288 ci->semaphore_wait(&sample_queue.emu_evt_reply); 288 ci->semaphore_wait(&sample_queue.emu_evt_reply, TIMEOUT_BLOCK);
289 } 289 }
290 290
291 return sample_queue.retval; 291 return sample_queue.retval;
@@ -308,11 +308,10 @@ static bool emu_thread_process_msg(struct sample_queue_chunk *chunk)
308 sample_queue.retval = SPC_load_spc(&spc_emu, ld->buf, ld->size); 308 sample_queue.retval = SPC_load_spc(&spc_emu, ld->buf, ld->size);
309 309
310 /* Empty the audio queue */ 310 /* Empty the audio queue */
311 /* This is a dirty hack a timeout based wait would make unnescessary but 311 ci->semaphore_release(&sample_queue.emu_sem_tail);
312 still safe because the other thread is known to be waiting for a reply 312 ci->semaphore_release(&sample_queue.emu_sem_tail);
313 and is not using the objects. */ 313 ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_NOBLOCK);
314 ci->semaphore_init(&sample_queue.emu_sem_tail, 2, 2); 314 ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_NOBLOCK);
315 ci->semaphore_init(&sample_queue.emu_sem_head, 2, 0);
316 sample_queue.head = sample_queue.tail = 0; 315 sample_queue.head = sample_queue.tail = 0;
317 } 316 }
318 317
diff --git a/apps/plugin.h b/apps/plugin.h
index 8c2d458c57..2275b309d7 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -145,12 +145,12 @@ void* plugin_get_buffer(size_t *buffer_size);
145#define PLUGIN_MAGIC 0x526F634B /* RocK */ 145#define PLUGIN_MAGIC 0x526F634B /* RocK */
146 146
147/* increase this every time the api struct changes */ 147/* increase this every time the api struct changes */
148#define PLUGIN_API_VERSION 199 148#define PLUGIN_API_VERSION 200
149 149
150/* update this to latest version if a change to the api struct breaks 150/* update this to latest version if a change to the api struct breaks
151 backwards compatibility (and please take the opportunity to sort in any 151 backwards compatibility (and please take the opportunity to sort in any
152 new function which are "waiting" at the end of the function table) */ 152 new function which are "waiting" at the end of the function table) */
153#define PLUGIN_MIN_API_VERSION 199 153#define PLUGIN_MIN_API_VERSION 200
154 154
155/* plugin return codes */ 155/* plugin return codes */
156/* internal returns start at 0x100 to make exit(1..255) work */ 156/* internal returns start at 0x100 to make exit(1..255) work */
@@ -901,7 +901,7 @@ struct plugin_api {
901 901
902#ifdef HAVE_SEMAPHORE_OBJECTS 902#ifdef HAVE_SEMAPHORE_OBJECTS
903 void (*semaphore_init)(struct semaphore *s, int max, int start); 903 void (*semaphore_init)(struct semaphore *s, int max, int start);
904 void (*semaphore_wait)(struct semaphore *s); 904 int (*semaphore_wait)(struct semaphore *s, int timeout);
905 void (*semaphore_release)(struct semaphore *s); 905 void (*semaphore_release)(struct semaphore *s);
906#endif 906#endif
907 907
diff --git a/firmware/export/config.h b/firmware/export/config.h
index d00958a71d..341985f9e7 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -741,8 +741,6 @@ Lyre prototype 1 */
741#endif /* PLATFORM_NATIVE */ 741#endif /* PLATFORM_NATIVE */
742 742
743 743
744#define HAVE_SEMAPHORE_OBJECTS
745
746#ifdef HAVE_USBSTACK 744#ifdef HAVE_USBSTACK
747#if CONFIG_USBOTG == USBOTG_ARC 745#if CONFIG_USBOTG == USBOTG_ARC
748#define USB_STATUS_BY_EVENT 746#define USB_STATUS_BY_EVENT
@@ -769,7 +767,7 @@ Lyre prototype 1 */
769 || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \ 767 || (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \
770 || defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \ 768 || defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \
771 || defined(APPLICATION) 769 || defined(APPLICATION)
772#define HAVE_WAKEUP_OBJECTS 770#define HAVE_SEMAPHORE_OBJECTS
773#endif 771#endif
774 772
775/*include support for crossfading - requires significant PCM buffer space*/ 773/*include support for crossfading - requires significant PCM buffer space*/
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h
index 20743c554b..6aaf11ddb9 100644
--- a/firmware/export/kernel.h
+++ b/firmware/export/kernel.h
@@ -160,22 +160,12 @@ struct mutex
160struct semaphore 160struct semaphore
161{ 161{
162 struct thread_entry *queue; /* Waiter list */ 162 struct thread_entry *queue; /* Waiter list */
163 int count; /* # of waits remaining before unsignaled */ 163 int volatile count; /* # of waits remaining before unsignaled */
164 int max; /* maximum # of waits to remain signaled */ 164 int max; /* maximum # of waits to remain signaled */
165 IF_COP( struct corelock cl; ) /* multiprocessor sync */ 165 IF_COP( struct corelock cl; ) /* multiprocessor sync */
166}; 166};
167#endif 167#endif
168 168
169#ifdef HAVE_WAKEUP_OBJECTS
170struct wakeup
171{
172 struct thread_entry *queue; /* waiter list */
173 bool volatile signalled; /* signalled status */
174 IF_COP( struct corelock cl; ) /* multiprocessor sync */
175};
176#endif
177
178
179/* global tick variable */ 169/* global tick variable */
180#if defined(CPU_PP) && defined(BOOTLOADER) && \ 170#if defined(CPU_PP) && defined(BOOTLOADER) && \
181 !defined(HAVE_BOOTLOADER_USB_MODE) 171 !defined(HAVE_BOOTLOADER_USB_MODE)
@@ -280,14 +270,8 @@ static inline bool mutex_test(const struct mutex *m)
280 270
281#ifdef HAVE_SEMAPHORE_OBJECTS 271#ifdef HAVE_SEMAPHORE_OBJECTS
282extern void semaphore_init(struct semaphore *s, int max, int start); 272extern void semaphore_init(struct semaphore *s, int max, int start);
283extern void semaphore_wait(struct semaphore *s); 273extern int semaphore_wait(struct semaphore *s, int timeout);
284extern void semaphore_release(struct semaphore *s); 274extern void semaphore_release(struct semaphore *s);
285#endif /* HAVE_SEMAPHORE_OBJECTS */ 275#endif /* HAVE_SEMAPHORE_OBJECTS */
286 276
287#ifdef HAVE_WAKEUP_OBJECTS
288extern void wakeup_init(struct wakeup *w);
289extern int wakeup_wait(struct wakeup *w, int timeout);
290extern int wakeup_signal(struct wakeup *w);
291#endif /* HAVE_WAKEUP_OBJECTS */
292
293#endif /* _KERNEL_H_ */ 277#endif /* _KERNEL_H_ */
diff --git a/firmware/export/thread.h b/firmware/export/thread.h
index 179979a98a..0db849ab0a 100644
--- a/firmware/export/thread.h
+++ b/firmware/export/thread.h
@@ -284,7 +284,9 @@ struct thread_entry
284 and priority disinheritance */ 284 and priority disinheritance */
285 /* Only enabled when using queue_send for now */ 285 /* Only enabled when using queue_send for now */
286#endif 286#endif
287#if defined(HAVE_EXTENDED_MESSAGING_AND_NAME) || NUM_CORES > 1 287#if defined(HAVE_SEMAPHORE_OBJECTS) || \
288 defined(HAVE_EXTENDED_MESSAGING_AND_NAME) || \
289 NUM_CORES > 1
288 volatile intptr_t retval; /* Return value from a blocked operation/ 290 volatile intptr_t retval; /* Return value from a blocked operation/
289 misc. use */ 291 misc. use */
290#endif 292#endif
diff --git a/firmware/kernel.c b/firmware/kernel.c
index 588bbd2a75..a8718ebf34 100644
--- a/firmware/kernel.c
+++ b/firmware/kernel.c
@@ -978,6 +978,9 @@ void mutex_unlock(struct mutex *m)
978 * Simple semaphore functions ;) 978 * Simple semaphore functions ;)
979 ****************************************************************************/ 979 ****************************************************************************/
980#ifdef HAVE_SEMAPHORE_OBJECTS 980#ifdef HAVE_SEMAPHORE_OBJECTS
981/* Initialize the semaphore object.
982 * max = maximum up count the semaphore may assume (max >= 1)
983 * start = initial count of semaphore (0 <= count <= max) */
981void semaphore_init(struct semaphore *s, int max, int start) 984void semaphore_init(struct semaphore *s, int max, int start)
982{ 985{
983 KERNEL_ASSERT(max > 0 && start >= 0 && start <= max, 986 KERNEL_ASSERT(max > 0 && start >= 0 && start <= max,
@@ -988,132 +991,97 @@ void semaphore_init(struct semaphore *s, int max, int start)
988 corelock_init(&s->cl); 991 corelock_init(&s->cl);
989} 992}
990 993
991void semaphore_wait(struct semaphore *s) 994/* Down the semaphore's count or wait for 'timeout' ticks for it to go up if
995 * it is already 0. 'timeout' as TIMEOUT_NOBLOCK (0) will not block and may
996 * safely be used in an ISR. */
997int semaphore_wait(struct semaphore *s, int timeout)
992{ 998{
993 struct thread_entry *current; 999 int ret;
1000 int oldlevel;
1001 int count;
994 1002
1003 oldlevel = disable_irq_save();
995 corelock_lock(&s->cl); 1004 corelock_lock(&s->cl);
996 1005
997 if(LIKELY(--s->count >= 0)) 1006 count = s->count;
1007
1008 if(LIKELY(count > 0))
998 { 1009 {
999 /* wait satisfied */ 1010 /* count is not zero; down it */
1000 corelock_unlock(&s->cl); 1011 s->count = count - 1;
1001 return; 1012 ret = OBJ_WAIT_SUCCEEDED;
1013 }
1014 else if(timeout == 0)
1015 {
1016 /* just polling it */
1017 ret = OBJ_WAIT_TIMEDOUT;
1002 } 1018 }
1019 else
1020 {
1021 /* too many waits - block until count is upped... */
1022 struct thread_entry * current = thread_id_entry(THREAD_ID_CURRENT);
1023 IF_COP( current->obj_cl = &s->cl; )
1024 current->bqp = &s->queue;
1025 /* return value will be OBJ_WAIT_SUCCEEDED after wait if wake was
1026 * explicit in semaphore_release */
1027 current->retval = OBJ_WAIT_TIMEDOUT;
1028
1029 if(timeout > 0)
1030 block_thread_w_tmo(current, timeout); /* ...or timed out... */
1031 else
1032 block_thread(current); /* -timeout = infinite */
1003 1033
1004 /* too many waits - block until dequeued... */ 1034 corelock_unlock(&s->cl);
1005 current = thread_id_entry(THREAD_ID_CURRENT);
1006 1035
1007 IF_COP( current->obj_cl = &s->cl; ) 1036 /* ...and turn control over to next thread */
1008 current->bqp = &s->queue; 1037 switch_thread();
1009 1038
1010 disable_irq(); 1039 return current->retval;
1011 block_thread(current); 1040 }
1012 1041
1013 corelock_unlock(&s->cl); 1042 corelock_unlock(&s->cl);
1043 restore_irq(oldlevel);
1014 1044
1015 /* ...and turn control over to next thread */ 1045 return ret;
1016 switch_thread();
1017} 1046}
1018 1047
1048/* Up the semaphore's count and release any thread waiting at the head of the
1049 * queue. The count is saturated to the value of the 'max' parameter specified
1050 * in 'semaphore_init'. */
1019void semaphore_release(struct semaphore *s) 1051void semaphore_release(struct semaphore *s)
1020{ 1052{
1021 IF_PRIO( unsigned int result = THREAD_NONE; ) 1053 IF_PRIO( unsigned int result = THREAD_NONE; )
1054 int oldlevel;
1022 1055
1056 oldlevel = disable_irq_save();
1023 corelock_lock(&s->cl); 1057 corelock_lock(&s->cl);
1024 1058
1025 if(s->count < s->max && ++s->count <= 0) 1059 if(LIKELY(s->queue != NULL))
1026 { 1060 {
1027 /* there should be threads in this queue */ 1061 /* a thread was queued - wake it up and keep count at 0 */
1028 KERNEL_ASSERT(s->queue != NULL, "semaphore->wakeup\n"); 1062 KERNEL_ASSERT(s->count == 0,
1029 /* a thread was queued - wake it up */ 1063 "semaphore_release->threads queued but count=%d!\n", s->count);
1030 int oldlevel = disable_irq_save(); 1064 s->queue->retval = OBJ_WAIT_SUCCEEDED; /* indicate explicit wake */
1031 IF_PRIO( result = ) wakeup_thread(&s->queue); 1065 IF_PRIO( result = ) wakeup_thread(&s->queue);
1032 restore_irq(oldlevel); 1066 }
1067 else
1068 {
1069 int count = s->count;
1070 if(count < s->max)
1071 {
1072 /* nothing waiting - up it */
1073 s->count = count + 1;
1074 }
1033 } 1075 }
1034 1076
1035 corelock_unlock(&s->cl); 1077 corelock_unlock(&s->cl);
1078 restore_irq(oldlevel);
1036 1079
1037#ifdef HAVE_PRIORITY_SCHEDULING 1080#if defined(HAVE_PRIORITY_SCHEDULING) && defined(irq_enabled_checkval)
1038 if(result & THREAD_SWITCH) 1081 /* No thread switch if IRQ disabled - it's probably called via ISR.
1082 * switch_thread would as well enable them anyway. */
1083 if((result & THREAD_SWITCH) && irq_enabled_checkval(oldlevel))
1039 switch_thread(); 1084 switch_thread();
1040#endif 1085#endif
1041} 1086}
1042#endif /* HAVE_SEMAPHORE_OBJECTS */ 1087#endif /* HAVE_SEMAPHORE_OBJECTS */
1043
1044#ifdef HAVE_WAKEUP_OBJECTS
1045/****************************************************************************
1046 * Lightweight IRQ-compatible wakeup object
1047 */
1048
1049/* Initialize the wakeup object */
1050void wakeup_init(struct wakeup *w)
1051{
1052 w->queue = NULL;
1053 w->signalled = false;
1054 IF_COP( corelock_init(&w->cl); )
1055}
1056
1057/* Wait for a signal blocking indefinitely or for a specified period */
1058int wakeup_wait(struct wakeup *w, int timeout)
1059{
1060 int ret = OBJ_WAIT_SUCCEEDED; /* Presume success */
1061 int oldlevel = disable_irq_save();
1062
1063 corelock_lock(&w->cl);
1064
1065 if(LIKELY(!w->signalled && timeout != TIMEOUT_NOBLOCK))
1066 {
1067 struct thread_entry * current = thread_id_entry(THREAD_ID_CURRENT);
1068
1069 IF_COP( current->obj_cl = &w->cl; )
1070 current->bqp = &w->queue;
1071
1072 if (timeout != TIMEOUT_BLOCK)
1073 block_thread_w_tmo(current, timeout);
1074 else
1075 block_thread(current);
1076
1077 corelock_unlock(&w->cl);
1078 switch_thread();
1079
1080 oldlevel = disable_irq_save();
1081 corelock_lock(&w->cl);
1082 }
1083
1084 if(UNLIKELY(!w->signalled))
1085 {
1086 /* Timed-out or failed */
1087 ret = (timeout != TIMEOUT_BLOCK) ?
1088 OBJ_WAIT_TIMEDOUT : OBJ_WAIT_FAILED;
1089 }
1090
1091 w->signalled = false; /* Reset */
1092
1093 corelock_unlock(&w->cl);
1094 restore_irq(oldlevel);
1095
1096 return ret;
1097}
1098
1099/* Signal the thread waiting or leave the signal if the thread hasn't
1100 * waited yet.
1101 *
1102 * returns THREAD_NONE or THREAD_OK
1103 */
1104int wakeup_signal(struct wakeup *w)
1105{
1106 int oldlevel = disable_irq_save();
1107 int ret;
1108
1109 corelock_lock(&w->cl);
1110
1111 w->signalled = true;
1112 ret = wakeup_thread(&w->queue);
1113
1114 corelock_unlock(&w->cl);
1115 restore_irq(oldlevel);
1116
1117 return ret;
1118}
1119#endif /* HAVE_WAKEUP_OBJECTS */
diff --git a/firmware/target/arm/as3525/ascodec-as3525.c b/firmware/target/arm/as3525/ascodec-as3525.c
index 822d48e241..39658c0637 100644
--- a/firmware/target/arm/as3525/ascodec-as3525.c
+++ b/firmware/target/arm/as3525/ascodec-as3525.c
@@ -107,7 +107,7 @@ struct ascodec_request {
107 unsigned char status; 107 unsigned char status;
108 unsigned char cnt; 108 unsigned char cnt;
109 unsigned char data[ASCODEC_REQ_MAXLEN]; 109 unsigned char data[ASCODEC_REQ_MAXLEN];
110 struct wakeup wkup; 110 struct semaphore complete;
111 ascodec_cb_fn *callback; 111 ascodec_cb_fn *callback;
112 struct ascodec_request *next; 112 struct ascodec_request *next;
113}; 113};
@@ -121,7 +121,7 @@ static unsigned char *req_data_ptr = NULL;
121static struct ascodec_request *req_head = NULL; 121static struct ascodec_request *req_head = NULL;
122static struct ascodec_request *req_tail = NULL; 122static struct ascodec_request *req_tail = NULL;
123 123
124static struct wakeup adc_wkup; 124static struct semaphore adc_done_sem;
125static struct ascodec_request as_audio_req; 125static struct ascodec_request as_audio_req;
126 126
127#ifdef DEBUG 127#ifdef DEBUG
@@ -168,7 +168,7 @@ static void ascodec_finish_req(struct ascodec_request *req)
168 if (req->callback) { 168 if (req->callback) {
169 req->callback(req->data, req_data_ptr - req->data); 169 req->callback(req->data, req_data_ptr - req->data);
170 } 170 }
171 wakeup_signal(&req->wkup); 171 semaphore_release(&req->complete);
172 172
173 req_head = req->next; 173 req_head = req->next;
174 req->next = NULL; 174 req->next = NULL;
@@ -263,7 +263,7 @@ void ascodec_init(void)
263 int prescaler; 263 int prescaler;
264 264
265 mutex_init(&as_mtx); 265 mutex_init(&as_mtx);
266 wakeup_init(&adc_wkup); 266 semaphore_init(&adc_done_sem, 1, 0);
267 267
268 /* enable clock */ 268 /* enable clock */
269 bitset32(&CGU_PERI, CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE); 269 bitset32(&CGU_PERI, CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE);
@@ -312,7 +312,7 @@ void ascodec_init(void)
312static void ascodec_req_init(struct ascodec_request *req, int type, 312static void ascodec_req_init(struct ascodec_request *req, int type,
313 unsigned int index, unsigned int cnt) 313 unsigned int index, unsigned int cnt)
314{ 314{
315 wakeup_init(&req->wkup); 315 semaphore_init(&req->complete, 1, 0);
316 req->next = NULL; 316 req->next = NULL;
317 req->callback = NULL; 317 req->callback = NULL;
318 req->type = type; 318 req->type = type;
@@ -337,19 +337,10 @@ static void ascodec_submit(struct ascodec_request *req)
337 restore_irq(oldlevel); 337 restore_irq(oldlevel);
338} 338}
339 339
340static int irq_disabled(void)
341{
342 unsigned long cpsr;
343
344 asm volatile ("mrs %0, cpsr" : "=r"(cpsr));
345
346 return (cpsr & IRQ_STATUS) == IRQ_DISABLED;
347}
348
349static void ascodec_wait(struct ascodec_request *req) 340static void ascodec_wait(struct ascodec_request *req)
350{ 341{
351 if (!irq_disabled()) { 342 if (irq_enabled()) {
352 wakeup_wait(&req->wkup, TIMEOUT_BLOCK); 343 semaphore_wait(&req->complete, TIMEOUT_BLOCK);
353 return; 344 return;
354 } 345 }
355 346
@@ -477,7 +468,7 @@ static void ascodec_read_cb(unsigned const char *data, unsigned int len)
477 } 468 }
478 if (data[2] & IRQ_ADC) { /* adc finished */ 469 if (data[2] & IRQ_ADC) { /* adc finished */
479 IFDEBUG(int_adc++); 470 IFDEBUG(int_adc++);
480 wakeup_signal(&adc_wkup); 471 semaphore_release(&adc_done_sem);
481 } 472 }
482 VIC_INT_ENABLE = INTERRUPT_AUDIO; 473 VIC_INT_ENABLE = INTERRUPT_AUDIO;
483} 474}
@@ -492,7 +483,7 @@ void INT_AUDIO(void)
492 483
493void ascodec_wait_adc_finished(void) 484void ascodec_wait_adc_finished(void)
494{ 485{
495 wakeup_wait(&adc_wkup, TIMEOUT_BLOCK); 486 semaphore_wait(&adc_done_sem, TIMEOUT_BLOCK);
496} 487}
497 488
498#ifdef CONFIG_CHARGING 489#ifdef CONFIG_CHARGING
diff --git a/firmware/target/arm/as3525/ascodec-target.h b/firmware/target/arm/as3525/ascodec-target.h
index 7c47bd7e9c..85c3d1c103 100644
--- a/firmware/target/arm/as3525/ascodec-target.h
+++ b/firmware/target/arm/as3525/ascodec-target.h
@@ -28,7 +28,7 @@
28#ifndef SIMULATOR 28#ifndef SIMULATOR
29 29
30#include "as3514.h" 30#include "as3514.h"
31#include "kernel.h" /* for struct wakeup */ 31#include "kernel.h" /* for struct semaphore */
32#include "clock-target.h" /* for AS3525_I2C_PRESCALER */ 32#include "clock-target.h" /* for AS3525_I2C_PRESCALER */
33#include "system-arm.h" 33#include "system-arm.h"
34 34
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 5a6e0df39a..a2d20c36fa 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -136,7 +136,7 @@ static bool hs_card = false;
136#define EXT_SD_BITS (1<<2) 136#define EXT_SD_BITS (1<<2)
137#endif 137#endif
138 138
139static struct wakeup transfer_completion_signal; 139static struct semaphore transfer_completion_signal;
140static volatile unsigned int transfer_error[NUM_VOLUMES]; 140static volatile unsigned int transfer_error[NUM_VOLUMES];
141#define PL180_MAX_TRANSFER_ERRORS 10 141#define PL180_MAX_TRANSFER_ERRORS 10
142 142
@@ -191,7 +191,7 @@ void INT_NAND(void)
191 191
192 transfer_error[INTERNAL_AS3525] = status & MCI_DATA_ERROR; 192 transfer_error[INTERNAL_AS3525] = status & MCI_DATA_ERROR;
193 193
194 wakeup_signal(&transfer_completion_signal); 194 semaphore_release(&transfer_completion_signal);
195 MCI_CLEAR(INTERNAL_AS3525) = status; 195 MCI_CLEAR(INTERNAL_AS3525) = status;
196} 196}
197 197
@@ -202,7 +202,7 @@ void INT_MCI0(void)
202 202
203 transfer_error[SD_SLOT_AS3525] = status & MCI_DATA_ERROR; 203 transfer_error[SD_SLOT_AS3525] = status & MCI_DATA_ERROR;
204 204
205 wakeup_signal(&transfer_completion_signal); 205 semaphore_release(&transfer_completion_signal);
206 MCI_CLEAR(SD_SLOT_AS3525) = status; 206 MCI_CLEAR(SD_SLOT_AS3525) = status;
207} 207}
208#endif 208#endif
@@ -568,7 +568,7 @@ int sd_init(void)
568 bitset32(&CCU_IO, 1<<2); 568 bitset32(&CCU_IO, 1<<2);
569#endif 569#endif
570 570
571 wakeup_init(&transfer_completion_signal); 571 semaphore_init(&transfer_completion_signal, 1, 0);
572 572
573 init_pl180_controller(INTERNAL_AS3525); 573 init_pl180_controller(INTERNAL_AS3525);
574 ret = sd_init_card(INTERNAL_AS3525); 574 ret = sd_init_card(INTERNAL_AS3525);
@@ -678,7 +678,7 @@ static int sd_select_bank(signed char bank)
678 (9<<4) /* 2^9 = 512 */ ; 678 (9<<4) /* 2^9 = 512 */ ;
679 679
680 /* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */ 680 /* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */
681 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 681 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
682 682
683 /* Wait for FIFO to empty, card may still be in PRG state */ 683 /* Wait for FIFO to empty, card may still be in PRG state */
684 while(MCI_STATUS(INTERNAL_AS3525) & MCI_TX_ACTIVE ); 684 while(MCI_STATUS(INTERNAL_AS3525) & MCI_TX_ACTIVE );
@@ -837,7 +837,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
837 (9<<4) /* 2^9 = 512 */ ; 837 (9<<4) /* 2^9 = 512 */ ;
838 838
839 /* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */ 839 /* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */
840 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 840 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
841 841
842 /* Wait for FIFO to empty, card may still be in PRG state for writes */ 842 /* Wait for FIFO to empty, card may still be in PRG state for writes */
843 while(MCI_STATUS(drive) & MCI_TX_ACTIVE); 843 while(MCI_STATUS(drive) & MCI_TX_ACTIVE);
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 70d7c8fda1..b863337cbc 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -342,8 +342,8 @@ static struct event_queue sd_queue;
342bool sd_enabled = false; 342bool sd_enabled = false;
343#endif 343#endif
344 344
345static struct wakeup transfer_completion_signal; 345static struct semaphore transfer_completion_signal;
346static struct wakeup command_completion_signal; 346static struct semaphore command_completion_signal;
347static volatile bool retry; 347static volatile bool retry;
348static volatile int cmd_error; 348static volatile int cmd_error;
349 349
@@ -365,12 +365,12 @@ void INT_NAND(void)
365 retry = true; 365 retry = true;
366 366
367 if( status & (MCI_INT_DTO|MCI_DATA_ERROR)) 367 if( status & (MCI_INT_DTO|MCI_DATA_ERROR))
368 wakeup_signal(&transfer_completion_signal); 368 semaphore_release(&transfer_completion_signal);
369 369
370 cmd_error = status & MCI_CMD_ERROR; 370 cmd_error = status & MCI_CMD_ERROR;
371 371
372 if(status & MCI_INT_CD) 372 if(status & MCI_INT_CD)
373 wakeup_signal(&command_completion_signal); 373 semaphore_release(&command_completion_signal);
374 374
375 MCI_CTRL |= INT_ENABLE; 375 MCI_CTRL |= INT_ENABLE;
376} 376}
@@ -442,7 +442,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg, const int fl
442 _buttonlight_off(); 442 _buttonlight_off();
443 } 443 }
444#endif 444#endif
445 wakeup_wait(&command_completion_signal, TIMEOUT_BLOCK); 445 semaphore_wait(&command_completion_signal, TIMEOUT_BLOCK);
446 446
447 /* Handle command responses & errors */ 447 /* Handle command responses & errors */
448 if(flags & MCI_RESP) 448 if(flags & MCI_RESP)
@@ -769,8 +769,8 @@ int sd_init(void)
769 | (AS3525_SDSLOT_DIV << 2) 769 | (AS3525_SDSLOT_DIV << 2)
770 | 1; /* clock source = PLLA */ 770 | 1; /* clock source = PLLA */
771 771
772 wakeup_init(&transfer_completion_signal); 772 semaphore_init(&transfer_completion_signal, 1, 0);
773 wakeup_init(&command_completion_signal); 773 semaphore_init(&command_completion_signal, 1, 0);
774 774
775#if defined(SANSA_FUZEV2) || defined(SANSA_CLIPPLUS) 775#if defined(SANSA_FUZEV2) || defined(SANSA_CLIPPLUS)
776 if (amsv2_variant == 1) 776 if (amsv2_variant == 1)
@@ -932,7 +932,7 @@ sd_transfer_retry_with_reinit:
932 goto sd_transfer_error; 932 goto sd_transfer_error;
933 } 933 }
934 934
935 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 935 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
936 936
937 last_disk_activity = current_tick; 937 last_disk_activity = current_tick;
938 938
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.c b/firmware/target/arm/as3525/usb-drv-as3525.c
index 2e5330ec1b..69c50cda93 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525.c
@@ -40,6 +40,7 @@
40static struct usb_endpoint endpoints[USB_NUM_EPS][2]; 40static struct usb_endpoint endpoints[USB_NUM_EPS][2];
41static int got_set_configuration = 0; 41static int got_set_configuration = 0;
42static int usb_enum_timeout = -1; 42static int usb_enum_timeout = -1;
43static bool initialized = false;
43 44
44/* 45/*
45 * dma/setup descriptors and buffers should avoid sharing 46 * dma/setup descriptors and buffers should avoid sharing
@@ -180,19 +181,19 @@ static void reset_endpoints(int init)
180 if (endpoints[i][0].state & EP_STATE_BUSY) { 181 if (endpoints[i][0].state & EP_STATE_BUSY) {
181 if (endpoints[i][0].state & EP_STATE_ASYNC) { 182 if (endpoints[i][0].state & EP_STATE_ASYNC) {
182 endpoints[i][0].rc = -1; 183 endpoints[i][0].rc = -1;
183 wakeup_signal(&endpoints[i][0].complete); 184 semaphore_release(&endpoints[i][0].complete);
184 } else { 185 } else {
185 usb_core_transfer_complete(i, USB_DIR_IN, -1, 0); 186 usb_core_transfer_complete(i, USB_DIR_IN, -1, 0);
186 } 187 }
187 } 188 }
188 endpoints[i][0].state = 0; 189 endpoints[i][0].state = 0;
189 wakeup_init(&endpoints[i][0].complete); 190 semaphore_wait(&endpoints[i][0].complete, TIMEOUT_NOBLOCK);
190 191
191 if (i != 2) { /* Skip the OUT EP0 alias */ 192 if (i != 2) { /* Skip the OUT EP0 alias */
192 if (endpoints[i][1].state & EP_STATE_BUSY) 193 if (endpoints[i][1].state & EP_STATE_BUSY)
193 usb_core_transfer_complete(i, USB_DIR_OUT, -1, 0); 194 usb_core_transfer_complete(i, USB_DIR_OUT, -1, 0);
194 endpoints[i][1].state = 0; 195 endpoints[i][1].state = 0;
195 wakeup_init(&endpoints[i][1].complete); 196 semaphore_wait(&endpoints[i][1].complete, TIMEOUT_NOBLOCK);
196 USB_OEP_SUP_PTR(i) = 0; 197 USB_OEP_SUP_PTR(i) = 0;
197 } 198 }
198 } 199 }
@@ -225,6 +226,18 @@ void usb_drv_init(void)
225{ 226{
226 logf("usb_drv_init() !!!!\n"); 227 logf("usb_drv_init() !!!!\n");
227 228
229 if (!initialized)
230 {
231 int i;
232 for (i = 0; i < USB_NUM_EPS; i++)
233 {
234 semaphore_init(&endpoints[i][0].complete, 1, 0);
235 semaphore_init(&endpoints[i][1].complete, 1, 0);
236 }
237
238 initialized = true;
239 }
240
228 usb_enable_pll(); 241 usb_enable_pll();
229 242
230 /* we have external power, so boost cpu */ 243 /* we have external power, so boost cpu */
@@ -322,6 +335,7 @@ void usb_drv_exit(void)
322 ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) & ~(1<<4)); 335 ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) & ~(1<<4));
323 usb_disable_pll(); 336 usb_disable_pll();
324 cpu_boost(0); 337 cpu_boost(0);
338 initialized = false;
325 logf("usb_drv_exit() !!!!\n"); 339 logf("usb_drv_exit() !!!!\n");
326} 340}
327 341
@@ -529,7 +543,7 @@ int usb_drv_send(int ep, void *ptr, int len)
529 } 543 }
530 544
531 ep_send(ep, ptr, len); 545 ep_send(ep, ptr, len);
532 if (wakeup_wait(&endpoints[ep][0].complete, HZ) == OBJ_WAIT_TIMEDOUT) 546 if (semaphore_wait(&endpoints[ep][0].complete, HZ) == OBJ_WAIT_TIMEDOUT)
533 logf("send timed out!\n"); 547 logf("send timed out!\n");
534 548
535 return endpoints[ep][0].rc; 549 return endpoints[ep][0].rc;
@@ -570,7 +584,7 @@ static void handle_in_ep(int ep)
570 endpoints[ep][0].state &= ~EP_STATE_ASYNC; 584 endpoints[ep][0].state &= ~EP_STATE_ASYNC;
571 usb_core_transfer_complete(ep, USB_DIR_IN, 0, endpoints[ep][0].len); 585 usb_core_transfer_complete(ep, USB_DIR_IN, 0, endpoints[ep][0].len);
572 } else { 586 } else {
573 wakeup_signal(&endpoints[ep][0].complete); 587 semaphore_release(&endpoints[ep][0].complete);
574 } 588 }
575 ep_sts &= ~USB_EP_STAT_TDC; 589 ep_sts &= ~USB_EP_STAT_TDC;
576 } 590 }
diff --git a/firmware/target/arm/as3525/usb-drv-as3525.h b/firmware/target/arm/as3525/usb-drv-as3525.h
index 960b023039..0f8b3c0668 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525.h
+++ b/firmware/target/arm/as3525/usb-drv-as3525.h
@@ -310,7 +310,7 @@ struct usb_endpoint
310 unsigned int len; 310 unsigned int len;
311 volatile unsigned int state; 311 volatile unsigned int state;
312 int rc; 312 int rc;
313 struct wakeup complete; 313 struct semaphore complete;
314 struct usb_dev_dma_desc *uc_desc; 314 struct usb_dev_dma_desc *uc_desc;
315}; 315};
316 316
diff --git a/firmware/target/arm/as3525/usb-drv-as3525v2.c b/firmware/target/arm/as3525/usb-drv-as3525v2.c
index 78dc2a603f..24548f30c5 100644
--- a/firmware/target/arm/as3525/usb-drv-as3525v2.c
+++ b/firmware/target/arm/as3525/usb-drv-as3525v2.c
@@ -61,7 +61,7 @@ static const uint8_t out_ep_list[NUM_OUT_EP + 1] = {0, OUT_EP_LIST};
61struct usb_endpoint 61struct usb_endpoint
62{ 62{
63 unsigned int len; /* length of the data buffer */ 63 unsigned int len; /* length of the data buffer */
64 struct wakeup complete; /* wait object */ 64 struct semaphore complete; /* wait object */
65 int8_t status; /* completion status (0 for success) */ 65 int8_t status; /* completion status (0 for success) */
66 bool active; /* true is endpoint has been requested (true for EP0) */ 66 bool active; /* true is endpoint has been requested (true for EP0) */
67 bool wait; /* true if usb thread is blocked on completion */ 67 bool wait; /* true if usb thread is blocked on completion */
@@ -281,7 +281,7 @@ static void reset_endpoints(void)
281 if(endpoints[ep][DIR_IN].wait) 281 if(endpoints[ep][DIR_IN].wait)
282 { 282 {
283 endpoints[ep][DIR_IN].wait = false; 283 endpoints[ep][DIR_IN].wait = false;
284 wakeup_signal(&endpoints[ep][DIR_IN].complete); 284 semaphore_release(&endpoints[ep][DIR_IN].complete);
285 } 285 }
286 if(DIEPCTL(ep) & DEPCTL_epena) 286 if(DIEPCTL(ep) & DEPCTL_epena)
287 DIEPCTL(ep) = DEPCTL_snak; 287 DIEPCTL(ep) = DEPCTL_snak;
@@ -297,7 +297,7 @@ static void reset_endpoints(void)
297 if(endpoints[ep][DIR_OUT].wait) 297 if(endpoints[ep][DIR_OUT].wait)
298 { 298 {
299 endpoints[ep][DIR_OUT].wait = false; 299 endpoints[ep][DIR_OUT].wait = false;
300 wakeup_signal(&endpoints[ep][DIR_OUT].complete); 300 semaphore_release(&endpoints[ep][DIR_OUT].complete);
301 } 301 }
302 if(DOEPCTL(ep) & DEPCTL_epena) 302 if(DOEPCTL(ep) & DEPCTL_epena)
303 DOEPCTL(ep) = DEPCTL_snak; 303 DOEPCTL(ep) = DEPCTL_snak;
@@ -329,7 +329,7 @@ static void cancel_all_transfers(bool cancel_ep0)
329 if(endpoints[ep][DIR_IN].wait) 329 if(endpoints[ep][DIR_IN].wait)
330 { 330 {
331 endpoints[ep][DIR_IN].wait = false; 331 endpoints[ep][DIR_IN].wait = false;
332 wakeup_signal(&endpoints[ep][DIR_IN].complete); 332 semaphore_release(&endpoints[ep][DIR_IN].complete);
333 } 333 }
334 DIEPCTL(ep) = (DIEPCTL(ep) & ~DEPCTL_usbactep) | DEPCTL_snak; 334 DIEPCTL(ep) = (DIEPCTL(ep) & ~DEPCTL_usbactep) | DEPCTL_snak;
335 } 335 }
@@ -340,7 +340,7 @@ static void cancel_all_transfers(bool cancel_ep0)
340 if(endpoints[ep][DIR_OUT].wait) 340 if(endpoints[ep][DIR_OUT].wait)
341 { 341 {
342 endpoints[ep][DIR_OUT].wait = false; 342 endpoints[ep][DIR_OUT].wait = false;
343 wakeup_signal(&endpoints[ep][DIR_OUT].complete); 343 semaphore_release(&endpoints[ep][DIR_OUT].complete);
344 } 344 }
345 DOEPCTL(ep) = (DOEPCTL(ep) & ~DEPCTL_usbactep) | DEPCTL_snak; 345 DOEPCTL(ep) = (DOEPCTL(ep) & ~DEPCTL_usbactep) | DEPCTL_snak;
346 } 346 }
@@ -457,9 +457,9 @@ void usb_drv_init(void)
457 /* Core init */ 457 /* Core init */
458 core_init(); 458 core_init();
459 FOR_EACH_IN_EP_AND_EP0(i, ep) 459 FOR_EACH_IN_EP_AND_EP0(i, ep)
460 wakeup_init(&endpoints[ep][DIR_IN].complete); 460 semaphore_init(&endpoints[ep][DIR_IN].complete, 1, 0);
461 FOR_EACH_OUT_EP_AND_EP0(i, ep) 461 FOR_EACH_OUT_EP_AND_EP0(i, ep)
462 wakeup_init(&endpoints[ep][DIR_OUT].complete); 462 semaphore_init(&endpoints[ep][DIR_OUT].complete, 1, 0);
463 /* Enable global interrupts */ 463 /* Enable global interrupts */
464 enable_global_interrupts(); 464 enable_global_interrupts();
465} 465}
@@ -498,7 +498,7 @@ static void handle_ep_in_int(int ep)
498 if(endpoint->wait) 498 if(endpoint->wait)
499 { 499 {
500 endpoint->wait = false; 500 endpoint->wait = false;
501 wakeup_signal(&endpoint->complete); 501 semaphore_release(&endpoint->complete);
502 } 502 }
503 } 503 }
504 } 504 }
@@ -515,7 +515,7 @@ static void handle_ep_in_int(int ep)
515 if(endpoint->wait) 515 if(endpoint->wait)
516 { 516 {
517 endpoint->wait = false; 517 endpoint->wait = false;
518 wakeup_signal(&endpoint->complete); 518 semaphore_release(&endpoint->complete);
519 } 519 }
520 } 520 }
521 } 521 }
@@ -549,7 +549,7 @@ static void handle_ep_out_int(int ep)
549 if(endpoint->wait) 549 if(endpoint->wait)
550 { 550 {
551 endpoint->wait = false; 551 endpoint->wait = false;
552 wakeup_signal(&endpoint->complete); 552 semaphore_release(&endpoint->complete);
553 } 553 }
554 } 554 }
555 } 555 }
@@ -798,7 +798,7 @@ static int usb_drv_transfer(int ep, void *ptr, int len, bool dir_in, bool blocki
798 798
799 if(blocking) 799 if(blocking)
800 { 800 {
801 wakeup_wait(&endpoint->complete, TIMEOUT_BLOCK); 801 semaphore_wait(&endpoint->complete, TIMEOUT_BLOCK);
802 return endpoint->status; 802 return endpoint->status;
803 } 803 }
804 804
diff --git a/firmware/target/arm/imx31/ata-imx31.c b/firmware/target/arm/imx31/ata-imx31.c
index d539282e70..8a40c924ff 100644
--- a/firmware/target/arm/imx31/ata-imx31.c
+++ b/firmware/target/arm/imx31/ata-imx31.c
@@ -246,7 +246,7 @@ static const struct ata_udma_timings
246 246
247/** Threading **/ 247/** Threading **/
248/* Signal to tell thread when DMA is done */ 248/* Signal to tell thread when DMA is done */
249static struct wakeup ata_dma_wakeup; 249static struct semaphore ata_dma_complete;
250 250
251/** SDMA **/ 251/** SDMA **/
252/* Array of buffer descriptors for large transfers and alignnment */ 252/* Array of buffer descriptors for large transfers and alignnment */
@@ -445,7 +445,7 @@ static void ata_dma_callback(void)
445 ATA_INTERRUPT_CLEAR = ATA_INTERRUPT_PENDING; 445 ATA_INTERRUPT_CLEAR = ATA_INTERRUPT_PENDING;
446 446
447 ata_set_intrq(false); /* Return INTRQ to MCU */ 447 ata_set_intrq(false); /* Return INTRQ to MCU */
448 wakeup_signal(&ata_dma_wakeup); /* Signal waiting thread */ 448 semaphore_release(&ata_dma_complete); /* Signal waiting thread */
449} 449}
450 450
451bool ata_dma_setup(void *addr, unsigned long bytes, bool write) 451bool ata_dma_setup(void *addr, unsigned long bytes, bool write)
@@ -580,7 +580,8 @@ bool ata_dma_finish(void)
580 { 580 {
581 int oldirq; 581 int oldirq;
582 582
583 if (LIKELY(wakeup_wait(&ata_dma_wakeup, HZ/2) == OBJ_WAIT_SUCCEEDED)) 583 if (LIKELY(semaphore_wait(&ata_dma_complete, HZ/2)
584 == OBJ_WAIT_SUCCEEDED))
584 break; 585 break;
585 586
586 ata_keep_active(); 587 ata_keep_active();
@@ -594,7 +595,8 @@ bool ata_dma_finish(void)
594 sdma_channel_stop(channel); /* Stop DMA */ 595 sdma_channel_stop(channel); /* Stop DMA */
595 restore_irq(oldirq); 596 restore_irq(oldirq);
596 597
597 if (wakeup_wait(&ata_dma_wakeup, TIMEOUT_NOBLOCK) == OBJ_WAIT_SUCCEEDED) 598 if (semaphore_wait(&ata_dma_complete, TIMEOUT_NOBLOCK)
599 == OBJ_WAIT_SUCCEEDED)
598 break; /* DMA really did finish after timeout */ 600 break; /* DMA really did finish after timeout */
599 601
600 sdma_channel_reset(channel); /* Reset everything + clear error */ 602 sdma_channel_reset(channel); /* Reset everything + clear error */
@@ -716,7 +718,7 @@ void ata_device_init(void)
716 ata_dma_selected = ATA_DMA_PIO; 718 ata_dma_selected = ATA_DMA_PIO;
717 719
718 /* Called for first time at startup */ 720 /* Called for first time at startup */
719 wakeup_init(&ata_dma_wakeup); 721 semaphore_init(&ata_dma_complete, 1, 0);
720 722
721 if (!sdma_channel_init(ATA_DMA_CH_NUM_RD, &ata_cd_rd, ata_bda) || 723 if (!sdma_channel_init(ATA_DMA_CH_NUM_RD, &ata_cd_rd, ata_bda) ||
722 !sdma_channel_init(ATA_DMA_CH_NUM_WR, &ata_cd_wr, ata_bda)) 724 !sdma_channel_init(ATA_DMA_CH_NUM_WR, &ata_cd_wr, ata_bda))
diff --git a/firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c
index f7bc0ed37c..eb30919077 100644
--- a/firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/adc-gigabeat-s.c
@@ -35,7 +35,7 @@ static const unsigned char reg_array[4] =
35}; 35};
36 36
37static uint32_t channels[2][4]; 37static uint32_t channels[2][4];
38static struct wakeup adc_wake; 38static struct semaphore adc_done_signal;
39static struct mutex adc_mtx; 39static struct mutex adc_mtx;
40static long last_adc_read[2]; /* One for each input group */ 40static long last_adc_read[2]; /* One for each input group */
41 41
@@ -67,7 +67,7 @@ unsigned short adc_read(int channel)
67 mc13783_write(MC13783_ADC1, adc1); 67 mc13783_write(MC13783_ADC1, adc1);
68 68
69 /* Wait for done signal */ 69 /* Wait for done signal */
70 wakeup_wait(&adc_wake, TIMEOUT_BLOCK); 70 semaphore_wait(&adc_done_signal, TIMEOUT_BLOCK);
71 71
72 /* Read all 8 channels that are converted - two channels in each 72 /* Read all 8 channels that are converted - two channels in each
73 * word. */ 73 * word. */
@@ -113,12 +113,12 @@ bool adc_enable_channel(int channel, bool enable)
113/* Called by mc13783 interrupt thread when conversion is complete */ 113/* Called by mc13783 interrupt thread when conversion is complete */
114void adc_done(void) 114void adc_done(void)
115{ 115{
116 wakeup_signal(&adc_wake); 116 semaphore_release(&adc_done_signal);
117} 117}
118 118
119void adc_init(void) 119void adc_init(void)
120{ 120{
121 wakeup_init(&adc_wake); 121 semaphore_init(&adc_done_signal, 1, 0);
122 mutex_init(&adc_mtx); 122 mutex_init(&adc_mtx);
123 123
124 /* Init so first reads get data */ 124 /* Init so first reads get data */
diff --git a/firmware/target/arm/imx31/gigabeat-s/headphone-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/headphone-gigabeat-s.c
index 0f8cb67a9d..6e76615308 100644
--- a/firmware/target/arm/imx31/gigabeat-s/headphone-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/headphone-gigabeat-s.c
@@ -29,7 +29,7 @@
29#include "adc.h" 29#include "adc.h"
30#include "button.h" 30#include "button.h"
31 31
32static struct wakeup headphone_wakeup; 32static struct semaphore headphone_wakeup;
33static unsigned int headphone_thread_id; 33static unsigned int headphone_thread_id;
34static int headphone_stack[200/sizeof(int)]; /* Not much stack needed */ 34static int headphone_stack[200/sizeof(int)]; /* Not much stack needed */
35static const char * const headphone_thread_name = "headphone"; 35static const char * const headphone_thread_name = "headphone";
@@ -115,7 +115,7 @@ static void headphone_thread(void)
115 115
116 while (1) 116 while (1)
117 { 117 {
118 int rc = wakeup_wait(&headphone_wakeup, headphone_wait_timeout); 118 int rc = semaphore_wait(&headphone_wakeup, headphone_wait_timeout);
119 unsigned int data = adc_read(ADC_HPREMOTE); 119 unsigned int data = adc_read(ADC_HPREMOTE);
120 120
121 if (rc == OBJ_WAIT_TIMEDOUT) 121 if (rc == OBJ_WAIT_TIMEDOUT)
@@ -175,7 +175,7 @@ static void headphone_thread(void)
175void headphone_detect_event(void) 175void headphone_detect_event(void)
176{ 176{
177 /* Trigger the thread immediately. */ 177 /* Trigger the thread immediately. */
178 wakeup_signal(&headphone_wakeup); 178 semaphore_release(&headphone_wakeup);
179} 179}
180 180
181/* Tell if anything is in the jack. */ 181/* Tell if anything is in the jack. */
@@ -187,7 +187,7 @@ bool headphones_inserted(void)
187void INIT_ATTR headphone_init(void) 187void INIT_ATTR headphone_init(void)
188{ 188{
189 /* A thread is required to monitor the remote ADC and jack state. */ 189 /* A thread is required to monitor the remote ADC and jack state. */
190 wakeup_init(&headphone_wakeup); 190 semaphore_init(&headphone_wakeup, 1, 0);
191 headphone_thread_id = create_thread(headphone_thread, 191 headphone_thread_id = create_thread(headphone_thread,
192 headphone_stack, 192 headphone_stack,
193 sizeof(headphone_stack), 193 sizeof(headphone_stack),
diff --git a/firmware/target/arm/imx31/i2c-imx31.c b/firmware/target/arm/imx31/i2c-imx31.c
index 4e810c588f..975f951fdc 100644
--- a/firmware/target/arm/imx31/i2c-imx31.c
+++ b/firmware/target/arm/imx31/i2c-imx31.c
@@ -48,7 +48,7 @@ static struct i2c_module_descriptor
48 volatile unsigned short * const base; /* Module base address */ 48 volatile unsigned short * const base; /* Module base address */
49 void (* const handler)(void); /* Module interrupt handler */ 49 void (* const handler)(void); /* Module interrupt handler */
50 struct mutex m; /* Node mutual-exclusion */ 50 struct mutex m; /* Node mutual-exclusion */
51 struct wakeup w; /* I2C done signal */ 51 struct semaphore complete; /* I2C completion signal */
52 unsigned char *addr_data; /* Additional addressing data */ 52 unsigned char *addr_data; /* Additional addressing data */
53 int addr_count; /* Addressing byte count */ 53 int addr_count; /* Addressing byte count */
54 unsigned char *data; /* TX/RX buffer (actual data) */ 54 unsigned char *data; /* TX/RX buffer (actual data) */
@@ -164,7 +164,7 @@ i2c_stop:
164 base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN); 164 base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
165i2c_done: 165i2c_done:
166 /* Signal thread we're done */ 166 /* Signal thread we're done */
167 wakeup_signal(&desc->w); 167 semaphore_release(&desc->complete);
168} 168}
169 169
170#if (I2C_MODULE_MASK & USE_I2C1_MODULE) 170#if (I2C_MODULE_MASK & USE_I2C1_MODULE)
@@ -221,7 +221,7 @@ static int i2c_transfer(struct i2c_node * const node,
221 base[I2DR] = desc->addr; 221 base[I2DR] = desc->addr;
222 222
223 /* Wait for transfer to complete */ 223 /* Wait for transfer to complete */
224 if (wakeup_wait(&desc->w, HZ) == OBJ_WAIT_SUCCEEDED) 224 if (semaphore_wait(&desc->complete, HZ) == OBJ_WAIT_SUCCEEDED)
225 { 225 {
226 count -= desc->data_count; 226 count -= desc->data_count;
227 } 227 }
@@ -294,7 +294,7 @@ void i2c_init(void)
294 struct i2c_module_descriptor *const desc = &i2c_descs[i]; 294 struct i2c_module_descriptor *const desc = &i2c_descs[i];
295 ccm_module_clock_gating(desc->cg, CGM_ON_RUN_WAIT); 295 ccm_module_clock_gating(desc->cg, CGM_ON_RUN_WAIT);
296 mutex_init(&desc->m); 296 mutex_init(&desc->m);
297 wakeup_init(&desc->w); 297 semaphore_init(&desc->complete, 1, 0);
298 desc->base[I2CR] = 0; 298 desc->base[I2CR] = 0;
299 ccm_module_clock_gating(desc->cg, CGM_OFF); 299 ccm_module_clock_gating(desc->cg, CGM_OFF);
300 } 300 }
diff --git a/firmware/target/arm/imx31/mc13783-imx31.c b/firmware/target/arm/imx31/mc13783-imx31.c
index d5d22e2c75..006b065ea5 100644
--- a/firmware/target/arm/imx31/mc13783-imx31.c
+++ b/firmware/target/arm/imx31/mc13783-imx31.c
@@ -32,11 +32,11 @@ extern struct spi_node mc13783_spi;
32/* PMIC event service data */ 32/* PMIC event service data */
33static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]; 33static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)];
34static const char *mc13783_thread_name = "pmic"; 34static const char *mc13783_thread_name = "pmic";
35static struct wakeup mc13783_svc_wake; 35static struct semaphore mc13783_svc_wake;
36 36
37/* Synchronous thread communication objects */ 37/* Synchronous thread communication objects */
38static struct mutex mc13783_spi_mutex; 38static struct mutex mc13783_spi_mutex;
39static struct wakeup mc13783_spi_wake; 39static struct semaphore mc13783_spi_complete;
40 40
41/* Tracking for which interrupts are enabled */ 41/* Tracking for which interrupts are enabled */
42static uint32_t pmic_int_enabled[2] = 42static uint32_t pmic_int_enabled[2] =
@@ -69,13 +69,13 @@ static void mc13783_xfer_complete_cb(struct spi_transfer_desc *xfer)
69 if (xfer->count != 0) 69 if (xfer->count != 0)
70 return; 70 return;
71 71
72 wakeup_signal(&mc13783_spi_wake); 72 semaphore_release(&mc13783_spi_complete);
73} 73}
74 74
75static inline bool wait_for_transfer_complete(void) 75static inline bool wait_for_transfer_complete(void)
76{ 76{
77 return wakeup_wait(&mc13783_spi_wake, HZ*2) == OBJ_WAIT_SUCCEEDED && 77 return semaphore_wait(&mc13783_spi_complete, HZ*2)
78 mc13783_transfer.count == 0; 78 == OBJ_WAIT_SUCCEEDED && mc13783_transfer.count == 0;
79} 79}
80 80
81static void mc13783_interrupt_thread(void) 81static void mc13783_interrupt_thread(void)
@@ -89,7 +89,7 @@ static void mc13783_interrupt_thread(void)
89 { 89 {
90 const struct mc13783_event *event, *event_last; 90 const struct mc13783_event *event, *event_last;
91 91
92 wakeup_wait(&mc13783_svc_wake, TIMEOUT_BLOCK); 92 semaphore_wait(&mc13783_svc_wake, TIMEOUT_BLOCK);
93 93
94 if (mc13783_thread_id == 0) 94 if (mc13783_thread_id == 0)
95 break; 95 break;
@@ -140,16 +140,16 @@ void mc13783_event(void)
140 /* Mask the interrupt (unmasked when PMIC thread services it). */ 140 /* Mask the interrupt (unmasked when PMIC thread services it). */
141 bitclr32(&MC13783_GPIO_IMR, 1ul << MC13783_GPIO_LINE); 141 bitclr32(&MC13783_GPIO_IMR, 1ul << MC13783_GPIO_LINE);
142 MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE); 142 MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE);
143 wakeup_signal(&mc13783_svc_wake); 143 semaphore_release(&mc13783_svc_wake);
144} 144}
145 145
146void INIT_ATTR mc13783_init(void) 146void INIT_ATTR mc13783_init(void)
147{ 147{
148 /* Serial interface must have been initialized first! */ 148 /* Serial interface must have been initialized first! */
149 wakeup_init(&mc13783_svc_wake); 149 semaphore_init(&mc13783_svc_wake, 1, 0);
150 mutex_init(&mc13783_spi_mutex); 150 mutex_init(&mc13783_spi_mutex);
151 151
152 wakeup_init(&mc13783_spi_wake); 152 semaphore_init(&mc13783_spi_complete, 1, 0);
153 153
154 /* Enable the PMIC SPI module */ 154 /* Enable the PMIC SPI module */
155 spi_enable_module(&mc13783_spi); 155 spi_enable_module(&mc13783_spi);
@@ -175,7 +175,7 @@ void mc13783_close(void)
175 return; 175 return;
176 176
177 mc13783_thread_id = 0; 177 mc13783_thread_id = 0;
178 wakeup_signal(&mc13783_svc_wake); 178 semaphore_release(&mc13783_svc_wake);
179 thread_wait(thread_id); 179 thread_wait(thread_id);
180 spi_disable_module(&mc13783_spi); 180 spi_disable_module(&mc13783_spi);
181} 181}
diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c
index dd561b2e50..d5edd2bebc 100644
--- a/firmware/target/arm/ipod/button-clickwheel.c
+++ b/firmware/target/arm/ipod/button-clickwheel.c
@@ -84,7 +84,7 @@ int int_btn = BUTTON_NONE;
84#endif 84#endif
85 85
86#if CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702 86#if CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
87static struct wakeup button_init_wakeup; 87static struct semaphore button_init_wakeup;
88#endif 88#endif
89 89
90#if CONFIG_CPU==S5L8702 90#if CONFIG_CPU==S5L8702
@@ -273,7 +273,7 @@ static inline int ipod_4g_button_read(void)
273 btn |= BUTTON_PLAY; 273 btn |= BUTTON_PLAY;
274 if (status & 0x00100000) 274 if (status & 0x00100000)
275 btn |= BUTTON_MENU; 275 btn |= BUTTON_MENU;
276 wakeup_signal(&button_init_wakeup); 276 semaphore_release(&button_init_wakeup);
277 } 277 }
278#endif 278#endif
279 279
@@ -373,7 +373,7 @@ void s5l_clickwheel_init(void)
373 373
374void button_init_device(void) 374void button_init_device(void)
375{ 375{
376 wakeup_init(&button_init_wakeup); 376 semaphore_init(&button_init_wakeup, 1, 0);
377#if CONFIG_CPU==S5L8701 377#if CONFIG_CPU==S5L8701
378 INTMSK |= (1<<26); 378 INTMSK |= (1<<26);
379#elif CONFIG_CPU==S5L8702 379#elif CONFIG_CPU==S5L8702
@@ -381,7 +381,7 @@ void button_init_device(void)
381 holdswitch_last_value = (pmu_read(0x87) & 2) == 0; 381 holdswitch_last_value = (pmu_read(0x87) & 2) == 0;
382#endif 382#endif
383 s5l_clickwheel_init(); 383 s5l_clickwheel_init();
384 wakeup_wait(&button_init_wakeup, HZ / 10); 384 semaphore_wait(&button_init_wakeup, HZ / 10);
385} 385}
386 386
387bool button_hold(void) 387bool button_hold(void)
diff --git a/firmware/target/arm/ipod/video/lcd-video.c b/firmware/target/arm/ipod/video/lcd-video.c
index 944f2c4236..c499e9f745 100644
--- a/firmware/target/arm/ipod/video/lcd-video.c
+++ b/firmware/target/arm/ipod/video/lcd-video.c
@@ -107,7 +107,7 @@ struct
107#ifdef HAVE_LCD_SLEEP 107#ifdef HAVE_LCD_SLEEP
108 bool display_on; 108 bool display_on;
109 bool waking; 109 bool waking;
110 struct wakeup initwakeup; 110 struct semaphore initwakeup;
111#endif 111#endif
112} lcd_state IBSS_ATTR; 112} lcd_state IBSS_ATTR;
113 113
@@ -188,7 +188,7 @@ static inline unsigned bcm_read32(unsigned address)
188static void continue_lcd_awake(void) 188static void continue_lcd_awake(void)
189{ 189{
190 lcd_state.waking = false; 190 lcd_state.waking = false;
191 wakeup_signal(&(lcd_state.initwakeup)); 191 semaphore_release(&(lcd_state.initwakeup));
192} 192}
193#endif 193#endif
194 194
@@ -357,7 +357,7 @@ void lcd_init_device(void)
357 /* lcd_write_data needs an even number of 16 bit values */ 357 /* lcd_write_data needs an even number of 16 bit values */
358 flash_vmcs_length = ((flash_vmcs_length + 3) >> 1) & ~1; 358 flash_vmcs_length = ((flash_vmcs_length + 3) >> 1) & ~1;
359 } 359 }
360 wakeup_init(&(lcd_state.initwakeup)); 360 semaphore_init(&(lcd_state.initwakeup), 1, 0);
361 lcd_state.waking = false; 361 lcd_state.waking = false;
362 362
363 if (GPO32_VAL & 0x4000) 363 if (GPO32_VAL & 0x4000)
@@ -620,7 +620,7 @@ void lcd_awake(void)
620 */ 620 */
621 lcd_state.waking = true; 621 lcd_state.waking = true;
622 tick_add_task(&lcd_tick); 622 tick_add_task(&lcd_tick);
623 wakeup_wait(&(lcd_state.initwakeup), TIMEOUT_BLOCK); 623 semaphore_wait(&(lcd_state.initwakeup), TIMEOUT_BLOCK);
624 624
625 send_event(LCD_EVENT_ACTIVATION, NULL); 625 send_event(LCD_EVENT_ACTIVATION, NULL);
626 } 626 }
diff --git a/firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c b/firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c
index 036b6ae71c..d1e1c82c95 100644
--- a/firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c
+++ b/firmware/target/arm/olympus/mrobe-100/lcd-remote-mr100.c
@@ -67,7 +67,7 @@ unsigned char rc_buf[5];
67/* Remote thread functions */ 67/* Remote thread functions */
68/* These functions are private to the remote thread */ 68/* These functions are private to the remote thread */
69/* ================================================== */ 69/* ================================================== */
70static struct wakeup rc_thread_wakeup; 70static struct semaphore rc_thread_wakeup;
71static unsigned int remote_thread_id; 71static unsigned int remote_thread_id;
72static int remote_stack[256/sizeof(int)]; 72static int remote_stack[256/sizeof(int)];
73static const char * const remote_thread_name = "remote"; 73static const char * const remote_thread_name = "remote";
@@ -368,7 +368,7 @@ static void remote_thread(void)
368 368
369 while (1) 369 while (1)
370 { 370 {
371 wakeup_wait(&rc_thread_wakeup, rc_thread_wait_timeout); 371 semaphore_wait(&rc_thread_wakeup, rc_thread_wait_timeout);
372 372
373 /* Error handling (most likely due to remote not present) */ 373 /* Error handling (most likely due to remote not present) */
374 if (rc_status & RC_ERROR_MASK) 374 if (rc_status & RC_ERROR_MASK)
@@ -500,7 +500,7 @@ void lcd_remote_off(void)
500{ 500{
501 /* should only be used to power off at shutdown */ 501 /* should only be used to power off at shutdown */
502 rc_status |= RC_POWER_OFF; 502 rc_status |= RC_POWER_OFF;
503 wakeup_signal(&rc_thread_wakeup); 503 semaphore_release(&rc_thread_wakeup);
504 504
505 /* wait until the things are powered off */ 505 /* wait until the things are powered off */
506 while (rc_status & RC_DEV_INIT) 506 while (rc_status & RC_DEV_INIT)
@@ -515,7 +515,7 @@ void lcd_remote_on(void)
515 { 515 {
516 rc_status &= ~RC_FORCE_DETECT; 516 rc_status &= ~RC_FORCE_DETECT;
517 rc_status &= ~RC_POWER_OFF; 517 rc_status &= ~RC_POWER_OFF;
518 wakeup_signal(&rc_thread_wakeup); 518 semaphore_release(&rc_thread_wakeup);
519 } 519 }
520} 520}
521 521
@@ -536,7 +536,7 @@ void lcd_remote_init_device(void)
536 GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80); 536 GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80);
537 537
538 /* a thread is required to poll & update the remote */ 538 /* a thread is required to poll & update the remote */
539 wakeup_init(&rc_thread_wakeup); 539 semaphore_init(&rc_thread_wakeup, 1, 0);
540 remote_thread_id = create_thread(remote_thread, remote_stack, 540 remote_thread_id = create_thread(remote_thread, remote_stack,
541 sizeof(remote_stack), 0, remote_thread_name 541 sizeof(remote_stack), 0, remote_thread_name
542 IF_PRIO(, PRIORITY_SYSTEM) 542 IF_PRIO(, PRIORITY_SYSTEM)
diff --git a/firmware/target/arm/s3c2440/i2c-s3c2440.c b/firmware/target/arm/s3c2440/i2c-s3c2440.c
index 155eb2f956..33c4e3180a 100644
--- a/firmware/target/arm/s3c2440/i2c-s3c2440.c
+++ b/firmware/target/arm/s3c2440/i2c-s3c2440.c
@@ -21,7 +21,7 @@
21#include "system.h" 21#include "system.h"
22#include "i2c-s3c2440.h" 22#include "i2c-s3c2440.h"
23 23
24static struct wakeup i2c_wake; /* Transfer completion signal */ 24static struct semaphore i2c_complete; /* Transfer completion signal */
25static struct mutex i2c_mtx; /* Mutual exclusion */ 25static struct mutex i2c_mtx; /* Mutual exclusion */
26static unsigned char *buf_ptr; /* Next byte to transfer */ 26static unsigned char *buf_ptr; /* Next byte to transfer */
27static int buf_count; /* Number of bytes remaining to transfer */ 27static int buf_count; /* Number of bytes remaining to transfer */
@@ -64,7 +64,7 @@ void i2c_write(int addr, const unsigned char *buf, int count)
64 /* Generate START */ 64 /* Generate START */
65 IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_START | I2C_RXTX_ENB; 65 IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_START | I2C_RXTX_ENB;
66 66
67 if (wakeup_wait(&i2c_wake, HZ) != OBJ_WAIT_SUCCEEDED) 67 if (semaphore_wait(&i2c_complete, HZ) != OBJ_WAIT_SUCCEEDED)
68 { 68 {
69 /* Something went wrong - stop transmission */ 69 /* Something went wrong - stop transmission */
70 int oldlevel = disable_irq_save(); 70 int oldlevel = disable_irq_save();
@@ -84,7 +84,7 @@ void i2c_write(int addr, const unsigned char *buf, int count)
84void i2c_init(void) 84void i2c_init(void)
85{ 85{
86 /* Init kernel objects */ 86 /* Init kernel objects */
87 wakeup_init(&i2c_wake); 87 semaphore_init(&i2c_complete, 1, 0);
88 mutex_init(&i2c_mtx); 88 mutex_init(&i2c_mtx);
89 89
90 /* Clear pending source */ 90 /* Clear pending source */
@@ -134,7 +134,7 @@ void IIC(void)
134 i2c_stop(); 134 i2c_stop();
135 135
136 /* Signal thread */ 136 /* Signal thread */
137 wakeup_signal(&i2c_wake); 137 semaphore_release(&i2c_complete);
138 break; 138 break;
139 } 139 }
140 140
diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c
index 4a15835b67..0dcd900d11 100644
--- a/firmware/target/arm/s3c2440/sd-s3c2440.c
+++ b/firmware/target/arm/s3c2440/sd-s3c2440.c
@@ -119,7 +119,7 @@ static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
119static const char sd_thread_name[] = "sd"; 119static const char sd_thread_name[] = "sd";
120static struct mutex sd_mtx SHAREDBSS_ATTR; 120static struct mutex sd_mtx SHAREDBSS_ATTR;
121static struct event_queue sd_queue; 121static struct event_queue sd_queue;
122static struct wakeup transfer_completion_signal; 122static struct semaphore transfer_completion_signal;
123static volatile unsigned int transfer_error[NUM_VOLUMES]; 123static volatile unsigned int transfer_error[NUM_VOLUMES];
124/* align on cache line size */ 124/* align on cache line size */
125static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 125static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
@@ -223,7 +223,7 @@ void SDI (void)
223 223
224 dbgprintf ("SDI %x\n", transfer_error[curr_card]); 224 dbgprintf ("SDI %x\n", transfer_error[curr_card]);
225 225
226 wakeup_signal(&transfer_completion_signal); 226 semaphore_release(&transfer_completion_signal);
227 227
228 /* Ack the interrupt */ 228 /* Ack the interrupt */
229 SRCPND = SDI_MASK; 229 SRCPND = SDI_MASK;
@@ -242,7 +242,7 @@ void dma_callback (void)
242 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ 242 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
243 243
244 dbgprintf ("dma_cb\n"); 244 dbgprintf ("dma_cb\n");
245 wakeup_signal(&transfer_completion_signal); 245 semaphore_release(&transfer_completion_signal);
246} 246}
247#endif 247#endif
248 248
@@ -783,7 +783,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
783 (9<<4) /* 2^9 = 512 */ ; 783 (9<<4) /* 2^9 = 512 */ ;
784#endif 784#endif
785 785
786 wakeup_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/); 786 semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/);
787 787
788 /* wait for DMA to finish */ 788 /* wait for DMA to finish */
789 while (DSTAT0 & DSTAT_STAT_BUSY) 789 while (DSTAT0 & DSTAT_STAT_BUSY)
@@ -928,7 +928,7 @@ int sd_init(void)
928 sd_enabled = true; 928 sd_enabled = true;
929 sd_enable(false); 929 sd_enable(false);
930#endif 930#endif
931 wakeup_init(&transfer_completion_signal); 931 semaphore_init(&transfer_completion_signal, 1, 0);
932 /* init mutex */ 932 /* init mutex */
933 mutex_init(&sd_mtx); 933 mutex_init(&sd_mtx);
934 queue_init(&sd_queue, true); 934 queue_init(&sd_queue, true);
diff --git a/firmware/target/arm/s5l8700/adc-s5l8700.c b/firmware/target/arm/s5l8700/adc-s5l8700.c
index f979a9d54f..270c133e94 100644
--- a/firmware/target/arm/s5l8700/adc-s5l8700.c
+++ b/firmware/target/arm/s5l8700/adc-s5l8700.c
@@ -42,11 +42,11 @@
42 42
43 43
44static struct mutex adc_mtx; 44static struct mutex adc_mtx;
45static struct wakeup adc_wakeup; 45static struct semaphore adc_wakeup;
46 46
47void INT_ADC(void) 47void INT_ADC(void)
48{ 48{
49 wakeup_signal(&adc_wakeup); 49 semaphore_release(&adc_wakeup);
50} 50}
51 51
52unsigned short adc_read(int channel) 52unsigned short adc_read(int channel)
@@ -61,7 +61,7 @@ unsigned short adc_read(int channel)
61 (1 << 0); /* enable start */ 61 (1 << 0); /* enable start */
62 62
63 /* wait for conversion */ 63 /* wait for conversion */
64 wakeup_wait(&adc_wakeup, TIMEOUT_BLOCK); 64 semaphore_wait(&adc_wakeup, TIMEOUT_BLOCK);
65 65
66 /* get the converted data */ 66 /* get the converted data */
67 data = ADCDAT0 & 0x3FF; 67 data = ADCDAT0 & 0x3FF;
@@ -77,7 +77,7 @@ unsigned short adc_read(int channel)
77void adc_init(void) 77void adc_init(void)
78{ 78{
79 mutex_init(&adc_mtx); 79 mutex_init(&adc_mtx);
80 wakeup_init(&adc_wakeup); 80 semaphore_init(&adc_wakeup, 1, 0);
81 81
82 /* enable clock to ADC */ 82 /* enable clock to ADC */
83 PWRCON &= ~(1 << 10); 83 PWRCON &= ~(1 << 10);
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
index 8a4541a226..9261e5b3a0 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
@@ -94,9 +94,9 @@ static long nand_last_activity_value = -1;
94static long nand_stack[DEFAULT_STACK_SIZE]; 94static long nand_stack[DEFAULT_STACK_SIZE];
95 95
96static struct mutex nand_mtx; 96static struct mutex nand_mtx;
97static struct wakeup nand_wakeup; 97static struct semaphore nand_complete;
98static struct mutex ecc_mtx; 98static struct mutex ecc_mtx;
99static struct wakeup ecc_wakeup; 99static struct semaphore ecc_complete;
100 100
101static uint8_t nand_data[0x800] STORAGE_ALIGN_ATTR; 101static uint8_t nand_data[0x800] STORAGE_ALIGN_ATTR;
102static uint8_t nand_ctrl[0x200] STORAGE_ALIGN_ATTR; 102static uint8_t nand_ctrl[0x200] STORAGE_ALIGN_ATTR;
@@ -731,9 +731,9 @@ static void nand_thread(void)
731int nand_device_init(void) 731int nand_device_init(void)
732{ 732{
733 mutex_init(&nand_mtx); 733 mutex_init(&nand_mtx);
734 wakeup_init(&nand_wakeup); 734 semaphore_init(&nand_complete, 1, 0);
735 mutex_init(&ecc_mtx); 735 mutex_init(&ecc_mtx);
736 wakeup_init(&ecc_wakeup); 736 semaphore_init(&ecc_complete, 1, 0);
737 737
738 uint32_t type; 738 uint32_t type;
739 uint32_t i, j; 739 uint32_t i, j;
diff --git a/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
index de731a91b8..0ad9da22bb 100644
--- a/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/lcd-ipod6g.c
@@ -50,7 +50,7 @@
50 50
51int lcd_type; /* also needed in debug-s5l8702.c */ 51int lcd_type; /* also needed in debug-s5l8702.c */
52static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff] CACHEALIGN_ATTR; 52static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff] CACHEALIGN_ATTR;
53static struct wakeup lcd_wakeup; 53static struct semaphore lcd_wakeup;
54static struct mutex lcd_mutex; 54static struct mutex lcd_mutex;
55static uint16_t lcd_dblbuf[LCD_HEIGHT][LCD_WIDTH]; 55static uint16_t lcd_dblbuf[LCD_HEIGHT][LCD_WIDTH];
56 56
@@ -149,7 +149,7 @@ void lcd_sleep(void)
149void lcd_init_device(void) 149void lcd_init_device(void)
150{ 150{
151 /* Detect lcd type */ 151 /* Detect lcd type */
152 wakeup_init(&lcd_wakeup); 152 semaphore_init(&lcd_wakeup, 1, 0);
153 mutex_init(&lcd_mutex); 153 mutex_init(&lcd_mutex);
154 lcd_type = (PDAT6 & 0x30) >> 4; 154 lcd_type = (PDAT6 & 0x30) >> 4;
155} 155}
@@ -180,7 +180,7 @@ static void displaylcd_setup(int x, int y, int width, int height) ICODE_ATTR;
180static void displaylcd_setup(int x, int y, int width, int height) 180static void displaylcd_setup(int x, int y, int width, int height)
181{ 181{
182 mutex_lock(&lcd_mutex); 182 mutex_lock(&lcd_mutex);
183 while (DMAC0C4CONFIG & 1) wakeup_wait(&lcd_wakeup, HZ / 10); 183 while (DMAC0C4CONFIG & 1) semaphore_wait(&lcd_wakeup, HZ / 10);
184 184
185 int xe = (x + width) - 1; /* max horiz */ 185 int xe = (x + width) - 1; /* max horiz */
186 int ye = (y + height) - 1; /* max vert */ 186 int ye = (y + height) - 1; /* max vert */
@@ -237,7 +237,7 @@ void INT_DMAC0C4(void) ICODE_ATTR;
237void INT_DMAC0C4(void) 237void INT_DMAC0C4(void)
238{ 238{
239 DMAC0INTTCCLR = 0x10; 239 DMAC0INTTCCLR = 0x10;
240 wakeup_signal(&lcd_wakeup); 240 semaphore_release(&lcd_wakeup);
241} 241}
242 242
243/* Update a fraction of the display. */ 243/* Update a fraction of the display. */
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
index 66e02d65bb..79a8964c3c 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
@@ -53,7 +53,7 @@ bool ata_lba48;
53bool ata_dma; 53bool ata_dma;
54uint64_t ata_total_sectors; 54uint64_t ata_total_sectors;
55struct mutex ata_mutex; 55struct mutex ata_mutex;
56static struct wakeup ata_wakeup; 56static struct semaphore ata_wakeup;
57static uint32_t ata_dma_flags; 57static uint32_t ata_dma_flags;
58static long ata_last_activity_value = -1; 58static long ata_last_activity_value = -1;
59static long ata_sleep_timeout = 20 * HZ; 59static long ata_sleep_timeout = 20 * HZ;
@@ -61,8 +61,8 @@ static uint32_t ata_stack[(DEFAULT_STACK_SIZE + 0x400) / 4];
61static bool ata_powered; 61static bool ata_powered;
62static const int ata_retries = ATA_RETRIES; 62static const int ata_retries = ATA_RETRIES;
63static const bool ata_error_srst = true; 63static const bool ata_error_srst = true;
64static struct wakeup mmc_wakeup; 64static struct semaphore mmc_wakeup;
65static struct wakeup mmc_comp_wakeup; 65static struct semaphore mmc_comp_wakeup;
66static int spinup_time = 0; 66static int spinup_time = 0;
67static int dma_mode = 0; 67static int dma_mode = 0;
68 68
@@ -319,7 +319,7 @@ void mmc_discard_irq(void)
319{ 319{
320 SDCI_IRQ = SDCI_IRQ_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT 320 SDCI_IRQ = SDCI_IRQ_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT
321 | SDCI_IRQ_MASK_MASK_READ_WAIT_INT; 321 | SDCI_IRQ_MASK_MASK_READ_WAIT_INT;
322 wakeup_wait(&mmc_wakeup, 0); 322 semaphore_wait(&mmc_wakeup, 0);
323} 323}
324 324
325int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size) 325int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size)
@@ -338,7 +338,8 @@ int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size)
338 | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc) 338 | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
339 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), 339 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
340 NULL, CEATA_COMMAND_TIMEOUT), 2, 1); 340 NULL, CEATA_COMMAND_TIMEOUT), 2, 1);
341 if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) RET_ERR(2); 341 if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000)
342 == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
342 PASS_RC(mmc_dsta_check_data_success(), 2, 3); 343 PASS_RC(mmc_dsta_check_data_success(), 2, 3);
343 return 0; 344 return 0;
344} 345}
@@ -362,7 +363,8 @@ int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size)
362 SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; 363 SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
363 for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i]; 364 for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i];
364 long startusec = USEC_TIMER; 365 long startusec = USEC_TIMER;
365 if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) RET_ERR(2); 366 if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000)
367 == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
366 while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE) 368 while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE)
367 { 369 {
368 if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3); 370 if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3);
@@ -479,13 +481,13 @@ int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long timeout)
479 direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), 481 direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count),
480 NULL, CEATA_COMMAND_TIMEOUT), 4, 0); 482 NULL, CEATA_COMMAND_TIMEOUT), 4, 0);
481 if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; 483 if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
482 if (wakeup_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT) 484 if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
483 { 485 {
484 PASS_RC(ceata_cancel_command(), 4, 1); 486 PASS_RC(ceata_cancel_command(), 4, 1);
485 RET_ERR(2); 487 RET_ERR(2);
486 } 488 }
487 PASS_RC(mmc_dsta_check_data_success(), 4, 3); 489 PASS_RC(mmc_dsta_check_data_success(), 4, 3);
488 if (wakeup_wait(&mmc_comp_wakeup, timeout) == OBJ_WAIT_TIMEDOUT) 490 if (semaphore_wait(&mmc_comp_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
489 { 491 {
490 PASS_RC(ceata_cancel_command(), 4, 4); 492 PASS_RC(ceata_cancel_command(), 4, 4);
491 RET_ERR(4); 493 RET_ERR(4);
@@ -750,11 +752,12 @@ int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bool writ
750 ATA_XFR_NUM = SECTOR_SIZE * cnt - 1; 752 ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
751 ATA_CFG |= ata_dma_flags; 753 ATA_CFG |= ata_dma_flags;
752 ATA_CFG &= ~(BIT(7) | BIT(8)); 754 ATA_CFG &= ~(BIT(7) | BIT(8));
753 wakeup_wait(&ata_wakeup, 0); 755 semaphore_wait(&ata_wakeup, 0);
754 ATA_IRQ = BITRANGE(0, 4); 756 ATA_IRQ = BITRANGE(0, 4);
755 ATA_IRQ_MASK = BIT(0); 757 ATA_IRQ_MASK = BIT(0);
756 ATA_COMMAND = BIT(0); 758 ATA_COMMAND = BIT(0);
757 if (wakeup_wait(&ata_wakeup, 500000 * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) 759 if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000)
760 == OBJ_WAIT_TIMEDOUT)
758 { 761 {
759 ATA_COMMAND = BIT(1); 762 ATA_COMMAND = BIT(1);
760 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); 763 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
@@ -1068,9 +1071,9 @@ void ata_bbt_reload(void)
1068int ata_init(void) 1071int ata_init(void)
1069{ 1072{
1070 mutex_init(&ata_mutex); 1073 mutex_init(&ata_mutex);
1071 wakeup_init(&ata_wakeup); 1074 semaphore_init(&ata_wakeup, 1, 0);
1072 wakeup_init(&mmc_wakeup); 1075 semaphore_init(&mmc_wakeup, 1, 0);
1073 wakeup_init(&mmc_comp_wakeup); 1076 semaphore_init(&mmc_comp_wakeup, 1, 0);
1074 ceata = PDAT(11) & BIT(1); 1077 ceata = PDAT(11) & BIT(1);
1075 if (ceata) 1078 if (ceata)
1076 { 1079 {
@@ -1129,14 +1132,14 @@ void INT_ATA(void)
1129{ 1132{
1130 uint32_t ata_irq = ATA_IRQ; 1133 uint32_t ata_irq = ATA_IRQ;
1131 ATA_IRQ = ata_irq; 1134 ATA_IRQ = ata_irq;
1132 if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup); 1135 if (ata_irq & ATA_IRQ_MASK) semaphore_release(&ata_wakeup);
1133 ATA_IRQ_MASK = 0; 1136 ATA_IRQ_MASK = 0;
1134} 1137}
1135 1138
1136void INT_MMC(void) 1139void INT_MMC(void)
1137{ 1140{
1138 uint32_t irq = SDCI_IRQ; 1141 uint32_t irq = SDCI_IRQ;
1139 if (irq & SDCI_IRQ_DAT_DONE_INT) wakeup_signal(&mmc_wakeup); 1142 if (irq & SDCI_IRQ_DAT_DONE_INT) semaphore_release(&mmc_wakeup);
1140 if (irq & SDCI_IRQ_IOCARD_IRQ_INT) wakeup_signal(&mmc_comp_wakeup); 1143 if (irq & SDCI_IRQ_IOCARD_IRQ_INT) semaphore_release(&mmc_comp_wakeup);
1141 SDCI_IRQ = irq; 1144 SDCI_IRQ = irq;
1142} 1145}
diff --git a/firmware/target/arm/system-arm.h b/firmware/target/arm/system-arm.h
index 7f10a30bdb..b3630a8473 100644
--- a/firmware/target/arm/system-arm.h
+++ b/firmware/target/arm/system-arm.h
@@ -62,6 +62,21 @@ void __div0(void);
62#define enable_fiq() \ 62#define enable_fiq() \
63 enable_interrupt(FIQ_STATUS) 63 enable_interrupt(FIQ_STATUS)
64 64
65#define irq_enabled() \
66 interrupt_enabled(IRQ_STATUS)
67#define fiq_enabled() \
68 interrupt_enabled(FIQ_STATUS)
69#define ints_enabled() \
70 interrupt_enabled(IRQ_FIQ_STATUS)
71
72#define irq_enabled_checkval(val) \
73 (((val) & IRQ_STATUS) == 0)
74#define fiq_enabled_checkval(val) \
75 (((val) & FIQ_STATUS) == 0)
76#define ints_enabled_checkval(val) \
77 (((val) & IRQ_FIQ_STATUS) == 0)
78
79
65/* Core-level interrupt masking */ 80/* Core-level interrupt masking */
66 81
67static inline int set_interrupt_status(int status, int mask) 82static inline int set_interrupt_status(int status, int mask)
@@ -87,6 +102,13 @@ static inline void restore_interrupt(int cpsr)
87 asm volatile ("msr cpsr_c, %0" : : "r"(cpsr)); 102 asm volatile ("msr cpsr_c, %0" : : "r"(cpsr));
88} 103}
89 104
105static inline bool interrupt_enabled(int status)
106{
107 unsigned long cpsr;
108 asm ("mrs %0, cpsr" : "=r"(cpsr));
109 return (cpsr & status) == 0;
110}
111
90/* ARM_ARCH version section for architecture*/ 112/* ARM_ARCH version section for architecture*/
91 113
92#if ARM_ARCH >= 6 114#if ARM_ARCH >= 6
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c
index d1408fee70..6a74ff5e57 100644
--- a/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c
+++ b/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c
@@ -37,14 +37,14 @@
37#define CF_START 0x40000000 37#define CF_START 0x40000000
38#define SSFDC_START 0x48000000 38#define SSFDC_START 0x48000000
39 39
40static struct wakeup transfer_completion_signal; 40static struct semaphore transfer_completion_signal;
41 41
42static bool dma_in_progress = false; 42static bool dma_in_progress = false;
43 43
44void MTC0(void) 44void MTC0(void)
45{ 45{
46 IO_INTC_IRQ1 = INTR_IRQ1_MTC0; 46 IO_INTC_IRQ1 = INTR_IRQ1_MTC0;
47 wakeup_signal(&transfer_completion_signal); 47 semaphore_release(&transfer_completion_signal);
48 dma_in_progress = false; 48 dma_in_progress = false;
49} 49}
50 50
@@ -59,7 +59,7 @@ void dma_start(const void* addr, size_t size)
59void dma_ata_read(unsigned char* buf, int shortcount) 59void dma_ata_read(unsigned char* buf, int shortcount)
60{ 60{
61 if(dma_in_progress) 61 if(dma_in_progress)
62 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 62 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
63 63
64 while((unsigned long)buf & 0x1F) 64 while((unsigned long)buf & 0x1F)
65 { 65 {
@@ -83,7 +83,7 @@ void dma_ata_read(unsigned char* buf, int shortcount)
83 IO_EMIF_DMACTL = 3; /* Select MTC->AHB and start transfer */ 83 IO_EMIF_DMACTL = 3; /* Select MTC->AHB and start transfer */
84 84
85 dma_in_progress = true; 85 dma_in_progress = true;
86 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 86 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
87 87
88 if(shortcount % 2) 88 if(shortcount % 2)
89 { 89 {
@@ -97,7 +97,7 @@ void dma_ata_read(unsigned char* buf, int shortcount)
97void dma_ata_write(unsigned char* buf, int wordcount) 97void dma_ata_write(unsigned char* buf, int wordcount)
98{ 98{
99 if(dma_in_progress) 99 if(dma_in_progress)
100 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 100 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
101 101
102 while((unsigned long)buf & 0x1F) 102 while((unsigned long)buf & 0x1F)
103 { 103 {
@@ -121,12 +121,12 @@ void dma_ata_write(unsigned char* buf, int wordcount)
121 IO_EMIF_DMACTL = 1; /* Select AHB->MTC and start transfer */ 121 IO_EMIF_DMACTL = 1; /* Select AHB->MTC and start transfer */
122 122
123 dma_in_progress = true; 123 dma_in_progress = true;
124 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); 124 semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
125} 125}
126 126
127void dma_init(void) 127void dma_init(void)
128{ 128{
129 IO_INTC_EINT1 |= INTR_EINT1_MTC0; /* enable MTC interrupt */ 129 IO_INTC_EINT1 |= INTR_EINT1_MTC0; /* enable MTC interrupt */
130 wakeup_init(&transfer_completion_signal); 130 semaphore_init(&transfer_completion_signal, 1, 0);
131 dma_in_progress = false; 131 dma_in_progress = false;
132} 132}
diff --git a/firmware/target/arm/usb-drv-arc.c b/firmware/target/arm/usb-drv-arc.c
index fc74ce5bf0..f252f11f3e 100644
--- a/firmware/target/arm/usb-drv-arc.c
+++ b/firmware/target/arm/usb-drv-arc.c
@@ -349,7 +349,7 @@ struct queue_head {
349static struct queue_head qh_array[USB_NUM_ENDPOINTS*2] 349static struct queue_head qh_array[USB_NUM_ENDPOINTS*2]
350 USB_QHARRAY_ATTR; 350 USB_QHARRAY_ATTR;
351 351
352static struct wakeup transfer_completion_signal[USB_NUM_ENDPOINTS*2] 352static struct semaphore transfer_completion_signal[USB_NUM_ENDPOINTS*2]
353 SHAREDBSS_ATTR; 353 SHAREDBSS_ATTR;
354 354
355static const unsigned int pipe2mask[] = { 355static const unsigned int pipe2mask[] = {
@@ -424,7 +424,7 @@ void usb_drv_startup(void)
424 /* Initialize all the signal objects once */ 424 /* Initialize all the signal objects once */
425 int i; 425 int i;
426 for(i=0;i<USB_NUM_ENDPOINTS*2;i++) { 426 for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
427 wakeup_init(&transfer_completion_signal[i]); 427 semaphore_init(&transfer_completion_signal[i], 1, 0);
428 } 428 }
429} 429}
430 430
@@ -778,7 +778,7 @@ static int prime_transfer(int ep_num, void* ptr, int len, bool send, bool wait)
778 778
779 if (wait) { 779 if (wait) {
780 /* wait for transfer to finish */ 780 /* wait for transfer to finish */
781 wakeup_wait(&transfer_completion_signal[pipe], TIMEOUT_BLOCK); 781 semaphore_wait(&transfer_completion_signal[pipe], TIMEOUT_BLOCK);
782 if(qh->status!=0) { 782 if(qh->status!=0) {
783 /* No need to cancel wait here since it was done and the signal 783 /* No need to cancel wait here since it was done and the signal
784 * came. */ 784 * came. */
@@ -797,7 +797,7 @@ pt_error:
797 qh->wait = 0; 797 qh->wait = 0;
798 /* Make sure to remove any signal if interrupt fired before we zeroed 798 /* Make sure to remove any signal if interrupt fired before we zeroed
799 * qh->wait. Could happen during a bus reset for example. */ 799 * qh->wait. Could happen during a bus reset for example. */
800 wakeup_wait(&transfer_completion_signal[pipe], TIMEOUT_NOBLOCK); 800 semaphore_wait(&transfer_completion_signal[pipe], TIMEOUT_NOBLOCK);
801 } 801 }
802 802
803 return rc; 803 return rc;
@@ -814,7 +814,7 @@ void usb_drv_cancel_all_transfers(void)
814 if(qh_array[i].wait) { 814 if(qh_array[i].wait) {
815 qh_array[i].wait=0; 815 qh_array[i].wait=0;
816 qh_array[i].status=DTD_STATUS_HALTED; 816 qh_array[i].status=DTD_STATUS_HALTED;
817 wakeup_signal(&transfer_completion_signal[i]); 817 semaphore_release(&transfer_completion_signal[i]);
818 } 818 }
819 } 819 }
820} 820}
@@ -906,7 +906,7 @@ static void control_received(void)
906 if(qh_array[i].wait) { 906 if(qh_array[i].wait) {
907 qh_array[i].wait=0; 907 qh_array[i].wait=0;
908 qh_array[i].status=DTD_STATUS_HALTED; 908 qh_array[i].status=DTD_STATUS_HALTED;
909 wakeup_signal(&transfer_completion_signal[i]); 909 semaphore_release(&transfer_completion_signal[i]);
910 } 910 }
911 } 911 }
912 912
@@ -945,7 +945,7 @@ static void transfer_completed(void)
945 } 945 }
946 if(qh->wait) { 946 if(qh->wait) {
947 qh->wait=0; 947 qh->wait=0;
948 wakeup_signal(&transfer_completion_signal[pipe]); 948 semaphore_release(&transfer_completion_signal[pipe]);
949 } 949 }
950 950
951 usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT, 951 usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT,
diff --git a/firmware/target/arm/usb-s3c6400x.c b/firmware/target/arm/usb-s3c6400x.c
index eb7a0170bf..24e0fdc08a 100644
--- a/firmware/target/arm/usb-s3c6400x.c
+++ b/firmware/target/arm/usb-s3c6400x.c
@@ -44,7 +44,7 @@ struct ep_type
44 bool done; 44 bool done;
45 int rc; 45 int rc;
46 int size; 46 int size;
47 struct wakeup complete; 47 struct semaphore complete;
48} ; 48} ;
49 49
50static struct ep_type endpoints[USB_NUM_ENDPOINTS]; 50static struct ep_type endpoints[USB_NUM_ENDPOINTS];
@@ -64,7 +64,7 @@ static void reset_endpoints(int reinit)
64 endpoints[i].busy = false; 64 endpoints[i].busy = false;
65 endpoints[i].rc = -1; 65 endpoints[i].rc = -1;
66 endpoints[i].done = true; 66 endpoints[i].done = true;
67 wakeup_signal(&endpoints[i].complete); 67 semaphore_release(&endpoints[i].complete);
68 } 68 }
69 DIEPCTL0 = 0x8800; /* EP0 IN ACTIVE NEXT=1 */ 69 DIEPCTL0 = 0x8800; /* EP0 IN ACTIVE NEXT=1 */
70 DOEPCTL0 = 0x8000; /* EP0 OUT ACTIVE */ 70 DOEPCTL0 = 0x8000; /* EP0 OUT ACTIVE */
@@ -201,7 +201,7 @@ void INT_USB_FUNC(void)
201 endpoints[i].rc = 0; 201 endpoints[i].rc = 0;
202 endpoints[i].done = true; 202 endpoints[i].done = true;
203 usb_core_transfer_complete(i, USB_DIR_IN, 0, bytes); 203 usb_core_transfer_complete(i, USB_DIR_IN, 0, bytes);
204 wakeup_signal(&endpoints[i].complete); 204 semaphore_release(&endpoints[i].complete);
205 } 205 }
206 } 206 }
207 if (epints & 4) /* AHB error */ 207 if (epints & 4) /* AHB error */
@@ -213,7 +213,7 @@ void INT_USB_FUNC(void)
213 endpoints[i].busy = false; 213 endpoints[i].busy = false;
214 endpoints[i].rc = 1; 214 endpoints[i].rc = 1;
215 endpoints[i].done = true; 215 endpoints[i].done = true;
216 wakeup_signal(&endpoints[i].complete); 216 semaphore_release(&endpoints[i].complete);
217 } 217 }
218 } 218 }
219 DIEPINT(i) = epints; 219 DIEPINT(i) = epints;
@@ -233,7 +233,7 @@ void INT_USB_FUNC(void)
233 endpoints[i].rc = 0; 233 endpoints[i].rc = 0;
234 endpoints[i].done = true; 234 endpoints[i].done = true;
235 usb_core_transfer_complete(i, USB_DIR_OUT, 0, bytes); 235 usb_core_transfer_complete(i, USB_DIR_OUT, 0, bytes);
236 wakeup_signal(&endpoints[i].complete); 236 semaphore_release(&endpoints[i].complete);
237 } 237 }
238 } 238 }
239 if (epints & 4) /* AHB error */ 239 if (epints & 4) /* AHB error */
@@ -325,7 +325,7 @@ int usb_drv_send(int endpoint, void *ptr, int length)
325 endpoints[endpoint].done = false; 325 endpoints[endpoint].done = false;
326 ep_send(endpoint, ptr, length); 326 ep_send(endpoint, ptr, length);
327 while (!endpoints[endpoint].done && endpoints[endpoint].busy) 327 while (!endpoints[endpoint].done && endpoints[endpoint].busy)
328 wakeup_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK); 328 semaphore_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK);
329 return endpoints[endpoint].rc; 329 return endpoints[endpoint].rc;
330} 330}
331 331
@@ -412,7 +412,7 @@ void usb_init_device(void)
412{ 412{
413 unsigned int i; 413 unsigned int i;
414 for (i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++) 414 for (i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++)
415 wakeup_init(&endpoints[i].complete); 415 semaphore_init(&endpoints[i].complete, 1, 0);
416 416
417 /* Power up the core clocks to allow writing 417 /* Power up the core clocks to allow writing
418 to some registers needed to power it down */ 418 to some registers needed to power it down */
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index 22c1dc56e1..b7b239e3b9 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -117,7 +117,7 @@ static struct nand_param internal_param;
117static struct mutex nand_mtx; 117static struct mutex nand_mtx;
118#ifdef USE_DMA 118#ifdef USE_DMA
119static struct mutex nand_dma_mtx; 119static struct mutex nand_dma_mtx;
120static struct wakeup nand_wkup; 120static struct semaphore nand_dma_complete;
121#endif 121#endif
122static unsigned char temp_page[4096]; /* Max page size */ 122static unsigned char temp_page[4096]; /* Max page size */
123 123
@@ -170,7 +170,7 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
170 yield(); 170 yield();
171#else 171#else
172 REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */ 172 REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
173 wakeup_wait(&nand_wkup, TIMEOUT_BLOCK); 173 semaphore_wait(&nand_dma_complete, TIMEOUT_BLOCK);
174#endif 174#endif
175 175
176 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ 176 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
@@ -202,7 +202,7 @@ static void jz_nand_read_dma(void *target, unsigned int len, int bw)
202 yield(); 202 yield();
203#else 203#else
204 REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */ 204 REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
205 wakeup_wait(&nand_wkup, TIMEOUT_BLOCK); 205 semaphore_wait(&nand_dma_complete, TIMEOUT_BLOCK);
206#endif 206#endif
207 207
208 //REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ 208 //REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
@@ -226,7 +226,7 @@ void DMA_CALLBACK(DMA_NAND_CHANNEL)(void)
226 if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT) 226 if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT)
227 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT; 227 REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT;
228 228
229 wakeup_signal(&nand_wkup); 229 semaphore_release(&nand_dma_complete);
230} 230}
231#endif /* USE_DMA */ 231#endif /* USE_DMA */
232 232
@@ -603,7 +603,7 @@ int nand_init(void)
603 mutex_init(&nand_mtx); 603 mutex_init(&nand_mtx);
604#ifdef USE_DMA 604#ifdef USE_DMA
605 mutex_init(&nand_dma_mtx); 605 mutex_init(&nand_dma_mtx);
606 wakeup_init(&nand_wkup); 606 semaphore_init(&nand_dma_complete, 1, 0);
607 system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL)); 607 system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL));
608#endif 608#endif
609 609
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index efca66445a..846b9095f1 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -47,7 +47,7 @@ static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
47static const char sd_thread_name[] = "ata/sd"; 47static const char sd_thread_name[] = "ata/sd";
48static struct event_queue sd_queue; 48static struct event_queue sd_queue;
49static struct mutex sd_mtx; 49static struct mutex sd_mtx;
50static struct wakeup sd_wakeup; 50static struct semaphore sd_wakeup;
51static void sd_thread(void) NORETURN_ATTR; 51static void sd_thread(void) NORETURN_ATTR;
52 52
53static int use_4bit; 53static int use_4bit;
@@ -831,7 +831,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
831 831
832 /* Wait for command completion */ 832 /* Wait for command completion */
833 //__intc_unmask_irq(IRQ_MSC); 833 //__intc_unmask_irq(IRQ_MSC);
834 //wakeup_wait(&sd_wakeup, 100); 834 //semaphore_wait(&sd_wakeup, 100);
835 while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES)); 835 while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES));
836 836
837 837
@@ -881,7 +881,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
881#endif 881#endif
882 } 882 }
883 //__intc_unmask_irq(IRQ_MSC); 883 //__intc_unmask_irq(IRQ_MSC);
884 //wakeup_wait(&sd_wakeup, 100); 884 //semaphore_wait(&sd_wakeup, 100);
885 /* Wait for Data Done */ 885 /* Wait for Data Done */
886 while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE)); 886 while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE));
887 REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */ 887 REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
@@ -891,7 +891,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
891 if (events & SD_EVENT_PROG_DONE) 891 if (events & SD_EVENT_PROG_DONE)
892 { 892 {
893 //__intc_unmask_irq(IRQ_MSC); 893 //__intc_unmask_irq(IRQ_MSC);
894 //wakeup_wait(&sd_wakeup, 100); 894 //semaphore_wait(&sd_wakeup, 100);
895 while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE)); 895 while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE));
896 REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */ 896 REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
897 } 897 }
@@ -945,7 +945,7 @@ static void jz_sd_rx_handler(unsigned int arg)
945/* MSC interrupt handler */ 945/* MSC interrupt handler */
946void MSC(void) 946void MSC(void)
947{ 947{
948 //wakeup_signal(&sd_wakeup); 948 //semaphore_release(&sd_wakeup);
949 logf("MSC interrupt"); 949 logf("MSC interrupt");
950} 950}
951 951
@@ -1228,7 +1228,7 @@ int sd_init(void)
1228 static bool inited = false; 1228 static bool inited = false;
1229 if(!inited) 1229 if(!inited)
1230 { 1230 {
1231 wakeup_init(&sd_wakeup); 1231 semaphore_init(&sd_wakeup, 1, 0);
1232 mutex_init(&sd_mtx); 1232 mutex_init(&sd_mtx);
1233 queue_init(&sd_queue, true); 1233 queue_init(&sd_queue, true);
1234 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0, 1234 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
diff --git a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
index ef45317c3f..e74e227e47 100644
--- a/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/lcd-jz4740.c
@@ -34,7 +34,7 @@
34 34
35static volatile bool lcd_is_on = false; 35static volatile bool lcd_is_on = false;
36static struct mutex lcd_mtx; 36static struct mutex lcd_mtx;
37static struct wakeup lcd_wkup; 37static struct semaphore lcd_wkup;
38static int lcd_count = 0; 38static int lcd_count = 0;
39 39
40void lcd_clock_enable(void) 40void lcd_clock_enable(void)
@@ -56,7 +56,7 @@ void lcd_init_device(void)
56 56
57 lcd_is_on = true; 57 lcd_is_on = true;
58 mutex_init(&lcd_mtx); 58 mutex_init(&lcd_mtx);
59 wakeup_init(&lcd_wkup); 59 semaphore_init(&lcd_wkup, 1, 0);
60 system_enable_irq(DMA_IRQ(DMA_LCD_CHANNEL)); 60 system_enable_irq(DMA_IRQ(DMA_LCD_CHANNEL));
61} 61}
62 62
@@ -118,7 +118,7 @@ void lcd_update_rect(int x, int y, int width, int height)
118 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */ 118 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
119 REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */ 119 REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
120 120
121 wakeup_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */ 121 semaphore_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */
122 122
123 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */ 123 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
124 dma_disable(); 124 dma_disable();
@@ -145,7 +145,7 @@ void DMA_CALLBACK(DMA_LCD_CHANNEL)(void)
145 if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT) 145 if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT)
146 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_TT; 146 REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_TT;
147 147
148 wakeup_signal(&lcd_wkup); 148 semaphore_release(&lcd_wkup);
149} 149}
150 150
151/* Update the display. 151/* Update the display.
diff --git a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
index 92cf0d7552..99d73fa3c7 100644
--- a/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
+++ b/firmware/target/mips/ingenic_jz47xx/onda_vx747/sadc-onda_vx747.c
@@ -74,7 +74,7 @@ static int datacount = 0;
74static volatile int cur_touch = 0; 74static volatile int cur_touch = 0;
75static volatile bool pen_down = false; 75static volatile bool pen_down = false;
76static struct mutex battery_mtx; 76static struct mutex battery_mtx;
77static struct wakeup battery_wkup; 77static struct semaphore battery_done;
78 78
79const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = 79const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
80{ 80{
@@ -113,7 +113,7 @@ unsigned int battery_adc_voltage(void)
113 113
114 REG_SADC_ENA |= SADC_ENA_PBATEN; 114 REG_SADC_ENA |= SADC_ENA_PBATEN;
115 115
116 wakeup_wait(&battery_wkup, HZ/4); 116 semaphore_wait(&battery_done, HZ/4);
117 bat_val = REG_SADC_BATDAT; 117 bat_val = REG_SADC_BATDAT;
118 118
119 logf("%d %d", bat_val, (bat_val * BATTERY_SCALE_FACTOR) / 4096); 119 logf("%d %d", bat_val, (bat_val * BATTERY_SCALE_FACTOR) / 4096);
@@ -268,7 +268,7 @@ void SADC(void)
268 if(state & SADC_CTRL_PBATRDYM) 268 if(state & SADC_CTRL_PBATRDYM)
269 { 269 {
270 /* Battery AD IRQ */ 270 /* Battery AD IRQ */
271 wakeup_signal(&battery_wkup); 271 semaphore_release(&battery_done);
272 } 272 }
273} 273}
274 274
@@ -290,7 +290,7 @@ void adc_init(void)
290 REG_SADC_ENA = SADC_ENA_TSEN; 290 REG_SADC_ENA = SADC_ENA_TSEN;
291 291
292 mutex_init(&battery_mtx); 292 mutex_init(&battery_mtx);
293 wakeup_init(&battery_wkup); 293 semaphore_init(&battery_done, 1, 0);
294} 294}
295 295
296void adc_close(void) 296void adc_close(void)
diff --git a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
index f12f1bed82..a615d3d4da 100644
--- a/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/usb-jz4740.c
@@ -69,7 +69,7 @@ struct usb_endpoint
69 unsigned short fifo_size; 69 unsigned short fifo_size;
70 70
71 bool wait; 71 bool wait;
72 struct wakeup wakeup; 72 struct semaphore complete;
73}; 73};
74 74
75static unsigned char ep0_rx_buf[64]; 75static unsigned char ep0_rx_buf[64];
@@ -171,7 +171,7 @@ static inline void ep_transfer_completed(struct usb_endpoint* ep)
171 ep->buf = NULL; 171 ep->buf = NULL;
172 ep->busy = false; 172 ep->busy = false;
173 if(ep->wait) 173 if(ep->wait)
174 wakeup_signal(&ep->wakeup); 174 semaphore_release(&ep->complete);
175} 175}
176 176
177static void EP0_send(void) 177static void EP0_send(void)
@@ -598,7 +598,7 @@ void usb_init_device(void)
598 system_enable_irq(IRQ_UDC); 598 system_enable_irq(IRQ_UDC);
599 599
600 for(i=0; i<TOTAL_EP(); i++) 600 for(i=0; i<TOTAL_EP(); i++)
601 wakeup_init(&endpoints[i].wakeup); 601 semaphore_init(&endpoints[i].complete, 1, 0);
602} 602}
603 603
604#ifdef USB_GPIO_IRQ 604#ifdef USB_GPIO_IRQ
@@ -715,7 +715,7 @@ static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length
715 715
716 if(blocking) 716 if(blocking)
717 { 717 {
718 wakeup_wait(&ep->wakeup, TIMEOUT_BLOCK); 718 semaphore_wait(&ep->complete, TIMEOUT_BLOCK);
719 ep->wait = false; 719 ep->wait = false;
720 } 720 }
721} 721}