Patchwork escc: fix interrupt flags

login
register
mail settings
Submitter Aurelien Jarno
Date Jan. 27, 2011, 7:32 a.m.
Message ID <1296113530-11573-1-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/80606/
State New
Headers show

Comments

Aurelien Jarno - Jan. 27, 2011, 7:32 a.m.
Recent PowerPC kernel end up in kernel panic during boot in -nographic
mode. In this mode the second serial port is used as the udbg console,
and thus a few characters are sent on this port. This activates the
tx interrupt flag, and later choke the Linux kernel, as it was not
expecting such a flag to be set.

The problem here comes from the fact that contrary to most devices the
interrupt flags are only set if the interrupt is enabled. Quoting the
datasheet: "If the corresponding IE bit is not set, the IP for that
source of interrupt will never be set."

This patch fixes that by enabling the interrupt flag only when the
corresponding interrupt is enabled.

Cc: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 hw/escc.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)
Blue Swirl - Jan. 28, 2011, 8:53 p.m.
On Thu, Jan 27, 2011 at 7:32 AM, Aurelien Jarno <aurelien@aurel32.net> wrote:
> Recent PowerPC kernel end up in kernel panic during boot in -nographic
> mode. In this mode the second serial port is used as the udbg console,
> and thus a few characters are sent on this port. This activates the
> tx interrupt flag, and later choke the Linux kernel, as it was not
> expecting such a flag to be set.
>
> The problem here comes from the fact that contrary to most devices the
> interrupt flags are only set if the interrupt is enabled. Quoting the
> datasheet: "If the corresponding IE bit is not set, the IP for that
> source of interrupt will never be set."
>
> This patch fixes that by enabling the interrupt flag only when the
> corresponding interrupt is enabled.
>
> Cc: Blue Swirl <blauwirbel@gmail.com>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

Acked-by: Blue Swirl <blauwirbel@gmail.com>

Passes also quick tests with Sparc32 and PPC.

Patch

diff --git a/hw/escc.c b/hw/escc.c
index ba60636..f6fd919 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -369,14 +369,18 @@  static inline void set_txint(ChannelState *s)
     if (!s->rxint_under_svc) {
         s->txint_under_svc = 1;
         if (s->chn == chn_a) {
-            s->rregs[R_INTR] |= INTR_TXINTA;
+            if (s->wregs[W_INTR] & INTR_TXINT) {
+                s->rregs[R_INTR] |= INTR_TXINTA;
+            }
             if (s->wregs[W_MINTR] & MINTR_STATUSHI)
                 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
             else
                 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
         } else {
             s->rregs[R_IVEC] = IVEC_TXINTB;
-            s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
+            if (s->wregs[W_INTR] & INTR_TXINT) {
+                s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
+            }
         }
     escc_update_irq(s);
     }