diff options
author | Dave Jiang <dave.jiang@gmail.com> | 2005-11-04 12:15:44 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-11-04 12:15:44 -0500 |
commit | 7866f6492856dde7d70e4f878e3893e1f91216ce (patch) | |
tree | 0b63ebe5c257c98ed52bc7f86508829b2d7102f4 /arch/arm/mach-ixp2000/core.c | |
parent | 73f0f7c79b046dc5d6b56a3f145430d97d50f877 (diff) |
[ARM] 3086/1: ixp2xxx error irq handling
Patch from Dave Jiang
This provides support for IXP2xxx error interrupt handling. Previously there was a patch to remove this (although the original stuff was broken). Well, now the error bits are needed again. These are used extensively by the micro-engine drivers according to Deepak and also we will need it for the new EDAC code that Alan Cox is trying to push into the main kernel.
Re-submit of 3072/1, generated against git tree pulled today. AFAICT, this git tree pulled in all the ARM changes that's in arm.diff. Please let me know if there are additional changes. Thx!
Signed-off-by: Dave Jiang <djiang@mvista.com>
Signed-off-by: Deepak Saxena <dsaxena@plexity.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-ixp2000/core.c')
-rw-r--r-- | arch/arm/mach-ixp2000/core.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index c93a98b2a32c..df140962bb0f 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c | |||
@@ -402,6 +402,40 @@ static void ixp2000_pci_irq_unmask(unsigned int irq) | |||
402 | ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27))); | 402 | ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27))); |
403 | } | 403 | } |
404 | 404 | ||
405 | /* | ||
406 | * Error interrupts. These are used extensively by the microengine drivers | ||
407 | */ | ||
408 | static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) | ||
409 | { | ||
410 | int i; | ||
411 | unsigned long status = *IXP2000_IRQ_ERR_STATUS; | ||
412 | |||
413 | for(i = 31; i >= 0; i--) { | ||
414 | if(status & (1 << i)) { | ||
415 | desc = irq_desc + IRQ_IXP2000_DRAM0_MIN_ERR + i; | ||
416 | desc->handle(IRQ_IXP2000_DRAM0_MIN_ERR + i, desc, regs); | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static void ixp2000_err_irq_mask(unsigned int irq) | ||
422 | { | ||
423 | ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR, | ||
424 | (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR))); | ||
425 | } | ||
426 | |||
427 | static void ixp2000_err_irq_unmask(unsigned int irq) | ||
428 | { | ||
429 | ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET, | ||
430 | (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR))); | ||
431 | } | ||
432 | |||
433 | static struct irqchip ixp2000_err_irq_chip = { | ||
434 | .ack = ixp2000_err_irq_mask, | ||
435 | .mask = ixp2000_err_irq_mask, | ||
436 | .unmask = ixp2000_err_irq_unmask | ||
437 | }; | ||
438 | |||
405 | static struct irqchip ixp2000_pci_irq_chip = { | 439 | static struct irqchip ixp2000_pci_irq_chip = { |
406 | .ack = ixp2000_pci_irq_mask, | 440 | .ack = ixp2000_pci_irq_mask, |
407 | .mask = ixp2000_pci_irq_mask, | 441 | .mask = ixp2000_pci_irq_mask, |
@@ -459,6 +493,18 @@ void __init ixp2000_init_irq(void) | |||
459 | } else set_irq_flags(irq, 0); | 493 | } else set_irq_flags(irq, 0); |
460 | } | 494 | } |
461 | 495 | ||
496 | for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) { | ||
497 | if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) & | ||
498 | IXP2000_VALID_ERR_IRQ_MASK) { | ||
499 | set_irq_chip(irq, &ixp2000_err_irq_chip); | ||
500 | set_irq_handler(irq, do_level_IRQ); | ||
501 | set_irq_flags(irq, IRQF_VALID); | ||
502 | } | ||
503 | else | ||
504 | set_irq_flags(irq, 0); | ||
505 | } | ||
506 | set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler); | ||
507 | |||
462 | /* | 508 | /* |
463 | * GPIO IRQs are invalid until someone sets the interrupt mode | 509 | * GPIO IRQs are invalid until someone sets the interrupt mode |
464 | * by calling set_irq_type(). | 510 | * by calling set_irq_type(). |