Skip to content

Commit b2602ea

Browse files
committed
drivers: intc_dw: support multiple instances
Update the initializers to support platforms with multiple instances of the DesignWare interrupt aggregator. Also ensure that the initialize function calls irq_enable(). The calculation of the _sw_isr_table entry also now takes CONFIG_GEN_IRQ_START_VECTOR into account. Signed-off-by: Aaron Fong <afong@tenstorrent.com>
1 parent bb20f35 commit b2602ea

File tree

1 file changed

+27
-25
lines changed

1 file changed

+27
-25
lines changed

drivers/interrupt_controller/intc_dw.c

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ static ALWAYS_INLINE void dw_ictl_dispatch_child_isrs(uint32_t intr_status,
3030
while (intr_status) {
3131
intr_bitpos = find_lsb_set(intr_status) - 1;
3232
intr_status &= ~(1 << intr_bitpos);
33-
intr_offset = isr_base_offset + intr_bitpos;
33+
intr_offset = isr_base_offset + intr_bitpos - CONFIG_GEN_IRQ_START_VECTOR;
3434
_sw_isr_table[intr_offset].isr(
3535
_sw_isr_table[intr_offset].arg);
3636
}
@@ -39,13 +39,16 @@ static ALWAYS_INLINE void dw_ictl_dispatch_child_isrs(uint32_t intr_status,
3939
static int dw_ictl_initialize(const struct device *dev)
4040
{
4141
const struct dw_ictl_config *config = dev->config;
42+
#error "fail"
4243
volatile struct dw_ictl_registers * const regs =
4344
(struct dw_ictl_registers *)config->base_addr;
4445

4546
/* disable all interrupts */
4647
regs->irq_inten_l = 0U;
4748
regs->irq_inten_h = 0U;
4849

50+
config->config_func(dev);
51+
4952
return 0;
5053
}
5154

@@ -130,34 +133,33 @@ static int dw_ictl_intr_get_line_state(const struct device *dev,
130133
return 0;
131134
}
132135

133-
static void dw_ictl_config_irq(const struct device *dev);
134-
135-
static const struct dw_ictl_config dw_config = {
136-
.base_addr = DT_INST_REG_ADDR(0),
137-
.numirqs = DT_INST_PROP(0, num_irqs),
138-
.isr_table_offset = CONFIG_DW_ISR_TBL_OFFSET,
139-
.config_func = dw_ictl_config_irq,
140-
};
141-
142136
static const struct irq_next_level_api dw_ictl_apis = {
143137
.intr_enable = dw_ictl_intr_enable,
144138
.intr_disable = dw_ictl_intr_disable,
145139
.intr_get_state = dw_ictl_intr_get_state,
146140
.intr_get_line_state = dw_ictl_intr_get_line_state,
147141
};
148142

149-
DEVICE_DT_INST_DEFINE(0, dw_ictl_initialize, NULL,
150-
NULL, &dw_config, PRE_KERNEL_1,
151-
CONFIG_DW_ICTL_INIT_PRIORITY, &dw_ictl_apis);
152-
153-
static void dw_ictl_config_irq(const struct device *port)
154-
{
155-
IRQ_CONNECT(DT_INST_IRQN(0),
156-
DT_INST_IRQ(0, priority),
157-
dw_ictl_isr,
158-
DEVICE_DT_INST_GET(0),
159-
DT_INST_IRQ(0, sense));
160-
}
161-
162-
IRQ_PARENT_ENTRY_DEFINE(intc_dw, DEVICE_DT_INST_GET(0), DT_INST_IRQN(0),
163-
INTC_INST_ISR_TBL_OFFSET(0), DT_INST_INTC_GET_AGGREGATOR_LEVEL(0));
143+
#define INTC_DW_DEVICE_INIT(inst) \
144+
\
145+
static void dw_ictl_config_irq_##inst(const struct device *port) \
146+
{ \
147+
IRQ_CONNECT(DT_INST_IRQN(inst), DT_INST_IRQ(inst, priority), dw_ictl_isr, \
148+
DEVICE_DT_INST_GET(inst), DT_INST_IRQ(inst, sense)); \
149+
irq_enable(DT_INST_IRQN(inst)); \
150+
} \
151+
IRQ_PARENT_ENTRY_DEFINE(intc_dw##inst, DEVICE_DT_INST_GET(inst), DT_INST_IRQN(inst), \
152+
INTC_INST_ISR_TBL_OFFSET(inst), \
153+
DT_INST_INTC_GET_AGGREGATOR_LEVEL(inst)); \
154+
\
155+
static const struct dw_ictl_config dw_config_##inst = { \
156+
.base_addr = DT_INST_REG_ADDR(inst), \
157+
.numirqs = DT_INST_PROP(inst, num_irqs), \
158+
.isr_table_offset = INTC_INST_ISR_TBL_OFFSET(inst), \
159+
.config_func = dw_ictl_config_irq_##inst, \
160+
}; \
161+
\
162+
DEVICE_DT_INST_DEFINE(inst, dw_ictl_initialize, NULL, NULL, &dw_config_##inst, \
163+
PRE_KERNEL_1, CONFIG_DW_ICTL_INIT_PRIORITY, &dw_ictl_apis);
164+
165+
DT_INST_FOREACH_STATUS_OKAY(INTC_DW_DEVICE_INIT)

0 commit comments

Comments
 (0)