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:
Wayne Ren 2020-04-06 11:56:08 +08:00 committed by Andrew Boie
commit 8f76233029
3 changed files with 112 additions and 67 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2014 Wind River Systems, Inc.
* Copyright (c) 2020 Synopsys.
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -58,9 +59,8 @@ static struct arc_v2_irq_unit_ctx ctx;
* the window between a write to IRQ_SELECT and subsequent writes to the
* selected IRQ's registers.
*
* @return N/A
* @return 0 for success
*/
static int arc_v2_irq_unit_init(struct device *unused)
{
ARG_UNUSED(unused);
@ -88,26 +88,16 @@ static int arc_v2_irq_unit_init(struct device *unused)
return 0;
}
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);
}
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);
}
unsigned int z_arc_v2_irq_unit_trigger_get(int irq)
{
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_SELECT, irq);
return z_arc_v2_aux_reg_read(_ARC_V2_IRQ_TRIGGER);
}
#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
/*
* @brief Suspend the interrupt unit device driver
*
* Suspends the interrupt unit device driver and the device
* itself.
*
* @return 0 for success
*/
static int arc_v2_irq_unit_suspend(struct device *dev)
{
u8_t irq;
@ -136,10 +126,17 @@ static int arc_v2_irq_unit_suspend(struct device *dev)
return 0;
}
/*
* @brief Resume the interrupt unit device driver
*
* Resume the interrupt unit device driver and the device
* itself.
*
* @return 0 for success
*/
static int arc_v2_irq_unit_resume(struct device *dev)
{
u8_t irq;
u32_t status32;
ARG_UNUSED(dev);
@ -170,16 +167,16 @@ static int arc_v2_irq_unit_resume(struct device *dev)
#endif
z_arc_v2_aux_reg_write(_ARC_V2_IRQ_VECT_BASE, ctx.irq_vect_base);
status32 = z_arc_v2_aux_reg_read(_ARC_V2_STATUS32);
status32 |= Z_ARC_V2_STATUS32_E(_ARC_V2_DEF_IRQ_LEVEL);
__builtin_arc_kflag(status32);
_arc_v2_irq_unit_device_power_state = DEVICE_PM_ACTIVE_STATE;
return 0;
}
/*
* @brief Get the power state of interrupt unit
*
* @return the power state of interrupt unit
*/
static int arc_v2_irq_unit_get_state(struct device *dev)
{
ARG_UNUSED(dev);
@ -188,13 +185,18 @@ static int arc_v2_irq_unit_get_state(struct device *dev)
}
/*
* Implements the driver control management functionality
* the *context may include IN data or/and OUT data
* @brief Implement the driver control of interrupt unit
*
* The operation on interrupt unit requires interrupt lock.
* The *context may include IN data or/and OUT data
*
* @return operation result
*/
static int arc_v2_irq_unit_device_ctrl(struct device *device,
u32_t ctrl_command, void *context, device_pm_cb cb, void *arg)
{
int ret = 0;
unsigned int key = arch_irq_lock();
if (ctrl_command == DEVICE_PM_SET_POWER_STATE) {
if (*((u32_t *)context) == DEVICE_PM_SUSPEND_STATE) {
@ -206,6 +208,8 @@ static int arc_v2_irq_unit_device_ctrl(struct device *device,
*((u32_t *)context) = arc_v2_irq_unit_get_state(device);
}
arch_irq_unlock(key);
if (cb) {
cb(device, ret, context, arg);
}