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