linux-mips
[Top] [All Lists]

Re: Linux 2.6.39 on Cavium CN38xx

To: Guenter Roeck <guenter.roeck@ericsson.com>
Subject: Re: Linux 2.6.39 on Cavium CN38xx
From: David Daney <ddaney@caviumnetworks.com>
Date: Mon, 13 Jun 2011 14:10:06 -0700
Cc: "linux-mips@linux-mips.org" <linux-mips@linux-mips.org>
In-reply-to: <20110612164155.GA30615@ericsson.com>
References: <1307653714.8271.130.camel@groeck-laptop> <4DF13E25.2060502@caviumnetworks.com> <20110609220614.GA13583@ericsson.com> <4DF15068.30906@caviumnetworks.com> <1307751642.8271.315.camel@groeck-laptop> <20110612164155.GA30615@ericsson.com>
Sender: linux-mips-bounce@linux-mips.org
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Thunderbird/3.0.10
On 06/12/2011 09:41 AM, Guenter Roeck wrote:
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

        if (cd->desired_en)
                 set_c0_status(0x100<<  cd->bit);


That shouldn't be needed. The logic in irq_cpu_online() should only call chip->irq_cpu_online() if the irq is enabled.


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 
STATUSF_IP0
into the C0_CAUSE register ?


No. Nothing that I know of ever uses IP0 and IP1, so they should always be cleared.

David Daney.

<Prev in Thread] Current Thread [Next in Thread>