diff -ruN linux-2.4.7/arch/s390/kernel/s390_ext.c linux-2.4.7-extfix/arch/s390/kernel/s390_ext.c
--- linux-2.4.7/arch/s390/kernel/s390_ext.c	Sat Jul 13 12:33:48 2002
+++ linux-2.4.7-extfix/arch/s390/kernel/s390_ext.c	Mon Jul 29 15:59:32 2002
@@ -21,34 +21,31 @@
  * iucv and 0x2603 pfault) this is always the first element. 
  */
 ext_int_info_t *ext_int_hash[256] = { 0, };
-ext_int_info_t ext_int_info_timer;
-ext_int_info_t ext_int_info_hwc;
-ext_int_info_t ext_int_pfault;
 
 int register_external_interrupt(__u16 code, ext_int_handler_t handler) {
         ext_int_info_t *p;
         int index;
 
-        index = code & 0xff;
-        p = ext_int_hash[index];
-        while (p != NULL) {
-                if (p->code == code)
-                        return -EBUSY;
-                p = p->next;
-        }
-        if (code == 0x1004) /* time_init is done before kmalloc works :-/ */
-                p = &ext_int_info_timer;
-        else if (code == 0x2401) /* hwc_init is done too early too */
-                p = &ext_int_info_hwc;
-        else if (code == 0x2603) /* pfault_init is done too early too */
-		p = &ext_int_pfault;
-	else
-                p = (ext_int_info_t *)
-                          kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
+        p = (ext_int_info_t *) kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
         if (p == NULL)
                 return -ENOMEM;
         p->code = code;
         p->handler = handler;
+        index = code & 0xff;
+        p->next = ext_int_hash[index];
+        ext_int_hash[index] = p;
+        return 0;
+}
+
+int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                     ext_int_info_t *p) {
+        int index;
+
+        if (p == NULL)
+                return -EINVAL;
+        p->code = code;
+        p->handler = handler;
+        index = code & 0xff;
         p->next = ext_int_hash[index];
         ext_int_hash[index] = p;
         return 0;
@@ -73,11 +70,33 @@
                 q->next = p->next;
         else
                 ext_int_hash[index] = p->next;
-        if (code != 0x1004 && code != 0x2401 && code != 0x2603)
-                kfree(p);
+        kfree(p);
         return 0;
 }
 
+int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                       ext_int_info_t *p) {
+       ext_int_info_t *q;
+       int index;
+
+       if (p == NULL || p->code != code || p->handler != handler)
+               return -EINVAL;
+       index = code & 0xff;
+       q = ext_int_hash[index];
+       if (p != q) {
+               while (q != NULL) {
+                       if (q->next == p)
+                               break;
+                       q = q->next;
+               }
+               if (q == NULL)
+                       return -ENOENT;
+               q->next = p->next;
+       } else
+               ext_int_hash[index] = p->next;
+       return 0;
+}
+
 EXPORT_SYMBOL(register_external_interrupt);
 EXPORT_SYMBOL(unregister_external_interrupt);
 
diff -ruN linux-2.4.7/arch/s390/kernel/time.c linux-2.4.7-extfix/arch/s390/kernel/time.c
--- linux-2.4.7/arch/s390/kernel/time.c	Sat Jul 13 12:34:04 2002
+++ linux-2.4.7-extfix/arch/s390/kernel/time.c	Mon Jul 29 15:59:32 2002
@@ -41,6 +41,7 @@
 #define TICK_SIZE tick
 
 static uint64_t init_timer_cc, last_timer_cc;
+static ext_int_info_t ext_int_info_timer; 
 
 extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
@@ -243,8 +244,9 @@
                 break;
         }
         /* request the 0x1004 external interrupt */
-        if (register_external_interrupt(0x1004, do_timer_interrupt) != 0)
-                panic("Couldn't request external interrupts 0x1004");
+        if (register_early_external_interrupt(0x1004, do_timer_interrupt,
+                                             &ext_int_info_timer) != 0)
+                panic("Couldn't request external interrupt 0x1004");
         init_100hz_timer();
         init_timer_cc = S390_lowcore.jiffy_timer_cc;
         init_timer_cc -= 0x8126d60e46000000LL -
diff -ruN linux-2.4.7/arch/s390/kernel/traps.c linux-2.4.7-extfix/arch/s390/kernel/traps.c
--- linux-2.4.7/arch/s390/kernel/traps.c	Sat Jul 13 12:33:56 2002
+++ linux-2.4.7-extfix/arch/s390/kernel/traps.c	Mon Jul 29 15:59:32 2002
@@ -58,6 +58,7 @@
 extern int pfault_init(void);
 extern void pfault_fini(void);
 extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
+static ext_int_info_t ext_int_pfault;  
 #endif
 
 spinlock_t die_lock;
@@ -447,7 +448,8 @@
 #ifdef CONFIG_PFAULT
 	if (MACHINE_IS_VM) {
 		/* request the 0x2603 external interrupt */
-		if (register_external_interrupt(0x2603, pfault_interrupt) != 0)
+               if (register_early_external_interrupt(0x2603, pfault_interrupt,
+                                                     &ext_int_pfault) != 0)
 			panic("Couldn't request external interrupt 0x2603");
 		/*
 		 * First try to get pfault pseudo page faults going.
@@ -455,8 +457,9 @@
 		 */
 		if (pfault_init() != 0) {
 			/* Tough luck, no pfault. */
-			unregister_external_interrupt(0x2603,
-						      pfault_interrupt);
+                       unregister_early_external_interrupt(0x2603,
+                                                           pfault_interrupt,
+                                                           &ext_int_pfault);
 			cpcmd("SET PAGEX ON", NULL, 0);
 		}
 	}
diff -ruN linux-2.4.7/arch/s390x/kernel/s390_ext.c linux-2.4.7-extfix/arch/s390x/kernel/s390_ext.c
--- linux-2.4.7/arch/s390x/kernel/s390_ext.c	Sat Jul 13 12:33:48 2002
+++ linux-2.4.7-extfix/arch/s390x/kernel/s390_ext.c	Mon Jul 29 15:59:32 2002
@@ -21,34 +21,31 @@
  * iucv and 0x2603 pfault) this is always the first element. 
  */
 ext_int_info_t *ext_int_hash[256] = { 0, };
-ext_int_info_t ext_int_info_timer;
-ext_int_info_t ext_int_info_hwc;
-ext_int_info_t ext_int_pfault;
 
 int register_external_interrupt(__u16 code, ext_int_handler_t handler) {
         ext_int_info_t *p;
         int index;
 
-        index = code & 0xff;
-        p = ext_int_hash[index];
-        while (p != NULL) {
-                if (p->code == code)
-                        return -EBUSY;
-                p = p->next;
-        }
-        if (code == 0x1004) /* time_init is done before kmalloc works :-/ */
-                p = &ext_int_info_timer;
-        else if (code == 0x2401) /* hwc_init is done too early too */
-                p = &ext_int_info_hwc;
-        else if (code == 0x2603) /* pfault_init is done too early too */
-                p = &ext_int_pfault;
-        else
-                p = (ext_int_info_t *)
-                          kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
+        p = (ext_int_info_t *) kmalloc(sizeof(ext_int_info_t), GFP_ATOMIC);
         if (p == NULL)
                 return -ENOMEM;
         p->code = code;
         p->handler = handler;
+        index = code & 0xff;
+        p->next = ext_int_hash[index];
+        ext_int_hash[index] = p;
+        return 0;
+}
+
+int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                     ext_int_info_t *p) {
+        int index;
+
+        if (p == NULL)
+                return -EINVAL;
+        p->code = code;
+        p->handler = handler;
+        index = code & 0xff;
         p->next = ext_int_hash[index];
         ext_int_hash[index] = p;
         return 0;
@@ -73,11 +70,33 @@
                 q->next = p->next;
         else
                 ext_int_hash[index] = p->next;
-        if (code != 0x1004 && code != 0x2401 && code != 0x2603)
-                kfree(p);
+        kfree(p);
         return 0;
 }
 
+int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                       ext_int_info_t *p) {
+       ext_int_info_t *q;
+       int index;
+
+       if (p == NULL || p->code != code || p->handler != handler)
+               return -EINVAL;
+       index = code & 0xff;
+       q = ext_int_hash[index];
+       if (p != q) {
+               while (q != NULL) {
+                       if (q->next == p)
+                               break;
+                       q = q->next;
+               }
+               if (q == NULL)
+                       return -ENOENT;
+               q->next = p->next;
+       } else
+               ext_int_hash[index] = p->next;
+       return 0;
+}
+
 EXPORT_SYMBOL(register_external_interrupt);
 EXPORT_SYMBOL(unregister_external_interrupt);
 
diff -ruN linux-2.4.7/arch/s390x/kernel/time.c linux-2.4.7-extfix/arch/s390x/kernel/time.c
--- linux-2.4.7/arch/s390x/kernel/time.c	Sat Jul 13 12:34:04 2002
+++ linux-2.4.7-extfix/arch/s390x/kernel/time.c	Mon Jul 29 15:59:32 2002
@@ -41,6 +41,7 @@
 #define TICK_SIZE tick
 
 static uint64_t init_timer_cc, last_timer_cc;
+static ext_int_info_t ext_int_info_timer; 
 
 extern rwlock_t xtime_lock;
 extern unsigned long wall_jiffies;
@@ -249,8 +250,9 @@
                 break;
         }
         /* request the 0x1004 external interrupt */
-        if (register_external_interrupt(0x1004, do_timer_interrupt) != 0)
-                panic("Couldn't request external interrupts 0x1004");
+        if (register_early_external_interrupt(0x1004, do_comparator_interrupt,
+                                             &ext_int_info_timer) != 0)
+                panic("Couldn't request external interrupt 0x1004");
         init_100hz_timer();
         init_timer_cc = S390_lowcore.jiffy_timer_cc;
         init_timer_cc -= 0x8126d60e46000000LL -
diff -ruN linux-2.4.7/arch/s390x/kernel/traps.c linux-2.4.7-extfix/arch/s390x/kernel/traps.c
--- linux-2.4.7/arch/s390x/kernel/traps.c	Sat Jul 13 12:33:56 2002
+++ linux-2.4.7-extfix/arch/s390x/kernel/traps.c	Mon Jul 29 15:59:32 2002
@@ -56,6 +56,7 @@
 extern int pfault_init(void);
 extern void pfault_fini(void);
 extern void pfault_interrupt(struct pt_regs *regs, __u16 error_code);
+static ext_int_info_t ext_int_pfault;
 #endif
 
 spinlock_t die_lock;
@@ -296,15 +297,17 @@
 #ifdef CONFIG_PFAULT
 	if (MACHINE_IS_VM) {
 		/* request the 0x2603 external interrupt */
-		if (register_external_interrupt(0x2603, pfault_interrupt) != 0)
-			panic("Couldn't request external interrupt 0x2603");
+               if (register_early_external_interrupt(0x2603, pfault_interrupt,
+                                                     &ext_int_pfault) != 0)
+                        panic("Couldn't request external interrupt 0x2603");
 		/*
 		 * Try to get pfault pseudo page faults going.
 		 */
 		if (pfault_init() != 0) {
 			/* Tough luck, no pfault. */
-			unregister_external_interrupt(0x2603,
-						      pfault_interrupt);
+                       unregister_early_external_interrupt(0x2603,
+                                                           pfault_interrupt,
+                                                           &ext_int_pfault);
 		}
 	}
 #endif
diff -ruN linux-2.4.7/drivers/s390/char/hwc_rw.c linux-2.4.7-extfix/drivers/s390/char/hwc_rw.c
--- linux-2.4.7/drivers/s390/char/hwc_rw.c	Sat Jul 13 12:33:45 2002
+++ linux-2.4.7-extfix/drivers/s390/char/hwc_rw.c	Mon Jul 29 15:59:36 2002
@@ -231,6 +231,8 @@
 static unsigned long cr0_save __attribute__ ((aligned (8)));
 static unsigned char psw_mask __attribute__ ((aligned (8)));
 
+static ext_int_info_t ext_int_info_hwc;
+
 #define DELAYED_WRITE 0
 #define IMMEDIATE_WRITE 1
 
@@ -2004,7 +2006,8 @@
 
 #endif
 
-	if (register_external_interrupt (0x2401, hwc_interrupt_handler) != 0)
+	if (register_early_external_interrupt (0x2401, hwc_interrupt_handler,
+					       &ext_int_info_hwc) != 0)
 		panic ("Couldn't request external interrupts 0x2401");
 
 	spin_lock_init (&hwc_data.lock);
diff -ruN linux-2.4.7/include/asm-s390/s390_ext.h linux-2.4.7-extfix/include/asm-s390/s390_ext.h
--- linux-2.4.7/include/asm-s390/s390_ext.h	Tue Feb 13 23:13:44 2001
+++ linux-2.4.7-extfix/include/asm-s390/s390_ext.h	Mon Jul 29 15:59:32 2002
@@ -25,6 +25,10 @@
 extern ext_int_info_t *ext_int_hash[];
 
 int register_external_interrupt(__u16 code, ext_int_handler_t handler);
+int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                     ext_int_info_t *info);
 int unregister_external_interrupt(__u16 code, ext_int_handler_t handler);
+int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                       ext_int_info_t *info);
 
 #endif
diff -ruN linux-2.4.7/include/asm-s390x/s390_ext.h linux-2.4.7-extfix/include/asm-s390x/s390_ext.h
--- linux-2.4.7/include/asm-s390x/s390_ext.h	Tue Feb 13 23:13:44 2001
+++ linux-2.4.7-extfix/include/asm-s390x/s390_ext.h	Mon Jul 29 15:59:32 2002
@@ -25,6 +25,10 @@
 extern ext_int_info_t *ext_int_hash[];
 
 int register_external_interrupt(__u16 code, ext_int_handler_t handler);
+int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                     ext_int_info_t *info);
 int unregister_external_interrupt(__u16 code, ext_int_handler_t handler);
+int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
+                                       ext_int_info_t *info);
 
 #endif
