summary refs log tree commit diff
path: root/arch/arm/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-07-02 15:04:12 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-02 15:04:12 -0700
commita8c4c20dfa8b28a3c99e33c639d9c2ea5657741e (patch)
tree887b64d29b5a46d9ab2ca1267d8a2f05b5845561 /arch/arm/mm
parent168d04b3b4de7723eb73b3cffc9cb75224e0f393 (diff)
parent2dc7667b9d0674db6572723356fe3857031101a4 (diff)
downloadlinux-a8c4c20dfa8b28a3c99e33c639d9c2ea5657741e.tar.gz
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (44 commits)
  [ARM] 3541/2: workaround for PXA27x erratum E7
  [ARM] nommu: provide a way for correct control register value selection
  [ARM] 3705/1: add supersection support to ioremap()
  [ARM] 3707/1: iwmmxt: use the generic thread notifier infrastructure
  [ARM] 3706/2: ep93xx: add cirrus logic edb9315a support
  [ARM] 3704/1: format IOP Kconfig with tabs, create more consistency
  [ARM] 3703/1: Add help description for ARCH_EP80219
  [ARM] 3678/1: MMC: Make OMAP MMC work
  [ARM] 3677/1: OMAP: Update H2 defconfig
  [ARM] 3676/1: ARM: OMAP: Fix dmtimers and timer32k to compile on OMAP1
  [ARM] Add section support to ioremap
  [ARM] Fix sa11x0 SDRAM selection
  [ARM] Set bit 4 on section mappings correctly depending on CPU
  [ARM] 3666/1: TRIZEPS4 [1/5] core
  ARM: OMAP: Multiplexing for 24xx GPMC wait pin monitoring
  ARM: OMAP: Fix SRAM to use MT_MEMORY instead of MT_DEVICE
  ARM: OMAP: Update dmtimers
  ARM: OMAP: Make clock variables static
  ARM: OMAP: Fix GPMC compilation when DEBUG is defined
  ARM: OMAP: Mux updates for external DMA and GPIO
  ...
Diffstat (limited to 'arch/arm/mm')
-rw-r--r--arch/arm/mm/Kconfig4
-rw-r--r--arch/arm/mm/ioremap.c227
-rw-r--r--arch/arm/mm/mm-armv.c37
-rw-r--r--arch/arm/mm/proc-arm1020.S19
-rw-r--r--arch/arm/mm/proc-arm1020e.S39
-rw-r--r--arch/arm/mm/proc-arm1022.S39
-rw-r--r--arch/arm/mm/proc-arm1026.S39
-rw-r--r--arch/arm/mm/proc-arm6_7.S16
-rw-r--r--arch/arm/mm/proc-arm720.S23
-rw-r--r--arch/arm/mm/proc-arm920.S33
-rw-r--r--arch/arm/mm/proc-arm922.S33
-rw-r--r--arch/arm/mm/proc-arm925.S39
-rw-r--r--arch/arm/mm/proc-arm926.S36
-rw-r--r--arch/arm/mm/proc-macros.S10
-rw-r--r--arch/arm/mm/proc-sa110.S19
-rw-r--r--arch/arm/mm/proc-sa1100.S21
-rw-r--r--arch/arm/mm/proc-v6.S19
-rw-r--r--arch/arm/mm/proc-xsc3.S28
-rw-r--r--arch/arm/mm/proc-xscale.S63
19 files changed, 480 insertions, 264 deletions
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c4bca753165b..5f80f184cd32 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -121,8 +121,8 @@ config CPU_ARM925T
 # ARM926T
 config CPU_ARM926T
 	bool "Support ARM926T processor"
-	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412
-	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412
+	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261
+	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261
 	select CPU_32v5
 	select CPU_ABRT_EV5TJ
 	select CPU_CACHE_VIVT
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 7691cfdba567..7eac87f05180 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -27,7 +27,16 @@
 
 #include <asm/cacheflush.h>
 #include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
+#include <asm/sizes.h>
+
+/*
+ * Used by ioremap() and iounmap() code to mark (super)section-mapped
+ * I/O regions in vm_struct->flags field.
+ */
+#define VM_ARM_SECTION_MAPPING	0x80000000
 
 static inline void
 remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
@@ -113,10 +122,168 @@ remap_area_pages(unsigned long start, unsigned long pfn,
 		dir++;
 	} while (address && (address < end));
 
-	flush_cache_vmap(start, end);
 	return err;
 }
 
