upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / staging / tidspbridge / include / dspbridge / list.h
1 /*
2  * list.h
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * Declarations of list management control structures and definitions
7  * of inline list management functions.
8  *
9  * Copyright (C) 2008 Texas Instruments, Inc.
10  *
11  * This package is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  *
15  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18  */
19
20 #ifndef LIST_
21 #define LIST_
22
23 #include <dspbridge/host_os.h>
24 #include <linux/list.h>
25
26 #define LST_IS_EMPTY(l)      list_empty(&(l)->head)
27
28 struct lst_list {
29         struct list_head head;
30 };
31
32 /*
33  *  ======== lst_first ========
34  *  Purpose:
35  *      Returns a pointer to the first element of the list, or NULL if the list
36  *      is empty.
37  *  Parameters:
38  *      lst:  Pointer to list control structure.
39  *  Returns:
40  *      Pointer to first list element, or NULL.
41  *  Requires:
42  *      - LST initialized.
43  *      - lst != NULL.
44  *  Ensures:
45  */
46 static inline struct list_head *lst_first(struct lst_list *lst)
47 {
48         if (lst && !list_empty(&lst->head))
49                 return lst->head.next;
50         return NULL;
51 }
52
53 /*
54  *  ======== lst_get_head ========
55  *  Purpose:
56  *      Pops the head off the list and returns a pointer to it.
57  *  Details:
58  *      If the list is empty, returns NULL.
59  *      Else, removes the element at the head of the list, making the next
60  *      element the head of the list.
61  *      The head is removed by making the tail element of the list point its
62  *      "next" pointer at the next element after the head, and by making the
63  *      "prev" pointer of the next element after the head point at the tail
64  *      element.  So the next element after the head becomes the new head of
65  *      the list.
66  *  Parameters:
67  *      lst:    Pointer to list control structure of list whose head
68  *              element is to be removed
69  *  Returns:
70  *      Pointer to element that was at the head of the list (success)
71  *      NULL          No elements in list
72  *  Requires:
73  *      - LST initialized.
74  *      - lst != NULL.
75  *  Ensures:
76  *  Notes:
77  *      Because the tail of the list points forward (its "next" pointer) to
78  *      the head of the list, and the head of the list points backward (its
79  *      "prev" pointer) to the tail of the list, this list is circular.
80  */
81 static inline struct list_head *lst_get_head(struct lst_list *lst)
82 {
83         struct list_head *elem_list;
84
85         if (!lst || list_empty(&lst->head))
86                 return NULL;
87
88         elem_list = lst->head.next;
89         lst->head.next = elem_list->next;
90         elem_list->next->prev = &lst->head;
91
92         return elem_list;
93 }
94
95 /*
96  *  ======== lst_init_elem ========
97  *  Purpose:
98  *      Initializes a list element to default (cleared) values
99  *  Details:
100  *  Parameters:
101  *      elem_list:  Pointer to list element to be reset
102  *  Returns:
103  *  Requires:
104  *      LST initialized.
105  *  Ensures:
106  *  Notes:
107  *      This function must not be called to "reset" an element in the middle
108  *      of a list chain -- that would break the chain.
109  *
110  */
111 static inline void lst_init_elem(struct list_head *elem_list)
112 {
113         if (elem_list) {
114                 elem_list->next = NULL;
115                 elem_list->prev = NULL;
116         }
117 }
118
119 /*
120  *  ======== lst_insert_before ========
121  *  Purpose:
122  *     Insert the element before the existing element.
123  *  Parameters:
124  *      lst:            Pointer to list control structure.
125  *      elem_list:          Pointer to element in list to insert.
126  *      elem_existing:  Pointer to existing list element.
127  *  Returns:
128  *  Requires:
129  *      - LST initialized.
130  *      - lst != NULL.
131  *      - elem_list != NULL.
132  *      - elem_existing != NULL.
133  *  Ensures:
134  */
135 static inline void lst_insert_before(struct lst_list *lst,
136                                      struct list_head *elem_list,
137                                      struct list_head *elem_existing)
138 {
139         if (lst && elem_list && elem_existing)
140                 list_add_tail(elem_list, elem_existing);
141 }
142
143 /*
144  *  ======== lst_next ========
145  *  Purpose:
146  *      Returns a pointer to the next element of the list, or NULL if the next
147  *      element is the head of the list or the list is empty.
148  *  Parameters:
149  *      lst:        Pointer to list control structure.
150  *      cur_elem:   Pointer to element in list to remove.
151  *  Returns:
152  *      Pointer to list element, or NULL.
153  *  Requires:
154  *      - LST initialized.
155  *      - lst != NULL.
156  *      - cur_elem != NULL.
157  *  Ensures:
158  */
159 static inline struct list_head *lst_next(struct lst_list *lst,
160                                          struct list_head *cur_elem)
161 {
162         if (lst && !list_empty(&lst->head) && cur_elem &&
163             (cur_elem->next != &lst->head))
164                 return cur_elem->next;
165         return NULL;
166 }
167
168 /*
169  *  ======== lst_put_tail ========
170  *  Purpose:
171  *      Adds the specified element to the tail of the list
172  *  Details:
173  *      Sets new element's "prev" pointer to the address previously held by
174  *      the head element's prev pointer.  This is the previous tail member of
175  *      the list.
176  *      Sets the new head's prev pointer to the address of the element.
177  *      Sets next pointer of the previous tail member of the list to point to
178  *      the new element (rather than the head, which it had been pointing at).
179  *      Sets new element's next pointer to the address of the head element.
180  *      Sets head's prev pointer to the address of the new element.
181  *  Parameters:
182  *      lst:    Pointer to list control structure to which *elem_list will be
183  *              added
184  *      elem_list:  Pointer to list element to be added
185  *  Returns:
186  *      Void
187  *  Requires:
188  *      *elem_list and *lst must both exist.
189  *      LST initialized.
190  *  Ensures:
191  *  Notes:
192  *      Because the tail is always "just before" the head of the list (the
193  *      tail's "next" pointer points at the head of the list, and the head's
194  *      "prev" pointer points at the tail of the list), the list is circular.
195  */
196 static inline void lst_put_tail(struct lst_list *lst,
197                                 struct list_head *elem_list)
198 {
199         if (lst && elem_list)
200                 list_add_tail(elem_list, &lst->head);
201 }
202
203 /*
204  *  ======== lst_remove_elem ========
205  *  Purpose:
206  *      Removes (unlinks) the given element from the list, if the list is not
207  *      empty.  Does not free the list element.
208  *  Parameters:
209  *      lst:        Pointer to list control structure.
210  *      cur_elem:   Pointer to element in list to remove.
211  *  Returns:
212  *  Requires:
213  *      - LST initialized.
214  *      - lst != NULL.
215  *      - cur_elem != NULL.
216  *  Ensures:
217  */
218 static inline void lst_remove_elem(struct lst_list *lst,
219                                    struct list_head *cur_elem)
220 {
221         if (lst && !list_empty(&lst->head) && cur_elem)
222                 list_del_init(cur_elem);
223 }
224
225 #endif /* LIST_ */