hwspinlock/core: remove stubs for register/unregister
[linux-3.10.git] / include / linux / hwspinlock.h
1 /*
2  * Hardware spinlock public header
3  *
4  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
5  *
6  * Contact: Ohad Ben-Cohen <ohad@wizery.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License version 2 as published
10  * by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17
18 #ifndef __LINUX_HWSPINLOCK_H
19 #define __LINUX_HWSPINLOCK_H
20
21 #include <linux/err.h>
22 #include <linux/sched.h>
23
24 /* hwspinlock mode argument */
25 #define HWLOCK_IRQSTATE 0x01    /* Disable interrupts, save state */
26 #define HWLOCK_IRQ      0x02    /* Disable interrupts, don't save state */
27
28 struct hwspinlock;
29
30 /**
31  * struct hwspinlock_pdata - platform data for hwspinlock drivers
32  * @base_id: base id for this hwspinlock device
33  *
34  * hwspinlock devices provide system-wide hardware locks that are used
35  * by remote processors that have no other way to achieve synchronization.
36  *
37  * To achieve that, each physical lock must have a system-wide id number
38  * that is agreed upon, otherwise remote processors can't possibly assume
39  * they're using the same hardware lock.
40  *
41  * Usually boards have a single hwspinlock device, which provides several
42  * hwspinlocks, and in this case, they can be trivially numbered 0 to
43  * (num-of-locks - 1).
44  *
45  * In case boards have several hwspinlocks devices, a different base id
46  * should be used for each hwspinlock device (they can't all use 0 as
47  * a starting id!).
48  *
49  * This platform data structure should be used to provide the base id
50  * for each device (which is trivially 0 when only a single hwspinlock
51  * device exists). It can be shared between different platforms, hence
52  * its location.
53  */
54 struct hwspinlock_pdata {
55         int base_id;
56 };
57
58 #if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE)
59
60 int hwspin_lock_register(struct hwspinlock *lock);
61 struct hwspinlock *hwspin_lock_unregister(unsigned int id);
62 struct hwspinlock *hwspin_lock_request(void);
63 struct hwspinlock *hwspin_lock_request_specific(unsigned int id);
64 int hwspin_lock_free(struct hwspinlock *hwlock);
65 int hwspin_lock_get_id(struct hwspinlock *hwlock);
66 int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int,
67                                                         unsigned long *);
68 int __hwspin_trylock(struct hwspinlock *, int, unsigned long *);
69 void __hwspin_unlock(struct hwspinlock *, int, unsigned long *);
70
71 #else /* !CONFIG_HWSPINLOCK */
72
73 /*
74  * We don't want these functions to fail if CONFIG_HWSPINLOCK is not
75  * enabled. We prefer to silently succeed in this case, and let the
76  * code path get compiled away. This way, if CONFIG_HWSPINLOCK is not
77  * required on a given setup, users will still work.
78  *
79  * The only exception is hwspin_lock_register/hwspin_lock_unregister, with which
80  * we _do_ want users to fail (no point in registering hwspinlock instances if
81  * the framework is not available).
82  *
83  * Note: ERR_PTR(-ENODEV) will still be considered a success for NULL-checking
84  * users. Others, which care, can still check this with IS_ERR.
85  */
86 static inline struct hwspinlock *hwspin_lock_request(void)
87 {
88         return ERR_PTR(-ENODEV);
89 }
90
91 static inline struct hwspinlock *hwspin_lock_request_specific(unsigned int id)
92 {
93         return ERR_PTR(-ENODEV);
94 }
95
96 static inline int hwspin_lock_free(struct hwspinlock *hwlock)
97 {
98         return 0;
99 }
100
101 static inline
102 int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to,
103                                         int mode, unsigned long *flags)
104 {
105         return 0;
106 }
107
108 static inline
109 int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
110 {
111         return 0;
112 }
113
114 static inline
115 void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
116 {
117         return 0;
118 }
119
120 static inline int hwspin_lock_get_id(struct hwspinlock *hwlock)
121 {
122         return 0;
123 }
124
125 #endif /* !CONFIG_HWSPINLOCK */
126
127 /**
128  * hwspin_trylock_irqsave() - try to lock an hwspinlock, disable interrupts
129  * @hwlock: an hwspinlock which we want to trylock
130  * @flags: a pointer to where the caller's interrupt state will be saved at
131  *
132  * This function attempts to lock the underlying hwspinlock, and will
133  * immediately fail if the hwspinlock is already locked.
134  *
135  * Upon a successful return from this function, preemption and local
136  * interrupts are disabled (previous interrupts state is saved at @flags),
137  * so the caller must not sleep, and is advised to release the hwspinlock
138  * as soon as possible.
139  *
140  * Returns 0 if we successfully locked the hwspinlock, -EBUSY if
141  * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid.
142  */
143 static inline
144 int hwspin_trylock_irqsave(struct hwspinlock *hwlock, unsigned long *flags)
145 {
146         return __hwspin_trylock(hwlock, HWLOCK_IRQSTATE, flags);
147 }
148
149 /**
150  * hwspin_trylock_irq() - try to lock an hwspinlock, disable interrupts
151  * @hwlock: an hwspinlock which we want to trylock
152  *
153  * This function attempts to lock the underlying hwspinlock, and will
154  * immediately fail if the hwspinlock is already locked.
155  *
156  * Upon a successful return from this function, preemption and local
157  * interrupts are disabled, so the caller must not sleep, and is advised
158  * to release the hwspinlock as soon as possible.
159  *
160  * Returns 0 if we successfully locked the hwspinlock, -EBUSY if
161  * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid.
162  */
163 static inline int hwspin_trylock_irq(struct hwspinlock *hwlock)
164 {
165         return __hwspin_trylock(hwlock, HWLOCK_IRQ, NULL);
166 }
167
168 /**
169  * hwspin_trylock() - attempt to lock a specific hwspinlock
170  * @hwlock: an hwspinlock which we want to trylock
171  *
172  * This function attempts to lock an hwspinlock, and will immediately fail
173  * if the hwspinlock is already taken.
174  *
175  * Upon a successful return from this function, preemption is disabled,
176  * so the caller must not sleep, and is advised to release the hwspinlock
177  * as soon as possible. This is required in order to minimize remote cores
178  * polling on the hardware interconnect.
179  *
180  * Returns 0 if we successfully locked the hwspinlock, -EBUSY if
181  * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid.
182  */
183 static inline int hwspin_trylock(struct hwspinlock *hwlock)
184 {
185         return __hwspin_trylock(hwlock, 0, NULL);
186 }
187
188 /**
189  * hwspin_lock_timeout_irqsave() - lock hwspinlock, with timeout, disable irqs
190  * @hwlock: the hwspinlock to be locked
191  * @to: timeout value in msecs
192  * @flags: a pointer to where the caller's interrupt state will be saved at
193  *
194  * This function locks the underlying @hwlock. If the @hwlock
195  * is already taken, the function will busy loop waiting for it to
196  * be released, but give up when @timeout msecs have elapsed.
197  *
198  * Upon a successful return from this function, preemption and local interrupts
199  * are disabled (plus previous interrupt state is saved), so the caller must
200  * not sleep, and is advised to release the hwspinlock as soon as possible.
201  *
202  * Returns 0 when the @hwlock was successfully taken, and an appropriate
203  * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still
204  * busy after @timeout msecs). The function will never sleep.
205  */
206 static inline int hwspin_lock_timeout_irqsave(struct hwspinlock *hwlock,
207                                 unsigned int to, unsigned long *flags)
208 {
209         return __hwspin_lock_timeout(hwlock, to, HWLOCK_IRQSTATE, flags);
210 }
211
212 /**
213  * hwspin_lock_timeout_irq() - lock hwspinlock, with timeout, disable irqs
214  * @hwlock: the hwspinlock to be locked
215  * @to: timeout value in msecs
216  *
217  * This function locks the underlying @hwlock. If the @hwlock
218  * is already taken, the function will busy loop waiting for it to
219  * be released, but give up when @timeout msecs have elapsed.
220  *
221  * Upon a successful return from this function, preemption and local interrupts
222  * are disabled so the caller must not sleep, and is advised to release the
223  * hwspinlock as soon as possible.
224  *
225  * Returns 0 when the @hwlock was successfully taken, and an appropriate
226  * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still
227  * busy after @timeout msecs). The function will never sleep.
228  */
229 static inline
230 int hwspin_lock_timeout_irq(struct hwspinlock *hwlock, unsigned int to)
231 {
232         return __hwspin_lock_timeout(hwlock, to, HWLOCK_IRQ, NULL);
233 }
234
235 /**
236  * hwspin_lock_timeout() - lock an hwspinlock with timeout limit
237  * @hwlock: the hwspinlock to be locked
238  * @to: timeout value in msecs
239  *
240  * This function locks the underlying @hwlock. If the @hwlock
241  * is already taken, the function will busy loop waiting for it to
242  * be released, but give up when @timeout msecs have elapsed.
243  *
244  * Upon a successful return from this function, preemption is disabled
245  * so the caller must not sleep, and is advised to release the hwspinlock
246  * as soon as possible.
247  * This is required in order to minimize remote cores polling on the
248  * hardware interconnect.
249  *
250  * Returns 0 when the @hwlock was successfully taken, and an appropriate
251  * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still
252  * busy after @timeout msecs). The function will never sleep.
253  */
254 static inline
255 int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to)
256 {
257         return __hwspin_lock_timeout(hwlock, to, 0, NULL);
258 }
259
260 /**
261  * hwspin_unlock_irqrestore() - unlock hwspinlock, restore irq state
262  * @hwlock: a previously-acquired hwspinlock which we want to unlock
263  * @flags: previous caller's interrupt state to restore
264  *
265  * This function will unlock a specific hwspinlock, enable preemption and
266  * restore the previous state of the local interrupts. It should be used
267  * to undo, e.g., hwspin_trylock_irqsave().
268  *
269  * @hwlock must be already locked before calling this function: it is a bug
270  * to call unlock on a @hwlock that is already unlocked.
271  */
272 static inline void hwspin_unlock_irqrestore(struct hwspinlock *hwlock,
273                                                         unsigned long *flags)
274 {
275         __hwspin_unlock(hwlock, HWLOCK_IRQSTATE, flags);
276 }
277
278 /**
279  * hwspin_unlock_irq() - unlock hwspinlock, enable interrupts
280  * @hwlock: a previously-acquired hwspinlock which we want to unlock
281  *
282  * This function will unlock a specific hwspinlock, enable preemption and
283  * enable local interrupts. Should be used to undo hwspin_lock_irq().
284  *
285  * @hwlock must be already locked (e.g. by hwspin_trylock_irq()) before
286  * calling this function: it is a bug to call unlock on a @hwlock that is
287  * already unlocked.
288  */
289 static inline void hwspin_unlock_irq(struct hwspinlock *hwlock)
290 {
291         __hwspin_unlock(hwlock, HWLOCK_IRQ, NULL);
292 }
293
294 /**
295  * hwspin_unlock() - unlock hwspinlock
296  * @hwlock: a previously-acquired hwspinlock which we want to unlock
297  *
298  * This function will unlock a specific hwspinlock and enable preemption
299  * back.
300  *
301  * @hwlock must be already locked (e.g. by hwspin_trylock()) before calling
302  * this function: it is a bug to call unlock on a @hwlock that is already
303  * unlocked.
304  */
305 static inline void hwspin_unlock(struct hwspinlock *hwlock)
306 {
307         __hwspin_unlock(hwlock, 0, NULL);
308 }
309
310 #endif /* __LINUX_HWSPINLOCK_H */