Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
[pandora-kernel.git] / arch / arm / lib / bitops.h
1 #include <asm/unwind.h>
2
3 #if __LINUX_ARM_ARCH__ >= 6
4         .macro  bitop, name, instr
5 ENTRY(  \name           )
6 UNWIND( .fnstart        )
7         ands    ip, r1, #3
8         strneb  r1, [ip]                @ assert word-aligned
9         mov     r2, #1
10         and     r3, r0, #31             @ Get bit offset
11         mov     r0, r0, lsr #5
12         add     r1, r1, r0, lsl #2      @ Get word offset
13         mov     r3, r2, lsl r3
14 1:      ldrex   r2, [r1]
15         \instr  r2, r2, r3
16         strex   r0, r2, [r1]
17         cmp     r0, #0
18         bne     1b
19         bx      lr
20 UNWIND( .fnend          )
21 ENDPROC(\name           )
22         .endm
23
24         .macro  testop, name, instr, store
25 ENTRY(  \name           )
26 UNWIND( .fnstart        )
27         ands    ip, r1, #3
28         strneb  r1, [ip]                @ assert word-aligned
29         mov     r2, #1
30         and     r3, r0, #31             @ Get bit offset
31         mov     r0, r0, lsr #5
32         add     r1, r1, r0, lsl #2      @ Get word offset
33         mov     r3, r2, lsl r3          @ create mask
34         smp_dmb
35 1:      ldrex   r2, [r1]
36         ands    r0, r2, r3              @ save old value of bit
37         \instr  r2, r2, r3              @ toggle bit
38         strex   ip, r2, [r1]
39         cmp     ip, #0
40         bne     1b
41         smp_dmb
42         cmp     r0, #0
43         movne   r0, #1
44 2:      bx      lr
45 UNWIND( .fnend          )
46 ENDPROC(\name           )
47         .endm
48 #else
49         .macro  bitop, name, instr
50 ENTRY(  \name           )
51 UNWIND( .fnstart        )
52         ands    ip, r1, #3
53         strneb  r1, [ip]                @ assert word-aligned
54         and     r2, r0, #31
55         mov     r0, r0, lsr #5
56         mov     r3, #1
57         mov     r3, r3, lsl r2
58         save_and_disable_irqs ip
59         ldr     r2, [r1, r0, lsl #2]
60         \instr  r2, r2, r3
61         str     r2, [r1, r0, lsl #2]
62         restore_irqs ip
63         mov     pc, lr
64 UNWIND( .fnend          )
65 ENDPROC(\name           )
66         .endm
67
68 /**
69  * testop - implement a test_and_xxx_bit operation.
70  * @instr: operational instruction
71  * @store: store instruction
72  *
73  * Note: we can trivially conditionalise the store instruction
74  * to avoid dirtying the data cache.
75  */
76         .macro  testop, name, instr, store
77 ENTRY(  \name           )
78 UNWIND( .fnstart        )
79         ands    ip, r1, #3
80         strneb  r1, [ip]                @ assert word-aligned
81         and     r3, r0, #31
82         mov     r0, r0, lsr #5
83         save_and_disable_irqs ip
84         ldr     r2, [r1, r0, lsl #2]!
85         mov     r0, #1
86         tst     r2, r0, lsl r3
87         \instr  r2, r2, r0, lsl r3
88         \store  r2, [r1]
89         moveq   r0, #0
90         restore_irqs ip
91         mov     pc, lr
92 UNWIND( .fnend          )
93 ENDPROC(\name           )
94         .endm
95 #endif