diff options
Diffstat (limited to 'drivers/staging/tidspbridge/gen/gb.c')
-rw-r--r-- | drivers/staging/tidspbridge/gen/gb.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/drivers/staging/tidspbridge/gen/gb.c b/drivers/staging/tidspbridge/gen/gb.c new file mode 100644 index 000000000000..06eb3d361225 --- /dev/null +++ b/drivers/staging/tidspbridge/gen/gb.c @@ -0,0 +1,167 @@ +/* + * 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. + */ +#include <linux/types.h> + +/* ----------------------------------- 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; +} |