Browse Source

drivers: intc: esp32: Shared allocator for Xtensa and RISCV

Update interrupt allocator to use the same driver for both
Xtensa and RISCV devices.

Signed-off-by: Raffael Rostagno <raffael.rostagno@espressif.com>
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
pull/87800/merge
Raffael Rostagno 5 months ago committed by Benjamin Cabé
parent
commit
034c0cb977
  1. 1
      drivers/interrupt_controller/CMakeLists.txt
  2. 2
      drivers/interrupt_controller/Kconfig
  3. 3
      drivers/interrupt_controller/Kconfig.esp32
  4. 21
      drivers/interrupt_controller/Kconfig.esp32c3
  5. 162
      drivers/interrupt_controller/intc_esp32.c
  6. 277
      drivers/interrupt_controller/intc_esp32c3.c
  7. 36
      include/zephyr/drivers/interrupt_controller/intc_esp32.h
  8. 124
      include/zephyr/drivers/interrupt_controller/intc_esp32c3.h
  9. 7
      include/zephyr/dt-bindings/interrupt-controller/esp-esp32c2-intmux.h
  10. 7
      include/zephyr/dt-bindings/interrupt-controller/esp-esp32c3-intmux.h
  11. 7
      include/zephyr/dt-bindings/interrupt-controller/esp-esp32c6-intmux.h
  12. 4
      include/zephyr/dt-bindings/interrupt-controller/esp-xtensa-intmux.h
  13. 4
      include/zephyr/dt-bindings/interrupt-controller/esp32s2-xtensa-intmux.h
  14. 4
      include/zephyr/dt-bindings/interrupt-controller/esp32s3-xtensa-intmux.h

1
drivers/interrupt_controller/CMakeLists.txt

@ -28,7 +28,6 @@ zephyr_library_sources_ifdef(CONFIG_RV32M1_INTMUX intc_rv32m1_intmux.c @@ -28,7 +28,6 @@ zephyr_library_sources_ifdef(CONFIG_RV32M1_INTMUX intc_rv32m1_intmux.c
zephyr_library_sources_ifdef(CONFIG_SAM0_EIC intc_sam0_eic.c)
zephyr_library_sources_ifdef(CONFIG_SHARED_IRQ intc_shared_irq.c)
zephyr_library_sources_ifdef(CONFIG_INTC_ESP32 intc_esp32.c)
zephyr_library_sources_ifdef(CONFIG_INTC_ESP32C3 intc_esp32c3.c)
zephyr_library_sources_ifdef(CONFIG_SWERV_PIC intc_swerv_pic.c)
zephyr_library_sources_ifdef(CONFIG_VEXRISCV_LITEX_IRQ intc_vexriscv_litex.c)
zephyr_library_sources_ifdef(CONFIG_VIM intc_vim.c)

2
drivers/interrupt_controller/Kconfig

@ -84,8 +84,6 @@ source "drivers/interrupt_controller/Kconfig.intel_vtd" @@ -84,8 +84,6 @@ source "drivers/interrupt_controller/Kconfig.intel_vtd"
source "drivers/interrupt_controller/Kconfig.esp32"
source "drivers/interrupt_controller/Kconfig.esp32c3"
source "drivers/interrupt_controller/Kconfig.xec"
source "drivers/interrupt_controller/Kconfig.clic"

3
drivers/interrupt_controller/Kconfig.esp32

@ -4,10 +4,9 @@ @@ -4,10 +4,9 @@
# SPDX-License-Identifier: Apache-2.0
config INTC_ESP32
bool "Interrupt allocator for Xtensa-based Espressif SoCs"
bool "Interrupt allocator for Espressif SoCs"
default y
depends on SOC_FAMILY_ESPRESSIF_ESP32
depends on !SOC_SERIES_ESP32C2 && !SOC_SERIES_ESP32C3 && !SOC_SERIES_ESP32C6
help
Enable custom interrupt allocator for Espressif SoCs based on Xtensa
architecture.

21
drivers/interrupt_controller/Kconfig.esp32c3

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
# Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
# SPDX-License-Identifier: Apache-2.0
config INTC_ESP32C3
bool "ESP32C3 interrupt controller driver"
depends on SOC_FAMILY_ESPRESSIF_ESP32
depends on SOC_SERIES_ESP32C2 || SOC_SERIES_ESP32C3 || SOC_SERIES_ESP32C6
default y
help
Enables the esp32c3 interrupt controller driver to handle ISR
management at SoC level.
config INTC_ESP32C3_DECISIONS_LOG
bool "Espressif's interrupt allocator logging"
depends on INTC_ESP32C3
select LOG
help
Enable this option to visualize information on decisions made by the
interrupt allocator. This has no impact on the interrupt allocator usage
but may be valuable for debugging purposes. When enabled, messages are
print to the serial console.

162
drivers/interrupt_controller/intc_esp32.c

@ -1,10 +1,11 @@ @@ -1,10 +1,11 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
* Copyright (c) 2021-2025 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/irq.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -15,13 +16,14 @@ @@ -15,13 +16,14 @@
#include <esp_memory_utils.h>
#include <esp_attr.h>
#include <esp_cpu.h>
#include <esp_rom_sys.h>
#include <esp_private/rtc_ctrl.h>
#include <limits.h>
#include <assert.h>
#include <soc/soc.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(esp32_intc, CONFIG_LOG_DEFAULT_LEVEL);
LOG_MODULE_REGISTER(intc_esp32, CONFIG_LOG_DEFAULT_LEVEL);
#define ETS_INTERNAL_TIMER0_INTR_NO 6
#define ETS_INTERNAL_TIMER1_INTR_NO 15
@ -47,7 +49,6 @@ LOG_MODULE_REGISTER(esp32_intc, CONFIG_LOG_DEFAULT_LEVEL); @@ -47,7 +49,6 @@ LOG_MODULE_REGISTER(esp32_intc, CONFIG_LOG_DEFAULT_LEVEL);
#endif
/* Typedef for C-callable interrupt handler function */
typedef void (*intc_handler_t)(void *);
typedef void (*intc_dyn_handler_t)(const void *);
/* shared critical section context */
@ -63,32 +64,6 @@ static inline void esp_intr_unlock(void) @@ -63,32 +64,6 @@ static inline void esp_intr_unlock(void)
irq_unlock(esp_intc_csec);
}
/*
* Interrupt handler table and unhandled interrupt routine. Duplicated
* from xtensa_intr.c... it's supposed to be private, but we need to look
* into it in order to see if someone allocated an int using
* set_interrupt_handler.
*/
struct intr_alloc_table_entry {
void (*handler)(void *arg);
void *arg;
};
/* Default handler for unhandled interrupts. */
void IRAM_ATTR default_intr_handler(void *arg)
{
esp_rom_printf("Unhandled interrupt %d on cpu %d!\n", (int)arg, esp_cpu_get_core_id());
}
static struct intr_alloc_table_entry intr_alloc_table[ESP_INTC_INTS_NUM * CONFIG_MP_MAX_NUM_CPUS];
static void set_interrupt_handler(int n, intc_handler_t f, void *arg)
{
irq_disable(n);
intr_alloc_table[n * CONFIG_MP_MAX_NUM_CPUS].handler = f;
irq_connect_dynamic(n, 0, (intc_dyn_handler_t)f, arg, 0);
}
/* Linked list of vector descriptions, sorted by cpu.intno value */
static struct vector_desc_t *vector_desc_head; /* implicitly initialized to NULL */
@ -201,19 +176,9 @@ static struct vector_desc_t *find_desc_for_source(int source, int cpu) @@ -201,19 +176,9 @@ static struct vector_desc_t *find_desc_for_source(int source, int cpu)
return vd;
}
void esp_intr_initialize(void)
{
unsigned int num_cpus = arch_num_cpus();
for (size_t i = 0; i < (ESP_INTC_INTS_NUM * num_cpus); ++i) {
intr_alloc_table[i].handler = default_intr_handler;
intr_alloc_table[i].arg = (void *)i;
}
}
int esp_intr_mark_shared(int intno, int cpu, bool is_int_ram)
{
if (intno >= ESP_INTC_INTS_NUM) {
if (intno >= SOC_CPU_INTR_NUM) {
return -EINVAL;
}
if (cpu >= arch_num_cpus()) {
@ -238,7 +203,7 @@ int esp_intr_mark_shared(int intno, int cpu, bool is_int_ram) @@ -238,7 +203,7 @@ int esp_intr_mark_shared(int intno, int cpu, bool is_int_ram)
int esp_intr_reserve(int intno, int cpu)
{
if (intno >= ESP_INTC_INTS_NUM) {
if (intno >= SOC_CPU_INTR_NUM) {
return -EINVAL;
}
if (cpu >= arch_num_cpus()) {
@ -263,7 +228,7 @@ static bool intr_has_handler(int intr, int cpu) @@ -263,7 +228,7 @@ static bool intr_has_handler(int intr, int cpu)
{
bool r;
r = intr_alloc_table[intr * CONFIG_MP_MAX_NUM_CPUS + cpu].handler != default_intr_handler;
r = _sw_isr_table[intr * CONFIG_MP_MAX_NUM_CPUS + cpu].isr != z_irq_spurious;
return r;
}
@ -273,7 +238,6 @@ static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, in @@ -273,7 +238,6 @@ static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, in
/* Check if interrupt is not reserved by design */
int x = vd->intno;
esp_cpu_intr_desc_t intr_desc;
esp_cpu_intr_get_desc(cpu, x, &intr_desc);
if (intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD) {
@ -286,14 +250,14 @@ static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, in @@ -286,14 +250,14 @@ static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, in
}
#ifndef SOC_CPU_HAS_FLEXIBLE_INTC
/* Check if the interrupt priority is acceptable */
/* Check if the interrupt level is acceptable */
if (!(flags & (1 << intr_desc.priority))) {
INTC_LOG("....Unusable: incompatible priority");
INTC_LOG("....Unusable: incompatible level");
return false;
}
/* check if edge/level type matches what we want */
if (((flags & ESP_INTR_FLAG_EDGE) && (intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL)) ||
(((!(flags & ESP_INTR_FLAG_EDGE)) && (intr_desc.type == ESP_CPU_INTR_TYPE_EDGE)))) {
(((!(flags & ESP_INTR_FLAG_EDGE)) && (intr_desc.type == ESP_CPU_INTR_TYPE_EDGE)))) {
INTC_LOG("....Unusable: incompatible trigger type");
return false;
}
@ -335,7 +299,6 @@ static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, in @@ -335,7 +299,6 @@ static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, in
return false;
}
} else if (intr_has_handler(x, cpu)) {
/* Check if interrupt already is allocated by set_interrupt_handler */
INTC_LOG("....Unusable: already allocated");
return false;
}
@ -400,7 +363,7 @@ static int get_available_int(int flags, int cpu, int force, int source) @@ -400,7 +363,7 @@ static int get_available_int(int flags, int cpu, int force, int source)
INTC_LOG("%s: start looking. Current cpu: %d", __func__, cpu);
/* No allocated handlers as well as forced intr, iterate over the 32 possible interrupts */
for (x = 0; x < ESP_INTC_INTS_NUM; x++) {
for (x = 0; x < SOC_CPU_INTR_NUM; x++) {
/* Grab the vector_desc for this vector. */
vd = find_desc_for_int(x, cpu);
if (vd == NULL) {
@ -409,12 +372,10 @@ static int get_available_int(int flags, int cpu, int force, int source) @@ -409,12 +372,10 @@ static int get_available_int(int flags, int cpu, int force, int source)
}
esp_cpu_intr_desc_t intr_desc;
esp_cpu_intr_get_desc(cpu, x, &intr_desc);
INTC_LOG("Int %d reserved %d level %d %s hasIsr %d",
x, intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD,
intr_desc.priority,
x, intr_desc.flags & ESP_CPU_INTR_DESC_FLAG_RESVD, intr_desc.priority,
intr_desc.type == ESP_CPU_INTR_TYPE_LEVEL ? "LEVEL" : "EDGE",
intr_has_handler(x, cpu));
@ -438,7 +399,8 @@ static int get_available_int(int flags, int cpu, int force, int source) @@ -438,7 +399,8 @@ static int get_available_int(int flags, int cpu, int force, int source)
no++;
svdesc = svdesc->next;
}
if (no < best_shared_ct || best_level > intr_desc.priority) {
if (no < best_shared_ct ||
best_level > intr_desc.priority) {
/*
* Seems like this shared vector is both okay and has
* the least amount of ISRs already attached to it.
@ -500,8 +462,7 @@ static void IRAM_ATTR shared_intr_isr(void *arg) @@ -500,8 +462,7 @@ static void IRAM_ATTR shared_intr_isr(void *arg)
esp_intr_lock();
while (sh_vec) {
if (!sh_vec->disabled) {
if ((sh_vec->statusreg == NULL) ||
(*sh_vec->statusreg & sh_vec->statusmask)) {
if (!(sh_vec->statusreg) || (*sh_vec->statusreg & sh_vec->statusmask)) {
sh_vec->isr(sh_vec->arg);
}
}
@ -516,9 +477,9 @@ int esp_intr_alloc_intrstatus(int source, @@ -516,9 +477,9 @@ int esp_intr_alloc_intrstatus(int source,
uint32_t intrstatusmask,
intr_handler_t handler,
void *arg,
struct intr_handle_data_t **ret_handle)
intr_handle_t *ret_handle)
{
struct intr_handle_data_t *ret = NULL;
intr_handle_data_t *ret = NULL;
int force = -1;
INTC_LOG("%s (cpu %d): checking args", __func__, esp_cpu_get_core_id());
@ -544,8 +505,8 @@ int esp_intr_alloc_intrstatus(int source, @@ -544,8 +505,8 @@ int esp_intr_alloc_intrstatus(int source,
* we need to make sure the interrupt is connected to the CPU0.
* CPU1 does not have access to the RTC fast memory through this region.
*/
if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) &&
!esp_ptr_in_rtc_iram_fast(handler)) {
if ((flags & ESP_INTR_FLAG_IRAM) && handler &&
!esp_ptr_in_iram(handler) && !esp_ptr_in_rtc_iram_fast(handler)) {
return -EINVAL;
}
@ -636,16 +597,20 @@ int esp_intr_alloc_intrstatus(int source, @@ -636,16 +597,20 @@ int esp_intr_alloc_intrstatus(int source,
sv->disabled = 0;
vd->shared_vec_info = sv;
vd->flags |= VECDESC_FL_SHARED;
/* Disable interrupt to avoid assert at IRQ install */
irq_disable(intr);
/* (Re-)set shared isr handler to new value. */
set_interrupt_handler(intr, shared_intr_isr, vd);
irq_connect_dynamic(intr, 0, (intc_dyn_handler_t)shared_intr_isr, vd, 0);
} else {
/* Mark as unusable for other interrupt sources. This is ours now! */
vd->flags = VECDESC_FL_NONSHARED;
if (handler) {
set_interrupt_handler(intr, handler, arg);
irq_connect_dynamic(intr, 0, (intc_dyn_handler_t)handler, arg, 0);
}
if (flags & ESP_INTR_FLAG_EDGE) {
xthal_set_intclear(1 << intr);
esp_cpu_intr_edge_ack(intr);
}
vd->source = source;
}
@ -675,10 +640,9 @@ int esp_intr_alloc_intrstatus(int source, @@ -675,10 +640,9 @@ int esp_intr_alloc_intrstatus(int source,
esp_intr_disable(ret);
}
#ifdef SOC_CPU_HAS_FLEXIBLE_INTC
#if SOC_CPU_HAS_FLEXIBLE_INTC
/* Extract the level from the interrupt passed flags */
int level = esp_intr_flags_to_level(flags);
esp_cpu_intr_set_priority(intr, level);
if (flags & ESP_INTR_FLAG_EDGE) {
@ -688,6 +652,11 @@ int esp_intr_alloc_intrstatus(int source, @@ -688,6 +652,11 @@ int esp_intr_alloc_intrstatus(int source,
}
#endif
#if SOC_INT_PLIC_SUPPORTED
/* Make sure the interrupt is not delegated to user mode (IDF uses machine mode only) */
RV_CLEAR_CSR(mideleg, BIT(intr));
#endif
esp_intr_unlock();
/* Fill return handle if needed, otherwise free handle. */
@ -698,6 +667,7 @@ int esp_intr_alloc_intrstatus(int source, @@ -698,6 +667,7 @@ int esp_intr_alloc_intrstatus(int source,
}
LOG_DBG("Connected src %d to int %d (cpu %d)", source, intr, cpu);
return 0;
}
@ -705,7 +675,7 @@ int esp_intr_alloc(int source, @@ -705,7 +675,7 @@ int esp_intr_alloc(int source,
int flags,
intr_handler_t handler,
void *arg,
struct intr_handle_data_t **ret_handle)
intr_handle_t *ret_handle)
{
/*
* As an optimization, we can create a table with the possible interrupt status
@ -715,7 +685,7 @@ int esp_intr_alloc(int source, @@ -715,7 +685,7 @@ int esp_intr_alloc(int source,
return esp_intr_alloc_intrstatus(source, flags, 0, 0, handler, arg, ret_handle);
}
int IRAM_ATTR esp_intr_set_in_iram(struct intr_handle_data_t *handle, bool is_in_iram)
int IRAM_ATTR esp_intr_set_in_iram(intr_handle_t handle, bool is_in_iram)
{
if (!handle) {
return -EINVAL;
@ -739,7 +709,7 @@ int IRAM_ATTR esp_intr_set_in_iram(struct intr_handle_data_t *handle, bool is_in @@ -739,7 +709,7 @@ int IRAM_ATTR esp_intr_set_in_iram(struct intr_handle_data_t *handle, bool is_in
return 0;
}
int esp_intr_free(struct intr_handle_data_t *handle)
int esp_intr_free(intr_handle_t handle)
{
bool free_shared_vector = false;
@ -780,18 +750,20 @@ int esp_intr_free(struct intr_handle_data_t *handle) @@ -780,18 +750,20 @@ int esp_intr_free(struct intr_handle_data_t *handle)
if ((handle->vector_desc->flags & VECDESC_FL_NONSHARED) || free_shared_vector) {
INTC_LOG("%s: Disabling int, killing handler", __func__);
/* Reset to normal handler */
set_interrupt_handler(handle->vector_desc->intno,
default_intr_handler,
(void *)((int)handle->vector_desc->intno));
/* Disable interrupt to avoid assert at IRQ install */
irq_disable(handle->vector_desc->intno);
/* Reset IRQ handler */
irq_connect_dynamic(handle->vector_desc->intno, 0,
(intc_dyn_handler_t)z_irq_spurious,
(void *)((int)handle->vector_desc->intno), 0);
/*
* Theoretically, we could free the vector_desc... not sure if that's worth the
* few bytes of memory we save.(We can also not use the same exit path for empty
* shared ints anymore if we delete the desc.) For now, just mark it as free.
*/
handle->vector_desc->flags &= ~(VECDESC_FL_NONSHARED |
VECDESC_FL_RESERVED | VECDESC_FL_SHARED);
handle->vector_desc->flags &= !(VECDESC_FL_NONSHARED | VECDESC_FL_RESERVED);
/* Also kill non_iram mask bit. */
non_iram_int_mask[handle->vector_desc->cpu] &= ~(1 << (handle->vector_desc->intno));
}
@ -800,12 +772,12 @@ int esp_intr_free(struct intr_handle_data_t *handle) @@ -800,12 +772,12 @@ int esp_intr_free(struct intr_handle_data_t *handle)
return 0;
}
int esp_intr_get_intno(struct intr_handle_data_t *handle)
int esp_intr_get_intno(intr_handle_t handle)
{
return handle->vector_desc->intno;
}
int esp_intr_get_cpu(struct intr_handle_data_t *handle)
int esp_intr_get_cpu(intr_handle_t handle)
{
return handle->vector_desc->cpu;
}
@ -824,7 +796,7 @@ int esp_intr_get_cpu(struct intr_handle_data_t *handle) @@ -824,7 +796,7 @@ int esp_intr_get_cpu(struct intr_handle_data_t *handle)
*/
#define INT_MUX_DISABLED_INTNO 6
int IRAM_ATTR esp_intr_enable(struct intr_handle_data_t *handle)
int IRAM_ATTR esp_intr_enable(intr_handle_t handle)
{
if (!handle) {
return -EINVAL;
@ -840,8 +812,8 @@ int IRAM_ATTR esp_intr_enable(struct intr_handle_data_t *handle) @@ -840,8 +812,8 @@ int IRAM_ATTR esp_intr_enable(struct intr_handle_data_t *handle)
}
if (source >= 0) {
/* Disabled using int matrix; re-connect to enable */
esp_rom_route_intr_matrix(handle->vector_desc->cpu,
source, handle->vector_desc->intno);
esp_rom_route_intr_matrix(handle->vector_desc->cpu, source,
handle->vector_desc->intno);
} else {
/* Re-enable using cpu int ena reg */
if (handle->vector_desc->cpu != esp_cpu_get_core_id()) {
@ -854,7 +826,7 @@ int IRAM_ATTR esp_intr_enable(struct intr_handle_data_t *handle) @@ -854,7 +826,7 @@ int IRAM_ATTR esp_intr_enable(struct intr_handle_data_t *handle)
return 0;
}
int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle)
int IRAM_ATTR esp_intr_disable(intr_handle_t handle)
{
if (!handle) {
return -EINVAL;
@ -884,8 +856,8 @@ int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle) @@ -884,8 +856,8 @@ int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle)
if (source >= 0) {
if (disabled) {
/* Disable using int matrix */
esp_rom_route_intr_matrix(handle->vector_desc->cpu,
source, INT_MUX_DISABLED_INTNO);
esp_rom_route_intr_matrix(handle->vector_desc->cpu, source,
INT_MUX_DISABLED_INTNO);
}
} else {
/* Disable using per-cpu regs */
@ -899,7 +871,6 @@ int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle) @@ -899,7 +871,6 @@ int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle)
return 0;
}
void IRAM_ATTR esp_intr_noniram_disable(void)
{
esp_intr_lock();
@ -914,6 +885,7 @@ void IRAM_ATTR esp_intr_noniram_disable(void) @@ -914,6 +885,7 @@ void IRAM_ATTR esp_intr_noniram_disable(void)
oldint = esp_cpu_intr_get_enabled_mask();
esp_cpu_intr_disable(non_iram_ints);
rtc_isr_noniram_disable(cpu);
/* Save which ints we did disable */
non_iram_int_disabled[cpu] = oldint & non_iram_ints;
esp_intr_unlock();
}
@ -932,3 +904,29 @@ void IRAM_ATTR esp_intr_noniram_enable(void) @@ -932,3 +904,29 @@ void IRAM_ATTR esp_intr_noniram_enable(void)
rtc_isr_noniram_enable(cpu);
esp_intr_unlock();
}
#if defined(CONFIG_RISCV)
/*
* Functions below are implemented to keep consistency with current
* Xtensa chips API behavior. When accessing Zephyr's API
* directly, the CPU IRQs can be enabled or disabled directly. This
* is mostly used to control lines that are not muxed, thus bypass the
* interrupt matrix. For RISCV, these functions are not expected to
* be used via user API, as peripherals are all routed through INTMUX
* and shared interrupts require managing sources state.
*/
void arch_irq_enable(unsigned int irq)
{
esp_cpu_intr_enable(1 << irq);
}
void arch_irq_disable(unsigned int irq)
{
esp_cpu_intr_disable(1 << irq);
}
int arch_irq_is_enabled(unsigned int irq)
{
return !!(esp_cpu_intr_get_enabled_mask() & (1 << irq));
}
#endif

277
drivers/interrupt_controller/intc_esp32c3.c

@ -1,277 +0,0 @@ @@ -1,277 +0,0 @@
/*
* Copyright (c) 2021-2025 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <soc/periph_defs.h>
#include <limits.h>
#include <assert.h>
#include "soc/soc.h"
#include <soc.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
#include <zephyr/sw_isr_table.h>
#include <riscv/interrupt.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(intc_esp32, CONFIG_LOG_DEFAULT_LEVEL);
/*
* Define this to debug the choices made when allocating the interrupt. This leads to much debugging
* output within a critical region, which can lead to weird effects like e.g. the interrupt watchdog
* being triggered, that is why it is separate from the normal LOG* scheme.
*/
#ifdef CONFIG_INTC_ESP32C3_DECISIONS_LOG
# define INTC_LOG(...) LOG_INF(__VA_ARGS__)
#else
# define INTC_LOG(...) do {} while (0)
#endif
#define ESP32_INTC_DEFAULT_PRIORITY 15
#define ESP32_INTC_DEFAULT_THRESHOLD 1
#define ESP32_INTC_DISABLED_SLOT 31
#define ESP32_INTC_SRCS_PER_IRQ 2
/* Define maximum interrupt sources per SoC */
#if defined(CONFIG_SOC_SERIES_ESP32C6)
/*
* Interrupt reserved mask
* 0 is reserved
* 1 is for Wi-Fi
* 3, 4 and 7 are unavailable for PULP CPU as they are bound to Core-Local Interrupts (CLINT)
*/
#define RSVD_MASK (BIT(0) | BIT(1) | BIT(3) | BIT(4) | BIT(7))
#define ESP_INTC_AVAILABLE_IRQS 31
#else
/*
* Interrupt reserved mask
* 1 is for Wi-Fi
*/
#define RSVD_MASK (BIT(0) | BIT(1))
#define ESP_INTC_AVAILABLE_IRQS 30
#endif
/* Single array for IRQ allocation */
static uint8_t esp_intr_irq_alloc[ESP_INTC_AVAILABLE_IRQS * ESP32_INTC_SRCS_PER_IRQ];
#define ESP_INTR_IDX(irq, slot) ((irq % ESP_INTC_AVAILABLE_IRQS) * ESP32_INTC_SRCS_PER_IRQ + slot)
#define STATUS_MASK_NUM 3
static uint32_t esp_intr_enabled_mask[STATUS_MASK_NUM] = {0, 0, 0};
static uint32_t esp_intr_find_irq_for_source(uint32_t source)
{
if (source >= ETS_MAX_INTR_SOURCE) {
return IRQ_NA;
}
uint32_t irq = source / ESP32_INTC_SRCS_PER_IRQ;
/* Check if the derived IRQ is usable first */
for (int j = 0; j < ESP32_INTC_SRCS_PER_IRQ; j++) {
int idx = ESP_INTR_IDX(irq, j);
/* Ensure idx is within a valid range */
if (idx >= ARRAY_SIZE(esp_intr_irq_alloc)) {
continue;
}
/* If source is already assigned, return the IRQ */
if (esp_intr_irq_alloc[idx] == source) {
return irq;
}
/* If slot is free, allocate it */
if (esp_intr_irq_alloc[idx] == IRQ_FREE) {
esp_intr_irq_alloc[idx] = source;
return irq;
}
}
/* If derived IRQ is full, search for another available IRQ */
for (irq = 0; irq < ESP_INTC_AVAILABLE_IRQS; irq++) {
if (RSVD_MASK & (1U << irq)) {
continue;
}
for (int j = 0; j < ESP32_INTC_SRCS_PER_IRQ; j++) {
int idx = ESP_INTR_IDX(irq, j);
/* Ensure idx is within a valid range */
if (idx >= ARRAY_SIZE(esp_intr_irq_alloc)) {
continue;
}
/* If source is already assigned, return this IRQ */
if (esp_intr_irq_alloc[idx] == source) {
return irq;
}
/* If slot is free, allocate it */
if (esp_intr_irq_alloc[idx] == IRQ_FREE) {
esp_intr_irq_alloc[idx] = source;
return irq;
}
}
}
/* No available slot found */
return IRQ_NA;
}
void esp_intr_initialize(void)
{
for (int i = 0; i < ETS_MAX_INTR_SOURCE; i++) {
esp_rom_intr_matrix_set(0, i, ESP32_INTC_DISABLED_SLOT);
}
for (int irq = 0; irq < ESP_INTC_AVAILABLE_IRQS; irq++) {
for (int j = 0; j < ESP32_INTC_SRCS_PER_IRQ; j++) {
int idx = ESP_INTR_IDX(irq, j);
if (RSVD_MASK & (1U << irq)) {
esp_intr_irq_alloc[idx] = IRQ_NA;
} else {
esp_intr_irq_alloc[idx] = IRQ_FREE;
}
}
}
/* set global INTC masking level */
esprv_intc_int_set_threshold(ESP32_INTC_DEFAULT_THRESHOLD);
}
int esp_intr_alloc(int source,
int flags,
isr_handler_t handler,
void *arg,
void **ret_handle)
{
ARG_UNUSED(flags);
ARG_UNUSED(ret_handle);
if (handler == NULL) {
return -EINVAL;
}
if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
return -EINVAL;
}
uint32_t key = irq_lock();
uint32_t irq = esp_intr_find_irq_for_source(source);
if (irq == IRQ_NA) {
irq_unlock(key);
return -ENOMEM;
}
irq_connect_dynamic(source,
ESP32_INTC_DEFAULT_PRIORITY,
handler,
arg,
0);
INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X -- 2: 0x%X",
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1], esp_intr_enabled_mask[2]);
irq_unlock(key);
int ret = esp_intr_enable(source);
return ret;
}
int esp_intr_disable(int source)
{
if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
return -EINVAL;
}
uint32_t key = irq_lock();
esp_rom_intr_matrix_set(0,
source,
ESP32_INTC_DISABLED_SLOT);
for (int i = 0; i < ESP_INTC_AVAILABLE_IRQS; i++) {
if (RSVD_MASK & (1U << i)) {
continue;
}
for (int j = 0; j < ESP32_INTC_SRCS_PER_IRQ; j++) {
int idx = ESP_INTR_IDX(i, j);
if (esp_intr_irq_alloc[idx] == source) {
esp_intr_irq_alloc[idx] = IRQ_FREE;
}
}
}
if (source < 32) {
esp_intr_enabled_mask[0] &= ~(1 << source);
} else if (source < 64) {
esp_intr_enabled_mask[1] &= ~(1 << (source - 32));
} else if (source < 96) {
esp_intr_enabled_mask[2] &= ~(1 << (source - 64));
}
INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X -- 2: 0x%X",
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1], esp_intr_enabled_mask[2]);
irq_unlock(key);
return 0;
}
int esp_intr_enable(int source)
{
if (source < 0 || source >= ETS_MAX_INTR_SOURCE) {
return -EINVAL;
}
uint32_t key = irq_lock();
uint32_t irq = esp_intr_find_irq_for_source(source);
if (irq == IRQ_NA) {
irq_unlock(key);
return -ENOMEM;
}
esp_rom_intr_matrix_set(0, source, irq);
if (source < 32) {
esp_intr_enabled_mask[0] |= (1 << source);
} else if (source < 64) {
esp_intr_enabled_mask[1] |= (1 << (source - 32));
} else if (source < 96) {
esp_intr_enabled_mask[2] |= (1 << (source - 64));
}
INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X -- 2: 0x%X",
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1], esp_intr_enabled_mask[2]);
esprv_intc_int_set_priority(irq, ESP32_INTC_DEFAULT_PRIORITY);
esprv_intc_int_set_type(irq, INTR_TYPE_LEVEL);
esprv_intc_int_enable(1 << irq);
irq_unlock(key);
return 0;
}
uint32_t esp_intr_get_enabled_intmask(int status_mask_number)
{
INTC_LOG("Enabled ISRs -- 0: 0x%X -- 1: 0x%X -- 2: 0x%X",
esp_intr_enabled_mask[0], esp_intr_enabled_mask[1], esp_intr_enabled_mask[2]);
if (status_mask_number < STATUS_MASK_NUM) {
return esp_intr_enabled_mask[status_mask_number];
}
return 0;
}

