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