diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c
index 32d359321ae2..22136855fa1a 100644
--- a/arch/arm/mach-uniphier/dram_init.c
+++ b/arch/arm/mach-uniphier/dram_init.c
@@ -15,9 +15,6 @@
 #include "sg-regs.h"
 #include "soc-info.h"
 
-#define pr_warn(fmt, args...)	printf(fmt, ##args)
-#define pr_err(fmt, args...)	printf(fmt, ##args)
-
 DECLARE_GLOBAL_DATA_PTR;
 
 struct uniphier_memif_data {
diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h
index 29f638d94703..da209354ed50 100644
--- a/arch/arm/mach-uniphier/init.h
+++ b/arch/arm/mach-uniphier/init.h
@@ -104,9 +104,4 @@ int uniphier_have_internal_stm(void);
 int uniphier_boot_from_backend(void);
 int uniphier_pin_init(const char *pinconfig_name);
 
-#undef pr_warn
-#define pr_warn(fmt, args...)	printf(fmt, ##args)
-#undef pr_err
-#define pr_err(fmt, args...)	printf(fmt, ##args)
-
 #endif /* __MACH_INIT_H */
diff --git a/common/Kconfig b/common/Kconfig
index 4d8cae96109a..79fe781ba59f 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -243,6 +243,23 @@ config IDENT_STRING
 	help
 	  This options adds the board specific name to u-boot version.
 
+config LOGLEVEL
+	int "loglevel"
+	default 6
+	range 0 8
+	help
+	  All Messages with a loglevel smaller than the console loglevel will
+	  be compiled in. The loglevels are defined as follows:
+
+	  0 (KERN_EMERG)          system is unusable
+	  1 (KERN_ALERT)          action must be taken immediately
+	  2 (KERN_CRIT)           critical conditions
+	  3 (KERN_ERR)            error conditions
+	  4 (KERN_WARNING)        warning conditions
+	  5 (KERN_NOTICE)         normal but significant condition
+	  6 (KERN_INFO)           informational
+	  7 (KERN_DEBUG)          debug-level messages
+
 config SILENT_CONSOLE
 	bool "Support a silent console"
 	help
diff --git a/configs/axm_defconfig b/configs/axm_defconfig
index 81654b230431..cd89c2a235ff 100644
--- a/configs/axm_defconfig
+++ b/configs/axm_defconfig
@@ -41,3 +41,4 @@ CONFIG_SPI_FLASH=y
 CONFIG_SPI_FLASH_STMICRO=y
 CONFIG_PHYLIB=y
 CONFIG_USE_TINY_PRINTF=y
+CONFIG_LOGLEVEL=4
diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig
index 1ffe86180974..49315d0638ed 100644
--- a/configs/colibri_vf_defconfig
+++ b/configs/colibri_vf_defconfig
@@ -6,6 +6,7 @@ CONFIG_TARGET_COLIBRI_VF=y
 CONFIG_DEFAULT_DEVICE_TREE="vf610-colibri"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/toradex/colibri_vf/imximage.cfg,IMX_NAND"
 CONFIG_BOOTDELAY=1
+CONFIG_LOGLEVEL=3
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_ARCH_MISC_INIT=y
diff --git a/configs/corvus_defconfig b/configs/corvus_defconfig
index 705e00145700..059cb5992e92 100644
--- a/configs/corvus_defconfig
+++ b/configs/corvus_defconfig
@@ -14,6 +14,7 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9M10G45,MACH_TYPE=2066,SYS_USE_NANDFLASH"
 CONFIG_BOOTDELAY=3
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) root=/dev/mtdblock7 rw rootfstype=jffs2"
+CONFIG_LOGLEVEL=4
 # CONFIG_DISPLAY_BOARDINFO is not set
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL=y
diff --git a/configs/omapl138_lcdk_defconfig b/configs/omapl138_lcdk_defconfig
index c95134bcf990..3e9eb4fa84e2 100644
--- a/configs/omapl138_lcdk_defconfig
+++ b/configs/omapl138_lcdk_defconfig
@@ -8,6 +8,7 @@ CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_NAND_SUPPORT=y
 CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=4
 CONFIG_VERSION_VARIABLE=y
 # CONFIG_DISPLAY_CPUINFO is not set
 # CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/openrd_base_defconfig b/configs/openrd_base_defconfig
