Skip to content

Commit a3b8bc0

Browse files
authored
Merge pull request zephyrproject-rtos#9 from dcpleung/sof/fix_assert
xtensa: fixes undefined reference to z_arch_irq_is_enabled()
2 parents 0930cf8 + 54230b4 commit a3b8bc0

File tree

10 files changed

+179
-0
lines changed

10 files changed

+179
-0
lines changed

arch/xtensa/core/xtensa-asm2.c

+8
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,11 @@ void *xtensa_excint1_c(int *interrupted_stack)
207207
return z_get_next_switch_handle(interrupted_stack);
208208
}
209209

210+
int z_xtensa_irq_is_enabled(unsigned int irq)
211+
{
212+
u32_t ie;
213+
214+
__asm__ volatile("rsr.intenable %0" : "=r"(ie));
215+
216+
return (ie & (1 << irq)) != 0;
217+
}

drivers/interrupt_controller/cavs_ictl.c

+15
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,25 @@ static inline unsigned int cavs_ictl_irq_get_state(struct device *dev)
7575
return 1;
7676
}
7777

78+
static int cavs_ictl_irq_get_line_state(struct device *dev, unsigned int irq)
79+
{
80+
struct cavs_ictl_runtime *context = dev->driver_data;
81+
82+
volatile struct cavs_registers * const regs =
83+
(struct cavs_registers *)context->base_addr;
84+
85+
if ((regs->disable_state_il & BIT(irq)) == 0) {
86+
return 1;
87+
}
88+
89+
return 0;
90+
}
91+
7892
static const struct irq_next_level_api cavs_apis = {
7993
.intr_enable = cavs_ictl_irq_enable,
8094
.intr_disable = cavs_ictl_irq_disable,
8195
.intr_get_state = cavs_ictl_irq_get_state,
96+
.intr_get_line_state = cavs_ictl_irq_get_line_state,
8297
};
8398

8499
static int cavs_ictl_0_initialize(struct device *port)

drivers/interrupt_controller/dw_ictl.c

+23
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,28 @@ static inline unsigned int dw_ictl_intr_get_state(struct device *dev)
113113
return 0;
114114
}
115115

116+
static int dw_ictl_intr_get_line_state(struct device *dev, unsigned int irq)
117+
{
118+
struct dw_ictl_runtime *context = dev->driver_data;
119+
120+
const struct dw_ictl_config *config = dev->config->config_info;
121+
122+
volatile struct dw_ictl_registers * const regs =
123+
(struct dw_ictl_registers *)context->base_addr;
124+
125+
if (config->numirqs > 32) {
126+
if ((regs->irq_inten_h & BIT(irq - 32)) != 0) {
127+
return 1;
128+
}
129+
} else {
130+
if ((regs->irq_inten_l & BIT(irq)) != 0) {
131+
return 1;
132+
}
133+
}
134+
135+
return 0;
136+
}
137+
116138
static void dw_ictl_config_irq(struct device *port);
117139

