/*
 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <soc.h>
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
#include "esp_attr.h"
#include <hal/cpu_hal.h>
#include <hal/interrupt_controller_hal.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);

#define ETS_INTERNAL_TIMER0_INTR_NO 6
#define ETS_INTERNAL_TIMER1_INTR_NO 15
#define ETS_INTERNAL_TIMER2_INTR_NO 16
#define ETS_INTERNAL_SW0_INTR_NO 7
#define ETS_INTERNAL_SW1_INTR_NO 29
#define ETS_INTERNAL_PROFILING_INTR_NO 11

#define VECDESC_FL_RESERVED     (1 << 0)
#define VECDESC_FL_INIRAM       (1 << 1)
#define VECDESC_FL_SHARED       (1 << 2)
#define VECDESC_FL_NONSHARED    (1 << 3)

/*
 * 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_ESP32_DECISIONS_LOG
# define INTC_LOG(...) LOG_INF(__VA_ARGS__)
#else
# define INTC_LOG(...) do {} while (false)
#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 */
static int esp_intc_csec;

static inline void esp_intr_lock(void)
{
	esp_intc_csec = irq_lock();
}

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 default_intr_handler(void *arg)
{
	printk("Unhandled interrupt %d on cpu %d!\n", (int)arg, esp_core_id());
}

static struct intr_alloc_table_entry intr_alloc_table[ESP_INTC_INTS_NUM * CONFIG_MP_NUM_CPUS];

static void set_interrupt_handler(int n, intc_handler_t f, void *arg)
{
	irq_disable(n);
	intr_alloc_table[n * CONFIG_MP_NUM_CPUS].handler = f;
	irq_connect_dynamic(n, n, (intc_dyn_handler_t)f, arg, 0);
	irq_enable(n);
}

/* Linked list of vector descriptions, sorted by cpu.intno value */
static struct vector_desc_t *vector_desc_head; /* implicitly initialized to NULL */

/* This bitmask has an 1 if the int should be disabled when the flash is disabled. */
static uint32_t non_iram_int_mask[CONFIG_MP_NUM_CPUS];
/* This bitmask has 1 in it if the int was disabled using esp_intr_noniram_disable. */
static uint32_t non_iram_int_disabled[CONFIG_MP_NUM_CPUS];
static bool non_iram_int_disabled_flag[CONFIG_MP_NUM_CPUS];

/*
 * Inserts an item into vector_desc list so that the list is sorted
 * with an incrementing cpu.intno value.
 */
static void insert_vector_desc(struct vector_desc_t *to_insert)
{
	struct vector_desc_t *vd = vector_desc_head;
	struct vector_desc_t *prev = NULL;

	while (vd != NULL) {
		if (vd->cpu > to_insert->cpu) {
			break;
		}
		if (vd->cpu == to_insert->cpu && vd->intno >= to_insert->intno) {
			break;
		}
		prev = vd;
		vd = vd->next;
	}
	if ((vector_desc_head == NULL) || (prev == NULL)) {
		/* First item */
		to_insert->next = vd;
		vector_desc_head = to_insert;
	} else {
		prev->next = to_insert;
		to_insert->next = vd;
	}
}

/* Returns a vector_desc entry for an intno/cpu, or NULL if none exists. */
static struct vector_desc_t *find_desc_for_int(int intno, int cpu)
{
	struct vector_desc_t *vd = vector_desc_head;

	while (vd != NULL) {
		if (vd->cpu == cpu && vd->intno == intno) {
			break;
		}
		vd = vd->next;
	}
	return vd;
}

/*
 * Returns a vector_desc entry for an intno/cpu.
 * Either returns a preexisting one or allocates a new one and inserts
 * it into the list. Returns NULL on malloc fail.
 */
static struct vector_desc_t *get_desc_for_int(int intno, int cpu)
{
	struct vector_desc_t *vd = find_desc_for_int(intno, cpu);