36
include/zephyr/drivers/interrupt_controller/intc_esp32.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
* Copyright (c) 2021-2025 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -10,9 +10,6 @@ @@ -10,9 +10,6 @@
#include <stdint.h>
#include <stdbool.h>
/* number of possible interrupts per core */
#define ESP_INTC_INTS_NUM (32)
/*
* Interrupt allocation flags - These flags can be used to specify
* which interrupt qualities the code calling esp_intr_alloc* needs.
@ -71,6 +68,12 @@ @@ -71,6 +68,12 @@
/* Function prototype for interrupt handler function */
typedef void (*intr_handler_t)(void *arg);
/* Interrupt handler associated data structure */
typedef struct intr_handle_data_t intr_handle_data_t;
/* Handle to an interrupt handler */
typedef intr_handle_data_t *intr_handle_t;
struct shared_vector_desc_t {
int disabled : 1;
int source : 8;
@ -97,11 +100,6 @@ struct intr_handle_data_t { @@ -97,11 +100,6 @@ struct intr_handle_data_t {
struct shared_vector_desc_t *shared_vector_desc;
};
/**
* @brief Initializes interrupt table to its defaults
*/
void esp_intr_initialize(void);
/**
* @brief Mark an interrupt as a shared interrupt
*
@ -158,7 +156,7 @@ int esp_intr_reserve(int intno, int cpu); @@ -158,7 +156,7 @@ int esp_intr_reserve(int intno, int cpu);
* @param handler The interrupt handler. Must be NULL when an interrupt of level >3
* is requested, because these types of interrupts aren't C-callable.
* @param arg Optional argument for passed to the interrupt handler
* @param ret_handle Pointer to a struct intr_handle_data_t pointer to store a handle that can
* @param ret_handle Pointer to an intr_handle_t pointer to store a handle that can
* later be used to request details or free the interrupt. Can be NULL if no handle
* is required.
*
@ -170,7 +168,7 @@ int esp_intr_alloc(int source, @@ -170,7 +168,7 @@ int esp_intr_alloc(int source,
int flags,
intr_handler_t handler,
void *arg,
struct intr_handle_data_t **ret_handle);
intr_handle_t *ret_handle);
/**
@ -200,7 +198,7 @@ int esp_intr_alloc(int source, @@ -200,7 +198,7 @@ int esp_intr_alloc(int source,
* @param handler The interrupt handler. Must be NULL when an interrupt of level >3
* is requested, because these types of interrupts aren't C-callable.
* @param arg Optional argument for passed to the interrupt handler
* @param ret_handle Pointer to a struct intr_handle_data_t pointer to store a handle that can
* @param ret_handle Pointer to an intr_handle_t pointer to store a handle that can
* later be used to request details or free the interrupt. Can be NULL if no handle
* is required.
*
@ -214,7 +212,7 @@ int esp_intr_alloc_intrstatus(int source, @@ -214,7 +212,7 @@ int esp_intr_alloc_intrstatus(int source,
uint32_t intrstatusmask,
intr_handler_t handler,
void *arg,
struct intr_handle_data_t **ret_handle);
intr_handle_t *ret_handle);
/**
@ -235,7 +233,7 @@ int esp_intr_alloc_intrstatus(int source, @@ -235,7 +233,7 @@ int esp_intr_alloc_intrstatus(int source,
* @return -EINVAL the handle is NULL
* 0 otherwise
*/
int esp_intr_free(struct intr_handle_data_t *handle);
int esp_intr_free(intr_handle_t handle);
/**
@ -245,7 +243,7 @@ int esp_intr_free(struct intr_handle_data_t *handle); @@ -245,7 +243,7 @@ int esp_intr_free(struct intr_handle_data_t *handle);
*
* @return The core number where the interrupt is allocated
*/
int esp_intr_get_cpu(struct intr_handle_data_t *handle);
int esp_intr_get_cpu(intr_handle_t handle);
/**
* @brief Get the allocated interrupt for a certain handle
@ -254,7 +252,7 @@ int esp_intr_get_cpu(struct intr_handle_data_t *handle); @@ -254,7 +252,7 @@ int esp_intr_get_cpu(struct intr_handle_data_t *handle);
*
* @return The interrupt number
*/
int esp_intr_get_intno(struct intr_handle_data_t *handle);
int esp_intr_get_intno(intr_handle_t handle);
/**
* @brief Disable the interrupt associated with the handle
@ -272,7 +270,7 @@ int esp_intr_get_intno(struct intr_handle_data_t *handle); @@ -272,7 +270,7 @@ int esp_intr_get_intno(struct intr_handle_data_t *handle);
* @return -EINVAL if the combination of arguments is invalid.
* 0 otherwise
*/
int esp_intr_disable(struct intr_handle_data_t *handle);
int esp_intr_disable(intr_handle_t handle);
/**
* @brief Enable the interrupt associated with the handle
@ -285,7 +283,7 @@ int esp_intr_disable(struct intr_handle_data_t *handle); @@ -285,7 +283,7 @@ int esp_intr_disable(struct intr_handle_data_t *handle);
* @return -EINVAL if the combination of arguments is invalid.
* 0 otherwise
*/
int esp_intr_enable(struct intr_handle_data_t *handle);
int esp_intr_enable(intr_handle_t handle);
/**
* @brief Set the "in IRAM" status of the handler.
@ -299,7 +297,7 @@ int esp_intr_enable(struct intr_handle_data_t *handle); @@ -299,7 +297,7 @@ int esp_intr_enable(struct intr_handle_data_t *handle);
* @return -EINVAL if the combination of arguments is invalid.
* 0 otherwise
*/
int esp_intr_set_in_iram(struct intr_handle_data_t *handle, bool is_in_iram);
int esp_intr_set_in_iram(intr_handle_t handle, bool is_in_iram);
/**
* @brief Disable interrupts that aren't specifically marked as running from IRAM

124
include/zephyr/drivers/interrupt_controller/intc_esp32c3.h

@ -1,124 +0,0 @@ @@ -1,124 +0,0 @@
/*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_INTERRUPT_CONTROLLER_INTC_ESP32C3_H_
#define ZEPHYR_INCLUDE_DRIVERS_INTERRUPT_CONTROLLER_INTC_ESP32C3_H_
#include <stdint.h>
#include <stdbool.h>
#include <soc.h>
/*
* Interrupt allocation flags - These flags can be used to specify
* which interrupt qualities the code calling esp_intr_alloc* needs.
*/
/* Keep the LEVELx values as they are here; they match up with (1<<level) */
#define ESP_INTR_FLAG_LEVEL1 (1<<1) /* Accept a Level 1 int vector, lowest priority */
#define ESP_INTR_FLAG_LEVEL2 (1<<2) /* Accept a Level 2 int vector */
#define ESP_INTR_FLAG_LEVEL3 (1<<3) /* Accept a Level 3 int vector */
#define ESP_INTR_FLAG_LEVEL4 (1<<4) /* Accept a Level 4 int vector */
#define ESP_INTR_FLAG_LEVEL5 (1<<5) /* Accept a Level 5 int vector */
#define ESP_INTR_FLAG_LEVEL6 (1<<6) /* Accept a Level 6 int vector */
#define ESP_INTR_FLAG_NMI (1<<7) /* Accept a Level 7 int vector, highest priority */
#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */
#define ESP_INTR_FLAG_EDGE (1<<9) /* Edge-triggered interrupt */
#define ESP_INTR_FLAG_IRAM (1<<10) /* ISR can be called if cache is disabled */
#define ESP_INTR_FLAG_INTRDISABLED (1<<11) /* Return with this interrupt disabled */
/* Low and medium prio interrupts. These can be handled in C. */
#define ESP_INTR_FLAG_LOWMED (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3)
/* High level interrupts. Need to be handled in assembly. */
#define ESP_INTR_FLAG_HIGH (ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6| \
ESP_INTR_FLAG_NMI)
/* Mask for all level flags */
#define ESP_INTR_FLAG_LEVELMASK (ESP_INTR_FLAG_LEVEL1|ESP_INTR_FLAG_LEVEL2|ESP_INTR_FLAG_LEVEL3| \
ESP_INTR_FLAG_LEVEL4|ESP_INTR_FLAG_LEVEL5|ESP_INTR_FLAG_LEVEL6| \
ESP_INTR_FLAG_NMI)
#define IRQ_NA 0xFF /* IRQ not available */
#define IRQ_FREE 0xFE /* IRQ available for use */
/*
* Get the interrupt flags from the supplied priority.
*/
#define ESP_PRIO_TO_FLAGS(priority) \
((priority) > 0 ? ((1 << (priority)) & ESP_INTR_FLAG_LEVELMASK) : 0)
/*
* Check interrupt flags from input and filter unallowed values.
*/
#define ESP_INT_FLAGS_CHECK(int_flags) ((int_flags) & ESP_INTR_FLAG_SHARED)
/* Function prototype for interrupt handler function */
typedef void (*isr_handler_t)(const void *arg);
/**
* @brief Initializes interrupt table to its defaults
*/
void esp_intr_initialize(void);
/**
* @brief Allocate an interrupt with the given parameters.
*
* This finds an interrupt that matches the restrictions as given in the flags
* parameter, maps the given interrupt source to it and hooks up the given
* interrupt handler (with optional argument) as well. If needed, it can return
* a handle for the interrupt as well.
*
* @param source The interrupt source.
* @param flags An ORred mask of the ESP_INTR_FLAG_* defines. These restrict the
* choice of interrupts that this routine can choose from. If this value
* is 0, it will default to allocating a non-shared interrupt of level
* 1, 2 or 3. If this is ESP_INTR_FLAG_SHARED, it will allocate a shared
* interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return
* from this function with the interrupt disabled.
* @param handler The interrupt handler.
* @param arg Optional argument for passed to the interrupt handler
* @param ret_handle Pointer to a struct intr_handle_data_t pointer to store a handle that can
* later be used to request details or free the interrupt. Can be NULL if no handle
* is required.
*
* @return -EINVAL if the combination of arguments is invalid.
* -ENODEV No free interrupt found with the specified flags
* 0 otherwise
*/
int esp_intr_alloc(int source,
int flags,
isr_handler_t handler,
void *arg,
void **ret_handle);
/**
* @brief Disable the interrupt associated with the source
*
* @param source The interrupt source
*
* @return -EINVAL if the combination of arguments is invalid.
* 0 otherwise
*/
int esp_intr_disable(int source);
/**
* @brief Enable the interrupt associated with the source
*
* @param source The interrupt source
* @return -EINVAL if the combination of arguments is invalid.
* 0 otherwise
*/
int esp_intr_enable(int source);
/**
* @brief Gets the current enabled interrupts
*
* @param status_mask_number the status mask can be 0 or 1
* @return bitmask of enabled interrupt sources
*/
uint32_t esp_intr_get_enabled_intmask(int status_mask_number);
#endif /* ZEPHYR_INCLUDE_DRIVERS_INTERRUPT_CONTROLLER_INTC_ESP32C3_H_ */

