summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Packham <judge.packham@gmail.com>2023-03-20 10:23:43 +1300
committerTom Rini <trini@konsulko.com>2023-03-30 15:09:59 -0400
commitb5f045e12fea0a64a3749c4da1bdfd579530b67e (patch)
tree80a9d7bee027eac1f34c6d17c7ad2400d7cc87b0
parentd87bdb82eae66512c222fd93280acaf4dd1cd4be (diff)
downloadu-boot-b5f045e12fea0a64a3749c4da1bdfd579530b67e.tar.gz
u-boot-b5f045e12fea0a64a3749c4da1bdfd579530b67e.tar.bz2
u-boot-b5f045e12fea0a64a3749c4da1bdfd579530b67e.zip
include: kernel.h: port find_closest() from Linux
The find_closest() macro can be used to find an element in a sorted array that is closest to an input value. Bring in this macro from Linux v6.3-rc1-2-g8ca09d5fa354. Signed-off-by: Chris Packham <judge.packham@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
-rw-r--r--include/linux/kernel.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 3e71d61074..5cd6c9dc82 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -284,4 +284,28 @@
offsetof(struct structure, member) == (offset), \
"`struct " #structure "` offset for `" #member "` is not " #offset)
+#define __find_closest(x, a, as, op) \
+({ \
+ typeof(as) __fc_i, __fc_as = (as) - 1; \
+ typeof(x) __fc_x = (x); \
+ typeof(*a) const *__fc_a = (a); \
+ for (__fc_i = 0; __fc_i < __fc_as; __fc_i++) { \
+ if (__fc_x op DIV_ROUND_CLOSEST(__fc_a[__fc_i] + \
+ __fc_a[__fc_i + 1], 2)) \
+ break; \
+ } \
+ (__fc_i); \
+})
+
+/**
+ * find_closest - locate the closest element in a sorted array
+ * @x: The reference value.
+ * @a: The array in which to look for the closest element. Must be sorted
+ * in ascending order.
+ * @as: Size of 'a'.
+ *
+ * Returns the index of the element closest to 'x'.
+ */
+#define find_closest(x, a, as) __find_closest(x, a, as, <=)
+
#endif