blob: a35dc72ae3bca20abdf30ab83a08a116481a6ca5 [file] [log] [blame]
xia.jin958d2932024-06-07 03:12:53 +00001/* SPDX-License-Identifier: GPL-2.0
2 * (C) Copyright 2013
3 */
4#ifndef _SPINLOCK_H_
5#define _SPINLOCK_H_
6#include <asm/system.h>
7
8typedef struct {
9 volatile u32 lock;
10} spin_lock_t;
11
12#define UNLOCK 0
13#define LOCK 1
14
15/* Current Program Status Register(CPSR) */
16#define CPSR_N_FLAG (0x01 << 31)
17#define CPSR_Z_FLAG (0x01 << 30)
18#define CPSR_C_FLAG (0x01 << 29)
19#define CPSR_V_FLAG (0x01 << 28)
20#define CPSR_Q_FLAG (0x01 << 27)
21#define CPSR_IT_1_0 (0x03 << 25)
22#define CPSR_JAZELLE (0x01 << 24)
23/* [23:20] RAZ/SBZP */
24#define CPSR_GE (0x01 << 16)
25#define CPSR_IT_7_2 (0x3F << 10)
26#define CPSR_E_STATE (0x01 << 9) /* Endianness execution state. 0:Little, 1:Big */
27#define CPSR_A_DISABLE (0x01 << 8) /* Asynchronous abort disable bit */
28#define CPSR_I_DISABLE (0x01 << 7) /* Interrupt disable bit */
29#define CPSR_F_DISABLE (0x01 << 6) /* Fast interrupt disable bit */
30#define CPSR_T_STATE (0x01 << 5) /* Thumb execution state bit */
31#define CPSR_MODE (0x1F << 0) /* The current mode of the processor */
32
33#define CPSR_MODE_USER 0x10
34#define CPSR_MODE_FIQ 0x11
35#define CPSR_MODE_IRQ 0x12
36#define CPSR_MODE_SVC 0x13
37#define CPSR_MODE_ABT 0x17
38#define CPSR_MODE_UND 0x1B
39#define CPSR_MODE_SYS 0x1F
40
41#define INIT_SPIN_LOCK {.lock = UNLOCK}
42
43/*
44 * RTK FIXME: there is a the same name definition in io.h.
45 * So in orderto prevent compiler error, we comment this function temporarily.
46 */
47static inline unsigned long local_irq_flags(void)
48{
49 unsigned long flags;
50
51 asm volatile ("mrs %0, daif // arch_local_irq_save\n"
52 : "=r" (flags)
53 :
54 : "memory", "cc"
55 );
56 return flags;
57}
58
59static inline int is_irq_on(void)
60{
61 if (local_irq_flags() & CPSR_I_DISABLE)
62 return 0;
63 return 1;
64}
65
66static inline unsigned long arch_local_irq_save(void)
67{
68 unsigned long flags;
69
70 asm volatile("mrs %0, daif /// save arch local irq\n"
71 "msr daifset, #2"
72 : "=r" (flags)
73 :
74 : "memory");
75 return flags;
76}
77
78static inline void arch_local_irq_enable(void)
79{
80 asm volatile("msr daifclr, #2 // enable arch local irq\n"
81 :
82 :
83 : "memory");
84}
85
86static inline void arch_local_irq_disable(void)
87{
88 asm volatile("msr daifset, #2 // disable arch local irq\n"
89 :
90 :
91 : "memory");
92}
93
94/*
95 * restore saved IRQ state
96 */
97static inline void arch_local_irq_restore(unsigned long flags)
98{
99 asm volatile("msr daif, %0 // restore arch local irq\n"
100 :
101 : "r" (flags)
102 : "memory");
103}
104
105static inline unsigned long save_cpsr(void)
106{
107 return arch_local_irq_save();
108}
109
110static inline void restore_cpsr(unsigned long flags)
111{
112 arch_local_irq_restore(flags);
113}
114
115static inline void irq_enable(void)
116{
117 arch_local_irq_enable();
118}
119
120static inline void irq_disable(void)
121{
122 arch_local_irq_disable();
123}
124
125#ifdef CONFIG_ARMV8_MULTIENTRY
126/* Below functions should be defined in arch */
127void arch_spin_lock(void *lock);
128int arch_try_lock(void *lock);
129void arch_spin_unlock(void *lock);
130
131static inline void spin_lock_init(spin_lock_t *lock)
132{
133 lock->lock = UNLOCK;
134}
135
136static inline void spin_lock(spin_lock_t *lock)
137{
138 arch_spin_lock((void *)&lock->lock);
139}
140
141static inline int spin_trylock(spin_lock_t *lock)
142{
143 return arch_try_lock((void *)&lock->lock);
144}
145
146static inline void spin_unlock(spin_lock_t *lock)
147{
148 arch_spin_unlock((void *)&lock->lock);
149}
150
151#define spin_lock_irq(lock) { irq_disable(); spin_lock(lock); }
152#define spin_unlock_irq(lock) { spin_unlock(lock); irq_enable(); }
153
154#define spin_lock_save(lock, flags) { flags = save_cpsr(); spin_lock(lock); }
155#define spin_unlock_restore(lock, flags) { spin_unlock(lock); restore_cpsr(flags); }
156
157#else
158#define spin_lock_init(lock) {(void)lock; }
159#define spin_lock(lock) {(void)lock; }
160#define spin_trylock(lock) (1)
161#define spin_unlock(lock) {(void)lock; }
162
163#define spin_lock_irq(lock) do {irq_disable(); (void)lock; } while (0)
164#define spin_unlock_irq(lock) do {(void)lock; irq_enable(); } while (0)
165#define spin_lock_save(lock, flags) do {flags = save_cpsr(); (void)lock; } while (0)
166#define spin_unlock_restore(lock, flags) do {(void)lock; restore_cpsr(flags); } while (0)
167#endif
168#endif //_SPINLOCK_H_
169