Patch "bitops: introduce the for_each_set_clump8 macro" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    bitops: introduce the for_each_set_clump8 macro

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     bitops-introduce-the-for_each_set_clump8-macro.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit c140c3bd62861ac1b796f37deabbc405e9112b17
Author: William Breathitt Gray <vilhelm.gray@xxxxxxxxx>
Date:   Wed Dec 4 16:50:57 2019 -0800

    bitops: introduce the for_each_set_clump8 macro
    
    [ Upstream commit 169c474fb22d8a5e909e172f177b957546d0519d ]
    
    Pach series "Introduce the for_each_set_clump8 macro", v18.
    
    While adding GPIO get_multiple/set_multiple callback support for various
    drivers, I noticed a pattern of looping manifesting that would be useful
    standardized as a macro.
    
    This patchset introduces the for_each_set_clump8 macro and utilizes it
    in several GPIO drivers.  The for_each_set_clump macro8 facilitates a
    for-loop syntax that iterates over a memory region entire groups of set
    bits at a time.
    
    For example, suppose you would like to iterate over a 32-bit integer 8
    bits at a time, skipping over 8-bit groups with no set bit, where
    XXXXXXXX represents the current 8-bit group:
    
        Example:        10111110 00000000 11111111 00110011
        First loop:     10111110 00000000 11111111 XXXXXXXX
        Second loop:    10111110 00000000 XXXXXXXX 00110011
        Third loop:     XXXXXXXX 00000000 11111111 00110011
    
    Each iteration of the loop returns the next 8-bit group that has at
    least one set bit.
    
    The for_each_set_clump8 macro has four parameters:
    
        * start: set to the bit offset of the current clump
        * clump: set to the current clump value
        * bits: bitmap to search within
        * size: bitmap size in number of bits
    
    In this version of the patchset, the for_each_set_clump macro has been
    reimplemented and simplified based on the suggestions provided by Rasmus
    Villemoes and Andy Shevchenko in the version 4 submission.
    
    In particular, the function of the for_each_set_clump macro has been
    restricted to handle only 8-bit clumps; the drivers that use the
    for_each_set_clump macro only handle 8-bit ports so a generic
    for_each_set_clump implementation is not necessary.  Thus, a solution
    for large clumps (i.e.  those larger than the width of a bitmap word)
    can be postponed until a driver appears that actually requires such a
    generic for_each_set_clump implementation.
    
    For what it's worth, a semi-generic for_each_set_clump (i.e.  for clumps
    smaller than the width of a bitmap word) can be implemented by simply
    replacing the hardcoded '8' and '0xFF' instances with respective
    variables.  I have not yet had a need for such an implementation, and
    since it falls short of a true generic for_each_set_clump function, I
    have decided to forgo such an implementation for now.
    
    In addition, the bitmap_get_value8 and bitmap_set_value8 functions are
    introduced to get and set 8-bit values respectively.  Their use is based
    on the behavior suggested in the patchset version 4 review.
    
    This patch (of 14):
    
    This macro iterates for each 8-bit group of bits (clump) with set bits,
    within a bitmap memory region.  For each iteration, "start" is set to
    the bit offset of the found clump, while the respective clump value is
    stored to the location pointed by "clump".  Additionally, the
    bitmap_get_value8 and bitmap_set_value8 functions are introduced to
    respectively get and set an 8-bit value in a bitmap memory region.
    
    [gustavo@xxxxxxxxxxxxxx: fix potential sign-extension overflow]
      Link: http://lkml.kernel.org/r/20191015184657.GA26541@embeddedor
    [akpm@xxxxxxxxxxxxxxxxxxxx: s/ULL/UL/, per Joe]
    [vilhelm.gray@xxxxxxxxx: add for_each_set_clump8 documentation]
      Link: http://lkml.kernel.org/r/20191016161825.301082-1-vilhelm.gray@xxxxxxxxx
    Link: http://lkml.kernel.org/r/893c3b4f03266c9496137cc98ac2b1bd27f92c73.1570641097.git.vilhelm.gray@xxxxxxxxx
    Signed-off-by: William Breathitt Gray <vilhelm.gray@xxxxxxxxx>
    Signed-off-by: Gustavo A. R. Silva <gustavo@xxxxxxxxxxxxxx>
    Suggested-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>
    Suggested-by: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
    Suggested-by: Lukas Wunner <lukas@xxxxxxxxx>
    Tested-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
    Cc: Arnd Bergmann <arnd@xxxxxxxx>
    Cc: Linus Walleij <linus.walleij@xxxxxxxxxx>
    Cc: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>
    Cc: Masahiro Yamada <yamada.masahiro@xxxxxxxxxxxxx>
    Cc: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx>
    Cc: Phil Reid <preid@xxxxxxxxxxxxxxxxx>
    Cc: Geert Uytterhoeven <geert+renesas@xxxxxxxxx>
    Cc: Mathias Duckeck <m.duckeck@xxxxxxxxx>
    Cc: Morten Hein Tiljeset <morten.tiljeset@xxxxxxxxx>
    Cc: Sean Nyekjaer <sean.nyekjaer@xxxxxxxxx>
    Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
    Stable-dep-of: 9d6a811b522b ("gpio: tqmx86: introduce shadow register for GPIO output value")
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/include/asm-generic/bitops/find.h b/include/asm-generic/bitops/find.h
index 8a1ee10014def..9fdf21302fdf3 100644
--- a/include/asm-generic/bitops/find.h
+++ b/include/asm-generic/bitops/find.h
@@ -80,4 +80,21 @@ extern unsigned long find_first_zero_bit(const unsigned long *addr,
 
 #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
 
+/**
+ * find_next_clump8 - find next 8-bit clump with set bits in a memory region
+ * @clump: location to store copy of found clump
+ * @addr: address to base the search on
+ * @size: bitmap size in number of bits
+ * @offset: bit offset at which to start searching
+ *
+ * Returns the bit offset for the next set clump; the found clump value is
+ * copied to the location pointed by @clump. If no bits are set, returns @size.
+ */
+extern unsigned long find_next_clump8(unsigned long *clump,
+				      const unsigned long *addr,
+				      unsigned long size, unsigned long offset);
+
+#define find_first_clump8(clump, bits, size) \
+	find_next_clump8((clump), (bits), (size), 0)
+
 #endif /*_ASM_GENERIC_BITOPS_FIND_H_ */
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 29fc933df3bf0..9f046609e8090 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -66,6 +66,8 @@
  *  bitmap_allocate_region(bitmap, pos, order)  Allocate specified bit region
  *  bitmap_from_arr32(dst, buf, nbits)          Copy nbits from u32[] buf to dst
  *  bitmap_to_arr32(buf, src, nbits)            Copy nbits from buf to u32[] dst
+ *  bitmap_get_value8(map, start)               Get 8bit value from map at start
+ *  bitmap_set_value8(map, value, start)        Set 8bit value 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
@@ -489,6 +491,39 @@ static inline void bitmap_from_u64(unsigned long *dst, u64 mask)
 		dst[1] = mask >> 32;
 }
 
