[PATCH 2.5] More i8259 cleanups

Tom Rini trini at kernel.crashing.org
Thu May 16 03:11:04 EST 2002


Hey all.  I've been doing more OpenPIC/i8259 work and here's the next
patch I'll be pushing to linuxppc-2.5 soon.  What I've done is change
what openpic_init() does and create a few new calls as well.

First, openpic_init() now takes a 'linux_irq_offset' parameter.  This is
mostly what the 'offset' param was before.  But it's now no longer tied
to the cascade irq[1].  This is just where we want to start mapping
OpenPIC IRQs to Linux IRQs.  Second, it now takes 'openpic_serial_mode'
which is if the OpenPIC is running in serial interrupt mode or not.
This is so we can eliminate CONFIG_EPIC_SERIAL_MODE.  Also, it removes
the 'main_pic' argument.  After talking to Paul, we don't think
openpic_init() works with main_pic == 0.  Is anyone using openpic_init()
with main_pic == 0?

Next, there's now openpic_init_cascade() (or should this be called
openpic_hookup_cascade() ?) which takes the Linux IRQ number a cascade
is attached to and the name of it.  This might allow (but is untested)
multiple cascades, if xxxx_get_irq() knows which IRQs are cascaded, and
is a small step at allowing an arbitrary cascade.

Also, we now always setup IRQs with a priority of '8' and now we have
openpic_init_nmi_irq(), which will correctly set the priority of the NMI
IRQ.  This allows us to stop passing in 'programmer_switch_irq' to
openpic_init.  This is untested however.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

[1]: This isn't tested yet, but I'll try and test this shortly once I
have a sandpoint.

===== arch/ppc/kernel/open_pic.c 1.12 vs edited =====
--- 1.12/arch/ppc/kernel/open_pic.c	Wed May  1 07:37:15 2002
+++ edited/arch/ppc/kernel/open_pic.c	Wed May 15 07:51:51 2002
@@ -263,7 +263,6 @@
 }
 #endif /* CONFIG_SMP */

-#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PMAC_PBOOK)
 static void openpic_reset(void)
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -272,9 +271,7 @@
 				 OPENPIC_CONFIG_RESET))
 		mb();
 }
-#endif

-#ifdef CONFIG_EPIC_SERIAL_MODE
 static void openpic_enable_sie(void)
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration1,
@@ -286,7 +283,6 @@
 	openpic_writefield(&OpenPIC->Global.Global_Configuration1,
 			 OPENPIC_EICR_S_CLK_MASK, (clkval << 28));
 }
-#endif

 void openpic_set_sources(int first_irq, int num_irqs, void *first_ISR)
 {
@@ -302,7 +298,7 @@
 		ISR[i] = src;
 }

-void __init openpic_init(int main_pic, int offset, int programmer_switch_irq)
+void __init openpic_init(int linux_irq_offset, int openpic_serial_mode)
 {
 	u_int t, i;
 	u_int timerfreq;
@@ -314,11 +310,9 @@
 	}
 	OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr;

-#ifdef CONFIG_EPIC_SERIAL_MODE
-	/* Have to start from ground zero.
-	*/
-	openpic_reset();
-#endif
+	/* Make sure we have all the right bits set for serial mode */
+	if (openpic_serial_mode)
+		openpic_reset();

 	if (ppc_md.progress) ppc_md.progress("openpic enter", 0x122);

@@ -351,16 +345,13 @@
 		printk("OpenPIC timer frequency is %d.%06d MHz\n",
 		       timerfreq / 1000000, timerfreq % 1000000);

-	if (!main_pic)
-		return;
-
-	open_pic_irq_offset = offset;
+	open_pic_irq_offset = linux_irq_offset;

 	/* Initialize timer interrupts */
 	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);
+		openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+linux_irq_offset);
 		/* No processor */
 		openpic_maptimer(i, 0);
 	}
@@ -370,10 +361,12 @@
 	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);
+		openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+linux_irq_offset);
 		/* IPIs are per-CPU */
-		irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU;
-		irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi;
+		irq_desc[OPENPIC_VEC_IPI+i+linux_irq_offset].status |=
+			IRQ_PER_CPU;
+		irq_desc[OPENPIC_VEC_IPI+i+linux_irq_offset].handler =
+			&open_pic_ipi;
 	}
 #endif

