patch-2.4.20 linux-2.4.20/arch/ppc/kernel/open_pic.c

Next file: linux-2.4.20/arch/ppc/kernel/open_pic.h
Previous file: linux-2.4.20/arch/ppc/kernel/oak_setup.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/arch/ppc/kernel/open_pic.c linux-2.4.20/arch/ppc/kernel/open_pic.c
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.open_pic.c 1.33 12/19/01 09:45:54 trini
+ * BK Id: %F% %I% %G% %U% %#%
  */
 /*
  *  arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
@@ -17,18 +17,16 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/irq.h>
-#include <linux/init.h>
 #include <asm/ptrace.h>
 #include <asm/signal.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/prom.h>
 #include <asm/sections.h>
+#include <asm/open_pic.h>
+#include <asm/i8259.h>
 
-#include "local_irq.h"
-#include "open_pic.h"
 #include "open_pic_defs.h"
-#include "i8259.h"
 
 void* OpenPIC_Addr;
 static volatile struct OpenPIC *OpenPIC = NULL;
@@ -36,18 +34,12 @@
 u_char *OpenPIC_InitSenses __initdata = NULL;
 extern int use_of_interrupt_tree;
 
-void find_ISUs(void);
-
 static u_int NumProcessors;
 static u_int NumSources;
-#ifdef CONFIG_POWER3
-static int NumISUs;
-#endif
 static int open_pic_irq_offset;
+static volatile OpenPIC_Source *ISR[NR_IRQS];
 static volatile unsigned char* chrp_int_ack_special;
 
-OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU];
-
 /* Global Operations */
 static void openpic_disable_8259_pass_through(void);
 static void openpic_set_priority(u_int pri);
@@ -68,7 +60,7 @@
 static void openpic_disable_irq(u_int irq);
 static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
 			    int is_level);
-static void openpic_mapirq(u_int irq, u_int cpumask);
+static void openpic_mapirq(u_int irq, u_int cpumask, u_int keepmask);
 
 /*
  * These functions are not used but the code is kept here
@@ -167,12 +159,6 @@
 #define check_arg_cpu(cpu)	do {} while (0)
 #endif
 
-#ifdef CONFIG_POWER3
-	#define GET_ISU(source)	ISU[(source) >> 4][(source) & 0xf]
-#else
-	#define GET_ISU(source)	ISU[0][(source)]
-#endif
-
 u_int openpic_read(volatile u_int *addr)
 {
 	u_int val;
@@ -261,6 +247,20 @@
 }
 #endif /* CONFIG_SMP */
 
+void __init openpic_set_sources(int first_irq, int num_irqs, void *first_ISR)
+{
+	volatile OpenPIC_Source *src = first_ISR;
+	int i, last_irq;
+
+	last_irq = first_irq + num_irqs;
+	if (last_irq > NumSources)
+		NumSources = last_irq;
+	if (src == 0)
+		src = &((struct OpenPIC *)OpenPIC_Addr)->Source[first_irq];
+	for (i = first_irq; i < last_irq; ++i, ++src)
+		ISR[i] = src;
+}
+
 void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
 			 int programmer_switch_irq)
 {
@@ -274,7 +274,7 @@
 	}
 	OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr;
 
-	if ( ppc_md.progress ) ppc_md.progress("openpic enter",0x122);
+	if (ppc_md.progress) ppc_md.progress("openpic: enter", 0x122);
 
 	t = openpic_read(&OpenPIC->Global.Feature_Reporting0);
 	switch (t & OPENPIC_FEATURE_VERSION_MASK) {
@@ -293,8 +293,11 @@
 	}
 	NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >>
 			 OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1;
-	NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
-		      OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1;
+	if (NumSources == 0)
+		openpic_set_sources(0,
+				    ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
+				     OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1,
+				    NULL);
 	printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n",
 	       version, NumProcessors, NumSources, OpenPIC);
 	timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
@@ -309,7 +312,7 @@
 	chrp_int_ack_special = (volatile unsigned char*)chrp_ack;
 
 	/* Initialize timer interrupts */
-	if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba);
+	if ( ppc_md.progress ) ppc_md.progress("openpic: timer",0x3ba);
 	for (i = 0; i < OPENPIC_NUM_TIMERS; i++) {
 		/* Disabled, Priority 0 */
 		openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+offset);
@@ -319,7 +322,7 @@
 
 #ifdef CONFIG_SMP
 	/* Initialize IPI interrupts */
-	if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb);
+	if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb);
 	for (i = 0; i < OPENPIC_NUM_IPI; i++) {
 		/* Disabled, Priority 10..13 */
 		openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset);
@@ -329,8 +332,6 @@
 	}
 #endif
 
-	find_ISUs();
-
 	/* Initialize external interrupts */
 	if (ppc_md.progress) ppc_md.progress("openpic ext",0x3bc);
 
@@ -339,13 +340,16 @@
 	/* SIOint (8259 cascade) is special */
 	if (offset) {
 		openpic_initirq(0, 8, offset, 1, 1);
-		openpic_mapirq(0, 1<<0);
+		openpic_mapirq(0, 1<<0, 0);
 	}
 
 	/* Init all external sources */
 	for (i = 1; i < NumSources; i++) {
 		int pri, sense;
 
+		if (ISR[i] == 0)
+			continue;
+
 		/* the bootloader may have left it enabled (bad !) */
 		openpic_disable_irq(i+offset);
 
@@ -357,7 +361,7 @@
 		/* Enabled, Priority 8 or 9 */
 		openpic_initirq(i, pri, i+offset, !sense, sense);
 		/* Processor 0 */
-		openpic_mapirq(i, 1<<0);
+		openpic_mapirq(i, 1<<0, 0);
 	}
 
 	/* Init descriptors */
@@ -365,7 +369,7 @@
 		irq_desc[i].handler = &open_pic;
 
 	/* Initialize the spurious interrupt */
-	if (ppc_md.progress) ppc_md.progress("openpic spurious",0x3bd);
+	if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd);
 	openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset);
 
 	/* Initialize the cascade */
@@ -380,39 +384,6 @@
 	if (ppc_md.progress) ppc_md.progress("openpic exit",0x222);
 }
 
-#ifdef CONFIG_POWER3
-void openpic_setup_ISU(int isu_num, unsigned long addr)
-{
-	if (isu_num >= OPENPIC_MAX_ISU)
-		return;
-	ISU[isu_num] = (OpenPIC_SourcePtr) ioremap(addr, 0x400);
-	if (isu_num >= NumISUs)
-		NumISUs = isu_num + 1;
-}
-#endif
-
-void find_ISUs(void)
-{
-#ifdef CONFIG_POWER3
-        /* Use /interrupt-controller/reg and
-         * /interrupt-controller/interrupt-ranges from OF device tree
-	 * the ISU array is setup in chrp_pci.c in ibm_add_bridges
-	 * as a result
-	 * -- tgall
-         */
-
-	/* basically each ISU is a bus, and this assumes that
-	 * open_pic_isu_count interrupts per bus are possible 
-	 * ISU == Interrupt Source
-	 */
-	NumSources = NumISUs * 0x10;
-
-#else
-	/* for non-distributed OpenPIC implementations it's in the IDU -- Cort */
-	ISU[0] = (OpenPIC_Source *)OpenPIC->Source;
-#endif
-}
-
 static void openpic_reset(void)
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -430,6 +401,7 @@
 }
 #endif /* notused */
 
+/* This can't be __init, it is used in openpic_sleep_restore_intrs */
 static void openpic_disable_8259_pass_through(void)
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -471,7 +443,7 @@
 }
 #endif /* notused */
 
-static void openpic_set_priority(u_int pri)
+static void __init openpic_set_priority(u_int pri)
 {
 	DECL_THIS_CPU;
 
@@ -492,6 +464,7 @@
 }
 #endif /* notused */
 
+/* This can't be __init, it is used in openpic_sleep_restore_intrs */
 static void openpic_set_spurious(u_int vec)
 {
 	check_arg_vec(vec);
@@ -521,7 +494,9 @@
 	openpic_write(&OpenPIC->Global.Processor_Initialization, mask);
 }
 
+#if defined(CONFIG_SMP) || defined(CONFIG_PMAC_PBOOK)
 static spinlock_t openpic_setup_lock = SPIN_LOCK_UNLOCKED;
+#endif
 
 #ifdef CONFIG_SMP
 /*
@@ -603,8 +578,8 @@
  	 * we should make sure we also change the default values of irq_affinity
  	 * in irq.c.
  	 */
- 	for (i = 0; i < NumSources ; i++)
-		openpic_mapirq(i, openpic_read(&GET_ISU(i).Destination) | msk);
+ 	for (i = 0; i < NumSources; i++)
+		openpic_mapirq(i, msk, ~0U);
 #endif /* CONFIG_IRQ_ALL_CPUS */
  	openpic_set_priority(0);
 
@@ -654,26 +629,29 @@
  */
 static void openpic_enable_irq(u_int irq)
 {
+	volatile u_int *vpp;
+
 	check_arg_irq(irq);
-	openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
+	vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
+	openpic_clearfield(vpp, OPENPIC_MASK);
 	/* make sure mask gets to controller before we return to user */
 	do {
 		mb(); /* sync is probably useless here */
-	} while(openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority,
-			OPENPIC_MASK));
+	} while (openpic_readfield(vpp, OPENPIC_MASK));
 }
 
 static void openpic_disable_irq(u_int irq)
 {
+	volatile u_int *vpp;
 	u32 vp;
 	
 	check_arg_irq(irq);
-	openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK);
+	vpp = &ISR[irq - open_pic_irq_offset]->Vector_Priority;
+	openpic_setfield(vpp, OPENPIC_MASK);
 	/* make sure mask gets to controller before we return to user */
 	do {
 		mb();  /* sync is probably useless here */
-		vp = openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority,
-    			OPENPIC_MASK | OPENPIC_ACTIVITY);
+		vp = openpic_readfield(vpp, OPENPIC_MASK | OPENPIC_ACTIVITY);
 	} while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK));
 }
 
