aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Daney <ddaney@caviumnetworks.com>2010-01-07 14:05:00 -0500
committerRalf Baechle <ralf@linux-mips.org>2010-02-27 06:53:06 -0500
commitdbb103b243e09475c84df2b8ef17615975593761 (patch)
tree80e99c4b63aac1d9e10e0845f29931e2d61cf79c /arch
parent6b07d38aaa520cee922fadfeaf90c97faf217045 (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 6f2acf09328d..1460d0836dc0 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -193,7 +193,7 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq)
193 * Disable the irq on the current core for chips that have the EN*_W1{S,C} 193 * Disable the irq on the current core for chips that have the EN*_W1{S,C}
194 * registers. 194 * registers.
195 */ 195 */
196static void octeon_irq_ciu0_disable_v2(unsigned int irq) 196static void octeon_irq_ciu0_ack_v2(unsigned int irq)
197{ 197{
198 int index = cvmx_get_core_num() * 2; 198 int index = cvmx_get_core_num() * 2;
199 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0); 199 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
@@ -202,6 +202,20 @@ static void octeon_irq_ciu0_disable_v2(unsigned int irq)
202} 202}
203 203
204/* 204/*
205 * Enable the irq on the current core for chips that have the EN*_W1{S,C}
206 * registers.
207 */
208static void octeon_irq_ciu0_eoi_v2(unsigned int irq)
209{
210 struct irq_desc *desc = irq_desc + irq;
211 int index = cvmx_get_core_num() * 2;
212 u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
213
214 if ((desc->status & IRQ_DISABLED) == 0)
215 cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
216}
217
218/*
205 * Disable the irq on the all cores for chips that have the EN*_W1{S,C} 219 * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
206 * registers. 220 * registers.
207 */ 221 */
@@ -272,8 +286,8 @@ static struct irq_chip octeon_irq_chip_ciu0_v2 = {
272 .name = "CIU0", 286 .name = "CIU0",
273 .enable = octeon_irq_ciu0_enable_v2, 287 .enable = octeon_irq_ciu0_enable_v2,
274 .disable = octeon_irq_ciu0_disable_all_v2, 288 .disable = octeon_irq_ciu0_disable_all_v2,
275 .ack = octeon_irq_ciu0_disable_v2, 289 .ack = octeon_irq_ciu0_ack_v2,
276 .eoi = octeon_irq_ciu0_enable_v2, 290 .eoi = octeon_irq_ciu0_eoi_v2,
277#ifdef CONFIG_SMP 291#ifdef CONFIG_SMP
278 .set_affinity = octeon_irq_ciu0_set_affinity_v2, 292 .set_affinity = octeon_irq_ciu0_set_affinity_v2,
279#endif 293#endif
@@ -374,7 +388,7 @@ static void octeon_irq_ciu1_enable_v2(unsigned int irq)
374 * Disable the irq on the current core for chips that have the EN*_W1{S,C} 388 * Disable the irq on the current core for chips that have the EN*_W1{S,C}
375 * registers. 389 * registers.
376 */ 390 */
377static void octeon_irq_ciu1_disable_v2(unsigned int irq) 391static void octeon_irq_ciu1_ack_v2(unsigned int irq)
378{ 392{
379 int index = cvmx_get_core_num() * 2 + 1; 393 int index = cvmx_get_core_num() * 2 + 1;
380 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0); 394 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
@@ -383,6 +397,20 @@ static void octeon_irq_ciu1_disable_v2(unsigned int irq)
383} 397}
384 398
385/* 399/*
400 * Enable the irq on the current core for chips that have the EN*_W1{S,C}
401 * registers.
402 */
403static void octeon_irq_ciu1_eoi_v2(unsigned int irq)
404{
405 struct irq_desc *desc = irq_desc + irq;
406 int index = cvmx_get_core_num() * 2 + 1;
407 u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
408
409 if ((desc->status & IRQ_DISABLED) == 0)
410 cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
411}
412
413/*
386 * Disable the irq on the all cores for chips that have the EN*_W1{S,C} 414 * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
387 * registers. 415 * registers.
388 */ 416 */
@@ -455,8 +483,8 @@ static struct irq_chip octeon_irq_chip_ciu1_v2 = {
455 .name = "CIU0", 483 .name = "CIU0",
456 .enable = octeon_irq_ciu1_enable_v2, 484 .enable = octeon_irq_ciu1_enable_v2,
457 .disable = octeon_irq_ciu1_disable_all_v2, 485 .disable = octeon_irq_ciu1_disable_all_v2,
458 .ack = octeon_irq_ciu1_disable_v2, 486 .ack = octeon_irq_ciu1_ack_v2,
459 .eoi = octeon_irq_ciu1_enable_v2, 487 .eoi = octeon_irq_ciu1_eoi_v2,
460#ifdef CONFIG_SMP 488#ifdef CONFIG_SMP
461 .set_affinity = octeon_irq_ciu1_set_affinity_v2, 489 .set_affinity = octeon_irq_ciu1_set_affinity_v2,
462#endif 490#endif