Merge branch 'fix/intel' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[sfrench/cifs-2.6.git] / arch / alpha / lib / dec_and_lock.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * arch/alpha/lib/dec_and_lock.c
4  *
5  * ll/sc version of atomic_dec_and_lock()
6  * 
7  */
8
9 #include <linux/spinlock.h>
10 #include <linux/atomic.h>
11 #include <linux/export.h>
12
13   asm (".text                                   \n\
14         .global _atomic_dec_and_lock            \n\
15         .ent _atomic_dec_and_lock               \n\
16         .align  4                               \n\
17 _atomic_dec_and_lock:                           \n\
18         .prologue 0                             \n\
19 1:      ldl_l   $1, 0($16)                      \n\
20         subl    $1, 1, $1                       \n\
21         beq     $1, 2f                          \n\
22         stl_c   $1, 0($16)                      \n\
23         beq     $1, 4f                          \n\
24         mb                                      \n\
25         clr     $0                              \n\
26         ret                                     \n\
27 2:      br      $29, 3f                         \n\
28 3:      ldgp    $29, 0($29)                     \n\
29         br      $atomic_dec_and_lock_1..ng      \n\
30         .subsection 2                           \n\
31 4:      br      1b                              \n\
32         .previous                               \n\
33         .end _atomic_dec_and_lock");
34
35 static int __used atomic_dec_and_lock_1(atomic_t *atomic, spinlock_t *lock)
36 {
37         /* Slow path */
38         spin_lock(lock);
39         if (atomic_dec_and_test(atomic))
40                 return 1;
41         spin_unlock(lock);
42         return 0;
43 }
44 EXPORT_SYMBOL(_atomic_dec_and_lock);