Port-arm archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[PATCH 5/11] ARM: fix IRQ unblocking / reenabling



--Imre
From e47051ae52dbc97b838270311abf285f16a4a2a8 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak%teleca.com@localhost>
Date: Fri, 25 Apr 2008 15:52:33 +0300
Subject: [PATCH] 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