diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 15:35:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-25 15:35:32 -0700 |
commit | 0798b1dbfbd9ff2a370c5968c5f0621ef0075fe0 (patch) | |
tree | c7f61ab9683786a070da0933b9981fc74a4d865f /arch/tile/include/asm/bitops_64.h | |
parent | ad363e0916423b2e6cdfcdc30ae707ec709f0a65 (diff) | |
parent | 6738d3210aabe3016a1b03cd98a7fc479c229197 (diff) | |
download | kernel_samsung_smdk4412-0798b1dbfbd9ff2a370c5968c5f0621ef0075fe0.zip kernel_samsung_smdk4412-0798b1dbfbd9ff2a370c5968c5f0621ef0075fe0.tar.gz kernel_samsung_smdk4412-0798b1dbfbd9ff2a370c5968c5f0621ef0075fe0.tar.bz2 |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile: (26 commits)
arch/tile: prefer "tilepro" as the name of the 32-bit architecture
compat: include aio_abi.h for aio_context_t
arch/tile: cleanups for tilegx compat mode
arch/tile: allocate PCI IRQs later in boot
arch/tile: support signal "exception-trace" hook
arch/tile: use better definitions of xchg() and cmpxchg()
include/linux/compat.h: coding-style fixes
tile: add an RTC driver for the Tilera hypervisor
arch/tile: finish enabling support for TILE-Gx 64-bit chip
compat: fixes to allow working with tile arch
arch/tile: update defconfig file to something more useful
tile: do_hardwall_trap: do not play with task->sighand
tile: replace mm->cpu_vm_mask with mm_cpumask()
tile,mn10300: add device parameter to dma_cache_sync()
audit: support the "standard" <asm-generic/unistd.h>
arch/tile: clarify flush_buffer()/finv_buffer() function names
arch/tile: kernel-related cleanups from removing static page size
arch/tile: various header improvements for building drivers
arch/tile: disable GX prefetcher during cache flush
arch/tile: tolerate disabling CONFIG_BLK_DEV_INITRD
...
Diffstat (limited to 'arch/tile/include/asm/bitops_64.h')
-rw-r--r-- | arch/tile/include/asm/bitops_64.h | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/arch/tile/include/asm/bitops_64.h b/arch/tile/include/asm/bitops_64.h new file mode 100644 index 0000000..99615e8 --- /dev/null +++ b/arch/tile/include/asm/bitops_64.h @@ -0,0 +1,105 @@ +/* + * Copyright 2011 Tilera Corporation. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for + * more details. + */ + +#ifndef _ASM_TILE_BITOPS_64_H +#define _ASM_TILE_BITOPS_64_H + +#include <linux/compiler.h> +#include <asm/atomic.h> +#include <asm/system.h> + +/* See <asm/bitops.h> for API comments. */ + +static inline void set_bit(unsigned nr, volatile unsigned long *addr) +{ + unsigned long mask = (1UL << (nr % BITS_PER_LONG)); + __insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask); +} + +static inline void clear_bit(unsigned nr, volatile unsigned long *addr) +{ + unsigned long mask = (1UL << (nr % BITS_PER_LONG)); + __insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask); +} + +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() + + +static inline void change_bit(unsigned nr, volatile unsigned long *addr) +{ + unsigned long old, mask = (1UL << (nr % BITS_PER_LONG)); + long guess, oldval; + addr += nr / BITS_PER_LONG; + old = *addr; + do { + guess = oldval; + oldval = atomic64_cmpxchg((atomic64_t *)addr, + guess, guess ^ mask); + } while (guess != oldval); +} + + +/* + * The test_and_xxx_bit() routines require a memory fence before we + * start the operation, and after the operation completes. We use + * smp_mb() before, and rely on the "!= 0" comparison, plus a compiler + * barrier(), to block until the atomic op is complete. + */ + +static inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr) +{ + int val; + unsigned long mask = (1UL << (nr % BITS_PER_LONG)); + smp_mb(); /* barrier for proper semantics */ + val = (__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask) + & mask) != 0; + barrier(); + return val; +} + + +static inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr) +{ + int val; + unsigned long mask = (1UL << (nr % BITS_PER_LONG)); + smp_mb(); /* barrier for proper semantics */ + val = (__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask) + & mask) != 0; + barrier(); + return val; +} + + +static inline int test_and_change_bit(unsigned nr, + volatile unsigned long *addr) +{ + unsigned long mask = (1UL << (nr % BITS_PER_LONG)); + long guess, oldval = *addr; + addr += nr / BITS_PER_LONG; + oldval = *addr; + do { + guess = oldval; + oldval = atomic64_cmpxchg((atomic64_t *)addr, + guess, guess ^ mask); + } while (guess != oldval); + return (oldval & mask) != 0; +} + +#define ext2_set_bit_atomic(lock, nr, addr) \ + test_and_set_bit((nr), (unsigned long *)(addr)) +#define ext2_clear_bit_atomic(lock, nr, addr) \ + test_and_clear_bit((nr), (unsigned long *)(addr)) + +#endif /* _ASM_TILE_BITOPS_64_H */ |