diff --git a/arch/m32r/boot/setup.S b/arch/m32r/boot/setup.S
index 742669fab8a915d9372d10f7b1b619e3d7912b73..398542507d84aead8075127c07c625fb81f49d54 100644
--- a/arch/m32r/boot/setup.S
+++ b/arch/m32r/boot/setup.S
@@ -1,11 +1,10 @@
 /*
  *  linux/arch/m32r/boot/setup.S -- A setup code.
  *
- *  Copyright (C) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *  and Hitoshi Yamamoto
+ *  Copyright (C) 2001-2005   Hiroyuki Kondo, Hirokazu Takata,
+ *                            Hitoshi Yamamoto, Hayato Fujiwara
  *
  */
-/* $Id$ */
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
@@ -81,6 +80,16 @@ ENTRY(boot)
 ;	ldi	r1, #0x00		; cache off
 	st	r1, @r0
 #elif defined(CONFIG_CHIP_M32104)
+	ldi	r0, #-96		; DNCR0
+	seth	r1, #0x0060		;  from 0x00600000
+	or3	r1, r1, #0x0005		;  size 2MB
+	st	r1, @r0
+	seth	r1, #0x0100		;  from 0x01000000
+	or3	r1, r1, #0x0003		;  size 16MB
+	st	r1, @+r0
+	seth	r1, #0x0200		;  from 0x02000000
+	or3	r1, r1, #0x0002		;  size 32MB
+	st	r1, @+r0
 	ldi	r0, #-4              ;LDIMM	(r0, M32R_MCCR)
 	ldi	r1, #0x703		; cache on (with invalidation)
 	st	r1, @r0
diff --git a/arch/m32r/mm/cache.c b/arch/m32r/mm/cache.c
index c6f72a64ae12e4c85c8c7f6219eeb198763f66a9..9f54dd9370132452517c853162462e6005d781f8 100644
--- a/arch/m32r/mm/cache.c
+++ b/arch/m32r/mm/cache.c
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/m32r/mm/cache.c
  *
- *  Copyright (C) 2002  Hirokazu Takata
+ *  Copyright (C) 2002-2005  Hirokazu Takata, Hayato Fujiwara
  */
 
 #include <linux/config.h>
@@ -9,7 +9,8 @@
 
 #undef MCCR
 
-#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP)
+#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) \
+	|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP)
 /* Cache Control Register */
 #define MCCR		((volatile unsigned long*)0xfffffffc)
 #define MCCR_CC		(1UL << 7)	/* Cache mode modify bit */
@@ -27,7 +28,7 @@
 #define MCCR_IIV	(1UL << 0)	/* I-cache invalidate */
 #define MCCR_ICACHE_INV		MCCR_IIV
 #elif defined(CONFIG_CHIP_M32104)
-#define MCCR		((volatile unsigned long*)0xfffffffc)
+#define MCCR		((volatile unsigned short*)0xfffffffe)
 #define MCCR_IIV	(1UL << 8)	/* I-cache invalidate */
 #define MCCR_DIV	(1UL << 9)	/* D-cache invalidate */
 #define MCCR_DCB	(1UL << 10)	/* D-cache copy back */
@@ -36,7 +37,7 @@
 #define MCCR_ICACHE_INV		MCCR_IIV
 #define MCCR_DCACHE_CB		MCCR_DCB
 #define MCCR_DCACHE_CBINV	(MCCR_DIV|MCCR_DCB)
-#endif /* CONFIG_CHIP_XNUX2 || CONFIG_CHIP_M32700 */
+#endif
 
 #ifndef MCCR
 #error Unknown cache type.
@@ -47,29 +48,42 @@
 void _flush_cache_all(void)
 {
 #if defined(CONFIG_CHIP_M32102)
+	unsigned char mccr;
 	*MCCR = MCCR_ICACHE_INV;
+#elif defined(CONFIG_CHIP_M32104)
+	unsigned short mccr;
+
+	/* Copyback and invalidate D-cache */
+	/* Invalidate I-cache */
+	*MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CBINV);
 #else
 	unsigned long mccr;
 
 	/* Copyback and invalidate D-cache */
 	/* Invalidate I-cache */
 	*MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CBINV;
-	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 #endif
+	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 }
 
 /* Copy back D-cache and invalidate I-cache all */
 void _flush_cache_copyback_all(void)
 {
 #if defined(CONFIG_CHIP_M32102)
+	unsigned char mccr;
 	*MCCR = MCCR_ICACHE_INV;
+#elif defined(CONFIG_CHIP_M32104)
+	unsigned short mccr;
+
+	/* Copyback and invalidate D-cache */
+	/* Invalidate I-cache */
+	*MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CB);
 #else
 	unsigned long mccr;
 
 	/* Copyback D-cache */
 	/* Invalidate I-cache */
 	*MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CB;
-	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
-
 #endif
+	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 }