+
+void __check_kvm_seq(struct mm_struct *mm)
+{
+	unsigned int seq;
+
+	do {
+		seq = init_mm.context.kvm_seq;
+		memcpy(pgd_offset(mm, VMALLOC_START),
+		       pgd_offset_k(VMALLOC_START),
+		       sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
+					pgd_index(VMALLOC_START)));
+		mm->context.kvm_seq = seq;
+	} while (seq != init_mm.context.kvm_seq);
+}
+
+#ifndef CONFIG_SMP
+/*
+ * Section support is unsafe on SMP - If you iounmap and ioremap a region,
+ * the other CPUs will not see this change until their next context switch.
+ * Meanwhile, (eg) if an interrupt comes in on one of those other CPUs
+ * which requires the new ioremap'd region to be referenced, the CPU will
+ * reference the _old_ region.
+ *
+ * Note that get_vm_area() allocates a guard 4K page, so we need to mask
+ * the size back to 1MB aligned or we will overflow in the loop below.
+ */
+static void unmap_area_sections(unsigned long virt, unsigned long size)
+{
+	unsigned long addr = virt, end = virt + (size & ~SZ_1M);
+	pgd_t *pgd;
+
+	flush_cache_vunmap(addr, end);
+	pgd = pgd_offset_k(addr);
+	do {
+		pmd_t pmd, *pmdp = pmd_offset(pgd, addr);
+
+		pmd = *pmdp;
+		if (!pmd_none(pmd)) {
+			/*
+			 * Clear the PMD from the page table, and
+			 * increment the kvm sequence so others
+			 * notice this change.
+			 *
+			 * Note: this is still racy on SMP machines.
+			 */
+			pmd_clear(pmdp);
+			init_mm.context.kvm_seq++;
+
+			/*
+			 * Free the page table, if there was one.
+			 */
+			if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE)
+				pte_free_kernel(pmd_page_kernel(pmd));
+		}
+
+		addr += PGDIR_SIZE;
+		pgd++;
+	} while (addr < end);
+
+	/*
+	 * Ensure that the active_mm is up to date - we want to
+	 * catch any use-after-iounmap cases.
+	 */
+	if (current->active_mm->context.kvm_seq != init_mm.context.kvm_seq)
+		__check_kvm_seq(current->active_mm);
+
+	flush_tlb_kernel_range(virt, end);
+}
+
+static int
+remap_area_sections(unsigned long virt, unsigned long pfn,
+		    unsigned long size, unsigned long flags)
+{
+	unsigned long prot, addr = virt, end = virt + size;
+	pgd_t *pgd;
+
+	/*
+	 * Remove and free any PTE-based mapping, and
+	 * sync the current kernel mapping.
+	 */
+	unmap_area_sections(virt, size);
+
+	prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO) |
+	       (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE));
+
+	/*
+	 * ARMv6 and above need XN set to prevent speculative prefetches
+	 * hitting IO.
+	 */
+	if (cpu_architecture() >= CPU_ARCH_ARMv6)
+		prot |= PMD_SECT_XN;
+
+	pgd = pgd_offset_k(addr);
+	do {
+		pmd_t *pmd = pmd_offset(pgd, addr);
+
+		pmd[0] = __pmd(__pfn_to_phys(pfn) | prot);
+		pfn += SZ_1M >> PAGE_SHIFT;
+		pmd[1] = __pmd(__pfn_to_phys(pfn) | prot);
+		pfn += SZ_1M >> PAGE_SHIFT;
+		flush_pmd_entry(pmd);
+
+		addr += PGDIR_SIZE;
+		pgd++;
+	} while (addr < end);
+
+	return 0;
+}
+
+static int
+remap_area_supersections(unsigned long virt, unsigned long pfn,
+			 unsigned long size, unsigned long flags)
+{
+	unsigned long prot, addr = virt, end = virt + size;
+	pgd_t *pgd;
+
+	/*
+	 * Remove and free any PTE-based mapping, and
+	 * sync the current kernel mapping.
+	 */
+	unmap_area_sections(virt, size);
+
+	prot = PMD_TYPE_SECT | PMD_SECT_SUPER | PMD_SECT_AP_WRITE |
+			PMD_DOMAIN(DOMAIN_IO) |
+			(flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE));
+
+	/*
+	 * ARMv6 and above need XN set to prevent speculative prefetches
+	 * hitting IO.
+	 */
+	if (cpu_architecture() >= CPU_ARCH_ARMv6)
+		prot |= PMD_SECT_XN;
+
+	pgd = pgd_offset_k(virt);
+	do {
+		unsigned long super_pmd_val, i;
+
+		super_pmd_val = __pfn_to_phys(pfn) | prot;
+		super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20;
+
+		for (i = 0; i < 8; i++) {
+			pmd_t *pmd = pmd_offset(pgd, addr);
+
+			pmd[0] = __pmd(super_pmd_val);
+			pmd[1] = __pmd(super_pmd_val);
+			flush_pmd_entry(pmd);
+
+			addr += PGDIR_SIZE;
+			pgd++;
+		}
+
+		pfn += SUPERSECTION_SIZE >> PAGE_SHIFT;
+	} while (addr < end);
+
+	return 0;
+}
+#endif
+
+
 /*
  * Remap an arbitrary physical address space into the kernel virtual
  * address space. Needed when the kernel wants to access high addresses
@@ -133,18 +300,42 @@ void __iomem *
 __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
 	      unsigned long flags)
 {
+	int err;
 	unsigned long addr;
  	struct vm_struct * area;
+	unsigned int cr = get_cr();
+
+	/*
+	 * High mappings must be supersection aligned
+	 */
+	if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
+		return NULL;
 
  	area = get_vm_area(size, VM_IOREMAP);
  	if (!area)
  		return NULL;
  	addr = (unsigned long)area->addr;
