patch-2.4.0-test2 linux/arch/ia64/kernel/irq_ia64.c

Next file: linux/arch/ia64/kernel/ivt.S
Previous file: linux/arch/ia64/kernel/irq.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/arch/ia64/kernel/irq_ia64.c linux/arch/ia64/kernel/irq_ia64.c
@@ -33,7 +33,9 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+#define IRQ_DEBUG	0
+
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
 spinlock_t ivr_read_lock;
 #endif
 
@@ -49,7 +51,7 @@
 	0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x40, 0x41
 };
 
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
 
 int usbfix;
 
@@ -63,7 +65,7 @@
 
 __setup("usbfix", usbfix_option);
 
-#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */
+#endif /* CONFIG_ITANIUM_A1_SPECIFIC */
 
 /*
  * That's where the IVT branches when we get an external
@@ -73,13 +75,8 @@
 void
 ia64_handle_irq (unsigned long vector, struct pt_regs *regs)
 {
-	unsigned long bsp, sp, saved_tpr;
-
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
-# ifndef CONFIG_SMP
-	static unsigned int max_prio = 0;
-	unsigned int prev_prio;
-# endif
+	unsigned long saved_tpr;
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
 	unsigned long eoi_ptr;
  
 # ifdef CONFIG_USB
@@ -95,18 +92,14 @@
 	spin_lock(&ivr_read_lock);
 	{
 		unsigned int tmp;
-
 		/*
 		 * Disable PCI writes
 		 */
 		outl(0x80ff81c0, 0xcf8);
 		tmp = inl(0xcfc);
 		outl(tmp | 0x400, 0xcfc);
-
 		eoi_ptr = inl(0xcfc);
-
 		vector = ia64_get_ivr();
-
 		/*
 		 * Enable PCI writes
 		 */
@@ -118,75 +111,61 @@
 	if (usbfix)
 		reenable_usb();
 # endif
+#endif /* CONFIG_ITANIUM_A1_SPECIFIC */
 
-# ifndef CONFIG_SMP
-	prev_prio = max_prio;
-	if (vector < max_prio) {
-		printk ("ia64_handle_irq: got vector %lu while %u was in progress!\n",
-			vector, max_prio);
-		
-	} else
-		max_prio = vector;
-# endif /* !CONFIG_SMP */
-#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */
-
-	/*
-	 * Always set TPR to limit maximum interrupt nesting depth to
-	 * 16 (without this, it would be ~240, which could easily lead
-	 * to kernel stack overflows.
-	 */
-	saved_tpr = ia64_get_tpr();
-	ia64_srlz_d();
-	ia64_set_tpr(vector);
-	ia64_srlz_d();
+#if IRQ_DEBUG
+	{
+		unsigned long bsp, sp;
 
-	asm ("mov %0=ar.bsp" : "=r"(bsp));
-	asm ("mov %0=sp" : "=r"(sp));
+		asm ("mov %0=ar.bsp" : "=r"(bsp));
+		asm ("mov %0=sp" : "=r"(sp));
 
-	if ((sp - bsp) < 1024) {
-		static long last_time;
-		static unsigned char count;
-
-		if (count > 5 && jiffies - last_time > 5*HZ)
-			count = 0;
-		if (++count < 5) {
-			last_time = jiffies;
-			printk("ia64_handle_irq: DANGER: less than 1KB of free stack space!!\n"
-			       "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
+		if ((sp - bsp) < 1024) {
+			static unsigned char count;
+			static long last_time;
+
+			if (count > 5 && jiffies - last_time > 5*HZ)
+				count = 0;
+			if (++count < 5) {
+				last_time = jiffies;
+				printk("ia64_handle_irq: DANGER: less than "
+				       "1KB of free stack space!!\n"
+				       "(bsp=0x%lx, sp=%lx)\n", bsp, sp);
+			}
 		}
 	}
+#endif /* IRQ_DEBUG */
 
 	/*
-	 * The interrupt is now said to be in service
+	 * Always set TPR to limit maximum interrupt nesting depth to
+	 * 16 (without this, it would be ~240, which could easily lead
+	 * to kernel stack overflows).
 	 */
-	if (vector >= NR_IRQS) {
-		printk("handle_irq: invalid vector %lu\n", vector);
-		goto out;
-	}
-
-	do_IRQ(vector, regs);
-  out:
-#ifdef CONFIG_ITANIUM_ASTEP_SPECIFIC
-	{
-		long pEOI;
-
-		asm ("mov %0=0;; (p1) mov %0=1" : "=r"(pEOI));
-		if (!pEOI) {
-			printk("Yikes: ia64_handle_irq() without pEOI!!\n");
-			asm volatile ("cmp.eq p1,p0=r0,r0" : "=r"(pEOI));
+	saved_tpr = ia64_get_tpr();
+	ia64_srlz_d();
+	do {
+		if (vector >= NR_IRQS) {
+			printk("handle_irq: invalid vector %lu\n", vector);
+			ia64_set_tpr(saved_tpr);
+			ia64_srlz_d();
+			return;
 		}
-	}
+		ia64_set_tpr(vector);
+		ia64_srlz_d();
 
-	local_irq_disable();
-# ifndef CONFIG_SMP
-	if (max_prio == vector)
-		max_prio = prev_prio;
-# endif /* !CONFIG_SMP */
-#endif /* CONFIG_ITANIUM_ASTEP_SPECIFIC */
+		do_IRQ(vector, regs);
 
-	ia64_srlz_d();
-	ia64_set_tpr(saved_tpr);
-	ia64_srlz_d();
+		/*
+		 * Disable interrupts and send EOI:
+		 */
+		local_irq_disable();
+		ia64_set_tpr(saved_tpr);
+		ia64_eoi();
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
+		break;
+#endif
+		vector = ia64_get_ivr();
+	} while (vector != IA64_SPURIOUS_INT);
 }
 
 #ifdef CONFIG_SMP
@@ -210,12 +189,12 @@
 	ia64_set_lrr0(0, 1);	
 	ia64_set_lrr1(0, 1);	
 
-	irq_desc[TIMER_IRQ].handler	    = &irq_type_ia64_sapic;
 	irq_desc[IA64_SPURIOUS_INT].handler = &irq_type_ia64_sapic;
 #ifdef CONFIG_SMP
 	/* 
 	 * Configure the IPI vector and handler
 	 */
+	irq_desc[IPI_IRQ].status |= IRQ_PER_CPU;
 	irq_desc[IPI_IRQ].handler = &irq_type_ia64_sapic;
 	setup_irq(IPI_IRQ, &ipi_irqaction);
 #endif
@@ -234,7 +213,7 @@
 {
 	unsigned long ipi_addr;
 	unsigned long ipi_data;
-#ifdef	CONFIG_ITANIUM_ASTEP_SPECIFIC
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
 	unsigned long flags;
 #endif
 #	define EID	0
@@ -242,13 +221,13 @@
 	ipi_data = (delivery_mode << 8) | (vector & 0xff);
 	ipi_addr = ipi_base_addr | ((cpu << 8 | EID) << 4) | ((redirect & 1)  << 3);
 
-#ifdef	CONFIG_ITANIUM_ASTEP_SPECIFIC
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
 	spin_lock_irqsave(&ivr_read_lock, flags);
-#endif	/* CONFIG_ITANIUM_ASTEP_SPECIFIC */
+#endif
 
 	writeq(ipi_data, ipi_addr);
 
-#ifdef	CONFIG_ITANIUM_ASTEP_SPECIFIC
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
 	spin_unlock_irqrestore(&ivr_read_lock, flags);
 #endif
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)