118140
static const struct dw_ictl_config dw_config = {
@@ -130,6 +152,7 @@ static const struct irq_next_level_api dw_ictl_apis = {
130152
.intr_enable = dw_ictl_intr_enable,
131153
.intr_disable = dw_ictl_intr_disable,
132154
.intr_get_state = dw_ictl_intr_get_state,
155+
.intr_get_line_state = dw_ictl_intr_get_line_state,
133156
};
134157

135158
DEVICE_AND_API_INIT(dw_ictl, CONFIG_DW_ICTL_NAME, dw_ictl_initialize,

drivers/interrupt_controller/rv32m1_intmux.c

+14
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ static u32_t rv32m1_intmux_get_state(struct device *dev)
8686
return 0;
8787
}
8888

89+
static int rv32m1_intmux_get_line_state(struct device *dev, unsigned int irq)
90+
{
91+
INTMUX_Type *regs = DEV_REGS(dev);
92+
u32_t channel = rv32m1_intmux_channel(irq);
93+
u32_t line = rv32m1_intmux_line(irq);
94+
95+
if ((regs->CHANNEL[channel].CHn_IER_31_0 & BIT(line)) != 0) {
96+
return 1;
97+
}
98+
99+
return 0;
100+
}
101+
89102
/*
90103
* IRQ handling.
91104
*/
@@ -113,6 +126,7 @@ static const struct irq_next_level_api rv32m1_intmux_apis = {
113126
.intr_enable = rv32m1_intmux_irq_enable,
114127
.intr_disable = rv32m1_intmux_irq_disable,
115128
.intr_get_state = rv32m1_intmux_get_state,
129+
.intr_get_line_state = rv32m1_intmux_get_line_state,
116130
};
117131

118132
static const struct rv32m1_intmux_config rv32m1_intmux_cfg = {

include/arch/xtensa/irq.h

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#define z_arch_irq_enable(irq) z_soc_irq_enable(irq)
3535
#define z_arch_irq_disable(irq) z_soc_irq_disable(irq)
3636

37+
#define z_arch_irq_is_enabled(irq) z_soc_irq_is_enabled(irq)
38+
3739
#ifdef CONFIG_DYNAMIC_INTERRUPTS
3840
extern int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
3941
void (*routine)(void *parameter),
@@ -47,6 +49,8 @@ extern int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
4749
#define z_arch_irq_enable(irq) z_xtensa_irq_enable(irq)
4850
#define z_arch_irq_disable(irq) z_xtensa_irq_disable(irq)
4951

52+
#define z_arch_irq_is_enabled(irq) z_xtensa_irq_is_enabled(irq)
53+
5054
#endif
5155

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

105+
extern int z_xtensa_irq_is_enabled(unsigned int irq);
106+
101107
#include <irq.h>
102108

103109
#endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_ */

include/irq_nextlevel.h

+21
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@ extern "C" {
2323
*/
2424
typedef void (*irq_next_level_func_t)(struct device *dev, unsigned int irq);
2525
typedef unsigned int (*irq_next_level_get_state_t)(struct device *dev);
26+
typedef int (*irq_next_level_get_line_state_t)(struct device *dev,
27+
unsigned int irq);
2628

2729
struct irq_next_level_api {
2830
irq_next_level_func_t intr_enable;
2931
irq_next_level_func_t intr_disable;
3032
irq_next_level_get_state_t intr_get_state;
33+
irq_next_level_get_line_state_t intr_get_line_state;
3134
};
3235
/**
3336
* @endcond
@@ -84,6 +87,24 @@ static inline unsigned int irq_is_enabled_next_level(struct device *dev)
8487
return api->intr_get_state(dev);
8588
}
8689

90+
/**
91+
* @brief Get IRQ line enable state.
92+
*
93+
* Query if a particular IRQ line is enabled.
94+
*
95+
* @param dev Pointer to the device structure for the driver instance.
96+
* @param irq IRQ line to be queried.
97+
*
98+
* @return interrupt enable state, true or false
99+
*/
100+
static inline unsigned int irq_line_is_enabled_next_level(struct device *dev,
101+
unsigned int irq)
102+
{
103+
const struct irq_next_level_api *api = dev->driver_api;
104+
105+
return api->intr_get_line_state(dev, irq);
106+
}
107+
87108
/**
88109
* @}
89110
*/

soc/xtensa/intel_apl_adsp/soc.c

+37
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,43 @@ void z_soc_irq_disable(u32_t irq)
101101
}
102102
}
103103

104+
int z_soc_irq_is_enabled(unsigned int irq)
105+
{
106+
struct device *dev_cavs;
107+
int ret = 0;
108+
109+
switch (XTENSA_IRQ_NUMBER(irq)) {
110+
case DT_CAVS_ICTL_0_IRQ:
111+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_0_NAME);
112+
break;
113+
case DT_CAVS_ICTL_1_IRQ:
114+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_1_NAME);
115+
break;
116+
case DT_CAVS_ICTL_2_IRQ:
117+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_2_NAME);
118+
break;
119+
case DT_CAVS_ICTL_3_IRQ:
120+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_3_NAME);
121+
break;
122+
default:
123+
/* regular interrupt */
124+
ret = z_xtensa_irq_is_enabled(XTENSA_IRQ_NUMBER(irq));
125+
goto out;
126+
}
127+
128+
if (!dev_cavs) {
129+
LOG_DBG("board: CAVS device binding failed");
130+
ret = -ENODEV;
131+
goto out;
132+
}
133+
134+
/* Then enable the interrupt in CAVS interrupt controller */
135+
ret = irq_line_is_enabled_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));
136+
137+
out:
138+
return ret;
139+
}
140+
104141
#ifdef CONFIG_DYNAMIC_INTERRUPTS
105142
int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
106143
void (*routine)(void *parameter),

