printk: collect printk stuff into <linux/printk.h> with loglevel support

When we import code from Linux, with regular re-sync planned, we want
to use printk() and pr_*().  U-Boot does not support them in a clean
way.  So, people end up with local macros, or compat headers here and
there, then we occasionally see build errors of definition conflicts.

We have include/linux/compat.h, but putting all sorts of unrelated
things into a single header is just a temporal workaround.  Hence this
patch, to find the best home for all printk variants.  If you want to
use printk() and friends, please include <linux/printk.h>.  This header
is self-contained, and pulls in only a few headers.

When I was testing this clean-up, I noticed the image size exceeded
its platform limit on some boards.  This is because all pr_*() that
were previously defined as no-op in include/linux/mtd/mtd.h (unless
CONFIG_MTD_DEBUG is set), are now enabled.

To make such boards happy, this commit also implements CONFIG_LOGLEVEL.
The concept is similar to the kernel parameter "loglevel".  (Actually,
the Kconfig help message was taken from kernel-paremeter.txt of Linux)
Messages with a loglevel smaller than console loglevel will be printed.

The difference is the loglevel is build-time determined.  To save the
image size, lower priority pr_*() are compiled out.  I set the default
of CONFIG_LOGLEVEL to 6, i.e. pr_notice and higher priority messages
are compiled in.

I adjusted CONFIG_LOGLEVEL to avoid build error for some boards.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
[trini: Add in SPL_LOGLEVEL that is the same as LOGLEVEL]
Signed-off-by: Tom Rini <trini@konsulko.com>
diff --git a/include/common.h b/include/common.h
index 5e84194..4eb9229 100644
--- a/include/common.h
+++ b/include/common.h
@@ -25,6 +25,7 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/types.h>
+#include <linux/printk.h>
 #include <linux/string.h>
 #include <linux/stringify.h>
 #include <asm/ptrace.h>
@@ -55,11 +56,6 @@
 #define _SPL_BUILD	0
 #endif
 
-/* Define this at the top of a file to add a prefix to debug messages */
-#ifndef pr_fmt
-#define pr_fmt(fmt) fmt
-#endif
-
 /*
  * Output a debug text when condition "cond" is met. The "cond" should be
  * computed by a preprocessor in the best case, allowing for the best
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 2336b56..bc027ad 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -25,17 +25,6 @@
 	printf(fmt, ##args)
 #define dev_warn(dev, fmt, args...)		\
 	printf(fmt, ##args)
-#define printk	printf
-#define printk_once	printf
-
-#define KERN_EMERG
-#define KERN_ALERT
-#define KERN_CRIT
-#define KERN_ERR
-#define KERN_WARNING
-#define KERN_NOTICE
-#define KERN_INFO
-#define KERN_DEBUG
 
 #define GFP_ATOMIC ((gfp_t) 0)
 #define GFP_KERNEL ((gfp_t) 0)
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 1fd17c3..3e1694b 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -452,28 +452,20 @@
 #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */
 
 #ifdef CONFIG_MTD_DEBUG
-#define pr_debug(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
 #define MTDDEBUG(n, args...)				\
 	do {						\
 		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\
 			printk(KERN_INFO args);		\
 	} while(0)
 #else /* CONFIG_MTD_DEBUG */
-#define pr_debug(args...)
 #define MTDDEBUG(n, args...)				\
 	do {						\
 		if (0)					\
 			printk(KERN_INFO args);		\
 	} while(0)
 #endif /* CONFIG_MTD_DEBUG */
-#define pr_info(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
-#define pr_warn(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
-#define pr_err(args...)		MTDDEBUG(MTD_DEBUG_LEVEL0, args)
-#define pr_crit(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
-#define pr_cont(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
-#define pr_notice(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)
 #endif
- 
+
 static inline int mtd_is_bitflip(int err) {
 	return err == -EUCLEAN;
 }
diff --git a/include/linux/printk.h b/include/linux/printk.h
new file mode 100644
index 0000000..088513a
--- /dev/null
+++ b/include/linux/printk.h
@@ -0,0 +1,79 @@
+#ifndef __KERNEL_PRINTK__
+#define __KERNEL_PRINTK__
+
+#include <stdio.h>
+#include <linux/compiler.h>
+
+#define KERN_EMERG
+#define KERN_ALERT
+#define KERN_CRIT
+#define KERN_ERR
+#define KERN_WARNING
+#define KERN_NOTICE
+#define KERN_INFO
+#define KERN_DEBUG
+#define KERN_CONT
+
+#define printk(fmt, ...) \
+	printf(fmt, ##__VA_ARGS__)
+
+/*
+ * Dummy printk for disabled debugging statements to use whilst maintaining
+ * gcc's format checking.
+ */
+#define no_printk(fmt, ...)				\
+({							\
+	if (0)						\
+		printk(fmt, ##__VA_ARGS__);		\
+	0;						\
+})
+
+#define __printk(level, fmt, ...)					\
+({									\
+	level < CONFIG_LOGLEVEL ? printk(fmt, ##__VA_ARGS__) : 0;	\
+})
+
+#ifndef pr_fmt
+#define pr_fmt(fmt) fmt
+#endif
+
+#define pr_emerg(fmt, ...) \
+	__printk(0, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_alert(fmt, ...) \
+	__printk(1, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_crit(fmt, ...) \
+	__printk(2, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_err(fmt, ...) \
+	__printk(3, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warning(fmt, ...) \
+	__printk(4, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_warn pr_warning
+#define pr_notice(fmt, ...) \
+	__printk(5, pr_fmt(fmt), ##__VA_ARGS__)
+#define pr_info(fmt, ...) \
+	__printk(6, pr_fmt(fmt), ##__VA_ARGS__)
+
+#define pr_cont(fmt, ...) \
+	printk(fmt, ##__VA_ARGS__)
+
+/* pr_devel() should produce zero code unless DEBUG is defined */
+#ifdef DEBUG
+#define pr_devel(fmt, ...) \
+	__printk(7, pr_fmt(fmt), ##__VA_ARGS__)
+#else
+#define pr_devel(fmt, ...) \
+	no_printk(pr_fmt(fmt), ##__VA_ARGS__)
+#endif
+
+#ifdef DEBUG
+#define pr_debug(fmt, ...) \
+	__printk(7, pr_fmt(fmt), ##__VA_ARGS__)
+#else
+#define pr_debug(fmt, ...) \
+	no_printk(pr_fmt(fmt), ##__VA_ARGS__)
+#endif
+
+#define printk_once(fmt, ...) \
+	printk(fmt, ##__VA_ARGS__)
+
+#endif