summaryrefslogtreecommitdiff
path: root/drivers/gpu/arm/mali400/r4p0_rel0/common/mali_osk_list.h
blob: cf54e812d3ca04506a136d9a28b3370d5020949b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/*
 * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
 * 
 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
 * 
 * A copy of the licence is included with the program, and can also be obtained from Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

/**
 * @file mali_osk_list.h
 * Implementation of the OS abstraction layer for the kernel device driver
 */

#ifndef __MALI_OSK_LIST_H__
#define __MALI_OSK_LIST_H__

#include "mali_osk.h"
#include "mali_kernel_common.h"

#ifdef __cplusplus
extern "C" {
#endif

MALI_STATIC_INLINE void __mali_osk_list_add(_mali_osk_list_t *new_entry, _mali_osk_list_t *prev, _mali_osk_list_t *next)
{
	next->prev = new_entry;
	new_entry->next = next;
	new_entry->prev = prev;
	prev->next = new_entry;
}

MALI_STATIC_INLINE void __mali_osk_list_del(_mali_osk_list_t *prev, _mali_osk_list_t *next)
{
	next->prev = prev;
	prev->next = next;
}

/** @addtogroup _mali_osk_list OSK Doubly-Linked Circular Lists
 * @{ */

/** Reference implementations of Doubly-linked Circular Lists are provided.
 * There is often no need to re-implement these.
 *
 * @note The implementation may differ subtly from any lists the OS provides.
 * For this reason, these lists should not be mixed with OS-specific lists
 * inside the OSK/UKK implementation. */

/** @brief Initialize a list to be a head of an empty list
 * @param exp the list to initialize. */
#define _MALI_OSK_INIT_LIST_HEAD(exp) _mali_osk_list_init(exp)

/** @brief Define a list variable, which is uninitialized.
 * @param exp the name of the variable that the list will be defined as. */
#define _MALI_OSK_LIST_HEAD(exp) _mali_osk_list_t exp

/** @brief Define a list variable, which is initialized.
 * @param exp the name of the variable that the list will be defined as. */
#define _MALI_OSK_LIST_HEAD_STATIC_INIT(exp) _mali_osk_list_t exp = { &exp, &exp }

/** @brief Initialize a list element.
 *
 * All list elements must be initialized before use.
 *
 * Do not use on any list element that is present in a list without using
 * _mali_osk_list_del first, otherwise this will break the list.
 *
 * @param list the list element to initialize
 */
MALI_STATIC_INLINE void _mali_osk_list_init( _mali_osk_list_t *list )
{
	list->next = list;
	list->prev = list;
}

/** @brief Insert a single list element after an entry in a list
 *
 * As an example, if this is inserted to the head of a list, then this becomes
 * the first element of the list.
 *
 * Do not use to move list elements from one list to another, as it will break
 * the originating list.
 *
 *
 * @param newlist the list element to insert
 * @param list the list in which to insert. The new element will be the next
 * entry in this list
 */
MALI_STATIC_INLINE void _mali_osk_list_add( _mali_osk_list_t *new_entry, _mali_osk_list_t *list )
{
	__mali_osk_list_add(new_entry, list, list->next);
}

/** @brief Insert a single list element before an entry in a list
 *
 * As an example, if this is inserted to the head of a list, then this becomes
 * the last element of the list.
 *
 * Do not use to move list elements from one list to another, as it will break
 * the originating list.
 *
 * @param newlist the list element to insert
 * @param list the list in which to insert. The new element will be the previous
 * entry in this list
 */
MALI_STATIC_INLINE void _mali_osk_list_addtail( _mali_osk_list_t *new_entry, _mali_osk_list_t *list )
{
	__mali_osk_list_add(new_entry, list->prev, list);
}

/** @brief Remove a single element from a list
 *
 * The element will no longer be present in the list. The removed list element
 * will be uninitialized, and so should not be traversed. It must be
 * initialized before further use.
 *
 * @param list the list element to remove.
 */
MALI_STATIC_INLINE void _mali_osk_list_del( _mali_osk_list_t *list )
{
	__mali_osk_list_del(list->prev, list->next);
}

/** @brief Remove a single element from a list, and re-initialize it
 *
 * The element will no longer be present in the list. The removed list element
 * will initialized, and so can be used as normal.
 *
 * @param list the list element to remove and initialize.
 */
MALI_STATIC_INLINE void _mali_osk_list_delinit( _mali_osk_list_t *list )
{
	__mali_osk_list_del(list->prev, list->next);
	_mali_osk_list_init(list);
}

/** @brief Determine whether a list is empty.
 *
 * An empty list is one that contains a single element that points to itself.
 *
 * @param list the list to check.
 * @return non-zero if the list is empty, and zero otherwise.
 */
MALI_STATIC_INLINE mali_bool _mali_osk_list_empty( _mali_osk_list_t *list )
{
	return list->next == list;
}

/** @brief Move a list element from one list to another.
 *
 * The list element must be initialized.
 *
 * As an example, moving a list item to the head of a new list causes this item
 * to be the first element in the new list.
 *
 * @param move the list element to move
 * @param list the new list into which the element will be inserted, as the next
 * element in the list.
 */
MALI_STATIC_INLINE void _mali_osk_list_move( _mali_osk_list_t *move_entry, _mali_osk_list_t *list )
{
	__mali_osk_list_del(move_entry->prev, move_entry->next);
	_mali_osk_list_add(move_entry, list);
}

/** @brief Move an entire list
 *
 * The list element must be initialized.
 *
 * Allows you to move a list from one list head to another list head
 *
 * @param old_list The existing list head
 * @param new_list The new list head (must be an empty list)
 */
MALI_STATIC_INLINE void _mali_osk_list_move_list( _mali_osk_list_t *old_list, _mali_osk_list_t *new_list )
{
	MALI_DEBUG_ASSERT(_mali_osk_list_empty(new_list));
	if (!_mali_osk_list_empty(old_list)) {
		new_list->next = old_list->next;
		new_list->prev = old_list->prev;
		new_list->next->prev = new_list;
		new_list->prev->next = new_list;
		old_list->next = old_list;
		old_list->prev = old_list;
	}
}

/** @brief Find the containing structure of a list
 *
 * When traversing a list, this is used to recover the containing structure,
 * given that is contains a _mali_osk_list_t member.
 *
 * Each list must be of structures of one type, and must link the same members
 * together, otherwise it will not be possible to correctly recover the
 * sturctures that the lists link.
 *
 * @note no type or memory checking occurs to ensure that a structure does in
 * fact exist for the list entry, and that it is being recovered with respect
 * to the correct list member.
 *
 * @param ptr the pointer to the _mali_osk_list_t member in this structure
 * @param type the type of the structure that contains the member
 * @param member the member of the structure that ptr points to.
 * @return a pointer to a \a type object which contains the _mali_osk_list_t
 * \a member, as pointed to by the _mali_osk_list_t \a *ptr.
 */
#define _MALI_OSK_LIST_ENTRY(ptr, type, member) \
	_MALI_OSK_CONTAINER_OF(ptr, type, member)

/** @brief Enumerate a list safely
 *
 * With this macro, lists can be enumerated in a 'safe' manner. That is,
 * entries can be deleted from the list without causing an error during
 * enumeration. To achieve this, a 'temporary' pointer is required, which must
 * be provided to the macro.
 *
 * Use it like a 'for()', 'while()' or 'do()' construct, and so it must be
 * followed by a statement or compound-statement which will be executed for
 * each list entry.
 *
 * Upon loop completion, providing that an early out was not taken in the
 * loop body, then it is guaranteed that ptr->member == list, even if the loop
 * body never executed.
 *
 * @param ptr a pointer to an object of type 'type', which points to the
 * structure that contains the currently enumerated list entry.
 * @param tmp a pointer to an object of type 'type', which must not be used
 * inside the list-execution statement.
 * @param list a pointer to a _mali_osk_list_t, from which enumeration will
 * begin
 * @param type the type of the structure that contains the _mali_osk_list_t
 * member that is part of the list to be enumerated.
 * @param member the _mali_osk_list_t member of the structure that is part of
 * the list to be enumerated.
 */
#define _MALI_OSK_LIST_FOREACHENTRY(ptr, tmp, list, type, member)         \
	for (ptr = _MALI_OSK_LIST_ENTRY((list)->next, type, member),      \
	     tmp = _MALI_OSK_LIST_ENTRY(ptr->member.next, type, member);  \
	     &ptr->member != (list);                                      \
	     ptr = tmp,                                                   \
	     tmp = _MALI_OSK_LIST_ENTRY(tmp->member.next, type, member))

/** @brief Enumerate a list in reverse order safely
 *
 * This macro is identical to @ref _MALI_OSK_LIST_FOREACHENTRY, except that
 * entries are enumerated in reverse order.
 *
 * @param ptr a pointer to an object of type 'type', which points to the
 * structure that contains the currently enumerated list entry.
 * @param tmp a pointer to an object of type 'type', which must not be used
 * inside the list-execution statement.
 * @param list a pointer to a _mali_osk_list_t, from which enumeration will
 * begin
 * @param type the type of the structure that contains the _mali_osk_list_t
 * member that is part of the list to be enumerated.
 * @param member the _mali_osk_list_t member of the structure that is part of
 * the list to be enumerated.
 */
#define _MALI_OSK_LIST_FOREACHENTRY_REVERSE(ptr, tmp, list, type, member) \
	for (ptr = _MALI_OSK_LIST_ENTRY((list)->prev, type, member),      \
	     tmp = _MALI_OSK_LIST_ENTRY(ptr->member.prev, type, member);  \
	     &ptr->member != (list);                                      \
	     ptr = tmp,                                                   \
	     tmp = _MALI_OSK_LIST_ENTRY(tmp->member.prev, type, member))

/** @} */ /* end group _mali_osk_list */

#ifdef __cplusplus
}
#endif

#endif /* __MALI_OSK_LIST_H__ */