soc/xtensa/intel_apl_adsp/soc.h

+1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ struct soc_dsp_shim_regs {
184184

185185
extern void z_soc_irq_enable(u32_t irq);
186186
extern void z_soc_irq_disable(u32_t irq);
187+
extern int z_soc_irq_is_enabled(unsigned int irq);
187188

188189
extern u32_t soc_get_ref_clk_freq(void);
189190

soc/xtensa/intel_s1000/soc.c

+53
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,59 @@ void z_soc_irq_disable(u32_t irq)
147147
}
148148
}
149149

150+
int z_soc_irq_is_enabled(unsigned int irq)
151+
{
152+
struct device *dev_cavs, *dev_ictl;
153+
int ret = -EINVAL;
154+
155+
switch (XTENSA_IRQ_NUMBER(irq)) {
156+
case DT_CAVS_ICTL_0_IRQ:
157+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_0_NAME);
158+
break;
159+
case DT_CAVS_ICTL_1_IRQ:
160+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_1_NAME);
161+
break;
162+
case DT_CAVS_ICTL_2_IRQ:
163+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_2_NAME);
164+
break;
165+
case DT_CAVS_ICTL_3_IRQ:
166+
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_3_NAME);
167+
break;
168+
default:
169+
/* regular interrupt */
170+
ret = z_xtensa_is_irq_enabled(XTENSA_IRQ_NUMBER(irq));
171+
goto out;
172+
}
173+
174+
if (!dev_cavs) {
175+
LOG_DBG("board: CAVS device binding failed");
176+
ret = -ENODEV;
177+
goto out;
178+
}
179+
180+
switch (CAVS_IRQ_NUMBER(irq)) {
181+
case DW_ICTL_IRQ_CAVS_OFFSET:
182+
dev_ictl = device_get_binding(CONFIG_DW_ICTL_NAME);
183+
break;
184+
default:
185+
/* The source of the interrupt is in CAVS interrupt logic */
186+
ret = irq_line_is_enabled_next_level(dev_cavs,
187+
CAVS_IRQ_NUMBER(irq));
188+
goto out;
189+
}
190+
191+
if (!dev_ictl) {
192+
LOG_DBG("board: DW intr_control device binding failed");
193+
ret = -NODEV;
194+
goto out;
195+
}
196+
197+
ret = irq_line_is_enabled_next_level(dev_ictl, INTR_CNTL_IRQ_NUM(irq));
198+
199+
out:
200+
return ret;
201+
}
202+
150203
static inline void soc_set_resource_ownership(void)
151204
{
152205
volatile struct soc_resource_alloc_regs *regs =

soc/xtensa/intel_s1000/soc.h

+1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ struct soc_global_regs {
212212

213213
extern void z_soc_irq_enable(u32_t irq);
214214
extern void z_soc_irq_disable(u32_t irq);
215+
extern int z_soc_irq_is_enabled(unsigned int irq);
215216

216217
extern u32_t soc_get_ref_clk_freq(void);
217218

0 commit comments

Comments
 (0)