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
This commit is contained in:
Michael Sevakis 2011-03-02 08:49:38 +00:00
parent 05e180a130
commit 12375d1d3a
38 changed files with 294 additions and 311 deletions

View file

@ -75,12 +75,12 @@
#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
/* increase this every time the api struct changes */
#define CODEC_API_VERSION 38
#define CODEC_API_VERSION 39
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
#define CODEC_MIN_API_VERSION 38
#define CODEC_MIN_API_VERSION 39
/* codec return codes */
enum codec_status {
@ -166,7 +166,7 @@ struct codec_api {
void (*thread_thaw)(unsigned int thread_id);
void (*thread_wait)(unsigned int thread_id);
void (*semaphore_init)(struct semaphore *s, int max, int start);
void (*semaphore_wait)(struct semaphore *s);
int (*semaphore_wait)(struct semaphore *s, int timeout);
void (*semaphore_release)(struct semaphore *s);
#endif /* NUM_CORES */

View file

@ -211,7 +211,7 @@ static void mad_synth_thread(void)
{
while(1) {
ci->semaphore_release(&synth_done_sem);
ci->semaphore_wait(&synth_pending_sem);
ci->semaphore_wait(&synth_pending_sem, TIMEOUT_BLOCK);
if(die)
break;
@ -224,7 +224,7 @@ static void mad_synth_thread(void)
* synthesized */
static inline void mad_synth_thread_wait_pcm(void)
{
ci->semaphore_wait(&synth_done_sem);
ci->semaphore_wait(&synth_done_sem, TIMEOUT_BLOCK);
}
/* increment the done semaphore - used after a wait for idle to preserve the

View file

@ -244,7 +244,7 @@ static inline void samples_release_wrbuf(void)
static inline struct sample_queue_chunk * samples_get_wrbuf(void)
{
ci->semaphore_wait(&sample_queue.emu_sem_tail);
ci->semaphore_wait(&sample_queue.emu_sem_tail, TIMEOUT_BLOCK);
return &sample_queue.wav_chunk[sample_queue.tail & WAV_CHUNK_MASK];
}
@ -259,7 +259,7 @@ static inline void samples_release_rdbuf(void)
static inline int32_t * samples_get_rdbuf(void)
{
ci->semaphore_wait(&sample_queue.emu_sem_head);
ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_BLOCK);
if (ci->stop_codec || ci->new_track)
{
@ -275,7 +275,7 @@ static intptr_t emu_thread_send_msg(long id, intptr_t data)
{
struct sample_queue_chunk *chunk;
/* Grab an audio output buffer */
ci->semaphore_wait(&sample_queue.emu_sem_head);
ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_BLOCK);
chunk = &sample_queue.wav_chunk[sample_queue.head & WAV_CHUNK_MASK];
/* Place a message in it instead of audio */
chunk->id = id;
@ -285,7 +285,7 @@ static intptr_t emu_thread_send_msg(long id, intptr_t data)
if (id != SPC_EMU_QUIT) {
/* Wait for a response */
ci->semaphore_wait(&sample_queue.emu_evt_reply);
ci->semaphore_wait(&sample_queue.emu_evt_reply, TIMEOUT_BLOCK);
}
return sample_queue.retval;
@ -308,11 +308,10 @@ static bool emu_thread_process_msg(struct sample_queue_chunk *chunk)
sample_queue.retval = SPC_load_spc(&spc_emu, ld->buf, ld->size);
/* Empty the audio queue */
/* This is a dirty hack a timeout based wait would make unnescessary but
still safe because the other thread is known to be waiting for a reply
and is not using the objects. */
ci->semaphore_init(&sample_queue.emu_sem_tail, 2, 2);
ci->semaphore_init(&sample_queue.emu_sem_head, 2, 0);
ci->semaphore_release(&sample_queue.emu_sem_tail);
ci->semaphore_release(&sample_queue.emu_sem_tail);
ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_NOBLOCK);
ci->semaphore_wait(&sample_queue.emu_sem_head, TIMEOUT_NOBLOCK);
sample_queue.head = sample_queue.tail = 0;
}

View file

@ -145,12 +145,12 @@ void* plugin_get_buffer(size_t *buffer_size);
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 199
#define PLUGIN_API_VERSION 200
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
#define PLUGIN_MIN_API_VERSION 199
#define PLUGIN_MIN_API_VERSION 200
/* plugin return codes */
/* internal returns start at 0x100 to make exit(1..255) work */
@ -901,7 +901,7 @@ struct plugin_api {
#ifdef HAVE_SEMAPHORE_OBJECTS
void (*semaphore_init)(struct semaphore *s, int max, int start);
void (*semaphore_wait)(struct semaphore *s);
int (*semaphore_wait)(struct semaphore *s, int timeout);
void (*semaphore_release)(struct semaphore *s);
#endif

View file

@ -741,8 +741,6 @@ Lyre prototype 1 */
#endif /* PLATFORM_NATIVE */
#define HAVE_SEMAPHORE_OBJECTS
#ifdef HAVE_USBSTACK
#if CONFIG_USBOTG == USBOTG_ARC
#define USB_STATUS_BY_EVENT
@ -769,7 +767,7 @@ Lyre prototype 1 */
|| (CONFIG_CPU == AS3525) || (CONFIG_CPU == AS3525v2) \
|| defined(CPU_S5L870X) || (CONFIG_CPU == S3C2440) \
|| defined(APPLICATION)
#define HAVE_WAKEUP_OBJECTS
#define HAVE_SEMAPHORE_OBJECTS
#endif
/*include support for crossfading - requires significant PCM buffer space*/

View file

@ -160,22 +160,12 @@ struct mutex
struct semaphore
{
struct thread_entry *queue; /* Waiter list */
int count; /* # of waits remaining before unsignaled */
int volatile count; /* # of waits remaining before unsignaled */
int max; /* maximum # of waits to remain signaled */
IF_COP( struct corelock cl; ) /* multiprocessor sync */
};
#endif
#ifdef HAVE_WAKEUP_OBJECTS
struct wakeup
{
struct thread_entry *queue; /* waiter list */
bool volatile signalled; /* signalled status */
IF_COP( struct corelock cl; ) /* multiprocessor sync */
};
#endif
/* global tick variable */
#if defined(CPU_PP) && defined(BOOTLOADER) && \
!defined(HAVE_BOOTLOADER_USB_MODE)
@ -280,14 +270,8 @@ static inline bool mutex_test(const struct mutex *m)
#ifdef HAVE_SEMAPHORE_OBJECTS
extern void semaphore_init(struct semaphore *s, int max, int start);
extern void semaphore_wait(struct semaphore *s);
extern int semaphore_wait(struct semaphore *s, int timeout);
extern void semaphore_release(struct semaphore *s);
#endif /* HAVE_SEMAPHORE_OBJECTS */
#ifdef HAVE_WAKEUP_OBJECTS
extern void wakeup_init(struct wakeup *w);
extern int wakeup_wait(struct wakeup *w, int timeout);
extern int wakeup_signal(struct wakeup *w);
#endif /* HAVE_WAKEUP_OBJECTS */
#endif /* _KERNEL_H_ */

View file

@ -284,7 +284,9 @@ struct thread_entry
and priority disinheritance */
/* Only enabled when using queue_send for now */
#endif
#if defined(HAVE_EXTENDED_MESSAGING_AND_NAME) || NUM_CORES > 1
#if defined(HAVE_SEMAPHORE_OBJECTS) || \
defined(HAVE_EXTENDED_MESSAGING_AND_NAME) || \
NUM_CORES > 1
volatile intptr_t retval; /* Return value from a blocked operation/
misc. use */
#endif

View file

@ -978,6 +978,9 @@ void mutex_unlock(struct mutex *m)
* Simple semaphore functions ;)
****************************************************************************/
#ifdef HAVE_SEMAPHORE_OBJECTS
/* Initialize the semaphore object.
* max = maximum up count the semaphore may assume (max >= 1)
* start = initial count of semaphore (0 <= count <= max) */
void semaphore_init(struct semaphore *s, int max, int start)
{
KERNEL_ASSERT(max > 0 && start >= 0 && start <= max,
@ -988,132 +991,97 @@ void semaphore_init(struct semaphore *s, int max, int start)
corelock_init(&s->cl);
}
void semaphore_wait(struct semaphore *s)
/* Down the semaphore's count or wait for 'timeout' ticks for it to go up if
* it is already 0. 'timeout' as TIMEOUT_NOBLOCK (0) will not block and may
* safely be used in an ISR. */
int semaphore_wait(struct semaphore *s, int timeout)
{
struct thread_entry *current;
int ret;
int oldlevel;
int count;
oldlevel = disable_irq_save();
corelock_lock(&s->cl);
if(LIKELY(--s->count >= 0))
count = s->count;
if(LIKELY(count > 0))
{
/* wait satisfied */
/* count is not zero; down it */
s->count = count - 1;
ret = OBJ_WAIT_SUCCEEDED;
}
else if(timeout == 0)
{
/* just polling it */
ret = OBJ_WAIT_TIMEDOUT;
}
else
{
/* too many waits - block until count is upped... */
struct thread_entry * current = thread_id_entry(THREAD_ID_CURRENT);
IF_COP( current->obj_cl = &s->cl; )
current->bqp = &s->queue;
/* return value will be OBJ_WAIT_SUCCEEDED after wait if wake was
* explicit in semaphore_release */
current->retval = OBJ_WAIT_TIMEDOUT;
if(timeout > 0)
block_thread_w_tmo(current, timeout); /* ...or timed out... */
else
block_thread(current); /* -timeout = infinite */
corelock_unlock(&s->cl);
return;
/* ...and turn control over to next thread */
switch_thread();
return current->retval;
}
/* too many waits - block until dequeued... */
current = thread_id_entry(THREAD_ID_CURRENT);
IF_COP( current->obj_cl = &s->cl; )
current->bqp = &s->queue;
disable_irq();
block_thread(current);
corelock_unlock(&s->cl);
restore_irq(oldlevel);
/* ...and turn control over to next thread */
switch_thread();
return ret;
}
/* Up the semaphore's count and release any thread waiting at the head of the
* queue. The count is saturated to the value of the 'max' parameter specified
* in 'semaphore_init'. */
void semaphore_release(struct semaphore *s)
{
IF_PRIO( unsigned int result = THREAD_NONE; )
int oldlevel;
oldlevel = disable_irq_save();
corelock_lock(&s->cl);
if(s->count < s->max && ++s->count <= 0)
if(LIKELY(s->queue != NULL))
{
/* there should be threads in this queue */
KERNEL_ASSERT(s->queue != NULL, "semaphore->wakeup\n");
/* a thread was queued - wake it up */
int oldlevel = disable_irq_save();
/* a thread was queued - wake it up and keep count at 0 */
KERNEL_ASSERT(s->count == 0,
"semaphore_release->threads queued but count=%d!\n", s->count);
s->queue->retval = OBJ_WAIT_SUCCEEDED; /* indicate explicit wake */
IF_PRIO( result = ) wakeup_thread(&s->queue);
restore_irq(oldlevel);
}
else
{
int count = s->count;
if(count < s->max)
{
/* nothing waiting - up it */
s->count = count + 1;
}
}
corelock_unlock(&s->cl);
restore_irq(oldlevel);
#ifdef HAVE_PRIORITY_SCHEDULING
if(result & THREAD_SWITCH)
#if defined(HAVE_PRIORITY_SCHEDULING) && defined(irq_enabled_checkval)
/* No thread switch if IRQ disabled - it's probably called via ISR.
* switch_thread would as well enable them anyway. */
if((result & THREAD_SWITCH) && irq_enabled_checkval(oldlevel))
switch_thread();
#endif
}
#endif /* HAVE_SEMAPHORE_OBJECTS */
#ifdef HAVE_WAKEUP_OBJECTS
/****************************************************************************
* Lightweight IRQ-compatible wakeup object
*/
/* Initialize the wakeup object */
void wakeup_init(struct wakeup *w)
{
w->queue = NULL;
w->signalled = false;
IF_COP( corelock_init(&w->cl); )
}
/* Wait for a signal blocking indefinitely or for a specified period */
int wakeup_wait(struct wakeup *w, int timeout)
{
int ret = OBJ_WAIT_SUCCEEDED; /* Presume success */
int oldlevel = disable_irq_save();
corelock_lock(&w->cl);
if(LIKELY(!w->signalled && timeout != TIMEOUT_NOBLOCK))
{
struct thread_entry * current = thread_id_entry(THREAD_ID_CURRENT);
IF_COP( current->obj_cl = &w->cl; )
current->bqp = &w->queue;
if (timeout != TIMEOUT_BLOCK)
block_thread_w_tmo(current, timeout);
else
block_thread(current);
corelock_unlock(&w->cl);
switch_thread();
oldlevel = disable_irq_save();
corelock_lock(&w->cl);
}
if(UNLIKELY(!w->signalled))
{
/* Timed-out or failed */
ret = (timeout != TIMEOUT_BLOCK) ?
OBJ_WAIT_TIMEDOUT : OBJ_WAIT_FAILED;
}
w->signalled = false; /* Reset */
corelock_unlock(&w->cl);
restore_irq(oldlevel);
return ret;
}
/* Signal the thread waiting or leave the signal if the thread hasn't
* waited yet.
*
* returns THREAD_NONE or THREAD_OK
*/
int wakeup_signal(struct wakeup *w)
{
int oldlevel = disable_irq_save();
int ret;
corelock_lock(&w->cl);
w->signalled = true;
ret = wakeup_thread(&w->queue);
corelock_unlock(&w->cl);
restore_irq(oldlevel);
return ret;
}
#endif /* HAVE_WAKEUP_OBJECTS */

View file

@ -107,7 +107,7 @@ struct ascodec_request {
unsigned char status;
unsigned char cnt;
unsigned char data[ASCODEC_REQ_MAXLEN];
struct wakeup wkup;
struct semaphore complete;
ascodec_cb_fn *callback;
struct ascodec_request *next;
};
@ -121,7 +121,7 @@ static unsigned char *req_data_ptr = NULL;
static struct ascodec_request *req_head = NULL;
static struct ascodec_request *req_tail = NULL;
static struct wakeup adc_wkup;
static struct semaphore adc_done_sem;
static struct ascodec_request as_audio_req;
#ifdef DEBUG
@ -168,7 +168,7 @@ static void ascodec_finish_req(struct ascodec_request *req)
if (req->callback) {
req->callback(req->data, req_data_ptr - req->data);
}
wakeup_signal(&req->wkup);
semaphore_release(&req->complete);
req_head = req->next;
req->next = NULL;
@ -263,7 +263,7 @@ void ascodec_init(void)
int prescaler;
mutex_init(&as_mtx);
wakeup_init(&adc_wkup);
semaphore_init(&adc_done_sem, 1, 0);
/* enable clock */
bitset32(&CGU_PERI, CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE);
@ -312,7 +312,7 @@ void ascodec_init(void)
static void ascodec_req_init(struct ascodec_request *req, int type,
unsigned int index, unsigned int cnt)
{
wakeup_init(&req->wkup);
semaphore_init(&req->complete, 1, 0);
req->next = NULL;
req->callback = NULL;
req->type = type;
@ -337,19 +337,10 @@ static void ascodec_submit(struct ascodec_request *req)
restore_irq(oldlevel);
}
static int irq_disabled(void)
{
unsigned long cpsr;
asm volatile ("mrs %0, cpsr" : "=r"(cpsr));
return (cpsr & IRQ_STATUS) == IRQ_DISABLED;
}
static void ascodec_wait(struct ascodec_request *req)
{
if (!irq_disabled()) {
wakeup_wait(&req->wkup, TIMEOUT_BLOCK);
if (irq_enabled()) {
semaphore_wait(&req->complete, TIMEOUT_BLOCK);
return;
}
@ -477,7 +468,7 @@ static void ascodec_read_cb(unsigned const char *data, unsigned int len)
}
if (data[2] & IRQ_ADC) { /* adc finished */
IFDEBUG(int_adc++);
wakeup_signal(&adc_wkup);
semaphore_release(&adc_done_sem);
}
VIC_INT_ENABLE = INTERRUPT_AUDIO;
}
@ -492,7 +483,7 @@ void INT_AUDIO(void)
void ascodec_wait_adc_finished(void)
{
wakeup_wait(&adc_wkup, TIMEOUT_BLOCK);
semaphore_wait(&adc_done_sem, TIMEOUT_BLOCK);
}
#ifdef CONFIG_CHARGING

View file

@ -28,7 +28,7 @@
#ifndef SIMULATOR
#include "as3514.h"
#include "kernel.h" /* for struct wakeup */
#include "kernel.h" /* for struct semaphore */
#include "clock-target.h" /* for AS3525_I2C_PRESCALER */
#include "system-arm.h"

View file

@ -136,7 +136,7 @@ static bool hs_card = false;
#define EXT_SD_BITS (1<<2)
#endif
static struct wakeup transfer_completion_signal;
static struct semaphore transfer_completion_signal;
static volatile unsigned int transfer_error[NUM_VOLUMES];
#define PL180_MAX_TRANSFER_ERRORS 10
@ -191,7 +191,7 @@ void INT_NAND(void)
transfer_error[INTERNAL_AS3525] = status & MCI_DATA_ERROR;
wakeup_signal(&transfer_completion_signal);
semaphore_release(&transfer_completion_signal);
MCI_CLEAR(INTERNAL_AS3525) = status;
}
@ -202,7 +202,7 @@ void INT_MCI0(void)
transfer_error[SD_SLOT_AS3525] = status & MCI_DATA_ERROR;
wakeup_signal(&transfer_completion_signal);
semaphore_release(&transfer_completion_signal);
MCI_CLEAR(SD_SLOT_AS3525) = status;
}
#endif
@ -568,7 +568,7 @@ int sd_init(void)
bitset32(&CCU_IO, 1<<2);
#endif
wakeup_init(&transfer_completion_signal);
semaphore_init(&transfer_completion_signal, 1, 0);
init_pl180_controller(INTERNAL_AS3525);
ret = sd_init_card(INTERNAL_AS3525);
@ -678,7 +678,7 @@ static int sd_select_bank(signed char bank)
(9<<4) /* 2^9 = 512 */ ;
/* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
/* Wait for FIFO to empty, card may still be in PRG state */
while(MCI_STATUS(INTERNAL_AS3525) & MCI_TX_ACTIVE );
@ -837,7 +837,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
(9<<4) /* 2^9 = 512 */ ;
/* Wakeup signal from NAND/MCIO isr on MCI_DATA_ERROR | MCI_DATA_END */
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
/* Wait for FIFO to empty, card may still be in PRG state for writes */
while(MCI_STATUS(drive) & MCI_TX_ACTIVE);

