Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / drivers / staging / tidspbridge / gen / gb.c
1 /*
2  * gb.c
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * Generic bitmap operations.
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 #include <linux/types.h>
19
20 /*  ----------------------------------- DSP/BIOS Bridge */
21 #include <linux/types.h>
22 /*  ----------------------------------- This */
23 #include <dspbridge/gs.h>
24 #include <dspbridge/gb.h>
25
26 struct gb_t_map {
27         u32 len;
28         u32 wcnt;
29         u32 *words;
30 };
31
32 /*
33  *  ======== gb_clear ========
34  *  purpose:
35  *      Clears a bit in the bit map.
36  */
37
38 void gb_clear(struct gb_t_map *map, u32 bitn)
39 {
40         u32 mask;
41
42         mask = 1L << (bitn % BITS_PER_LONG);
43         map->words[bitn / BITS_PER_LONG] &= ~mask;
44 }
45
46 /*
47  *  ======== gb_create ========
48  *  purpose:
49  *      Creates a bit map.
50  */
51
52 struct gb_t_map *gb_create(u32 len)
53 {
54         struct gb_t_map *map;
55         u32 i;
56         map = (struct gb_t_map *)gs_alloc(sizeof(struct gb_t_map));
57         if (map != NULL) {
58                 map->len = len;
59                 map->wcnt = len / BITS_PER_LONG + 1;
60                 map->words = (u32 *) gs_alloc(map->wcnt * sizeof(u32));
61                 if (map->words != NULL) {
62                         for (i = 0; i < map->wcnt; i++)
63                                 map->words[i] = 0L;
64
65                 } else {
66                         gs_frees(map, sizeof(struct gb_t_map));
67                         map = NULL;
68                 }
69         }
70
71         return map;
72 }
73
74 /*
75  *  ======== gb_delete ========
76  *  purpose:
77  *      Frees a bit map.
78  */
79
80 void gb_delete(struct gb_t_map *map)
81 {
82         gs_frees(map->words, map->wcnt * sizeof(u32));
83         gs_frees(map, sizeof(struct gb_t_map));
84 }
85
86 /*
87  *  ======== gb_findandset ========
88  *  purpose:
89  *      Finds a free bit and sets it.
90  */
91 u32 gb_findandset(struct gb_t_map *map)
92 {
93         u32 bitn;
94
95         bitn = gb_minclear(map);
96
97         if (bitn != GB_NOBITS)
98                 gb_set(map, bitn);
99
100         return bitn;
101 }
102
103 /*
104  *  ======== gb_minclear ========
105  *  purpose:
106  *      returns the location of the first unset bit in the bit map.
107  */
108 u32 gb_minclear(struct gb_t_map *map)
109 {
110         u32 bit_location = 0;
111         u32 bit_acc = 0;
112         u32 i;
113         u32 bit;
114         u32 *word;
115
116         for (word = map->words, i = 0; i < map->wcnt; word++, i++) {
117                 if (~*word) {
118                         for (bit = 0; bit < BITS_PER_LONG; bit++, bit_acc++) {
119                                 if (bit_acc == map->len)
120                                         return GB_NOBITS;
121
122                                 if (~*word & (1L << bit)) {
123                                         bit_location = i * BITS_PER_LONG + bit;
124                                         return bit_location;
125                                 }
126
127                         }
128                 } else {
129                         bit_acc += BITS_PER_LONG;
130                 }
131         }
132
133         return GB_NOBITS;
134 }
135
136 /*
137  *  ======== gb_set ========
138  *  purpose:
139  *      Sets a bit in the bit map.
140  */
141
142 void gb_set(struct gb_t_map *map, u32 bitn)
143 {
144         u32 mask;
145
146         mask = 1L << (bitn % BITS_PER_LONG);
147         map->words[bitn / BITS_PER_LONG] |= mask;
148 }
149
150 /*
151  *  ======== gb_test ========
152  *  purpose:
153  *      Returns true if the bit is set in the specified location.
154  */
155
156 bool gb_test(struct gb_t_map *map, u32 bitn)
157 {
158         bool state;
159         u32 mask;
160         u32 word;
161
162         mask = 1L << (bitn % BITS_PER_LONG);
163         word = map->words[bitn / BITS_PER_LONG];
164         state = word & mask ? true : false;
165
166         return state;
167 }