|
7 | 7 | * it under the terms of the GNU General Public License version 2 as
|
8 | 8 | * published by the Free Software Foundation.
|
9 | 9 | */
|
| 10 | +#include <linux/hardirq.h> |
10 | 11 | #include <asm-generic/xor.h>
|
| 12 | +#include <asm/hwcap.h> |
| 13 | +#include <asm/neon.h> |
11 | 14 |
|
12 | 15 | #define __XOR(a1, a2) a1 ^= a2
|
13 | 16 |
|
@@ -138,4 +141,74 @@ static struct xor_block_template xor_block_arm4regs = {
|
138 | 141 | xor_speed(&xor_block_arm4regs); \
|
139 | 142 | xor_speed(&xor_block_8regs); \
|
140 | 143 | xor_speed(&xor_block_32regs); \
|
| 144 | + NEON_TEMPLATES; \ |
141 | 145 | } while (0)
|
| 146 | + |
| 147 | +#ifdef CONFIG_KERNEL_MODE_NEON |
| 148 | + |
| 149 | +extern struct xor_block_template const xor_block_neon_inner; |
| 150 | + |
| 151 | +static void |
| 152 | +xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) |
| 153 | +{ |
| 154 | + if (in_interrupt()) { |
| 155 | + xor_arm4regs_2(bytes, p1, p2); |
| 156 | + } else { |
| 157 | + kernel_neon_begin(); |
| 158 | + xor_block_neon_inner.do_2(bytes, p1, p2); |
| 159 | + kernel_neon_end(); |
| 160 | + } |
| 161 | +} |
| 162 | + |
| 163 | +static void |
| 164 | +xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, |
| 165 | + unsigned long *p3) |
| 166 | +{ |
| 167 | + if (in_interrupt()) { |
| 168 | + xor_arm4regs_3(bytes, p1, p2, p3); |
| 169 | + } else { |
| 170 | + kernel_neon_begin(); |
| 171 | + xor_block_neon_inner.do_3(bytes, p1, p2, p3); |
| 172 | + kernel_neon_end(); |
| 173 | + } |
| 174 | +} |
| 175 | + |
| 176 | +static void |
| 177 | +xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, |
| 178 | + unsigned long *p3, unsigned long *p4) |
| 179 | +{ |
| 180 | + if (in_interrupt()) { |
| 181 | + xor_arm4regs_4(bytes, p1, p2, p3, p4); |
| 182 | + } else { |
| 183 | + kernel_neon_begin(); |
| 184 | + xor_block_neon_inner.do_4(bytes, p1, p2, p3, p4); |
| 185 | + kernel_neon_end(); |
| 186 | + } |
| 187 | +} |
| 188 | + |
| 189 | +static void |
| 190 | +xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, |
| 191 | + unsigned long *p3, unsigned long *p4, unsigned long *p5) |
| 192 | +{ |
| 193 | + if (in_interrupt()) { |
| 194 | + xor_arm4regs_5(bytes, p1, p2, p3, p4, p5); |
| 195 | + } else { |
| 196 | + kernel_neon_begin(); |
| 197 | + xor_block_neon_inner.do_5(bytes, p1, p2, p3, p4, p5); |
| 198 | + kernel_neon_end(); |
| 199 | + } |
| 200 | +} |
| 201 | + |
| 202 | +static struct xor_block_template xor_block_neon = { |
| 203 | + .name = "neon", |
| 204 | + .do_2 = xor_neon_2, |
| 205 | + .do_3 = xor_neon_3, |
| 206 | + .do_4 = xor_neon_4, |
| 207 | + .do_5 = xor_neon_5 |
| 208 | +}; |
| 209 | + |
| 210 | +#define NEON_TEMPLATES \ |
| 211 | + do { if (cpu_has_neon()) xor_speed(&xor_block_neon); } while (0) |
| 212 | +#else |
| 213 | +#define NEON_TEMPLATES |
| 214 | +#endif |
0 commit comments