]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - drivers/staging/tidspbridge/include/dspbridge/ntfy.h
Initial 2.6.37
[mcf548x/linux.git] / drivers / staging / tidspbridge / include / dspbridge / ntfy.h
1 /*
2  * ntfy.h
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * Manage lists of notification events.
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 #ifndef NTFY_
20 #define NTFY_
21
22 #include <dspbridge/host_os.h>
23 #include <dspbridge/dbdefs.h>
24 #include <dspbridge/sync.h>
25
26 /**
27  * ntfy_object - head structure to nofify dspbridge events
28  * @head:       List of notify objects
29  * @ntfy_lock:  lock for list access.
30  *
31  */
32 struct ntfy_object {
33         struct raw_notifier_head head;/* List of notifier objects */
34         spinlock_t ntfy_lock;   /* For critical sections */
35 };
36
37 /**
38  * ntfy_event - structure store specify event to be notified
39  * @noti_block: List of notify objects
40  * @event:      event that it respond
41  * @type:       event type (only DSP_SIGNALEVENT supported)
42  * @sync_obj:   sync_event used to set the event
43  *
44  */
45 struct ntfy_event {
46         struct notifier_block noti_block;
47         u32 event;      /* Events to be notified about */
48         u32 type;       /* Type of notification to be sent */
49         struct sync_object sync_obj;
50 };
51
52
53 /**
54  * dsp_notifier_event() - callback function to nofity events
55  * @this:               pointer to itself struct notifier_block
56  * @event:      event to be notified.
57  * @data:               Currently not used.
58  *
59  */
60 int dsp_notifier_event(struct notifier_block *this, unsigned long event,
61                            void *data);
62
63 /**
64  * ntfy_init() - Set the initial state of the ntfy_object structure.
65  * @no:         pointer to ntfy_object structure.
66  *
67  * This function sets the initial state of the ntfy_object in order it
68  * can be used by the other ntfy functions.
69  */
70
71 static inline void ntfy_init(struct ntfy_object *no)
72 {
73         spin_lock_init(&no->ntfy_lock);
74         RAW_INIT_NOTIFIER_HEAD(&no->head);
75 }
76
77 /**
78  * ntfy_delete() - delete list of nofy events registered.
79  * @ntfy_obj:   Pointer to the ntfy object structure.
80  *
81  * This function is used to remove all the notify events  registered.
82  * unregister function is not needed in this function, to unregister
83  * a ntfy_event please look at ntfy_register function.
84  *
85  */
86 static inline void ntfy_delete(struct ntfy_object *ntfy_obj)
87 {
88         struct ntfy_event *ne;
89         struct notifier_block *nb;
90
91         spin_lock_bh(&ntfy_obj->ntfy_lock);
92         nb = ntfy_obj->head.head;
93         while (nb) {
94                 ne = container_of(nb, struct ntfy_event, noti_block);
95                 nb = nb->next;
96                 kfree(ne);
97         }
98         spin_unlock_bh(&ntfy_obj->ntfy_lock);
99 }
100
101 /**
102  * ntfy_notify() - nofity all event register for an specific event.
103  * @ntfy_obj:   Pointer to the ntfy_object structure.
104  * @event:      event to be notified.
105  *
106  * This function traverses all the ntfy events registers and
107  * set the event with mach with @event.
108  */
109 static inline void ntfy_notify(struct ntfy_object *ntfy_obj, u32 event)
110 {
111         spin_lock_bh(&ntfy_obj->ntfy_lock);
112         raw_notifier_call_chain(&ntfy_obj->head, event, NULL);
113         spin_unlock_bh(&ntfy_obj->ntfy_lock);
114 }
115
116
117
118 /**
119  * ntfy_init() - Create and initialize a ntfy_event structure.
120  * @event:      event that the ntfy event will respond
121  * @type                event type (only DSP_SIGNALEVENT supported)
122  *
123  * This function create a ntfy_event element and sets the event it will
124  * respond the ntfy_event in order it can be used by the other ntfy functions.
125  * In case of success it will return a pointer to the ntfy_event struct
126  * created. Otherwise it will return NULL;
127  */
128
129 static inline struct ntfy_event *ntfy_event_create(u32 event, u32 type)
130 {
131         struct ntfy_event *ne;
132         ne = kmalloc(sizeof(struct ntfy_event), GFP_KERNEL);
133         if (ne) {
134                 sync_init_event(&ne->sync_obj);
135                 ne->noti_block.notifier_call = dsp_notifier_event;
136                 ne->event = event;
137                 ne->type = type;
138         }
139         return ne;
140 }
141
142 /**
143  * ntfy_register() - register new ntfy_event into a given ntfy_object
144  * @ntfy_obj:   Pointer to the ntfy_object structure.
145  * @noti:               Pointer to the handle to be returned to the user space.
146  * @event       event that the ntfy event will respond
147  * @type                event type (only DSP_SIGNALEVENT supported)
148  *
149  * This function register a new ntfy_event into the ntfy_object list,
150  * which will respond to the @event passed.
151  * This function will return 0 in case of error.
152  * -EFAULT in case of bad pointers and
153  * DSP_EMemory in case of no memory to create ntfy_event.
154  */
155 static  inline int ntfy_register(struct ntfy_object *ntfy_obj,
156                          struct dsp_notification *noti,
157                          u32 event, u32 type)
158 {
159         struct ntfy_event *ne;
160         int status = 0;
161
162         if (!noti || !ntfy_obj) {
163                 status = -EFAULT;
164                 goto func_end;
165         }
166         if (!event) {
167                 status = -EINVAL;
168                 goto func_end;
169         }
170         ne = ntfy_event_create(event, type);
171         if (!ne) {
172                 status = -ENOMEM;
173                 goto func_end;
174         }
175         noti->handle = &ne->sync_obj;
176
177         spin_lock_bh(&ntfy_obj->ntfy_lock);
178         raw_notifier_chain_register(&ntfy_obj->head, &ne->noti_block);
179         spin_unlock_bh(&ntfy_obj->ntfy_lock);
180 func_end:
181         return status;
182 }
183
184 /**
185  * ntfy_unregister() - unregister a ntfy_event from a given ntfy_object
186  * @ntfy_obj:   Pointer to the ntfy_object structure.
187  * @noti:               Pointer to the event that will be removed.
188  *
189  * This function unregister a ntfy_event from the ntfy_object list,
190  * @noti contains the event which is wanted to be removed.
191  * This function will return 0 in case of error.
192  * -EFAULT in case of bad pointers and
193  * DSP_EMemory in case of no memory to create ntfy_event.
194  */
195 static  inline int ntfy_unregister(struct ntfy_object *ntfy_obj,
196                          struct dsp_notification *noti)
197 {
198         int status = 0;
199         struct ntfy_event *ne;
200
201         if (!noti || !ntfy_obj) {
202                 status = -EFAULT;
203                 goto func_end;
204         }
205
206         ne = container_of((struct sync_object *)noti, struct ntfy_event,
207                                                                 sync_obj);
208         spin_lock_bh(&ntfy_obj->ntfy_lock);
209         raw_notifier_chain_unregister(&ntfy_obj->head,
210                                                 &ne->noti_block);
211         kfree(ne);
212         spin_unlock_bh(&ntfy_obj->ntfy_lock);
213 func_end:
214         return status;
215 }
216
217 #endif                          /* NTFY_ */