0001
0002 #include <asm/assembler.h>
0003 #include <asm/unwind.h>
0004
0005 #if __LINUX_ARM_ARCH__ >= 6
0006 .macro bitop, name, instr
0007 ENTRY( \name )
0008 UNWIND( .fnstart )
0009 ands ip, r1, #3
0010 strbne r1, [ip] @ assert word-aligned
0011 mov r2, #1
0012 and r3, r0, #31 @ Get bit offset
0013 mov r0, r0, lsr #5
0014 add r1, r1, r0, lsl #2 @ Get word offset
0015 #if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
0016 .arch_extension mp
0017 ALT_SMP(W(pldw) [r1])
0018 ALT_UP(W(nop))
0019 #endif
0020 mov r3, r2, lsl r3
0021 1: ldrex r2, [r1]
0022 \instr r2, r2, r3
0023 strex r0, r2, [r1]
0024 cmp r0, #0
0025 bne 1b
0026 bx lr
0027 UNWIND( .fnend )
0028 ENDPROC(\name )
0029 .endm
0030
0031 .macro testop, name, instr, store
0032 ENTRY( \name )
0033 UNWIND( .fnstart )
0034 ands ip, r1, #3
0035 strbne r1, [ip] @ assert word-aligned
0036 mov r2, #1
0037 and r3, r0, #31 @ Get bit offset
0038 mov r0, r0, lsr #5
0039 add r1, r1, r0, lsl #2 @ Get word offset
0040 mov r3, r2, lsl r3 @ create mask
0041 smp_dmb
0042 #if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
0043 .arch_extension mp
0044 ALT_SMP(W(pldw) [r1])
0045 ALT_UP(W(nop))
0046 #endif
0047 1: ldrex r2, [r1]
0048 ands r0, r2, r3 @ save old value of bit
0049 \instr r2, r2, r3 @ toggle bit
0050 strex ip, r2, [r1]
0051 cmp ip, #0
0052 bne 1b
0053 smp_dmb
0054 cmp r0, #0
0055 movne r0, #1
0056 2: bx lr
0057 UNWIND( .fnend )
0058 ENDPROC(\name )
0059 .endm
0060 #else
0061 .macro bitop, name, instr
0062 ENTRY( \name )
0063 UNWIND( .fnstart )
0064 ands ip, r1, #3
0065 strbne r1, [ip] @ assert word-aligned
0066 and r2, r0, #31
0067 mov r0, r0, lsr #5
0068 mov r3, #1
0069 mov r3, r3, lsl r2
0070 save_and_disable_irqs ip
0071 ldr r2, [r1, r0, lsl #2]
0072 \instr r2, r2, r3
0073 str r2, [r1, r0, lsl #2]
0074 restore_irqs ip
0075 ret lr
0076 UNWIND( .fnend )
0077 ENDPROC(\name )
0078 .endm
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 .macro testop, name, instr, store
0089 ENTRY( \name )
0090 UNWIND( .fnstart )
0091 ands ip, r1, #3
0092 strbne r1, [ip] @ assert word-aligned
0093 and r3, r0, #31
0094 mov r0, r0, lsr #5
0095 save_and_disable_irqs ip
0096 ldr r2, [r1, r0, lsl #2]!
0097 mov r0, #1
0098 tst r2, r0, lsl r3
0099 \instr r2, r2, r0, lsl r3
0100 \store r2, [r1]
0101 moveq r0, #0
0102 restore_irqs ip
0103 ret lr
0104 UNWIND( .fnend )
0105 ENDPROC(\name )
0106 .endm
0107 #endif