@@ -384,15 +377,14 @@

 	/* Init all external sources, including possibly the cascade. */
 	for (i = 0; i < NumSources; i++) {
-		int pri, sense;
+		int sense;

 		if (ISR[i] == 0)
 			continue;

 		/* the bootloader may have left it enabled (bad !) */
-		openpic_disable_irq(i+offset);
+		openpic_disable_irq(i+linux_irq_offset);

-		pri = (i == programmer_switch_irq)? 9: 8;
 		/*
 		 * We find the vale from either the InitSenses table
 		 * or assume a negative polarity level interrupt.
@@ -400,39 +392,47 @@
 		sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1;

 		if ((sense & IRQ_SENSE_MASK) == 1)
-			irq_desc[i+offset].status = IRQ_LEVEL;
+			irq_desc[i+linux_irq_offset].status = IRQ_LEVEL;

-		/* Enabled, Priority 8 or 9 */
-		openpic_initirq(i, pri, i+offset, (sense & IRQ_POLARITY_MASK),
+		/* Enabled, Priority 8 */
+		openpic_initirq(i, 8, i+linux_irq_offset,
+				(sense & IRQ_POLARITY_MASK),
 				(sense & IRQ_SENSE_MASK));
 		/* Processor 0 */
 		openpic_mapirq(i, 1<<0, 0);
 	}

 	/* Init descriptors */
-	for (i = offset; i < NumSources + offset; i++)
+	for (i = linux_irq_offset; i < NumSources + linux_irq_offset; i++)
 		irq_desc[i].handler = &open_pic;

 	/* Initialize the spurious interrupt */
 	if (ppc_md.progress) ppc_md.progress("openpic spurious",0x3bd);
-	openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset);
+	openpic_set_spurious(OPENPIC_VEC_SPURIOUS+linux_irq_offset);

-	/* Initialize the cascade */
-	if (offset) {
-		if (request_irq(offset, no_action, SA_INTERRUPT,
-				"82c59 cascade", NULL))
-			printk("Unable to get OpenPIC IRQ 0 for cascade\n");
-	}
  	openpic_disable_8259_pass_through();
-#ifdef CONFIG_EPIC_SERIAL_MODE
-	openpic_eicr_set_clk(7);	/* Slowest value until we know better */
-	openpic_enable_sie();
-#endif
+	if (openpic_serial_mode) {
+		/* Slowest value until we know better */
+		openpic_eicr_set_clk(7);
+		openpic_enable_sie();
+	}
 	openpic_set_priority(0);

 	if (ppc_md.progress) ppc_md.progress("openpic exit",0x222);
 }

+/*
+ * This will hook up a casacade to the OpenPIC.
+ *
+ * irq: The LinuxIRQ the cascade is attached to.
+ */
+void openpic_init_cascade(u_int irq, char *name)
+{
+	if (request_irq(irq, no_action, SA_INTERRUPT, name, NULL))
+		printk("Unable to get OpenPIC IRQ %d for cascade\n",
+				irq - open_pic_irq_offset);
+}
+
 #ifdef notused
 static void openpic_enable_8259_pass_through(void)
 {
@@ -441,6 +441,9 @@
 }
 #endif /* notused */

+/*
+ * Make sure that we don't pass i8259 interrupts through to the CPU.
+ */
 static void openpic_disable_8259_pass_through(void)
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -655,11 +658,10 @@

 /*
  *
- * All functions below take an offset'ed irq argument
+ * All functions below take an offset'ed irq argument unless otherwise noted.
  *
  */

-
 /*
  *  Enable/disable an external interrupt source
  *
@@ -735,6 +737,30 @@
 				(sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE));
 }

+/*
+ * Initalize the interrupt source which will generate an NMI (and disable it).
+ *
+ * irq: The logical IRQ which generates an NMI.
+ */
+void __init
+openpic_init_nmi_irq(u_int irq)
+{
+	int sense;
+
+	sense = (irq < OpenPIC_NumInitSenses) ? OpenPIC_InitSenses[irq] : 1;
+
+	openpic_safe_writefield(&ISR[irq]->Vector_Priority,
+				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
+				OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK,
+				(9 << OPENPIC_PRIORITY_SHIFT) |
+				(irq + open_pic_irq_offset) |
+				((sense & IRQ_POLARITY_MASK) ?
+				 OPENPIC_POLARITY_POSITIVE :
+				 OPENPIC_POLARITY_NEGATIVE) |
+				((sense & IRQ_SENSE_MASK) ? OPENPIC_SENSE_LEVEL
+				 : OPENPIC_SENSE_EDGE));
+}
+
 /*
  *  Map an interrupt source to one or more CPUs
  */
===== arch/ppc/platforms/chrp_setup.c 1.20 vs edited =====
--- 1.20/arch/ppc/platforms/chrp_setup.c	Thu May  9 00:26:18 2002
+++ edited/arch/ppc/platforms/chrp_setup.c	Wed May 15 07:36:12 2002
@@ -388,7 +388,6 @@
 	int i;
 	unsigned long chrp_int_ack;
 	unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
-	int nmi_irq = -1;
 #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
 	struct device_node *kbd;
 #endif
@@ -411,8 +410,10 @@
 	OpenPIC_InitSenses = init_senses;
 	OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;

