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
- Lines: 224
- Date:
Thu Jun 22 07:09:44 2000
- Orig file:
v2.4.0-test1/linux/arch/ia64/kernel/irq_ia64.c
- Orig date:
Wed Apr 26 16:34:06 2000
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)