View file

@ -342,8 +342,8 @@ static struct event_queue sd_queue;
bool sd_enabled = false;
#endif
static struct wakeup transfer_completion_signal;
static struct wakeup command_completion_signal;
static struct semaphore transfer_completion_signal;
static struct semaphore command_completion_signal;
static volatile bool retry;
static volatile int cmd_error;
@ -365,12 +365,12 @@ void INT_NAND(void)
retry = true;
if( status & (MCI_INT_DTO|MCI_DATA_ERROR))
wakeup_signal(&transfer_completion_signal);
semaphore_release(&transfer_completion_signal);
cmd_error = status & MCI_CMD_ERROR;
if(status & MCI_INT_CD)
wakeup_signal(&command_completion_signal);
semaphore_release(&command_completion_signal);
MCI_CTRL |= INT_ENABLE;
}
@ -442,7 +442,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg, const int fl
_buttonlight_off();
}
#endif
wakeup_wait(&command_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&command_completion_signal, TIMEOUT_BLOCK);
/* Handle command responses & errors */
if(flags & MCI_RESP)
@ -769,8 +769,8 @@ int sd_init(void)
| (AS3525_SDSLOT_DIV << 2)
| 1; /* clock source = PLLA */
wakeup_init(&transfer_completion_signal);
wakeup_init(&command_completion_signal);
semaphore_init(&transfer_completion_signal, 1, 0);
semaphore_init(&command_completion_signal, 1, 0);
#if defined(SANSA_FUZEV2) || defined(SANSA_CLIPPLUS)
if (amsv2_variant == 1)
@ -932,7 +932,7 @@ sd_transfer_retry_with_reinit:
goto sd_transfer_error;
}
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
last_disk_activity = current_tick;