	if (vd == NULL) {
		struct vector_desc_t *newvd = k_malloc(sizeof(struct vector_desc_t));

		if (newvd == NULL) {
			return NULL;
		}
		memset(newvd, 0, sizeof(struct vector_desc_t));
		newvd->intno = intno;
		newvd->cpu = cpu;
		insert_vector_desc(newvd);
		return newvd;
	} else {
		return vd;
	}
}

/*
 * Returns a vector_desc entry for an source, the cpu parameter is used
 * to tell GPIO_INT and GPIO_NMI from different CPUs
 */
static struct vector_desc_t *find_desc_for_source(int source, int cpu)
{
	struct vector_desc_t *vd = vector_desc_head;

	while (vd != NULL) {
		if (!(vd->flags & VECDESC_FL_SHARED)) {
			if (vd->source == source && cpu == vd->cpu) {
				break;
			}
		} else if (vd->cpu == cpu) {
			/* check only shared vds for the correct cpu, otherwise skip */
			bool found = false;
			struct shared_vector_desc_t *svd = vd->shared_vec_info;

			assert(svd != NULL);
			while (svd) {
				if (svd->source == source) {
					found = true;
					break;
				}
				svd = svd->next;
			}
			if (found) {
				break;
			}
		}
		vd = vd->next;
	}
	return vd;
}

void esp_intr_initialize(void)
{
	for (size_t i = 0; i < (ESP_INTC_INTS_NUM * CONFIG_MP_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) {
		return -EINVAL;
	}
	if (cpu >= CONFIG_MP_NUM_CPUS) {
		return -EINVAL;
	}

	esp_intr_lock();
	struct vector_desc_t *vd = get_desc_for_int(intno, cpu);

	if (vd == NULL) {
		esp_intr_unlock();
		return -ENOMEM;
	}
	vd->flags = VECDESC_FL_SHARED;
	if (is_int_ram) {
		vd->flags |= VECDESC_FL_INIRAM;
	}
	esp_intr_unlock();

	return 0;
}

int esp_intr_reserve(int intno, int cpu)
{
	if (intno >= ESP_INTC_INTS_NUM) {
		return -EINVAL;
	}
	if (cpu >= CONFIG_MP_NUM_CPUS) {
		return -EINVAL;
	}

	esp_intr_lock();
	struct vector_desc_t *vd = get_desc_for_int(intno, cpu);

	if (vd == NULL) {
		esp_intr_unlock();
		return -ENOMEM;
	}
	vd->flags = VECDESC_FL_RESERVED;
	esp_intr_unlock();

	return 0;
}

/* Returns true if handler for interrupt is not the default unhandled interrupt handler */
static bool intr_has_handler(int intr, int cpu)
{
	return (intr_alloc_table[intr * CONFIG_MP_NUM_CPUS + cpu].handler != default_intr_handler);
}

static bool is_vect_desc_usable(struct vector_desc_t *vd, int flags, int cpu, int force)
{
	/* Check if interrupt is not reserved by design */
	int x = vd->intno;

	if (interrupt_controller_hal_get_cpu_desc_flags(x, cpu) == INTDESC_RESVD) {
		INTC_LOG("....Unusable: reserved");
		return false;
	}
	if (interrupt_controller_hal_get_cpu_desc_flags(x, cpu) == INTDESC_SPECIAL && force == -1) {
		INTC_LOG("....Unusable: special-purpose int");
		return false;
	}
	/* Check if the interrupt level is acceptable */
	if (!(flags & (1 << interrupt_controller_hal_get_level(x)))) {
		INTC_LOG("....Unusable: incompatible level");
		return false;
	}
	/* check if edge/level type matches what we want */
	if (((flags & ESP_INTR_FLAG_EDGE) &&
		(interrupt_controller_hal_get_type(x) == INTTP_LEVEL)) ||
		(((!(flags & ESP_INTR_FLAG_EDGE)) &&
		(interrupt_controller_hal_get_type(x) == INTTP_EDGE)))) {
		INTC_LOG("....Unusable: incompatible trigger type");
		return false;
	}
	/* check if interrupt is reserved at runtime */
	if (vd->flags & VECDESC_FL_RESERVED) {
		INTC_LOG("....Unusable: reserved at runtime.");
		return false;
	}

	/* Ints can't be both shared and non-shared. */
	assert(!((vd->flags & VECDESC_FL_SHARED) && (vd->flags & VECDESC_FL_NONSHARED)));
	/* check if interrupt already is in use by a non-shared interrupt */
	if (vd->flags & VECDESC_FL_NONSHARED) {
		INTC_LOG("....Unusable: already in (non-shared) use.");
		return false;
	}
	/* check shared interrupt flags */
	if (vd->flags & VECDESC_FL_SHARED) {
		if (flags & ESP_INTR_FLAG_SHARED) {
			bool in_iram_flag = ((flags & ESP_INTR_FLAG_IRAM) != 0);
			bool desc_in_iram_flag = ((vd->flags & VECDESC_FL_INIRAM) != 0);
			/*
			 * Bail out if int is shared, but iram property
			 * doesn't match what we want.
			 */
			if ((vd->flags & VECDESC_FL_SHARED) &&
				(desc_in_iram_flag != in_iram_flag)) {
				INTC_LOG("....Unusable: shared but iram prop doesn't match");
				return false;
			}
		} else {
			/*
			 * We need an unshared IRQ; can't use shared ones;
			 * bail out if this is shared.
			 */
			INTC_LOG("...Unusable: int is shared, we need non-shared.");
			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;
	}

	return true;
}

/*
 * Locate a free interrupt compatible with the flags given.
 * The 'force' argument can be -1, or 0-31 to force checking a certain interrupt.
 * When a CPU is forced, the INTDESC_SPECIAL marked interrupts are also accepted.
 */
static int get_available_int(int flags, int cpu, int force, int source)
{
	int x;
	int best = -1;
	int best_level = 9;
	int best_shared_ct = INT_MAX;
	/* Default vector desc, for vectors not in the linked list */
	struct vector_desc_t empty_vect_desc;

	memset(&empty_vect_desc, 0, sizeof(struct vector_desc_t));


	/* Level defaults to any low/med interrupt */
	if (!(flags & ESP_INTR_FLAG_LEVELMASK)) {
		flags |= ESP_INTR_FLAG_LOWMED;
	}

	INTC_LOG("%s: try to find existing. Cpu: %d, Source: %d", __func__, cpu, source);
	struct vector_desc_t *vd = find_desc_for_source(source, cpu);

	if (vd) {
		/* if existing vd found, don't need to search any more. */
		INTC_LOG("%s: existing vd found. intno: %d", __func__, vd->intno);
		if (force != -1 && force != vd->intno) {
			INTC_LOG("%s: intr forced but not match existing. "
				 "existing intno: %d, force: %d", __func__, vd->intno, force);
		} else if (!is_vect_desc_usable(vd, flags, cpu, force)) {
			INTC_LOG("%s: existing vd invalid.", __func__);
		} else {
			best = vd->intno;
		}
		return best;
	}
	if (force != -1) {
		INTC_LOG("%s: try to find force. "
			 "Cpu: %d, Source: %d, Force: %d", __func__, cpu, source, force);
		/* if force assigned, don't need to search any more. */
		vd = find_desc_for_int(force, cpu);
		if (vd == NULL) {
			/* if existing vd not found, just check the default state for the intr. */
			empty_vect_desc.intno = force;
			vd = &empty_vect_desc;
		}
		if (is_vect_desc_usable(vd, flags, cpu, force)) {
			best = vd->intno;
		} else {
			INTC_LOG("%s: forced vd invalid.", __func__);
		}
		return best;
	}

	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++) {
		/* Grab the vector_desc for this vector. */
		vd = find_desc_for_int(x, cpu);
		if (vd == NULL) {
			empty_vect_desc.intno = x;
			vd = &empty_vect_desc;
		}

		INTC_LOG("Int %d reserved %d level %d %s hasIsr %d",
			 x,
			 interrupt_controller_hal_get_cpu_desc_flags(x, cpu) == INTDESC_RESVD,
			 interrupt_controller_hal_get_level(x),
			 interrupt_controller_hal_get_type(x) == INTTP_LEVEL ? "LEVEL" : "EDGE",
			 intr_has_handler(x, cpu));

		if (!is_vect_desc_usable(vd, flags, cpu, force)) {
			continue;
		}

		if (flags & ESP_INTR_FLAG_SHARED) {
			/* We're allocating a shared int. */

			/* See if int already is used as a shared interrupt. */
			if (vd->flags & VECDESC_FL_SHARED) {
				/*
				 * We can use this already-marked-as-shared interrupt. Count the
				 * already attached isrs in order to see how useful it is.
				 */
				int no = 0;
				struct shared_vector_desc_t *svdesc = vd->shared_vec_info;

				while (svdesc != NULL) {
					no++;
					svdesc = svdesc->next;
				}
				if (no < best_shared_ct ||
					best_level > interrupt_controller_hal_get_level(x)) {
					/*
					 * Seems like this shared vector is both okay and has
					 * the least amount of ISRs already attached to it.
					 */
					best = x;
					best_shared_ct = no;
					best_level = interrupt_controller_hal_get_level(x);
					INTC_LOG("...int %d more usable as a shared int: "
						 "has %d existing vectors", x, no);
				} else {
					INTC_LOG("...worse than int %d", best);
				}
			} else {
				if (best == -1) {
					/*
					 * We haven't found a feasible shared interrupt yet.
					 * This one is still free and usable, even if not
					 * marked as shared.
					 * Remember it in case we don't find any other shared
					 * interrupt that qualifies.
					 */
					if (best_level > interrupt_controller_hal_get_level(x)) {
						best = x;
						best_level = interrupt_controller_hal_get_level(x);
						INTC_LOG("...int %d usable as new shared int", x);
					}
				} else {
					INTC_LOG("...already have a shared int");
				}
			}
		} else {
			/*
			 * Seems this interrupt is feasible. Select it and break out of the loop
			 * No need to search further.
			 */
			if (best_level > interrupt_controller_hal_get_level(x)) {
				best = x;
				best_level = interrupt_controller_hal_get_level(x);
			} else {
				INTC_LOG("...worse than int %d", best);
			}
		}
	}
	INTC_LOG("%s: using int %d", __func__, best);

	/*
	 * By now we have looked at all potential interrupts and
	 * hopefully have selected the best one in best.
	 */
	return best;
}

/* Common shared isr handler. Chain-call all ISRs. */
static void IRAM_ATTR shared_intr_isr(void *arg)
{
	struct vector_desc_t *vd = (struct vector_desc_t *)arg;
	struct shared_vector_desc_t *sh_vec = vd->shared_vec_info;

	esp_intr_lock();
	while (sh_vec) {
		if (!sh_vec->disabled) {
			if (!(sh_vec->statusreg) || (*sh_vec->statusreg & sh_vec->statusmask)) {
				sh_vec->isr(sh_vec->arg);
			}
		}
		sh_vec = sh_vec->next;
	}
	esp_intr_unlock();
}

int esp_intr_alloc_intrstatus(int source,
			      int flags,
			      uint32_t intrstatusreg,
			      uint32_t intrstatusmask,
			      intr_handler_t handler,
			      void *arg,
			      struct intr_handle_data_t **ret_handle)
{
	struct intr_handle_data_t *ret = NULL;
	int force = -1;

	INTC_LOG("%s (cpu %d): checking args", __func__, esp_core_id());
	/* Shared interrupts should be level-triggered. */
	if ((flags & ESP_INTR_FLAG_SHARED) && (flags & ESP_INTR_FLAG_EDGE)) {
		return -EINVAL;
	}
	/* You can't set an handler / arg for a non-C-callable interrupt. */
	if ((flags & ESP_INTR_FLAG_HIGH) && (handler)) {
		return -EINVAL;
	}
	/* Shared ints should have handler and non-processor-local source */
	if ((flags & ESP_INTR_FLAG_SHARED) && (!handler || source < 0)) {
		return -EINVAL;
	}
	/* Statusreg should have a mask */
	if (intrstatusreg && !intrstatusmask) {
		return -EINVAL;
	}
	/*
	 * If the ISR is marked to be IRAM-resident, the handler must not be in the cached region
	 * If we are to allow placing interrupt handlers into the 0x400c0000—0x400c2000 region,
	 * 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) &&
	    (ptrdiff_t) handler >= SOC_RTC_IRAM_HIGH &&
	    (ptrdiff_t) handler < SOC_RTC_DATA_LOW) {
		return -EINVAL;
	}

	/*
	 * Default to prio 1 for shared interrupts.
	 * Default to prio 1, 2 or 3 for non-shared interrupts.
	 */
	if ((flags & ESP_INTR_FLAG_LEVELMASK) == 0) {
		if (flags & ESP_INTR_FLAG_SHARED) {
			flags |= ESP_INTR_FLAG_LEVEL1;
		} else {
			flags |= ESP_INTR_FLAG_LOWMED;
		}
	}
	INTC_LOG("%s (cpu %d): Args okay."
		"Resulting flags 0x%X", __func__, esp_core_id(), flags);

	/*
	 * Check 'special' interrupt sources. These are tied to one specific
	 * interrupt, so we have to force get_available_int to only look at that.
	 */
	switch (source) {
	case ETS_INTERNAL_TIMER0_INTR_SOURCE:
		force = ETS_INTERNAL_TIMER0_INTR_NO;
		break;
	case ETS_INTERNAL_TIMER1_INTR_SOURCE:
		force = ETS_INTERNAL_TIMER1_INTR_NO;
		break;
	case ETS_INTERNAL_TIMER2_INTR_SOURCE:
		force = ETS_INTERNAL_TIMER2_INTR_NO;
		break;
	case ETS_INTERNAL_SW0_INTR_SOURCE:
		force = ETS_INTERNAL_SW0_INTR_NO;
		break;
	case ETS_INTERNAL_SW1_INTR_SOURCE:
		force = ETS_INTERNAL_SW1_INTR_NO;
		break;
	case ETS_INTERNAL_PROFILING_INTR_SOURCE:
		force = ETS_INTERNAL_PROFILING_INTR_NO;
		break;
	default:
		break;
	}

	/* Allocate a return handle. If we end up not needing it, we'll free it later on. */
	ret = k_malloc(sizeof(struct intr_handle_data_t));
	if (ret == NULL) {
		return -ENOMEM;
	}

	esp_intr_lock();
	int cpu = esp_core_id();
	/* See if we can find an interrupt that matches the flags. */
	int intr = get_available_int(flags, cpu, force, source);

	if (intr == -1) {
		/* None found. Bail out. */
		esp_intr_unlock();
		k_free(ret);
		return -ENODEV;
	}
	/* Get an int vector desc for int. */
	struct vector_desc_t *vd = get_desc_for_int(intr, cpu);

	if (vd == NULL) {
		esp_intr_unlock();
		k_free(ret);
		return -ENOMEM;
	}

	/* Allocate that int! */
	if (flags & ESP_INTR_FLAG_SHARED) {
		/* Populate vector entry and add to linked list. */
		struct shared_vector_desc_t *sv = k_malloc(sizeof(struct shared_vector_desc_t));

		if (sv == NULL) {
			esp_intr_unlock();
			k_free(ret);
			return -ENOMEM;
		}
		memset(sv, 0, sizeof(struct shared_vector_desc_t));
		sv->statusreg = (uint32_t *)intrstatusreg;
		sv->statusmask = intrstatusmask;
		sv->isr = handler;
		sv->arg = arg;
		sv->next = vd->shared_vec_info;
		sv->source = source;
		sv->disabled = 0;
		vd->shared_vec_info = sv;
		vd->flags |= VECDESC_FL_SHARED;
		/* (Re-)set shared isr handler to new value. */
		set_interrupt_handler(intr, shared_intr_isr, vd);
	} 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);
		}
		if (flags & ESP_INTR_FLAG_EDGE) {
			xthal_set_intclear(1 << intr);
		}
		vd->source = source;
	}
	if (flags & ESP_INTR_FLAG_IRAM) {
		vd->flags |= VECDESC_FL_INIRAM;
		non_iram_int_mask[cpu] &= ~(1 << intr);
	} else {
		vd->flags &= ~VECDESC_FL_INIRAM;
		non_iram_int_mask[cpu] |= (1 << intr);
	}
	if (source >= 0) {
		intr_matrix_set(cpu, source, intr);
	}

	/* Fill return handle data. */
	ret->vector_desc = vd;
	ret->shared_vector_desc = vd->shared_vec_info;

	/* Enable int at CPU-level; */
	irq_enable(intr);

	/*
	 * If interrupt has to be started disabled, do that now; ints won't be enabled for
	 * real until the end of the critical section.
	 */
	if (flags & ESP_INTR_FLAG_INTRDISABLED) {
		esp_intr_disable(ret);
	}

	esp_intr_unlock();

	/* Fill return handle if needed, otherwise free handle. */
	if (ret_handle != NULL) {
		*ret_handle = ret;
	} else {
		k_free(ret);
	}

	LOG_DBG("Connected src %d to int %d (cpu %d)", source, intr, cpu);
	return 0;
}

