162306a36Sopenharmony_ci#ifndef __LINUX_SPINLOCK_API_SMP_H
262306a36Sopenharmony_ci#define __LINUX_SPINLOCK_API_SMP_H
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#ifndef __LINUX_INSIDE_SPINLOCK_H
562306a36Sopenharmony_ci# error "please don't include this file directly"
662306a36Sopenharmony_ci#endif
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/*
962306a36Sopenharmony_ci * include/linux/spinlock_api_smp.h
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * spinlock API declarations on SMP (and debug)
1262306a36Sopenharmony_ci * (implemented in kernel/spinlock.c)
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * portions Copyright 2005, Red Hat, Inc., Ingo Molnar
1562306a36Sopenharmony_ci * Released under the General Public License (GPL).
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciint in_lock_functions(unsigned long addr);
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#define assert_raw_spin_locked(x)	BUG_ON(!raw_spin_is_locked(x))
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_civoid __lockfunc _raw_spin_lock(raw_spinlock_t *lock)		__acquires(lock);
2362306a36Sopenharmony_civoid __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass)
2462306a36Sopenharmony_ci								__acquires(lock);
2562306a36Sopenharmony_civoid __lockfunc
2662306a36Sopenharmony_ci_raw_spin_lock_nest_lock(raw_spinlock_t *lock, struct lockdep_map *map)
2762306a36Sopenharmony_ci								__acquires(lock);
2862306a36Sopenharmony_civoid __lockfunc _raw_spin_lock_bh(raw_spinlock_t *lock)		__acquires(lock);
2962306a36Sopenharmony_civoid __lockfunc _raw_spin_lock_irq(raw_spinlock_t *lock)
3062306a36Sopenharmony_ci								__acquires(lock);
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciunsigned long __lockfunc _raw_spin_lock_irqsave(raw_spinlock_t *lock)
3362306a36Sopenharmony_ci								__acquires(lock);
3462306a36Sopenharmony_ciunsigned long __lockfunc
3562306a36Sopenharmony_ci_raw_spin_lock_irqsave_nested(raw_spinlock_t *lock, int subclass)
3662306a36Sopenharmony_ci								__acquires(lock);
3762306a36Sopenharmony_ciint __lockfunc _raw_spin_trylock(raw_spinlock_t *lock);
3862306a36Sopenharmony_ciint __lockfunc _raw_spin_trylock_bh(raw_spinlock_t *lock);
3962306a36Sopenharmony_civoid __lockfunc _raw_spin_unlock(raw_spinlock_t *lock)		__releases(lock);
4062306a36Sopenharmony_civoid __lockfunc _raw_spin_unlock_bh(raw_spinlock_t *lock)	__releases(lock);
4162306a36Sopenharmony_civoid __lockfunc _raw_spin_unlock_irq(raw_spinlock_t *lock)	__releases(lock);
4262306a36Sopenharmony_civoid __lockfunc
4362306a36Sopenharmony_ci_raw_spin_unlock_irqrestore(raw_spinlock_t *lock, unsigned long flags)
4462306a36Sopenharmony_ci								__releases(lock);
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_LOCK
4762306a36Sopenharmony_ci#define _raw_spin_lock(lock) __raw_spin_lock(lock)
4862306a36Sopenharmony_ci#endif
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_LOCK_BH
5162306a36Sopenharmony_ci#define _raw_spin_lock_bh(lock) __raw_spin_lock_bh(lock)
5262306a36Sopenharmony_ci#endif
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_LOCK_IRQ
5562306a36Sopenharmony_ci#define _raw_spin_lock_irq(lock) __raw_spin_lock_irq(lock)
5662306a36Sopenharmony_ci#endif
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_LOCK_IRQSAVE
5962306a36Sopenharmony_ci#define _raw_spin_lock_irqsave(lock) __raw_spin_lock_irqsave(lock)
6062306a36Sopenharmony_ci#endif
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_TRYLOCK
6362306a36Sopenharmony_ci#define _raw_spin_trylock(lock) __raw_spin_trylock(lock)
6462306a36Sopenharmony_ci#endif
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_TRYLOCK_BH
6762306a36Sopenharmony_ci#define _raw_spin_trylock_bh(lock) __raw_spin_trylock_bh(lock)
6862306a36Sopenharmony_ci#endif
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#ifndef CONFIG_UNINLINE_SPIN_UNLOCK
7162306a36Sopenharmony_ci#define _raw_spin_unlock(lock) __raw_spin_unlock(lock)
7262306a36Sopenharmony_ci#endif
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_UNLOCK_BH
7562306a36Sopenharmony_ci#define _raw_spin_unlock_bh(lock) __raw_spin_unlock_bh(lock)
7662306a36Sopenharmony_ci#endif
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQ
7962306a36Sopenharmony_ci#define _raw_spin_unlock_irq(lock) __raw_spin_unlock_irq(lock)
8062306a36Sopenharmony_ci#endif
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE
8362306a36Sopenharmony_ci#define _raw_spin_unlock_irqrestore(lock, flags) __raw_spin_unlock_irqrestore(lock, flags)
8462306a36Sopenharmony_ci#endif
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistatic inline int __raw_spin_trylock(raw_spinlock_t *lock)
8762306a36Sopenharmony_ci{
8862306a36Sopenharmony_ci	preempt_disable();
8962306a36Sopenharmony_ci	if (do_raw_spin_trylock(lock)) {
9062306a36Sopenharmony_ci		spin_acquire(&lock->dep_map, 0, 1, _RET_IP_);
9162306a36Sopenharmony_ci		return 1;
9262306a36Sopenharmony_ci	}
9362306a36Sopenharmony_ci	preempt_enable();
9462306a36Sopenharmony_ci	return 0;
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/*
9862306a36Sopenharmony_ci * If lockdep is enabled then we use the non-preemption spin-ops
9962306a36Sopenharmony_ci * even on CONFIG_PREEMPTION, because lockdep assumes that interrupts are
10062306a36Sopenharmony_ci * not re-enabled during lock-acquire (which the preempt-spin-ops do):
10162306a36Sopenharmony_ci */
10262306a36Sopenharmony_ci#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_cistatic inline unsigned long __raw_spin_lock_irqsave(raw_spinlock_t *lock)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	unsigned long flags;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	local_irq_save(flags);
10962306a36Sopenharmony_ci	preempt_disable();
11062306a36Sopenharmony_ci	spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
11162306a36Sopenharmony_ci	LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
11262306a36Sopenharmony_ci	return flags;
11362306a36Sopenharmony_ci}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistatic inline void __raw_spin_lock_irq(raw_spinlock_t *lock)
11662306a36Sopenharmony_ci{
11762306a36Sopenharmony_ci	local_irq_disable();
11862306a36Sopenharmony_ci	preempt_disable();
11962306a36Sopenharmony_ci	spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
12062306a36Sopenharmony_ci	LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
12162306a36Sopenharmony_ci}
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistatic inline void __raw_spin_lock_bh(raw_spinlock_t *lock)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
12662306a36Sopenharmony_ci	spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
12762306a36Sopenharmony_ci	LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
12862306a36Sopenharmony_ci}
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_cistatic inline void __raw_spin_lock(raw_spinlock_t *lock)
13162306a36Sopenharmony_ci{
13262306a36Sopenharmony_ci	preempt_disable();
13362306a36Sopenharmony_ci	spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
13462306a36Sopenharmony_ci	LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_cistatic inline void __raw_spin_unlock(raw_spinlock_t *lock)
14062306a36Sopenharmony_ci{
14162306a36Sopenharmony_ci	spin_release(&lock->dep_map, _RET_IP_);
14262306a36Sopenharmony_ci	do_raw_spin_unlock(lock);
14362306a36Sopenharmony_ci	preempt_enable();
14462306a36Sopenharmony_ci}
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cistatic inline void __raw_spin_unlock_irqrestore(raw_spinlock_t *lock,
14762306a36Sopenharmony_ci					    unsigned long flags)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci	spin_release(&lock->dep_map, _RET_IP_);
15062306a36Sopenharmony_ci	do_raw_spin_unlock(lock);
15162306a36Sopenharmony_ci	local_irq_restore(flags);
15262306a36Sopenharmony_ci	preempt_enable();
15362306a36Sopenharmony_ci}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistatic inline void __raw_spin_unlock_irq(raw_spinlock_t *lock)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	spin_release(&lock->dep_map, _RET_IP_);
15862306a36Sopenharmony_ci	do_raw_spin_unlock(lock);
15962306a36Sopenharmony_ci	local_irq_enable();
16062306a36Sopenharmony_ci	preempt_enable();
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic inline void __raw_spin_unlock_bh(raw_spinlock_t *lock)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	spin_release(&lock->dep_map, _RET_IP_);
16662306a36Sopenharmony_ci	do_raw_spin_unlock(lock);
16762306a36Sopenharmony_ci	__local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistatic inline int __raw_spin_trylock_bh(raw_spinlock_t *lock)
17162306a36Sopenharmony_ci{
17262306a36Sopenharmony_ci	__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
17362306a36Sopenharmony_ci	if (do_raw_spin_trylock(lock)) {
17462306a36Sopenharmony_ci		spin_acquire(&lock->dep_map, 0, 1, _RET_IP_);
17562306a36Sopenharmony_ci		return 1;
17662306a36Sopenharmony_ci	}
17762306a36Sopenharmony_ci	__local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
17862306a36Sopenharmony_ci	return 0;
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci/* PREEMPT_RT has its own rwlock implementation */
18262306a36Sopenharmony_ci#ifndef CONFIG_PREEMPT_RT
18362306a36Sopenharmony_ci#include <linux/rwlock_api_smp.h>
18462306a36Sopenharmony_ci#endif
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci#endif /* __LINUX_SPINLOCK_API_SMP_H */
187