View file

@ -40,6 +40,7 @@
static struct usb_endpoint endpoints[USB_NUM_EPS][2];
static int got_set_configuration = 0;
static int usb_enum_timeout = -1;
static bool initialized = false;
/*
* dma/setup descriptors and buffers should avoid sharing
@ -180,19 +181,19 @@ static void reset_endpoints(int init)
if (endpoints[i][0].state & EP_STATE_BUSY) {
if (endpoints[i][0].state & EP_STATE_ASYNC) {
endpoints[i][0].rc = -1;
wakeup_signal(&endpoints[i][0].complete);
semaphore_release(&endpoints[i][0].complete);
} else {
usb_core_transfer_complete(i, USB_DIR_IN, -1, 0);
}
}
endpoints[i][0].state = 0;
wakeup_init(&endpoints[i][0].complete);
semaphore_wait(&endpoints[i][0].complete, TIMEOUT_NOBLOCK);
if (i != 2) { /* Skip the OUT EP0 alias */
if (endpoints[i][1].state & EP_STATE_BUSY)
usb_core_transfer_complete(i, USB_DIR_OUT, -1, 0);
endpoints[i][1].state = 0;
wakeup_init(&endpoints[i][1].complete);
semaphore_wait(&endpoints[i][1].complete, TIMEOUT_NOBLOCK);
USB_OEP_SUP_PTR(i) = 0;
}
}
@ -225,6 +226,18 @@ void usb_drv_init(void)
{
logf("usb_drv_init() !!!!\n");
if (!initialized)
{
int i;
for (i = 0; i < USB_NUM_EPS; i++)
{
semaphore_init(&endpoints[i][0].complete, 1, 0);
semaphore_init(&endpoints[i][1].complete, 1, 0);
}
initialized = true;
}
usb_enable_pll();
/* we have external power, so boost cpu */
@ -322,6 +335,7 @@ void usb_drv_exit(void)
ascodec_write(AS3515_USB_UTIL, ascodec_read(AS3515_USB_UTIL) & ~(1<<4));
usb_disable_pll();
cpu_boost(0);
initialized = false;
logf("usb_drv_exit() !!!!\n");
}
@ -529,7 +543,7 @@ int usb_drv_send(int ep, void *ptr, int len)
}
ep_send(ep, ptr, len);
if (wakeup_wait(&endpoints[ep][0].complete, HZ) == OBJ_WAIT_TIMEDOUT)
if (semaphore_wait(&endpoints[ep][0].complete, HZ) == OBJ_WAIT_TIMEDOUT)
logf("send timed out!\n");
return endpoints[ep][0].rc;
@ -570,7 +584,7 @@ static void handle_in_ep(int ep)
endpoints[ep][0].state &= ~EP_STATE_ASYNC;
usb_core_transfer_complete(ep, USB_DIR_IN, 0, endpoints[ep][0].len);
} else {
wakeup_signal(&endpoints[ep][0].complete);
semaphore_release(&endpoints[ep][0].complete);
}
ep_sts &= ~USB_EP_STAT_TDC;
}

View file

@ -310,7 +310,7 @@ struct usb_endpoint
unsigned int len;
volatile unsigned int state;
int rc;
struct wakeup complete;
struct semaphore complete;
struct usb_dev_dma_desc *uc_desc;
};

View file

