diff options
Diffstat (limited to 'arch/arm/mach-rpc/irq.c')
-rw-r--r-- | arch/arm/mach-rpc/irq.c | 136 |
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 | ||
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; |
118 | 72 | ||
119 | void __init rpc_init_irq(void) | 73 | void __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 | |||