提交 45fdd3bf 编写于 作者: P Peter Crosthwaite 提交者: Edgar E. Iglesias

intc/xilinx_intc: Handle level interrupt retriggering

Acking a level sensitive interrupt should have no effect if the
interrupt pin is still asserted. The current implementation requires
and edge condition to occur for setting a level sensitive IRQ, which
means an ACK can clear a level sensitive interrupt, until the original
source strobes the interrupt again.

Fix by keeping track of the interrupt pin state and setting ISR based
on this every time update_irq() is called.
Signed-off-by: NPeter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: NEdgar E. Iglesias <edgar.iglesias@gmail.com>
上级 6327c221
......@@ -49,11 +49,19 @@ struct xlx_pic
/* Runtime control registers. */
uint32_t regs[R_MAX];
/* state of the interrupt input pins */
uint32_t irq_pin_state;
};
static void update_irq(struct xlx_pic *p)
{
uint32_t i;
/* level triggered interrupt */
if (p->regs[R_MER] & 2) {
p->regs[R_ISR] |= p->irq_pin_state & ~p->c_kind_of_intr;
}
/* Update the pending register. */
p->regs[R_IPR] = p->regs[R_ISR] & p->regs[R_IER];
......@@ -135,7 +143,13 @@ static void irq_handler(void *opaque, int irq, int level)
return;
}
p->regs[R_ISR] |= (level << irq);
/* edge triggered interrupt */
if (p->c_kind_of_intr & (1 << irq) && p->regs[R_MER] & 2) {
p->regs[R_ISR] |= (level << irq);
}
p->irq_pin_state &= ~(1 << irq);
p->irq_pin_state |= level << irq;
update_irq(p);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册