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 26struct 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 38void 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 52struct 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 80void 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 */ 91u32 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 */ 108u32 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 142void 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 156bool 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} 168