- 	if (remap_area_pages(addr, pfn, size, flags)) {
+
+#ifndef CONFIG_SMP
+	if ((((cpu_architecture() >= CPU_ARCH_ARMv6) && (cr & CR_XP)) ||
+	       cpu_is_xsc3()) &&
+	       !((__pfn_to_phys(pfn) | size | addr) & ~SUPERSECTION_MASK)) {
+		area->flags |= VM_ARM_SECTION_MAPPING;
+		err = remap_area_supersections(addr, pfn, size, flags);
+	} else if (!((__pfn_to_phys(pfn) | size | addr) & ~PMD_MASK)) {
+		area->flags |= VM_ARM_SECTION_MAPPING;
+		err = remap_area_sections(addr, pfn, size, flags);
+	} else
+#endif
+		err = remap_area_pages(addr, pfn, size, flags);
+
+	if (err) {
  		vunmap((void *)addr);
  		return NULL;
  	}
- 	return (void __iomem *) (offset + (char *)addr);
+
+	flush_cache_vmap(addr, addr + size);
+	return (void __iomem *) (offset + addr);
 }
 EXPORT_SYMBOL(__ioremap_pfn);
 
@@ -173,6 +364,34 @@ EXPORT_SYMBOL(__ioremap);
 
 void __iounmap(void __iomem *addr)
 {
-	vunmap((void *)(PAGE_MASK & (unsigned long)addr));
+	struct vm_struct **p, *tmp;
+	unsigned int section_mapping = 0;
+
+	addr = (void __iomem *)(PAGE_MASK & (unsigned long)addr);
+
+	/*
+	 * If this is a section based mapping we need to handle it
+	 * specially as the VM subysystem does not know how to handle
+	 * such a beast. We need the lock here b/c we need to clear
+	 * all the mappings before the area can be reclaimed
+	 * by someone else.
+	 */
+	write_lock(&vmlist_lock);
+	for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
+		if((tmp->flags & VM_IOREMAP) && (tmp->addr == addr)) {
+			if (tmp->flags & VM_ARM_SECTION_MAPPING) {
+				*p = tmp->next;
+				unmap_area_sections((unsigned long)tmp->addr,
+						    tmp->size);
+				kfree(tmp);
+				section_mapping = 1;
+			}
+			break;
+		}
+	}
+	write_unlock(&vmlist_lock);
+
+	if (!section_mapping)
+		vunmap(addr);
 }
 EXPORT_SYMBOL(__iounmap);
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index b0242c6ea066..38769f5862bc 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -302,16 +302,16 @@ static struct mem_types mem_types[] __initdata = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_WRITE,
 		.prot_l1   = PMD_TYPE_TABLE,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_UNCACHED |
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
 				PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_IO,
 	},
 	[MT_CACHECLEAN] = {
-		.prot_sect = PMD_TYPE_SECT,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_MINICLEAN] = {
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_LOW_VECTORS] = {
@@ -327,25 +327,25 @@ static struct mem_types mem_types[] __initdata = {
 		.domain    = DOMAIN_USER,
 	},
 	[MT_MEMORY] = {
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_ROM] = {
-		.prot_sect = PMD_TYPE_SECT,
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4,
 		.domain    = DOMAIN_KERNEL,
 	},
 	[MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_WRITE,
 		.prot_l1   = PMD_TYPE_TABLE,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_UNCACHED |
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
 				PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE |
 				PMD_SECT_TEX(1),
 		.domain    = DOMAIN_IO,
 	},
 	[MT_NONSHARED_DEVICE] = {
 		.prot_l1   = PMD_TYPE_TABLE,
-		.prot_sect = PMD_TYPE_SECT | PMD_SECT_NONSHARED_DEV |
+		.prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV |
 				PMD_SECT_AP_WRITE,
 		.domain    = DOMAIN_IO,
 	}
@@ -375,14 +375,21 @@ void __init build_mem_type_table(void)
 		ecc_mask = 0;
 	}
 
-	if (cpu_arch <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) {
-		for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+	/*
+	 * Xscale must not have PMD bit 4 set for section mappings.
+	 */
+	if (cpu_is_xscale())
+		for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+			mem_types[i].prot_sect &= ~PMD_BIT4;
+
+	/*
+	 * ARMv5 and lower, excluding Xscale, bit 4 must be set for
+	 * page tables.
+	 */
+	if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale())
+		for (i = 0; i < ARRAY_SIZE(mem_types); i++)
 			if (mem_types[i].prot_l1)
 				mem_types[i].prot_l1 |= PMD_BIT4;
-			if (mem_types[i].prot_sect)
-				mem_types[i].prot_sect |= PMD_BIT4;
-		}
-	}
 
 	cp = &cache_policies[cachepolicy];
 	kern_pgprot = user_pgprot = cp->pte;
@@ -406,8 +413,8 @@ void __init build_mem_type_table(void)
 		 * bit 4 becomes XN which we must clear for the
 		 * kernel memory mapping.
 		 */
-		mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
-		mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
+		mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN;
+		mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN;
 
 		/*
 		 * Mark cache clean areas and XIP ROM read only
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index cc609666df05..700297ae4a55 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -439,11 +439,12 @@ __arm1020_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 #endif
+
+	adr	r5, arm1020_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm1020_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm1020_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .R.. .... .... ....
 #endif
@@ -455,12 +456,9 @@ __arm1020_setup:
 	 * .RVI ZFRS BLDP WCAM
 	 * .011 1001 ..11 0101
 	 */
-	.type	arm1020_cr1_clear, #object
-	.type	arm1020_cr1_set, #object
-arm1020_cr1_clear:
-	.word	0x593f
-arm1020_cr1_set:
-	.word	0x3935
+	.type	arm1020_crval, #object
+arm1020_crval:
+	crval	clear=0x0000593f, mmuset=0x00003935, ucset=0x00001930
 
 	__INITDATA
 
@@ -526,6 +524,9 @@ __arm1020_proc_info:
 	.long   PMD_TYPE_SECT | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1020_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 117a946c28c8..0c33a5ed5a61 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -421,11 +421,11 @@ __arm1020e_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 #endif
+	adr	r5, arm1020e_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm1020e_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm1020e_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .R.. .... .... ....
 #endif
@@ -437,12 +437,9 @@ __arm1020e_setup:
 	 * .RVI ZFRS BLDP WCAM
 	 * .011 1001 ..11 0101
 	 */
-	.type	arm1020e_cr1_clear, #object
-	.type	arm1020e_cr1_set, #object
-arm1020e_cr1_clear:
-	.word	0x5f3f
-arm1020e_cr1_set:
-	.word	0x3935
+	.type	arm1020e_crval, #object
+arm1020e_crval:
+	crval	clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
 
 	__INITDATA
 
@@ -476,25 +473,7 @@ cpu_elf_name:
 
 	.type	cpu_arm1020e_name, #object
 cpu_arm1020e_name:
-	.ascii	"ARM1020E"
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	.ascii	"i"
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	.ascii	"d"
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	.ascii	"(wt)"
-#else
-	.ascii	"(wb)"
-#endif
-#endif
-#ifndef CONFIG_CPU_BPREDICT_DISABLE
-	.ascii	"B"
-#endif
-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	.ascii	"RR"
-#endif
-	.ascii	"\0"
+	.asciz	"ARM1020E"
 	.size	cpu_arm1020e_name, . - cpu_arm1020e_name
 
 	.align
@@ -509,6 +488,10 @@ __arm1020e_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1020e_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 39b7c102180a..566a55653072 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -403,11 +403,11 @@ __arm1022_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 #endif
+	adr	r5, arm1022_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm1022_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm1022_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .R..............
 #endif
@@ -420,12 +420,9 @@ __arm1022_setup:
 	 * .011 1001 ..11 0101
 	 * 
 	 */
-	.type	arm1022_cr1_clear, #object
-	.type	arm1022_cr1_set, #object
-arm1022_cr1_clear:
-	.word	0x7f3f
-arm1022_cr1_set:
-	.word	0x3935
+	.type	arm1022_crval, #object
+arm1022_crval:
+	crval	clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001930
 
 	__INITDATA
 
@@ -459,25 +456,7 @@ cpu_elf_name:
 
 	.type	cpu_arm1022_name, #object
 cpu_arm1022_name:
-	.ascii	"arm1022"
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	.ascii	"i"
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	.ascii	"d"
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	.ascii	"(wt)"
-#else
-	.ascii	"(wb)"
-#endif
-#endif
-#ifndef CONFIG_CPU_BPREDICT_DISABLE
-	.ascii	"B"
-#endif
-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	.ascii	"RR"
-#endif
-	.ascii	"\0"
+	.asciz	"ARM1022"
 	.size	cpu_arm1022_name, . - cpu_arm1022_name
 
 	.align
@@ -492,6 +471,10 @@ __arm1022_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1022_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 33e1ab8eb1d6..6ea76321d0df 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -398,11 +398,11 @@ __arm1026_setup:
 	mov	r0, #4				@ explicitly disable writeback
 	mcr	p15, 7, r0, c15, c0, 0
 #endif
+	adr	r5, arm1026_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm1026_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm1026_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000 		@ .R.. .... .... ....
 #endif
@@ -415,12 +415,9 @@ __arm1026_setup:
 	 * .011 1001 ..11 0101
 	 * 
 	 */