@ -61,7 +61,7 @@ static const uint8_t out_ep_list[NUM_OUT_EP + 1] = {0, OUT_EP_LIST};
struct usb_endpoint
{
unsigned int len; /* length of the data buffer */
struct wakeup complete; /* wait object */
struct semaphore complete; /* wait object */
int8_t status; /* completion status (0 for success) */
bool active; /* true is endpoint has been requested (true for EP0) */
bool wait; /* true if usb thread is blocked on completion */
@ -281,7 +281,7 @@ static void reset_endpoints(void)
if(endpoints[ep][DIR_IN].wait)
{
endpoints[ep][DIR_IN].wait = false;
wakeup_signal(&endpoints[ep][DIR_IN].complete);
semaphore_release(&endpoints[ep][DIR_IN].complete);
}
if(DIEPCTL(ep) & DEPCTL_epena)
DIEPCTL(ep) = DEPCTL_snak;
@ -297,7 +297,7 @@ static void reset_endpoints(void)
if(endpoints[ep][DIR_OUT].wait)
{
endpoints[ep][DIR_OUT].wait = false;
wakeup_signal(&endpoints[ep][DIR_OUT].complete);
semaphore_release(&endpoints[ep][DIR_OUT].complete);
}
if(DOEPCTL(ep) & DEPCTL_epena)
DOEPCTL(ep) = DEPCTL_snak;
@ -329,7 +329,7 @@ static void cancel_all_transfers(bool cancel_ep0)
if(endpoints[ep][DIR_IN].wait)
{
endpoints[ep][DIR_IN].wait = false;
wakeup_signal(&endpoints[ep][DIR_IN].complete);
semaphore_release(&endpoints[ep][DIR_IN].complete);
}
DIEPCTL(ep) = (DIEPCTL(ep) & ~DEPCTL_usbactep) | DEPCTL_snak;
}
@ -340,7 +340,7 @@ static void cancel_all_transfers(bool cancel_ep0)
if(endpoints[ep][DIR_OUT].wait)
{
endpoints[ep][DIR_OUT].wait = false;
wakeup_signal(&endpoints[ep][DIR_OUT].complete);
semaphore_release(&endpoints[ep][DIR_OUT].complete);
}
DOEPCTL(ep) = (DOEPCTL(ep) & ~DEPCTL_usbactep) | DEPCTL_snak;
}
@ -457,9 +457,9 @@ void usb_drv_init(void)
/* Core init */
core_init();
FOR_EACH_IN_EP_AND_EP0(i, ep)
wakeup_init(&endpoints[ep][DIR_IN].complete);
semaphore_init(&endpoints[ep][DIR_IN].complete, 1, 0);
FOR_EACH_OUT_EP_AND_EP0(i, ep)
wakeup_init(&endpoints[ep][DIR_OUT].complete);
semaphore_init(&endpoints[ep][DIR_OUT].complete, 1, 0);
/* Enable global interrupts */
enable_global_interrupts();
}
@ -498,7 +498,7 @@ static void handle_ep_in_int(int ep)
if(endpoint->wait)
{
endpoint->wait = false;
wakeup_signal(&endpoint->complete);
semaphore_release(&endpoint->complete);
}
}
}
@ -515,7 +515,7 @@ static void handle_ep_in_int(int ep)
if(endpoint->wait)
{
endpoint->wait = false;
wakeup_signal(&endpoint->complete);
semaphore_release(&endpoint->complete);
}
}
}
@ -549,7 +549,7 @@ static void handle_ep_out_int(int ep)
if(endpoint->wait)
{
endpoint->wait = false;
wakeup_signal(&endpoint->complete);
semaphore_release(&endpoint->complete);
}
}
}
@ -798,7 +798,7 @@ static int usb_drv_transfer(int ep, void *ptr, int len, bool dir_in, bool blocki
if(blocking)
{
wakeup_wait(&endpoint->complete, TIMEOUT_BLOCK);
semaphore_wait(&endpoint->complete, TIMEOUT_BLOCK);
return endpoint->status;
}

View file

@ -246,7 +246,7 @@ static const struct ata_udma_timings
/** Threading **/
/* Signal to tell thread when DMA is done */
static struct wakeup ata_dma_wakeup;
static struct semaphore ata_dma_complete;
/** SDMA **/
/* Array of buffer descriptors for large transfers and alignnment */
@ -445,7 +445,7 @@ static void ata_dma_callback(void)
ATA_INTERRUPT_CLEAR = ATA_INTERRUPT_PENDING;
ata_set_intrq(false); /* Return INTRQ to MCU */
wakeup_signal(&ata_dma_wakeup); /* Signal waiting thread */
semaphore_release(&ata_dma_complete); /* Signal waiting thread */
}
bool ata_dma_setup(void *addr, unsigned long bytes, bool write)
@ -580,7 +580,8 @@ bool ata_dma_finish(void)
{
int oldirq;
if (LIKELY(wakeup_wait(&ata_dma_wakeup, HZ/2) == OBJ_WAIT_SUCCEEDED))
if (LIKELY(semaphore_wait(&ata_dma_complete, HZ/2)
== OBJ_WAIT_SUCCEEDED))
break;
ata_keep_active();
@ -594,7 +595,8 @@ bool ata_dma_finish(void)
sdma_channel_stop(channel); /* Stop DMA */
restore_irq(oldirq);
if (wakeup_wait(&ata_dma_wakeup, TIMEOUT_NOBLOCK) == OBJ_WAIT_SUCCEEDED)
if (semaphore_wait(&ata_dma_complete, TIMEOUT_NOBLOCK)
== OBJ_WAIT_SUCCEEDED)
break; /* DMA really did finish after timeout */
sdma_channel_reset(channel); /* Reset everything + clear error */
@ -716,7 +718,7 @@ void ata_device_init(void)
ata_dma_selected = ATA_DMA_PIO;
/* Called for first time at startup */
wakeup_init(&ata_dma_wakeup);
semaphore_init(&ata_dma_complete, 1, 0);
if (!sdma_channel_init(ATA_DMA_CH_NUM_RD, &ata_cd_rd, ata_bda) ||
!sdma_channel_init(ATA_DMA_CH_NUM_WR, &ata_cd_wr, ata_bda))

View file

@ -35,7 +35,7 @@ static const unsigned char reg_array[4] =
};
static uint32_t channels[2][4];
static struct wakeup adc_wake;
static struct semaphore adc_done_signal;
static struct mutex adc_mtx;
static long last_adc_read[2]; /* One for each input group */
@ -67,7 +67,7 @@ unsigned short adc_read(int channel)
mc13783_write(MC13783_ADC1, adc1);
/* Wait for done signal */
wakeup_wait(&adc_wake, TIMEOUT_BLOCK);
semaphore_wait(&adc_done_signal, TIMEOUT_BLOCK);
/* Read all 8 channels that are converted - two channels in each
* word. */
@ -113,12 +113,12 @@ bool adc_enable_channel(int channel, bool enable)
/* Called by mc13783 interrupt thread when conversion is complete */
void adc_done(void)
{
wakeup_signal(&adc_wake);
semaphore_release(&adc_done_signal);
}
void adc_init(void)
{
wakeup_init(&adc_wake);
semaphore_init(&adc_done_signal, 1, 0);
mutex_init(&adc_mtx);
/* Init so first reads get data */

View file

@ -29,7 +29,7 @@
#include "adc.h"
#include "button.h"
static struct wakeup headphone_wakeup;
static struct semaphore headphone_wakeup;
static unsigned int headphone_thread_id;
static int headphone_stack[200/sizeof(int)]; /* Not much stack needed */
static const char * const headphone_thread_name = "headphone";
@ -115,7 +115,7 @@ static void headphone_thread(void)
while (1)
{
int rc = wakeup_wait(&headphone_wakeup, headphone_wait_timeout);
int rc = semaphore_wait(&headphone_wakeup, headphone_wait_timeout);
unsigned int data = adc_read(ADC_HPREMOTE);
if (rc == OBJ_WAIT_TIMEDOUT)
@ -175,7 +175,7 @@ static void headphone_thread(void)
void headphone_detect_event(void)
{
/* Trigger the thread immediately. */
wakeup_signal(&headphone_wakeup);
semaphore_release(&headphone_wakeup);
}
/* Tell if anything is in the jack. */
@ -187,7 +187,7 @@ bool headphones_inserted(void)
void INIT_ATTR headphone_init(void)
{
/* A thread is required to monitor the remote ADC and jack state. */
wakeup_init(&headphone_wakeup);
semaphore_init(&headphone_wakeup, 1, 0);
headphone_thread_id = create_thread(headphone_thread,
headphone_stack,
sizeof(headphone_stack),

View file

@ -48,7 +48,7 @@ static struct i2c_module_descriptor
volatile unsigned short * const base; /* Module base address */
void (* const handler)(void); /* Module interrupt handler */
struct mutex m; /* Node mutual-exclusion */
struct wakeup w; /* I2C done signal */
struct semaphore complete; /* I2C completion signal */
unsigned char *addr_data; /* Additional addressing data */
int addr_count; /* Addressing byte count */
unsigned char *data; /* TX/RX buffer (actual data) */
@ -164,7 +164,7 @@ i2c_stop:
base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
i2c_done:
/* Signal thread we're done */
wakeup_signal(&desc->w);
semaphore_release(&desc->complete);
}
#if (I2C_MODULE_MASK & USE_I2C1_MODULE)
@ -221,7 +221,7 @@ static int i2c_transfer(struct i2c_node * const node,
base[I2DR] = desc->addr;
/* Wait for transfer to complete */
if (wakeup_wait(&desc->w, HZ) == OBJ_WAIT_SUCCEEDED)
if (semaphore_wait(&desc->complete, HZ) == OBJ_WAIT_SUCCEEDED)
{
count -= desc->data_count;
}
@ -294,7 +294,7 @@ void i2c_init(void)
struct i2c_module_descriptor *const desc = &i2c_descs[i];
ccm_module_clock_gating(desc->cg, CGM_ON_RUN_WAIT);
mutex_init(&desc->m);
wakeup_init(&desc->w);
semaphore_init(&desc->complete, 1, 0);
desc->base[I2CR] = 0;
ccm_module_clock_gating(desc->cg, CGM_OFF);
}

View file

@ -32,11 +32,11 @@ extern struct spi_node mc13783_spi;
/* PMIC event service data */
static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)];
static const char *mc13783_thread_name = "pmic";
static struct wakeup mc13783_svc_wake;
static struct semaphore mc13783_svc_wake;
/* Synchronous thread communication objects */
static struct mutex mc13783_spi_mutex;
static struct wakeup mc13783_spi_wake;
static struct semaphore mc13783_spi_complete;
/* Tracking for which interrupts are enabled */
static uint32_t pmic_int_enabled[2] =
@ -69,13 +69,13 @@ static void mc13783_xfer_complete_cb(struct spi_transfer_desc *xfer)
if (xfer->count != 0)
return;
wakeup_signal(&mc13783_spi_wake);
semaphore_release(&mc13783_spi_complete);
}
static inline bool wait_for_transfer_complete(void)
{
return wakeup_wait(&mc13783_spi_wake, HZ*2) == OBJ_WAIT_SUCCEEDED &&
mc13783_transfer.count == 0;
return semaphore_wait(&mc13783_spi_complete, HZ*2)
== OBJ_WAIT_SUCCEEDED && mc13783_transfer.count == 0;
}
static void mc13783_interrupt_thread(void)
@ -89,7 +89,7 @@ static void mc13783_interrupt_thread(void)
{
const struct mc13783_event *event, *event_last;
wakeup_wait(&mc13783_svc_wake, TIMEOUT_BLOCK);
semaphore_wait(&mc13783_svc_wake, TIMEOUT_BLOCK);
if (mc13783_thread_id == 0)
break;
@ -140,16 +140,16 @@ void mc13783_event(void)
/* Mask the interrupt (unmasked when PMIC thread services it). */
bitclr32(&MC13783_GPIO_IMR, 1ul << MC13783_GPIO_LINE);
MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE);
wakeup_signal(&mc13783_svc_wake);
semaphore_release(&mc13783_svc_wake);
}
void INIT_ATTR mc13783_init(void)
{
/* Serial interface must have been initialized first! */
wakeup_init(&mc13783_svc_wake);
semaphore_init(&mc13783_svc_wake, 1, 0);
mutex_init(&mc13783_spi_mutex);
wakeup_init(&mc13783_spi_wake);
semaphore_init(&mc13783_spi_complete, 1, 0);
/* Enable the PMIC SPI module */
spi_enable_module(&mc13783_spi);
@ -175,7 +175,7 @@ void mc13783_close(void)
return;
mc13783_thread_id = 0;
wakeup_signal(&mc13783_svc_wake);
semaphore_release(&mc13783_svc_wake);
thread_wait(thread_id);
spi_disable_module(&mc13783_spi);
}

