aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@gmail.com>2005-11-04 12:15:44 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-11-04 12:15:44 -0500
commit7866f6492856dde7d70e4f878e3893e1f91216ce (patch)
tree0b63ebe5c257c98ed52bc7f86508829b2d7102f4
parent73f0f7c79b046dc5d6b56a3f145430d97d50f877 (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>
-rw-r--r--arch/arm/mach-ixp2000/core.c46
-rw-r--r--include/asm-arm/arch-ixp2000/irqs.h35
2 files changed, 80 insertions, 1 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 */
408static 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
421static 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
427static 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
433static 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
405static struct irqchip ixp2000_pci_irq_chip = { 439static 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().
diff --git a/include/asm-arm/arch-ixp2000/irqs.h b/include/asm-arm/arch-ixp2000/irqs.h
index 0deb96c12adb..62f09c7ff420 100644
--- a/include/asm-arm/arch-ixp2000/irqs.h
+++ b/include/asm-arm/arch-ixp2000/irqs.h
@@ -67,12 +67,45 @@
67#define IRQ_IXP2000_PCIA 40 67#define IRQ_IXP2000_PCIA 40
68#define IRQ_IXP2000_PCIB 41 68#define IRQ_IXP2000_PCIB 41
69 69
70#define NR_IXP2000_IRQS 42 70/* Int sources from IRQ_ERROR_STATUS */
71#define IRQ_IXP2000_DRAM0_MIN_ERR 42
72#define IRQ_IXP2000_DRAM0_MAJ_ERR 43
73#define IRQ_IXP2000_DRAM1_MIN_ERR 44
74#define IRQ_IXP2000_DRAM1_MAJ_ERR 45
75#define IRQ_IXP2000_DRAM2_MIN_ERR 46
76#define IRQ_IXP2000_DRAM2_MAJ_ERR 47
77/* 48-57 reserved */
78#define IRQ_IXP2000_SRAM0_ERR 58
79#define IRQ_IXP2000_SRAM1_ERR 59
80#define IRQ_IXP2000_SRAM2_ERR 60
81#define IRQ_IXP2000_SRAM3_ERR 61
82/* 62-65 reserved */
83#define IRQ_IXP2000_MEDIA_ERR 66
84#define IRQ_IXP2000_PCI_ERR 67
85#define IRQ_IXP2000_SP_INT 68
86
87#define NR_IXP2000_IRQS 69
71 88
72#define IXP2000_BOARD_IRQ(x) (NR_IXP2000_IRQS + (x)) 89#define IXP2000_BOARD_IRQ(x) (NR_IXP2000_IRQS + (x))
73 90
74#define IXP2000_BOARD_IRQ_MASK(irq) (1 << (irq - NR_IXP2000_IRQS)) 91#define IXP2000_BOARD_IRQ_MASK(irq) (1 << (irq - NR_IXP2000_IRQS))
75 92
93#define IXP2000_ERR_IRQ_MASK(irq) ( 1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR))
94#define IXP2000_VALID_ERR_IRQ_MASK (\
95 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MIN_ERR) | \
96 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MAJ_ERR) | \
97 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MIN_ERR) | \
98 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MAJ_ERR) | \
99 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MIN_ERR) | \
100 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MAJ_ERR) | \
101 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM0_ERR) | \
102 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM1_ERR) | \
103 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM2_ERR) | \
104 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM3_ERR) | \
105 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_MEDIA_ERR) | \
106 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_PCI_ERR) | \
107 IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SP_INT) )
108
76/* 109/*
77 * This allows for all the on-chip sources plus up to 32 CPLD based 110 * This allows for all the on-chip sources plus up to 32 CPLD based
78 * IRQs. Should be more than enough. 111 * IRQs. Should be more than enough.