Skip to content

Commit

Permalink
Merge pull request zephyrproject-rtos#9 from dcpleung/sof/fix_assert
Browse files Browse the repository at this point in the history
xtensa: fixes undefined reference to z_arch_irq_is_enabled()
  • Loading branch information
jhedberg authored Aug 26, 2019
2 parents 0930cf8 + 54230b4 commit a3b8bc0
Show file tree
Hide file tree
Showing 10 changed files with 179 additions and 0 deletions.
8 changes: 8 additions & 0 deletions arch/xtensa/core/xtensa-asm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,3 +207,11 @@ void *xtensa_excint1_c(int *interrupted_stack)
return z_get_next_switch_handle(interrupted_stack);
}

int z_xtensa_irq_is_enabled(unsigned int irq)
{
u32_t ie;

__asm__ volatile("rsr.intenable %0" : "=r"(ie));

return (ie & (1 << irq)) != 0;
}
15 changes: 15 additions & 0 deletions drivers/interrupt_controller/cavs_ictl.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,25 @@ static inline unsigned int cavs_ictl_irq_get_state(struct device *dev)
return 1;
}

static int cavs_ictl_irq_get_line_state(struct device *dev, unsigned int irq)
{
struct cavs_ictl_runtime *context = dev->driver_data;

volatile struct cavs_registers * const regs =
(struct cavs_registers *)context->base_addr;

if ((regs->disable_state_il & BIT(irq)) == 0) {
return 1;
}

return 0;
}

static const struct irq_next_level_api cavs_apis = {
.intr_enable = cavs_ictl_irq_enable,
.intr_disable = cavs_ictl_irq_disable,
.intr_get_state = cavs_ictl_irq_get_state,
.intr_get_line_state = cavs_ictl_irq_get_line_state,
};

static int cavs_ictl_0_initialize(struct device *port)
Expand Down
23 changes: 23 additions & 0 deletions drivers/interrupt_controller/dw_ictl.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,28 @@ static inline unsigned int dw_ictl_intr_get_state(struct device *dev)
return 0;
}

static int dw_ictl_intr_get_line_state(struct device *dev, unsigned int irq)
{
struct dw_ictl_runtime *context = dev->driver_data;

const struct dw_ictl_config *config = dev->config->config_info;

volatile struct dw_ictl_registers * const regs =
(struct dw_ictl_registers *)context->base_addr;

if (config->numirqs > 32) {
if ((regs->irq_inten_h & BIT(irq - 32)) != 0) {
return 1;
}
} else {
if ((regs->irq_inten_l & BIT(irq)) != 0) {
return 1;
}
}

return 0;
}

static void dw_ictl_config_irq(struct device *port);

static const struct dw_ictl_config dw_config = {
Expand All @@ -130,6 +152,7 @@ static const struct irq_next_level_api dw_ictl_apis = {
.intr_enable = dw_ictl_intr_enable,
.intr_disable = dw_ictl_intr_disable,
.intr_get_state = dw_ictl_intr_get_state,
.intr_get_line_state = dw_ictl_intr_get_line_state,
};

DEVICE_AND_API_INIT(dw_ictl, CONFIG_DW_ICTL_NAME, dw_ictl_initialize,
Expand Down
14 changes: 14 additions & 0 deletions drivers/interrupt_controller/rv32m1_intmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ static u32_t rv32m1_intmux_get_state(struct device *dev)
return 0;
}

static int rv32m1_intmux_get_line_state(struct device *dev, unsigned int irq)
{
INTMUX_Type *regs = DEV_REGS(dev);
u32_t channel = rv32m1_intmux_channel(irq);
u32_t line = rv32m1_intmux_line(irq);

if ((regs->CHANNEL[channel].CHn_IER_31_0 & BIT(line)) != 0) {
return 1;
}

return 0;
}

/*
* IRQ handling.
*/
Expand Down Expand Up @@ -113,6 +126,7 @@ static const struct irq_next_level_api rv32m1_intmux_apis = {
.intr_enable = rv32m1_intmux_irq_enable,
.intr_disable = rv32m1_intmux_irq_disable,
.intr_get_state = rv32m1_intmux_get_state,
.intr_get_line_state = rv32m1_intmux_get_line_state,
};

static const struct rv32m1_intmux_config rv32m1_intmux_cfg = {
Expand Down
6 changes: 6 additions & 0 deletions include/arch/xtensa/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#define z_arch_irq_enable(irq) z_soc_irq_enable(irq)
#define z_arch_irq_disable(irq) z_soc_irq_disable(irq)

#define z_arch_irq_is_enabled(irq) z_soc_irq_is_enabled(irq)

#ifdef CONFIG_DYNAMIC_INTERRUPTS
extern int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
void (*routine)(void *parameter),
Expand All @@ -47,6 +49,8 @@ extern int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
#define z_arch_irq_enable(irq) z_xtensa_irq_enable(irq)
#define z_arch_irq_disable(irq) z_xtensa_irq_disable(irq)

#define z_arch_irq_is_enabled(irq) z_xtensa_irq_is_enabled(irq)

#endif

/**
Expand Down Expand Up @@ -98,6 +102,8 @@ static ALWAYS_INLINE bool z_arch_irq_unlocked(unsigned int key)
return (key & 0xf) == 0; /* INTLEVEL field */
}

extern int z_xtensa_irq_is_enabled(unsigned int irq);

#include <irq.h>

#endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_ */
21 changes: 21 additions & 0 deletions include/irq_nextlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ extern "C" {
*/
typedef void (*irq_next_level_func_t)(struct device *dev, unsigned int irq);
typedef unsigned int (*irq_next_level_get_state_t)(struct device *dev);
typedef int (*irq_next_level_get_line_state_t)(struct device *dev,
unsigned int irq);

struct irq_next_level_api {
irq_next_level_func_t intr_enable;
irq_next_level_func_t intr_disable;
irq_next_level_get_state_t intr_get_state;
irq_next_level_get_line_state_t intr_get_line_state;
};
/**
* @endcond
Expand Down Expand Up @@ -84,6 +87,24 @@ static inline unsigned int irq_is_enabled_next_level(struct device *dev)
return api->intr_get_state(dev);
}

/**
* @brief Get IRQ line enable state.
*
* Query if a particular IRQ line is enabled.
*
* @param dev Pointer to the device structure for the driver instance.
* @param irq IRQ line to be queried.
*
* @return interrupt enable state, true or false
*/
static inline unsigned int irq_line_is_enabled_next_level(struct device *dev,
unsigned int irq)
{
const struct irq_next_level_api *api = dev->driver_api;

return api->intr_get_line_state(dev, irq);
}

/**
* @}
*/
Expand Down
37 changes: 37 additions & 0 deletions soc/xtensa/intel_apl_adsp/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,43 @@ void z_soc_irq_disable(u32_t irq)
}
}

