MIPS: Alchemy: Fix hang with high-frequency edge interrupts

The handle_edge_irq() flowhandler disables edge int sources which occur
too fast (i.e. another edge comes in before the irq handler function
had a chance to finish). Currently, the mask_ack() callback does not
ack the edges in hardware, leading to an endless loop in the flowhandler
where it tries to shut up the irq source.

When I rewrote the alchemy IRQ code I wrongly assumed the mask_ack()
callback was only used by the level flowhandler, hence it omitted the
(at the time pointless) edge acks. Turned out I was wrong; so here
is a complete mask_ack implementation for Alchemy IC, which fixes
the above mentioned problem.

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by Manuel Lauss and committed by Ralf Baechle 44f2c586 fcc152f3

+26 -8
+26 -8
arch/mips/alchemy/common/irq.c
··· 354 354 au_sync(); 355 355 } 356 356 357 + static void au1x_ic0_maskack(unsigned int irq_nr) 358 + { 359 + unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 360 + 361 + au_writel(1 << bit, IC0_WAKECLR); 362 + au_writel(1 << bit, IC0_MASKCLR); 363 + au_writel(1 << bit, IC0_RISINGCLR); 364 + au_writel(1 << bit, IC0_FALLINGCLR); 365 + au_sync(); 366 + } 367 + 368 + static void au1x_ic1_maskack(unsigned int irq_nr) 369 + { 370 + unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; 371 + 372 + au_writel(1 << bit, IC1_WAKECLR); 373 + au_writel(1 << bit, IC1_MASKCLR); 374 + au_writel(1 << bit, IC1_RISINGCLR); 375 + au_writel(1 << bit, IC1_FALLINGCLR); 376 + au_sync(); 377 + } 378 + 357 379 static int au1x_ic1_setwake(unsigned int irq, unsigned int on) 358 380 { 359 381 unsigned int bit = irq - AU1000_INTC1_INT_BASE; ··· 401 379 /* 402 380 * irq_chips for both ICs; this way the mask handlers can be 403 381 * as short as possible. 404 - * 405 - * NOTE: the ->ack() callback is used by the handle_edge_irq 406 - * flowhandler only, the ->mask_ack() one by handle_level_irq, 407 - * so no need for an irq_chip for each type of irq (level/edge). 408 382 */ 409 383 static struct irq_chip au1x_ic0_chip = { 410 384 .name = "Alchemy-IC0", 411 - .ack = au1x_ic0_ack, /* edge */ 385 + .ack = au1x_ic0_ack, 412 386 .mask = au1x_ic0_mask, 413 - .mask_ack = au1x_ic0_mask, /* level */ 387 + .mask_ack = au1x_ic0_maskack, 414 388 .unmask = au1x_ic0_unmask, 415 389 .set_type = au1x_ic_settype, 416 390 }; 417 391 418 392 static struct irq_chip au1x_ic1_chip = { 419 393 .name = "Alchemy-IC1", 420 - .ack = au1x_ic1_ack, /* edge */ 394 + .ack = au1x_ic1_ack, 421 395 .mask = au1x_ic1_mask, 422 - .mask_ack = au1x_ic1_mask, /* level */ 396 + .mask_ack = au1x_ic1_maskack, 423 397 .unmask = au1x_ic1_unmask, 424 398 .set_type = au1x_ic_settype, 425 399 .set_wake = au1x_ic1_setwake,