diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c
index 391feb3250e42f665627c11cc7d07f182ffc2b4f..1b919ed82289d1d4d30e4daccf057c8c4e89e9ed 100644
--- a/arch/mips/cpu/cpu.c
+++ b/arch/mips/cpu/cpu.c
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <command.h>
 #include <linux/compiler.h>
+#include <asm/cache.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 
@@ -35,3 +36,9 @@ void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
 	write_c0_index(index);
 	tlb_write_indexed();
 }
+
+int arch_cpu_init(void)
+{
+	mips_cache_probe();
+	return 0;
+}
diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
index 0cea581e5d8cd1575653c0730fdc32790b01321a..669c362a52a563ab6f7dfcf43188b8559644b69d 100644
--- a/arch/mips/include/asm/cache.h
+++ b/arch/mips/include/asm/cache.h
@@ -19,4 +19,13 @@
  */
 #define CONFIG_SYS_CACHELINE_SIZE ARCH_DMA_MINALIGN
 
+/**
+ * mips_cache_probe() - Probe the properties of the caches
+ *
+ * Call this to probe the properties such as line sizes of the caches
+ * present in the system, if any. This must be done before cache maintenance
+ * functions such as flush_cache may be called.
+ */
+void mips_cache_probe(void);
+
 #endif /* __MIPS_CACHE_H__ */
diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
index 37f8ed52e6a4ff07612a93948b4d6e255aa62bac..8533b691b656ebd7c39f7804ed9af119572ca1cd 100644
--- a/arch/mips/include/asm/global_data.h
+++ b/arch/mips/include/asm/global_data.h
@@ -21,6 +21,10 @@ struct arch_global_data {
 	unsigned long rev;
 	unsigned long ver;
 #endif
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+	unsigned short l1i_line_size;
+	unsigned short l1d_line_size;
+#endif
 };
 
 #include <asm-generic/global_data.h>
diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c
index db81953f86c5486bd1730fed99ac72a5b52f7401..d8baf08aa85238645e8a49e5a8788979c2d9c81c 100644
--- a/arch/mips/lib/cache.c
+++ b/arch/mips/lib/cache.c
@@ -9,32 +9,39 @@
 #include <asm/cacheops.h>
 #include <asm/mipsregs.h>
 
-static inline unsigned long icache_line_size(void)
-{
-	unsigned long conf1, il;
+DECLARE_GLOBAL_DATA_PTR;
 
-	if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
-		return CONFIG_SYS_ICACHE_LINE_SIZE;
+void mips_cache_probe(void)
+{
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+	unsigned long conf1, il, dl;
 
 	conf1 = read_c0_config1();
+
 	il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHF;
-	if (!il)
-		return 0;
-	return 2 << il;
+	dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
+
+	gd->arch.l1i_line_size = il ? (2 << il) : 0;
+	gd->arch.l1d_line_size = dl ? (2 << dl) : 0;
+#endif
 }
 
-static inline unsigned long dcache_line_size(void)
+static inline unsigned long icache_line_size(void)
 {
-	unsigned long conf1, dl;
-
-	if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
-		return CONFIG_SYS_DCACHE_LINE_SIZE;
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+	return gd->arch.l1i_line_size;
+#else
+	return CONFIG_SYS_ICACHE_LINE_SIZE;
+#endif
+}
 
-	conf1 = read_c0_config1();
-	dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
-	if (!dl)
-		return 0;
-	return 2 << dl;
+static inline unsigned long dcache_line_size(void)
+{
+#ifdef CONFIG_SYS_CACHE_SIZE_AUTO
+	return gd->arch.l1d_line_size;
+#else
+	return CONFIG_SYS_DCACHE_LINE_SIZE;
+#endif
 }
 
 #define cache_loop(start, end, lsize, ops...) do {			\