[Sound-open-firmware] [PATCH 0/7] interrupt refinement
The issues for original data structure and algorithm are: (1)it only supports 2 level interrupt architecture. (2)it doesn't support different HW interrupt shares one IRQ value. (3)it doesn't support multi-core.
The refinement is based on the prototype provided by Liam. refine irq data structure to make it support more than 2 level and issue(2). Add multi-core support in interrupt setting
test on CNL & APL & BYT, pass SOF: master 85ae8e74181f kernel: v4.14 2cd03d26b66f8fee2 SOF-tools: master 56e26dd528b6c77
Rander Wang (7): interrupt: refine irq structure and algorithm interrupt: add irq id in IRQ cnl-interrupt: refine interrupt setting for change in irq_desc cnl-dma: remove special dma code for cnl apl-interrupt: refine interrupt code according to interrupt change byt-interrupt: port irq change to byt hsw-interrupt: port irq change to hsw
src/drivers/dw-dma.c | 32 +-- src/include/sof/interrupt-map.h | 17 ++ src/include/sof/interrupt.h | 32 +-- src/lib/interrupt.c | 120 +++++------ .../apollolake/include/platform/interrupt.h | 2 +- src/platform/apollolake/include/platform/memory.h | 4 +- .../apollolake/include/platform/platform.h | 2 + src/platform/apollolake/interrupt.c | 210 ++++++++++++-------- src/platform/baytrail/include/platform/interrupt.h | 2 +- src/platform/cannonlake/dma.c | 2 +- .../cannonlake/include/platform/interrupt.h | 16 +- src/platform/cannonlake/include/platform/memory.h | 2 +- .../cannonlake/include/platform/platform.h | 2 + src/platform/cannonlake/interrupt.c | 220 +++++++++++++-------- src/platform/haswell/include/platform/interrupt.h | 2 +- 15 files changed, 382 insertions(+), 283 deletions(-)
The issues for original data structure and algorithm are: (1)it only support 2 level interrupt architecture. (2)it doesn't support different HW interrupt shares one IRQ value.
Unify irq parent and child to irq_desc. Now each irq_desc maybe directly attach to xtensa core or another irq_desc.Each irq_desc may have 32 child lists instead of 32 child.
Signed-off-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/include/sof/interrupt.h | 32 ++++++------ src/lib/interrupt.c | 120 +++++++++++++++++++++++--------------------- 2 files changed, 79 insertions(+), 73 deletions(-)
diff --git a/src/include/sof/interrupt.h b/src/include/sof/interrupt.h index 2dc8954..f5c37c3 100644 --- a/src/include/sof/interrupt.h +++ b/src/include/sof/interrupt.h @@ -37,27 +37,29 @@ #include <sof/trace.h> #include <sof/debug.h> #include <sof/lock.h> +#include <sof/list.h>
#define trace_irq(__e) trace_event(TRACE_CLASS_IRQ, __e) #define trace_irq_error(__e) trace_error(TRACE_CLASS_IRQ, __e)
-/* child interrupt source */ -struct irq_child { - uint32_t enabled; +struct irq_desc { + /* irq must be first for constructor */ + int irq; /* logical IRQ number */
+ /* handler is optional for constructor */ void (*handler)(void *arg); void *handler_arg; -};
-/* parent source */ -struct irq_parent { - int num; - void (*handler)(void *arg); - uint32_t enabled_count; + /* to identify interrupt with the same IRQ */ + int id; spinlock_t lock; + uint32_t enabled_count; + + /* to link to other irq_desc */ + struct list_item irq_list;
uint32_t num_children; - struct irq_child *child[PLATFORM_IRQ_CHILDREN]; + struct list_item child[PLATFORM_IRQ_CHILDREN]; };
int interrupt_register(uint32_t irq, @@ -87,10 +89,10 @@ static inline void interrupt_global_enable(uint32_t flags) }
/* called by platform interrupt ops */ -int irq_register_child(struct irq_parent *parent, int irq, - void (*handler)(void *arg), void *arg); -void irq_unregister_child(struct irq_parent *parent, int irq); -uint32_t irq_enable_child(struct irq_parent *parent, int irq); -uint32_t irq_disable_child(struct irq_parent *parent, int irq); +int irq_register_child(struct irq_desc *parent, int irq, + void (*handler)(void *arg), void *arg); +void irq_unregister_child(struct irq_desc *parent, int irq); +uint32_t irq_enable_child(struct irq_desc *parent, int irq); +uint32_t irq_disable_child(struct irq_desc *parent, int irq);
#endif diff --git a/src/lib/interrupt.c b/src/lib/interrupt.c index e8e2899..e53d4c8 100644 --- a/src/lib/interrupt.c +++ b/src/lib/interrupt.c @@ -38,127 +38,131 @@ #include <stdint.h> #include <stdlib.h>
-int irq_register_child(struct irq_parent *parent, int irq, - void (*handler)(void *arg), void *arg) +int irq_register_child(struct irq_desc *parent, int irq, + void (*handler)(void *arg), void *arg) { int ret = 0; + struct irq_desc *child;
if (parent == NULL) return -EINVAL;
spin_lock(&parent->lock);
- /* does child already exist ? */ - if (parent->child[SOF_IRQ_BIT(irq)]) { - /* already registered, return */ - goto finish; - } - /* init child */ - parent->child[SOF_IRQ_BIT(irq)] = - rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM, - sizeof(struct irq_child)); - parent->child[SOF_IRQ_BIT(irq)]->enabled = 0; - parent->child[SOF_IRQ_BIT(irq)]->handler = handler; - parent->child[SOF_IRQ_BIT(irq)]->handler_arg = arg; + child = rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM, + sizeof(struct irq_desc)); + child->enabled_count = 0; + child->handler = handler; + child->handler_arg = arg; + child->id = SOF_IRQ_ID(irq); + + list_item_append(&child->irq_list, &parent->child[SOF_IRQ_BIT(irq)]);
/* do we need to register parent ? */ if (parent->num_children == 0) { - ret = arch_interrupt_register(parent->num, - parent->handler, parent); + ret = arch_interrupt_register(parent->irq, + parent->handler, parent); }
/* increment number of children */ - parent->num_children += 1; + parent->num_children++;
-finish: spin_unlock(&parent->lock); return ret; - }
-void irq_unregister_child(struct irq_parent *parent, int irq) +void irq_unregister_child(struct irq_desc *parent, int irq) { spin_lock(&parent->lock); + struct irq_desc *child; + struct list_item *clist;
/* does child already exist ? */ - if (!parent->child[SOF_IRQ_BIT(irq)]) + if (list_is_empty(&parent->child[SOF_IRQ_BIT(irq)])) goto finish;
- /* free child */ - parent->num_children -= 1; - rfree(parent->child[SOF_IRQ_BIT(irq)]); - parent->child[SOF_IRQ_BIT(irq)] = NULL; + list_for_item(clist, &parent->child[SOF_IRQ_BIT(irq)]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (SOF_IRQ_ID(irq) == child->id) { + list_item_del(&child->irq_list); + rfree(child); + parent->num_children--; + } + }
/* * unregister the root interrupt if the this l2 is * the last registered one. */ if (parent->num_children == 0) - arch_interrupt_unregister(parent->num); + arch_interrupt_unregister(parent->irq);
finish: spin_unlock(&parent->lock); }
-uint32_t irq_enable_child(struct irq_parent *parent, int irq) +uint32_t irq_enable_child(struct irq_desc *parent, int irq) { - struct irq_child *child; + struct irq_desc *child; + struct list_item *clist;
spin_lock(&parent->lock);
- child = parent->child[SOF_IRQ_BIT(irq)]; - - /* already enabled ? */ - if (child->enabled) - goto finish; - /* enable the parent interrupt */ if (parent->enabled_count == 0) arch_interrupt_enable_mask(1 << SOF_IRQ_NUMBER(irq)); - child->enabled = 1; - parent->enabled_count++;
- /* enable the child interrupt */ - platform_interrupt_unmask(irq, 0); + list_for_item(clist, &parent->child[SOF_IRQ_BIT(irq)]) { + child = container_of(clist, struct irq_desc, irq_list); + + if ((SOF_IRQ_ID(irq) == child->id) && + !child->enabled_count) { + child->enabled_count = 1; + parent->enabled_count++; + + /* enable the child interrupt */ + platform_interrupt_unmask(irq, 0); + } + }
-finish: spin_unlock(&parent->lock); return 0;
}
-uint32_t irq_disable_child(struct irq_parent *parent, int irq) +uint32_t irq_disable_child(struct irq_desc *parent, int irq) { - struct irq_child *child; + struct irq_desc *child; + struct list_item *clist;
spin_lock(&parent->lock);
- child = parent->child[SOF_IRQ_BIT(irq)]; - - /* already disabled ? */ - if (!child->enabled) - goto finish; + list_for_item(clist, &parent->child[SOF_IRQ_BIT(irq)]) { + child = container_of(clist, struct irq_desc, irq_list);
- /* disable the child interrupt */ - platform_interrupt_mask(irq, 0); - child->enabled = 0; + if ((SOF_IRQ_ID(irq) == child->id) && + child->enabled_count) { + child->enabled_count = 0; + parent->enabled_count--; + } + }
- /* disable the parent interrupt */ - parent->enabled_count--; - if (parent->enabled_count == 0) + if (parent->enabled_count == 0) { + /* disable the child interrupt */ + platform_interrupt_mask(irq, 0); arch_interrupt_disable_mask(1 << SOF_IRQ_NUMBER(irq)); + }
-finish: spin_unlock(&parent->lock); return 0; - }
int interrupt_register(uint32_t irq, void (*handler)(void *arg), void *arg) { - struct irq_parent *parent; + struct irq_desc *parent;
/* no parent means we are registering DSP internal IRQ */ parent = platform_irq_get_parent(irq); @@ -170,7 +174,7 @@ int interrupt_register(uint32_t irq,
void interrupt_unregister(uint32_t irq) { - struct irq_parent *parent; + struct irq_desc *parent;
/* no parent means we are unregistering DSP internal IRQ */ parent = platform_irq_get_parent(irq); @@ -182,7 +186,7 @@ void interrupt_unregister(uint32_t irq)
uint32_t interrupt_enable(uint32_t irq) { - struct irq_parent *parent; + struct irq_desc *parent;
/* no parent means we are enabling DSP internal IRQ */ parent = platform_irq_get_parent(irq); @@ -194,7 +198,7 @@ uint32_t interrupt_enable(uint32_t irq)
uint32_t interrupt_disable(uint32_t irq) { - struct irq_parent *parent; + struct irq_desc *parent;
/* no parent means we are disabling DSP internal IRQ */ parent = platform_irq_get_parent(irq);
On 5/4/18 3:14 AM, Rander Wang wrote:
The issues for original data structure and algorithm are: (1)it only support 2 level interrupt architecture. (2)it doesn't support different HW interrupt shares one IRQ value.
Unify irq parent and child to irq_desc. Now each irq_desc maybe directly attach to xtensa core or another irq_desc.Each irq_desc may have 32 child lists instead of 32 child.
Signed-off-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com
src/include/sof/interrupt.h | 32 ++++++------ src/lib/interrupt.c | 120 +++++++++++++++++++++++--------------------- 2 files changed, 79 insertions(+), 73 deletions(-)
diff --git a/src/include/sof/interrupt.h b/src/include/sof/interrupt.h index 2dc8954..f5c37c3 100644 --- a/src/include/sof/interrupt.h +++ b/src/include/sof/interrupt.h @@ -37,27 +37,29 @@ #include <sof/trace.h> #include <sof/debug.h> #include <sof/lock.h> +#include <sof/list.h>
#define trace_irq(__e) trace_event(TRACE_CLASS_IRQ, __e) #define trace_irq_error(__e) trace_error(TRACE_CLASS_IRQ, __e)
-/* child interrupt source */ -struct irq_child {
- uint32_t enabled;
+struct irq_desc {
/* irq must be first for constructor */
int irq; /* logical IRQ number */
/* handler is optional for constructor */ void (*handler)(void *arg); void *handler_arg;
-};
-/* parent source */ -struct irq_parent {
- int num;
- void (*handler)(void *arg);
- uint32_t enabled_count;
/* to identify interrupt with the same IRQ */
int id; spinlock_t lock;
uint32_t enabled_count;
/* to link to other irq_desc */
struct list_item irq_list;
uint32_t num_children;
- struct irq_child *child[PLATFORM_IRQ_CHILDREN];
struct list_item child[PLATFORM_IRQ_CHILDREN]; };
int interrupt_register(uint32_t irq,
@@ -87,10 +89,10 @@ static inline void interrupt_global_enable(uint32_t flags) }
/* called by platform interrupt ops */ -int irq_register_child(struct irq_parent *parent, int irq,
- void (*handler)(void *arg), void *arg);
-void irq_unregister_child(struct irq_parent *parent, int irq); -uint32_t irq_enable_child(struct irq_parent *parent, int irq); -uint32_t irq_disable_child(struct irq_parent *parent, int irq); +int irq_register_child(struct irq_desc *parent, int irq,
void (*handler)(void *arg), void *arg);
+void irq_unregister_child(struct irq_desc *parent, int irq); +uint32_t irq_enable_child(struct irq_desc *parent, int irq); +uint32_t irq_disable_child(struct irq_desc *parent, int irq);
#endif diff --git a/src/lib/interrupt.c b/src/lib/interrupt.c index e8e2899..e53d4c8 100644 --- a/src/lib/interrupt.c +++ b/src/lib/interrupt.c @@ -38,127 +38,131 @@ #include <stdint.h> #include <stdlib.h>
-int irq_register_child(struct irq_parent *parent, int irq,
- void (*handler)(void *arg), void *arg)
+int irq_register_child(struct irq_desc *parent, int irq,
void (*handler)(void *arg), void *arg)
{ int ret = 0;
struct irq_desc *child;
if (parent == NULL) return -EINVAL;
spin_lock(&parent->lock);
- /* does child already exist ? */
- if (parent->child[SOF_IRQ_BIT(irq)]) {
/* already registered, return */
goto finish;
- }
- /* init child */
- parent->child[SOF_IRQ_BIT(irq)] =
rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM,
sizeof(struct irq_child)); > - parent->child[SOF_IRQ_BIT(irq)]->enabled = 0;
- parent->child[SOF_IRQ_BIT(irq)]->handler = handler;
- parent->child[SOF_IRQ_BIT(irq)]->handler_arg = arg;
- child = rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM,
sizeof(struct irq_desc));
if (!child) ret = -ENOMEM; goto finish; }
child->enabled_count = 0;
child->handler = handler;
child->handler_arg = arg;
child->id = SOF_IRQ_ID(irq);
list_item_append(&child->irq_list, &parent->child[SOF_IRQ_BIT(irq)]);
/* do we need to register parent ? */ if (parent->num_children == 0) {
ret = arch_interrupt_register(parent->num,
parent->handler, parent);
ret = arch_interrupt_register(parent->irq,
parent->handler, parent);
}
/* increment number of children */
- parent->num_children += 1;
- parent->num_children++;
-finish: spin_unlock(&parent->lock); return ret;
- }
-void irq_unregister_child(struct irq_parent *parent, int irq) +void irq_unregister_child(struct irq_desc *parent, int irq) { spin_lock(&parent->lock);
struct irq_desc *child;
struct list_item *clist;
/* does child already exist ? */
- if (!parent->child[SOF_IRQ_BIT(irq)])
- if (list_is_empty(&parent->child[SOF_IRQ_BIT(irq)])) goto finish;
- /* free child */
- parent->num_children -= 1;
- rfree(parent->child[SOF_IRQ_BIT(irq)]);
- parent->child[SOF_IRQ_BIT(irq)] = NULL;
list_for_item(clist, &parent->child[SOF_IRQ_BIT(irq)]) {
child = container_of(clist, struct irq_desc, irq_list);
if (SOF_IRQ_ID(irq) == child->id) {
list_item_del(&child->irq_list);
rfree(child);
parent->num_children--;
}
}
/*
- unregister the root interrupt if the this l2 is
- the last registered one.
*/ if (parent->num_children == 0)
arch_interrupt_unregister(parent->num);
arch_interrupt_unregister(parent->irq);
finish: spin_unlock(&parent->lock); }
-uint32_t irq_enable_child(struct irq_parent *parent, int irq) +uint32_t irq_enable_child(struct irq_desc *parent, int irq) {
- struct irq_child *child;
struct irq_desc *child;
struct list_item *clist;
spin_lock(&parent->lock);
child = parent->child[SOF_IRQ_BIT(irq)];
/* already enabled ? */
if (child->enabled)
goto finish;
/* enable the parent interrupt */ if (parent->enabled_count == 0) arch_interrupt_enable_mask(1 << SOF_IRQ_NUMBER(irq));
child->enabled = 1;
parent->enabled_count++;
/* enable the child interrupt */
platform_interrupt_unmask(irq, 0);
- list_for_item(clist, &parent->child[SOF_IRQ_BIT(irq)]) {
child = container_of(clist, struct irq_desc, irq_list);
if ((SOF_IRQ_ID(irq) == child->id) &&
!child->enabled_count) {
child->enabled_count = 1;
parent->enabled_count++;
/* enable the child interrupt */
platform_interrupt_unmask(irq, 0);
}
- }
-finish: spin_unlock(&parent->lock); return 0;
}
-uint32_t irq_disable_child(struct irq_parent *parent, int irq) +uint32_t irq_disable_child(struct irq_desc *parent, int irq) {
- struct irq_child *child;
struct irq_desc *child;
struct list_item *clist;
spin_lock(&parent->lock);
- child = parent->child[SOF_IRQ_BIT(irq)];
- /* already disabled ? */
- if (!child->enabled)
goto finish;
- list_for_item(clist, &parent->child[SOF_IRQ_BIT(irq)]) {
child = container_of(clist, struct irq_desc, irq_list);
- /* disable the child interrupt */
- platform_interrupt_mask(irq, 0);
- child->enabled = 0;
if ((SOF_IRQ_ID(irq) == child->id) &&
child->enabled_count) {
child->enabled_count = 0;
parent->enabled_count--;
}
- }
- /* disable the parent interrupt */
- parent->enabled_count--;
- if (parent->enabled_count == 0)
- if (parent->enabled_count == 0) {
/* disable the child interrupt */
arch_interrupt_disable_mask(1 << SOF_IRQ_NUMBER(irq));platform_interrupt_mask(irq, 0);
- }
-finish: spin_unlock(&parent->lock); return 0;
}
int interrupt_register(uint32_t irq, void (*handler)(void *arg), void *arg) {
struct irq_parent *parent;
struct irq_desc *parent;
/* no parent means we are registering DSP internal IRQ */ parent = platform_irq_get_parent(irq);
@@ -170,7 +174,7 @@ int interrupt_register(uint32_t irq,
void interrupt_unregister(uint32_t irq) {
- struct irq_parent *parent;
struct irq_desc *parent;
/* no parent means we are unregistering DSP internal IRQ */ parent = platform_irq_get_parent(irq);
@@ -182,7 +186,7 @@ void interrupt_unregister(uint32_t irq)
uint32_t interrupt_enable(uint32_t irq) {
- struct irq_parent *parent;
struct irq_desc *parent;
/* no parent means we are enabling DSP internal IRQ */ parent = platform_irq_get_parent(irq);
@@ -194,7 +198,7 @@ uint32_t interrupt_enable(uint32_t irq)
uint32_t interrupt_disable(uint32_t irq) {
- struct irq_parent *parent;
struct irq_desc *parent;
/* no parent means we are disabling DSP internal IRQ */ parent = platform_irq_get_parent(irq);
For CNL or later chips, a group of HW IP(like GP-DMA) share the same IRQ value. Now add id in IRQ to identify each HW interrupt. If no IRQ shared, call SOF_IRQ to get the IRQ value, and the default id value would be zero. otherwise call SOF_ID_IRQ to record its id in IRQ value.
Signed-off-by: Rander Wang rander.wang@linux.intel.com --- src/include/sof/interrupt-map.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/src/include/sof/interrupt-map.h b/src/include/sof/interrupt-map.h index bea567a..cec85df 100644 --- a/src/include/sof/interrupt-map.h +++ b/src/include/sof/interrupt-map.h @@ -33,6 +33,7 @@
#include <config.h>
+#define SOF_IRQ_ID_SHIFT 29 #define SOF_IRQ_BIT_SHIFT 24 #define SOF_IRQ_LEVEL_SHIFT 16 #define SOF_IRQ_CPU_SHIFT 8 @@ -41,6 +42,7 @@ #define SOF_IRQ_LEVEL_MASK 0xff #define SOF_IRQ_BIT_MASK 0x1f #define SOF_IRQ_CPU_MASK 0xff +#define SOF_IRQ_ID_MASK 0x7
#define SOF_IRQ(_bit, _level, _cpu, _number) \ (((_bit) << SOF_IRQ_BIT_SHIFT) \ @@ -48,6 +50,18 @@ | ((_cpu) << SOF_IRQ_CPU_SHIFT) \ | ((_number) << SOF_IRQ_NUM_SHIFT))
+/* + * for chip CNL or later, a group of HW IP(GP-DMA) share + * the same IRQ. So add id in IRQ to identify each HW IP + * for this case, it will be 5 levels + */ +#define SOF_ID_IRQ(_id, _bit, _level, _cpu, _number) \ + (((_id) << SOF_IRQ_ID_SHIFT) \ + | ((_bit) << SOF_IRQ_BIT_SHIFT) \ + | ((_level) << SOF_IRQ_LEVEL_SHIFT) \ + | ((_cpu) << SOF_IRQ_CPU_SHIFT) \ + | ((_number) << SOF_IRQ_NUM_SHIFT)) + #ifdef CONFIG_IRQ_MAP /* * IRQs are mapped on 4 levels. @@ -65,6 +79,8 @@ (((_bit) >> SOF_IRQ_BIT_SHIFT) & SOF_IRQ_BIT_MASK) #define SOF_IRQ_CPU(_cpu) \ (((_cpu) >> SOF_IRQ_CPU_SHIFT) & SOF_IRQ_CPU_MASK) +#define SOF_IRQ_ID(_bit) \ + (((_bit) >> SOF_IRQ_ID_SHIFT) & SOF_IRQ_ID_MASK) #else /* * IRQs are directly mapped onto a single level, bit and level. @@ -73,6 +89,7 @@ #define SOF_IRQ_LEVEL(_level) 0 #define SOF_IRQ_BIT(_bit) 0 #define SOF_IRQ_CPU(_cpu) 0 +#define SOF_IRQ_ID(_bit) 0 #endif
#endif
(1)Add core id check in interrupt register setting. (2)Check child list in interrupt function (3)Extend root irq_desc to support 4 core on cnl. (4)Refine macro for interrupt setting
Signed-off-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/platform/cannonlake/dma.c | 2 +- .../cannonlake/include/platform/interrupt.h | 16 +- src/platform/cannonlake/include/platform/memory.h | 2 +- .../cannonlake/include/platform/platform.h | 2 + src/platform/cannonlake/interrupt.c | 220 +++++++++++++-------- 5 files changed, 150 insertions(+), 92 deletions(-)
diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index b606d1e..3f9d6cb 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -125,7 +125,7 @@ static struct dma dma[] = { .id = DMA_GP_LP_DMAC1, .base = LP_GP_DMA_BASE(1), .channels = 8, - .irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0), + .irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0), .drv_plat_data = &dmac1, }, .ops = &dw_dma_ops, diff --git a/src/platform/cannonlake/include/platform/interrupt.h b/src/platform/cannonlake/include/platform/interrupt.h index 03857a7..b14cfdf 100644 --- a/src/platform/cannonlake/include/platform/interrupt.h +++ b/src/platform/cannonlake/include/platform/interrupt.h @@ -88,7 +88,7 @@ #define IRQ_BIT_LVL5_DMIC 6 #define IRQ_BIT_LVL5_SSP(x) (0 + x)
-/* Level 2 Peripheral IRQ mappings */ +/* Priority 2 Peripheral IRQ mappings */ #define IRQ_EXT_HP_GPDMA_LVL2(xcpu) \ SOF_IRQ(IRQ_BIT_LVL2_HP_GP_DMA0(0), 2, xcpu, IRQ_NUM_EXT_LEVEL2) #define IRQ_EXT_IDC_LVL2(xcpu) \ @@ -106,7 +106,7 @@ #define IRQ_EXT_SHA256_LVL2(xcpu) \ SOF_IRQ(IRQ_BIT_LVL2_SHA256, 2, xcpu, IRQ_NUM_EXT_LEVEL2)
-/* Level 3 Peripheral IRQ mappings */ +/* Priority 3 Peripheral IRQ mappings */ #define IRQ_EXT_CODE_DMA_LVL3(xcpu) \ SOF_IRQ(IRQ_BIT_LVL3_CODE_LOADER, 3, xcpu, IRQ_NUM_EXT_LEVEL3) #define IRQ_EXT_HOST_DMA_IN_LVL3(xcpu, channel) \ @@ -114,17 +114,17 @@ #define IRQ_EXT_HOST_DMA_OUT_LVL3(xcpu, channel) \ SOF_IRQ(IRQ_BIT_LVL3_HOST_STREAM_OUT(channel), 3, xcpu, IRQ_NUM_EXT_LEVEL3)
-/* Level 4 Peripheral IRQ mappings */ +/* Priority 4 Peripheral IRQ mappings */ #define IRQ_EXT_LINK_DMA_IN_LVL4(xcpu, channel) \ SOF_IRQ(IRQ_BIT_LVL4_LINK_STREAM_IN(channel), 4, xcpu, IRQ_NUM_EXT_LEVEL4) #define IRQ_EXT_LINK_DMA_OUT_LVL4(xcpu, channel) \ SOF_IRQ(IRQ_BIT_LVL4_LINK_STREAM_OUT(channel), 4, xcpu, IRQ_NUM_EXT_LEVEL4)
-/* Level 5 Peripheral IRQ mappings */ +/* Priority 5 Peripheral IRQ mappings */ #define IRQ_EXT_LP_GPDMA0_LVL5(xcpu, channel) \ - SOF_IRQ(IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5) -#define IRQ_EXT_LP_GPDMA1_LVL4(xcpu, channel) \ - SOF_IRQ(IRQ_BIT_LVL5_LP_GP_DMA1, 4, xcpu, IRQ_NUM_EXT_LEVEL4) + SOF_ID_IRQ(0, IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5) +#define IRQ_EXT_LP_GPDMA1_LVL5(xcpu, channel) \ + SOF_ID_IRQ(1, IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5) #define IRQ_EXT_SSP0_LVL5(xcpu) \ SOF_IRQ(IRQ_BIT_LVL5_SSP(0), 5, xcpu, IRQ_NUM_EXT_LEVEL5) #define IRQ_EXT_SSP1_LVL5(xcpu) \ @@ -161,7 +161,7 @@
void platform_interrupt_init(void);
-struct irq_parent *platform_irq_get_parent(uint32_t irq); +struct irq_desc *platform_irq_get_parent(uint32_t irq); void platform_interrupt_set(int irq); void platform_interrupt_clear(uint32_t irq, uint32_t mask); uint32_t platform_interrupt_get_enabled(void); diff --git a/src/platform/cannonlake/include/platform/memory.h b/src/platform/cannonlake/include/platform/memory.h index c7f4750..67f574a 100644 --- a/src/platform/cannonlake/include/platform/memory.h +++ b/src/platform/cannonlake/include/platform/memory.h @@ -240,7 +240,7 @@ #define SOF_TEXT_SIZE 0x18000
/* initialized data */ -#define SOF_DATA_SIZE 0x18000 +#define SOF_DATA_SIZE 0x19000
/* bss data */ #define SOF_BSS_DATA_SIZE 0x8000 diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h index c5bf42a..3d262b4 100644 --- a/src/platform/cannonlake/include/platform/platform.h +++ b/src/platform/cannonlake/include/platform/platform.h @@ -42,6 +42,8 @@ struct sof; #define PLATFORM_SSP_COUNT 3 #define MAX_GPDMA_COUNT 2
+#define MAX_CORE_COUNT 4 + /* Host page size */ #define HOST_PAGE_SIZE 4096 #define PLATFORM_PAGE_TABLE_SIZE 256 diff --git a/src/platform/cannonlake/interrupt.c b/src/platform/cannonlake/interrupt.c index 8c47e14..e9ef4e7 100644 --- a/src/platform/cannonlake/interrupt.c +++ b/src/platform/cannonlake/interrupt.c @@ -39,19 +39,22 @@ #include <stdint.h> #include <stdlib.h>
-static void parent_level2_handler(void *data) +static void irq_lvl2_level2_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL2);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL2SD(0)); - irq_write(REG_IRQ_IL2MSD(0), status); + status = irq_read(REG_IRQ_IL2SD(core)); + irq_write(REG_IRQ_IL2MSD(core), status);
/* handle each child */ while (status) { @@ -61,17 +64,22 @@ static void parent_level2_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL2MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL2MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -82,19 +90,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL2); }
-static void parent_level3_handler(void *data) +static void irq_lvl2_level3_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL3);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL3SD(0)); - irq_write(REG_IRQ_IL3MSD(0), status); + status = irq_read(REG_IRQ_IL3SD(core)); + irq_write(REG_IRQ_IL3MSD(core), status);
/* handle each child */ while (status) { @@ -104,17 +115,22 @@ static void parent_level3_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL3MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL3MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -125,19 +141,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL3); }
-static void parent_level4_handler(void *data) +static void irq_lvl2_level4_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL4);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL4SD(0)); - irq_write(REG_IRQ_IL4MSD(0), status); + status = irq_read(REG_IRQ_IL4SD(core)); + irq_write(REG_IRQ_IL4MSD(core), status);
/* handle each child */ while (status) { @@ -147,17 +166,22 @@ static void parent_level4_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL4MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL4MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -168,19 +192,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL4); }
-static void parent_level5_handler(void *data) +static void irq_lvl2_level5_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL5);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL5SD(0)); - irq_write(REG_IRQ_IL5MSD(0), status); + status = irq_read(REG_IRQ_IL5SD(core)); + irq_write(REG_IRQ_IL5MSD(core), status);
/* handle each child */ while (status) { @@ -190,17 +217,22 @@ static void parent_level5_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL5MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL5MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -212,24 +244,41 @@ next: }
/* DSP internal interrupts */ -static struct irq_parent dsp_irq[4] = { - {IRQ_NUM_EXT_LEVEL2, parent_level2_handler, }, - {IRQ_NUM_EXT_LEVEL3, parent_level3_handler, }, - {IRQ_NUM_EXT_LEVEL4, parent_level4_handler, }, - {IRQ_NUM_EXT_LEVEL5, parent_level5_handler, }, +static struct irq_desc dsp_irq[MAX_CORE_COUNT][4] = { + {{IRQ_NUM_EXT_LEVEL2, irq_lvl2_level2_handler, }, + {IRQ_NUM_EXT_LEVEL3, irq_lvl2_level3_handler, }, + {IRQ_NUM_EXT_LEVEL4, irq_lvl2_level4_handler, }, + {IRQ_NUM_EXT_LEVEL5, irq_lvl2_level5_handler, } }, + + {{IRQ_NUM_EXT_LEVEL2, irq_lvl2_level2_handler, }, + {IRQ_NUM_EXT_LEVEL3, irq_lvl2_level3_handler, }, + {IRQ_NUM_EXT_LEVEL4, irq_lvl2_level4_handler, }, + {IRQ_NUM_EXT_LEVEL5, irq_lvl2_level5_handler, } }, + + {{IRQ_NUM_EXT_LEVEL2, irq_lvl2_level2_handler, }, + {IRQ_NUM_EXT_LEVEL3, irq_lvl2_level3_handler, }, + {IRQ_NUM_EXT_LEVEL4, irq_lvl2_level4_handler, }, + {IRQ_NUM_EXT_LEVEL5, irq_lvl2_level5_handler, } }, + + {{IRQ_NUM_EXT_LEVEL2, irq_lvl2_level2_handler, }, + {IRQ_NUM_EXT_LEVEL3, irq_lvl2_level3_handler, }, + {IRQ_NUM_EXT_LEVEL4, irq_lvl2_level4_handler, }, + {IRQ_NUM_EXT_LEVEL5, irq_lvl2_level5_handler, } }, };
-struct irq_parent *platform_irq_get_parent(uint32_t irq) +struct irq_desc *platform_irq_get_parent(uint32_t irq) { + int core = xthal_get_prid(); + switch (SOF_IRQ_NUMBER(irq)) { case IRQ_NUM_EXT_LEVEL2: - return &dsp_irq[0]; + return &dsp_irq[core][0]; case IRQ_NUM_EXT_LEVEL3: - return &dsp_irq[1]; + return &dsp_irq[core][1]; case IRQ_NUM_EXT_LEVEL4: - return &dsp_irq[2]; + return &dsp_irq[core][2]; case IRQ_NUM_EXT_LEVEL5: - return &dsp_irq[3]; + return &dsp_irq[core][3]; default: return NULL; } @@ -242,19 +291,21 @@ uint32_t platform_interrupt_get_enabled(void)
void platform_interrupt_mask(uint32_t irq, uint32_t mask) { + int core = xthal_get_prid(); + /* mask external interrupt bit */ switch (SOF_IRQ_NUMBER(irq)) { case IRQ_NUM_EXT_LEVEL5: - irq_write(REG_IRQ_IL5MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL5MSD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL4: - irq_write(REG_IRQ_IL4MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL4MSD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL3: - irq_write(REG_IRQ_IL3MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL3MSD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL2: - irq_write(REG_IRQ_IL2MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL2MSD(core), 1 << SOF_IRQ_BIT(irq)); break; default: break; @@ -264,19 +315,21 @@ void platform_interrupt_mask(uint32_t irq, uint32_t mask)
void platform_interrupt_unmask(uint32_t irq, uint32_t mask) { + int core = xthal_get_prid(); + /* unmask external interrupt bit */ switch (SOF_IRQ_NUMBER(irq)) { case IRQ_NUM_EXT_LEVEL5: - irq_write(REG_IRQ_IL5MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL5MCD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL4: - irq_write(REG_IRQ_IL4MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL4MCD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL3: - irq_write(REG_IRQ_IL3MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL3MCD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL2: - irq_write(REG_IRQ_IL2MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL2MCD(core), 1 << SOF_IRQ_BIT(irq)); break; default: break; @@ -290,15 +343,18 @@ void platform_interrupt_clear(uint32_t irq, uint32_t mask)
void platform_interrupt_init(void) { - int i; + int i, j; + int core = xthal_get_prid();
/* mask all external IRQs by default */ - irq_write(REG_IRQ_IL2MSD(0), REG_IRQ_IL2MD_ALL); - irq_write(REG_IRQ_IL3MSD(0), REG_IRQ_IL3MD_ALL); - irq_write(REG_IRQ_IL4MSD(0), REG_IRQ_IL4MD_ALL); - irq_write(REG_IRQ_IL5MSD(0), REG_IRQ_IL5MD_ALL); - - for (i = 0; i < ARRAY_SIZE(dsp_irq); i++) { - spinlock_init(&dsp_irq[i].lock); + irq_write(REG_IRQ_IL2MSD(core), REG_IRQ_IL2MD_ALL); + irq_write(REG_IRQ_IL3MSD(core), REG_IRQ_IL3MD_ALL); + irq_write(REG_IRQ_IL4MSD(core), REG_IRQ_IL4MD_ALL); + irq_write(REG_IRQ_IL5MSD(core), REG_IRQ_IL5MD_ALL); + + for (i = 0; i < ARRAY_SIZE(dsp_irq[core]); i++) { + spinlock_init(&dsp_irq[core][i].lock); + for (j = 0; j < PLATFORM_IRQ_CHILDREN; j++) + list_init(&dsp_irq[core][i].child[j]); } }
On Fri, 2018-05-04 at 16:14 +0800, Rander Wang wrote:
(1)Add core id check in interrupt register setting. (2)Check child list in interrupt function (3)Extend root irq_desc to support 4 core on cnl. (4)Refine macro for interrupt setting
Signed-off-by: Rander Wang rander.wang@linux.intel.com Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com
src/platform/cannonlake/dma.c | 2 +- .../cannonlake/include/platform/interrupt.h | 16 +- src/platform/cannonlake/include/platform/memory.h | 2 +- .../cannonlake/include/platform/platform.h | 2 + src/platform/cannonlake/interrupt.c | 220 +++++++++++++-------
5 files changed, 150 insertions(+), 92 deletions(-)
diff --git a/src/platform/cannonlake/dma.c b/src/platform/cannonlake/dma.c index b606d1e..3f9d6cb 100644 --- a/src/platform/cannonlake/dma.c +++ b/src/platform/cannonlake/dma.c @@ -125,7 +125,7 @@ static struct dma dma[] = { .id = DMA_GP_LP_DMAC1, .base = LP_GP_DMA_BASE(1), .channels = 8,
.irq = IRQ_EXT_LP_GPDMA0_LVL5(0, 0),
.drv_plat_data = &dmac1, }, .ops = &dw_dma_ops,.irq = IRQ_EXT_LP_GPDMA1_LVL5(0, 0),
diff --git a/src/platform/cannonlake/include/platform/interrupt.h b/src/platform/cannonlake/include/platform/interrupt.h index 03857a7..b14cfdf 100644 --- a/src/platform/cannonlake/include/platform/interrupt.h +++ b/src/platform/cannonlake/include/platform/interrupt.h @@ -88,7 +88,7 @@ #define IRQ_BIT_LVL5_DMIC 6 #define IRQ_BIT_LVL5_SSP(x) (0 + x)
-/* Level 2 Peripheral IRQ mappings */ +/* Priority 2 Peripheral IRQ mappings */ #define IRQ_EXT_HP_GPDMA_LVL2(xcpu) \ SOF_IRQ(IRQ_BIT_LVL2_HP_GP_DMA0(0), 2, xcpu, IRQ_NUM_EXT_LEVEL2) #define IRQ_EXT_IDC_LVL2(xcpu) \ @@ -106,7 +106,7 @@ #define IRQ_EXT_SHA256_LVL2(xcpu) \ SOF_IRQ(IRQ_BIT_LVL2_SHA256, 2, xcpu, IRQ_NUM_EXT_LEVEL2)
-/* Level 3 Peripheral IRQ mappings */ +/* Priority 3 Peripheral IRQ mappings */ #define IRQ_EXT_CODE_DMA_LVL3(xcpu) \ SOF_IRQ(IRQ_BIT_LVL3_CODE_LOADER, 3, xcpu, IRQ_NUM_EXT_LEVEL3) #define IRQ_EXT_HOST_DMA_IN_LVL3(xcpu, channel) \ @@ -114,17 +114,17 @@ #define IRQ_EXT_HOST_DMA_OUT_LVL3(xcpu, channel) \ SOF_IRQ(IRQ_BIT_LVL3_HOST_STREAM_OUT(channel), 3, xcpu, IRQ_NUM_EXT_LEVEL3)
-/* Level 4 Peripheral IRQ mappings */ +/* Priority 4 Peripheral IRQ mappings */ #define IRQ_EXT_LINK_DMA_IN_LVL4(xcpu, channel) \ SOF_IRQ(IRQ_BIT_LVL4_LINK_STREAM_IN(channel), 4, xcpu, IRQ_NUM_EXT_LEVEL4) #define IRQ_EXT_LINK_DMA_OUT_LVL4(xcpu, channel) \ SOF_IRQ(IRQ_BIT_LVL4_LINK_STREAM_OUT(channel), 4, xcpu, IRQ_NUM_EXT_LEVEL4)
-/* Level 5 Peripheral IRQ mappings */ +/* Priority 5 Peripheral IRQ mappings */ #define IRQ_EXT_LP_GPDMA0_LVL5(xcpu, channel) \
- SOF_IRQ(IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5)
-#define IRQ_EXT_LP_GPDMA1_LVL4(xcpu, channel) \
- SOF_IRQ(IRQ_BIT_LVL5_LP_GP_DMA1, 4, xcpu, IRQ_NUM_EXT_LEVEL4)
- SOF_ID_IRQ(0, IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5)
+#define IRQ_EXT_LP_GPDMA1_LVL5(xcpu, channel) \
- SOF_ID_IRQ(1, IRQ_BIT_LVL5_LP_GP_DMA0, 5, xcpu, IRQ_NUM_EXT_LEVEL5)
#define IRQ_EXT_SSP0_LVL5(xcpu) \ SOF_IRQ(IRQ_BIT_LVL5_SSP(0), 5, xcpu, IRQ_NUM_EXT_LEVEL5) #define IRQ_EXT_SSP1_LVL5(xcpu) \ @@ -161,7 +161,7 @@
void platform_interrupt_init(void);
-struct irq_parent *platform_irq_get_parent(uint32_t irq); +struct irq_desc *platform_irq_get_parent(uint32_t irq); void platform_interrupt_set(int irq); void platform_interrupt_clear(uint32_t irq, uint32_t mask); uint32_t platform_interrupt_get_enabled(void); diff --git a/src/platform/cannonlake/include/platform/memory.h b/src/platform/cannonlake/include/platform/memory.h index c7f4750..67f574a 100644 --- a/src/platform/cannonlake/include/platform/memory.h +++ b/src/platform/cannonlake/include/platform/memory.h @@ -240,7 +240,7 @@ #define SOF_TEXT_SIZE 0x18000
/* initialized data */ -#define SOF_DATA_SIZE 0x18000 +#define SOF_DATA_SIZE 0x19000
/* bss data */ #define SOF_BSS_DATA_SIZE 0x8000 diff --git a/src/platform/cannonlake/include/platform/platform.h b/src/platform/cannonlake/include/platform/platform.h index c5bf42a..3d262b4 100644 --- a/src/platform/cannonlake/include/platform/platform.h +++ b/src/platform/cannonlake/include/platform/platform.h @@ -42,6 +42,8 @@ struct sof; #define PLATFORM_SSP_COUNT 3 #define MAX_GPDMA_COUNT 2
+#define MAX_CORE_COUNT 4
/* Host page size */ #define HOST_PAGE_SIZE 4096 #define PLATFORM_PAGE_TABLE_SIZE 256 diff --git a/src/platform/cannonlake/interrupt.c b/src/platform/cannonlake/interrupt.c index 8c47e14..e9ef4e7 100644 --- a/src/platform/cannonlake/interrupt.c +++ b/src/platform/cannonlake/interrupt.c @@ -39,19 +39,22 @@ #include <stdint.h> #include <stdlib.h>
-static void parent_level2_handler(void *data) +static void irq_lvl2_level2_handler(void *data) {
- struct irq_parent *parent = (struct irq_parent *)data;
- struct irq_child * child = NULL;
struct irq_desc *parent = (struct irq_desc *)data;
struct irq_desc *child = NULL;
struct list_item *clist; uint32_t status; uint32_t i = 0;
uint32_t unmask = 0;
int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL2);
/* mask all child interrupts */
- status = irq_read(REG_IRQ_IL2SD(0));
- irq_write(REG_IRQ_IL2MSD(0), status);
status = irq_read(REG_IRQ_IL2SD(core));
irq_write(REG_IRQ_IL2MSD(core), status);
/* handle each child */ while (status) {
@@ -61,17 +64,22 @@ static void parent_level2_handler(void *data) goto next;
/* get child if any and run handler */
child = parent->child[i];
if (child && child->handler) {
child->handler(child->handler_arg);
/* unmask this bit i interrupt */
irq_write(REG_IRQ_IL2MCD(0), 0x1 << i);
} else {
/* nobody cared ? */
trace_irq_error("nbc");
list_for_item(clist, &parent->child[i]) {
child = container_of(clist, struct irq_desc,
irq_list);
if (child && child->handler) {
child->handler(child->handler_arg);
unmask = 1;
} else {
/* nobody cared ? */
trace_irq_error("nbc");
}
}
/* unmask this bit i interrupt */
if (unmask)
irq_write(REG_IRQ_IL2MCD(core), 0x1 << i);
next: status >>= 1; i++; @@ -82,19 +90,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL2); }
-static void parent_level3_handler(void *data) +static void irq_lvl2_level3_handler(void *data) {
- struct irq_parent *parent = (struct irq_parent *)data;
- struct irq_child * child = NULL;
struct irq_desc *parent = (struct irq_desc *)data;
struct irq_desc *child = NULL;
struct list_item *clist; uint32_t status; uint32_t i = 0;
uint32_t unmask = 0;
int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL3);
/* mask all child interrupts */
- status = irq_read(REG_IRQ_IL3SD(0));
- irq_write(REG_IRQ_IL3MSD(0), status);
status = irq_read(REG_IRQ_IL3SD(core));
irq_write(REG_IRQ_IL3MSD(core), status);
/* handle each child */ while (status) {
@@ -104,17 +115,22 @@ static void parent_level3_handler(void *data) goto next;
/* get child if any and run handler */
child = parent->child[i];
if (child && child->handler) {
child->handler(child->handler_arg);
/* unmask this bit i interrupt */
irq_write(REG_IRQ_IL3MCD(0), 0x1 << i);
} else {
/* nobody cared ? */
trace_irq_error("nbc");
list_for_item(clist, &parent->child[i]) {
child = container_of(clist, struct irq_desc,
irq_list);
if (child && child->handler) {
child->handler(child->handler_arg);
unmask = 1;
} else {
/* nobody cared ? */
trace_irq_error("nbc");
}
}
/* unmask this bit i interrupt */
if (unmask)
irq_write(REG_IRQ_IL3MCD(core), 0x1 << i);
next: status >>= 1; i++; @@ -125,19 +141,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL3); }
-static void parent_level4_handler(void *data) +static void irq_lvl2_level4_handler(void *data) {
- struct irq_parent *parent = (struct irq_parent *)data;
- struct irq_child * child = NULL;
- struct irq_desc *parent = (struct irq_desc *)data;
- struct irq_desc *child = NULL;
- struct list_item *clist; uint32_t status; uint32_t i = 0;
- uint32_t unmask = 0;
- int core = xthal_get_prid();
We cant call this directly in "generic" code. Can you send a separate patch that wraps this as a static inline or better still does inline assembly (as a static inline).
Liam
These code is for CNL for it is not supported that two HW IPs share one irq pin. Now it is resolved in new algorithm, so delete it.
Signed-off-by: Rander Wang rander.wang@linux.intel.com --- src/drivers/dw-dma.c | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-)
diff --git a/src/drivers/dw-dma.c b/src/drivers/dw-dma.c index e0fbc5f..f16153f 100644 --- a/src/drivers/dw-dma.c +++ b/src/drivers/dw-dma.c @@ -1054,7 +1054,7 @@ static void dw_dma_irq_handler(void *data)
status_intr = dw_read(dma, DW_INTR_STATUS); if (!status_intr) { - trace_dma_error("eI0"); + return; }
tracev_dma("DIr"); @@ -1144,32 +1144,6 @@ static void dw_dma_irq_handler(void *data) } }
-#if defined CONFIG_CANNONLAKE -/*All the dma share the same interrupt on CNL, so check each dma*/ -/*controller when interrupt coming, then do the work */ -static void dw_dma_irq_cnl(void *data) -{ - struct dma *dma; - uint32_t status_intr; - - /*check interrupt status of DMA controller 0*/ - dma = dma_get(DMA_GP_LP_DMAC0); - if (dma) { - status_intr = dw_read(dma, DW_INTR_STATUS); - if (status_intr) - dw_dma_irq_handler(dma); - } - - /*check interrupt status of DMA controller 1*/ - dma = dma_get(DMA_GP_LP_DMAC1); - if (dma) { - status_intr = dw_read(dma, DW_INTR_STATUS); - if (status_intr) - dw_dma_irq_handler(dma); - } -} -#endif - static int dw_dma_probe(struct dma *dma) { struct dma_pdata *dw_pdata; @@ -1192,11 +1166,7 @@ static int dw_dma_probe(struct dma *dma) }
/* register our IRQ handler */ -#if defined CONFIG_CANNONLAKE - interrupt_register(dma_irq(dma), dw_dma_irq_cnl, dma); -#else interrupt_register(dma_irq(dma), dw_dma_irq_handler, dma); -#endif interrupt_enable(dma_irq(dma));
return 0;
Port the change on cnl to apl
Signed-off-by: Rander Wang rander.wang@linux.intel.com --- .../apollolake/include/platform/interrupt.h | 2 +- src/platform/apollolake/include/platform/memory.h | 4 +- .../apollolake/include/platform/platform.h | 2 + src/platform/apollolake/interrupt.c | 210 +++++++++++++-------- 4 files changed, 133 insertions(+), 85 deletions(-)
diff --git a/src/platform/apollolake/include/platform/interrupt.h b/src/platform/apollolake/include/platform/interrupt.h index 8e29deb..6778661 100644 --- a/src/platform/apollolake/include/platform/interrupt.h +++ b/src/platform/apollolake/include/platform/interrupt.h @@ -164,7 +164,7 @@
void platform_interrupt_init(void);
-struct irq_parent *platform_irq_get_parent(uint32_t irq); +struct irq_desc *platform_irq_get_parent(uint32_t irq); void platform_interrupt_set(int irq); void platform_interrupt_clear(uint32_t irq, uint32_t mask); uint32_t platform_interrupt_get_enabled(void); diff --git a/src/platform/apollolake/include/platform/memory.h b/src/platform/apollolake/include/platform/memory.h index c71d8c6..6b3f21f 100644 --- a/src/platform/apollolake/include/platform/memory.h +++ b/src/platform/apollolake/include/platform/memory.h @@ -171,7 +171,7 @@ #define SOF_TEXT_SIZE 0x19000
/* initialized data */ -#define SOF_DATA_SIZE 0x18000 +#define SOF_DATA_SIZE 0x19000
/* bss data */ #define SOF_BSS_DATA_SIZE 0x2800 @@ -180,7 +180,7 @@ #define HEAP_SYSTEM_BASE \ (SOF_TEXT_BASE + SOF_TEXT_SIZE +\ SOF_DATA_SIZE + SOF_BSS_DATA_SIZE) -#define HEAP_SYSTEM_SIZE 0x3200 +#define HEAP_SYSTEM_SIZE 0x5000
#define HEAP_RUNTIME_BASE (HEAP_SYSTEM_BASE + HEAP_SYSTEM_SIZE) #define HEAP_RUNTIME_SIZE \ diff --git a/src/platform/apollolake/include/platform/platform.h b/src/platform/apollolake/include/platform/platform.h index 8503ce2..4fed91f 100644 --- a/src/platform/apollolake/include/platform/platform.h +++ b/src/platform/apollolake/include/platform/platform.h @@ -38,6 +38,8 @@
struct sof;
+#define MAX_CORE_COUNT 2 + /* Host page size */ #define HOST_PAGE_SIZE 4096 #define PLATFORM_PAGE_TABLE_SIZE 256 diff --git a/src/platform/apollolake/interrupt.c b/src/platform/apollolake/interrupt.c index d4af079..4c76643 100644 --- a/src/platform/apollolake/interrupt.c +++ b/src/platform/apollolake/interrupt.c @@ -39,19 +39,22 @@ #include <stdint.h> #include <stdlib.h>
-static void parent_level2_handler(void *data) +static void irq_lvl2_level2_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL2);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL2SD(0)); - irq_write(REG_IRQ_IL2MSD(0), status); + status = irq_read(REG_IRQ_IL2SD(core)); + irq_write(REG_IRQ_IL2MSD(core), status);
/* handle each child */ while (status) { @@ -61,17 +64,22 @@ static void parent_level2_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL2MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL2MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -82,19 +90,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL2); }
-static void parent_level3_handler(void *data) +static void irq_lvl2_level3_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL3);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL3SD(0)); - irq_write(REG_IRQ_IL3MSD(0), status); + status = irq_read(REG_IRQ_IL3SD(core)); + irq_write(REG_IRQ_IL3MSD(core), status);
/* handle each child */ while (status) { @@ -104,17 +115,22 @@ static void parent_level3_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL3MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL3MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -125,19 +141,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL3); }
-static void parent_level4_handler(void *data) +static void irq_lvl2_level4_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL4);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL4SD(0)); - irq_write(REG_IRQ_IL4MSD(0), status); + status = irq_read(REG_IRQ_IL4SD(core)); + irq_write(REG_IRQ_IL4MSD(core), status);
/* handle each child */ while (status) { @@ -147,17 +166,22 @@ static void parent_level4_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL4MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL4MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -168,19 +192,22 @@ next: arch_interrupt_enable_mask(1 << IRQ_NUM_EXT_LEVEL4); }
-static void parent_level5_handler(void *data) +static void irq_lvl2_level5_handler(void *data) { - struct irq_parent *parent = (struct irq_parent *)data; - struct irq_child * child = NULL; + struct irq_desc *parent = (struct irq_desc *)data; + struct irq_desc *child = NULL; + struct list_item *clist; uint32_t status; uint32_t i = 0; + uint32_t unmask = 0; + int core = xthal_get_prid();
/* mask the parent IRQ */ arch_interrupt_disable_mask(1 << IRQ_NUM_EXT_LEVEL5);
/* mask all child interrupts */ - status = irq_read(REG_IRQ_IL5SD(0)); - irq_write(REG_IRQ_IL5MSD(0), status); + status = irq_read(REG_IRQ_IL5SD(core)); + irq_write(REG_IRQ_IL5MSD(core), status);
/* handle each child */ while (status) { @@ -190,17 +217,22 @@ static void parent_level5_handler(void *data) goto next;
/* get child if any and run handler */ - child = parent->child[i]; - if (child && child->handler) { - child->handler(child->handler_arg); - - /* unmask this bit i interrupt */ - irq_write(REG_IRQ_IL5MCD(0), 0x1 << i); - } else { - /* nobody cared ? */ - trace_irq_error("nbc"); + list_for_item(clist, &parent->child[i]) { + child = container_of(clist, struct irq_desc, irq_list); + + if (child && child->handler) { + child->handler(child->handler_arg); + unmask = 1; + } else { + /* nobody cared ? */ + trace_irq_error("nbc"); + } }
+ /* unmask this bit i interrupt */ + if (unmask) + irq_write(REG_IRQ_IL5MCD(core), 0x1 << i); + next: status >>= 1; i++; @@ -212,24 +244,31 @@ next: }
/* DSP internal interrupts */ -static struct irq_parent dsp_irq[4] = { - {IRQ_NUM_EXT_LEVEL2, parent_level2_handler, }, - {IRQ_NUM_EXT_LEVEL3, parent_level3_handler, }, - {IRQ_NUM_EXT_LEVEL4, parent_level4_handler, }, - {IRQ_NUM_EXT_LEVEL5, parent_level5_handler, }, +static struct irq_desc dsp_irq[MAX_CORE_COUNT][4] = { + {{IRQ_NUM_EXT_LEVEL2, irq_lvl2_level2_handler, }, + {IRQ_NUM_EXT_LEVEL3, irq_lvl2_level3_handler, }, + {IRQ_NUM_EXT_LEVEL4, irq_lvl2_level4_handler, }, + {IRQ_NUM_EXT_LEVEL5, irq_lvl2_level5_handler, } }, + + {{IRQ_NUM_EXT_LEVEL2, irq_lvl2_level2_handler, }, + {IRQ_NUM_EXT_LEVEL3, irq_lvl2_level3_handler, }, + {IRQ_NUM_EXT_LEVEL4, irq_lvl2_level4_handler, }, + {IRQ_NUM_EXT_LEVEL5, irq_lvl2_level5_handler, } }, };
-struct irq_parent *platform_irq_get_parent(uint32_t irq) +struct irq_desc *platform_irq_get_parent(uint32_t irq) { + int core = xthal_get_prid(); + switch (SOF_IRQ_NUMBER(irq)) { case IRQ_NUM_EXT_LEVEL2: - return &dsp_irq[0]; + return &dsp_irq[core][0]; case IRQ_NUM_EXT_LEVEL3: - return &dsp_irq[1]; + return &dsp_irq[core][1]; case IRQ_NUM_EXT_LEVEL4: - return &dsp_irq[2]; + return &dsp_irq[core][2]; case IRQ_NUM_EXT_LEVEL5: - return &dsp_irq[3]; + return &dsp_irq[core][3]; default: return NULL; } @@ -242,19 +281,21 @@ uint32_t platform_interrupt_get_enabled(void)
void platform_interrupt_mask(uint32_t irq, uint32_t mask) { + int core = xthal_get_prid(); + /* mask external interrupt bit */ switch (SOF_IRQ_NUMBER(irq)) { case IRQ_NUM_EXT_LEVEL5: - irq_write(REG_IRQ_IL5MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL5MSD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL4: - irq_write(REG_IRQ_IL4MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL4MSD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL3: - irq_write(REG_IRQ_IL3MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL3MSD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL2: - irq_write(REG_IRQ_IL2MSD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL2MSD(core), 1 << SOF_IRQ_BIT(irq)); break; default: break; @@ -264,19 +305,21 @@ void platform_interrupt_mask(uint32_t irq, uint32_t mask)
void platform_interrupt_unmask(uint32_t irq, uint32_t mask) { + int core = xthal_get_prid(); + /* unmask external interrupt bit */ switch (SOF_IRQ_NUMBER(irq)) { case IRQ_NUM_EXT_LEVEL5: - irq_write(REG_IRQ_IL5MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL5MCD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL4: - irq_write(REG_IRQ_IL4MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL4MCD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL3: - irq_write(REG_IRQ_IL3MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL3MCD(core), 1 << SOF_IRQ_BIT(irq)); break; case IRQ_NUM_EXT_LEVEL2: - irq_write(REG_IRQ_IL2MCD(0), 1 << SOF_IRQ_BIT(irq)); + irq_write(REG_IRQ_IL2MCD(core), 1 << SOF_IRQ_BIT(irq)); break; default: break; @@ -290,15 +333,18 @@ void platform_interrupt_clear(uint32_t irq, uint32_t mask)
void platform_interrupt_init(void) { - int i; + int i, j; + int core = xthal_get_prid();
/* mask all external IRQs by default */ - irq_write(REG_IRQ_IL2MSD(0), REG_IRQ_IL2MD_ALL); - irq_write(REG_IRQ_IL3MSD(0), REG_IRQ_IL3MD_ALL); - irq_write(REG_IRQ_IL4MSD(0), REG_IRQ_IL4MD_ALL); - irq_write(REG_IRQ_IL5MSD(0), REG_IRQ_IL5MD_ALL); - - for (i = 0; i < ARRAY_SIZE(dsp_irq); i++) { - spinlock_init(&dsp_irq[i].lock); + irq_write(REG_IRQ_IL2MSD(core), REG_IRQ_IL2MD_ALL); + irq_write(REG_IRQ_IL3MSD(core), REG_IRQ_IL3MD_ALL); + irq_write(REG_IRQ_IL4MSD(core), REG_IRQ_IL4MD_ALL); + irq_write(REG_IRQ_IL5MSD(core), REG_IRQ_IL5MD_ALL); + + for (i = 0; i < ARRAY_SIZE(dsp_irq[core]); i++) { + spinlock_init(&dsp_irq[core][i].lock); + for (j = 0; j < PLATFORM_IRQ_CHILDREN; j++) + list_init(&dsp_irq[core][i].child[j]); } }
Almost no change for byt because only one interrupt level on byt.
Signed-off-by: Rander Wang rander.wang@linux.intel.com --- src/platform/baytrail/include/platform/interrupt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/platform/baytrail/include/platform/interrupt.h b/src/platform/baytrail/include/platform/interrupt.h index 9ea2c42..d0cd17b 100644 --- a/src/platform/baytrail/include/platform/interrupt.h +++ b/src/platform/baytrail/include/platform/interrupt.h @@ -90,7 +90,7 @@
static inline void platform_interrupt_init(void) {}
-static inline struct irq_parent *platform_irq_get_parent(uint32_t irq) +static inline struct irq_desc *platform_irq_get_parent(uint32_t irq) { return NULL; }
Almost no change for hsw because only one interrupt level on hsw.
Signed-off-by: Rander Wang rander.wang@linux.intel.com --- src/platform/haswell/include/platform/interrupt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/platform/haswell/include/platform/interrupt.h b/src/platform/haswell/include/platform/interrupt.h index 603da5f..14d0e30 100644 --- a/src/platform/haswell/include/platform/interrupt.h +++ b/src/platform/haswell/include/platform/interrupt.h @@ -69,7 +69,7 @@ static inline void platform_interrupt_init(void) {}
/* haswell does not support child IRQs */ -static inline struct irq_parent *platform_irq_get_parent(uint32_t irq) +static inline struct irq_desc *platform_irq_get_parent(uint32_t irq) { return NULL; }
participants (3)
-
Liam Girdwood
-
Pierre-Louis Bossart
-
Rander Wang