+/**
+ * bitmap_get_value8 - get an 8-bit value within a memory region
+ * @map: address to the bitmap memory region
+ * @start: bit offset of the 8-bit value; must be a multiple of 8
+ *
+ * Returns the 8-bit value located at the @start bit offset within the @src
+ * memory region.
+ */
+static inline unsigned long bitmap_get_value8(const unsigned long *map,
+					      unsigned long start)
+{
+	const size_t index = BIT_WORD(start);
+	const unsigned long offset = start % BITS_PER_LONG;
+
+	return (map[index] >> offset) & 0xFF;
+}
+
+/**
+ * bitmap_set_value8 - set an 8-bit value within a memory region
+ * @map: address to the bitmap memory region
+ * @value: the 8-bit value; values wider than 8 bits may clobber bitmap
+ * @start: bit offset of the 8-bit value; must be a multiple of 8
+ */
+static inline void bitmap_set_value8(unsigned long *map, unsigned long value,
+				     unsigned long start)
+{
+	const size_t index = BIT_WORD(start);
+	const unsigned long offset = start % BITS_PER_LONG;
+
+	map[index] &= ~(0xFFUL << offset);
+	map[index] |= value << offset;
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __LINUX_BITMAP_H */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index e9e74af163fab..5e51d28b33f8d 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -48,6 +48,18 @@ extern unsigned long __sw_hweight64(__u64 w);
 	     (bit) < (size);					\
 	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
 
+/**
+ * for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
+ * @start: bit offset to start search and to store the current iteration offset
+ * @clump: location to store copy of current 8-bit clump
+ * @bits: bitmap address to base the search on
+ * @size: bitmap size in number of bits
+ */
+#define for_each_set_clump8(start, clump, bits, size) \
+	for ((start) = find_first_clump8(&(clump), (bits), (size)); \
+	     (start) < (size); \
+	     (start) = find_next_clump8(&(clump), (bits), (size), (start) + 8))
+
 static inline int get_bitmask_order(unsigned int count)
 {
 	int order;
diff --git a/lib/find_bit.c b/lib/find_bit.c
index 4e68490fa7035..06e503c339f37 100644
--- a/lib/find_bit.c
+++ b/lib/find_bit.c
@@ -202,3 +202,17 @@ EXPORT_SYMBOL(find_next_bit_le);
 #endif
 
 #endif /* __BIG_ENDIAN */
+
+unsigned long find_next_clump8(unsigned long *clump, const unsigned long *addr,
+			       unsigned long size, unsigned long offset)
+{
+	offset = find_next_bit(addr, size, offset);
+	if (offset == size)
+		return size;
+
+	offset = round_down(offset, 8);
+	*clump = bitmap_get_value8(addr, offset);
+
+	return offset;
+}
+EXPORT_SYMBOL(find_next_clump8);




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux