Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
ARM: fix IRQ unblocking / interrupt reenabling
ARM: fix IRQ unblocking / interrupt reenabling
- Add missing part to remove processed pic from the blocked list.
- Don't disable / reenable IRQs in pic_list_deliver_irqs.
pic_deliver_irqs will do that on a per IRQ basis anyway. Also
this function is called at the moment only from pic_do_pending_ints
which in turn assumes IRQs being off.
- Remove the assert on pic_blocked_pics. It can happend that a higher
priority IRQ will interrupt our processing of a lower priority
IRQ.
- Move pic_list_unblock_irqs right after processing an ipl in
pic_list_deliver_irqs. The same would happen if we called it before
pic_list_deliver_irqs except for the last iteration, but after that
unblock would be called outside of the loop. Calling unblock without
interrupts actually being processed is not necessary on the other
hand, so the call outside of the loop can go away.
---
sys/arch/arm/pic/pic.c | 13 ++++---------
1 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/sys/arch/arm/pic/pic.c b/sys/arch/arm/pic/pic.c
index 260f9ee..c45e208 100644
--- a/sys/arch/arm/pic/pic.c
+++ b/sys/arch/arm/pic/pic.c
@@ -297,6 +297,7 @@ pic_list_unblock_irqs(void)
*iblocked = 0;
}
}
+ blocked &= ~(1 << pic_id);
#else
KASSERT(pic->pic_blocked_irqs[0] != 0);
(*pic->pic_ops->pic_unblock_irqs)(pic,
@@ -327,18 +328,15 @@ pic_list_find_pic_by_pending_ipl(uint32_t ipl_mask)
void
pic_list_deliver_irqs(register_t psw, int ipl, void *frame)
-{
+{
const uint32_t ipl_mask = __BIT(ipl);
struct pic_softc *pic;
- cpsid(I32_bit);
while ((pic = pic_list_find_pic_by_pending_ipl(ipl_mask)) != NULL) {
pic_deliver_irqs(pic, ipl, frame);
KASSERT((pic->pic_pending_ipls & ipl_mask) == 0);
}
pic_pending_ipls &= ~ipl_mask;
- if ((psw & I32_bit) == 0)
- cpsie(I32_bit);
}
void
@@ -347,7 +345,6 @@ pic_do_pending_ints(register_t psw, int newipl,
void *frame)
struct cpu_info * const ci = curcpu();
if (__predict_false(newipl == IPL_HIGH))
return;
- KASSERT(pic_blocked_pics == 0);
while ((pic_pending_ipls & ~__BIT(newipl)) > __BIT(newipl)) {
KASSERT(pic_pending_ipls < __BIT(NIPL));
for (;;) {
@@ -357,14 +354,12 @@ pic_do_pending_ints(register_t psw, int newipl,
void *frame)
break;
ci->ci_cpl = ipl;
- pic_list_unblock_irqs();
pic_list_deliver_irqs(psw, ipl, frame);
+ pic_list_unblock_irqs();
}
}
- if (ci->ci_cpl != newipl) {
+ if (ci->ci_cpl != newipl)
ci->ci_cpl = newipl;
- pic_list_unblock_irqs();
- }
#ifdef __HAVE_FAST_SOFTINTS
cpu_dosoftints();
#endif
--
1.5.4.2
Home |
Main Index |
Thread Index |
Old Index