ppc64 irq cleanup

Anton Blanchard anton at samba.org
Sat Jun 7 12:42:36 EST 2003


Hi,

Ive been looking at the IRQ consolidation patches and what needs to be
done for ppc64 to work. One problem is how we use request_irq before
the memory subsystem is up.

There were two places in which we did this, the 8259 interrupt and its
cascade and the RAS interrupts. I just changed the RAS interrupt
initialisation to be called out of an initcall, so that leaves the 8259.

This is what I am playing with at the moment, basically we do 8259
initialisation (and the associated request_irqs) in an arch_initcall.

When we go to dynamically allocating irq_descs this should make things a
bit easier.

Anton

===== arch/ppc64/kernel/irq.c 1.29 vs edited =====
--- 1.29/arch/ppc64/kernel/irq.c	Sat Jun  7 11:59:39 2003
+++ edited/arch/ppc64/kernel/irq.c	Sat Jun  7 12:28:21 2003
@@ -72,40 +72,6 @@
 int ppc_spurious_interrupts = 0;
 unsigned long lpEvent_count = 0;

-/* nasty hack for shared irq's since we need to do kmalloc calls but
- * can't very early in the boot when we need to do a request irq.
- * this needs to be removed.
- * -- Cort
- */
-#define IRQ_KMALLOC_ENTRIES 16
-static int cache_bitmask = 0;
-static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
-extern int mem_init_done;
-
-void *irq_kmalloc(size_t size, int pri)
-{
-	unsigned int i;
-	if ( mem_init_done )
-		return kmalloc(size,pri);
-	for ( i = 0; i < IRQ_KMALLOC_ENTRIES ; i++ )
-		if ( ! ( cache_bitmask & (1<<i) ) ) {
-			cache_bitmask |= (1<<i);
-			return (void *)(&malloc_cache[i]);
-		}
-	return 0;
-}
-
-void irq_kfree(void *ptr)
-{
-	unsigned int i;
-	for ( i = 0 ; i < IRQ_KMALLOC_ENTRIES ; i++ )
-		if ( ptr == &malloc_cache[i] ) {
-			cache_bitmask &= ~(1<<i);
-			return;
-		}
-	kfree(ptr);
-}
-
 int
 setup_irq(unsigned int irq, struct irqaction * new)
 {
@@ -205,7 +171,7 @@

 			/* Wait to make sure it's not being used on another CPU */
 			synchronize_irq(irq);
-			irq_kfree(action);
+			kfree(action);
 			return 0;
 		}
 		printk("Trying to free free IRQ%d\n",irq);
@@ -229,9 +195,9 @@
 		return do_free_irq(irq, dev_id);

 	action = (struct irqaction *)
-		irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+		kmalloc(sizeof(struct irqaction), GFP_KERNEL);
 	if (!action) {
-		printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq);
+		printk(KERN_ERR "kmalloc() failed for irq %d !\n", irq);
 		return -ENOMEM;
 	}

===== arch/ppc64/kernel/open_pic.c 1.13 vs edited =====
--- 1.13/arch/ppc64/kernel/open_pic.c	Thu Apr 24 15:45:15 2003
+++ edited/arch/ppc64/kernel/open_pic.c	Sat Jun  7 12:25:19 2003
@@ -158,7 +158,6 @@
         openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq);
         for ( i = 0 ; i < NUM_8259_INTERRUPTS  ; i++ )
                 irq_desc[i].handler = &i8259_pic;
-        i8259_init();
 }

 static inline u_int openpic_read(volatile u_int *addr)
@@ -384,17 +383,27 @@
 	ppc64_boot_msg(0x24, "OpenPic Spurious");
 	openpic_set_spurious(openpic_vec_spurious);

-	/* Initialize the cascade */
-	if (offset) {
-		if (request_irq(offset, no_action, SA_INTERRUPT,
-				"82c59 cascade", NULL))
-			printk(KERN_ERR "Unable to get OpenPIC IRQ 0 for cascade\n");
-	}
 	openpic_set_priority(0);
 	openpic_disable_8259_pass_through();

 	ppc64_boot_msg(0x25, "OpenPic Done");
 }
+
+/*
+ * We cant do this in init_IRQ because we need the memory subsystem up for
+ * request_irq()
+ */
+static int __init openpic_setup_i8259(void)
+{
+	if (naca->interrupt_controller == IC_OPEN_PIC) {
+		/* Initialize the cascade */
+		if (request_irq(NUM_8259_INTERRUPTS, no_action, SA_INTERRUPT,
+				"82c59 cascade", NULL))
+			printk(KERN_ERR "Unable to get OpenPIC IRQ 0 for cascade\n");
+		i8259_init();
+	}
+}
+arch_initcall(openpic_setup_i8259);

 void openpic_setup_ISU(int isu_num, unsigned long addr)
 {
===== arch/ppc64/kernel/smp.c 1.38 vs edited =====
--- 1.38/arch/ppc64/kernel/smp.c	Sat Jun  7 11:19:27 2003
+++ edited/arch/ppc64/kernel/smp.c	Sat Jun  7 12:08:06 2003
@@ -208,7 +208,7 @@
 	}
 }

-static int __init smp_chrp_probe(void)
+static int __init smp_openpic_probe(void)
 {
 	int i;
 	int nr_cpus = 0;
@@ -301,6 +301,10 @@
 		if (cpu_possible(i))
 			nr_cpus++;
 	}
+#ifdef CONFIG_SMP
+	extern void xics_request_IPIs(void);
+	xics_request_IPIs();
+#endif

 	return nr_cpus;
 }
@@ -337,7 +341,7 @@

 	if (naca->interrupt_controller == IC_OPEN_PIC) {
 		smp_ops->message_pass	= smp_openpic_message_pass;
-		smp_ops->probe		= smp_chrp_probe;
+		smp_ops->probe		= smp_openpic_probe;
 	} else {
 		smp_ops->message_pass	= smp_xics_message_pass;
 		smp_ops->probe		= smp_xics_probe;
===== arch/ppc64/kernel/xics.c 1.24 vs edited =====
--- 1.24/arch/ppc64/kernel/xics.c	Wed May 28 08:36:24 2003
+++ edited/arch/ppc64/kernel/xics.c	Sat Jun  7 12:27:09 2003
@@ -16,6 +16,7 @@
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/signal.h>
+#include <linux/init.h>
 #include <asm/prom.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -490,23 +491,38 @@

 	ops->cppr_info(boot_cpuid, 0xff);
 	iosync();
-	if (xics_irq_8259_cascade != -1) {
+
+	ppc64_boot_msg(0x21, "XICS Done");
+}
+
+/*
+ * We cant do this in init_IRQ because we need the memory subsystem up for
+ * request_irq()
+ */
+static int __init xics_setup_i8259(void)
+{
+	if (naca->interrupt_controller == IC_PPC_XIC &&
+	    xics_irq_8259_cascade != -1) {
 		if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET,
 				no_action, 0, "8259 cascade", 0))
 			printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n");
 		i8259_init();
 	}
+	return 0;
+}
+arch_initcall(xics_setup_i8259);

 #ifdef CONFIG_SMP
+void xics_request_IPIs(void)
+{
 	real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] =
 		XICS_IPI;
 	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
 	request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, SA_INTERRUPT,
 		    "IPI", 0);
 	irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU;
-#endif
-	ppc64_boot_msg(0x21, "XICS Done");
 }
+#endif

 void xics_set_affinity(unsigned int virq, unsigned long cpumask)
 {

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list