-	.type	arm1026_cr1_clear, #object
-	.type	arm1026_cr1_set, #object
-arm1026_cr1_clear:
-	.word	0x7f3f
-arm1026_cr1_set:
-	.word	0x3935
+	.type	arm1026_crval, #object
+arm1026_crval:
+	crval	clear=0x00007f3f, mmuset=0x00003935, ucset=0x00001934
 
 	__INITDATA
 
@@ -455,25 +452,7 @@ cpu_elf_name:
 
 	.type	cpu_arm1026_name, #object
 cpu_arm1026_name:
-	.ascii	"ARM1026EJ-S"
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	.ascii	"i"
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	.ascii	"d"
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	.ascii	"(wt)"
-#else
-	.ascii	"(wb)"
-#endif
-#endif
-#ifndef CONFIG_CPU_BPREDICT_DISABLE
-	.ascii	"B"
-#endif
-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	.ascii	"RR"
-#endif
-	.ascii	"\0"
+	.asciz	"ARM1026EJ-S"
 	.size	cpu_arm1026_name, . - cpu_arm1026_name
 
 	.align
@@ -488,6 +467,10 @@ __arm1026_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm1026_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 7a705edfa4b2..0432e4806888 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -355,6 +355,10 @@ __arm6_proc_info:
 		.long	0x41560600
 		.long	0xfffffff0
 		.long	0x00000c1e
+		.long   PMD_TYPE_SECT | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm6_setup
 		.long	cpu_arch_name
 		.long	cpu_elf_name
@@ -371,6 +375,10 @@ __arm610_proc_info:
 		.long	0x41560610
 		.long	0xfffffff0
 		.long	0x00000c1e
+		.long   PMD_TYPE_SECT | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm6_setup
 		.long	cpu_arch_name
 		.long	cpu_elf_name
@@ -387,6 +395,10 @@ __arm7_proc_info:
 		.long	0x41007000
 		.long	0xffffff00
 		.long	0x00000c1e
+		.long   PMD_TYPE_SECT | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm7_setup
 		.long	cpu_arch_name
 		.long	cpu_elf_name
@@ -408,6 +420,10 @@ __arm710_proc_info:
 			PMD_BIT4 | \
 			PMD_SECT_AP_WRITE | \
 			PMD_SECT_AP_READ
+		.long   PMD_TYPE_SECT | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm7_setup
 		.long	cpu_arch_name
 		.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 86102467d37f..0e6946ab6e5b 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -169,11 +169,11 @@ __arm720_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7, 0		@ flush TLB (v4)
 #endif
+	adr	r5, arm720_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register
-	ldr	r5, arm720_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm720_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 	mov	pc, lr				@ __ret (head.S)
 	.size	__arm720_setup, . - __arm720_setup
 
@@ -183,12 +183,9 @@ __arm720_setup:
 	 * ..1. 1001 ..11 1101
 	 * 
 	 */
-	.type	arm720_cr1_clear, #object
-	.type	arm720_cr1_set, #object
-arm720_cr1_clear:
-	.word	0x2f3f
-arm720_cr1_set:
-	.word	0x213d
+	.type	arm720_crval, #object
+arm720_crval:
+	crval	clear=0x00002f3f, mmuset=0x0000213d, ucset=0x00000130
 
 		__INITDATA
 
@@ -246,6 +243,10 @@ __arm710_proc_info:
 			PMD_BIT4 | \
 			PMD_SECT_AP_WRITE | \
 			PMD_SECT_AP_READ
+		.long   PMD_TYPE_SECT | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm710_setup				@ cpu_flush
 		.long	cpu_arch_name				@ arch_name
 		.long	cpu_elf_name				@ elf_name
@@ -267,6 +268,10 @@ __arm720_proc_info:
 			PMD_BIT4 | \
 			PMD_SECT_AP_WRITE | \
 			PMD_SECT_AP_READ
+		.long   PMD_TYPE_SECT | \
+			PMD_BIT4 | \
+			PMD_SECT_AP_WRITE | \
+			PMD_SECT_AP_READ
 		b	__arm720_setup				@ cpu_flush
 		.long	cpu_arch_name				@ arch_name
 		.long	cpu_elf_name				@ elf_name
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 6f0db29ab842..4adb46b3a4e0 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -390,11 +390,11 @@ __arm920_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 #endif
+	adr	r5, arm920_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm920_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm920_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 	mov	pc, lr
 	.size	__arm920_setup, . - __arm920_setup
 
@@ -404,12 +404,9 @@ __arm920_setup:
 	 * ..11 0001 ..11 0101
 	 * 
 	 */
-	.type	arm920_cr1_clear, #object
-	.type	arm920_cr1_set, #object
-arm920_cr1_clear:
-	.word	0x3f3f
-arm920_cr1_set:
-	.word	0x3135
+	.type	arm920_crval, #object
+arm920_crval:
+	crval	clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130
 
 	__INITDATA
 
