Skip to content

Commit

Permalink
MIPS: Octeon: Fix EOI handling.
Browse files Browse the repository at this point in the history
If an interrupt handler disables interrupts, the EOI function will
just reenable them.  This will put us in an endless loop when the
upcoming Ethernet driver patches are applied.

Only reenable the interrupt on EOI if it is not IRQ_DISABLED.  This
requires that the EOI function be separate from the ENABLE function.
We also rename the ACK functions to correspond with their function.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
To: gregkh@suse.de
Patchwork: http://patchwork.linux-mips.org/patch/840/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
David Daney authored and Ralf Baechle committed Feb 27, 2010
1 parent 6b07d38 commit dbb103b
Showing 1 changed file with 34 additions and 6 deletions.
40 changes: 34 additions & 6 deletions arch/mips/cavium-octeon/octeon-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,28 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq)
* Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu0_disable_v2(unsigned int irq)
static void octeon_irq_ciu0_ack_v2(unsigned int irq)
{
int index = cvmx_get_core_num() * 2;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);

cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
}

/*
* Enable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
{
struct irq_desc *desc = irq_desc + irq;
int index = cvmx_get_core_num() * 2;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);

if ((desc->status & IRQ_DISABLED) == 0)
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
}

/*
* Disable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers.
Expand Down Expand Up @@ -272,8 +286,8 @@ static struct irq_chip octeon_irq_chip_ciu0_v2 = {
.name = "CIU0",
.enable = octeon_irq_ciu0_enable_v2,
.disable = octeon_irq_ciu0_disable_all_v2,
.ack = octeon_irq_ciu0_disable_v2,
.eoi = octeon_irq_ciu0_enable_v2,
.ack = octeon_irq_ciu0_ack_v2,
.eoi = octeon_irq_ciu0_eoi_v2,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu0_set_affinity_v2,
#endif
Expand Down Expand Up @@ -374,14 +388,28 @@ static void octeon_irq_ciu1_enable_v2(unsigned int irq)
* Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu1_disable_v2(unsigned int irq)
static void octeon_irq_ciu1_ack_v2(unsigned int irq)
{
int index = cvmx_get_core_num() * 2 + 1;
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);

cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
}

/*
* Enable the irq on the current core for chips that have the EN*_W1{S,C}
* registers.
*/
static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
{
struct irq_desc *desc = irq_desc + irq;
int index = cvmx_get_core_num() * 2 + 1;
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);

if ((desc->status & IRQ_DISABLED) == 0)
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
}

/*
* Disable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers.
Expand Down Expand Up @@ -455,8 +483,8 @@ static struct irq_chip octeon_irq_chip_ciu1_v2 = {
.name = "CIU0",
.enable = octeon_irq_ciu1_enable_v2,
.disable = octeon_irq_ciu1_disable_all_v2,
.ack = octeon_irq_ciu1_disable_v2,
.eoi = octeon_irq_ciu1_enable_v2,
.ack = octeon_irq_ciu1_ack_v2,
.eoi = octeon_irq_ciu1_eoi_v2,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu1_set_affinity_v2,
#endif
Expand Down

0 comments on commit dbb103b

Please sign in to comment.