1 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
2 /*
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4 */
5
6 #ifndef _HWSPINLOCK_H_
7 #define _HWSPINLOCK_H_
8
9 /**
10 * Implement a hwspinlock uclass.
11 * Hardware spinlocks are used to perform hardware protection of
12 * critical sections and synchronisation between multiprocessors.
13 */
14
15 struct udevice;
16
17 /**
18 * struct hwspinlock - A handle to (allowing control of) a single hardware
19 * spinlock.
20 *
21 * @dev: The device which implements the hardware spinlock.
22 * @id: The hardware spinlock ID within the provider.
23 */
24 struct hwspinlock {
25 struct udevice *dev;
26 unsigned long id;
27 };
28
29 #if CONFIG_IS_ENABLED(DM_HWSPINLOCK)
30
31 /**
32 * hwspinlock_get_by_index - Get a hardware spinlock by integer index
33 *
34 * This looks up and request a hardware spinlock. The index is relative to the
35 * client device; each device is assumed to have n hardware spinlock associated
36 * with it somehow, and this function finds and requests one of them.
37 *
38 * @dev: The client device.
39 * @index: The index of the hardware spinlock to request, within the
40 * client's list of hardware spinlock.
41 * @hws: A pointer to a hardware spinlock struct to initialize.
42 * @return 0 if OK, or a negative error code.
43 */
44 int hwspinlock_get_by_index(struct udevice *dev,
45 int index, struct hwspinlock *hws);
46
47 /**
48 * Lock the hardware spinlock
49 *
50 * @hws: A hardware spinlock struct that previously requested by
51 * hwspinlock_get_by_index
52 * @timeout: Timeout value in msecs
53 * @return: 0 if OK, -ETIMEDOUT if timeout, -ve on other errors
54 */
55 int hwspinlock_lock_timeout(struct hwspinlock *hws, unsigned int timeout);
56
57 /**
58 * Unlock the hardware spinlock
59 *
60 * @hws: A hardware spinlock struct that previously requested by
61 * hwspinlock_get_by_index
62 * @return: 0 if OK, -ve on error
63 */
64 int hwspinlock_unlock(struct hwspinlock *hws);
65
66 #else
67
hwspinlock_get_by_index(struct udevice * dev,int index,struct hwspinlock * hws)68 static inline int hwspinlock_get_by_index(struct udevice *dev,
69 int index,
70 struct hwspinlock *hws)
71 {
72 return -ENOSYS;
73 }
74
hwspinlock_lock_timeout(struct hwspinlock * hws,int timeout)75 static inline int hwspinlock_lock_timeout(struct hwspinlock *hws,
76 int timeout)
77 {
78 return -ENOSYS;
79 }
80
hwspinlock_unlock(struct hwspinlock * hws)81 static inline int hwspinlock_unlock(struct hwspinlock *hws)
82 {
83 return -ENOSYS;
84 }
85
86 #endif /* CONFIG_DM_HWSPINLOCK */
87
88 struct ofnode_phandle_args;
89
90 /**
91 * struct hwspinlock_ops - Driver model hwspinlock operations
92 *
93 * The uclass interface is implemented by all hwspinlock devices which use
94 * driver model.
95 */
96 struct hwspinlock_ops {
97 /**
98 * of_xlate - Translate a client's device-tree (OF) hardware specifier.
99 *
100 * The hardware core calls this function as the first step in
101 * implementing a client's hwspinlock_get_by_*() call.
102 *
103 * @hws: The hardware spinlock struct to hold the translation
104 * result.
105 * @args: The hardware spinlock specifier values from device tree.
106 * @return 0 if OK, or a negative error code.
107 */
108 int (*of_xlate)(struct hwspinlock *hws,
109 struct ofnode_phandle_args *args);
110
111 /**
112 * Lock the hardware spinlock
113 *
114 * @dev: hwspinlock Device
115 * @index: index of the lock to be used
116 * @return 0 if OK, -ve on error
117 */
118 int (*lock)(struct udevice *dev, int index);
119
120 /**
121 * Unlock the hardware spinlock
122 *
123 * @dev: hwspinlock Device
124 * @index: index of the lock to be unlocked
125 * @return 0 if OK, -ve on error
126 */
127 int (*unlock)(struct udevice *dev, int index);
128
129 /**
130 * Relax - optional
131 * Platform-specific relax method, called by hwspinlock core
132 * while spinning on a lock, between two successive call to
133 * lock
134 *
135 * @dev: hwspinlock Device
136 */
137 void (*relax)(struct udevice *dev);
138 };
139
140 #endif /* _HWSPINLOCK_H_ */
141