tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / sipc / simple_events.h
1 /*
2  * Copyright (C) 2014 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #ifndef _SIMPLE_EVENTS_H_
15 #define _SIMPLE_EVENTS_H_
16
17 #include <linux/wait.h>
18
19
20
21 struct __simple_event {
22         spinlock_t lock;
23         wait_queue_head_t wq;
24         unsigned int flags;
25         
26 };
27
28 typedef struct __simple_event simple_event_t;
29
30
31 static inline void simple_evnet_init(simple_event_t* evt)
32 {
33         spin_lock_init(&evt->lock);
34         init_waitqueue_head(&evt->wq);
35         evt->flags = 0;
36 }
37
38 static inline int simple_evnet_get(simple_event_t* evt, unsigned int req_flags,
39         unsigned int *actual_flags)
40 {
41         unsigned long flags;
42                 
43         if(!evt) return -1;
44
45         *actual_flags = 0;
46
47         while(!(*actual_flags)) {
48                 wait_event(evt->wq, (evt->flags & req_flags));
49                   
50                 spin_lock_irqsave(&evt->lock, flags);
51                 *actual_flags = evt->flags & req_flags;
52                 evt->flags &= ~req_flags;
53                 spin_unlock_irqrestore(&evt->lock, flags);
54         }
55         
56         return 0;
57 }
58
59
60 static inline int simple_evnet_set(simple_event_t* evt, unsigned int flags, 
61         int opt_and)
62 {
63         unsigned long irq_flags;
64         int need_wake = 0;
65         
66         if(!evt) return -1;
67
68         spin_lock_irqsave(&evt->lock, irq_flags);
69         if(!opt_and) {
70                 evt->flags |= flags;
71         } else {
72                 evt->flags &= flags;
73         }
74
75         if(evt->flags) {
76                 need_wake = 1;
77         }
78         spin_unlock_irqrestore(&evt->lock, irq_flags);
79
80         if(need_wake) {
81                 wake_up(&evt->wq);
82         }
83         
84         return 0;
85 }
86
87
88 #endif /* !_SIMPLE_EVENTS_H_ */
89