History

Merge tag 'hwlock-v5.3' of git://github.com/andersson/remoteproc

Pull hwspinlock updates from Bjorn Andersson: "This contains support for hardware spinlock TI K3 AM65x and J721E family of SoCs, support for using hwspinlocks from atomic context and better error reporting when dealing with hardware disabled in DeviceTree" * tag 'hwlock-v5.3' of git://github.com/andersson/remoteproc: hwspinlock: add the 'in_atomic' API hwspinlock: document the hwspinlock 'raw' API hwspinlock: stm32: implement the relax() ops hwspinlock: ignore disabled device hwspinlock/omap: Add a trace during probe hwspinlock/omap: Add support for TI K3 SoCs dt-bindings: hwlock: Update OMAP binding for TI K3 SoCs

Linus Torvalds committed 7 years ago

Commit 57ab5f72 parents fdcec00 360aa647 files · +206 −22Browse files

Unified · Split

7 files
  1. Documentation/devicetree/bindings/hwlock/omap-hwspinlock.txt +20 −5
  2. Documentation/hwspinlock.txt +81 −0
  3. drivers/hwspinlock/Kconfig +1 −1
  4. drivers/hwspinlock/hwspinlock_core.c +35 −13
  5. drivers/hwspinlock/omap_hwspinlock.c +4 −0
  6. drivers/hwspinlock/stm32_hwspinlock.c +7 −0
  7. include/linux/hwspinlock.h +58 −3
