2 * Copyright (C) 2010, 2013-2015 ARM Limited. All rights reserved.
4 * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5 * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7 * A copy of the licence is included with the program, and can also be obtained from Free Software
8 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 * @file mali_osk_bitmap.c
\r
13 * Implementation of the OS abstraction layer for the kernel device driver
\r
16 #include <linux/errno.h>
\r
17 #include <linux/slab.h>
\r
18 #include <linux/mm.h>
\r
19 #include <linux/bitmap.h>
\r
20 #include <linux/vmalloc.h>
\r
21 #include "common/mali_kernel_common.h"
\r
22 #include "mali_osk_types.h"
\r
23 #include "mali_osk.h"
\r
25 u32 _mali_osk_bitmap_alloc(struct _mali_osk_bitmap *bitmap)
\r
29 MALI_DEBUG_ASSERT_POINTER(bitmap);
\r
31 _mali_osk_spinlock_lock(bitmap->lock);
\r
33 obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->reserve);
\r
35 if (obj < bitmap->max) {
\r
36 set_bit(obj, bitmap->table);
\r
43 _mali_osk_spinlock_unlock(bitmap->lock);
\r
48 void _mali_osk_bitmap_free(struct _mali_osk_bitmap *bitmap, u32 obj)
\r
50 MALI_DEBUG_ASSERT_POINTER(bitmap);
\r
52 _mali_osk_bitmap_free_range(bitmap, obj, 1);
\r
55 u32 _mali_osk_bitmap_alloc_range(struct _mali_osk_bitmap *bitmap, int cnt)
\r
59 MALI_DEBUG_ASSERT_POINTER(bitmap);
\r
66 return _mali_osk_bitmap_alloc(bitmap);
\r
69 _mali_osk_spinlock_lock(bitmap->lock);
\r
70 obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
\r
71 bitmap->last, cnt, 0);
\r
73 if (obj >= bitmap->max) {
\r
74 obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max,
\r
75 bitmap->reserve, cnt, 0);
\r
78 if (obj < bitmap->max) {
\r
79 bitmap_set(bitmap->table, obj, cnt);
\r
81 bitmap->last = (obj + cnt);
\r
82 if (bitmap->last >= bitmap->max) {
\r
83 bitmap->last = bitmap->reserve;
\r
90 bitmap->avail -= cnt;
\r
93 _mali_osk_spinlock_unlock(bitmap->lock);
\r
98 u32 _mali_osk_bitmap_avail(struct _mali_osk_bitmap *bitmap)
\r
100 MALI_DEBUG_ASSERT_POINTER(bitmap);
\r
102 return bitmap->avail;
\r
105 void _mali_osk_bitmap_free_range(struct _mali_osk_bitmap *bitmap, u32 obj, int cnt)
\r
107 MALI_DEBUG_ASSERT_POINTER(bitmap);
\r
109 _mali_osk_spinlock_lock(bitmap->lock);
\r
110 bitmap_clear(bitmap->table, obj, cnt);
\r
111 bitmap->last = min(bitmap->last, obj);
\r
113 bitmap->avail += cnt;
\r
114 _mali_osk_spinlock_unlock(bitmap->lock);
\r
117 int _mali_osk_bitmap_init(struct _mali_osk_bitmap *bitmap, u32 num, u32 reserve)
\r
119 MALI_DEBUG_ASSERT_POINTER(bitmap);
\r
120 MALI_DEBUG_ASSERT(reserve <= num);
\r
122 bitmap->reserve = reserve;
\r
123 bitmap->last = reserve;
\r
125 bitmap->avail = num - reserve;
\r
126 bitmap->lock = _mali_osk_spinlock_init(_MALI_OSK_LOCKFLAG_UNORDERED, _MALI_OSK_LOCK_ORDER_FIRST);
\r
127 if (!bitmap->lock) {
\r
128 return _MALI_OSK_ERR_NOMEM;
\r
130 bitmap->table = kzalloc(BITS_TO_LONGS(bitmap->max) *
\r
131 sizeof(long), GFP_KERNEL);
\r
132 if (!bitmap->table) {
\r
133 _mali_osk_spinlock_term(bitmap->lock);
\r
134 return _MALI_OSK_ERR_NOMEM;
\r
137 return _MALI_OSK_ERR_OK;
\r
140 void _mali_osk_bitmap_term(struct _mali_osk_bitmap *bitmap)
\r
142 MALI_DEBUG_ASSERT_POINTER(bitmap);
\r
144 if (NULL != bitmap->lock) {
\r
145 _mali_osk_spinlock_term(bitmap->lock);
\r
148 if (NULL != bitmap->table) {
\r
149 kfree(bitmap->table);
\r