/* * VFP support code initialisation. */ static int __init vfp_init(void) { unsigned int vfpsid; unsigned int cpu_arch = cpu_architecture(); u32 access = 0; if (cpu_arch >= CPU_ARCH_ARMv6) { access = get_copro_access(); /* * Enable full access to VFP (cp10 and cp11) */ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11)); } /* * First check that there is a VFP that we can use. * The handler is already setup to just log calls, so * we just need to read the VFPSID register. */ vfp_vector = vfp_testing_entry; barrier(); vfpsid = fmrx(FPSID); barrier(); vfp_vector = vfp_null_entry; printk(KERN_INFO "VFP support v0.3: "); if (VFP_arch) { printk("not present\n"); /* * Restore the copro access register. */ if (cpu_arch >= CPU_ARCH_ARMv6) set_copro_access(access); } else if (vfpsid & FPSID_NODOUBLE) { printk("no double precision support\n"); } else { smp_call_function(vfp_enable, NULL, 1, 1); VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */ printk("implementor %02x architecture %d part %02x variant %x rev %x\n", (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT, (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT, (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT, (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT, (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT); vfp_vector = vfp_support_entry; thread_register_notifier(&vfp_notifier_block); /* * We detected VFP, and the support code is * in place; report VFP support to userspace. */ elf_hwcap |= HWCAP_VFP; } return 0; }
static void vfp_enable(void *unused) { u32 access = get_copro_access(); /* * Enable full access to VFP (cp10 and cp11) */ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11)); }
static void vfp_enable(void *unused) { u32 access; BUG_ON(preemptible()); access = get_copro_access(); set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11)); }