1 #include <linux/config.h> 2 3 #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K) 4 .macro bitop, instr 5 mov r2, #1 6 and r3, r0, #7 @ Get bit offset 7 add r1, r1, r0, lsr #3 @ Get byte offset 8 mov r3, r2, lsl r3 9 1: ldrexb r2, [r1] 10 \instr r2, r2, r3 11 strexb r0, r2, [r1] 12 cmp r0, #0 13 bne 1b 14 mov pc, lr 15 .endm 16 17 .macro testop, instr, store 18 and r3, r0, #7 @ Get bit offset 19 mov r2, #1 20 add r1, r1, r0, lsr #3 @ Get byte offset 21 mov r3, r2, lsl r3 @ create mask 22 1: ldrexb r2, [r1] 23 ands r0, r2, r3 @ save old value of bit 24 \instr r2, r2, r3 @ toggle bit 25 strexb ip, r2, [r1] 26 cmp ip, #0 27 bne 1b 28 cmp r0, #0 29 movne r0, #1 30 2: mov pc, lr 31 .endm 32 #else 33 .macro bitop, instr 34 and r2, r0, #7 35 mov r3, #1 36 mov r3, r3, lsl r2 37 save_and_disable_irqs ip 38 ldrb r2, [r1, r0, lsr #3] 39 \instr r2, r2, r3 40 strb r2, [r1, r0, lsr #3] 41 restore_irqs ip 42 mov pc, lr 43 .endm 44 45 /** 46 * testop - implement a test_and_xxx_bit operation. 47 * @instr: operational instruction 48 * @store: store instruction 49 * 50 * Note: we can trivially conditionalise the store instruction 51 * to avoid dirting the data cache. 52 */ 53 .macro testop, instr, store 54 add r1, r1, r0, lsr #3 55 and r3, r0, #7 56 mov r0, #1 57 save_and_disable_irqs ip 58 ldrb r2, [r1] 59 tst r2, r0, lsl r3 60 \instr r2, r2, r0, lsl r3 61 \store r2, [r1] 62 restore_irqs ip 63 moveq r0, #0 64 mov pc, lr 65 .endm 66 #endif 67