Documentation/devicetree/bindings/hwlock/omap-hwspinlock.txt+20−5
@@ -1,12 +1,16 @@
1−OMAP4+ HwSpinlock Driver
2−========================
1+TI HwSpinlock for OMAP and K3 based SoCs
2+=========================================
33
44 Required properties:
5−- compatible: Should be "ti,omap4-hwspinlock" for
6− OMAP44xx, OMAP54xx, AM33xx, AM43xx, DRA7xx SoCs
5+- compatible: Should be one of the following,
6+ "ti,omap4-hwspinlock" for
7+ OMAP44xx, OMAP54xx, AM33xx, AM43xx, DRA7xx SoCs
8+ "ti,am654-hwspinlock" for
9+ K3 AM65x and J721E SoCs
710 - reg: Contains the hwspinlock module register address space
811 (base address and length)
912 - ti,hwmods: Name of the hwmod associated with the hwspinlock device
13+ (for OMAP architecture based SoCs only)
1014 - #hwlock-cells: Should be 1. The OMAP hwspinlock users will use a
1115 0-indexed relative hwlock number as the argument
1216 specifier value for requesting a specific hwspinlock
@@ -17,10 +21,21 @@ Please look at the generic hwlock binding for usage information for consumers, · 4 unmodified lines
1721
1822 Example:
1923
20−/* OMAP4 */
24+1. OMAP4 SoCs
2125 hwspinlock: spinlock@4a0f6000 {
2226 compatible = "ti,omap4-hwspinlock";
2327 reg = <0x4a0f6000 0x1000>;
2428 ti,hwmods = "spinlock";
2529 #hwlock-cells = <1>;
2630 };
31+
32+2. AM65x SoCs and J721E SoCs
33+&cbass_main {
34+ cbass_main_navss: interconnect0 {
35+ hwspinlock: spinlock@30e00000 {
36+ compatible = "ti,am654-hwspinlock";
37+ reg = <0x00 0x30e00000 0x00 0x1000>;
38+ #hwlock-cells = <1>;
39+ };
40+ };
41+};
Documentation/hwspinlock.txt+81−0
@@ -134,6 +134,39 @@ notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). · 133 unmodified lines
134134
135135 The function will never sleep.
136136
137+::
138+
139+ int hwspin_lock_timeout_raw(struct hwspinlock *hwlock, unsigned int timeout);
140+
141+Lock a previously-assigned hwspinlock with a timeout limit (specified in
142+msecs). If the hwspinlock is already taken, the function will busy loop
143+waiting for it to be released, but give up when the timeout elapses.
144+
145+Caution: User must protect the routine of getting hardware lock with mutex
146+or spinlock to avoid dead-lock, that will let user can do some time-consuming
147+or sleepable operations under the hardware lock.
148+
149+Returns 0 when successful and an appropriate error code otherwise (most
150+notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).
151+
152+The function will never sleep.
153+
154+::
155+
156+ int hwspin_lock_timeout_in_atomic(struct hwspinlock *hwlock, unsigned int to);
157+
158+Lock a previously-assigned hwspinlock with a timeout limit (specified in
159+msecs). If the hwspinlock is already taken, the function will busy loop
160+waiting for it to be released, but give up when the timeout elapses.
161+
162+This function shall be called only from an atomic context and the timeout
163+value shall not exceed a few msecs.
164+
165+Returns 0 when successful and an appropriate error code otherwise (most
166+notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs).
167+
168+The function will never sleep.
169+
137170 ::
138171
139172 int hwspin_trylock(struct hwspinlock *hwlock);
@@ -184,6 +217,34 @@ Returns 0 on success and an appropriate error code otherwise (most · 44 unmodified lines
184217 notably -EBUSY if the hwspinlock was already taken).
185218 The function will never sleep.
186219
220+::
221+
222+ int hwspin_trylock_raw(struct hwspinlock *hwlock);
223+
224+Attempt to lock a previously-assigned hwspinlock, but immediately fail if
225+it is already taken.
226+
227+Caution: User must protect the routine of getting hardware lock with mutex
228+or spinlock to avoid dead-lock, that will let user can do some time-consuming
229+or sleepable operations under the hardware lock.
230+
231+Returns 0 on success and an appropriate error code otherwise (most
232+notably -EBUSY if the hwspinlock was already taken).
233+The function will never sleep.
234+
235+::
236+
237+ int hwspin_trylock_in_atomic(struct hwspinlock *hwlock);
238+
239+Attempt to lock a previously-assigned hwspinlock, but immediately fail if
240+it is already taken.
241+
242+This function shall be called only from an atomic context.
243+
244+Returns 0 on success and an appropriate error code otherwise (most
245+notably -EBUSY if the hwspinlock was already taken).
246+The function will never sleep.
247+
187248 ::
188249
189250 void hwspin_unlock(struct hwspinlock *hwlock);
@@ -220,6 +281,26 @@ Upon a successful return from this function, preemption is reenabled, · 30 unmodified lines
220281 and the state of the local interrupts is restored to the state saved at
221282 the given flags. This function will never sleep.
222283
284+::
285+
286+ void hwspin_unlock_raw(struct hwspinlock *hwlock);
287+
288+Unlock a previously-locked hwspinlock.
289+
290+The caller should **never** unlock an hwspinlock which is already unlocked.
291+Doing so is considered a bug (there is no protection against this).
292+This function will never sleep.
293+
294+::
295+
296+ void hwspin_unlock_in_atomic(struct hwspinlock *hwlock);
297+
298+Unlock a previously-locked hwspinlock.
299+
300+The caller should **never** unlock an hwspinlock which is already unlocked.
301+Doing so is considered a bug (there is no protection against this).
302+This function will never sleep.
303+
223304 ::
224305
225306 int hwspin_lock_get_id(struct hwspinlock *hwlock);
drivers/hwspinlock/Kconfig+1−1
@@ -9,7 +9,7 @@ menuconfig HWSPINLOCK · 8 unmodified lines
99 config HWSPINLOCK_OMAP
1010 tristate "OMAP Hardware Spinlock device"
1111 depends on HWSPINLOCK
12− depends on ARCH_OMAP4 || SOC_OMAP5 || SOC_DRA7XX || SOC_AM33XX || SOC_AM43XX
12+ depends on ARCH_OMAP4 || SOC_OMAP5 || SOC_DRA7XX || SOC_AM33XX || SOC_AM43XX || ARCH_K3
1313 help
1414 Say y here to support the OMAP Hardware Spinlock device (firstly
1515 introduced in OMAP4).
drivers/hwspinlock/hwspinlock_core.c+35−13
@@ -9,6 +9,7 @@ · 8 unmodified lines
99
1010 #define pr_fmt(fmt) "%s: " fmt, __func__
1111
12+#include <linux/delay.h>
1213 #include <linux/kernel.h>
1314 #include <linux/module.h>
1415 #include <linux/spinlock.h>
@@ -23,6 +24,9 @@ · 8 unmodified lines
2324
2425 #include "hwspinlock_internal.h"
2526
27+/* retry delay used in atomic context */
28+#define HWSPINLOCK_RETRY_DELAY_US 100
29+
2630 /* radix tree tags */
2731 #define HWSPINLOCK_UNUSED (0) /* tags an hwspinlock as unused */
2832
@@ -68,11 +72,11 @@ static DEFINE_MUTEX(hwspinlock_tree_lock); · 39 unmodified lines
6872 * user need some time-consuming or sleepable operations under the hardware
6973 * lock, they need one sleepable lock (like mutex) to protect the operations.
7074 *
71− * If the mode is not HWLOCK_RAW, upon a successful return from this function,
72− * preemption (and possibly interrupts) is disabled, so the caller must not
73− * sleep, and is advised to release the hwspinlock as soon as possible. This is
74− * required in order to minimize remote cores polling on the hardware
75− * interconnect.
75+ * If the mode is neither HWLOCK_IN_ATOMIC nor HWLOCK_RAW, upon a successful
76+ * return from this function, preemption (and possibly interrupts) is disabled,
77+ * so the caller must not sleep, and is advised to release the hwspinlock as
78+ * soon as possible. This is required in order to minimize remote cores polling
79+ * on the hardware interconnect.
7680 *
7781 * The user decides whether local interrupts are disabled or not, and if yes,
7882 * whether he wants their previous state to be saved. It is up to the user
@@ -112,6 +116,7 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) · 33 unmodified lines
112116 ret = spin_trylock_irq(&hwlock->lock);
113117 break;
114118 case HWLOCK_RAW:
119+ case HWLOCK_IN_ATOMIC:
115120 ret = 1;
116121 break;
117122 default:
@@ -136,6 +141,7 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) · 18 unmodified lines
136141 spin_unlock_irq(&hwlock->lock);
137142 break;
138143 case HWLOCK_RAW:
144+ case HWLOCK_IN_ATOMIC:
139145 /* Nothing to do */
140146 break;
141147 default:
@@ -179,11 +185,14 @@ EXPORT_SYMBOL_GPL(__hwspin_trylock); · 37 unmodified lines
179185 * user need some time-consuming or sleepable operations under the hardware
180186 * lock, they need one sleepable lock (like mutex) to protect the operations.
181187 *
182− * If the mode is not HWLOCK_RAW, upon a successful return from this function,
183− * preemption is disabled (and possibly local interrupts, too), so the caller
184− * must not sleep, and is advised to release the hwspinlock as soon as possible.
185− * This is required in order to minimize remote cores polling on the
186− * hardware interconnect.
188+ * If the mode is HWLOCK_IN_ATOMIC (called from an atomic context) the timeout
189+ * is handled with busy-waiting delays, hence shall not exceed few msecs.
190+ *
191+ * If the mode is neither HWLOCK_IN_ATOMIC nor HWLOCK_RAW, upon a successful
192+ * return from this function, preemption (and possibly interrupts) is disabled,
193+ * so the caller must not sleep, and is advised to release the hwspinlock as
194+ * soon as possible. This is required in order to minimize remote cores polling
195+ * on the hardware interconnect.
187196 *
188197 * The user decides whether local interrupts are disabled or not, and if yes,
189198 * whether he wants their previous state to be saved. It is up to the user
@@ -198,7 +207,7 @@ int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to, · 8 unmodified lines
198207 int mode, unsigned long *flags)
199208 {
200209 int ret;
201− unsigned long expire;
210+ unsigned long expire, atomic_delay = 0;
202211
203212 expire = msecs_to_jiffies(to) + jiffies;
204213
@@ -212,8 +221,15 @@ int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to, · 7 unmodified lines
212221 * The lock is already taken, let's check if the user wants
213222 * us to try again
214223 */
215− if (time_is_before_eq_jiffies(expire))
216− return -ETIMEDOUT;
224+ if (mode == HWLOCK_IN_ATOMIC) {
225+ udelay(HWSPINLOCK_RETRY_DELAY_US);
226+ atomic_delay += HWSPINLOCK_RETRY_DELAY_US;
227+ if (atomic_delay > to * 1000)
228+ return -ETIMEDOUT;
229+ } else {
230+ if (time_is_before_eq_jiffies(expire))
231+ return -ETIMEDOUT;
232+ }
217233
218234 /*
219235 * Allow platform-specific relax handlers to prevent
@@ -276,6 +292,7 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) · 56 unmodified lines
276292 spin_unlock_irq(&hwlock->lock);
277293 break;
278294 case HWLOCK_RAW:
295+ case HWLOCK_IN_ATOMIC:
279296 /* Nothing to do */
280297 break;
281298 default:
@@ -333,6 +350,11 @@ int of_hwspin_lock_get_id(struct device_node *np, int index) · 51 unmodified lines
333350 if (ret)
334351 return ret;
335352
353+ if (!of_device_is_available(args.np)) {
354+ ret = -ENOENT;
355+ goto out;
356+ }
357+
336358 /* Find the hwspinlock device: we need its base_id */
337359 ret = -EPROBE_DEFER;
338360 rcu_read_lock();
drivers/hwspinlock/omap_hwspinlock.c+4−0
@@ -140,6 +140,9 @@ static int omap_hwspinlock_probe(struct platform_device *pdev) · 139 unmodified lines
140140 if (ret)
141141 goto reg_fail;
142142
143+ dev_dbg(&pdev->dev, "Registered %d locks with HwSpinlock core\n",
144+ num_locks);
145+
143146 return 0;
144147
145148 reg_fail:
@@ -171,6 +174,7 @@ static int omap_hwspinlock_remove(struct platform_device *pdev) · 25 unmodified lines
171174
172175 static const struct of_device_id omap_hwspinlock_of_match[] = {
173176 { .compatible = "ti,omap4-hwspinlock", },
177+ { .compatible = "ti,am654-hwspinlock", },
174178 { /* end */ },
175179 };
176180 MODULE_DEVICE_TABLE(of, omap_hwspinlock_of_match);
drivers/hwspinlock/stm32_hwspinlock.c+7−0
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 */
66
77 #include <linux/clk.h>
8+#include <linux/delay.h>
89 #include <linux/hwspinlock.h>
910 #include <linux/io.h>
1011 #include <linux/kernel.h>
@@ -42,9 +43,15 @@ static void stm32_hwspinlock_unlock(struct hwspinlock *lock) · 31 unmodified lines
4243 writel(STM32_MUTEX_COREID, lock_addr);
4344 }
4445
46+static void stm32_hwspinlock_relax(struct hwspinlock *lock)
47+{
48+ ndelay(50);
49+}
50+
4551 static const struct hwspinlock_ops stm32_hwspinlock_ops = {
4652 .trylock = stm32_hwspinlock_trylock,
4753 .unlock = stm32_hwspinlock_unlock,
54+ .relax = stm32_hwspinlock_relax,
4855 };
4956
5057 static int stm32_hwspinlock_probe(struct platform_device *pdev)
include/linux/hwspinlock.h+58−3
@@ -14,9 +14,10 @@ · 13 unmodified lines
1414 #include <linux/sched.h>
1515
1616 /* hwspinlock mode argument */
17−#define HWLOCK_IRQSTATE 0x01 /* Disable interrupts, save state */
18−#define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */
19−#define HWLOCK_RAW 0x03
17+#define HWLOCK_IRQSTATE 0x01 /* Disable interrupts, save state */
18+#define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */
19+#define HWLOCK_RAW 0x03
20+#define HWLOCK_IN_ATOMIC 0x04 /* Called while in atomic context */
2021
2122 struct device;
2223 struct device_node;
@@ -222,6 +223,23 @@ static inline int hwspin_trylock_raw(struct hwspinlock *hwlock) · 199 unmodified lines
222223 return __hwspin_trylock(hwlock, HWLOCK_RAW, NULL);
223224 }
224225
226+/**
227+ * hwspin_trylock_in_atomic() - attempt to lock a specific hwspinlock
228+ * @hwlock: an hwspinlock which we want to trylock
229+ *
230+ * This function attempts to lock an hwspinlock, and will immediately fail
231+ * if the hwspinlock is already taken.
232+ *
233+ * This function shall be called only from an atomic context.
234+ *
235+ * Returns 0 if we successfully locked the hwspinlock, -EBUSY if
236+ * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid.
237+ */
238+static inline int hwspin_trylock_in_atomic(struct hwspinlock *hwlock)
239+{
240+ return __hwspin_trylock(hwlock, HWLOCK_IN_ATOMIC, NULL);
241+}
242+
225243 /**
226244 * hwspin_trylock() - attempt to lock a specific hwspinlock
227245 * @hwlock: an hwspinlock which we want to trylock
@@ -312,6 +330,28 @@ int hwspin_lock_timeout_raw(struct hwspinlock *hwlock, unsigned int to) · 84 unmodified lines
312330 return __hwspin_lock_timeout(hwlock, to, HWLOCK_RAW, NULL);
313331 }
314332
333+/**
334+ * hwspin_lock_timeout_in_atomic() - lock an hwspinlock with timeout limit
335+ * @hwlock: the hwspinlock to be locked
336+ * @to: timeout value in msecs
337+ *
338+ * This function locks the underlying @hwlock. If the @hwlock
339+ * is already taken, the function will busy loop waiting for it to
340+ * be released, but give up when @timeout msecs have elapsed.
341+ *
342+ * This function shall be called only from an atomic context and the timeout
343+ * value shall not exceed a few msecs.
344+ *
345+ * Returns 0 when the @hwlock was successfully taken, and an appropriate
346+ * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still
347+ * busy after @timeout msecs). The function will never sleep.
348+ */
349+static inline
350+int hwspin_lock_timeout_in_atomic(struct hwspinlock *hwlock, unsigned int to)
351+{
352+ return __hwspin_lock_timeout(hwlock, to, HWLOCK_IN_ATOMIC, NULL);
353+}
354+
315355 /**
316356 * hwspin_lock_timeout() - lock an hwspinlock with timeout limit
317357 * @hwlock: the hwspinlock to be locked
@@ -386,6 +426,21 @@ static inline void hwspin_unlock_raw(struct hwspinlock *hwlock) · 68 unmodified lines
386426 __hwspin_unlock(hwlock, HWLOCK_RAW, NULL);
387427 }
388428
429+/**
430+ * hwspin_unlock_in_atomic() - unlock hwspinlock
431+ * @hwlock: a previously-acquired hwspinlock which we want to unlock
432+ *
433+ * This function will unlock a specific hwspinlock.
434+ *
435+ * @hwlock must be already locked (e.g. by hwspin_trylock()) before calling
436+ * this function: it is a bug to call unlock on a @hwlock that is already
437+ * unlocked.
438+ */
439+static inline void hwspin_unlock_in_atomic(struct hwspinlock *hwlock)
440+{
441+ __hwspin_unlock(hwlock, HWLOCK_IN_ATOMIC, NULL);
442+}
443+
389444 /**
390445 * hwspin_unlock() - unlock hwspinlock
391446 * @hwlock: a previously-acquired hwspinlock which we want to unlock

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t