7
include/zephyr/dt-bindings/interrupt-controller/esp-esp32c2-intmux.h

@ -51,11 +51,8 @@ @@ -51,11 +51,8 @@
#define CORE0_PIF_PMS_SIZE_INTR_SOURCE 41
#define CACHE_CORE0_ACS_INTR_SOURCE 42
/* RISC-V supports priority values from 1 (lowest) to 15.
* As interrupt controller for Xtensa and RISC-V is shared, this is
* set to an intermediate and compatible value.
*/
#define IRQ_DEFAULT_PRIORITY 3
/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */
#define IRQ_DEFAULT_PRIORITY 0
#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */

7
include/zephyr/dt-bindings/interrupt-controller/esp-esp32c3-intmux.h

@ -70,11 +70,8 @@ @@ -70,11 +70,8 @@
#define BAK_PMS_VIOLATE_INTR_SOURCE 60
#define CACHE_CORE0_ACS_INTR_SOURCE 61
/* RISC-V supports priority values from 1 (lowest) to 15.
* As interrupt controller for Xtensa and RISC-V is shared, this is
* set to an intermediate and compatible value.
*/
#define IRQ_DEFAULT_PRIORITY 3
/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */
#define IRQ_DEFAULT_PRIORITY 0
#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */

7
include/zephyr/dt-bindings/interrupt-controller/esp-esp32c6-intmux.h

