|
8 | 8 | #include <asm/irq.h>
|
9 | 9 | #include <asm/fiq.h>
|
10 | 10 |
|
11 |
| -static void iomd_ack_irq_a(struct irq_data *d) |
12 |
| -{ |
13 |
| - unsigned int val, mask; |
14 |
| - |
15 |
| - mask = 1 << d->irq; |
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; |
| 11 | +// These are offsets from the stat register for each IRQ bank |
| 12 | +#define STAT 0x00 |
| 13 | +#define REQ 0x04 |
| 14 | +#define CLR 0x04 |
| 15 | +#define MASK 0x08 |
24 | 16 |
|
25 |
| - mask = 1 << d->irq; |
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) |
| 17 | +static void __iomem *iomd_get_base(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; |
35 |
| - val = iomd_readb(IOMD_IRQMASKA); |
36 |
| - iomd_writeb(val | mask, IOMD_IRQMASKA); |
| 21 | + return (void __iomem *)(unsigned long)cd; |
37 | 22 | }
|
38 | 23 |
|
39 |
| -static struct irq_chip iomd_a_chip = { |
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) |
| 24 | +static void iomd_set_base_mask(unsigned int irq, void __iomem *base, u32 mask) |
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); |
50 |
| - val = iomd_readb(IOMD_IRQMASKB); |
51 |
| - iomd_writeb(val & ~mask, IOMD_IRQMASKB); |
| 28 | + d->mask = mask; |
| 29 | + irq_set_chip_data(irq, (void *)(unsigned long)base); |
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); |
59 |
| - val = iomd_readb(IOMD_IRQMASKB); |
60 |
| - iomd_writeb(val | mask, IOMD_IRQMASKB); |
| 37 | + val = readb(base + MASK); |
| 38 | + writeb(val & ~mask, base + MASK); |
| 39 | + writeb(mask, base + CLR); |
61 | 40 | }
|
62 | 41 |
|
63 |
| -static struct irq_chip iomd_b_chip = { |
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) |
| 42 | +static void iomd_irq_mask(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); |
74 |
| - val = iomd_readb(IOMD_DMAMASK); |
75 |
| - iomd_writeb(val & ~mask, IOMD_DMAMASK); |
| 47 | + val = readb(base + MASK); |
| 48 | + writeb(val & ~mask, base + MASK); |
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); |
83 |
| - val = iomd_readb(IOMD_DMAMASK); |
84 |
| - iomd_writeb(val | mask, IOMD_DMAMASK); |
| 56 | + val = readb(base + MASK); |
| 57 | + writeb(val | mask, base + MASK); |
85 | 58 | }
|
86 | 59 |
|
87 |
| -static struct irq_chip iomd_dma_chip = { |
88 |
| - .irq_ack = iomd_mask_irq_dma, |
89 |
| - .irq_mask = iomd_mask_irq_dma, |
90 |
| - .irq_unmask = iomd_unmask_irq_dma, |
| 60 | +static struct irq_chip iomd_chip_clr = { |
| 61 | + .irq_mask_ack = iomd_irq_mask_ack, |
| 62 | + .irq_mask = iomd_irq_mask, |
| 63 | + .irq_unmask = iomd_irq_unmask, |
91 | 64 | };
|
92 | 65 |
|
93 |
| -static void iomd_mask_irq_fiq(struct irq_data *d) |
94 |
| -{ |
95 |
| - unsigned int val, mask; |
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, |
| 66 | +static struct irq_chip iomd_chip_noclr = { |
| 67 | + .irq_mask = iomd_irq_mask, |
| 68 | + .irq_unmask = iomd_irq_unmask, |
115 | 69 | };
|
116 | 70 |
|
117 | 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 | 96 | switch (irq) {
|
143 | 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 | 99 | handle_level_irq);
|
146 | 100 | irq_modify_status(irq, clr, set);
|
| 101 | + iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATA, |
| 102 | + BIT(irq)); |
147 | 103 | break;
|
148 | 104 |
|
149 | 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 | 107 | handle_level_irq);
|
152 | 108 | irq_modify_status(irq, clr, set);
|
| 109 | + iomd_set_base_mask(irq, IOMD_BASE + IOMD_IRQSTATB, |
| 110 | + BIT(irq - 8)); |
153 | 111 | break;
|
154 | 112 |
|
155 | 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 | 115 | handle_level_irq);
|
158 | 116 | irq_modify_status(irq, clr, set);
|
| 117 | + iomd_set_base_mask(irq, IOMD_BASE + IOMD_DMASTAT, |
| 118 | + BIT(irq - 16)); |
159 | 119 | break;
|
160 | 120 |
|
161 | 121 | case 64 ... 71:
|
162 |
| - irq_set_chip(irq, &iomd_fiq_chip); |
| 122 | + irq_set_chip(irq, &iomd_chip_noclr); |
163 | 123 | irq_modify_status(irq, clr, set);
|
| 124 | + iomd_set_base_mask(irq, IOMD_BASE + IOMD_FIQSTAT, |
| 125 | + BIT(irq - 64)); |
164 | 126 | break;
|
165 | 127 | }
|
166 | 128 | }
|
167 | 129 |
|
168 | 130 | init_FIQ(FIQ_START);
|
169 | 131 | }
|
170 |
| - |
0 commit comments