18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_POWERPC_QSPINLOCK_H 38c2ecf20Sopenharmony_ci#define _ASM_POWERPC_QSPINLOCK_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm-generic/qspinlock_types.h> 68c2ecf20Sopenharmony_ci#include <asm/paravirt.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define _Q_PENDING_LOOPS (1 << 9) /* not tuned */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifdef CONFIG_PARAVIRT_SPINLOCKS 118c2ecf20Sopenharmony_ciextern void native_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); 128c2ecf20Sopenharmony_ciextern void __pv_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); 138c2ecf20Sopenharmony_ciextern void __pv_queued_spin_unlock(struct qspinlock *lock); 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic __always_inline void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci if (!is_shared_processor()) 188c2ecf20Sopenharmony_ci native_queued_spin_lock_slowpath(lock, val); 198c2ecf20Sopenharmony_ci else 208c2ecf20Sopenharmony_ci __pv_queued_spin_lock_slowpath(lock, val); 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define queued_spin_unlock queued_spin_unlock 248c2ecf20Sopenharmony_cistatic inline void queued_spin_unlock(struct qspinlock *lock) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci if (!is_shared_processor()) 278c2ecf20Sopenharmony_ci smp_store_release(&lock->locked, 0); 288c2ecf20Sopenharmony_ci else 298c2ecf20Sopenharmony_ci __pv_queued_spin_unlock(lock); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#else 338c2ecf20Sopenharmony_ciextern void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); 348c2ecf20Sopenharmony_ci#endif 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic __always_inline void queued_spin_lock(struct qspinlock *lock) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci u32 val = 0; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci if (likely(atomic_try_cmpxchg_lock(&lock->val, &val, _Q_LOCKED_VAL))) 418c2ecf20Sopenharmony_ci return; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci queued_spin_lock_slowpath(lock, val); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci#define queued_spin_lock queued_spin_lock 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#define smp_mb__after_spinlock() smp_mb() 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic __always_inline int queued_spin_is_locked(struct qspinlock *lock) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci /* 528c2ecf20Sopenharmony_ci * This barrier was added to simple spinlocks by commit 51d7d5205d338, 538c2ecf20Sopenharmony_ci * but it should now be possible to remove it, asm arm64 has done with 548c2ecf20Sopenharmony_ci * commit c6f5d02b6a0f. 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_ci smp_mb(); 578c2ecf20Sopenharmony_ci return atomic_read(&lock->val); 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci#define queued_spin_is_locked queued_spin_is_locked 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#ifdef CONFIG_PARAVIRT_SPINLOCKS 628c2ecf20Sopenharmony_ci#define SPIN_THRESHOLD (1<<15) /* not tuned */ 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic __always_inline void pv_wait(u8 *ptr, u8 val) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci if (*ptr != val) 678c2ecf20Sopenharmony_ci return; 688c2ecf20Sopenharmony_ci yield_to_any(); 698c2ecf20Sopenharmony_ci /* 708c2ecf20Sopenharmony_ci * We could pass in a CPU here if waiting in the queue and yield to 718c2ecf20Sopenharmony_ci * the previous CPU in the queue. 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic __always_inline void pv_kick(int cpu) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci prod_cpu(cpu); 788c2ecf20Sopenharmony_ci} 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ciextern void __pv_init_lock_hash(void); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic inline void pv_spinlocks_init(void) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci __pv_init_lock_hash(); 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#endif 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci#include <asm-generic/qspinlock.h> 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#endif /* _ASM_POWERPC_QSPINLOCK_H */ 92