int esp_intr_alloc(int source,
		int flags,
		intr_handler_t handler,
		void *arg,
		struct intr_handle_data_t **ret_handle)
{
	/*
	 * As an optimization, we can create a table with the possible interrupt status
	 * registers and masks for every single source there is. We can then add code here to
	 * look up an applicable value and pass that to the esp_intr_alloc_intrstatus function.
	 */
	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)
{
	if (!handle) {
		return -EINVAL;
	}
	struct vector_desc_t *vd = handle->vector_desc;

	if (vd->flags & VECDESC_FL_SHARED) {
		return -EINVAL;
	}
	esp_intr_lock();
	uint32_t mask = (1 << vd->intno);

	if (is_in_iram) {
		vd->flags |= VECDESC_FL_INIRAM;
		non_iram_int_mask[vd->cpu] &= ~mask;
	} else {
		vd->flags &= ~VECDESC_FL_INIRAM;
		non_iram_int_mask[vd->cpu] |= mask;
	}
	esp_intr_unlock();
	return 0;
}

int esp_intr_free(struct intr_handle_data_t *handle)
{
	bool free_shared_vector = false;

	if (!handle) {
		return -EINVAL;
	}

	esp_intr_lock();
	esp_intr_disable(handle);
	if (handle->vector_desc->flags & VECDESC_FL_SHARED) {
		/* Find and kill the shared int */
		struct shared_vector_desc_t *svd = handle->vector_desc->shared_vec_info;
		struct shared_vector_desc_t *prevsvd = NULL;

		assert(svd); /* should be something in there for a shared int */
		while (svd != NULL) {
			if (svd == handle->shared_vector_desc) {
				/* Found it. Now kill it. */
				if (prevsvd) {
					prevsvd->next = svd->next;
				} else {
					handle->vector_desc->shared_vec_info = svd->next;
				}
				k_free(svd);
				break;
			}
			prevsvd = svd;
			svd = svd->next;
		}
		/* If nothing left, disable interrupt. */
		if (handle->vector_desc->shared_vec_info == NULL) {
			free_shared_vector = true;
		}
		INTC_LOG("%s: Deleting shared int: %s. "
			"Shared int is %s", __func__, svd ? "not found or last one" : "deleted",
			free_shared_vector ? "empty now." : "still in use");
	}

	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));
		/*
		 * 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);
		/* Also kill non_iram mask bit. */
		non_iram_int_mask[handle->vector_desc->cpu] &= ~(1 << (handle->vector_desc->intno));
	}
	esp_intr_unlock();
	k_free(handle);
	return 0;
}

