PrPMC800 interrupt problem

10 messages, 2 authors, 2002-10-26 · open the first message on its own page

PrPMC800 interrupt problem

From: Anders Blomdell <hidden>
Date: 2002-10-24 17:01:19

When trying to use the linuxppc_2_4_devel on a PrPMC800, the system stops
responding to external interrupts after the first serial interrupt. Many
things works, since the system correctly gets its IP address via DHCP.

The system handles a little more than 100 interrupts that gets routed to
'e100intr', then it starts up my shell that does a write to the console.
This write triggers an interrupt that gets routed to 'rs_interrupt_single'
. After this no more interrupts are received, but 'rs_interrupt_single' is
called from the timer task in the serial driver, but the ethernet is
totally dead. Anybody that has a good idea what to do about this?

Regards

Anders Blomdell


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

Re: PrPMC800 interrupt problem

From: Tom Rini <hidden>
Date: 2002-10-24 17:26:42

On Thu, Oct 24, 2002 at 07:01:19PM +0200, Anders Blomdell wrote:
When trying to use the linuxppc_2_4_devel on a PrPMC800, the system stops
responding to external interrupts after the first serial interrupt. Many
things works, since the system correctly gets its IP address via DHCP.

The system handles a little more than 100 interrupts that gets routed to
'e100intr', then it starts up my shell that does a write to the console.
This write triggers an interrupt that gets routed to 'rs_interrupt_single'
. After this no more interrupts are received, but 'rs_interrupt_single' is
called from the timer task in the serial driver, but the ethernet is
totally dead. Anybody that has a good idea what to do about this?
Did you update the prpmc800_openpic_initsenses[] table and related?
(Look at how the lopec or sandpoint work now).

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

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

Re: PrPMC800 interrupt problem

From: Anders Blomdell <hidden>
Date: 2002-10-25 15:15:46

The problem seems to be that the UART generates an Harrier internal
interrupt. This should be handled as any other MPIC interrupt, but it isn'
t. This lack of an appropriate handler (irq_desc[16].handler == 0) makes
the Harrier chip wait forever for an EOI.

A very hacky solution to this is to modify 'prpmc800_init_IRQ' to:

static void __init
prpmc800_init_IRQ(void)
{

   openpic_init(0);
   // Handle UART interrupts as all other openpic interrupts, this is a
   // gross hack.
   openpic_set_sources(16, 1, OpenPIC_Addr + 0x10200);
   irq_desc[16].handler = irq_desc[15].handler;

#define PRIORITY	15
#define VECTOR	 	16
#define PROCESSOR	0
	/* initialize the harrier's internal interrupt priority 15, irq 1 */
	out_be32((u32 *)HARRIER_IFEVP_REG, (PRIORITY<<16) | VECTOR);
	out_be32((u32 *)HARRIER_IFEDE_REG, (1<<PROCESSOR));

	/* enable functional exceptions for uarts and abort */
	out_8((u8 *)HARRIER_FEEN_REG, (HARRIER_FE_UA0|HARRIER_FE_UA1));
	out_8((u8 *)HARRIER_FEMA_REG, ~(HARRIER_FE_UA0|HARRIER_FE_UA1));
}


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

Re: PrPMC800 interrupt problem

From: Tom Rini <hidden>
Date: 2002-10-25 15:40:20

On Fri, Oct 25, 2002 at 05:15:46PM +0200, Anders Blomdell wrote:
The problem seems to be that the UART generates an Harrier internal
interrupt. This should be handled as any other MPIC interrupt, but it isn'
t. This lack of an appropriate handler (irq_desc[16].handler == 0) makes
the Harrier chip wait forever for an EOI.

A very hacky solution to this is to modify 'prpmc800_init_IRQ' to:
Did you update the initsenses table as well?  And are you sure you are
calling openpic_set_sources() correctly?  That only maps OpenPIC source
16 to be Linux interrupt 16, and doesn't catch any of the other sources
('tho I don't have the prpmc800 manual in front of me)

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

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

Re: PrPMC800 interrupt problem

From: Anders Blomdell <hidden>
Date: 2002-10-25 15:44:26

A very hacky solution to this is to modify 'prpmc800_init_IRQ' to:
<snip>
A better solution is perhaps to change openpic_init from

	if (NumSources == 0)
		openpic_set_sources(0,
				    ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
				     OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1,
				    NULL);

to

	if (NumSources == 0) {
   		int irqs;
	    irqs = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
				     OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1;
	    if (irqs < OpenPIC_NumInitSenses) {
	      // Some internal interrupt is defined, init it's vector as well
		  irqs = OpenPIC_NumInitSenses;
        }
		openpic_set_sources(0, irqs, NULL);
     }

