blob: 9f9fd994ea25ddb201bf68d55175ba6f7c26475b [file] [log] [blame]
/*
* 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 <errno.h>
#include <zephyr/types.h>
#include <zephyr/sys/util.h>
#include <zephyr/device.h>
#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 <syscalls/hwspinlock.h>
#endif /* ZEPHYR_INCLUDE_DRIVERS_HWSPINLOCK_H_ */