1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 #ifndef _ASM_POWERPC_QSPINLOCK_TYPES_H 3 #define _ASM_POWERPC_QSPINLOCK_TYPES_H 4 5 #include <linux/types.h> 6 #include <asm/byteorder.h> 7 8 typedef struct qspinlock { 9 union { 10 u32 val; 11 12 #ifdef __LITTLE_ENDIAN 13 struct { 14 u16 locked; 15 u8 reserved[2]; 16 }; 17 #else 18 struct { 19 u8 reserved[2]; 20 u16 locked; 21 }; 22 #endif 23 }; 24 } arch_spinlock_t; 25 26 #define __ARCH_SPIN_LOCK_UNLOCKED { { .val = 0 } } 27 28 /* 29 * Bitfields in the lock word: 30 * 31 * 0: locked bit 32 * 1-14: lock holder cpu 33 * 15: lock owner or queuer vcpus observed to be preempted bit 34 * 16: must queue bit 35 * 17-31: tail cpu (+1) 36 */ 37 #define _Q_SET_MASK(type) (((1U << _Q_ ## type ## _BITS) - 1)\ 38 << _Q_ ## type ## _OFFSET) 39 /* 0x00000001 */ 40 #define _Q_LOCKED_OFFSET 0 41 #define _Q_LOCKED_BITS 1 42 #define _Q_LOCKED_VAL (1U << _Q_LOCKED_OFFSET) 43 44 /* 0x00007ffe */ 45 #define _Q_OWNER_CPU_OFFSET 1 46 #define _Q_OWNER_CPU_BITS 14 47 #define _Q_OWNER_CPU_MASK _Q_SET_MASK(OWNER_CPU) 48 49 #if CONFIG_NR_CPUS > (1U << _Q_OWNER_CPU_BITS) 50 #error "qspinlock does not support such large CONFIG_NR_CPUS" 51 #endif 52 53 /* 0x00008000 */ 54 #define _Q_SLEEPY_OFFSET 15 55 #define _Q_SLEEPY_BITS 1 56 #define _Q_SLEEPY_VAL (1U << _Q_SLEEPY_OFFSET) 57 58 /* 0x00010000 */ 59 #define _Q_MUST_Q_OFFSET 16 60 #define _Q_MUST_Q_BITS 1 61 #define _Q_MUST_Q_VAL (1U << _Q_MUST_Q_OFFSET) 62 63 /* 0xfffe0000 */ 64 #define _Q_TAIL_CPU_OFFSET 17 65 #define _Q_TAIL_CPU_BITS 15 66 #define _Q_TAIL_CPU_MASK _Q_SET_MASK(TAIL_CPU) 67 68 #if CONFIG_NR_CPUS >= (1U << _Q_TAIL_CPU_BITS) 69 #error "qspinlock does not support such large CONFIG_NR_CPUS" 70 #endif 71 72 #endif /* _ASM_POWERPC_QSPINLOCK_TYPES_H */ 73