@@ -443,19 +440,7 @@ cpu_elf_name:
 
 	.type	cpu_arm920_name, #object
 cpu_arm920_name:
-	.ascii	"ARM920T"
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	.ascii	"i"
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	.ascii	"d"
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	.ascii	"(wt)"
-#else
-	.ascii	"(wb)"
-#endif
-#endif
-	.ascii	"\0"
+	.asciz	"ARM920T"
 	.size	cpu_arm920_name, . - cpu_arm920_name
 
 	.align
@@ -472,6 +457,10 @@ __arm920_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm920_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 1ad464cc7bcb..571f082f0247 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -394,11 +394,11 @@ __arm922_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 #endif
+	adr	r5, arm922_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm922_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm922_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 	mov	pc, lr
 	.size	__arm922_setup, . - __arm922_setup
 
@@ -408,12 +408,9 @@ __arm922_setup:
 	 * ..11 0001 ..11 0101
 	 * 
 	 */
-	.type	arm922_cr1_clear, #object
-	.type	arm922_cr1_set, #object
-arm922_cr1_clear:
-	.word	0x3f3f
-arm922_cr1_set:
-	.word	0x3135
+	.type	arm922_crval, #object
+arm922_crval:
+	crval	clear=0x00003f3f, mmuset=0x00003135, ucset=0x00001130
 
 	__INITDATA
 
@@ -447,19 +444,7 @@ cpu_elf_name:
 
 	.type	cpu_arm922_name, #object
 cpu_arm922_name:
-	.ascii	"ARM922T"
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	.ascii	"i"
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	.ascii	"d"
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	.ascii	"(wt)"
-#else
-	.ascii	"(wb)"
-#endif
-#endif
-	.ascii	"\0"
+	.asciz	"ARM922T"
 	.size	cpu_arm922_name, . - cpu_arm922_name
 
 	.align
@@ -476,6 +461,10 @@ __arm922_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm922_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index a55d56ce2264..ad15f8503d51 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -454,11 +454,10 @@ __arm925_setup:
 	mcr	p15, 7, r0, c15, c0, 0
 #endif
 
+	adr	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm925_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm925_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000			@ .1.. .... .... ....
 #endif
@@ -471,12 +470,9 @@ __arm925_setup:
 	 * .011 0001 ..11 1101
 	 * 
 	 */
-	.type	arm925_cr1_clear, #object
-	.type	arm925_cr1_set, #object
-arm925_cr1_clear:
-	.word	0x7f3f
-arm925_cr1_set:
-	.word	0x313d
+	.type	arm925_crval, #object
+arm925_crval:
+	crval	clear=0x00007f3f, mmuset=0x0000313d, ucset=0x00001130
 
 	__INITDATA
 
@@ -510,22 +506,7 @@ cpu_elf_name:
 
 	.type	cpu_arm925_name, #object
 cpu_arm925_name:
-	.ascii	"ARM925T"
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	.ascii	"i"
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	.ascii	"d"
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	.ascii	"(wt)"
-#else
-	.ascii	"(wb)"
-#endif
-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	.ascii	"RR"
-#endif
-#endif
-	.ascii	"\0"
+	.asciz	"ARM925T"
 	.size	cpu_arm925_name, . - cpu_arm925_name
 
 	.align
@@ -540,6 +521,10 @@ __arm925_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm925_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -559,6 +544,10 @@ __arm915_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm925_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 20275967663d..1e89d4080474 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -403,11 +403,11 @@ __arm926_setup:
 	mcr	p15, 7, r0, c15, c0, 0
 #endif 
 
+	adr	r5, arm926_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, arm926_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, arm926_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 #ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
 	orr	r0, r0, #0x4000			@ .1.. .... .... ....
 #endif
@@ -420,12 +420,9 @@ __arm926_setup:
 	 * .011 0001 ..11 0101
 	 * 
 	 */
-	.type	arm926_cr1_clear, #object
-	.type	arm926_cr1_set, #object
-arm926_cr1_clear:
-	.word	0x7f3f
-arm926_cr1_set:
-	.word	0x3135
+	.type	arm926_crval, #object
+arm926_crval:
+	crval	clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134
 
 	__INITDATA
 
@@ -459,22 +456,7 @@ cpu_elf_name:
 
 	.type	cpu_arm926_name, #object
 cpu_arm926_name:
-	.ascii	"ARM926EJ-S"
-#ifndef CONFIG_CPU_ICACHE_DISABLE
-	.ascii	"i"
-#endif
-#ifndef CONFIG_CPU_DCACHE_DISABLE
-	.ascii	"d"
-#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-	.ascii	"(wt)"
-#else
-	.ascii	"(wb)"
-#endif
-#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-	.ascii	"RR"
-#endif
-#endif
-	.ascii	"\0"
+	.asciz	"ARM926EJ-S"
 	.size	cpu_arm926_name, . - cpu_arm926_name
 
 	.align
