Zephyr API Documentation 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
hwspinlock.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025 Sequans Communications
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
12
13#ifndef ZEPHYR_INCLUDE_DRIVERS_HWSPINLOCK_H_
14#define ZEPHYR_INCLUDE_DRIVERS_HWSPINLOCK_H_
15
22
23#include <zephyr/types.h>
24#include <zephyr/sys/util.h>
25#include <zephyr/sys/__assert.h>
26#include <zephyr/device.h>
27#include <zephyr/spinlock.h>
28#include <zephyr/devicetree.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
39 /*
40 * Per HW spinlock lock.
41 *
42 * HW spinlock protects resources across clusters, but we need to protect the
43 * access to the HW spinlock inside of the same cluster, so a single thread may
44 * claim the lock at a time.
45 */
46 struct k_spinlock lock;
48};
49
56
68
76#define HWSPINLOCK_CTX_INITIALIZER \
77 { \
78 .lock = {}, \
79 }
80
107#define HWSPINLOCK_DT_SPEC_GET_BY_IDX(node_id, idx) \
108 { \
109 .dev = DEVICE_DT_GET(DT_HWSPINLOCK_CTRL_BY_IDX(node_id, idx)), \
110 .id = DT_HWSPINLOCK_ID_BY_IDX(node_id, idx), \
111 .ctx = HWSPINLOCK_CTX_INITIALIZER, \
112 }
113
141#define HWSPINLOCK_DT_SPEC_GET_BY_NAME(node_id, name) \
142 { \
143 .dev = DEVICE_DT_GET(DT_HWSPINLOCK_CTRL_BY_NAME(node_id, name)), \
144 .id = DT_HWSPINLOCK_ID_BY_NAME(node_id, name), \
145 .ctx = HWSPINLOCK_CTX_INITIALIZER, \
146 }
147
156#define HWSPINLOCK_DT_SPEC_GET(node_id) \
157 HWSPINLOCK_DT_SPEC_GET_BY_IDX(node_id, 0)
158
167#define HWSPINLOCK_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
168 HWSPINLOCK_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
169
178#define HWSPINLOCK_DT_SPEC_INST_GET_BY_NAME(inst, name) \
179 HWSPINLOCK_DT_SPEC_GET_BY_NAME(DT_DRV_INST(inst), name)
180
187#define HWSPINLOCK_DT_SPEC_INST_GET(inst) \
188 HWSPINLOCK_DT_SPEC_GET(DT_DRV_INST(inst))
189
194
200typedef int (*hwspinlock_api_trylock)(const struct device *dev, uint32_t id);
201
207typedef void (*hwspinlock_api_lock)(const struct device *dev, uint32_t id);
208
214typedef void (*hwspinlock_api_unlock)(const struct device *dev, uint32_t id);
215
221typedef uint32_t (*hwspinlock_api_get_max_id)(const struct device *dev);
222
244
247
266static inline int hw_spin_trylock(const struct device *dev, hwspinlock_ctx_t *ctx, uint32_t id,
267 k_spinlock_key_t *key)
268{
269 const struct hwspinlock_driver_api *api = DEVICE_API_GET(hwspinlock, dev);
270 int ret;
271
272 if (api->trylock == NULL) {
273 return -ENOSYS;
274 }
275
276 ret = k_spin_trylock(&ctx->lock, key);
277 if (ret) {
278 return ret;
279 }
280
281 ret = api->trylock(dev, id);
282 if (ret) {
283 /* HW trylock failed: release local lock before returning. */
284 k_spin_unlock(&ctx->lock, *key);
285 return ret;
286 }
287
288 return 0;
289}
290
315static inline k_spinlock_key_t hw_spin_lock(const struct device *dev, hwspinlock_ctx_t *ctx,
316 uint32_t id)
317{
318 const struct hwspinlock_driver_api *api = DEVICE_API_GET(hwspinlock, dev);
320
321 __ASSERT(api->lock != NULL, "hwspinlock lock callback must be implemented");
322
323 k = k_spin_lock(&ctx->lock);
324 api->lock(dev, id);
325
326 return k;
327}
328
340static inline void hw_spin_unlock(const struct device *dev, hwspinlock_ctx_t *ctx, uint32_t id,
342{
343 const struct hwspinlock_driver_api *api = DEVICE_API_GET(hwspinlock, dev);
344
345 __ASSERT(api->unlock != NULL, "hwspinlock unlock callback must be implemented");
346
347 api->unlock(dev, id);
348 k_spin_unlock(&ctx->lock, key);
349}
350
361static inline uint32_t hw_spinlock_get_max_id(const struct device *dev)
362{
363 const struct hwspinlock_driver_api *api = DEVICE_API_GET(hwspinlock, dev);
364
365 __ASSERT(api->get_max_id != NULL, "hwspinlock get_max_id callback must be implemented");
366
367 return api->get_max_id(dev);
368}
369
381static inline int hw_spin_trylock_dt(struct hwspinlock_dt_spec *spec, k_spinlock_key_t *key)
382{
383 return hw_spin_trylock(spec->dev, &spec->ctx, spec->id, key);
384}
385
397{
398 return hw_spin_lock(spec->dev, &spec->ctx, spec->id);
399}
400
411static inline void hw_spin_unlock_dt(struct hwspinlock_dt_spec *spec, k_spinlock_key_t key)
412{
413 hw_spin_unlock(spec->dev, &spec->ctx, spec->id, key);
414}
415
427{
428 return hw_spinlock_get_max_id(spec->dev);
429}
430
431#ifdef __cplusplus
432}
433#endif
434
436
437#endif /* ZEPHYR_INCLUDE_DRIVERS_HWSPINLOCK_H_ */
#define DEVICE_API_GET(_class, _dev)
Expands to the pointer of a device's API for a given class.
Definition device.h:1425
Devicetree main header.
void(* hwspinlock_api_lock)(const struct device *dev, uint32_t id)
Callback API to lock an HW spinlock.
Definition hwspinlock.h:207
uint32_t(* hwspinlock_api_get_max_id)(const struct device *dev)
Callback API to get the maximum HW spinlock ID.
Definition hwspinlock.h:221
int(* hwspinlock_api_trylock)(const struct device *dev, uint32_t id)
Callback API to try to lock an HW spinlock.
Definition hwspinlock.h:200
void(* hwspinlock_api_unlock)(const struct device *dev, uint32_t id)
Callback API to unlock an HW spinlock.
Definition hwspinlock.h:214
static uint32_t hw_spinlock_get_max_id_dt(struct hwspinlock_dt_spec *spec)
Get HW spinlock max ID from a struct hwspinlock_dt_spec.
Definition hwspinlock.h:426
static void hw_spin_unlock_dt(struct hwspinlock_dt_spec *spec, k_spinlock_key_t key)
Unlock HW spinlock from a struct hwspinlock_dt_spec.
Definition hwspinlock.h:411
struct hwspinlock_context hwspinlock_ctx_t
Opaque type to represent a hwspinlock runtime context.
Definition hwspinlock.h:55
static int hw_spin_trylock(const struct device *dev, hwspinlock_ctx_t *ctx, uint32_t id, k_spinlock_key_t *key)
Try to lock HW spinlock.
Definition hwspinlock.h:266
static k_spinlock_key_t hw_spin_lock_dt(struct hwspinlock_dt_spec *spec)
Lock HW spinlock from a struct hwspinlock_dt_spec.
Definition hwspinlock.h:396
static void hw_spin_unlock(const struct device *dev, hwspinlock_ctx_t *ctx, uint32_t id, k_spinlock_key_t key)
Unlock HW spinlock.
Definition hwspinlock.h:340
static k_spinlock_key_t hw_spin_lock(const struct device *dev, hwspinlock_ctx_t *ctx, uint32_t id)
Lock HW spinlock.
Definition hwspinlock.h:315
static uint32_t hw_spinlock_get_max_id(const struct device *dev)
Get HW spinlock max ID.
Definition hwspinlock.h:361
static int hw_spin_trylock_dt(struct hwspinlock_dt_spec *spec, k_spinlock_key_t *key)
Try to lock HW spinlock from a struct hwspinlock_dt_spec.
Definition hwspinlock.h:381
static ALWAYS_INLINE int k_spin_trylock(struct k_spinlock *l, k_spinlock_key_t *k)
Attempt to lock a spinlock.
Definition spinlock.h:235
static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, k_spinlock_key_t key)
Unlock a spin lock.
Definition spinlock.h:305
static ALWAYS_INLINE k_spinlock_key_t k_spin_lock(struct k_spinlock *l)
Lock a spinlock.
Definition spinlock.h:185
struct z_spinlock_key k_spinlock_key_t
Spinlock key type.
Definition spinlock.h:130
#define ENOSYS
Function not implemented.
Definition errno.h:82
Public interface for spinlocks.
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
Runtime device structure (in ROM) per driver instance.
Definition device.h:513
HW spinlock controller runtime context.
Definition hwspinlock.h:37
<span class="mlabel">Driver Operations</span> Hardware Spinlock driver operations
Definition hwspinlock.h:226
hwspinlock_api_unlock unlock
<span class="op-badge op-req" title="This operation MUST be implemented by the driver....
Definition hwspinlock.h:238
hwspinlock_api_lock lock
<span class="op-badge op-req" title="This operation MUST be implemented by the driver....
Definition hwspinlock.h:234
hwspinlock_api_get_max_id get_max_id
<span class="op-badge op-req" title="This operation MUST be implemented by the driver....
Definition hwspinlock.h:242
hwspinlock_api_trylock trylock
<span class="op-badge op-opt" title="This operation MAY optionally be implemented by the driver....
Definition hwspinlock.h:230
Complete hardware spinlock DT information.
Definition hwspinlock.h:60
hwspinlock_ctx_t ctx
Runtime context.
Definition hwspinlock.h:66
const struct device * dev
HW spinlock device.
Definition hwspinlock.h:62
uint32_t id
HW spinlock id.
Definition hwspinlock.h:64
Kernel Spin Lock.
Definition spinlock.h:45
Misc utilities.