Any insight is welcome! As far as I can see, open_pic.c does not handle
timer, ipi, uart or any other internal interrupt sources (as they are not
reported in the feature register).


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

Re: PrPMC800 interrupt problem

From: Anders Blomdell <hidden>
Date: 2002-10-25 15:50:35

On fredag, oktober 25, 2002, at 05:40 , Tom Rini wrote:
On Fri, Oct 25, 2002 at 05:15:46PM +0200, Anders Blomdell wrote:
quoted
The problem seems to be that the UART generates an Harrier internal
interrupt. This should be handled as any other MPIC interrupt, but it isn'
t. This lack of an appropriate handler (irq_desc[16].handler == 0) makes
the Harrier chip wait forever for an EOI.

A very hacky solution to this is to modify 'prpmc800_init_IRQ' to:
Did you update the initsenses table as well?  And are you sure you are
calling openpic_set_sources() correctly?  That only maps OpenPIC source
16 to be Linux interrupt 16, and doesn't catch any of the other sources
('tho I don't have the prpmc800 manual in front of me)
The initsenses table was correct already, but open_pic.c relies on the
number of interrupt sources returned from the feature reporting register,
that excludes the internal sources (in Harrier, Hawk and Raven chips at
least). Thus these interrupts are not correctly setup. I posted a possible
(==untested) solution a few minutes ago.

BTW: Is there any documentation on the OpenPIC controllers, the AMD link
seems to have disappeared.

Regards

Anders Blomdell


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

Re: PrPMC800 interrupt problem

From: Tom Rini <hidden>
Date: 2002-10-25 16:00:01

On Fri, Oct 25, 2002 at 05:44:26PM +0200, Anders Blomdell wrote:
quoted
A very hacky solution to this is to modify 'prpmc800_init_IRQ' to:
<snip>
A better solution is perhaps to change openpic_init from

	if (NumSources == 0)
		openpic_set_sources(0,
				    ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK)
				    >>
				     OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1,
				    NULL);

to

	if (NumSources == 0) {
  		int irqs;
	    irqs = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >>
				     OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1;
	    if (irqs < OpenPIC_NumInitSenses) {
	      // Some internal interrupt is defined, init it's vector as well
		  irqs = OpenPIC_NumInitSenses;
       }
		openpic_set_sources(0, irqs, NULL);
    }

Any insight is welcome! As far as I can see, open_pic.c does not handle
timer, ipi, uart or any other internal interrupt sources (as they are not
reported in the feature register).
What you're suggesting brings back the old hacking behavior.  Again I
say, look at what lopec_setup.c does for handling interrupts, look at
the manual for the prpmc800 (and the MPC107 (OpenPIC/EPIC related bits)
or MPC8240 (again, OpenPIC/EPIC)) manuals.

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

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

Re: PrPMC800 interrupt problem

From: Tom Rini <hidden>
Date: 2002-10-25 16:04:33

On Fri, Oct 25, 2002 at 05:50:35PM +0200, Anders Blomdell wrote:
On fredag, oktober 25, 2002, at 05:40 , Tom Rini wrote:
quoted
On Fri, Oct 25, 2002 at 05:15:46PM +0200, Anders Blomdell wrote:
quoted
The problem seems to be that the UART generates an Harrier internal
interrupt. This should be handled as any other MPIC interrupt, but it isn'
t. This lack of an appropriate handler (irq_desc[16].handler == 0) makes
the Harrier chip wait forever for an EOI.

A very hacky solution to this is to modify 'prpmc800_init_IRQ' to:
Did you update the initsenses table as well?  And are you sure you are
calling openpic_set_sources() correctly?  That only maps OpenPIC source
16 to be Linux interrupt 16, and doesn't catch any of the other sources
('tho I don't have the prpmc800 manual in front of me)
The initsenses table was correct already, but open_pic.c relies on the
number of interrupt sources returned from the feature reporting register,
that excludes the internal sources (in Harrier, Hawk and Raven chips at
least). Thus these interrupts are not correctly setup. I posted a possible
(==untested) solution a few minutes ago.
If they are correct, change them from '1' / '0' to IRQ_SENSE_LEVEL |
IRQ_POLARITY_NEGATIVE.  I think the problem is that you are not calling
openpic_set_sources(...) correctly, or enough times.  openpic_init() can
only be called without calling openpic_set_sources() if the default call
in openpic_init() will work correctly, as is.
BTW: Is there any documentation on the OpenPIC controllers, the AMD link
seems to have disappeared.
The MPC107 manual or the MPC8240 manual, iirc.
Regards

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

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

Re: PrPMC800 interrupt problem

From: Anders Blomdell <hidden>
Date: 2002-10-25 16:42:22