int esp_intr_get_intno(struct intr_handle_data_t *handle)
{
	return handle->vector_desc->intno;
}

int esp_intr_get_cpu(struct intr_handle_data_t *handle)
{
	return handle->vector_desc->cpu;
}

/**
 * Interrupt disabling strategy:
 * If the source is >=0 (meaning a muxed interrupt), we disable it by muxing the interrupt to a
 * non-connected interrupt. If the source is <0 (meaning an internal, per-cpu interrupt).
 * This allows us to, for the muxed CPUs, disable an int from
 * the other core. It also allows disabling shared interrupts.
 */

/*
 * Muxing an interrupt source to interrupt 6, 7, 11, 15, 16 or 29
 * cause the interrupt to effectively be disabled.
 */
#define INT_MUX_DISABLED_INTNO 6

int IRAM_ATTR esp_intr_enable(struct intr_handle_data_t *handle)
{
	if (!handle) {
		return -EINVAL;
	}
	esp_intr_lock();
	int source;

	if (handle->shared_vector_desc) {
		handle->shared_vector_desc->disabled = 0;
		source = handle->shared_vector_desc->source;
	} else {
		source = handle->vector_desc->source;
	}
	if (source >= 0) {
		/* Disabled using int matrix; re-connect to enable */
		intr_matrix_set(handle->vector_desc->cpu, source, handle->vector_desc->intno);
	} else {
		/* Re-enable using cpu int ena reg */
		if (handle->vector_desc->cpu != esp_core_id()) {
			return -EINVAL; /* Can only enable these ints on this cpu */
		}
		irq_enable(handle->vector_desc->intno);
	}
	esp_intr_unlock();
	return 0;
}

