Files
E3/20250218-ETH-CAN_loadV1.3/e3_176_ref/drivers/source/vic/irq.c
2025-11-14 21:41:29 +08:00

211 lines
3.9 KiB
C

/*
* interrupt.c
*
* Copyright (c) 2020 Semidrive Semiconductor.
* All rights reserved.
*
* Description: interrupt driver.
*
* Revision History:
* -----------------
*/
#if CONFIG_IRQ
#include <types.h>
#include "armv7-r/cache.h"
#include "armv7-r/irq.h"
#include "core_id.h"
#include "irq.h"
#include "irq_num.h"
#include "sdrv_vic.h"
/* irq info type */
struct irq_info_s {
irq_handler handler; /* Address of the interrupt handler */
void *arg; /* The argument provided to the interrupt handler. */
};
struct irq_table {
struct irq_info_s irq_info[IRQ_MAX_INTR_NUM];
} __CACHE_ALIGN;
/* int table */
static struct irq_table g_irq_table[CORE_NUM_SMP];
static int irq_handle(uint32_t irq)
{
if (irq < IRQ_MAX_INTR_NUM) {
int core_id = get_core_id_smp();
struct irq_info_s *irq_info = &g_irq_table[core_id].irq_info[irq];
if (irq_info->handler) {
return irq_info->handler(irq, irq_info->arg);
}
}
return -1;
}
/**
* @brief Initialize interruppt controller.
*
* @param [in] base base address.
* @param [in] intr_num number of interrupts.
*/
void irq_initialize(uint32_t base, uint32_t intr_num)
{
irq_lld_initialize(base, intr_num, irq_handle);
arch_irq_enable();
}
/**
* @brief Interrupt attach.
*
* @param [in] irq IRQ number.
* @param [in] handler Pointer to function.
* @arg [in] arg parameter of handler.
* @return int Return zero after attach set;
*/
int irq_attach(uint32_t irq, irq_handler handler, void *arg)
{
int ret = -1;
if (irq < IRQ_MAX_INTR_NUM) {
int core_id = get_core_id_smp();
struct irq_info_s *irq_info = &g_irq_table[core_id].irq_info[irq];
IRQ_SAVE
irq_info->handler = handler;
irq_info->arg = arg;
irq_lld_set_priority(irq, DEFAULT_IRQ_PRIORITY);
IRQ_RESTORE
ret = 0;
}
return ret;
}
/**
* @brief Interrupt datach.
*
* @param [in] irq IRQ number.
* @return int Return zero after datach set succesfully;
*/
int irq_detach(uint32_t irq)
{
int ret = -1;
if (irq < IRQ_MAX_INTR_NUM) {
int core_id = get_core_id_smp();
struct irq_info_s *irq_info = &g_irq_table[core_id].irq_info[irq];
IRQ_SAVE
irq_lld_disable(irq);
irq_info->handler = NULL;
irq_info->arg = NULL;
IRQ_RESTORE
ret = 0;
}
return ret;
}
/**
* @brief Interrupt disptach.
*
*/
int irq_dispatch(void)
{
int ret = -1;
uint32_t irq = irq_lld_acknowledge();
ret = irq_handle(irq);
irq_lld_complete(irq);
return ret;
}
/**
* @brief irq enable.
*
* @param [in] irq irq number.
*/
void irq_enable(uint32_t irq)
{
irq_lld_enable(irq);
}
/**
* @brief irq disable.
*
* @param [in] irq number.
*/
void irq_disable(uint32_t irq)
{
irq_lld_disable(irq);
}
/**
* @brief interrupt set priority mask.
*
* @param [in]mask int priority mask.
* @return mask old int priority mask.
*/
uint32_t irq_mask(uint32_t mask)
{
return irq_lld_mask(mask);
}
/**
* @brief interrupt unmask all int.
*/
void irq_unmask(void)
{
irq_lld_unmask();
}
/**
* @brief set irq priority.
*
* @param [in] irq irq number.
* @param [in] priority irq priority.
*/
void irq_set_priority(uint32_t irq, uint32_t priority)
{
irq_lld_set_priority(irq, priority);
}
/**
* @brief get irq priority.
*
* @param [in] irq irq number.
* @return int irq priority.
*/
int irq_get_priority(uint32_t irq)
{
return irq_lld_get_priority(irq);
}
/**
* @brief interrupt get current int priority.
*
* @return int priority.
*/
uint32_t irq_get_current_priority(void)
{
return irq_lld_get_current_priority();
}
#endif /* CONFIG_IRQ */