View file

@ -84,7 +84,7 @@ int int_btn = BUTTON_NONE;
#endif
#if CONFIG_CPU==S5L8701 || CONFIG_CPU==S5L8702
static struct wakeup button_init_wakeup;
static struct semaphore button_init_wakeup;
#endif
#if CONFIG_CPU==S5L8702
@ -273,7 +273,7 @@ static inline int ipod_4g_button_read(void)
btn |= BUTTON_PLAY;
if (status & 0x00100000)
btn |= BUTTON_MENU;
wakeup_signal(&button_init_wakeup);
semaphore_release(&button_init_wakeup);
}
#endif
@ -373,7 +373,7 @@ void s5l_clickwheel_init(void)
void button_init_device(void)
{
wakeup_init(&button_init_wakeup);
semaphore_init(&button_init_wakeup, 1, 0);
#if CONFIG_CPU==S5L8701
INTMSK |= (1<<26);
#elif CONFIG_CPU==S5L8702
@ -381,7 +381,7 @@ void button_init_device(void)
holdswitch_last_value = (pmu_read(0x87) & 2) == 0;
#endif
s5l_clickwheel_init();
wakeup_wait(&button_init_wakeup, HZ / 10);
semaphore_wait(&button_init_wakeup, HZ / 10);
}
bool button_hold(void)

View file

@ -107,7 +107,7 @@ struct
#ifdef HAVE_LCD_SLEEP
bool display_on;
bool waking;
struct wakeup initwakeup;
struct semaphore initwakeup;
#endif
} lcd_state IBSS_ATTR;
@ -188,7 +188,7 @@ static inline unsigned bcm_read32(unsigned address)
static void continue_lcd_awake(void)
{
lcd_state.waking = false;
wakeup_signal(&(lcd_state.initwakeup));
semaphore_release(&(lcd_state.initwakeup));
}
#endif
@ -357,7 +357,7 @@ void lcd_init_device(void)
/* lcd_write_data needs an even number of 16 bit values */
flash_vmcs_length = ((flash_vmcs_length + 3) >> 1) & ~1;
}
wakeup_init(&(lcd_state.initwakeup));
semaphore_init(&(lcd_state.initwakeup), 1, 0);
lcd_state.waking = false;
if (GPO32_VAL & 0x4000)
@ -620,7 +620,7 @@ void lcd_awake(void)
*/
lcd_state.waking = true;
tick_add_task(&lcd_tick);
wakeup_wait(&(lcd_state.initwakeup), TIMEOUT_BLOCK);
semaphore_wait(&(lcd_state.initwakeup), TIMEOUT_BLOCK);
send_event(LCD_EVENT_ACTIVATION, NULL);
}

View file

@ -67,7 +67,7 @@ unsigned char rc_buf[5];
/* Remote thread functions */
/* These functions are private to the remote thread */
/* ================================================== */
static struct wakeup rc_thread_wakeup;
static struct semaphore rc_thread_wakeup;
static unsigned int remote_thread_id;
static int remote_stack[256/sizeof(int)];
static const char * const remote_thread_name = "remote";
@ -368,7 +368,7 @@ static void remote_thread(void)
while (1)
{
wakeup_wait(&rc_thread_wakeup, rc_thread_wait_timeout);
semaphore_wait(&rc_thread_wakeup, rc_thread_wait_timeout);
/* Error handling (most likely due to remote not present) */
if (rc_status & RC_ERROR_MASK)
@ -500,7 +500,7 @@ void lcd_remote_off(void)
{
/* should only be used to power off at shutdown */
rc_status |= RC_POWER_OFF;
wakeup_signal(&rc_thread_wakeup);
semaphore_release(&rc_thread_wakeup);
/* wait until the things are powered off */
while (rc_status & RC_DEV_INIT)
@ -515,7 +515,7 @@ void lcd_remote_on(void)
{
rc_status &= ~RC_FORCE_DETECT;
rc_status &= ~RC_POWER_OFF;
wakeup_signal(&rc_thread_wakeup);
semaphore_release(&rc_thread_wakeup);
}
}
@ -536,7 +536,7 @@ void lcd_remote_init_device(void)
GPIO_SET_BITWISE(GPIOL_OUTPUT_EN, 0x80);
/* a thread is required to poll & update the remote */
wakeup_init(&rc_thread_wakeup);
semaphore_init(&rc_thread_wakeup, 1, 0);
remote_thread_id = create_thread(remote_thread, remote_stack,
sizeof(remote_stack), 0, remote_thread_name
IF_PRIO(, PRIORITY_SYSTEM)

View file

@ -21,7 +21,7 @@
#include "system.h"
#include "i2c-s3c2440.h"
static struct wakeup i2c_wake; /* Transfer completion signal */
static struct semaphore i2c_complete; /* Transfer completion signal */
static struct mutex i2c_mtx; /* Mutual exclusion */
static unsigned char *buf_ptr; /* Next byte to transfer */
static int buf_count; /* Number of bytes remaining to transfer */
@ -64,7 +64,7 @@ void i2c_write(int addr, const unsigned char *buf, int count)
/* Generate START */
IICSTAT = I2C_MODE_MASTER | I2C_MODE_TX | I2C_START | I2C_RXTX_ENB;
if (wakeup_wait(&i2c_wake, HZ) != OBJ_WAIT_SUCCEEDED)
if (semaphore_wait(&i2c_complete, HZ) != OBJ_WAIT_SUCCEEDED)
{
/* Something went wrong - stop transmission */
int oldlevel = disable_irq_save();
@ -84,7 +84,7 @@ void i2c_write(int addr, const unsigned char *buf, int count)
void i2c_init(void)
{
/* Init kernel objects */
wakeup_init(&i2c_wake);
semaphore_init(&i2c_complete, 1, 0);
mutex_init(&i2c_mtx);
/* Clear pending source */
@ -134,7 +134,7 @@ void IIC(void)
i2c_stop();
/* Signal thread */
wakeup_signal(&i2c_wake);
semaphore_release(&i2c_complete);
break;
}

View file

@ -119,7 +119,7 @@ static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
static const char sd_thread_name[] = "sd";
static struct mutex sd_mtx SHAREDBSS_ATTR;
static struct event_queue sd_queue;
static struct wakeup transfer_completion_signal;
static struct semaphore transfer_completion_signal;
static volatile unsigned int transfer_error[NUM_VOLUMES];
/* align on cache line size */
static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
@ -223,7 +223,7 @@ void SDI (void)
dbgprintf ("SDI %x\n", transfer_error[curr_card]);
wakeup_signal(&transfer_completion_signal);
semaphore_release(&transfer_completion_signal);
/* Ack the interrupt */
SRCPND = SDI_MASK;
@ -242,7 +242,7 @@ void dma_callback (void)
SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
dbgprintf ("dma_cb\n");
wakeup_signal(&transfer_completion_signal);
semaphore_release(&transfer_completion_signal);
}
#endif
@ -783,7 +783,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
(9<<4) /* 2^9 = 512 */ ;
#endif
wakeup_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/);
semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/);
/* wait for DMA to finish */
while (DSTAT0 & DSTAT_STAT_BUSY)
@ -928,7 +928,7 @@ int sd_init(void)
sd_enabled = true;
sd_enable(false);
#endif
wakeup_init(&transfer_completion_signal);
semaphore_init(&transfer_completion_signal, 1, 0);
/* init mutex */
mutex_init(&sd_mtx);
queue_init(&sd_queue, true);

