blob: 60f80a4eed4e52cfc99756738024738a42537237 [file] [log] [blame]
Martin Schwidefsky951f22d2005-07-27 11:44:57 -07001/*
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
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070016int spin_retry = 1000;
17
18/**
19 * spin_retry= parameter
20 */
21static 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
28static inline void
29_diag44(void)
30{
Martin Schwidefsky347a8dc2006-01-06 00:19:28 -080031#ifdef CONFIG_64BIT
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070032 if (MACHINE_HAS_DIAG44)
33#endif
34 asm volatile("diag 0,0,0x44");
35}
36
37void
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070038_raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070039{
40 int count = spin_retry;
41
42 while (1) {
43 if (count-- <= 0) {
44 _diag44();
45 count = spin_retry;
46 }
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070047 if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
48 return;
49 }
50}
51EXPORT_SYMBOL(_raw_spin_lock_wait);
52
53int
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070054_raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070055{
56 int count = spin_retry;
57
58 while (count-- > 0) {
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070059 if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
60 return 1;
61 }
62 return 0;
63}
64EXPORT_SYMBOL(_raw_spin_trylock_retry);
65
66void
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070067_raw_read_lock_wait(raw_rwlock_t *rw)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070068{
69 unsigned int old;
70 int count = spin_retry;
71
72 while (1) {
73 if (count-- <= 0) {
74 _diag44();
75 count = spin_retry;
76 }
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070077 old = rw->lock & 0x7fffffffU;
78 if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
79 return;
80 }
81}
82EXPORT_SYMBOL(_raw_read_lock_wait);
83
84int
Ingo Molnarfb1c8f92005-09-10 00:25:56 -070085_raw_read_trylock_retry(raw_rwlock_t *rw)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070086{
87 unsigned int old;
88 int count = spin_retry;
89
90 while (count-- > 0) {
Martin Schwidefsky951f22d2005-07-27 11:44:57 -070091 old = rw->lock & 0x7fffffffU;
92 if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
93 return 1;
94 }
95 return 0;
96}
97EXPORT_SYMBOL(_raw_read_trylock_retry);
98
99void
Ingo Molnarfb1c8f92005-09-10 00:25:56 -0700100_raw_write_lock_wait(raw_rwlock_t *rw)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700101{
102 int count = spin_retry;
103
104 while (1) {
105 if (count-- <= 0) {
106 _diag44();
107 count = spin_retry;
108 }
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700109 if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
110 return;
111 }
112}
113EXPORT_SYMBOL(_raw_write_lock_wait);
114
115int
Ingo Molnarfb1c8f92005-09-10 00:25:56 -0700116_raw_write_trylock_retry(raw_rwlock_t *rw)
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700117{
118 int count = spin_retry;
119
120 while (count-- > 0) {
Martin Schwidefsky951f22d2005-07-27 11:44:57 -0700121 if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
122 return 1;
123 }
124 return 0;
125}
126EXPORT_SYMBOL(_raw_write_trylock_retry);