@@ -491,6 +473,10 @@ __arm926_proc_info:
 		PMD_BIT4 | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_BIT4 | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__arm926_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 7cfc2604a1ee..9e2c89eb2115 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -49,3 +49,13 @@
 	.macro	asid, rd, rn
 	and	\rd, \rn, #255
 	.endm
+
+	.macro	crval, clear, mmuset, ucset
+#ifdef CONFIG_MMU
+	.word	\clear
+	.word	\mmuset
+#else
+	.word	\clear
+	.word	\ucset
+#endif
+	.endm
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 5a760a2c629c..e812246277cf 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -185,11 +185,12 @@ __sa110_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r10, c8, c7		@ invalidate I,D TLBs on v4
 #endif
+
+	adr	r5, sa110_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, sa110_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, sa110_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 	mov	pc, lr
 	.size	__sa110_setup, . - __sa110_setup
 
@@ -199,12 +200,9 @@ __sa110_setup:
 	 * ..01 0001 ..11 1101
 	 * 
 	 */
-	.type	sa110_cr1_clear, #object
-	.type	sa110_cr1_set, #object
-sa110_cr1_clear:
-	.word	0x3f3f
-sa110_cr1_set:
-	.word	0x113d
+	.type	sa110_crval, #object
+sa110_crval:
+	crval	clear=0x00003f3f, mmuset=0x0000113d, ucset=0x00001130
 
 	__INITDATA
 
@@ -255,6 +253,9 @@ __sa110_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__sa110_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 0a2107ad4c32..ba32cc6296a0 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -198,11 +198,11 @@ __sa1100_setup:
 #ifdef CONFIG_MMU
 	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
 #endif
+	adr	r5, sa1100_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0		@ get control register v4
-	ldr	r5, sa1100_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, sa1100_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 	mov	pc, lr
 	.size	__sa1100_setup, . - __sa1100_setup
 
@@ -212,12 +212,9 @@ __sa1100_setup:
 	 * ..11 0001 ..11 1101
 	 * 
 	 */
-	.type	sa1100_cr1_clear, #object
-	.type	sa1100_cr1_set, #object
-sa1100_cr1_clear:
-	.word	0x3f3f
-sa1100_cr1_set:
-	.word	0x313d
+	.type	sa1100_crval, #object
+sa1100_crval:
+	crval	clear=0x00003f3f, mmuset=0x0000313d, ucset=0x00001130
 
 	__INITDATA
 
@@ -276,6 +273,9 @@ __sa1100_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__sa1100_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -296,6 +296,9 @@ __sa1110_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__sa1100_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index ca13d4d05f65..6f72549f8843 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -212,11 +212,11 @@ __v6_setup:
 	orr	r0, r0, #(0xf << 20)
 	mcr	p15, 0, r0, c1, c0, 2		@ Enable full access to VFP
 #endif
+	adr	r5, v6_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0, 0		@ read control register
-	ldr	r5, v6_cr1_clear		@ get mask for bits to clear
 	bic	r0, r0, r5			@ clear bits them
-	ldr	r5, v6_cr1_set			@ get mask for bits to set
-	orr	r0, r0, r5			@ set them
+	orr	r0, r0, r6			@ set them
 	mov	pc, lr				@ return to head.S:__ret
 
 	/*
@@ -225,12 +225,9 @@ __v6_setup:
 	 * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
 	 *         0 110       0011 1.00 .111 1101 < we want
 	 */
-	.type	v6_cr1_clear, #object
-	.type	v6_cr1_set, #object
-v6_cr1_clear:
-	.word	0x01e0fb7f
-v6_cr1_set:
-	.word	0x00c0387d
+	.type	v6_crval, #object
+v6_crval:
+	crval	clear=0x01e0fb7f, mmuset=0x00c0387d, ucset=0x00c0187c
 
 	.type	v6_processor_functions, #object
 ENTRY(v6_processor_functions)
@@ -269,6 +266,10 @@ __v6_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_XN | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__v6_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 8d32e21fe151..4ace2d8090c7 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -426,23 +426,26 @@ __xsc3_setup:
 	orr	r0, r0, #(1 << 10)		@ enable L2 for LLR cache
 #endif
 	mcr	p15, 0, r0, c1, c0, 1		@ set auxiliary control reg
+
+	adr	r5, xsc3_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0, 0		@ get control register
-	bic	r0, r0, #0x0002			@ .... .... .... ..A.
-	orr	r0, r0, #0x0005			@ .... .... .... .C.M
+	bic	r0, r0, r5			@ .... .... .... ..A.
+	orr	r0, r0, r6			@ .... .... .... .C.M
 #if BTB_ENABLE
