1633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 2633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This file is subject to the terms and conditions of the GNU General Public 3633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * License. See the file "COPYING" in the main directory of this archive 4633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * for more details. 5633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 6633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (c) 1994 - 1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) 7633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (c) 1999, 2000 Silicon Graphics, Inc. 8633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 9633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifndef _ASM_BITOPS_H 10633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define _ASM_BITOPS_H 11633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 12633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifndef _LINUX_BITOPS_H 13633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#error only <linux/bitops.h> can be included directly 14633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 15633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 16633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/compiler.h> 17633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/irqflags.h> 18633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/types.h> 19633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/barrier.h> 20633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/bug.h> 21633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/byteorder.h> /* sigh ... */ 22633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/cpu-features.h> 23633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/sgidefs.h> 24633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/war.h> 25633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 26633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#if _MIPS_SZLONG == 32 27633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_LOG 5 28633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_MASK 31UL 29633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __LL "ll " 30633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __SC "sc " 31633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __INS "ins " 32633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __EXT "ext " 33633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#elif _MIPS_SZLONG == 64 34633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_LOG 6 35633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define SZLONG_MASK 63UL 36633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __LL "lld " 37633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __SC "scd " 38633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __INS "dins " 39633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define __EXT "dext " 40633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 41633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 42633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 43633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit() doesn't provide any barrier for the compiler. 44633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 45633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define smp_mb__before_clear_bit() smp_llsc_mb() 46633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define smp_mb__after_clear_bit() smp_llsc_mb() 47633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 48633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 49633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * set_bit - Atomically set a bit in memory 50633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: the bit to set 51633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: the address to start counting from 52633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 53633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This function is atomic and may not be reordered. See __set_bit() 54633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * if you do not require the atomic guarantees. 55633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Note that @nr may be almost arbitrarily large; this function is not 56633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * restricted to acting on a single-word quantity. 57633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 58633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void set_bit(unsigned long nr, volatile unsigned long *addr) 59633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 60633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 61633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short bit = nr & SZLONG_MASK; 62633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 63633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 64633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (cpu_has_llsc && R10000_LLSC_WAR) { 65633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 66633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 67633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # set_bit \n" 68633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %0, %2 \n" 69633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 70633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqzl %0, 1b \n" 71633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 72633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 73633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (1UL << bit), "m" (*m)); 74633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_CPU_MIPSR2 75633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (__builtin_constant_p(bit)) { 76633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 77633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # set_bit \n" 78633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __INS "%0, %4, %2, 1 \n" 79633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 80633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %0, 2f \n" 81633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 82633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 83633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 84633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 85633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (bit), "m" (*m), "r" (~0)); 86633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* CONFIG_CPU_MIPSR2 */ 87633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (cpu_has_llsc) { 88633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 89633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 90633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # set_bit \n" 91633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %0, %2 \n" 92633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 93633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %0, 2f \n" 94633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 95633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 96633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 97633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 98633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 99633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (1UL << bit), "m" (*m)); 100633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 101633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *a = addr; 102633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long mask; 103633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long flags; 104633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 105633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham a += nr >> SZLONG_LOG; 106633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham mask = 1UL << bit; 107633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_save(flags); 108633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *a |= mask; 109633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_restore(flags); 110633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 111633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 112633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 113633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 114633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit - Clears a bit in memory 115633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear 116633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from 117633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 118633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit() is atomic and may not be reordered. However, it does 119633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * not contain a memory barrier, so if it is used for locking purposes, 120633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() 121633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * in order to ensure changes are visible on other processors. 122633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 123633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void clear_bit(unsigned long nr, volatile unsigned long *addr) 124633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 125633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 126633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short bit = nr & SZLONG_MASK; 127633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 128633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 129633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (cpu_has_llsc && R10000_LLSC_WAR) { 130633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 131633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 132633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # clear_bit \n" 133633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %0, %2 \n" 134633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 135633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqzl %0, 1b \n" 136633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 137633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 138633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (~(1UL << bit)), "m" (*m)); 139633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_CPU_MIPSR2 140633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (__builtin_constant_p(bit)) { 141633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 142633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # clear_bit \n" 143633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __INS "%0, $0, %2, 1 \n" 144633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 145633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %0, 2f \n" 146633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 147633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 148633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 149633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 150633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (bit), "m" (*m)); 151633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* CONFIG_CPU_MIPSR2 */ 152633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (cpu_has_llsc) { 153633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 154633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 155633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # clear_bit \n" 156633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %0, %2 \n" 157633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 158633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %0, 2f \n" 159633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 160633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 161633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 162633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 163633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 164633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (~(1UL << bit)), "m" (*m)); 165633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 166633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *a = addr; 167633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long mask; 168633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long flags; 169633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 170633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham a += nr >> SZLONG_LOG; 171633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham mask = 1UL << bit; 172633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_save(flags); 173633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *a &= ~mask; 174633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_restore(flags); 175633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 176633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 177633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 178633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 179633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit_unlock - Clears a bit in memory 180633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear 181633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from 182633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 183633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * clear_bit() is atomic and implies release semantics before the memory 184633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * operation. It can be used for an unlock. 185633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 186633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) 187633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 188633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_mb__before_clear_bit(); 189633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham clear_bit(nr, addr); 190633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 191633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 192633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 193633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * change_bit - Toggle a bit in memory 194633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to change 195633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from 196633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 197633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * change_bit() is atomic and may not be reordered. 198633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Note that @nr may be almost arbitrarily large; this function is not 199633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * restricted to acting on a single-word quantity. 200633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 201633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void change_bit(unsigned long nr, volatile unsigned long *addr) 202633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 203633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short bit = nr & SZLONG_MASK; 204633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 205633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (cpu_has_llsc && R10000_LLSC_WAR) { 206633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 207633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 208633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 209633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 210633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 211633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # change_bit \n" 212633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " xor %0, %2 \n" 213633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 214633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqzl %0, 1b \n" 215633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 216633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 217633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (1UL << bit), "m" (*m)); 218633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (cpu_has_llsc) { 219633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 220633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 221633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 222633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 223633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 224633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # change_bit \n" 225633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " xor %0, %2 \n" 226633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 227633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %0, 2f \n" 228633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 229633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 230633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 231633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 232633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m) 233633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (1UL << bit), "m" (*m)); 234633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 235633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *a = addr; 236633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long mask; 237633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long flags; 238633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 239633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham a += nr >> SZLONG_LOG; 240633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham mask = 1UL << bit; 241633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_save(flags); 242633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *a ^= mask; 243633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_restore(flags); 244633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 245633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 246633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 247633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 248633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_set_bit - Set a bit and return its old value 249633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to set 250633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from 251633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 252633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and cannot be reordered. 253633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * It also implies a memory barrier. 254633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 255633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_set_bit(unsigned long nr, 256633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *addr) 257633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 258633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short bit = nr & SZLONG_MASK; 259633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long res; 260633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 261633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_llsc_mb(); 262633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 263633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (cpu_has_llsc && R10000_LLSC_WAR) { 264633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 265633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 266633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 267633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 268633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 269633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_set_bit \n" 270633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %2, %0, %3 \n" 271633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%2, %1 \n" 272633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqzl %2, 1b \n" 273633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 274633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 275633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 276633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 277633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 278633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (cpu_has_llsc) { 279633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 280633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 281633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 282633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 283633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push \n" 284633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noreorder \n" 285633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 286633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_set_bit \n" 287633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %2, %0, %3 \n" 288633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%2, %1 \n" 289633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %2, 2f \n" 290633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 291633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 292633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 293633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " nop \n" 294633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 295633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop \n" 296633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 297633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 298633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 299633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 300633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *a = addr; 301633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long mask; 302633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long flags; 303633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 304633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham a += nr >> SZLONG_LOG; 305633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham mask = 1UL << bit; 306633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_save(flags); 307633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham res = (mask & *a); 308633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *a |= mask; 309633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_restore(flags); 310633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 311633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 312633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_llsc_mb(); 313633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 314633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return res != 0; 315633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 316633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 317633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 318633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_set_bit_lock - Set a bit and return its old value 319633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to set 320633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from 321633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 322633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and implies acquire ordering semantics 323633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * after the memory operation. 324633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 325633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_set_bit_lock(unsigned long nr, 326633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *addr) 327633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 328633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short bit = nr & SZLONG_MASK; 329633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long res; 330633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 331633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (cpu_has_llsc && R10000_LLSC_WAR) { 332633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 333633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 334633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 335633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 336633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 337633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_set_bit \n" 338633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %2, %0, %3 \n" 339633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%2, %1 \n" 340633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqzl %2, 1b \n" 341633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 342633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 343633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 344633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 345633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 346633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (cpu_has_llsc) { 347633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 348633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 349633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 350633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 351633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push \n" 352633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noreorder \n" 353633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 354633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_set_bit \n" 355633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %2, %0, %3 \n" 356633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%2, %1 \n" 357633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %2, 2f \n" 358633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 359633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 360633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 361633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " nop \n" 362633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 363633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop \n" 364633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 365633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 366633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 367633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 368633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *a = addr; 369633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long mask; 370633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long flags; 371633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 372633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham a += nr >> SZLONG_LOG; 373633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham mask = 1UL << bit; 374633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_save(flags); 375633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham res = (mask & *a); 376633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *a |= mask; 377633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_restore(flags); 378633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 379633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 380633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_llsc_mb(); 381633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 382633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return res != 0; 383633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 384633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 385633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_clear_bit - Clear a bit and return its old value 386633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear 387633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from 388633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 389633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and cannot be reordered. 390633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * It also implies a memory barrier. 391633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 392633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_clear_bit(unsigned long nr, 393633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *addr) 394633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 395633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short bit = nr & SZLONG_MASK; 396633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long res; 397633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 398633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_llsc_mb(); 399633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 400633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (cpu_has_llsc && R10000_LLSC_WAR) { 401633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 402633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 403633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 404633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 405633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 406633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_clear_bit \n" 407633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %2, %0, %3 \n" 408633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " xor %2, %3 \n" 409633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%2, %1 \n" 410633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqzl %2, 1b \n" 411633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 412633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 413633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 414633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 415633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 416633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_CPU_MIPSR2 417633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (__builtin_constant_p(nr)) { 418633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 419633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 420633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 421633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 422633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_clear_bit \n" 423633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __EXT "%2, %0, %3, 1 \n" 424633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __INS "%0, $0, %3, 1 \n" 425633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%0, %1 \n" 426633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %0, 2f \n" 427633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 428633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 429633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 430633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 431633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "ir" (bit), "m" (*m) 432633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 433633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 434633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (cpu_has_llsc) { 435633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 436633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 437633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 438633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 439633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push \n" 440633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noreorder \n" 441633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 442633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_clear_bit \n" 443633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " or %2, %0, %3 \n" 444633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " xor %2, %3 \n" 445633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%2, %1 \n" 446633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %2, 2f \n" 447633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 448633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 449633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 450633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " nop \n" 451633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 452633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop \n" 453633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 454633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 455633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 456633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 457633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *a = addr; 458633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long mask; 459633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long flags; 460633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 461633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham a += nr >> SZLONG_LOG; 462633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham mask = 1UL << bit; 463633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_save(flags); 464633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham res = (mask & *a); 465633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *a &= ~mask; 466633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_restore(flags); 467633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 468633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 469633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_llsc_mb(); 470633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 471633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return res != 0; 472633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 473633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 474633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 475633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * test_and_change_bit - Change a bit and return its old value 476633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to change 477633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to count from 478633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 479633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This operation is atomic and cannot be reordered. 480633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * It also implies a memory barrier. 481633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 482633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int test_and_change_bit(unsigned long nr, 483633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *addr) 484633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 485633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short bit = nr & SZLONG_MASK; 486633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long res; 487633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 488633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_llsc_mb(); 489633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 490633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (cpu_has_llsc && R10000_LLSC_WAR) { 491633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 492633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 493633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 494633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 495633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 496633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_change_bit \n" 497633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " xor %2, %0, %3 \n" 498633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "%2, %1 \n" 499633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqzl %2, 1b \n" 500633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 501633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips0 \n" 502633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 503633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 504633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 505633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else if (cpu_has_llsc) { 506633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 507633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long temp; 508633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 509633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__ __volatile__( 510633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push \n" 511633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noreorder \n" 512633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips3 \n" 513633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "1: " __LL "%0, %1 # test_and_change_bit \n" 514633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " xor %2, %0, %3 \n" 515633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " " __SC "\t%2, %1 \n" 516633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " beqz %2, 2f \n" 517633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " and %2, %0, %3 \n" 518633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .subsection 2 \n" 519633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "2: b 1b \n" 520633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " nop \n" 521633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .previous \n" 522633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop \n" 523633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=&r" (temp), "=m" (*m), "=&r" (res) 524633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (1UL << bit), "m" (*m) 525633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "memory"); 526633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } else { 527633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham volatile unsigned long *a = addr; 528633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long mask; 529633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned long flags; 530633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 531633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham a += nr >> SZLONG_LOG; 532633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham mask = 1UL << bit; 533633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_save(flags); 534633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham res = (mask & *a); 535633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *a ^= mask; 536633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham raw_local_irq_restore(flags); 537633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 538633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 539633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_llsc_mb(); 540633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 541633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return res != 0; 542633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 543633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 544633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/non-atomic.h> 545633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 546633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 547633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * __clear_bit_unlock - Clears a bit in memory 548633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @nr: Bit to clear 549633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @addr: Address to start counting from 550633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 551633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * __clear_bit() is non-atomic and implies release semantics before the memory 552633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * operation. It can be used for an unlock if no other CPUs can concurrently 553633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * modify other bits in the word. 554633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 555633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) 556633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 557633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham smp_mb(); 558633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __clear_bit(nr, addr); 559633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 560633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 561633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 562633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 563633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 564633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Return the bit position (0..63) of the most significant 1 bit in a word 565633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Returns -1 if no 1 bit exists 566633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 567633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline unsigned long __fls(unsigned long x) 568633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 569633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int lz; 570633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 571633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (sizeof(x) == 4) { 572633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__( 573633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push \n" 574633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips32 \n" 575633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " clz %0, %1 \n" 576633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop \n" 577633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=r" (lz) 578633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (x)); 579633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 580633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return 31 - lz; 581633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } 582633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 583633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham BUG_ON(sizeof(x) != 8); 584633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 585633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__( 586633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push \n" 587633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set mips64 \n" 588633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " dclz %0, %1 \n" 589633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop \n" 590633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=r" (lz) 591633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (x)); 592633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 593633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return 63 - lz; 594633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 595633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 596633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 597633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * __ffs - find first bit in word. 598633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @word: The word to search 599633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 600633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Returns 0..SZLONG-1 601633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Undefined if no bit exists, so code should check against 0 first. 602633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 603633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline unsigned long __ffs(unsigned long word) 604633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 605633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return __fls(word & -word); 606633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 607633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 608633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 609633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * fls - find last bit set. 610633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @word: The word to search 611633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 612633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This is defined the same way as ffs. 613633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. 614633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 615633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int fls(int word) 616633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 617633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__("clz %0, %1" : "=r" (word) : "r" (word)); 618633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 619633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return 32 - word; 620633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 621633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 622633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPS64) 623633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int fls64(__u64 word) 624633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 625633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__("dclz %0, %1" : "=r" (word) : "r" (word)); 626633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 627633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return 64 - word; 628633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 629633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#else 630633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/fls64.h> 631633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 632633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 633633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 634633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * ffs - find first bit set. 635633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * @word: The word to search 636633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 637633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This is defined the same way as 638633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * the libc and compiler builtin ffs routines, therefore 639633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * differs in spirit from the above ffz (man ffs). 640633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 641633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline int ffs(int word) 642633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 643633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (!word) 644633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return 0; 645633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 646633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return fls(word & -word); 647633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 648633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 649633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#else 650633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 651633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/__ffs.h> 652633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/__fls.h> 653633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ffs.h> 654633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/fls.h> 655633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/fls64.h> 656633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 657633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /*defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) */ 658633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 659633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ffz.h> 660633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/find.h> 661633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 662633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef __KERNEL__ 663633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 664633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/sched.h> 665633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/hweight.h> 666633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ext2-non-atomic.h> 667633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/ext2-atomic.h> 668633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm-generic/bitops/minix.h> 669633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 670633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* __KERNEL__ */ 671633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 672633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* _ASM_BITOPS_H */ 673