View file

@ -42,11 +42,11 @@
static struct mutex adc_mtx;
static struct wakeup adc_wakeup;
static struct semaphore adc_wakeup;
void INT_ADC(void)
{
wakeup_signal(&adc_wakeup);
semaphore_release(&adc_wakeup);
}
unsigned short adc_read(int channel)
@ -61,7 +61,7 @@ unsigned short adc_read(int channel)
(1 << 0); /* enable start */
/* wait for conversion */
wakeup_wait(&adc_wakeup, TIMEOUT_BLOCK);
semaphore_wait(&adc_wakeup, TIMEOUT_BLOCK);
/* get the converted data */
data = ADCDAT0 & 0x3FF;
@ -77,7 +77,7 @@ unsigned short adc_read(int channel)
void adc_init(void)
{
mutex_init(&adc_mtx);
wakeup_init(&adc_wakeup);
semaphore_init(&adc_wakeup, 1, 0);
/* enable clock to ADC */
PWRCON &= ~(1 << 10);

View file

@ -94,9 +94,9 @@ static long nand_last_activity_value = -1;
static long nand_stack[DEFAULT_STACK_SIZE];
static struct mutex nand_mtx;
static struct wakeup nand_wakeup;
static struct semaphore nand_complete;
static struct mutex ecc_mtx;
static struct wakeup ecc_wakeup;
static struct semaphore ecc_complete;
static uint8_t nand_data[0x800] STORAGE_ALIGN_ATTR;
static uint8_t nand_ctrl[0x200] STORAGE_ALIGN_ATTR;
@ -731,9 +731,9 @@ static void nand_thread(void)
int nand_device_init(void)
{
mutex_init(&nand_mtx);
wakeup_init(&nand_wakeup);
semaphore_init(&nand_complete, 1, 0);
mutex_init(&ecc_mtx);
wakeup_init(&ecc_wakeup);
semaphore_init(&ecc_complete, 1, 0);
uint32_t type;
uint32_t i, j;

View file

@ -50,7 +50,7 @@
int lcd_type; /* also needed in debug-s5l8702.c */
static struct dma_lli lcd_lli[(LCD_WIDTH * LCD_HEIGHT - 1) / 0xfff] CACHEALIGN_ATTR;
static struct wakeup lcd_wakeup;
static struct semaphore lcd_wakeup;
static struct mutex lcd_mutex;
static uint16_t lcd_dblbuf[LCD_HEIGHT][LCD_WIDTH];
@ -149,7 +149,7 @@ void lcd_sleep(void)
void lcd_init_device(void)
{
/* Detect lcd type */
wakeup_init(&lcd_wakeup);
semaphore_init(&lcd_wakeup, 1, 0);
mutex_init(&lcd_mutex);
lcd_type = (PDAT6 & 0x30) >> 4;
}
@ -180,7 +180,7 @@ static void displaylcd_setup(int x, int y, int width, int height) ICODE_ATTR;
static void displaylcd_setup(int x, int y, int width, int height)
{
mutex_lock(&lcd_mutex);
while (DMAC0C4CONFIG & 1) wakeup_wait(&lcd_wakeup, HZ / 10);
while (DMAC0C4CONFIG & 1) semaphore_wait(&lcd_wakeup, HZ / 10);
int xe = (x + width) - 1; /* max horiz */
int ye = (y + height) - 1; /* max vert */
@ -237,7 +237,7 @@ void INT_DMAC0C4(void) ICODE_ATTR;
void INT_DMAC0C4(void)
{
DMAC0INTTCCLR = 0x10;
wakeup_signal(&lcd_wakeup);
semaphore_release(&lcd_wakeup);
}
/* Update a fraction of the display. */

View file

@ -53,7 +53,7 @@ bool ata_lba48;
bool ata_dma;
uint64_t ata_total_sectors;
struct mutex ata_mutex;
static struct wakeup ata_wakeup;
static struct semaphore ata_wakeup;
static uint32_t ata_dma_flags;
static long ata_last_activity_value = -1;
static long ata_sleep_timeout = 20 * HZ;
@ -61,8 +61,8 @@ static uint32_t ata_stack[(DEFAULT_STACK_SIZE + 0x400) / 4];
static bool ata_powered;
static const int ata_retries = ATA_RETRIES;
static const bool ata_error_srst = true;
static struct wakeup mmc_wakeup;
static struct wakeup mmc_comp_wakeup;
static struct semaphore mmc_wakeup;
static struct semaphore mmc_comp_wakeup;
static int spinup_time = 0;
static int dma_mode = 0;
@ -319,7 +319,7 @@ void mmc_discard_irq(void)
{
SDCI_IRQ = SDCI_IRQ_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT
| SDCI_IRQ_MASK_MASK_READ_WAIT_INT;
wakeup_wait(&mmc_wakeup, 0);
semaphore_wait(&mmc_wakeup, 0);
}
int 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)
| MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
| MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
NULL, CEATA_COMMAND_TIMEOUT), 2, 1);
if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000)
== OBJ_WAIT_TIMEDOUT) RET_ERR(2);
PASS_RC(mmc_dsta_check_data_success(), 2, 3);
return 0;
}
@ -362,7 +363,8 @@ int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size)
SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i];
long startusec = USEC_TIMER;
if (wakeup_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT) RET_ERR(2);
if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000)
== OBJ_WAIT_TIMEDOUT) RET_ERR(2);
while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE)
{
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)
direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count),
NULL, CEATA_COMMAND_TIMEOUT), 4, 0);
if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
if (wakeup_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
{
PASS_RC(ceata_cancel_command(), 4, 1);
RET_ERR(2);
}
PASS_RC(mmc_dsta_check_data_success(), 4, 3);
if (wakeup_wait(&mmc_comp_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
if (semaphore_wait(&mmc_comp_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
{
PASS_RC(ceata_cancel_command(), 4, 4);
RET_ERR(4);
@ -750,11 +752,12 @@ int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bool writ
ATA_XFR_NUM = SECTOR_SIZE * cnt - 1;
ATA_CFG |= ata_dma_flags;
ATA_CFG &= ~(BIT(7) | BIT(8));
wakeup_wait(&ata_wakeup, 0);
semaphore_wait(&ata_wakeup, 0);
ATA_IRQ = BITRANGE(0, 4);
ATA_IRQ_MASK = BIT(0);
ATA_COMMAND = BIT(0);
if (wakeup_wait(&ata_wakeup, 500000 * HZ / 1000000) == OBJ_WAIT_TIMEDOUT)
if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000)
== OBJ_WAIT_TIMEDOUT)
{
ATA_COMMAND = BIT(1);
ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
@ -1068,9 +1071,9 @@ void ata_bbt_reload(void)
int ata_init(void)
{
mutex_init(&ata_mutex);
wakeup_init(&ata_wakeup);
wakeup_init(&mmc_wakeup);
wakeup_init(&mmc_comp_wakeup);
semaphore_init(&ata_wakeup, 1, 0);
semaphore_init(&mmc_wakeup, 1, 0);
semaphore_init(&mmc_comp_wakeup, 1, 0);
ceata = PDAT(11) & BIT(1);
if (ceata)
{
@ -1129,14 +1132,14 @@ void INT_ATA(void)
{
uint32_t ata_irq = ATA_IRQ;
ATA_IRQ = ata_irq;
if (ata_irq & ATA_IRQ_MASK) wakeup_signal(&ata_wakeup);
if (ata_irq & ATA_IRQ_MASK) semaphore_release(&ata_wakeup);
ATA_IRQ_MASK = 0;
}
void INT_MMC(void)
{
uint32_t irq = SDCI_IRQ;
if (irq & SDCI_IRQ_DAT_DONE_INT) wakeup_signal(&mmc_wakeup);
if (irq & SDCI_IRQ_IOCARD_IRQ_INT) wakeup_signal(&mmc_comp_wakeup);
if (irq & SDCI_IRQ_DAT_DONE_INT) semaphore_release(&mmc_wakeup);
if (irq & SDCI_IRQ_IOCARD_IRQ_INT) semaphore_release(&mmc_comp_wakeup);
SDCI_IRQ = irq;
}

View file

@ -62,6 +62,21 @@ void __div0(void);
#define enable_fiq() \
enable_interrupt(FIQ_STATUS)
#define irq_enabled() \
interrupt_enabled(IRQ_STATUS)
#define fiq_enabled() \
interrupt_enabled(FIQ_STATUS)
#define ints_enabled() \
interrupt_enabled(IRQ_FIQ_STATUS)
#define irq_enabled_checkval(val) \
(((val) & IRQ_STATUS) == 0)
#define fiq_enabled_checkval(val) \
(((val) & FIQ_STATUS) == 0)
#define ints_enabled_checkval(val) \
(((val) & IRQ_FIQ_STATUS) == 0)
/* Core-level interrupt masking */
static inline int set_interrupt_status(int status, int mask)
@ -87,6 +102,13 @@ static inline void restore_interrupt(int cpsr)
asm volatile ("msr cpsr_c, %0" : : "r"(cpsr));
}
static inline bool interrupt_enabled(int status)
{
unsigned long cpsr;
asm ("mrs %0, cpsr" : "=r"(cpsr));
return (cpsr & status) == 0;
}
/* ARM_ARCH version section for architecture*/
#if ARM_ARCH >= 6

View file

@ -37,14 +37,14 @@
#define CF_START 0x40000000
#define SSFDC_START 0x48000000
static struct wakeup transfer_completion_signal;
static struct semaphore transfer_completion_signal;
static bool dma_in_progress = false;
void MTC0(void)
{
IO_INTC_IRQ1 = INTR_IRQ1_MTC0;
wakeup_signal(&transfer_completion_signal);
semaphore_release(&transfer_completion_signal);
dma_in_progress = false;
}
@ -59,7 +59,7 @@ void dma_start(const void* addr, size_t size)
void dma_ata_read(unsigned char* buf, int shortcount)
{
if(dma_in_progress)
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
while((unsigned long)buf & 0x1F)
{
@ -83,7 +83,7 @@ void dma_ata_read(unsigned char* buf, int shortcount)
IO_EMIF_DMACTL = 3; /* Select MTC->AHB and start transfer */
dma_in_progress = true;
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
if(shortcount % 2)
{
@ -97,7 +97,7 @@ void dma_ata_read(unsigned char* buf, int shortcount)
void dma_ata_write(unsigned char* buf, int wordcount)
{
if(dma_in_progress)
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
while((unsigned long)buf & 0x1F)
{
@ -121,12 +121,12 @@ void dma_ata_write(unsigned char* buf, int wordcount)
IO_EMIF_DMACTL = 1; /* Select AHB->MTC and start transfer */
dma_in_progress = true;
wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
}
void dma_init(void)
{
IO_INTC_EINT1 |= INTR_EINT1_MTC0; /* enable MTC interrupt */
wakeup_init(&transfer_completion_signal);
semaphore_init(&transfer_completion_signal, 1, 0);
dma_in_progress = false;
}

View file

@ -349,7 +349,7 @@ struct queue_head {
static struct queue_head qh_array[USB_NUM_ENDPOINTS*2]
USB_QHARRAY_ATTR;
static struct wakeup transfer_completion_signal[USB_NUM_ENDPOINTS*2]
static struct semaphore transfer_completion_signal[USB_NUM_ENDPOINTS*2]
SHAREDBSS_ATTR;
static const unsigned int pipe2mask[] = {
@ -424,7 +424,7 @@ void usb_drv_startup(void)
/* Initialize all the signal objects once */
int i;
for(i=0;i<USB_NUM_ENDPOINTS*2;i++) {
wakeup_init(&transfer_completion_signal[i]);
semaphore_init(&transfer_completion_signal[i], 1, 0);
}
}
@ -778,7 +778,7 @@ static int prime_transfer(int ep_num, void* ptr, int len, bool send, bool wait)
if (wait) {
/* wait for transfer to finish */
wakeup_wait(&transfer_completion_signal[pipe], TIMEOUT_BLOCK);
semaphore_wait(&transfer_completion_signal[pipe], TIMEOUT_BLOCK);
if(qh->status!=0) {
/* No need to cancel wait here since it was done and the signal
* came. */
@ -797,7 +797,7 @@ pt_error:
qh->wait = 0;
/* Make sure to remove any signal if interrupt fired before we zeroed
* qh->wait. Could happen during a bus reset for example. */
wakeup_wait(&transfer_completion_signal[pipe], TIMEOUT_NOBLOCK);
semaphore_wait(&transfer_completion_signal[pipe], TIMEOUT_NOBLOCK);
}
return rc;
@ -814,7 +814,7 @@ void usb_drv_cancel_all_transfers(void)
if(qh_array[i].wait) {
qh_array[i].wait=0;
qh_array[i].status=DTD_STATUS_HALTED;
wakeup_signal(&transfer_completion_signal[i]);
semaphore_release(&transfer_completion_signal[i]);
}
}
}
@ -906,7 +906,7 @@ static void control_received(void)
if(qh_array[i].wait) {
qh_array[i].wait=0;
qh_array[i].status=DTD_STATUS_HALTED;
wakeup_signal(&transfer_completion_signal[i]);
semaphore_release(&transfer_completion_signal[i]);
}
}
@ -945,7 +945,7 @@ static void transfer_completed(void)
}
if(qh->wait) {
qh->wait=0;
wakeup_signal(&transfer_completion_signal[pipe]);
semaphore_release(&transfer_completion_signal[pipe]);
}
usb_core_transfer_complete(ep, dir?USB_DIR_IN:USB_DIR_OUT,

View file

@ -44,7 +44,7 @@ struct ep_type
bool done;
int rc;
int size;
struct wakeup complete;
struct semaphore complete;
} ;
static struct ep_type endpoints[USB_NUM_ENDPOINTS];
@ -64,7 +64,7 @@ static void reset_endpoints(int reinit)
endpoints[i].busy = false;
endpoints[i].rc = -1;
endpoints[i].done = true;
wakeup_signal(&endpoints[i].complete);
semaphore_release(&endpoints[i].complete);
}
DIEPCTL0 = 0x8800; /* EP0 IN ACTIVE NEXT=1 */
DOEPCTL0 = 0x8000; /* EP0 OUT ACTIVE */
@ -201,7 +201,7 @@ void INT_USB_FUNC(void)
endpoints[i].rc = 0;
endpoints[i].done = true;
usb_core_transfer_complete(i, USB_DIR_IN, 0, bytes);
wakeup_signal(&endpoints[i].complete);
semaphore_release(&endpoints[i].complete);
}
}
if (epints & 4) /* AHB error */
@ -213,7 +213,7 @@ void INT_USB_FUNC(void)
endpoints[i].busy = false;
endpoints[i].rc = 1;
endpoints[i].done = true;
wakeup_signal(&endpoints[i].complete);
semaphore_release(&endpoints[i].complete);
}
}
DIEPINT(i) = epints;
@ -233,7 +233,7 @@ void INT_USB_FUNC(void)
endpoints[i].rc = 0;
endpoints[i].done = true;
usb_core_transfer_complete(i, USB_DIR_OUT, 0, bytes);
wakeup_signal(&endpoints[i].complete);
semaphore_release(&endpoints[i].complete);
}
}
if (epints & 4) /* AHB error */
@ -325,7 +325,7 @@ int usb_drv_send(int endpoint, void *ptr, int length)
endpoints[endpoint].done = false;
ep_send(endpoint, ptr, length);
while (!endpoints[endpoint].done && endpoints[endpoint].busy)
wakeup_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK);
semaphore_wait(&endpoints[endpoint].complete, TIMEOUT_BLOCK);
return endpoints[endpoint].rc;
}
@ -412,7 +412,7 @@ void usb_init_device(void)
{
unsigned int i;
for (i = 0; i < sizeof(endpoints)/sizeof(struct ep_type); i++)
wakeup_init(&endpoints[i].complete);
semaphore_init(&endpoints[i].complete, 1, 0);
/* Power up the core clocks to allow writing
to some registers needed to power it down */

View file

@ -117,7 +117,7 @@ static struct nand_param internal_param;
static struct mutex nand_mtx;
#ifdef USE_DMA
static struct mutex nand_dma_mtx;
static struct wakeup nand_wkup;
static struct semaphore nand_dma_complete;
#endif
static unsigned char temp_page[4096]; /* Max page size */
@ -170,7 +170,7 @@ static void jz_nand_write_dma(void *source, unsigned int len, int bw)
yield();
#else
REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
wakeup_wait(&nand_wkup, TIMEOUT_BLOCK);
semaphore_wait(&nand_dma_complete, TIMEOUT_BLOCK);
#endif
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)
yield();
#else
REG_DMAC_DCMD(DMA_NAND_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
wakeup_wait(&nand_wkup, TIMEOUT_BLOCK);
semaphore_wait(&nand_dma_complete, TIMEOUT_BLOCK);
#endif
//REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
@ -226,7 +226,7 @@ void DMA_CALLBACK(DMA_NAND_CHANNEL)(void)
if (REG_DMAC_DCCSR(DMA_NAND_CHANNEL) & DMAC_DCCSR_TT)
REG_DMAC_DCCSR(DMA_NAND_CHANNEL) &= ~DMAC_DCCSR_TT;
wakeup_signal(&nand_wkup);
semaphore_release(&nand_dma_complete);
}
#endif /* USE_DMA */
@ -603,7 +603,7 @@ int nand_init(void)
mutex_init(&nand_mtx);
#ifdef USE_DMA
mutex_init(&nand_dma_mtx);
wakeup_init(&nand_wkup);
semaphore_init(&nand_dma_complete, 1, 0);
system_enable_irq(DMA_IRQ(DMA_NAND_CHANNEL));
#endif

