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