Add a prefetch abort handler

This patch adds a prefetch abort handler similar to the data abort one
and renames the latter for consistency. Initial implementation by Paul
Brook with some renaming by Catalin Marinas.

Signed-off-by: Paul Brook <paul@codesourcery.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 6604b47..0a0d247 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -111,5 +111,12 @@
   DEFINE(PROCINFO_INITFUNC,	offsetof(struct proc_info_list, __cpu_flush));
   DEFINE(PROCINFO_MM_MMUFLAGS,	offsetof(struct proc_info_list, __cpu_mm_mmu_flags));
   DEFINE(PROCINFO_IO_MMUFLAGS,	offsetof(struct proc_info_list, __cpu_io_mmu_flags));
+  BLANK();
+#ifdef MULTI_DABORT
+  DEFINE(PROCESSOR_DABT_FUNC,	offsetof(struct processor, _data_abort));
+#endif
+#ifdef MULTI_PABORT
+  DEFINE(PROCESSOR_PABT_FUNC,	offsetof(struct processor, _prefetch_abort));
+#endif
   return 0; 
 }
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a46d5b4..5e647eb 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -166,12 +166,12 @@
 	@ The abort handler must return the aborted address in r0, and
 	@ the fault status register in r1.  r9 must be preserved.
 	@
-#ifdef MULTI_ABORT
+#ifdef MULTI_DABORT
 	ldr	r4, .LCprocfns
 	mov	lr, pc
-	ldr	pc, [r4]
+	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
 #else
-	bl	CPU_ABORT_HANDLER
+	bl	CPU_DABORT_HANDLER
 #endif
 
 	@
@@ -293,7 +293,6 @@
 	mrs	r9, cpsr
 	tst	r3, #PSR_I_BIT
 	biceq	r9, r9, #PSR_I_BIT
-	msr	cpsr_c, r9
 
 	@
 	@ set args, then call main handler
@@ -301,7 +300,15 @@
 	@  r0 - address of faulting instruction
 	@  r1 - pointer to registers on stack
 	@
-	mov	r0, r2				@ address (pc)
+#ifdef MULTI_PABORT
+	mov	r0, r2			@ pass address of aborted instruction.
+	ldr	r4, .LCprocfns
+	mov	lr, pc
+	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
+#else
+	CPU_PABORT_HANDLER(r0, r2)
+#endif
+	msr	cpsr_c, r9			@ Maybe enable interrupts
 	mov	r1, sp				@ regs
 	bl	do_PrefetchAbort		@ call abort handler
 
@@ -320,7 +327,7 @@
 	.align	5
 .LCcralign:
 	.word	cr_alignment
-#ifdef MULTI_ABORT
+#ifdef MULTI_DABORT
 .LCprocfns:
 	.word	processor
 #endif
@@ -404,12 +411,12 @@
 	@ The abort handler must return the aborted address in r0, and
 	@ the fault status register in r1.
 	@
-#ifdef MULTI_ABORT
+#ifdef MULTI_DABORT
 	ldr	r4, .LCprocfns
 	mov	lr, pc