-	bic	r0, r0, #0x0200			@ .... ..R. .... ....
-	orr	r0, r0, #0x3900			@ ..VI Z..S .... ....
-#else
-	bic	r0, r0, #0x0a00			@ .... Z.R. .... ....
-	orr	r0, r0, #0x3100			@ ..VI ...S .... ....
+	orr	r0, r0, #0x00000800		@ ..VI Z..S .... ....
 #endif
 #if L2_CACHE_ENABLE
-	orr 	r0, r0, #0x4000000		@ L2 enable
+	orr 	r0, r0, #0x04000000		@ L2 enable
 #endif
 	mov	pc, lr
 
 	.size	__xsc3_setup, . - __xsc3_setup
 
+	.type	xsc3_crval, #object
+xsc3_crval:
+	crval	clear=0x04003b02, mmuset=0x00003105, ucset=0x00001100
+
 	__INITDATA
 
 /*
@@ -487,7 +490,14 @@ cpu_xsc3_name:
 __xsc3_proc_info:
 	.long	0x69056000
 	.long	0xffffe000
-	.long	0x00000c0e
+	.long	PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xsc3_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 29bcc4dd6517..521538671f4c 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -138,17 +138,23 @@ ENTRY(cpu_xscale_proc_fin)
  * to what would be the reset vector.
  *
  * loc: location to jump to for soft reset
+ *
+ * Beware PXA270 erratum E7.
  */
 	.align	5
 ENTRY(cpu_xscale_reset)
 	mov	r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
 	msr	cpsr_c, r1			@ reset CPSR
+	mcr	p15, 0, r1, c10, c4, 1		@ unlock I-TLB
+	mcr	p15, 0, r1, c8, c5, 0		@ invalidate I-TLB
 	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
 	bic	r1, r1, #0x0086			@ ........B....CA.
 	bic	r1, r1, #0x3900			@ ..VIZ..S........
+	sub	pc, pc, #4			@ flush pipeline
+	@ *** cache line aligned ***
 	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
-	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches & BTB
 	bic	r1, r1, #0x0001			@ ...............M
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches & BTB
 	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
 	@ CAUTION: MMU turned off from this point. We count on the pipeline
 	@ already containing those two last instructions to survive.
@@ -475,11 +481,12 @@ __xscale_setup:
 	orr     r0, r0, #1 << 6			@ cp6 for IOP3xx and Bulverde
 	orr	r0, r0, #1 << 13		@ Its undefined whether this
 	mcr	p15, 0, r0, c15, c1, 0		@ affects USR or SVC modes
+
+	adr	r5, xscale_crval
+	ldmia	r5, {r5, r6}
 	mrc	p15, 0, r0, c1, c0, 0		@ get control register
-	ldr	r5, xscale_cr1_clear
 	bic	r0, r0, r5
-	ldr	r5, xscale_cr1_set
-	orr	r0, r0, r5
+	orr	r0, r0, r6
 	mov	pc, lr
 	.size	__xscale_setup, . - __xscale_setup
 
@@ -489,12 +496,9 @@ __xscale_setup:
 	 * ..11 1.01 .... .101
 	 * 
 	 */
-	.type	xscale_cr1_clear, #object
-	.type	xscale_cr1_set, #object
-xscale_cr1_clear:
-	.word	0x3b07
-xscale_cr1_set:
-	.word	0x3905
+	.type	xscale_crval, #object
+xscale_crval:
+	crval	clear=0x00003b07, mmuset=0x00003905, ucset=0x00001900
 
 	__INITDATA
 
@@ -595,6 +599,9 @@ __80200_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -615,6 +622,9 @@ __8032x_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -635,6 +645,9 @@ __8033x_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -655,6 +668,9 @@ __pxa250_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -675,6 +691,9 @@ __pxa210_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -695,6 +714,9 @@ __ixp2400_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b       __xscale_setup
 	.long   cpu_arch_name
 	.long   cpu_elf_name
@@ -715,6 +737,9 @@ __ixp2800_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b       __xscale_setup
 	.long   cpu_arch_name
 	.long   cpu_elf_name
@@ -735,6 +760,9 @@ __ixp42x_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b       __xscale_setup
 	.long   cpu_arch_name
 	.long   cpu_elf_name
@@ -750,7 +778,14 @@ __ixp42x_proc_info:
 __ixp46x_proc_info:
 	.long   0x69054200
 	.long   0xffffff00
-	.long   0x00000c0e
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_BUFFERABLE | \
+		PMD_SECT_CACHEABLE | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b       __xscale_setup
 	.long   cpu_arch_name
 	.long   cpu_elf_name
@@ -771,6 +806,9 @@ __pxa255_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name
@@ -791,6 +829,9 @@ __pxa270_proc_info:
 		PMD_SECT_CACHEABLE | \
 		PMD_SECT_AP_WRITE | \
 		PMD_SECT_AP_READ
+	.long   PMD_TYPE_SECT | \
+		PMD_SECT_AP_WRITE | \
+		PMD_SECT_AP_READ
 	b	__xscale_setup
 	.long	cpu_arch_name
 	.long	cpu_elf_name