1*7d11965dSArd Biesheuvel /* 2*7d11965dSArd Biesheuvel * linux/lib/raid6/neon.c - RAID6 syndrome calculation using ARM NEON intrinsics 3*7d11965dSArd Biesheuvel * 4*7d11965dSArd Biesheuvel * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org> 5*7d11965dSArd Biesheuvel * 6*7d11965dSArd Biesheuvel * This program is free software; you can redistribute it and/or modify 7*7d11965dSArd Biesheuvel * it under the terms of the GNU General Public License version 2 as 8*7d11965dSArd Biesheuvel * published by the Free Software Foundation. 9*7d11965dSArd Biesheuvel */ 10*7d11965dSArd Biesheuvel 11*7d11965dSArd Biesheuvel #include <linux/raid/pq.h> 12*7d11965dSArd Biesheuvel 13*7d11965dSArd Biesheuvel #ifdef __KERNEL__ 14*7d11965dSArd Biesheuvel #include <asm/neon.h> 15*7d11965dSArd Biesheuvel #else 16*7d11965dSArd Biesheuvel #define kernel_neon_begin() 17*7d11965dSArd Biesheuvel #define kernel_neon_end() 18*7d11965dSArd Biesheuvel #define cpu_has_neon() (1) 19*7d11965dSArd Biesheuvel #endif 20*7d11965dSArd Biesheuvel 21*7d11965dSArd Biesheuvel /* 22*7d11965dSArd Biesheuvel * There are 2 reasons these wrappers are kept in a separate compilation unit 23*7d11965dSArd Biesheuvel * from the actual implementations in neonN.c (generated from neon.uc by 24*7d11965dSArd Biesheuvel * unroll.awk): 25*7d11965dSArd Biesheuvel * - the actual implementations use NEON intrinsics, and the GCC support header 26*7d11965dSArd Biesheuvel * (arm_neon.h) is not fully compatible (type wise) with the kernel; 27*7d11965dSArd Biesheuvel * - the neonN.c files are compiled with -mfpu=neon and optimization enabled, 28*7d11965dSArd Biesheuvel * and we have to make sure that we never use *any* NEON/VFP instructions 29*7d11965dSArd Biesheuvel * outside a kernel_neon_begin()/kernel_neon_end() pair. 30*7d11965dSArd Biesheuvel */ 31*7d11965dSArd Biesheuvel 32*7d11965dSArd Biesheuvel #define RAID6_NEON_WRAPPER(_n) \ 33*7d11965dSArd Biesheuvel static void raid6_neon ## _n ## _gen_syndrome(int disks, \ 34*7d11965dSArd Biesheuvel size_t bytes, void **ptrs) \ 35*7d11965dSArd Biesheuvel { \ 36*7d11965dSArd Biesheuvel void raid6_neon ## _n ## _gen_syndrome_real(int, \ 37*7d11965dSArd Biesheuvel unsigned long, void**); \ 38*7d11965dSArd Biesheuvel kernel_neon_begin(); \ 39*7d11965dSArd Biesheuvel raid6_neon ## _n ## _gen_syndrome_real(disks, \ 40*7d11965dSArd Biesheuvel (unsigned long)bytes, ptrs); \ 41*7d11965dSArd Biesheuvel kernel_neon_end(); \ 42*7d11965dSArd Biesheuvel } \ 43*7d11965dSArd Biesheuvel struct raid6_calls const raid6_neonx ## _n = { \ 44*7d11965dSArd Biesheuvel raid6_neon ## _n ## _gen_syndrome, \ 45*7d11965dSArd Biesheuvel raid6_have_neon, \ 46*7d11965dSArd Biesheuvel "neonx" #_n, \ 47*7d11965dSArd Biesheuvel 0 \ 48*7d11965dSArd Biesheuvel } 49*7d11965dSArd Biesheuvel 50*7d11965dSArd Biesheuvel static int raid6_have_neon(void) 51*7d11965dSArd Biesheuvel { 52*7d11965dSArd Biesheuvel return cpu_has_neon(); 53*7d11965dSArd Biesheuvel } 54*7d11965dSArd Biesheuvel 55*7d11965dSArd Biesheuvel RAID6_NEON_WRAPPER(1); 56*7d11965dSArd Biesheuvel RAID6_NEON_WRAPPER(2); 57*7d11965dSArd Biesheuvel RAID6_NEON_WRAPPER(4); 58*7d11965dSArd Biesheuvel RAID6_NEON_WRAPPER(8); 59