Commit 86568dc4 authored by David Daney's avatar David Daney Committed by Ralf Baechle

MIPS: Octeon: Do proper acknowledgment of CIU timer interrupts.

Signed-off-by: default avatarDavid Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
To: netdev@vger.kernel.org
To: gregkh@suse.de
Patchwork: http://patchwork.linux-mips.org/patch/967/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent f8c26486
...@@ -51,9 +51,6 @@ static void octeon_irq_core_eoi(unsigned int irq) ...@@ -51,9 +51,6 @@ static void octeon_irq_core_eoi(unsigned int irq)
*/ */
if (desc->status & IRQ_DISABLED) if (desc->status & IRQ_DISABLED)
return; return;
/* There is a race here. We should fix it. */
/* /*
* We don't need to disable IRQs to make these atomic since * We don't need to disable IRQs to make these atomic since
* they are already disabled earlier in the low level * they are already disabled earlier in the low level
...@@ -201,6 +198,29 @@ static void octeon_irq_ciu0_ack_v2(unsigned int irq) ...@@ -201,6 +198,29 @@ static void octeon_irq_ciu0_ack_v2(unsigned int irq)
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask); cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
} }
/*
* CIU timer type interrupts must be acknoleged by writing a '1' bit
* to their sum0 bit.
*/
static void octeon_irq_ciu0_timer_ack(unsigned int irq)
{
int index = cvmx_get_core_num() * 2;
uint64_t mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
}
static void octeon_irq_ciu0_timer_ack_v1(unsigned int irq)
{
octeon_irq_ciu0_timer_ack(irq);
octeon_irq_ciu0_ack(irq);
}
static void octeon_irq_ciu0_timer_ack_v2(unsigned int irq)
{
octeon_irq_ciu0_timer_ack(irq);
octeon_irq_ciu0_ack_v2(irq);
}
/* /*
* Enable the irq on the current core for chips that have the EN*_W1{S,C} * Enable the irq on the current core for chips that have the EN*_W1{S,C}
* registers. * registers.
...@@ -304,6 +324,28 @@ static struct irq_chip octeon_irq_chip_ciu0 = { ...@@ -304,6 +324,28 @@ static struct irq_chip octeon_irq_chip_ciu0 = {
#endif #endif
}; };
static struct irq_chip octeon_irq_chip_ciu0_timer_v2 = {
.name = "CIU0-T",
.enable = octeon_irq_ciu0_enable_v2,
.disable = octeon_irq_ciu0_disable_all_v2,
.ack = octeon_irq_ciu0_timer_ack_v2,
.eoi = octeon_irq_ciu0_eoi_v2,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu0_set_affinity_v2,
#endif
};
static struct irq_chip octeon_irq_chip_ciu0_timer = {
.name = "CIU0-T",
.enable = octeon_irq_ciu0_enable,
.disable = octeon_irq_ciu0_disable,
.ack = octeon_irq_ciu0_timer_ack_v1,
.eoi = octeon_irq_ciu0_eoi,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu0_set_affinity,
#endif
};
static void octeon_irq_ciu1_ack(unsigned int irq) static void octeon_irq_ciu1_ack(unsigned int irq)
{ {
...@@ -587,6 +629,7 @@ void __init arch_init_irq(void) ...@@ -587,6 +629,7 @@ void __init arch_init_irq(void)
{ {
int irq; int irq;
struct irq_chip *chip0; struct irq_chip *chip0;
struct irq_chip *chip0_timer;
struct irq_chip *chip1; struct irq_chip *chip1;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -602,9 +645,11 @@ void __init arch_init_irq(void) ...@@ -602,9 +645,11 @@ void __init arch_init_irq(void)
OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) || OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) { OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) {
chip0 = &octeon_irq_chip_ciu0_v2; chip0 = &octeon_irq_chip_ciu0_v2;
chip0_timer = &octeon_irq_chip_ciu0_timer_v2;
chip1 = &octeon_irq_chip_ciu1_v2; chip1 = &octeon_irq_chip_ciu1_v2;
} else { } else {
chip0 = &octeon_irq_chip_ciu0; chip0 = &octeon_irq_chip_ciu0;
chip0_timer = &octeon_irq_chip_ciu0_timer;
chip1 = &octeon_irq_chip_ciu1; chip1 = &octeon_irq_chip_ciu1;
} }
...@@ -618,7 +663,21 @@ void __init arch_init_irq(void) ...@@ -618,7 +663,21 @@ void __init arch_init_irq(void)
/* 24 - 87 CIU_INT_SUM0 */ /* 24 - 87 CIU_INT_SUM0 */
for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) { for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
switch (irq) {
case OCTEON_IRQ_GMX_DRP0:
case OCTEON_IRQ_GMX_DRP1:
case OCTEON_IRQ_IPD_DRP:
case OCTEON_IRQ_KEY_ZERO:
case OCTEON_IRQ_TIMER0:
case OCTEON_IRQ_TIMER1:
case OCTEON_IRQ_TIMER2:
case OCTEON_IRQ_TIMER3:
set_irq_chip_and_handler(irq, chip0_timer, handle_percpu_irq);
break;
default:
set_irq_chip_and_handler(irq, chip0, handle_percpu_irq); set_irq_chip_and_handler(irq, chip0, handle_percpu_irq);
break;
}
} }
/* 88 - 151 CIU_INT_SUM1 */ /* 88 - 151 CIU_INT_SUM1 */
......
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