-	ldr	pc, [r4]
+	ldr	pc, [r4, #PROCESSOR_DABT_FUNC]
 #else
-	bl	CPU_ABORT_HANDLER
+	bl	CPU_DABORT_HANDLER
 #endif
 
 	@
@@ -619,8 +626,15 @@
 __pabt_usr:
 	usr_entry
 
+#ifdef MULTI_PABORT
+	mov	r0, r2			@ pass address of aborted instruction.
+	ldr	r4, .LCprocfns
+	mov	lr, pc
+	ldr	pc, [r4, #PROCESSOR_PABT_FUNC]
+#else
+	CPU_PABORT_HANDLER(r0, r2)
+#endif
 	enable_irq				@ Enable interrupts
-	mov	r0, r2				@ address (pc)
 	mov	r1, sp				@ regs
 	bl	do_PrefetchAbort		@ call abort handler
 	/* fall through */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 6c90c50..597ed00 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -352,6 +352,11 @@
 		b	do_mmap2
 #endif
 
+ENTRY(pabort_ifar)
+		mrc	p15, 0, r0, cr6, cr0, 2
+ENTRY(pabort_noifar)
+		mov	pc, lr
+
 #ifdef CONFIG_OABI_COMPAT
 
 /*
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 084fe8d..708ee25 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -18,6 +18,7 @@
 	select CPU_CP15_MMU
 	select CPU_COPY_V3 if MMU
 	select CPU_TLB_V3 if MMU
+	select CPU_PABRT_NOIFAR
 	help
 	  The ARM610 is the successor to the ARM3 processor
 	  and was produced by VLSI Technology Inc.
@@ -49,6 +50,7 @@
 	select CPU_CP15_MMU
 	select CPU_COPY_V3 if MMU
 	select CPU_TLB_V3 if MMU
+	select CPU_PABRT_NOIFAR
 	help
 	  A 32-bit RISC microprocessor based on the ARM7 processor core
 	  designed by Advanced RISC Machines Ltd. The ARM710 is the
@@ -64,6 +66,7 @@
 	default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
 	select CPU_32v4T
 	select CPU_ABRT_LV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -113,6 +116,7 @@
 	default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
 	select CPU_32v4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -135,6 +139,7 @@
 	default y if ARCH_LH7A40X || ARCH_KS8695
 	select CPU_32v4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -155,6 +160,7 @@
  	default y if ARCH_OMAP15XX
 	select CPU_32v4T
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -175,6 +181,7 @@
 	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || ARCH_NS9XXX || ARCH_DAVINCI
 	select CPU_32v5
 	select CPU_ABRT_EV5TJ
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU
@@ -226,6 +233,7 @@
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -244,6 +252,7 @@
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WT
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -257,6 +266,7 @@
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_ABRT_EV4T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU # can probably do better
@@ -275,6 +285,7 @@
 	depends on ARCH_INTEGRATOR
 	select CPU_32v5
 	select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU # can probably do better
@@ -293,6 +304,7 @@
 	select CPU_32v3 if ARCH_RPC
 	select CPU_32v4 if !ARCH_RPC
 	select CPU_ABRT_EV4
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -314,6 +326,7 @@
 	default y
 	select CPU_32v4
 	select CPU_ABRT_EV4
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V4WB
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
@@ -326,6 +339,7 @@
 	default y
 	select CPU_32v5
 	select CPU_ABRT_EV5T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_TLB_V4WBI if MMU
@@ -349,6 +363,7 @@
 	default y
 	select CPU_32v5
 	select CPU_ABRT_EV5T
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_VIVT
 	select CPU_CP15_MMU
 	select CPU_COPY_V4WB if MMU
@@ -371,6 +386,7 @@
 	default y if ARCH_MSM7X00A
 	select CPU_32v6
 	select CPU_ABRT_EV6
+	select CPU_PABRT_NOIFAR
 	select CPU_CACHE_V6
 	select CPU_CACHE_VIPT
 	select CPU_CP15_MMU
@@ -397,6 +413,7 @@
 	select CPU_32v6K
 	select CPU_32v7
 	select CPU_ABRT_EV7
+	select CPU_PABRT_IFAR
 	select CPU_CACHE_V7
 	select CPU_CACHE_VIPT
 	select CPU_CP15_MMU
@@ -458,6 +475,12 @@
 config CPU_ABRT_EV7
 	bool
 
+config CPU_PABRT_IFAR
+	bool
+
+config CPU_PABRT_NOIFAR
+	bool
+
 # The cache model
 config CPU_CACHE_V3
 	bool
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 700c04d..32fd7ea 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -478,6 +478,7 @@
 	.word	cpu_arm1020_dcache_clean_area
 	.word	cpu_arm1020_switch_mm
 	.word	cpu_arm1020_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1020_processor_functions, . - arm1020_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 1cc206a..fe2b0ae 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -459,6 +459,7 @@
 	.word	cpu_arm1020e_dcache_clean_area
 	.word	cpu_arm1020e_switch_mm
 	.word	cpu_arm1020e_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1020e_processor_functions, . - arm1020e_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index aff0ea0..06dde67 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -442,6 +442,7 @@
 	.word	cpu_arm1022_dcache_clean_area
 	.word	cpu_arm1022_switch_mm
 	.word	cpu_arm1022_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1022_processor_functions, . - arm1022_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 65e43a1..f5506e6 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -437,6 +437,7 @@
 	.word	cpu_arm1026_dcache_clean_area
 	.word	cpu_arm1026_switch_mm
 	.word	cpu_arm1026_set_pte_ext
+	.word	pabort_noifar
 	.size	arm1026_processor_functions, . - arm1026_processor_functions
 
 	.section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 123a7dc7..14b6a95 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -300,6 +300,7 @@
 		.word	cpu_arm6_dcache_clean_area
 		.word	cpu_arm6_switch_mm
 		.word	cpu_arm6_set_pte_ext
+		.word	pabort_noifar
 		.size	arm6_processor_functions, . - arm6_processor_functions
 
 /*
@@ -316,6 +317,7 @@
 		.word	cpu_arm7_dcache_clean_area
 		.word	cpu_arm7_switch_mm
 		.word	cpu_arm7_set_pte_ext
+		.word	pabort_noifar
 		.size	arm7_processor_functions, . - arm7_processor_functions
 
 		.section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index dc763be..ca5e7aa 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -205,6 +205,7 @@
 		.word	cpu_arm720_dcache_clean_area
 		.word	cpu_arm720_switch_mm
 		.word	cpu_arm720_set_pte_ext
+		.word	pabort_noifar
 		.size	arm720_processor_functions, . - arm720_processor_functions
 
 		.section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 75c945e..0170d4f 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -424,6 +424,7 @@
 	.word	cpu_arm920_dcache_clean_area
 	.word	cpu_arm920_switch_mm
 	.word	cpu_arm920_set_pte_ext
+	.word	pabort_noifar
 	.size	arm920_processor_functions, . - arm920_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index ffb751b..b795249 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -428,6 +428,7 @@
 	.word	cpu_arm922_dcache_clean_area
 	.word	cpu_arm922_switch_mm
 	.word	cpu_arm922_set_pte_ext
+	.word	pabort_noifar
 	.size	arm922_processor_functions, . - arm922_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 44c2c99..e2988eb 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -491,6 +491,7 @@
 	.word	cpu_arm925_dcache_clean_area
 	.word	cpu_arm925_switch_mm
 	.word	cpu_arm925_set_pte_ext
+	.word	pabort_noifar
 	.size	arm925_processor_functions, . - arm925_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 194ef48..62f7d1d 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -444,6 +444,7 @@
 	.word	cpu_arm926_dcache_clean_area
 	.word	cpu_arm926_switch_mm
 	.word	cpu_arm926_set_pte_ext
+	.word	pabort_noifar
 	.size	arm926_processor_functions, . - arm926_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index fa0dc7e..2f169b2 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -430,6 +430,7 @@
 	.word	cpu_feroceon_dcache_clean_area
 	.word	cpu_feroceon_switch_mm
 	.word	cpu_feroceon_set_pte_ext
+	.word	pabort_noifar
 	.size	feroceon_processor_functions, . - feroceon_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 6e226e1..4db3d62 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -223,6 +223,7 @@
 	.word	cpu_sa110_dcache_clean_area
 	.word	cpu_sa110_switch_mm
 	.word	cpu_sa110_set_pte_ext
+	.word	pabort_noifar
 	.size	sa110_processor_functions, . - sa110_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 9afb11d..3cdef04 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -238,6 +238,7 @@
 	.word	cpu_sa1100_dcache_clean_area
 	.word	cpu_sa1100_switch_mm
 	.word	cpu_sa1100_set_pte_ext
+	.word	pabort_noifar
 	.size	sa1100_processor_functions, . - sa1100_processor_functions
 
 	.section ".rodata"
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index eb42e5b..2162a69 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -240,6 +240,7 @@
 	.word	cpu_v6_dcache_clean_area
 	.word	cpu_v6_switch_mm
 	.word	cpu_v6_set_pte_ext
+	.word	pabort_noifar
 	.size	v6_processor_functions, . - v6_processor_functions
 
 	.type	cpu_arch_name, #object
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index e0acc5a..a1d7331 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -212,6 +212,7 @@
 	.word	cpu_v7_dcache_clean_area
 	.word	cpu_v7_switch_mm
 	.word	cpu_v7_set_pte_ext
+	.word	pabort_ifar
 	.size	v7_processor_functions, . - v7_processor_functions
 
 	.type	cpu_arch_name, #object
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 016690b..1a6d898 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -534,6 +534,7 @@
 	.word	cpu_xscale_dcache_clean_area
 	.word	cpu_xscale_switch_mm
 	.word	cpu_xscale_set_pte_ext
+	.word	pabort_noifar
 	.size	xscale_processor_functions, . - xscale_processor_functions
 
 	.section ".rodata"
diff --git a/include/asm-arm/cpu-multi32.h b/include/asm-arm/cpu-multi32.h
index 715e18a..3479de9 100644
--- a/include/asm-arm/cpu-multi32.h
+++ b/include/asm-arm/cpu-multi32.h
@@ -21,6 +21,10 @@
 	 */
 	void (*_data_abort)(unsigned long pc);
 	/*
+	 * Retrieve prefetch fault address
+	 */
+	unsigned long (*_prefetch_abort)(unsigned long lr);
+	/*
 	 * Set up any processor specifics
 	 */
 	void (*_proc_init)(void);
diff --git a/include/asm-arm/glue.h b/include/asm-arm/glue.h
index 22274ce..a97a182 100644
--- a/include/asm-arm/glue.h
+++ b/include/asm-arm/glue.h
@@ -40,83 +40,110 @@
  *	  v6_early	- ARMv6 generic early abort handler
  *	  v7_early	- ARMv7 generic early abort handler
  */
-#undef CPU_ABORT_HANDLER
-#undef MULTI_ABORT
+#undef CPU_DABORT_HANDLER
+#undef MULTI_DABORT
 
 #if defined(CONFIG_CPU_ARM610)
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER cpu_arm6_data_abort
+#  define CPU_DABORT_HANDLER cpu_arm6_data_abort
 # endif
 #endif
 
 #if defined(CONFIG_CPU_ARM710)
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER cpu_arm7_data_abort
+#  define CPU_DABORT_HANDLER cpu_arm7_data_abort
 # endif
 #endif
 
 #ifdef CONFIG_CPU_ABRT_LV4T
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER v4t_late_abort
+#  define CPU_DABORT_HANDLER v4t_late_abort
 # endif
 #endif
 
 #ifdef CONFIG_CPU_ABRT_EV4
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER v4_early_abort
+#  define CPU_DABORT_HANDLER v4_early_abort
 # endif
 #endif
 
 #ifdef CONFIG_CPU_ABRT_EV4T
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER v4t_early_abort
+#  define CPU_DABORT_HANDLER v4t_early_abort
 # endif
 #endif
 
 #ifdef CONFIG_CPU_ABRT_EV5TJ
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER v5tj_early_abort
+#  define CPU_DABORT_HANDLER v5tj_early_abort
 # endif
 #endif
 
 #ifdef CONFIG_CPU_ABRT_EV5T
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER v5t_early_abort
+#  define CPU_DABORT_HANDLER v5t_early_abort
 # endif
 #endif
 
 #ifdef CONFIG_CPU_ABRT_EV6
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER v6_early_abort
+#  define CPU_DABORT_HANDLER v6_early_abort
 # endif
 #endif
 
 #ifdef CONFIG_CPU_ABRT_EV7
-# ifdef CPU_ABORT_HANDLER
-#  define MULTI_ABORT 1
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
 # else
-#  define CPU_ABORT_HANDLER v7_early_abort
+#  define CPU_DABORT_HANDLER v7_early_abort
 # endif
 #endif
 
-#ifndef CPU_ABORT_HANDLER
+#ifndef CPU_DABORT_HANDLER
 #error Unknown data abort handler type
 #endif
 
+/*
+ * Prefetch abort handler.  If the CPU has an IFAR use that, otherwise
+ * use the address of the aborted instruction
+ */
+#undef CPU_PABORT_HANDLER
+#undef MULTI_PABORT
+
+#ifdef CONFIG_CPU_PABRT_IFAR
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER(reg, insn)	mrc p15, 0, reg, cr6, cr0, 2
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_NOIFAR
+# ifdef CPU_PABORT_HANDLER
+#  define MULTI_PABORT 1
+# else
+#  define CPU_PABORT_HANDLER(reg, insn)	mov reg, insn
+# endif
+#endif
+
+#ifndef CPU_PABORT_HANDLER
+#error Unknown prefetch abort handler type
+#endif
+
 #endif