• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/tidspbridge/services/
1/*
2 * sync.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Synchronization services.
7 *
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19/*  ----------------------------------- Host OS */
20#include <dspbridge/host_os.h>
21
22/*  ----------------------------------- This */
23#include <dspbridge/sync.h>
24
25DEFINE_SPINLOCK(sync_lock);
26
27/**
28 * sync_set_event() - set or signal and specified event
29 * @event:	Event to be set..
30 *
31 * set the @event, if there is an thread waiting for the event
32 * it will be waken up, this function only wakes one thread.
33 */
34
35void sync_set_event(struct sync_object *event)
36{
37	spin_lock_bh(&sync_lock);
38	complete(&event->comp);
39	if (event->multi_comp)
40		complete(event->multi_comp);
41	spin_unlock_bh(&sync_lock);
42}
43
44/**
45 * sync_wait_on_multiple_events() - waits for multiple events to be set.
46 * @events:	Array of events to wait for them.
47 * @count:	number of elements of the array.
48 * @timeout	timeout on waiting for the evetns.
49 * @pu_index	index of the event set.
50 *
51 * This functios will wait until any of the array element is set or until
52 * timeout. In case of success the function will return 0 and
53 * @pu_index will store the index of the array element set or in case
54 * of timeout the function will return -ETIME or in case of
55 * interrupting by a signal it will return -EPERM.
56 */
57
58int sync_wait_on_multiple_events(struct sync_object **events,
59				     unsigned count, unsigned timeout,
60				     unsigned *index)
61{
62	unsigned i;
63	int status = -EPERM;
64	struct completion m_comp;
65
66	init_completion(&m_comp);
67
68	if (SYNC_INFINITE == timeout)
69		timeout = MAX_SCHEDULE_TIMEOUT;
70
71	spin_lock_bh(&sync_lock);
72	for (i = 0; i < count; i++) {
73		if (completion_done(&events[i]->comp)) {
74			INIT_COMPLETION(events[i]->comp);
75			*index = i;
76			spin_unlock_bh(&sync_lock);
77			status = 0;
78			goto func_end;
79		}
80	}
81
82	for (i = 0; i < count; i++)
83		events[i]->multi_comp = &m_comp;
84
85	spin_unlock_bh(&sync_lock);
86
87	if (!wait_for_completion_interruptible_timeout(&m_comp,
88					msecs_to_jiffies(timeout)))
89		status = -ETIME;
90
91	spin_lock_bh(&sync_lock);
92	for (i = 0; i < count; i++) {
93		if (completion_done(&events[i]->comp)) {
94			INIT_COMPLETION(events[i]->comp);
95			*index = i;
96			status = 0;
97		}
98		events[i]->multi_comp = NULL;
99	}
100	spin_unlock_bh(&sync_lock);
101func_end:
102	return status;
103}
104