@@ -708,9 +686,10 @@
  *  pol: polarity (1 for positive, 0 for negative)
  *  sense: 1 for level, 0 for edge
  */
-static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
+static void __init
+openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
 {
-	openpic_safe_writefield(&GET_ISU(irq).Vector_Priority,
+	openpic_safe_writefield(&ISR[irq]->Vector_Priority,
 				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
 				OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,
 				(pri << OPENPIC_PRIORITY_SHIFT) | vec |
@@ -722,9 +701,13 @@
 /*
  *  Map an interrupt source to one or more CPUs
  */
-static void openpic_mapirq(u_int irq, u_int physmask)
+static void openpic_mapirq(u_int irq, u_int physmask, u_int keepmask)
 {
-	openpic_write(&GET_ISU(irq).Destination, physmask);
+	if (ISR[irq] == 0)
+		return;
+	if (keepmask != 0)
+		physmask |= openpic_read(&ISR[irq]->Destination) & keepmask;
+	openpic_write(&ISR[irq]->Destination, physmask);
 }
 
 #ifdef notused
@@ -735,9 +718,10 @@
  */
 static void openpic_set_sense(u_int irq, int sense)
 {
-	openpic_safe_writefield(&GET_ISU(irq).Vector_Priority,
-				OPENPIC_SENSE_LEVEL,
-				(sense ? OPENPIC_SENSE_LEVEL : 0));
+	if (ISR[irq] != 0)
+		openpic_safe_writefield(&ISR[irq]->Vector_Priority,
+					OPENPIC_SENSE_LEVEL,
+					(sense ? OPENPIC_SENSE_LEVEL : 0));
 }
 #endif /* notused */
 
@@ -758,7 +742,7 @@
 
 static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
 {
-	openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask));
+	openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask), 0);
 }
 
 #ifdef CONFIG_SMP
@@ -799,7 +783,7 @@
 			irq = *chrp_int_ack_special;
 #ifndef CONFIG_GEMINI
 		else
-			irq = i8259_poll();
+			irq = i8259_poll(regs);
 #endif
 		openpic_eoi();
         }
@@ -856,9 +840,11 @@
 	for (i=0; i<OPENPIC_NUM_IPI; i++)
 		save_ipi_vp[i] = openpic_read(&OpenPIC->Global.IPI_Vector_Priority(i));
 	for (i=0; i<NumSources; i++) {
-		save_irq_src_vp[i] = openpic_read(&OpenPIC->Source[i].Vector_Priority)
+		if (ISR[i] == 0)
+			continue;
+		save_irq_src_vp[i] = openpic_read(&ISR[i]->Vector_Priority)
 			& ~OPENPIC_ACTIVITY;
-		save_irq_src_dest[i] = openpic_read(&OpenPIC->Source[i].Destination);
+		save_irq_src_dest[i] = openpic_read(&ISR[i]->Destination);
 	}
 	spin_unlock_irqrestore(&openpic_setup_lock, flags);
 }
@@ -874,15 +860,19 @@
 	openpic_reset();
 
 	for (i=0; i<OPENPIC_NUM_IPI; i++)
-		openpic_write(&OpenPIC->Global.IPI_Vector_Priority(i), save_ipi_vp[i]);
+		openpic_write(&OpenPIC->Global.IPI_Vector_Priority(i),
+			      save_ipi_vp[i]);
 	for (i=0; i<NumSources; i++) {
-		openpic_write(&OpenPIC->Source[i].Vector_Priority, save_irq_src_vp[i]);
-		openpic_write(&OpenPIC->Source[i].Destination, save_irq_src_dest[i]);
+		if (ISR[i] == 0)
+			continue;
+		openpic_write(&ISR[i]->Vector_Priority, save_irq_src_vp[i]);
+		openpic_write(&ISR[i]->Destination, save_irq_src_dest[i]);
 	}
 	openpic_set_spurious(OPENPIC_VEC_SPURIOUS+open_pic_irq_offset);
 	openpic_disable_8259_pass_through();
 	for (i=0; i<NumProcessors; i++)
-		openpic_write(&OpenPIC->Processor[i].Current_Task_Priority, save_cpu_task_pri[i]);
+		openpic_write(&OpenPIC->Processor[i].Current_Task_Priority,
+			      save_cpu_task_pri[i]);
 
 	spin_unlock_irqrestore(&openpic_setup_lock, flags);
 }

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