Merge branch 'master' into for-next
[platform/kernel/linux-starfive.git] / lib / bitmap.c
index a801379..6139489 100644 (file)
@@ -182,21 +182,22 @@ EXPORT_SYMBOL(__bitmap_shift_left);
  *
  * In pictures, example for a big-endian 32-bit architecture:
  *
- * @src:
- * 31                                   63
- * |                                    |
- * 10000000 11000001 11110010 00010101  10000000 11000001 01110010 00010101
- *                 |  |              |                                    |
- *                16  14             0                                   32
- *
- * if @cut is 3, and @first is 14, bits 14-16 in @src are cut and @dst is:
- *
- * 31                                   63
- * |                                    |
- * 10110000 00011000 00110010 00010101  00010000 00011000 00101110 01000010
- *                    |              |                                    |
- *                    14 (bit 17     0                                   32
- *                        from @src)
+ * The @src bitmap is::
+ *
+ *   31                                   63
+ *   |                                    |
+ *   10000000 11000001 11110010 00010101  10000000 11000001 01110010 00010101
+ *                   |  |              |                                    |
+ *                  16  14             0                                   32
+ *
+ * if @cut is 3, and @first is 14, bits 14-16 in @src are cut and @dst is::
+ *
+ *   31                                   63
+ *   |                                    |
+ *   10110000 00011000 00110010 00010101  00010000 00011000 00101110 01000010
+ *                      |              |                                    |
+ *                      14 (bit 17     0                                   32
+ *                          from @src)
  *
  * Note that @dst and @src might overlap partially or entirely.
  *
@@ -211,13 +212,13 @@ void bitmap_cut(unsigned long *dst, const unsigned long *src,
        unsigned long keep = 0, carry;
        int i;
 
-       memmove(dst, src, len * sizeof(*dst));
-
        if (first % BITS_PER_LONG) {
                keep = src[first / BITS_PER_LONG] &
                       (~0UL >> (BITS_PER_LONG - first % BITS_PER_LONG));
        }
 
+       memmove(dst, src, len * sizeof(*dst));
+
        while (cut--) {
                for (i = first / BITS_PER_LONG; i < len; i++) {
                        if (i < len - 1)
@@ -740,8 +741,9 @@ int bitmap_parse(const char *start, unsigned int buflen,
        int chunks = BITS_TO_U32(nmaskbits);
        u32 *bitmap = (u32 *)maskp;
        int unset_bit;
+       int chunk;
 
-       while (1) {
+       for (chunk = 0; ; chunk++) {
                end = bitmap_find_region_reverse(start, end);
                if (start > end)
                        break;
@@ -749,7 +751,11 @@ int bitmap_parse(const char *start, unsigned int buflen,
                if (!chunks--)
                        return -EOVERFLOW;
 
-               end = bitmap_get_x32_reverse(start, end, bitmap++);
+#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN)
+               end = bitmap_get_x32_reverse(start, end, &bitmap[chunk ^ 1]);
+#else
+               end = bitmap_get_x32_reverse(start, end, &bitmap[chunk]);
+#endif
                if (IS_ERR(end))
                        return PTR_ERR(end);
        }