On Fri, Jun 10, 2011 at 08:20:42PM -0400, Guenter Roeck wrote:
[ ... ]
> Hi David,
> Turns out my primary problem is that octeon_irq_setup_secondary_ciu()
> sets C0_STATUS to 0x1000efe0, ie all interrupts except IP4 are enabled.
> This mask is primarily set through octeon_irq_percpu_enable(), which
> sets C0_STATUS to 0x1000e3e0. The value differs from CPU 0, where
> C0_STATUS is set to 0x10008ce0.
> This causes persistent spurious interrupts on our boards (both with
> CN38xx and CN58xx), where C0_CAUSE persistently reads as zero in the
> interrupt handling code but interrupts are triggered anyway. The
> spurious interrupt problem goes away if I mask out IP0, IP1, IP5, and
> IP6 at the end of octeon_irq_setup_secondary_ciu().
Answering part of my own question: The interrupt enable bits for secondary CPUs
are all set through octeon_irq_core_eoi(), which is called from the per-CPU
initialization code and enables each interrupt even if "desired_en" is false
for a given bit. I modified octeon_irq_core_eoi() to
set_c0_status(0x100 << cd->bit);
which takes care of the problem. No idea if that is correct, though.
The actual interrupt causing trouble and spurious interrupts in my case is,
oddly enough, STATUSF_IP0. So far I have been unable to track down how that
is triggered; I don't see the bit being set set in C0_CAUSE anywhere.
Are there any means to trigger an IP0 interrupt other than by writing
into the C0_CAUSE register ?