summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-03-02 08:49:38 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-03-02 08:49:38 +0000
commit12375d1d3aa41f7d277a9af584c7b810b636ec95 (patch)
treefc9ce8029a6910a8dac71b3bf60c71155a01eea4 /firmware
parent05e180a1308a095d51d51d0e047fcd44425ea88f (diff)
downloadrockbox-12375d1d3aa41f7d277a9af584c7b810b636ec95.tar.gz
rockbox-12375d1d3aa41f7d277a9af584c7b810b636ec95.zip
Merge functionality of wakeups and semaphores-- fewer APIs and object types. semaphore_wait takes a timeout now so codecs and plugins have to be made incompatible. Don't make semaphores for targets not using them.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29492 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-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
34 files changed, 276 insertions, 292 deletions
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}