What you're suggesting brings back the old hacking behavior.  Again I
say, look at what lopec_setup.c does for handling interrupts, look at
the manual for the prpmc800 (and the MPC107 (OpenPIC/EPIC related bits)
or MPC8240 (again, OpenPIC/EPIC)) manuals.
OK, hope this is a correct solution then (it works, which is a good thing)
. Thanks for your patience, all the levels in the interrupt handling are a
bit hairy to understand.

Regards

Anders Blomdell
--- ../2002-10-14/arch/ppc/platforms/prpmc800_setup.c   Fri Oct 11 17:58:31
2002
+++ arch/ppc/platforms/prpmc800_setup.c Fri Oct 25 18:33:49 2002
@@ -53,23 +53,23 @@

  static u_char prpmc800_openpic_initsenses[] __initdata =
  {
-    1, /* PRPMC800_INT_HOSTINT0 */
-    1, /* PRPMC800_INT_UNUSED */
-    1, /* PRPMC800_INT_DEBUGINT */
-    1, /* PRPMC800_INT_HARRIER_WDT */
-    1, /* PRPMC800_INT_UNUSED */
-    1, /* PRPMC800_INT_UNUSED */
-    1, /* PRPMC800_INT_HOSTINT1 */
-    1, /* PRPMC800_INT_HOSTINT2 */
-    1, /* PRPMC800_INT_HOSTINT3 */
-    1, /* PRPMC800_INT_PMC_INTA */
-    1, /* PRPMC800_INT_PMC_INTB */
-    1, /* PRPMC800_INT_PMC_INTC */
-    1, /* PRPMC800_INT_PMC_INTD */
-    1, /* PRPMC800_INT_UNUSED */
-    1, /* PRPMC800_INT_UNUSED */
-    1, /* PRPMC800_INT_UNUSED */
-    1, /* PRPMC800_INT_HARRIER_INT (UARTS, ABORT, DMA) */
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_HOSTINT0 *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_UNUSED */
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_DEBUGINT *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_HARRIER_WDT
*/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_UNUSED */
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_UNUSED */
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_HOSTINT1 *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_HOSTINT2 *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_HOSTINT3 *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_PMC_INTA *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_PMC_INTB *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_PMC_INTC *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_PMC_INTD *
/
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_UNUSED */
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_UNUSED */
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_UNUSED */
+  (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),   /* PRPMC800_INT_HARRIER_INT
(UARTS, ABORT, DMA) */
  };

  static int
@@ -105,9 +105,6 @@
         conswitchp = &dummy_con;
  #endif

-       OpenPIC_InitSenses = prpmc800_openpic_initsenses;
-       OpenPIC_NumInitSenses = sizeof(prpmc800_openpic_initsenses);
-
         printk("PrPMC800 port (C) 2001 MontaVista Software, Inc. (source@m
vista.com)\n");
  }
@@ -198,14 +195,16 @@
  static void __init
  prpmc800_init_IRQ(void)
  {
-       openpic_init(0);
+  OpenPIC_InitSenses = prpmc800_openpic_initsenses;
+  OpenPIC_NumInitSenses = sizeof(prpmc800_openpic_initsenses);

-#define PRIORITY       15
-#define VECTOR         16
-#define PROCESSOR      0
-       /* initialize the harrier's internal interrupt priority 15, irq 1
*/
-       out_be32((u32 *)HARRIER_IFEVP_REG, (PRIORITY<<16) | VECTOR);
-       out_be32((u32 *)HARRIER_IFEDE_REG, (1<<PROCESSOR));
+  // Setup external interrupt sources
+  openpic_set_sources(0, 16, OpenPIC_Addr + 0x10000);
+  // Setup internal UART interrupt source
+  openpic_set_sources(16, 1, OpenPIC_Addr + 0x10200);
+
+  // Do the MPIC initialization based on the above settings
+  openpic_init(0);

         /* enable functional exceptions for uarts and abort */
         out_8((u8 *)HARRIER_FEEN_REG, (HARRIER_FE_UA0|HARRIER_FE_UA1));


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

Re: PrPMC800 interrupt problem

From: Tom Rini <hidden>
Date: 2002-10-26 01:39:09

On Fri, Oct 25, 2002 at 06:42:22PM +0200, Anders Blomdell wrote:
quoted
What you're suggesting brings back the old hacking behavior.  Again I
say, look at what lopec_setup.c does for handling interrupts, look at
the manual for the prpmc800 (and the MPC107 (OpenPIC/EPIC related bits)
or MPC8240 (again, OpenPIC/EPIC)) manuals.
OK, hope this is a correct solution then (it works, which is a good thing)
. Thanks for your patience, all the levels in the interrupt handling are a
bit hairy to understand.
This looks much better, I will commit this monday.

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

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help