---
 include/linux/kernel.h |   63 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff -r ae13f2576296 include/linux/kernel.h
--- a/include/linux/kernel.h	Mon Apr 07 15:27:35 2008 +1000
+++ b/include/linux/kernel.h	Mon Apr 07 15:39:49 2008 +1000
@@ -436,4 +436,67 @@ struct sysinfo {
 #define NUMA_BUILD 0
 #endif
 
+/**
+ * typesafe_cb - cast a callback function if it matches the arg
+ * @rettype: the return type of the callback function
+ * @fn: the callback function to cast
+ * @arg: the (pointer) argument to hand to the callback function.
+ *
+ * If a callback function takes a single argument, this macro does
+ * appropriate casts to a function which takes a single void * argument if the
+ * callback provided matches the @arg (or a const or volatile version).
+ *
+ * It is assumed that @arg is of pointer type: usually @arg is passed
+ * or assigned to a void * elsewhere anyway.
+ */
+#define typesafe_cb(rettype, fn, arg)					\
+	cast_if_type(cast_if_type(cast_if_type((fn),			\
+					       rettype (*)(const typeof(arg)), \
+					       rettype (*)(void *)),	\
+				  rettype (*)(volatile typeof(arg)),	\
+				  rettype (*)(void *)),			\
+		     rettype (*)(typeof(arg)),				\
+		     rettype (*)(void *))
+
+/**
+ * typesafe_cb_preargs - cast a callback function if it matches the arg
+ * @rettype: the return type of the callback function
+ * @fn: the callback function to cast
+ * @arg: the (pointer) argument to hand to the callback function.
+ *
+ * This is a version of typesafe_cb() for callbacks that take other arguments
+ * before the @arg.
+ */
+#define typesafe_cb_preargs(rettype, fn, arg, ...)			\
+	cast_if_type(cast_if_type(cast_if_type((fn),			\
+					       rettype (*)(__VA_ARGS__,	\
+							   const typeof(arg)), \
+					       rettype (*)(__VA_ARGS__,	\
+							   void *)),	\
+				  rettype (*)(__VA_ARGS__,		\
+					      volatile typeof(arg)),	\
+				  rettype (*)(__VA_ARGS__, void *)),	\
+		     rettype (*)(__VA_ARGS__, typeof(arg)),		\
+		     rettype (*)(__VA_ARGS__, void *))
+
+/**
+ * typesafe_cb_postargs - cast a callback function if it matches the arg
+ * @rettype: the return type of the callback function
+ * @fn: the callback function to cast
+ * @arg: the (pointer) argument to hand to the callback function.
+ *
+ * This is a version of typesafe_cb() for callbacks that take other arguments
+ * after the @arg.
+ */
+#define typesafe_cb_postargs(rettype, fn, arg, ...)			\
+	cast_if_type(cast_if_type(cast_if_type((fn),			\
+					       rettype (*)(const typeof(arg), \
+							   __VA_ARGS__), \
+					       rettype (*)(void *,	\
+							   __VA_ARGS__)), \
+				  rettype (*)(volatile typeof(arg),	\
+					      __VA_ARGS__),		\
+				  rettype (*)(void *, __VA_ARGS__)),	\
+		     rettype (*)(typeof(arg), __VA_ARGS__),		\
+		     rettype (*)(void *, __VA_ARGS__))
 #endif