-	openpic_init(1, NUM_8259_INTERRUPTS, nmi_irq);
-
+	openpic_init(NUM_8259_INTERRUPTS, 0);
+	/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
+	openpic_init_cascade(NUM_8259_INTERRUPTS, "82c59 cascade");
+
 	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
 		irq_desc[i].handler = &i8259_pic;
 	i8259_init(chrp_int_ack);
===== arch/ppc/platforms/lopec_setup.c 1.4 vs edited =====
--- 1.4/arch/ppc/platforms/lopec_setup.c	Wed May  1 07:37:15 2002
+++ edited/arch/ppc/platforms/lopec_setup.c	Wed May 15 07:35:55 2002
@@ -217,7 +217,9 @@
 	/* Skip reserved space and map Message Unit Interrupt (I2O) */
 	openpic_set_sources(19, 1, OpenPIC_Addr + 0x110C0);

-	openpic_init(1, NUM_8259_INTERRUPTS, -1);
+	openpic_init(NUM_8259_INTERRUPTS, 1);
+	/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
+	openpic_init_cascade(NUM_8259_INTERRUPTS, "82c59 cascade");

 	/* Map i8259 interrupts */
 	for(i = 0; i < NUM_8259_INTERRUPTS; i++)
===== arch/ppc/platforms/pmac_pic.c 1.13 vs edited =====
--- 1.13/arch/ppc/platforms/pmac_pic.c	Thu May  9 00:26:18 2002
+++ edited/arch/ppc/platforms/pmac_pic.c	Wed May 15 07:35:01 2002
@@ -375,26 +375,28 @@
 		printk("PowerMac using OpenPIC irq controller\n");
 		if (irqctrler->n_addrs > 0)
 		{
-			int nmi_irq = -1;
 			unsigned char senses[NR_IRQS];
-#ifdef CONFIG_XMON
-			struct device_node* pswitch;

-			pswitch = find_devices("programmer-switch");
-			if (pswitch && pswitch->n_intrs)
-				nmi_irq = pswitch->intrs[0].line;
-#endif /* CONFIG_XMON */
 			prom_get_irq_senses(senses, 0, NR_IRQS);
 			OpenPIC_InitSenses = senses;
 			OpenPIC_NumInitSenses = NR_IRQS;
 			ppc_md.get_irq = openpic_get_irq;
 			OpenPIC_Addr = ioremap(irqctrler->addrs[0].address,
 					       irqctrler->addrs[0].size);
-			openpic_init(1, 0, nmi_irq);
+			openpic_init(0, 0);
 #ifdef CONFIG_XMON
-			if (nmi_irq >= 0)
-				request_irq(nmi_irq, xmon_irq, 0,
-					    "NMI - XMON", 0);
+			{
+				struct device_node* pswitch;
+				int nmi_irq;
+
+				pswitch = find_devices("programmer-switch");
+				if (pswitch && pswitch->n_intrs) {
+					nmi_irq = pswitch->intrs[0].line;
+					openpic_init_nmi_irq(nmi_irq);
+					request_irq(nmi_irq, xmon_irq, 0,
+							"NMI - XMON", 0);
+				}
+			}
 #endif	/* CONFIG_XMON */
 			return;
 		}
===== arch/ppc/platforms/prep_setup.c 1.22 vs edited =====
--- 1.22/arch/ppc/platforms/prep_setup.c	Thu May  2 18:43:12 2002
+++ edited/arch/ppc/platforms/prep_setup.c	Wed May 15 07:35:01 2002
@@ -691,8 +691,11 @@
 {
 	int i;

-	if (OpenPIC_Addr != NULL)
-		openpic_init(1, NUM_8259_INTERRUPTS, -1);
+	if (OpenPIC_Addr != NULL) {
+		openpic_init(NUM_8259_INTERRUPTS, 0);
+		/* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
+		openpic_init_cascade(NUM_8259_INTERRUPTS, "82c59 cascade");
+	}
 	for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
 		irq_desc[i].handler = &i8259_pic;
 	i8259_init(MPC10X_MAPA_PCI_INTACK_ADDR);
===== include/asm-ppc/open_pic.h 1.10 vs edited =====
--- 1.10/include/asm-ppc/open_pic.h	Wed May  1 07:37:15 2002
+++ edited/include/asm-ppc/open_pic.h	Wed May 15 07:35:01 2002
@@ -55,7 +55,9 @@

 /* Exported functions */
 extern void openpic_set_sources(int first_irq, int num_irqs, void *isr);
-extern void openpic_init(int, int, int);
+extern void openpic_init(int linux_irq_offset, int openpic_serial_mode);
+extern void openpic_init_cascade(u_int irq, char *name);
+extern void openpic_init_nmi_irq(u_int irq);
 extern u_int openpic_irq(void);
 extern void openpic_eoi(void);
 extern void openpic_request_IPIs(void);

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





More information about the Linuxppc-embedded mailing list