Commit dbb103b2 authored by David Daney's avatar David Daney Committed by Ralf Baechle

MIPS: Octeon: Fix EOI handling.

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: default avatarDavid 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 6b07d38a
...@@ -193,7 +193,7 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq) ...@@ -193,7 +193,7 @@ 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} * Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers. * 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; int index = cvmx_get_core_num() * 2;
u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
...@@ -201,6 +201,20 @@ static void octeon_irq_ciu0_disable_v2(unsigned int irq) ...@@ -201,6 +201,20 @@ static void octeon_irq_ciu0_disable_v2(unsigned int irq)
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); 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} * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers. * registers.
...@@ -272,8 +286,8 @@ static struct irq_chip octeon_irq_chip_ciu0_v2 = { ...@@ -272,8 +286,8 @@ static struct irq_chip octeon_irq_chip_ciu0_v2 = {
.name = "CIU0", .name = "CIU0",
.enable = octeon_irq_ciu0_enable_v2, .enable = octeon_irq_ciu0_enable_v2,
.disable = octeon_irq_ciu0_disable_all_v2, .disable = octeon_irq_ciu0_disable_all_v2,
.ack = octeon_irq_ciu0_disable_v2, .ack = octeon_irq_ciu0_ack_v2,
.eoi = octeon_irq_ciu0_enable_v2, .eoi = octeon_irq_ciu0_eoi_v2,
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu0_set_affinity_v2, .set_affinity = octeon_irq_ciu0_set_affinity_v2,
#endif #endif
...@@ -374,7 +388,7 @@ static void octeon_irq_ciu1_enable_v2(unsigned int irq) ...@@ -374,7 +388,7 @@ 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} * Disable the irq on the current core for chips that have the EN*_W1{S,C}
* registers. * 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; int index = cvmx_get_core_num() * 2 + 1;
u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
...@@ -382,6 +396,20 @@ static void octeon_irq_ciu1_disable_v2(unsigned int irq) ...@@ -382,6 +396,20 @@ static void octeon_irq_ciu1_disable_v2(unsigned int irq)
cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask); 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} * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers. * registers.
...@@ -455,8 +483,8 @@ static struct irq_chip octeon_irq_chip_ciu1_v2 = { ...@@ -455,8 +483,8 @@ static struct irq_chip octeon_irq_chip_ciu1_v2 = {
.name = "CIU0", .name = "CIU0",
.enable = octeon_irq_ciu1_enable_v2, .enable = octeon_irq_ciu1_enable_v2,
.disable = octeon_irq_ciu1_disable_all_v2, .disable = octeon_irq_ciu1_disable_all_v2,
.ack = octeon_irq_ciu1_disable_v2, .ack = octeon_irq_ciu1_ack_v2,
.eoi = octeon_irq_ciu1_enable_v2, .eoi = octeon_irq_ciu1_eoi_v2,
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu1_set_affinity_v2, .set_affinity = octeon_irq_ciu1_set_affinity_v2,
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment