Merge branch 'timecounter-next'
[cascardo/linux.git] / lib / bitmap.c
index b499ab6..324ea9e 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/bug.h>
+
+#include <asm/page.h>
 #include <asm/uaccess.h>
 
 /*
@@ -326,30 +328,32 @@ void bitmap_clear(unsigned long *map, unsigned int start, int len)
 }
 EXPORT_SYMBOL(bitmap_clear);
 
-/*
- * bitmap_find_next_zero_area - find a contiguous aligned zero area
+/**
+ * bitmap_find_next_zero_area_off - find a contiguous aligned zero area
  * @map: The address to base the search on
  * @size: The bitmap size in bits
  * @start: The bitnumber to start searching at
  * @nr: The number of zeroed bits we're looking for
  * @align_mask: Alignment mask for zero area
+ * @align_offset: Alignment offset for zero area.
  *
  * The @align_mask should be one less than a power of 2; the effect is that
- * the bit offset of all zero areas this function finds is multiples of that
- * power of 2. A @align_mask of 0 means no alignment is required.
+ * the bit offset of all zero areas this function finds plus @align_offset
+ * is multiple of that power of 2.
  */
-unsigned long bitmap_find_next_zero_area(unsigned long *map,
-                                        unsigned long size,
-                                        unsigned long start,
-                                        unsigned int nr,
-                                        unsigned long align_mask)
+unsigned long bitmap_find_next_zero_area_off(unsigned long *map,
+                                            unsigned long size,
+                                            unsigned long start,
+                                            unsigned int nr,
+                                            unsigned long align_mask,
+                                            unsigned long align_offset)
 {
        unsigned long index, end, i;
 again:
        index = find_next_zero_bit(map, size, start);
 
        /* Align allocation */
-       index = __ALIGN_MASK(index, align_mask);
+       index = __ALIGN_MASK(index + align_offset, align_mask) - align_offset;
 
        end = index + nr;
        if (end > size)
@@ -361,7 +365,7 @@ again:
        }
        return index;
 }
-EXPORT_SYMBOL(bitmap_find_next_zero_area);
+EXPORT_SYMBOL(bitmap_find_next_zero_area_off);
 
 /*
  * Bitmap printing & parsing functions: first version by Nadia Yvette Chambers,
@@ -583,6 +587,33 @@ int bitmap_scnlistprintf(char *buf, unsigned int buflen,
 }
 EXPORT_SYMBOL(bitmap_scnlistprintf);
 
+/**
+ * bitmap_print_to_pagebuf - convert bitmap to list or hex format ASCII string
+ * @list: indicates whether the bitmap must be list
+ * @buf: page aligned buffer into which string is placed
+ * @maskp: pointer to bitmap to convert
+ * @nmaskbits: size of bitmap, in bits
+ *
+ * Output format is a comma-separated list of decimal numbers and
+ * ranges if list is specified or hex digits grouped into comma-separated
+ * sets of 8 digits/set. Returns the number of characters written to buf.
+ */
+int bitmap_print_to_pagebuf(bool list, char *buf, const unsigned long *maskp,
+                           int nmaskbits)
+{
+       ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf - 2;
+       int n = 0;
+
+       if (len > 1) {
+               n = list ? bitmap_scnlistprintf(buf, len, maskp, nmaskbits) :
+                          bitmap_scnprintf(buf, len, maskp, nmaskbits);
+               buf[n++] = '\n';
+               buf[n] = '\0';
+       }
+       return n;
+}
+EXPORT_SYMBOL(bitmap_print_to_pagebuf);
+
 /**
  * __bitmap_parselist - convert list format ASCII string to bitmap
  * @buf: read nul-terminated user string from this buffer