arch: arc: optimize the arc v2 interrupt unit driver
* add interrupt lock in low level API to gurantee the correctness of operations. * make some functions as in-line functions * clean up and optimize the code comments Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
parent
e268368fd4
commit
8f76233029
3 changed files with 112 additions and 67 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2014 Wind River Systems, Inc.
|
||||
* Copyright (c) 2020 Synopsys.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
@ -24,20 +25,16 @@ extern "C" {
|
|||
#ifndef _ASMLANGUAGE
|
||||
|
||||
/*
|
||||
* WARNING:
|
||||
* NOTE:
|
||||
*
|
||||
* All APIs provided by this file must be invoked with INTERRUPTS LOCKED. The
|
||||
* All APIs provided by this file are protected with INTERRUPTS LOCKED. The
|
||||
* APIs themselves are writing the IRQ_SELECT, selecting which IRQ's registers
|
||||
* it wants to write to, then write to them: THIS IS NOT AN ATOMIC OPERATION.
|
||||
*
|
||||
* Not locking the interrupts inside of the APIs allows a caller to:
|
||||
* Locking the interrupts inside of the APIs are some kind of self-protection
|
||||
* to guarantee the correctness of operation if the callers don't lock
|
||||
* the interrupt.
|
||||
*
|
||||
* - lock interrupts
|
||||
* - call many of these APIs
|
||||
* - unlock interrupts
|
||||
*
|
||||
* thus being more efficient then if the APIs themselves would lock
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -54,8 +51,12 @@ void z_arc_v2_irq_unit_irq_enable_set(
|
|||
unsigned char enable
|
||||
)
|
||||
{
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_ENABLE, enable);
|
||||
|
||||
arch_irq_unlock(key);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -97,8 +98,15 @@ void z_arc_v2_irq_unit_int_disable(int irq)
|
|||
static ALWAYS_INLINE
|
||||
bool z_arc_v2_irq_unit_int_enabled(int irq)
|
||||
{
|
||||
bool ret;
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
return z_arc_v2_aux_reg_read(_ARC_V2_IRQ_ENABLE) & 0x1;
|
||||
ret = z_arc_v2_aux_reg_read(_ARC_V2_IRQ_ENABLE) & 0x1;
|
||||
|
||||
arch_irq_unlock(key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,6 +122,8 @@ static ALWAYS_INLINE
|
|||
void z_arc_v2_irq_unit_prio_set(int irq, unsigned char prio)
|
||||
{
|
||||
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
#if defined(CONFIG_ARC_SECURE_FIRMWARE)
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||
|
@ -122,23 +132,35 @@ void z_arc_v2_irq_unit_prio_set(int irq, unsigned char prio)
|
|||
#else
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY, prio);
|
||||
#endif
|
||||
arch_irq_unlock(key);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARC_SECURE_FIRMWARE)
|
||||
/*
|
||||
* @brief Configure the secure state of interrupt
|
||||
*
|
||||
* Configure the secure state of the specified interrupt
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static ALWAYS_INLINE
|
||||
void z_arc_v2_irq_uinit_secure_set(int irq, bool secure)
|
||||
{
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
if (secure) {
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||
z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) |
|
||||
_ARC_V2_IRQ_PRIORITY_SECURE);
|
||||
} else {
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||
z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) &
|
||||
_ARC_V2_INT_PRIO_MASK);
|
||||
}
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
|
||||
if (secure) {
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||
z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) |
|
||||
_ARC_V2_IRQ_PRIORITY_SECURE);
|
||||
} else {
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PRIORITY,
|
||||
z_arc_v2_aux_reg_read(_ARC_V2_IRQ_PRIORITY) &
|
||||
_ARC_V2_INT_PRIO_MASK);
|
||||
}
|
||||
|
||||
arch_irq_unlock(key);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -156,8 +178,12 @@ void z_arc_v2_irq_uinit_secure_set(int irq, bool secure)
|
|||
static ALWAYS_INLINE
|
||||
void z_arc_v2_irq_unit_sensitivity_set(int irq, int s)
|
||||
{
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, s);
|
||||
|
||||
arch_irq_unlock(key);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -165,7 +191,7 @@ void z_arc_v2_irq_unit_sensitivity_set(int irq, int s)
|
|||
*
|
||||
* Check whether processor in interrupt/exception state
|
||||
*
|
||||
* @return N/A
|
||||
* @return 1 in interrupt/exception state; 0 not in
|
||||
*/
|
||||
static ALWAYS_INLINE
|
||||
bool z_arc_v2_irq_unit_is_in_isr(void)
|
||||
|
@ -189,8 +215,16 @@ bool z_arc_v2_irq_unit_is_in_isr(void)
|
|||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static ALWAYS_INLINE
|
||||
void z_arc_v2_irq_unit_trigger_set(int irq, unsigned int trigger)
|
||||
{
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
void z_arc_v2_irq_unit_trigger_set(int irq, unsigned int trigger);
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_TRIGGER, trigger);
|
||||
|
||||
arch_irq_unlock(key);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Returns an IRQ line trigger type
|
||||
|
@ -198,10 +232,21 @@ void z_arc_v2_irq_unit_trigger_set(int irq, unsigned int trigger);
|
|||
* Gets the IRQ line <irq> trigger type.
|
||||
* Valid values for <trigger> are _ARC_V2_INT_LEVEL and _ARC_V2_INT_PULSE.
|
||||
*
|
||||
* @return N/A
|
||||
* @return trigger state
|
||||
*/
|
||||
static ALWAYS_INLINE
|
||||
unsigned int z_arc_v2_irq_unit_trigger_get(int irq)
|
||||
{
|
||||
unsigned int ret;
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
unsigned int z_arc_v2_irq_unit_trigger_get(int irq);
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
ret = z_arc_v2_aux_reg_read(_ARC_V2_IRQ_TRIGGER);
|
||||
|
||||
arch_irq_unlock(key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Send EOI signal to interrupt unit
|
||||
|
@ -209,13 +254,18 @@ unsigned int z_arc_v2_irq_unit_trigger_get(int irq);
|
|||
* This routine sends an EOI (End Of Interrupt) signal to the interrupt unit
|
||||
* to clear a pulse-triggered interrupt.
|
||||
*
|
||||
* Interrupts must be locked or the ISR operating at P0 when invoking this
|
||||
* function.
|
||||
*
|
||||
* @return N/A
|
||||
*/
|
||||
static ALWAYS_INLINE
|
||||
void z_arc_v2_irq_unit_int_eoi(int irq)
|
||||
{
|
||||
unsigned int key = arch_irq_lock();
|
||||
|
||||
void z_arc_v2_irq_unit_int_eoi(int irq);
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
|
||||
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_PULSE_CANCEL, 1);
|
||||
|
||||
arch_irq_unlock(key);
|
||||
}
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue