Make Kprobes depend on modules
[linux-2.6.git] / arch / s390 / lib / spinlock.c
1 /*
2  *  arch/s390/lib/spinlock.c
3  *    Out of line spinlock code.
4  *
5  *  S390 version
6  *    Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8  */
9
10 #include <linux/types.h>
11 #include <linux/module.h>
12 #include <linux/spinlock.h>
13 #include <linux/init.h>
14 #include <asm/io.h>
15
16 int spin_retry = 1000;
17
18 /**
19  * spin_retry= parameter
20  */
21 static int __init spin_retry_setup(char *str)
22 {
23         spin_retry = simple_strtoul(str, &str, 0);
24         return 1;
25 }
26 __setup("spin_retry=", spin_retry_setup);
27
28 static inline void
29 _diag44(void)
30 {
31 #ifdef CONFIG_64BIT
32         if (MACHINE_HAS_DIAG44)
33 #endif
34                 asm volatile("diag 0,0,0x44");
35 }
36
37 void
38 _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
39 {
40         int count = spin_retry;
41
42         while (1) {
43                 if (count-- <= 0) {
44                         _diag44();
45                         count = spin_retry;
46                 }
47                 if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
48                         return;
49         }
50 }
51 EXPORT_SYMBOL(_raw_spin_lock_wait);
52
53 int
54 _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
55 {
56         int count = spin_retry;
57
58         while (count-- > 0) {
59                 if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
60                         return 1;
61         }
62         return 0;
63 }
64 EXPORT_SYMBOL(_raw_spin_trylock_retry);
65
66 void
67 _raw_read_lock_wait(raw_rwlock_t *rw)
68 {
69         unsigned int old;
70         int count = spin_retry;
71
72         while (1) {
73                 if (count-- <= 0) {
74                         _diag44();
75                         count = spin_retry;
76                 }
77                 old = rw->lock & 0x7fffffffU;
78                 if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
79                         return;
80         }
81 }
82 EXPORT_SYMBOL(_raw_read_lock_wait);
83
84 int
85 _raw_read_trylock_retry(raw_rwlock_t *rw)
86 {
87         unsigned int old;
88         int count = spin_retry;
89
90         while (count-- > 0) {
91                 old = rw->lock & 0x7fffffffU;
92                 if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
93                         return 1;
94         }
95         return 0;
96 }
97 EXPORT_SYMBOL(_raw_read_trylock_retry);
98
99 void
100 _raw_write_lock_wait(raw_rwlock_t *rw)
101 {
102         int count = spin_retry;
103
104         while (1) {
105                 if (count-- <= 0) {
106                         _diag44();
107                         count = spin_retry;
108                 }
109                 if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
110                         return;
111         }
112 }
113 EXPORT_SYMBOL(_raw_write_lock_wait);
114
115 int
116 _raw_write_trylock_retry(raw_rwlock_t *rw)
117 {
118         int count = spin_retry;
119
120         while (count-- > 0) {
121                 if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
122                         return 1;
123         }
124         return 0;
125 }
126 EXPORT_SYMBOL(_raw_write_trylock_retry);