/* * Copyright (c) 2023 Sequans Communications * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_DRIVERS_HWSPINLOCK_H_ #define ZEPHYR_INCLUDE_DRIVERS_HWSPINLOCK_H_ /** * @brief HW spinlock Interface * @defgroup hwspinlock_interface HW spinlock Interface * @ingroup io_interfaces * @{ */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** @cond INTERNAL_HIDDEN */ /** * @brief Callback API for trying to lock HW spinlock * @see hwspinlock_trylock(). */ typedef int (*hwspinlock_api_trylock)(const struct device *dev, uint32_t id); /** * @brief Callback API to lock HW spinlock * @see hwspinlock_lock(). */ typedef void (*hwspinlock_api_lock)(const struct device *dev, uint32_t id); /** * @brief Callback API to unlock HW spinlock * @see hwspinlock_unlock(). */ typedef void (*hwspinlock_api_unlock)(const struct device *dev, uint32_t id); /** * @brief Callback API to get HW spinlock max ID * @see hwspinlock_get_max_id(). */ typedef uint32_t (*hwspinlock_api_get_max_id)(const struct device *dev); __subsystem struct hwspinlock_driver_api { hwspinlock_api_trylock trylock; hwspinlock_api_lock lock; hwspinlock_api_unlock unlock; hwspinlock_api_get_max_id get_max_id; }; /** * @endcond */ /** * @brief Try to lock HW spinlock * * This function is used for try to lock specific HW spinlock. It should * be called before a critical section that we want to protect. * * @param dev HW spinlock device instance. * @param id Spinlock identifier. * * @retval 0 If successful. * @retval -errno In case of any failure. */ __syscall int hwspinlock_trylock(const struct device *dev, uint32_t id); static inline int z_impl_hwspinlock_trylock(const struct device *dev, uint32_t id) { const struct hwspinlock_driver_api *api = (const struct hwspinlock_driver_api *)dev->api; if (api->trylock == NULL) return -ENOSYS; return api->trylock(dev, id); } /** * @brief Lock HW spinlock * * This function is used to lock specific HW spinlock. It should be * called before a critical section that we want to protect. * * @param dev HW spinlock device instance. * @param id Spinlock identifier. */ __syscall void hwspinlock_lock(const struct device *dev, uint32_t id); static inline void z_impl_hwspinlock_lock(const struct device *dev, uint32_t id) { const struct hwspinlock_driver_api *api = (const struct hwspinlock_driver_api *)dev->api; if (api->lock != NULL) api->lock(dev, id); } /** * @brief Try to unlock HW spinlock * * This function is used for try to unlock specific HW spinlock. It should * be called after a critical section that we want to protect. * * @param dev HW spinlock device instance. * @param id Spinlock identifier. */ __syscall void hwspinlock_unlock(const struct device *dev, uint32_t id); static inline void z_impl_hwspinlock_unlock(const struct device *dev, uint32_t id) { const struct hwspinlock_driver_api *api = (const struct hwspinlock_driver_api *)dev->api; if (api->unlock != NULL) api->unlock(dev, id); } /** * @brief Get HW spinlock max ID * * This function is used to get the HW spinlock maximum ID. It should * be called before attempting to lock/unlock a specific HW spinlock. * * @param dev HW spinlock device instance. * * @retval HW spinlock max ID. * @retval 0 if the function is not implemented by the driver. */ __syscall uint32_t hwspinlock_get_max_id(const struct device *dev); static inline uint32_t z_impl_hwspinlock_get_max_id(const struct device *dev) { const struct hwspinlock_driver_api *api = (const struct hwspinlock_driver_api *)dev->api; if (api->get_max_id == NULL) return 0; return api->get_max_id(dev); } #ifdef __cplusplus } #endif /** @} */ #include #endif /* ZEPHYR_INCLUDE_DRIVERS_HWSPINLOCK_H_ */