index b2a0e04d36ce..f31af1c3fe75 100644
--- a/configs/openrd_base_defconfig
+++ b/configs/openrd_base_defconfig
@@ -5,6 +5,7 @@ CONFIG_TARGET_OPENRD=y
 CONFIG_IDENT_STRING="\nOpenRD-Base"
 CONFIG_SYS_EXTRA_OPTIONS="BOARD_IS_OPENRD_BASE"
 CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=3
 # CONFIG_DISPLAY_BOARDINFO is not set
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
diff --git a/configs/openrd_client_defconfig b/configs/openrd_client_defconfig
index 8b1d35edd10f..bee818b82cc1 100644
--- a/configs/openrd_client_defconfig
+++ b/configs/openrd_client_defconfig
@@ -5,6 +5,7 @@ CONFIG_TARGET_OPENRD=y
 CONFIG_IDENT_STRING="\nOpenRD-Client"
 CONFIG_SYS_EXTRA_OPTIONS="BOARD_IS_OPENRD_CLIENT"
 CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=3
 # CONFIG_DISPLAY_BOARDINFO is not set
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
diff --git a/configs/openrd_ultimate_defconfig b/configs/openrd_ultimate_defconfig
index 4cc0205629f6..e9462e59b2f1 100644
--- a/configs/openrd_ultimate_defconfig
+++ b/configs/openrd_ultimate_defconfig
@@ -5,6 +5,7 @@ CONFIG_TARGET_OPENRD=y
 CONFIG_IDENT_STRING="\nOpenRD-Ultimate"
 CONFIG_SYS_EXTRA_OPTIONS="BOARD_IS_OPENRD_ULTIMATE"
 CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=3
 # CONFIG_DISPLAY_BOARDINFO is not set
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig
index 71a382a3e132..5b7fc8ae1466 100644
--- a/configs/taurus_defconfig
+++ b/configs/taurus_defconfig
@@ -16,6 +16,7 @@ CONFIG_SPL_SPI_SUPPORT=y
 CONFIG_DEFAULT_DEVICE_TREE="at91sam9g20-taurus"
 CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20,MACH_TYPE=2067,BOARD_TAURUS"
 CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=4
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) root=/dev/mtdblock7 rw rootfstype=jffs2"
 # CONFIG_DISPLAY_BOARDINFO is not set
diff --git a/configs/vf610twr_defconfig b/configs/vf610twr_defconfig
index 948ea73edb91..3c277be6828f 100644
--- a/configs/vf610twr_defconfig
+++ b/configs/vf610twr_defconfig
@@ -3,6 +3,7 @@ CONFIG_ARCH_VF610=y
 CONFIG_DEFAULT_DEVICE_TREE="vf610-twr"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/vf610twr/imximage.cfg"
 CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=3
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
diff --git a/configs/vf610twr_nand_defconfig b/configs/vf610twr_nand_defconfig
index 10cdf0646c98..1cd22b1b8b31 100644
--- a/configs/vf610twr_nand_defconfig
+++ b/configs/vf610twr_nand_defconfig
@@ -3,6 +3,7 @@ CONFIG_ARCH_VF610=y
 CONFIG_DEFAULT_DEVICE_TREE="vf610-twr"
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/vf610twr/imximage.cfg"
 CONFIG_BOOTDELAY=3
+CONFIG_LOGLEVEL=3
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
diff --git a/drivers/bios_emulator/include/x86emu/x86emui.h b/drivers/bios_emulator/include/x86emu/x86emui.h
index a74957d992aa..3537255539fe 100644
--- a/drivers/bios_emulator/include/x86emu/x86emui.h
+++ b/drivers/bios_emulator/include/x86emu/x86emui.h
@@ -72,9 +72,6 @@
 #include <string.h>
 #endif
 
-#define printk printf
-
-
 /*--------------------------- Inline Functions ----------------------------*/
 
 #ifdef  __cplusplus
diff --git a/drivers/usb/dwc3/linux-compat.h b/drivers/usb/dwc3/linux-compat.h
index 9e944a31be11..64db4ecc3c6f 100644
--- a/drivers/usb/dwc3/linux-compat.h
+++ b/drivers/usb/dwc3/linux-compat.h
@@ -12,7 +12,6 @@
 #ifndef __DWC3_LINUX_COMPAT__
 #define __DWC3_LINUX_COMPAT__
 
-#define pr_debug(format)                debug(format)
 #define WARN(val, format, arg...)	debug(format, ##arg)
 #define dev_WARN(dev, format, arg...)	debug(format, ##arg)
 #define WARN_ON_ONCE(val)		debug("Error %d\n", val)
diff --git a/drivers/usb/musb-new/linux-compat.h b/drivers/usb/musb-new/linux-compat.h
index 4dae83ed6850..7bb53d2b198e 100644
--- a/drivers/usb/musb-new/linux-compat.h
+++ b/drivers/usb/musb-new/linux-compat.h
@@ -5,8 +5,6 @@
 #include <linux/list.h>
 #include <linux/compat.h>
 
-#define pr_debug(fmt, args...) debug(fmt, ##args)
-
 #define WARN(condition, fmt, args...) ({	\
 	int ret_warn = !!condition;		\
 	if (ret_warn)				\
diff --git a/include/common.h b/include/common.h
index 5e841947c17f..4eb92298a207 100644
--- a/include/common.h
+++ b/include/common.h
@@ -25,6 +25,7 @@ typedef volatile unsigned char	vu_char;
 #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 @@ typedef volatile unsigned char	vu_char;
 #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 2336b56cf5c1..bc027adcb936 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -25,17 +25,6 @@ extern struct p_current *current;
 	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 1fd17c303a8d..3e1694b3a5d3 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -452,28 +452,20 @@ static inline void mtd_erase_callback(struct erase_info *instr)
 #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 000000000000..088513ad29bb
--- /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
