diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-16 16:18:26 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-11-16 16:18:26 -0800 |
commit | 435e46f5d35dbe5ea745822db29f16e003fa07d7 (patch) | |
tree | 535db9ee2e47395eca1ff2f160dd444357b156d1 /arch/sparc/lib/atomic32.c | |
parent | 0fbae13642fc35ba6a774e9f76d0c1946e8f5c35 (diff) | |
parent | 5a2b59d3993e8ca4f7788a48a23e5cb303f26954 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc fixes from David Miller:
1) Fix NULL oops in Schizo PCI controller error handler.
2) Fix race between xchg and other operations on 32-bit sparc, from
Andreas Larsson.
3) swab*() helpers need a dummy memory input operand to show data flow
on 64-bit sparc.
4) Fix RCU warnings due to missing irq_{enter,exit}() around
generic_smp_call_function*() calls.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc64: Fix constraints on swab helpers.
sparc32: Implement xchg and atomic_xchg using ATOMIC_HASH locks
sparc64: Do irq_{enter,exit}() around generic_smp_call_function*().
sparc64: Fix crashes in schizo_pcierr_intr_other().
Diffstat (limited to 'arch/sparc/lib/atomic32.c')
-rw-r--r-- | arch/sparc/lib/atomic32.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c index a7c418ac26a..71cd65ab200 100644 --- a/arch/sparc/lib/atomic32.c +++ b/arch/sparc/lib/atomic32.c @@ -45,6 +45,19 @@ ATOMIC_OP(add, +=) #undef ATOMIC_OP +int atomic_xchg(atomic_t *v, int new) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(ATOMIC_HASH(v), flags); + ret = v->counter; + v->counter = new; + spin_unlock_irqrestore(ATOMIC_HASH(v), flags); + return ret; +} +EXPORT_SYMBOL(atomic_xchg); + int atomic_cmpxchg(atomic_t *v, int old, int new) { int ret; @@ -137,3 +150,17 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new) return (unsigned long)prev; } EXPORT_SYMBOL(__cmpxchg_u32); + +unsigned long __xchg_u32(volatile u32 *ptr, u32 new) +{ + unsigned long flags; + u32 prev; + + spin_lock_irqsave(ATOMIC_HASH(ptr), flags); + prev = *ptr; + *ptr = new; + spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags); + + return (unsigned long)prev; +} +EXPORT_SYMBOL(__xchg_u32); |