1867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* 2867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Copyright 2010 Tilera Corporation. All Rights Reserved. 3867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 4867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This program is free software; you can redistribute it and/or 5867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * modify it under the terms of the GNU General Public License 6867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * as published by the Free Software Foundation, version 2. 7867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 8867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This program is distributed in the hope that it will be useful, but 9867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * WITHOUT ANY WARRANTY; without even the implied warranty of 10867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * NON INFRINGEMENT. See the GNU General Public License for 12867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * more details. 13867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 14867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 15867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#ifndef _ASM_TILE_BITOPS_32_H 16867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#define _ASM_TILE_BITOPS_32_H 17867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 18867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <linux/compiler.h> 196dc9658fa1af9f58d358692b68135f464c167e10Chris Metcalf#include <asm/barrier.h> 20867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 21867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/* Tile-specific routines to support <asm/bitops.h>. */ 22867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfunsigned long _atomic_or(volatile unsigned long *p, unsigned long mask); 23867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfunsigned long _atomic_andn(volatile unsigned long *p, unsigned long mask); 24867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfunsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask); 25867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 26867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/** 27867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * set_bit - Atomically set a bit in memory 28867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @nr: the bit to set 29867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @addr: the address to start counting from 30867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 31867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This function is atomic and may not be reordered. 32867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * See __set_bit() if you do not require the atomic guarantees. 33867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Note that @nr may be almost arbitrarily large; this function is not 34867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * restricted to acting on a single-word quantity. 35867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 36867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline void set_bit(unsigned nr, volatile unsigned long *addr) 37867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 38867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf _atomic_or(addr + BIT_WORD(nr), BIT_MASK(nr)); 39867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 40867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 41867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/** 42867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * clear_bit - Clears a bit in memory 43867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @nr: Bit to clear 44867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @addr: Address to start counting from 45867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 46867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * clear_bit() is atomic and may not be reordered. 47867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * See __clear_bit() if you do not require the atomic guarantees. 48867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Note that @nr may be almost arbitrarily large; this function is not 49867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * restricted to acting on a single-word quantity. 50867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 51867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * clear_bit() may not contain a memory barrier, so if it is used for 52ce3609f93445846f7b5a5b4bacb236a9bdc35216Peter Zijlstra * locking purposes, you should call smp_mb__before_atomic() and/or 53ce3609f93445846f7b5a5b4bacb236a9bdc35216Peter Zijlstra * smp_mb__after_atomic() to ensure changes are visible on other cpus. 54867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 55867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline void clear_bit(unsigned nr, volatile unsigned long *addr) 56867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 57867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf _atomic_andn(addr + BIT_WORD(nr), BIT_MASK(nr)); 58867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 59867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 60867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/** 61867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * change_bit - Toggle a bit in memory 62867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @nr: Bit to change 63867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @addr: Address to start counting from 64867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 65867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * change_bit() is atomic and may not be reordered. 66867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * See __change_bit() if you do not require the atomic guarantees. 67867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * Note that @nr may be almost arbitrarily large; this function is not 68867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * restricted to acting on a single-word quantity. 69867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 70867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline void change_bit(unsigned nr, volatile unsigned long *addr) 71867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 72867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf _atomic_xor(addr + BIT_WORD(nr), BIT_MASK(nr)); 73867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 74867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 75867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/** 76867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * test_and_set_bit - Set a bit and return its old value 77867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @nr: Bit to set 78867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @addr: Address to count from 79867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 80867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This operation is atomic and cannot be reordered. 81867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * It also implies a memory barrier. 82867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 83867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr) 84867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 85867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf unsigned long mask = BIT_MASK(nr); 86867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf addr += BIT_WORD(nr); 87867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf smp_mb(); /* barrier for proper semantics */ 88867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return (_atomic_or(addr, mask) & mask) != 0; 89867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 90867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 91867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/** 92867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * test_and_clear_bit - Clear a bit and return its old value 93867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @nr: Bit to clear 94867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @addr: Address to count from 95867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 96867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This operation is atomic and cannot be reordered. 97867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * It also implies a memory barrier. 98867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 99867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr) 100867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 101867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf unsigned long mask = BIT_MASK(nr); 102867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf addr += BIT_WORD(nr); 103867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf smp_mb(); /* barrier for proper semantics */ 104867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return (_atomic_andn(addr, mask) & mask) != 0; 105867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 106867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 107867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf/** 108867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * test_and_change_bit - Change a bit and return its old value 109867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @nr: Bit to change 110867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * @addr: Address to count from 111867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * 112867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * This operation is atomic and cannot be reordered. 113867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf * It also implies a memory barrier. 114867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf */ 115867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalfstatic inline int test_and_change_bit(unsigned nr, 116867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf volatile unsigned long *addr) 117867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf{ 118867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf unsigned long mask = BIT_MASK(nr); 119867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf addr += BIT_WORD(nr); 120867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf smp_mb(); /* barrier for proper semantics */ 121867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf return (_atomic_xor(addr, mask) & mask) != 0; 122867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf} 123867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 124867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#include <asm-generic/bitops/ext2-atomic.h> 125867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf 126867e359b97c970a60626d5d76bbe2a8fadbf38fbChris Metcalf#endif /* _ASM_TILE_BITOPS_32_H */ 127