summaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/gen/gb.c
blob: 9f590230473b19f0f7ec0c3eeb66f2b7e7d7be14 (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
/*
 * gb.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Generic bitmap operations.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/*  ----------------------------------- DSP/BIOS Bridge */
#include <linux/types.h>
/*  ----------------------------------- This */
#include <dspbridge/gs.h>
#include <dspbridge/gb.h>

struct gb_t_map {
	u32 len;
	u32 wcnt;
	u32 *words;
};

/*
 *  ======== gb_clear ========
 *  purpose:
 *      Clears a bit in the bit map.
 */

void gb_clear(struct gb_t_map *map, u32 bitn)
{
	u32 mask;

	mask = 1L << (bitn % BITS_PER_LONG);
	map->words[bitn / BITS_PER_LONG] &= ~mask;
}

/*
 *  ======== gb_create ========
 *  purpose:
 *      Creates a bit map.
 */

struct gb_t_map *gb_create(u32 len)
{
	struct gb_t_map *map;
	u32 i;
	map = (struct gb_t_map *)gs_alloc(sizeof(struct gb_t_map));
	if (map != NULL) {
		map->len = len;
		map->wcnt = len / BITS_PER_LONG + 1;
		map->words = (u32 *) gs_alloc(map->wcnt * sizeof(u32));
		if (map->words != NULL) {
			for (i = 0; i < map->wcnt; i++)
				map->words[i] = 0L;

		} else {
			gs_frees(map, sizeof(struct gb_t_map));
			map = NULL;
		}
	}

	return map;
}

/*
 *  ======== gb_delete ========
 *  purpose:
 *      Frees a bit map.
 */

void gb_delete(struct gb_t_map *map)
{
	gs_frees(map->words, map->wcnt * sizeof(u32));
	gs_frees(map, sizeof(struct gb_t_map));
}

/*
 *  ======== gb_findandset ========
 *  purpose:
 *      Finds a free bit and sets it.
 */
u32 gb_findandset(struct gb_t_map *map)
{
	u32 bitn;

	bitn = gb_minclear(map);

	if (bitn != GB_NOBITS)
		gb_set(map, bitn);

	return bitn;
}

/*
 *  ======== gb_minclear ========
 *  purpose:
 *      returns the location of the first unset bit in the bit map.
 */
u32 gb_minclear(struct gb_t_map *map)
{
	u32 bit_location = 0;
	u32 bit_acc = 0;
	u32 i;
	u32 bit;
	u32 *word;

	for (word = map->words, i = 0; i < map->wcnt; word++, i++) {
		if (~*word) {
			for (bit = 0; bit < BITS_PER_LONG; bit++, bit_acc++) {
				if (bit_acc == map->len)
					return GB_NOBITS;

				if (~*word & (1L << bit)) {
					bit_location = i * BITS_PER_LONG + bit;
					return bit_location;
				}

			}
		} else {
			bit_acc += BITS_PER_LONG;
		}
	}

	return GB_NOBITS;
}

/*
 *  ======== gb_set ========
 *  purpose:
 *      Sets a bit in the bit map.
 */

void gb_set(struct gb_t_map *map, u32 bitn)
{
	u32 mask;

	mask = 1L << (bitn % BITS_PER_LONG);
	map->words[bitn / BITS_PER_LONG] |= mask;
}

/*
 *  ======== gb_test ========
 *  purpose:
 *      Returns true if the bit is set in the specified location.
 */

bool gb_test(struct gb_t_map *map, u32 bitn)
{
	bool state;
	u32 mask;
	u32 word;

	mask = 1L << (bitn % BITS_PER_LONG);
	word = map->words[bitn / BITS_PER_LONG];
	state = word & mask ? true : false;

	return state;
}
OpenPOWER on IntegriCloud