int z_soc_irq_is_enabled(unsigned int irq)
{
struct device *dev_cavs;
int ret = 0;

switch (XTENSA_IRQ_NUMBER(irq)) {
case DT_CAVS_ICTL_0_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_0_NAME);
break;
case DT_CAVS_ICTL_1_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_1_NAME);
break;
case DT_CAVS_ICTL_2_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_2_NAME);
break;
case DT_CAVS_ICTL_3_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_3_NAME);
break;
default:
/* regular interrupt */
ret = z_xtensa_irq_is_enabled(XTENSA_IRQ_NUMBER(irq));
goto out;
}

if (!dev_cavs) {
LOG_DBG("board: CAVS device binding failed");
ret = -ENODEV;
goto out;
}

/* Then enable the interrupt in CAVS interrupt controller */
ret = irq_line_is_enabled_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));

out:
return ret;
}

#ifdef CONFIG_DYNAMIC_INTERRUPTS
int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
void (*routine)(void *parameter),
Expand Down
1 change: 1 addition & 0 deletions soc/xtensa/intel_apl_adsp/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ struct soc_dsp_shim_regs {

extern void z_soc_irq_enable(u32_t irq);
extern void z_soc_irq_disable(u32_t irq);
extern int z_soc_irq_is_enabled(unsigned int irq);

extern u32_t soc_get_ref_clk_freq(void);

Expand Down
53 changes: 53 additions & 0 deletions soc/xtensa/intel_s1000/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,59 @@ void z_soc_irq_disable(u32_t irq)
}
}

int z_soc_irq_is_enabled(unsigned int irq)
{
struct device *dev_cavs, *dev_ictl;
int ret = -EINVAL;

switch (XTENSA_IRQ_NUMBER(irq)) {
case DT_CAVS_ICTL_0_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_0_NAME);
break;
case DT_CAVS_ICTL_1_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_1_NAME);
break;
case DT_CAVS_ICTL_2_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_2_NAME);
break;
case DT_CAVS_ICTL_3_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_3_NAME);
break;
default:
/* regular interrupt */
ret = z_xtensa_is_irq_enabled(XTENSA_IRQ_NUMBER(irq));
goto out;
}

if (!dev_cavs) {
LOG_DBG("board: CAVS device binding failed");
ret = -ENODEV;
goto out;
}

switch (CAVS_IRQ_NUMBER(irq)) {
case DW_ICTL_IRQ_CAVS_OFFSET:
dev_ictl = device_get_binding(CONFIG_DW_ICTL_NAME);
break;
default:
/* The source of the interrupt is in CAVS interrupt logic */
ret = irq_line_is_enabled_next_level(dev_cavs,
CAVS_IRQ_NUMBER(irq));
goto out;
}

if (!dev_ictl) {
LOG_DBG("board: DW intr_control device binding failed");
ret = -NODEV;
goto out;
}

ret = irq_line_is_enabled_next_level(dev_ictl, INTR_CNTL_IRQ_NUM(irq));

out:
return ret;
}

static inline void soc_set_resource_ownership(void)
{
volatile struct soc_resource_alloc_regs *regs =
Expand Down
1 change: 1 addition & 0 deletions soc/xtensa/intel_s1000/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ struct soc_global_regs {

extern void z_soc_irq_enable(u32_t irq);
extern void z_soc_irq_disable(u32_t irq);
extern int z_soc_irq_is_enabled(unsigned int irq);

extern u32_t soc_get_ref_clk_freq(void);

Expand Down

0 comments on commit a3b8bc0

Please sign in to comment.