From 1f8682f8a0114730274c17633ad3d453e084a652 Mon Sep 17 00:00:00 2001
From: Thomas Chou <thomas@wytron.com.tw>
Date: Sat, 19 Jan 2008 22:57:51 +0800
Subject: [PATCH] nios2: fix software exception check

The check of software_exception is incorrect. If any disabled irq line
is active, software_exception won't work. And the system will hang.

We must check "ienable" before handling hardware interrupts.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
---
 linux-2.6.x/arch/nios2nommu/kernel/entry.S |   23 ++++++++++-------------
 1 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/linux-2.6.x/arch/nios2nommu/kernel/entry.S b/linux-2.6.x/arch/nios2nommu/kernel/entry.S
index 8b4ea34..d8a50c4 100644
--- a/linux-2.6.x/arch/nios2nommu/kernel/entry.S
+++ b/linux-2.6.x/arch/nios2nommu/kernel/entry.S
@@ -158,6 +158,8 @@ ENTRY(inthandler)
 	andi	r24,r24,1
 	beq	r24,r0,software_exception
 	rdctl	r12,ipending
+	rdctl	r9,ienable
+	and	r12,r12,r9
 	beq	r12,r0,software_exception
 
 	movi	r24,-1
@@ -169,24 +171,19 @@ ENTRY(inthandler)
 
 	addi	ea,ea,-4		/* re-issue the interrupted instruction */
 	stw	ea,PT_EA(sp)
-2:	rdctl	r9,ienable		/* Isolate possible interrupts */
-	and	r12,r12,r9
-	beq	r12,r0,ret_from_interrupt /* No one to service done */
-	movi	r4,%lo(-1)		/* Start from bit position 0, highest priority */
+2:	movi	r4,%lo(-1)		/* Start from bit position 0, highest priority */
 					/* This is the IRQ # for handler call */
-1:	addi	r4,r4,1
-	srl	r10,r12,r4
-	andi	r10,r10,1		/* Isolate bit we are interested in */
-	cmpeqi	r11,r4,32		  /* ? End of the register */
-	bne	r11,r0,ret_from_interrupt /* Y - out of here */
+1:	andi	r10,r12,1		/* Isolate bit we are interested in */
+	srli	r12,r12,1		/* shift count is costly without hardware multiplier */
+	addi	r4,r4,1
 	beq	r10,r0,1b
 	mov	r5,sp			/* Setup pt_regs pointer for handler call */
-	PUSH	r4			/* Save state for return */
-	PUSH	r12
 	call	process_int
-	addi	sp,sp,8			/* pop r12,r4 */
 	rdctl	r12,ipending		/* check again if irq still pending */
-	bne	r12,r0,2b
+	rdctl	r9,ienable		/* Isolate possible interrupts */
+	and	r12,r12,r9
+	bne	r12,r0,2b		
+	br	ret_from_interrupt	
 
 ENTRY(ret_from_interrupt)
 	ldw	r4,PT_STATUS_EXTENSION(sp)
-- 
1.5.3.3

