@@ -151,16 +151,16 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask,
spin_lock_irqsave(&chip->gpio_lock[0], flags);
spin_lock(&chip->gpio_lock[1]);
- bitmap_set_value(old, state[0], 0, width[0]);
- bitmap_set_value(old, state[1], width[0], width[1]);
+ bitmap_set_value(old, 64, state[0], width[0], 0);
+ bitmap_set_value(old, 64, state[1], width[1], width[0]);
bitmap_replace(new, old, bits, mask, gc->ngpio);
- bitmap_set_value(old, state[0], 0, 32);
- bitmap_set_value(old, state[1], 32, 32);
+ bitmap_set_value(old, 64, state[0], 32, 0);
+ bitmap_set_value(old, 64, state[1], 32, 32);
state[0] = bitmap_get_value(new, 0, width[0]);
state[1] = bitmap_get_value(new, width[0], width[1]);
- bitmap_set_value(new, state[0], 0, 32);
- bitmap_set_value(new, state[1], 32, 32);
+ bitmap_set_value(new, 64, state[0], 32, 0);
+ bitmap_set_value(new, 64, state[1], 32, 32);
bitmap_xor(changed, old, new, 64);
if (((u32 *)changed)[0])
@@ -78,8 +78,9 @@
* bitmap_get_value(map, start, nbits) Get bit value of size
* 'nbits' from map at start
* bitmap_set_value8(map, value, start) Set 8bit value to map at start
- * bitmap_set_value(map, value, start, nbits) Set bit value of size 'nbits'
- * of map at start
+ * bitmap_set_value(map, nbits, value, value_width, start)
+ * Set bit value of size value_width
+ * to map at start
*
* Note, bitmap_zero() and bitmap_fill() operate over the region of
* unsigned longs, that is, bits behind bitmap till the unsigned long
@@ -610,30 +611,36 @@ static inline void bitmap_set_value8(unsigned long *map, unsigned long value,
}
/**
- * bitmap_set_value - set n-bit value within a memory region
+ * bitmap_set_value - set value within a memory region
* @map: address to the bitmap memory region
- * @value: value of nbits
- * @start: bit offset of the n-bit value
- * @nbits: size of value in bits (must be between 1 and BITS_PER_LONG inclusive).
+ * @nbits: size of map in bits
+ * @value: value of clump
+ * @value_width: size of value in bits (must be between 1 and BITS_PER_LONG inclusive)
+ * @start: bit offset of the value
*/
-static inline void bitmap_set_value(unsigned long *map,
- unsigned long value,
- unsigned long start, unsigned long nbits)
+static inline void bitmap_set_value(unsigned long *map, unsigned long nbits,
+ unsigned long value, unsigned long value_width,
+ unsigned long start)
{
- const size_t index = BIT_WORD(start);
+ const unsigned long index = BIT_WORD(start);
+ const unsigned long length = BIT_WORD(nbits);
const unsigned long offset = start % BITS_PER_LONG;
const unsigned long ceiling = round_up(start + 1, BITS_PER_LONG);
const unsigned long space = ceiling - start;
- value &= GENMASK(nbits - 1, 0);
+ value &= GENMASK(value_width - 1, 0);
- if (space >= nbits) {
- map[index] &= ~(GENMASK(nbits - 1, 0) << offset);
+ if (space >= value_width) {
+ map[index] &= ~(GENMASK(value_width - 1, 0) << offset);
map[index] |= value << offset;
} else {
map[index + 0] &= ~BITMAP_FIRST_WORD_MASK(start);
map[index + 0] |= value << offset;
- map[index + 1] &= ~BITMAP_LAST_WORD_MASK(start + nbits);
+
+ if (index + 1 >= length)
+ __builtin_unreachable();
+
+ map[index + 1] &= ~BITMAP_LAST_WORD_MASK(start + value_width);
map[index + 1] |= value >> space;
}
}
@@ -656,8 +656,8 @@ static void __init prepare_test_data(unsigned int index)
unsigned long width = 0;
for (i = 0; i < clump_test_data[index].count; i++) {
- bitmap_set_value(clump_test_data[index].data,
- clump_bitmap_data[(clump_test_data[index].offset)++], width, 32);
+ bitmap_set_value(clump_test_data[index].data, 256,
+ clump_bitmap_data[(clump_test_data[index].offset)++], 32, width);
width += 32;
}
}