1342a9324SThomas Gleixner// SPDX-License-Identifier: GPL-2.0-only
2342a9324SThomas Gleixner#ifndef __LINUX_SPINLOCK_RT_H
3342a9324SThomas Gleixner#define __LINUX_SPINLOCK_RT_H
4342a9324SThomas Gleixner
5342a9324SThomas Gleixner#ifndef __LINUX_SPINLOCK_H
6342a9324SThomas Gleixner#error Do not include directly. Use spinlock.h
7342a9324SThomas Gleixner#endif
8342a9324SThomas Gleixner
9342a9324SThomas Gleixner#ifdef CONFIG_DEBUG_LOCK_ALLOC
10342a9324SThomas Gleixnerextern void __rt_spin_lock_init(spinlock_t *lock, const char *name,
1131552385SThomas Gleixner				struct lock_class_key *key, bool percpu);
12342a9324SThomas Gleixner#else
13342a9324SThomas Gleixnerstatic inline void __rt_spin_lock_init(spinlock_t *lock, const char *name,
1431552385SThomas Gleixner				struct lock_class_key *key, bool percpu)
15342a9324SThomas Gleixner{
16342a9324SThomas Gleixner}
17342a9324SThomas Gleixner#endif
18342a9324SThomas Gleixner
1931552385SThomas Gleixner#define spin_lock_init(slock)					\
2031552385SThomas Gleixnerdo {								\
2131552385SThomas Gleixner	static struct lock_class_key __key;			\
2231552385SThomas Gleixner								\
2331552385SThomas Gleixner	rt_mutex_base_init(&(slock)->lock);			\
2431552385SThomas Gleixner	__rt_spin_lock_init(slock, #slock, &__key, false);	\
2531552385SThomas Gleixner} while (0)
2631552385SThomas Gleixner
2731552385SThomas Gleixner#define local_spin_lock_init(slock)				\
2831552385SThomas Gleixnerdo {								\
2931552385SThomas Gleixner	static struct lock_class_key __key;			\
3031552385SThomas Gleixner								\
3131552385SThomas Gleixner	rt_mutex_base_init(&(slock)->lock);			\
3231552385SThomas Gleixner	__rt_spin_lock_init(slock, #slock, &__key, true);	\
33342a9324SThomas Gleixner} while (0)
34342a9324SThomas Gleixner
35342a9324SThomas Gleixnerextern void rt_spin_lock(spinlock_t *lock);
36342a9324SThomas Gleixnerextern void rt_spin_lock_nested(spinlock_t *lock, int subclass);
37342a9324SThomas Gleixnerextern void rt_spin_lock_nest_lock(spinlock_t *lock, struct lockdep_map *nest_lock);
38342a9324SThomas Gleixnerextern void rt_spin_unlock(spinlock_t *lock);
39342a9324SThomas Gleixnerextern void rt_spin_lock_unlock(spinlock_t *lock);
40342a9324SThomas Gleixnerextern int rt_spin_trylock_bh(spinlock_t *lock);
41342a9324SThomas Gleixnerextern int rt_spin_trylock(spinlock_t *lock);
42342a9324SThomas Gleixner
43342a9324SThomas Gleixnerstatic __always_inline void spin_lock(spinlock_t *lock)
44342a9324SThomas Gleixner{
45342a9324SThomas Gleixner	rt_spin_lock(lock);
46342a9324SThomas Gleixner}
47342a9324SThomas Gleixner
48342a9324SThomas Gleixner#ifdef CONFIG_LOCKDEP
49342a9324SThomas Gleixner# define __spin_lock_nested(lock, subclass)				\
50342a9324SThomas Gleixner	rt_spin_lock_nested(lock, subclass)
51342a9324SThomas Gleixner
52342a9324SThomas Gleixner# define __spin_lock_nest_lock(lock, nest_lock)				\
53342a9324SThomas Gleixner	do {								\
54342a9324SThomas Gleixner		typecheck(struct lockdep_map *, &(nest_lock)->dep_map);	\
55342a9324SThomas Gleixner		rt_spin_lock_nest_lock(lock, &(nest_lock)->dep_map);	\
56342a9324SThomas Gleixner	} while (0)
57342a9324SThomas Gleixner# define __spin_lock_irqsave_nested(lock, flags, subclass)	\
58342a9324SThomas Gleixner	do {							\
59342a9324SThomas Gleixner		typecheck(unsigned long, flags);		\
60342a9324SThomas Gleixner		flags = 0;					\
61342a9324SThomas Gleixner		__spin_lock_nested(lock, subclass);		\
62342a9324SThomas Gleixner	} while (0)
63342a9324SThomas Gleixner
64342a9324SThomas Gleixner#else
65342a9324SThomas Gleixner /*
66342a9324SThomas Gleixner  * Always evaluate the 'subclass' argument to avoid that the compiler
67342a9324SThomas Gleixner  * warns about set-but-not-used variables when building with
68342a9324SThomas Gleixner  * CONFIG_DEBUG_LOCK_ALLOC=n and with W=1.
69342a9324SThomas Gleixner  */
70342a9324SThomas Gleixner# define __spin_lock_nested(lock, subclass)	spin_lock(((void)(subclass), (lock)))
71342a9324SThomas Gleixner# define __spin_lock_nest_lock(lock, subclass)	spin_lock(((void)(subclass), (lock)))
72342a9324SThomas Gleixner# define __spin_lock_irqsave_nested(lock, flags, subclass)	\
73342a9324SThomas Gleixner	spin_lock_irqsave(((void)(subclass), (lock)), flags)
74342a9324SThomas Gleixner#endif
75342a9324SThomas Gleixner
76342a9324SThomas Gleixner#define spin_lock_nested(lock, subclass)		\
77342a9324SThomas Gleixner	__spin_lock_nested(lock, subclass)
78342a9324SThomas Gleixner
79342a9324SThomas Gleixner#define spin_lock_nest_lock(lock, nest_lock)		\
80342a9324SThomas Gleixner	__spin_lock_nest_lock(lock, nest_lock)
81342a9324SThomas Gleixner
82342a9324SThomas Gleixner#define spin_lock_irqsave_nested(lock, flags, subclass)	\
83342a9324SThomas Gleixner	__spin_lock_irqsave_nested(lock, flags, subclass)
84342a9324SThomas Gleixner
85342a9324SThomas Gleixnerstatic __always_inline void spin_lock_bh(spinlock_t *lock)
86342a9324SThomas Gleixner{
87342a9324SThomas Gleixner	/* Investigate: Drop bh when blocking ? */
88342a9324SThomas Gleixner	local_bh_disable();
89342a9324SThomas Gleixner	rt_spin_lock(lock);
90342a9324SThomas Gleixner}
91342a9324SThomas Gleixner
92342a9324SThomas Gleixnerstatic __always_inline void spin_lock_irq(spinlock_t *lock)
93342a9324SThomas Gleixner{
94342a9324SThomas Gleixner	rt_spin_lock(lock);
95342a9324SThomas Gleixner}
96342a9324SThomas Gleixner
97342a9324SThomas Gleixner#define spin_lock_irqsave(lock, flags)			 \
98342a9324SThomas Gleixner	do {						 \
99342a9324SThomas Gleixner		typecheck(unsigned long, flags);	 \
100342a9324SThomas Gleixner		flags = 0;				 \
101342a9324SThomas Gleixner		spin_lock(lock);			 \
102342a9324SThomas Gleixner	} while (0)
103342a9324SThomas Gleixner
104342a9324SThomas Gleixnerstatic __always_inline void spin_unlock(spinlock_t *lock)
105342a9324SThomas Gleixner{
106342a9324SThomas Gleixner	rt_spin_unlock(lock);
107342a9324SThomas Gleixner}
108342a9324SThomas Gleixner
109342a9324SThomas Gleixnerstatic __always_inline void spin_unlock_bh(spinlock_t *lock)
110342a9324SThomas Gleixner{
111342a9324SThomas Gleixner	rt_spin_unlock(lock);
112342a9324SThomas Gleixner	local_bh_enable();
113342a9324SThomas Gleixner}
114342a9324SThomas Gleixner
115342a9324SThomas Gleixnerstatic __always_inline void spin_unlock_irq(spinlock_t *lock)
116342a9324SThomas Gleixner{
117342a9324SThomas Gleixner	rt_spin_unlock(lock);
118342a9324SThomas Gleixner}
119342a9324SThomas Gleixner
120342a9324SThomas Gleixnerstatic __always_inline void spin_unlock_irqrestore(spinlock_t *lock,
121342a9324SThomas Gleixner						   unsigned long flags)
122342a9324SThomas Gleixner{
123342a9324SThomas Gleixner	rt_spin_unlock(lock);
124342a9324SThomas Gleixner}
125342a9324SThomas Gleixner
126342a9324SThomas Gleixner#define spin_trylock(lock)				\
127342a9324SThomas Gleixner	__cond_lock(lock, rt_spin_trylock(lock))
128342a9324SThomas Gleixner
129342a9324SThomas Gleixner#define spin_trylock_bh(lock)				\
130342a9324SThomas Gleixner	__cond_lock(lock, rt_spin_trylock_bh(lock))
131342a9324SThomas Gleixner
132342a9324SThomas Gleixner#define spin_trylock_irq(lock)				\
133342a9324SThomas Gleixner	__cond_lock(lock, rt_spin_trylock(lock))
134342a9324SThomas Gleixner
135342a9324SThomas Gleixner#define __spin_trylock_irqsave(lock, flags)		\
136342a9324SThomas Gleixner({							\
137342a9324SThomas Gleixner	int __locked;					\
138342a9324SThomas Gleixner							\
139342a9324SThomas Gleixner	typecheck(unsigned long, flags);		\
140342a9324SThomas Gleixner	flags = 0;					\
141342a9324SThomas Gleixner	__locked = spin_trylock(lock);			\
142342a9324SThomas Gleixner	__locked;					\
143342a9324SThomas Gleixner})
144342a9324SThomas Gleixner
145342a9324SThomas Gleixner#define spin_trylock_irqsave(lock, flags)		\
146342a9324SThomas Gleixner	__cond_lock(lock, __spin_trylock_irqsave(lock, flags))
147342a9324SThomas Gleixner
148342a9324SThomas Gleixner#define spin_is_contended(lock)		(((void)(lock), 0))
149342a9324SThomas Gleixner
150342a9324SThomas Gleixnerstatic inline int spin_is_locked(spinlock_t *lock)
151342a9324SThomas Gleixner{
152342a9324SThomas Gleixner	return rt_mutex_base_is_locked(&lock->lock);
153342a9324SThomas Gleixner}
154342a9324SThomas Gleixner
155342a9324SThomas Gleixner#define assert_spin_locked(lock) BUG_ON(!spin_is_locked(lock))
156342a9324SThomas Gleixner
1578282947fSThomas Gleixner#include <linux/rwlock_rt.h>
1588282947fSThomas Gleixner
159342a9324SThomas Gleixner#endif
160