diff options
Diffstat (limited to 'drivers/staging/tidspbridge/core/sync.c')
-rw-r--r-- | drivers/staging/tidspbridge/core/sync.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/drivers/staging/tidspbridge/core/sync.c b/drivers/staging/tidspbridge/core/sync.c new file mode 100644 index 0000000..995986a --- /dev/null +++ b/drivers/staging/tidspbridge/core/sync.c @@ -0,0 +1,121 @@ +/* + * sync.c + * + * DSP-BIOS Bridge driver support functions for TI OMAP processors. + * + * Synchronization services. + * + * Copyright (C) 2005-2006 Texas Instruments, Inc. + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* ----------------------------------- Host OS */ +#include <dspbridge/host_os.h> + +/* ----------------------------------- This */ +#include <dspbridge/sync.h> +#include <dspbridge/ntfy.h> + +DEFINE_SPINLOCK(sync_lock); + +/** + * sync_set_event() - set or signal and specified event + * @event: Event to be set.. + * + * set the @event, if there is an thread waiting for the event + * it will be waken up, this function only wakes one thread. + */ + +void sync_set_event(struct sync_object *event) +{ + spin_lock_bh(&sync_lock); + complete(&event->comp); + if (event->multi_comp) + complete(event->multi_comp); + spin_unlock_bh(&sync_lock); +} + +/** + * sync_wait_on_multiple_events() - waits for multiple events to be set. + * @events: Array of events to wait for them. + * @count: number of elements of the array. + * @timeout timeout on waiting for the evetns. + * @pu_index index of the event set. + * + * This functios will wait until any of the array element is set or until + * timeout. In case of success the function will return 0 and + * @pu_index will store the index of the array element set or in case + * of timeout the function will return -ETIME or in case of + * interrupting by a signal it will return -EPERM. + */ + +int sync_wait_on_multiple_events(struct sync_object **events, + unsigned count, unsigned timeout, + unsigned *index) +{ + unsigned i; + int status = -EPERM; + struct completion m_comp; + + init_completion(&m_comp); + + if (SYNC_INFINITE == timeout) + timeout = MAX_SCHEDULE_TIMEOUT; + + spin_lock_bh(&sync_lock); + for (i = 0; i < count; i++) { + if (completion_done(&events[i]->comp)) { + INIT_COMPLETION(events[i]->comp); + *index = i; + spin_unlock_bh(&sync_lock); + status = 0; + goto func_end; + } + } + + for (i = 0; i < count; i++) + events[i]->multi_comp = &m_comp; + + spin_unlock_bh(&sync_lock); + + if (!wait_for_completion_interruptible_timeout(&m_comp, + msecs_to_jiffies(timeout))) + status = -ETIME; + + spin_lock_bh(&sync_lock); + for (i = 0; i < count; i++) { + if (completion_done(&events[i]->comp)) { + INIT_COMPLETION(events[i]->comp); + *index = i; + status = 0; + } + events[i]->multi_comp = NULL; + } + spin_unlock_bh(&sync_lock); +func_end: + return status; +} + +/** + * dsp_notifier_event() - callback function to nofity events + * @this: pointer to itself struct notifier_block + * @event: event to be notified. + * @data: Currently not used. + * + */ +int dsp_notifier_event(struct notifier_block *this, unsigned long event, + void *data) +{ + struct ntfy_event *ne = container_of(this, struct ntfy_event, + noti_block); + if (ne->event & event) + sync_set_event(&ne->sync_obj); + return NOTIFY_OK; +} |