@ -86,11 +86,8 @@ @@ -86,11 +86,8 @@
#define ECC_INTR_SOURCE 76 /* interrupt of ECC accelerator, level*/
#define MAX_INTR_SOURCE 77
/* RISC-V supports priority values from 1 (lowest) to 15.
* As interrupt controller for Xtensa and RISC-V is shared, this is
* set to an intermediate and compatible value.
*/
#define IRQ_DEFAULT_PRIORITY 3
/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */
#define IRQ_DEFAULT_PRIORITY 0
#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */

4
include/zephyr/dt-bindings/interrupt-controller/esp-xtensa-intmux.h

@ -79,9 +79,7 @@ @@ -79,9 +79,7 @@
#define CACHE_IA_INTR_SOURCE 68 /* Cache Invalid Access, LEVEL */
#define MAX_INTR_SOURCE 69 /* total number of interrupt sources */
/* For Xtensa architecture, zero will allocate low/medium
* levels of priority (ESP_INTR_FLAG_LOWMED)
*/
/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */
#define IRQ_DEFAULT_PRIORITY 0
#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */

4
include/zephyr/dt-bindings/interrupt-controller/esp32s2-xtensa-intmux.h

@ -106,9 +106,7 @@ @@ -106,9 +106,7 @@
#define ICACHE_SYNC_INTR_SOURCE 94 /* instruction cache sync done, level */
#define MAX_INTR_SOURCE 95 /* total number of interrupt sources */
/* For Xtensa architecture, zero will allocate low/medium
* levels of priority (ESP_INTR_FLAG_LOWMED)
*/
/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */
#define IRQ_DEFAULT_PRIORITY 0
#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */

4
include/zephyr/dt-bindings/interrupt-controller/esp32s3-xtensa-intmux.h

@ -104,9 +104,7 @@ @@ -104,9 +104,7 @@
#define DMA_EXTMEM_REJECT_SOURCE 98
#define MAX_INTR_SOURCE 99 /* number of interrupt sources */
/* For Xtensa architecture, zero will allocate low/medium
* levels of priority (ESP_INTR_FLAG_LOWMED)
*/
/* Zero will allocate low/medium levels of priority (ESP_INTR_FLAG_LOWMED) */
#define IRQ_DEFAULT_PRIORITY 0
#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */

Loading…
Cancel
Save