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