summaryrefslogtreecommitdiff
path: root/include/linux/bitmap.h
diff options
context:
space:
mode:
authorDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>2026-05-21 23:36:50 +0300
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>2026-05-21 23:36:50 +0300
commit5c8cbca290acdd49a694b36c0af76ba0c00bbf12 (patch)
tree9badfc236a65de7da92dc3cb528f53f56345f026 /include/linux/bitmap.h
parentdb339b6bc9f234b4883eb02946ea01d8d9faa11c (diff)
parentc5e3f2a3abcb925f0364df09abfd759ff0590454 (diff)
downloadlinux-5c8cbca290acdd49a694b36c0af76ba0c00bbf12.tar.xz
Merge branch '20260507-ubwc-rework-v4-4-c19593d20c1d@oss.qualcomm.com' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into HEAD
Merge the branch with the soc/qcom changes, required for the next UBWC patches. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Diffstat (limited to 'include/linux/bitmap.h')
-rw-r--r--include/linux/bitmap.h48
1 files changed, 48 insertions, 0 deletions
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index b0395e4ccf90..b007d54a9036 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -46,6 +46,7 @@ struct device;
* bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
* bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
* bitmap_weighted_or(dst, src1, src2, nbits) *dst = *src1 | *src2. Returns Hamming Weight of dst
+ * bitmap_weighted_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2. Returns Hamming Weight of dst
* bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
* bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
* bitmap_complement(dst, src, nbits) *dst = ~(*src)
@@ -57,6 +58,7 @@ struct device;
* bitmap_weight(src, nbits) Hamming Weight: number set bits
* bitmap_weight_and(src1, src2, nbits) Hamming Weight of and'ed bitmap
* bitmap_weight_andnot(src1, src2, nbits) Hamming Weight of andnot'ed bitmap
+ * bitmap_weight_from(src, start, end) Hamming Weight starting from @start
* bitmap_set(dst, pos, nbits) Set specified bit area
* bitmap_clear(dst, pos, nbits) Clear specified bit area
* bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
@@ -168,6 +170,8 @@ void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int nbits);
unsigned int __bitmap_weighted_or(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int nbits);
+unsigned int __bitmap_weighted_xor(unsigned long *dst, const unsigned long *bitmap1,
+ const unsigned long *bitmap2, unsigned int nbits);
void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
const unsigned long *bitmap2, unsigned int nbits);
bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
@@ -353,6 +357,18 @@ unsigned int bitmap_weighted_or(unsigned long *dst, const unsigned long *src1,
}
static __always_inline
+unsigned int bitmap_weighted_xor(unsigned long *dst, const unsigned long *src1,
+ const unsigned long *src2, unsigned int nbits)
+{
+ if (small_const_nbits(nbits)) {
+ *dst = *src1 ^ *src2;
+ return hweight_long(*dst & BITMAP_LAST_WORD_MASK(nbits));
+ } else {
+ return __bitmap_weighted_xor(dst, src1, src2, nbits);
+ }
+}
+
+static __always_inline
void bitmap_xor(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, unsigned int nbits)
{
@@ -479,6 +495,38 @@ unsigned long bitmap_weight_andnot(const unsigned long *src1,
return __bitmap_weight_andnot(src1, src2, nbits);
}
+/**
+ * bitmap_weight_from - Hamming weight for a memory region
+ * @bitmap: The base address
+ * @start: The bitnumber to starts weighting
+ * @end: the bitmap size in bits
+ *
+ * Returns the number of set bits in the region. If @start >= @end,
+ * return >= end.
+ */
+static __always_inline
+unsigned long bitmap_weight_from(const unsigned long *bitmap,
+ unsigned int start, unsigned int end)
+{
+ unsigned long w;
+
+ if (unlikely(start >= end))
+ return end;
+
+ if (small_const_nbits(end))
+ return hweight_long(*bitmap & GENMASK(end - 1, start));
+
+ bitmap += start / BITS_PER_LONG;
+ /* Opencode round_down() to not include math.h */
+ end -= start & ~(BITS_PER_LONG - 1);
+ start %= BITS_PER_LONG;
+ w = bitmap_weight(bitmap, end);
+ if (start)
+ w -= hweight_long(*bitmap & BITMAP_LAST_WORD_MASK(start));
+
+ return w;
+}
+
static __always_inline
void bitmap_set(unsigned long *map, unsigned int start, unsigned int nbits)
{