aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/mm/proc-arm926.S2
-rw-r--r--arch/arm/mm/proc-v6.S7
-rw-r--r--arch/arm/vfp/vfpmodule.c26
-rw-r--r--include/asm-arm/system.h43
5 files changed, 57 insertions, 24 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 238dd9b6db84..cf2bd4242803 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -354,9 +354,6 @@ static void __init setup_processor(void)
354#ifndef CONFIG_ARM_THUMB 354#ifndef CONFIG_ARM_THUMB
355 elf_hwcap &= ~HWCAP_THUMB; 355 elf_hwcap &= ~HWCAP_THUMB;
356#endif 356#endif
357#ifndef CONFIG_VFP
358 elf_hwcap &= ~HWCAP_VFP;
359#endif
360 357
361 cpu_proc_init(); 358 cpu_proc_init();
362} 359}
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 8628ed29a955..080efac9d9ff 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -480,7 +480,7 @@ __arm926_proc_info:
480 b __arm926_setup 480 b __arm926_setup
481 .long cpu_arch_name 481 .long cpu_arch_name
482 .long cpu_elf_name 482 .long cpu_elf_name
483 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA 483 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
484 .long cpu_arm926_name 484 .long cpu_arm926_name
485 .long arm926_processor_functions 485 .long arm926_processor_functions
486 .long v4wbi_tlb_fns 486 .long v4wbi_tlb_fns
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index b440c8a1d345..c40baf8a47f0 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -207,11 +207,6 @@ __v6_setup:
207#endif 207#endif
208 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 208 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
209#endif /* CONFIG_MMU */ 209#endif /* CONFIG_MMU */
210#ifdef CONFIG_VFP
211 mrc p15, 0, r0, c1, c0, 2
212 orr r0, r0, #(0xf << 20)
213 mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP
214#endif
215 adr r5, v6_crval 210 adr r5, v6_crval
216 ldmia r5, {r5, r6} 211 ldmia r5, {r5, r6}
217 mrc p15, 0, r0, c1, c0, 0 @ read control register 212 mrc p15, 0, r0, c1, c0, 0 @ read control register
@@ -273,7 +268,7 @@ __v6_proc_info:
273 b __v6_setup 268 b __v6_setup
274 .long cpu_arch_name 269 .long cpu_arch_name
275 .long cpu_elf_name 270 .long cpu_elf_name
276 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA 271 .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
277 .long cpu_v6_name 272 .long cpu_v6_name
278 .long v6_processor_functions 273 .long v6_processor_functions
279 .long v6wbi_tlb_fns 274 .long v6wbi_tlb_fns
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index f08eafbddcc1..e26cc1f59948 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -263,13 +263,24 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
263 if (exceptions) 263 if (exceptions)
264 vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs); 264 vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
265} 265}
266 266
267/* 267/*
268 * VFP support code initialisation. 268 * VFP support code initialisation.
269 */ 269 */
270static int __init vfp_init(void) 270static int __init vfp_init(void)
271{ 271{
272 unsigned int vfpsid; 272 unsigned int vfpsid;
273 unsigned int cpu_arch = cpu_architecture();
274 u32 access = 0;
275
276 if (cpu_arch >= CPU_ARCH_ARMv6) {
277 access = get_copro_access();
278
279 /*
280 * Enable full access to VFP (cp10 and cp11)
281 */
282 set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
283 }
273 284
274 /* 285 /*
275 * First check that there is a VFP that we can use. 286 * First check that there is a VFP that we can use.
@@ -281,6 +292,12 @@ static int __init vfp_init(void)
281 printk(KERN_INFO "VFP support v0.3: "); 292 printk(KERN_INFO "VFP support v0.3: ");
282 if (VFP_arch) { 293 if (VFP_arch) {
283 printk("not present\n"); 294 printk("not present\n");
295
296 /*
297 * Restore the copro access register.
298 */
299 if (cpu_arch >= CPU_ARCH_ARMv6)
300 set_copro_access(access);
284 } else if (vfpsid & FPSID_NODOUBLE) { 301 } else if (vfpsid & FPSID_NODOUBLE) {
285 printk("no double precision support\n"); 302 printk("no double precision support\n");
286 } else { 303 } else {
@@ -291,9 +308,16 @@ static int __init vfp_init(void)
291 (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, 308 (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
292 (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, 309 (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
293 (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); 310 (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
311
294 vfp_vector = vfp_support_entry; 312 vfp_vector = vfp_support_entry;
295 313
296 thread_register_notifier(&vfp_notifier_block); 314 thread_register_notifier(&vfp_notifier_block);
315
316 /*
317 * We detected VFP, and the support code is
318 * in place; report VFP support to userspace.
319 */
320 elf_hwcap |= HWCAP_VFP;
297 } 321 }
298 return 0; 322 return 0;
299} 323}
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index f05fbe31576c..f60faccf01fa 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -139,19 +139,36 @@ static inline int cpu_is_xsc3(void)
139#define cpu_is_xscale() 1 139#define cpu_is_xscale() 1
140#endif 140#endif
141 141
142#define set_cr(x) \ 142static inline unsigned int get_cr(void)
143 __asm__ __volatile__( \ 143{
144 "mcr p15, 0, %0, c1, c0, 0 @ set CR" \ 144 unsigned int val;
145 : : "r" (x) : "cc") 145 asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
146 146 return val;
147#define get_cr() \ 147}
148 ({ \ 148
149 unsigned int __val; \ 149static inline void set_cr(unsigned int val)
150 __asm__ __volatile__( \ 150{
151 "mrc p15, 0, %0, c1, c0, 0 @ get CR" \ 151 asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
152 : "=r" (__val) : : "cc"); \ 152 : : "r" (val) : "cc");
153 __val; \ 153}
154 }) 154
155#define CPACC_FULL(n) (3 << (n * 2))
156#define CPACC_SVC(n) (1 << (n * 2))
157#define CPACC_DISABLE(n) (0 << (n * 2))
158
159static inline unsigned int get_copro_access(void)
160{
161 unsigned int val;
162 asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
163 : "=r" (val) : : "cc");
164 return val;
165}
166
167static inline void set_copro_access(unsigned int val)
168{
169 asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
170 : : "r" (val) : "cc");
171}
155 172
156extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ 173extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
157extern unsigned long cr_alignment; /* defined in entry-armv.S */ 174extern unsigned long cr_alignment; /* defined in entry-armv.S */