aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-rpc/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-rpc/irq.c')
-rw-r--r--arch/arm/mach-rpc/irq.c136
1 files changed, 49 insertions, 87 deletions
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index b8a61cb11207..803aeb126f0e 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -8,117 +8,71 @@
8#include <asm/irq.h> 8#include <asm/irq.h>
9#include <asm/fiq.h> 9#include <asm/fiq.h>
10 10
11static void iomd_ack_irq_a(struct irq_data *d) 11// These are offsets from the stat register for each IRQ bank
12{ 12#define STAT 0x00
13 unsigned int val, mask; 13#define REQ 0x04
14 14#define CLR 0x04
15 mask = 1 << d->irq; 15#define MASK 0x08
16 val = iomd_readb(IOMD_IRQMASKA);
17 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
18 iomd_writeb(mask, IOMD_IRQCLRA);
19}
20
21static void iomd_mask_irq_a(struct irq_data *d)
22{
23 unsigned int val, mask;
24 16
25 mask = 1 << d->irq; 17static void __iomem *iomd_get_base(struct irq_data *d)
26 val = iomd_readb(IOMD_IRQMASKA);
27 iomd_writeb(val & ~mask, IOMD_IRQMASKA);
28}
29
30static void iomd_unmask_irq_a(struct irq_data *d)
31{ 18{
32 unsigned int val, mask; 19 void *cd = irq_data_get_irq_chip_data(d);
33 20
34 mask = 1 << d->irq; 21 return (void __iomem *)(unsigned long)cd;
35 val = iomd_readb(IOMD_IRQMASKA);
36 iomd_writeb(val | mask, IOMD_IRQMASKA);
37} 22}
38 23
39static struct irq_chip iomd_a_chip = { 24static void iomd_set_base_mask(unsigned int irq, void __iomem *base, u32 mask)
40 .irq_ack = iomd_ack_irq_a,
41 .irq_mask = iomd_mask_irq_a,
42 .irq_unmask = iomd_unmask_irq_a,
43};
44
45static void iomd_mask_irq_b(struct irq_data *d)
46{ 25{
47 unsigned int val, mask; 26 struct irq_data *d = irq_get_irq_data(irq);
48 27
49 mask = 1 << (d->irq & 7); 28 d->mask = mask;
50 val = iomd_readb(IOMD_IRQMASKB); 29 irq_set_chip_data(irq, (void *)(unsigned long)base);
51 iomd_writeb(val & ~mask, IOMD_IRQMASKB);
52} 30}
53 31
54static void iomd_unmask_irq_b(struct irq_data *d) 32static void iomd_irq_mask_ack(struct irq_data *d)
55{ 33{
56 unsigned int val, mask; 34 void __iomem *base = iomd_get_base(d);
35 unsigned int val, mask = d->mask;
57 36
58 mask = 1 << (d->irq & 7); 37 val = readb(base + MASK);
59 val = iomd_readb(IOMD_IRQMASKB); 38 writeb(val & ~mask, base + MASK);
60 iomd_writeb(val | mask, IOMD_IRQMASKB); 39 writeb(mask, base + CLR);
61} 40}
62 41
63static struct irq_chip iomd_b_chip = { 42static void iomd_irq_mask(struct irq_data *d)
64 .irq_ack = iomd_mask_irq_b,
65 .irq_mask = iomd_mask_irq_b,
66 .irq_unmask = iomd_unmask_irq_b,
67};
68
69static void iomd_mask_irq_dma(struct irq_data *d)
70{ 43{
71 unsigned int val, mask; 44 void __iomem *base = iomd_get_base(d);
45 unsigned int val, mask = d->mask;
72 46
73 mask = 1 << (d->irq & 7); 47 val = readb(base + MASK);
74 val = iomd_readb(IOMD_DMAMASK); 48 writeb(val & ~mask, base + MASK);
75 iomd_writeb(val & ~mask, IOMD_DMAMASK);
76} 49}
77 50
78static void iomd_unmask_irq_dma(struct irq_data *d) 51static void iomd_irq_unmask(struct irq_data *d)
79{ 52{
80 unsigned int val, mask; 53 void __iomem *base = iomd_get_base(d);
54 unsigned int val, mask = d->mask;
81 55
82 mask = 1 << (d->irq & 7); 56 val = readb(base + MASK);
83 val = iomd_readb(IOMD_DMAMASK); 57 writeb(val | mask, base + MASK);
84 iomd_writeb(val | mask, IOMD_DMAMASK);
85} 58}
86 59
87static struct irq_chip iomd_dma_chip = { 60static struct irq_chip iomd_chip_clr = {
88 .irq_ack = iomd_mask_irq_dma, 61 .irq_mask_ack = iomd_irq_mask_ack,
89 .irq_mask = iomd_mask_irq_dma, 62 .irq_mask = iomd_irq_mask,
90 .irq_unmask = iomd_unmask_irq_dma, 63 .irq_unmask = iomd_irq_unmask,
91}; 64};
92 65
93static void iomd_mask_irq_fiq(struct irq_data *d) 66static struct irq_chip iomd_chip_noclr = {
94{ 67 .irq_mask = iomd_irq_mask,
95 unsigned int val, mask; 68 .irq_unmask = iomd_irq_unmask,
96
97 mask = 1 << (d->irq & 7);
98 val = iomd_readb(IOMD_FIQMASK);
99 iomd_writeb(val & ~mask, IOMD_FIQMASK);
100}
101
102static void iomd_unmask_irq_fiq(struct irq_data *d)
103{
104 unsigned int val, mask;
105
106 mask = 1 << (d->irq & 7);
107 val = iomd_readb(IOMD_FIQMASK);
108 iomd_writeb(val | mask, IOMD_FIQMASK);
109}
110
111static struct irq_chip iomd_fiq_chip = {
112 .irq_ack = iomd_mask_irq_fiq,
113 .irq_mask = iomd_mask_irq_fiq,
114 .irq_unmask = iomd_unmask_irq_fiq,
115}; 69};
116 70
117extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; 71extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end;
118 72
119void __init rpc_init_irq(void) 73void __init rpc_init_irq(void)
120{ 74{
121 unsigned int irq, clr, set = 0; 75 unsigned int irq, clr, set;
122 76
123 iomd_writeb(0, IOMD_IRQMASKA); 77 iomd_writeb(0, IOMD_IRQMASKA);
124 iomd_writeb(0, IOMD_IRQMASKB); 78 iomd_writeb(0, IOMD_IRQMASKB);
@@ -130,6 +84,7 @@ void __init rpc_init_irq(void)
130 84
131 for (irq = 0; irq < NR_IRQS; irq++) { 85 for (irq = 0; irq < NR_IRQS; irq++) {
132 clr = IRQ_NOREQUEST; 86 clr = IRQ_NOREQUEST;
87 set = 0;
133 88
134 if (irq <= 6 || (irq >= 9 && irq <= 15)) 89 if (irq <= 6 || (irq >= 9 && irq <= 15))
135 clr |= IRQ_NOPROBE; 90 clr |= IRQ_NOPROBE;
@@ -140,30 +95,37 @@ void __init rpc_init_irq(void)
140 95
141 switch (irq) { 96 switch (irq) {
142 case 0 ... 7: 97 case 0 ... 7:
143 irq_set_chip_and_handler(irq, &iomd_a_chip, 98 irq_set_chip_and_handler(irq, &iomd_chip_clr,
144 handle_level_irq); 99 handle_level_irq);
145 irq_modify_status(irq, clr, set); 100 irq_modify_status(irq, clr, set);
101 iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATA,
102 BIT(irq));
146 break; 103 break;
147 104
148 case 8 ... 15: 105 case 8 ... 15:
149 irq_set_chip_and_handler(irq, &iomd_b_chip, 106 irq_set_chip_and_handler(irq, &iomd_chip_noclr,
150 handle_level_irq); 107 handle_level_irq);
151 irq_modify_status(irq, clr, set); 108 irq_modify_status(irq, clr, set);
109 iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATB,
110 BIT(irq - 8));
152 break; 111 break;
153 112
154 case 16 ... 21: 113 case 16 ... 21:
155 irq_set_chip_and_handler(irq, &iomd_dma_chip, 114 irq_set_chip_and_handler(irq, &iomd_chip_noclr,
156 handle_level_irq); 115 handle_level_irq);
157 irq_modify_status(irq, clr, set); 116 irq_modify_status(irq, clr, set);
117 iomd_set_base_mask(irq, IOMD_BASE + IOMD_DMASTAT,
118 BIT(irq - 16));
158 break; 119 break;
159 120
160 case 64 ... 71: 121 case 64 ... 71:
161 irq_set_chip(irq, &iomd_fiq_chip); 122 irq_set_chip(irq, &iomd_chip_noclr);
162 irq_modify_status(irq, clr, set); 123 irq_modify_status(irq, clr, set);
124 iomd_set_base_mask(irq, IOMD_BASE + IOMD_FIQSTAT,
125 BIT(irq - 64));
163 break; 126 break;
164 } 127 }
165 } 128 }
166 129
167 init_FIQ(FIQ_START); 130 init_FIQ(FIQ_START);
168} 131}
169