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: 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>
This commit is contained in:
parent
6b07d38aaa
commit
dbb103b243
|
@ -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}
|
||||
* 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);
|
||||
|
@ -201,6 +201,20 @@ static void octeon_irq_ciu0_disable_v2(unsigned int irq)
|
|||
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.
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
* 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);
|
||||
|
@ -382,6 +396,20 @@ static void octeon_irq_ciu1_disable_v2(unsigned int irq)
|
|||
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.
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue