]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - arch/arm/lib/bitops.h
Merge branch 'master' into for-next
[mirror_ubuntu-eoan-kernel.git] / arch / arm / lib / bitops.h
CommitLineData
c36ef4b1
WD
1#include <asm/unwind.h>
2
6323f0cc 3#if __LINUX_ARM_ARCH__ >= 6
c36ef4b1
WD
4 .macro bitop, name, instr
5ENTRY( \name )
6UNWIND( .fnstart )
a16ede35
RK
7 ands ip, r1, #3
8 strneb r1, [ip] @ assert word-aligned
54ea06f6 9 mov r2, #1
6323f0cc
RK
10 and r3, r0, #31 @ Get bit offset
11 mov r0, r0, lsr #5
12 add r1, r1, r0, lsl #2 @ Get word offset
b7ec6994 13#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
d779c07d
WD
14 .arch_extension mp
15 ALT_SMP(W(pldw) [r1])
16 ALT_UP(W(nop))
17#endif
54ea06f6 18 mov r3, r2, lsl r3
6323f0cc 191: ldrex r2, [r1]
54ea06f6 20 \instr r2, r2, r3
6323f0cc 21 strex r0, r2, [r1]
e7ec0293 22 cmp r0, #0
54ea06f6 23 bne 1b
3ba6e69a 24 bx lr
c36ef4b1
WD
25UNWIND( .fnend )
26ENDPROC(\name )
54ea06f6
RK
27 .endm
28
c36ef4b1
WD
29 .macro testop, name, instr, store
30ENTRY( \name )
31UNWIND( .fnstart )
a16ede35
RK
32 ands ip, r1, #3
33 strneb r1, [ip] @ assert word-aligned
54ea06f6 34 mov r2, #1
6323f0cc
RK
35 and r3, r0, #31 @ Get bit offset
36 mov r0, r0, lsr #5
37 add r1, r1, r0, lsl #2 @ Get word offset
54ea06f6 38 mov r3, r2, lsl r3 @ create mask
bac4e960 39 smp_dmb
6323f0cc 401: ldrex r2, [r1]
54ea06f6 41 ands r0, r2, r3 @ save old value of bit
6323f0cc
RK
42 \instr r2, r2, r3 @ toggle bit
43 strex ip, r2, [r1]
614d73ed 44 cmp ip, #0
54ea06f6 45 bne 1b
bac4e960 46 smp_dmb
54ea06f6
RK
47 cmp r0, #0
48 movne r0, #1
3ba6e69a 492: bx lr
c36ef4b1
WD
50UNWIND( .fnend )
51ENDPROC(\name )
54ea06f6
RK
52 .endm
53#else
c36ef4b1
WD
54 .macro bitop, name, instr
55ENTRY( \name )
56UNWIND( .fnstart )
a16ede35
RK
57 ands ip, r1, #3
58 strneb r1, [ip] @ assert word-aligned
6323f0cc
RK
59 and r2, r0, #31
60 mov r0, r0, lsr #5
7a55fd0b
RK
61 mov r3, #1
62 mov r3, r3, lsl r2
59d1ff3b 63 save_and_disable_irqs ip
6323f0cc 64 ldr r2, [r1, r0, lsl #2]
7a55fd0b 65 \instr r2, r2, r3
6323f0cc 66 str r2, [r1, r0, lsl #2]
7a55fd0b
RK
67 restore_irqs ip
68 mov pc, lr
c36ef4b1
WD
69UNWIND( .fnend )
70ENDPROC(\name )
7a55fd0b
RK
71 .endm
72
73/**
74 * testop - implement a test_and_xxx_bit operation.
75 * @instr: operational instruction
76 * @store: store instruction
77 *
78 * Note: we can trivially conditionalise the store instruction
6cbdc8c5 79 * to avoid dirtying the data cache.
7a55fd0b 80 */
c36ef4b1
WD
81 .macro testop, name, instr, store
82ENTRY( \name )
83UNWIND( .fnstart )
a16ede35
RK
84 ands ip, r1, #3
85 strneb r1, [ip] @ assert word-aligned
6323f0cc
RK
86 and r3, r0, #31
87 mov r0, r0, lsr #5
59d1ff3b 88 save_and_disable_irqs ip
6323f0cc
RK
89 ldr r2, [r1, r0, lsl #2]!
90 mov r0, #1
7a55fd0b
RK
91 tst r2, r0, lsl r3
92 \instr r2, r2, r0, lsl r3
93 \store r2, [r1]
7a55fd0b 94 moveq r0, #0
0d928b0b 95 restore_irqs ip
7a55fd0b 96 mov pc, lr
c36ef4b1
WD
97UNWIND( .fnend )
98ENDPROC(\name )
7a55fd0b 99 .endm
54ea06f6 100#endif