diff --git a/include/zephyr/drivers/intc.h b/include/zephyr/drivers/intc.h new file mode 100644 index 00000000000000..c6a5eda98284d6 --- /dev/null +++ b/include/zephyr/drivers/intc.h @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_INTC_H_ +#define ZEPHYR_INCLUDE_DRIVERS_INTC_H_ + +/** + * @brief Interrupt controller cnterface + * @defgroup intc_interface Interrupt controller interface + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Interrupt request handle forward declaration */ +struct intc_irq; + +/** Interrupt request handler */ +typedef void (*intc_irq_handler_t)(struct intc_irq *irq); + +/** @cond INTERNAL_HIDDEN */ + +/** Interrupt request specification */ +struct intc_irq_spec { + const struct device *intc; + uint32_t irq; + uint32_t flags; + intc_irq_handler_t handler; +}; + +/** Interrupt request handle */ +struct intc_irq { + /** Interrupt request single-linked list node */ + sys_snode_t node; + /** Interrupt request specification */ + const struct intc_irq_spec *spec; +}; + +/** Request interrupt request API template function */ +typedef int (*intc_api_request_irq)(struct intc_irq *irq); + +/** Set interrupt request priority API template function */ +typedef int (*intc_api_set_irq_priority)(struct intc_irq *irq, uint16_t priority); + +/** Enable interrupt request API template function */ +typedef int (*intc_api_enable_irq)(struct intc_irq *irq); + +/** Disable interrupt request API template function */ +typedef int (*intc_api_disable_irq)(struct intc_irq *irq); + +/** Interrupt request is enabled API template function */ +typedef int (*intc_api_irq_is_enabled)(struct intc_irq *irq); + +/** Release interrupt request API template function */ +typedef int (*intc_api_release_irq)(struct intc_irq *irq); + +/** Interrupt controller API structure */ +struct intc_driver_api { + intc_api_request_irq request_irq; + intc_api_set_irq_priority set_irq_priority; + intc_api_enable_irq enable_irq; + intc_api_disable_irq disable_irq; + intc_api_irq_is_enabled irq_is_enabled; + intc_api_release_irq release_irq; +}; + +/** @endcond */ + +/** + * @brief Request interrupt request + * + * @param irq Interrupt request handle + * @param spec Interrupt request specification + * + * @note The irq handle and the irq spec must remain valid until released + * + * @retval 0 if successful + * @retval -errno code if failure + */ +static int intc_request_irq(struct intc_irq *irq, const struct intc_irq_spec *spec) +{ + const struct intc_driver_api *api = (const struct intc_driver_api *)spec->intc->api; + + irq->spec = spec; + return api->request_irq(irq); +} + +/** + * @brief Set interrupt request priority + * + * @param irq Interrupt request handle + * @param priority Interrupt request priority to set + * + * @retval 0 if successful + * @retval -ENOTSUP if setting interrupt request priority is not supported + * @retval -errno code if failure + */ +static int intc_set_irq_priority(struct intc_irq *irq, uint16_t priority) +{ + const struct intc_driver_api *api = (const struct intc_driver_api *)irq->intc->api; + + if (!api->set_irq_priority) { + return -ENOTSUP; + } + + return api->set_irq_priority(irq, priority); +} + +/** + * @brief Enable interrupt request + * + * @param irq Interrupt request handle + * + * @retval 0 if successful + * @retval -errno code if failure + */ +static int intc_enable_irq(struct intc_irq *irq) +{ + const struct intc_driver_api *api = (const struct intc_driver_api *)irq->intc->api; + + return api->enable_irq(irq); +} + +/** + * @brief Disable interrupt request + * + * @param irq Interrupt request handle + * + * @retval 0 if successful + * @retval -errno code if failure + */ +static int intc_disable_irq(struct intc_irq *irq) +{ + const struct intc_driver_api *api = (const struct intc_driver_api *)irq->intc->api; + + return api->disable_irq(irq); +} + +/** + * @brief Test if interrupt request is enabled + * + * @param irq Interrupt request handle + * + * @retval 1 if interrupt request is enabled + * @retval 0 if interrupt request is disabled + * @retval -errno code if failure + */ +static int intc_irq_is_enabled(struct intc_irq *irq) +{ + const struct intc_driver_api *api = (const struct intc_driver_api *)irq->intc->api; + + return api->irq_is_enabled(irq); +} + +/** + * @brief Release interrupt request + * + * @param irq Interrupt request handle + * + * @retval 0 if successfull + * @retval -errno code if failure + */ +static int intc_release_irq(struct intc_irq *irq) +{ + const struct intc_driver_api *api = (const struct intc_driver_api *)irq->intc->api; + + return api->release_irq(irq); +} + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_INTC_H_ */