hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/include/linux/hwspinlock.h
....@@ -14,9 +14,10 @@
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;
....@@ -223,6 +224,23 @@
223224 }
224225
225226 /**
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
+
243
+/**
226244 * hwspin_trylock() - attempt to lock a specific hwspinlock
227245 * @hwlock: an hwspinlock which we want to trylock
228246 *
....@@ -313,6 +331,28 @@
313331 }
314332
315333 /**
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
+
355
+/**
316356 * hwspin_lock_timeout() - lock an hwspinlock with timeout limit
317357 * @hwlock: the hwspinlock to be locked
318358 * @to: timeout value in msecs
....@@ -387,6 +427,21 @@
387427 }
388428
389429 /**
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
+
444
+/**
390445 * hwspin_unlock() - unlock hwspinlock
391446 * @hwlock: a previously-acquired hwspinlock which we want to unlock
392447 *