diff options
-rw-r--r-- | arch/arm/mach-rpc/irq.c | 133 |
1 files changed, 47 insertions, 86 deletions
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c index 7f0f40178634..803aeb126f0e 100644 --- a/arch/arm/mach-rpc/irq.c +++ b/arch/arm/mach-rpc/irq.c | |||
@@ -8,110 +8,64 @@ | |||
8 | #include <asm/irq.h> | 8 | #include <asm/irq.h> |
9 | #include <asm/fiq.h> | 9 | #include <asm/fiq.h> |
10 | 10 | ||
11 | static 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 | |||
21 | static void iomd_mask_irq_a(struct irq_data *d) | ||
22 | { | ||
23 | unsigned int val, mask; | ||
24 | 16 | ||
25 | mask = 1 << d->irq; | 17 | static void __iomem *iomd_get_base(struct irq_data *d) |
26 | val = iomd_readb(IOMD_IRQMASKA); | ||
27 | iomd_writeb(val & ~mask, IOMD_IRQMASKA); | ||
28 | } | ||
29 | |||
30 | static 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 | ||
39 | static struct irq_chip iomd_a_chip = { | 24 | static 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 | |||
45 | static 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 | ||
54 | static void iomd_unmask_irq_b(struct irq_data *d) | 32 | static 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 | ||
63 | static struct irq_chip iomd_b_chip = { | 42 | static 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 | |||
69 | static 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 | ||
78 | static void iomd_unmask_irq_dma(struct irq_data *d) | 51 | static 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 | ||
87 | static struct irq_chip iomd_dma_chip = { | 60 | static 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 | ||
93 | static void iomd_mask_irq_fiq(struct irq_data *d) | 66 | static 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 | |||
102 | static 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 | |||
111 | static 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 | ||
117 | extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; | 71 | extern unsigned char rpc_default_fiq_start, rpc_default_fiq_end; |
@@ -141,30 +95,37 @@ void __init rpc_init_irq(void) | |||
141 | 95 | ||
142 | switch (irq) { | 96 | switch (irq) { |
143 | case 0 ... 7: | 97 | case 0 ... 7: |
144 | irq_set_chip_and_handler(irq, &iomd_a_chip, | 98 | irq_set_chip_and_handler(irq, &iomd_chip_clr, |
145 | handle_level_irq); | 99 | handle_level_irq); |
146 | 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)); | ||
147 | break; | 103 | break; |
148 | 104 | ||
149 | case 8 ... 15: | 105 | case 8 ... 15: |
150 | irq_set_chip_and_handler(irq, &iomd_b_chip, | 106 | irq_set_chip_and_handler(irq, &iomd_chip_noclr, |
151 | handle_level_irq); | 107 | handle_level_irq); |
152 | 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)); | ||
153 | break; | 111 | break; |
154 | 112 | ||
155 | case 16 ... 21: | 113 | case 16 ... 21: |
156 | irq_set_chip_and_handler(irq, &iomd_dma_chip, | 114 | irq_set_chip_and_handler(irq, &iomd_chip_noclr, |
157 | handle_level_irq); | 115 | handle_level_irq); |
158 | 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)); | ||
159 | break; | 119 | break; |
160 | 120 | ||
161 | case 64 ... 71: | 121 | case 64 ... 71: |
162 | irq_set_chip(irq, &iomd_fiq_chip); | 122 | irq_set_chip(irq, &iomd_chip_noclr); |
163 | 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)); | ||
164 | break; | 126 | break; |
165 | } | 127 | } |
166 | } | 128 | } |
167 | 129 | ||
168 | init_FIQ(FIQ_START); | 130 | init_FIQ(FIQ_START); |
169 | } | 131 | } |
170 | |||