int IRAM_ATTR esp_intr_disable(struct intr_handle_data_t *handle)
{
	if (!handle) {
		return -EINVAL;
	}
	esp_intr_lock();
	int source;
	bool disabled = 1;

	if (handle->shared_vector_desc) {
		handle->shared_vector_desc->disabled = 1;
		source = handle->shared_vector_desc->source;

		struct shared_vector_desc_t *svd = handle->vector_desc->shared_vec_info;

		assert(svd != NULL);
		while (svd) {
			if (svd->source == source && svd->disabled == 0) {
				disabled = 0;
				break;
			}
			svd = svd->next;
		}
	} else {
		source = handle->vector_desc->source;
	}

	if (source >= 0) {
		if (disabled) {
			/* Disable using int matrix */
			intr_matrix_set(handle->vector_desc->cpu, source, INT_MUX_DISABLED_INTNO);
		}
	} else {
		/* Disable using per-cpu regs */
		if (handle->vector_desc->cpu != esp_core_id()) {
			esp_intr_unlock();
			return -EINVAL; /* Can only enable these ints on this cpu */
		}
		irq_disable(handle->vector_desc->intno);
	}
	esp_intr_unlock();
	return 0;
}


void IRAM_ATTR esp_intr_noniram_disable(void)
{
	int oldint;
	int cpu = esp_core_id();
	int non_iram_ints = ~non_iram_int_mask[cpu];

	if (non_iram_int_disabled_flag[cpu]) {
		abort();
	}
	non_iram_int_disabled_flag[cpu] = true;
	oldint = interrupt_controller_hal_read_interrupt_mask();
	interrupt_controller_hal_disable_interrupts(non_iram_ints);
	/* Save which ints we did disable */
	non_iram_int_disabled[cpu] = oldint & non_iram_ints;
}

void IRAM_ATTR esp_intr_noniram_enable(void)
{
	int cpu = esp_core_id();
	int non_iram_ints = non_iram_int_disabled[cpu];

	if (!non_iram_int_disabled_flag[cpu]) {
		abort();
	}
	non_iram_int_disabled_flag[cpu] = false;
	interrupt_controller_hal_enable_interrupts(non_iram_ints);
}