View file

@ -47,7 +47,7 @@ static long sd_stack[(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
static const char sd_thread_name[] = "ata/sd";
static struct event_queue sd_queue;
static struct mutex sd_mtx;
static struct wakeup sd_wakeup;
static struct semaphore sd_wakeup;
static void sd_thread(void) NORETURN_ATTR;
static int use_4bit;
@ -831,7 +831,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
/* Wait for command completion */
//__intc_unmask_irq(IRQ_MSC);
//wakeup_wait(&sd_wakeup, 100);
//semaphore_wait(&sd_wakeup, 100);
while (timeout-- && !(REG_MSC_STAT & MSC_STAT_END_CMD_RES));
@ -881,7 +881,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
#endif
}
//__intc_unmask_irq(IRQ_MSC);
//wakeup_wait(&sd_wakeup, 100);
//semaphore_wait(&sd_wakeup, 100);
/* Wait for Data Done */
while (!(REG_MSC_IREG & MSC_IREG_DATA_TRAN_DONE));
REG_MSC_IREG = MSC_IREG_DATA_TRAN_DONE; /* clear status */
@ -891,7 +891,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
if (events & SD_EVENT_PROG_DONE)
{
//__intc_unmask_irq(IRQ_MSC);
//wakeup_wait(&sd_wakeup, 100);
//semaphore_wait(&sd_wakeup, 100);
while (!(REG_MSC_IREG & MSC_IREG_PRG_DONE));
REG_MSC_IREG = MSC_IREG_PRG_DONE; /* clear status */
}
@ -945,7 +945,7 @@ static void jz_sd_rx_handler(unsigned int arg)
/* MSC interrupt handler */
void MSC(void)
{
//wakeup_signal(&sd_wakeup);
//semaphore_release(&sd_wakeup);
logf("MSC interrupt");
}
@ -1228,7 +1228,7 @@ int sd_init(void)
static bool inited = false;
if(!inited)
{
wakeup_init(&sd_wakeup);
semaphore_init(&sd_wakeup, 1, 0);
mutex_init(&sd_mtx);
queue_init(&sd_queue, true);
create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,

View file

@ -34,7 +34,7 @@
static volatile bool lcd_is_on = false;
static struct mutex lcd_mtx;
static struct wakeup lcd_wkup;
static struct semaphore lcd_wkup;
static int lcd_count = 0;
void lcd_clock_enable(void)
@ -56,7 +56,7 @@ void lcd_init_device(void)
lcd_is_on = true;
mutex_init(&lcd_mtx);
wakeup_init(&lcd_wkup);
semaphore_init(&lcd_wkup, 1, 0);
system_enable_irq(DMA_IRQ(DMA_LCD_CHANNEL));
}
@ -118,7 +118,7 @@ void lcd_update_rect(int x, int y, int width, int height)
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) |= DMAC_DCCSR_EN; /* Enable DMA channel */
REG_DMAC_DCMD(DMA_LCD_CHANNEL) |= DMAC_DCMD_TIE; /* Enable DMA interrupt */
wakeup_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */
semaphore_wait(&lcd_wkup, TIMEOUT_BLOCK); /* Sleeping in lcd_update() should be safe */
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_EN; /* Disable DMA channel */
dma_disable();
@ -145,7 +145,7 @@ void DMA_CALLBACK(DMA_LCD_CHANNEL)(void)
if (REG_DMAC_DCCSR(DMA_LCD_CHANNEL) & DMAC_DCCSR_TT)
REG_DMAC_DCCSR(DMA_LCD_CHANNEL) &= ~DMAC_DCCSR_TT;
wakeup_signal(&lcd_wkup);
semaphore_release(&lcd_wkup);
}
/* Update the display.

View file

@ -74,7 +74,7 @@ static int datacount = 0;
static volatile int cur_touch = 0;
static volatile bool pen_down = false;
static struct mutex battery_mtx;
static struct wakeup battery_wkup;
static struct semaphore battery_done;
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
@ -113,7 +113,7 @@ unsigned int battery_adc_voltage(void)
REG_SADC_ENA |= SADC_ENA_PBATEN;
wakeup_wait(&battery_wkup, HZ/4);
semaphore_wait(&battery_done, HZ/4);
bat_val = REG_SADC_BATDAT;
logf("%d %d", bat_val, (bat_val * BATTERY_SCALE_FACTOR) / 4096);
@ -268,7 +268,7 @@ void SADC(void)
if(state & SADC_CTRL_PBATRDYM)
{
/* Battery AD IRQ */
wakeup_signal(&battery_wkup);
semaphore_release(&battery_done);
}
}
@ -290,7 +290,7 @@ void adc_init(void)
REG_SADC_ENA = SADC_ENA_TSEN;
mutex_init(&battery_mtx);
wakeup_init(&battery_wkup);
semaphore_init(&battery_done, 1, 0);
}
void adc_close(void)

View file

@ -69,7 +69,7 @@ struct usb_endpoint
unsigned short fifo_size;
bool wait;
struct wakeup wakeup;
struct semaphore complete;
};
static unsigned char ep0_rx_buf[64];
@ -171,7 +171,7 @@ static inline void ep_transfer_completed(struct usb_endpoint* ep)
ep->buf = NULL;
ep->busy = false;
if(ep->wait)
wakeup_signal(&ep->wakeup);
semaphore_release(&ep->complete);
}
static void EP0_send(void)
@ -598,7 +598,7 @@ void usb_init_device(void)
system_enable_irq(IRQ_UDC);
for(i=0; i<TOTAL_EP(); i++)
wakeup_init(&endpoints[i].wakeup);
semaphore_init(&endpoints[i].complete, 1, 0);
}
#ifdef USB_GPIO_IRQ
@ -715,7 +715,7 @@ static void usb_drv_send_internal(struct usb_endpoint* ep, void* ptr, int length
if(blocking)
{
wakeup_wait(&ep->wakeup, TIMEOUT_BLOCK);
semaphore_wait(&ep->complete, TIMEOUT_BLOCK);
ep->wait = false;
}
}