diff options
Diffstat (limited to 'arch/powerpc/sysdev/uic.c')
-rw-r--r-- | arch/powerpc/sysdev/uic.c | 84 |
1 files changed, 38 insertions, 46 deletions
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c index 0038fb78f094..984cd2029158 100644 --- a/arch/powerpc/sysdev/uic.c +++ b/arch/powerpc/sysdev/uic.c | |||
@@ -41,8 +41,6 @@ | |||
41 | #define UIC_VR 0x7 | 41 | #define UIC_VR 0x7 |
42 | #define UIC_VCR 0x8 | 42 | #define UIC_VCR 0x8 |
43 | 43 | ||
44 | #define uic_irq_to_hw(virq) (irq_map[virq].hwirq) | ||
45 | |||
46 | struct uic *primary_uic; | 44 | struct uic *primary_uic; |
47 | 45 | ||
48 | struct uic { | 46 | struct uic { |
@@ -55,18 +53,17 @@ struct uic { | |||
55 | struct irq_host *irqhost; | 53 | struct irq_host *irqhost; |
56 | }; | 54 | }; |
57 | 55 | ||
58 | static void uic_unmask_irq(unsigned int virq) | 56 | static void uic_unmask_irq(struct irq_data *d) |
59 | { | 57 | { |
60 | struct irq_desc *desc = irq_to_desc(virq); | 58 | struct uic *uic = irq_data_get_irq_chip_data(d); |
61 | struct uic *uic = get_irq_chip_data(virq); | 59 | unsigned int src = irqd_to_hwirq(d); |
62 | unsigned int src = uic_irq_to_hw(virq); | ||
63 | unsigned long flags; | 60 | unsigned long flags; |
64 | u32 er, sr; | 61 | u32 er, sr; |
65 | 62 | ||
66 | sr = 1 << (31-src); | 63 | sr = 1 << (31-src); |
67 | spin_lock_irqsave(&uic->lock, flags); | 64 | spin_lock_irqsave(&uic->lock, flags); |
68 | /* ack level-triggered interrupts here */ | 65 | /* ack level-triggered interrupts here */ |
69 | if (desc->status & IRQ_LEVEL) | 66 | if (irqd_is_level_type(d)) |
70 | mtdcr(uic->dcrbase + UIC_SR, sr); | 67 | mtdcr(uic->dcrbase + UIC_SR, sr); |
71 | er = mfdcr(uic->dcrbase + UIC_ER); | 68 | er = mfdcr(uic->dcrbase + UIC_ER); |
72 | er |= sr; | 69 | er |= sr; |
@@ -74,10 +71,10 @@ static void uic_unmask_irq(unsigned int virq) | |||
74 | spin_unlock_irqrestore(&uic->lock, flags); | 71 | spin_unlock_irqrestore(&uic->lock, flags); |
75 | } | 72 | } |
76 | 73 | ||
77 | static void uic_mask_irq(unsigned int virq) | 74 | static void uic_mask_irq(struct irq_data *d) |
78 | { | 75 | { |
79 | struct uic *uic = get_irq_chip_data(virq); | 76 | struct uic *uic = irq_data_get_irq_chip_data(d); |
80 | unsigned int src = uic_irq_to_hw(virq); | 77 | unsigned int src = irqd_to_hwirq(d); |
81 | unsigned long flags; | 78 | unsigned long flags; |
82 | u32 er; | 79 | u32 er; |
83 | 80 | ||
@@ -88,10 +85,10 @@ static void uic_mask_irq(unsigned int virq) | |||
88 | spin_unlock_irqrestore(&uic->lock, flags); | 85 | spin_unlock_irqrestore(&uic->lock, flags); |
89 | } | 86 | } |
90 | 87 | ||
91 | static void uic_ack_irq(unsigned int virq) | 88 | static void uic_ack_irq(struct irq_data *d) |
92 | { | 89 | { |
93 | struct uic *uic = get_irq_chip_data(virq); | 90 | struct uic *uic = irq_data_get_irq_chip_data(d); |
94 | unsigned int src = uic_irq_to_hw(virq); | 91 | unsigned int src = irqd_to_hwirq(d); |
95 | unsigned long flags; | 92 | unsigned long flags; |
96 | 93 | ||
97 | spin_lock_irqsave(&uic->lock, flags); | 94 | spin_lock_irqsave(&uic->lock, flags); |
@@ -99,11 +96,10 @@ static void uic_ack_irq(unsigned int virq) | |||
99 | spin_unlock_irqrestore(&uic->lock, flags); | 96 | spin_unlock_irqrestore(&uic->lock, flags); |
100 | } | 97 | } |
101 | 98 | ||
102 | static void uic_mask_ack_irq(unsigned int virq) | 99 | static void uic_mask_ack_irq(struct irq_data *d) |
103 | { | 100 | { |
104 | struct irq_desc *desc = irq_to_desc(virq); | 101 | struct uic *uic = irq_data_get_irq_chip_data(d); |
105 | struct uic *uic = get_irq_chip_data(virq); | 102 | unsigned int src = irqd_to_hwirq(d); |
106 | unsigned int src = uic_irq_to_hw(virq); | ||
107 | unsigned long flags; | 103 | unsigned long flags; |
108 | u32 er, sr; | 104 | u32 er, sr; |
109 | 105 | ||
@@ -120,23 +116,22 @@ static void uic_mask_ack_irq(unsigned int virq) | |||
120 | * level interrupts are ack'ed after the actual | 116 | * level interrupts are ack'ed after the actual |
121 | * isr call in the uic_unmask_irq() | 117 | * isr call in the uic_unmask_irq() |
122 | */ | 118 | */ |
123 | if (!(desc->status & IRQ_LEVEL)) | 119 | if (!irqd_is_level_type(d)) |
124 | mtdcr(uic->dcrbase + UIC_SR, sr); | 120 | mtdcr(uic->dcrbase + UIC_SR, sr); |
125 | spin_unlock_irqrestore(&uic->lock, flags); | 121 | spin_unlock_irqrestore(&uic->lock, flags); |
126 | } | 122 | } |
127 | 123 | ||
128 | static int uic_set_irq_type(unsigned int virq, unsigned int flow_type) | 124 | static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type) |
129 | { | 125 | { |
130 | struct uic *uic = get_irq_chip_data(virq); | 126 | struct uic *uic = irq_data_get_irq_chip_data(d); |
131 | unsigned int src = uic_irq_to_hw(virq); | 127 | unsigned int src = irqd_to_hwirq(d); |
132 | struct irq_desc *desc = irq_to_desc(virq); | ||
133 | unsigned long flags; | 128 | unsigned long flags; |
134 | int trigger, polarity; | 129 | int trigger, polarity; |
135 | u32 tr, pr, mask; | 130 | u32 tr, pr, mask; |
136 | 131 | ||
137 | switch (flow_type & IRQ_TYPE_SENSE_MASK) { | 132 | switch (flow_type & IRQ_TYPE_SENSE_MASK) { |
138 | case IRQ_TYPE_NONE: | 133 | case IRQ_TYPE_NONE: |
139 | uic_mask_irq(virq); | 134 | uic_mask_irq(d); |
140 | return 0; | 135 | return 0; |
141 | 136 | ||
142 | case IRQ_TYPE_EDGE_RISING: | 137 | case IRQ_TYPE_EDGE_RISING: |
@@ -166,11 +161,6 @@ static int uic_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
166 | mtdcr(uic->dcrbase + UIC_PR, pr); | 161 | mtdcr(uic->dcrbase + UIC_PR, pr); |
167 | mtdcr(uic->dcrbase + UIC_TR, tr); | 162 | mtdcr(uic->dcrbase + UIC_TR, tr); |
168 | 163 | ||
169 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | ||
170 | desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; | ||
171 | if (!trigger) | ||
172 | desc->status |= IRQ_LEVEL; | ||
173 | |||
174 | spin_unlock_irqrestore(&uic->lock, flags); | 164 | spin_unlock_irqrestore(&uic->lock, flags); |
175 | 165 | ||
176 | return 0; | 166 | return 0; |
@@ -178,11 +168,11 @@ static int uic_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
178 | 168 | ||
179 | static struct irq_chip uic_irq_chip = { | 169 | static struct irq_chip uic_irq_chip = { |
180 | .name = "UIC", | 170 | .name = "UIC", |
181 | .unmask = uic_unmask_irq, | 171 | .irq_unmask = uic_unmask_irq, |
182 | .mask = uic_mask_irq, | 172 | .irq_mask = uic_mask_irq, |
183 | .mask_ack = uic_mask_ack_irq, | 173 | .irq_mask_ack = uic_mask_ack_irq, |
184 | .ack = uic_ack_irq, | 174 | .irq_ack = uic_ack_irq, |
185 | .set_type = uic_set_irq_type, | 175 | .irq_set_type = uic_set_irq_type, |
186 | }; | 176 | }; |
187 | 177 | ||
188 | static int uic_host_map(struct irq_host *h, unsigned int virq, | 178 | static int uic_host_map(struct irq_host *h, unsigned int virq, |
@@ -190,13 +180,13 @@ static int uic_host_map(struct irq_host *h, unsigned int virq, | |||
190 | { | 180 | { |
191 | struct uic *uic = h->host_data; | 181 | struct uic *uic = h->host_data; |
192 | 182 | ||
193 | set_irq_chip_data(virq, uic); | 183 | irq_set_chip_data(virq, uic); |
194 | /* Despite the name, handle_level_irq() works for both level | 184 | /* Despite the name, handle_level_irq() works for both level |
195 | * and edge irqs on UIC. FIXME: check this is correct */ | 185 | * and edge irqs on UIC. FIXME: check this is correct */ |
196 | set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq); | 186 | irq_set_chip_and_handler(virq, &uic_irq_chip, handle_level_irq); |
197 | 187 | ||
198 | /* Set default irq type */ | 188 | /* Set default irq type */ |
199 | set_irq_type(virq, IRQ_TYPE_NONE); | 189 | irq_set_irq_type(virq, IRQ_TYPE_NONE); |
200 | 190 | ||
201 | return 0; | 191 | return 0; |
202 | } | 192 | } |
@@ -220,16 +210,18 @@ static struct irq_host_ops uic_host_ops = { | |||
220 | 210 | ||
221 | void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) | 211 | void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) |
222 | { | 212 | { |
223 | struct uic *uic = get_irq_data(virq); | 213 | struct irq_chip *chip = irq_desc_get_chip(desc); |
214 | struct irq_data *idata = irq_desc_get_irq_data(desc); | ||
215 | struct uic *uic = irq_get_handler_data(virq); | ||
224 | u32 msr; | 216 | u32 msr; |
225 | int src; | 217 | int src; |
226 | int subvirq; | 218 | int subvirq; |
227 | 219 | ||
228 | raw_spin_lock(&desc->lock); | 220 | raw_spin_lock(&desc->lock); |
229 | if (desc->status & IRQ_LEVEL) | 221 | if (irqd_is_level_type(idata)) |
230 | desc->chip->mask(virq); | 222 | chip->irq_mask(idata); |
231 | else | 223 | else |
232 | desc->chip->mask_ack(virq); | 224 | chip->irq_mask_ack(idata); |
233 | raw_spin_unlock(&desc->lock); | 225 | raw_spin_unlock(&desc->lock); |
234 | 226 | ||
235 | msr = mfdcr(uic->dcrbase + UIC_MSR); | 227 | msr = mfdcr(uic->dcrbase + UIC_MSR); |
@@ -243,10 +235,10 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) | |||
243 | 235 | ||
244 | uic_irq_ret: | 236 | uic_irq_ret: |
245 | raw_spin_lock(&desc->lock); | 237 | raw_spin_lock(&desc->lock); |
246 | if (desc->status & IRQ_LEVEL) | 238 | if (irqd_is_level_type(idata)) |
247 | desc->chip->ack(virq); | 239 | chip->irq_ack(idata); |
248 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) | 240 | if (!irqd_irq_disabled(idata) && chip->irq_unmask) |
249 | desc->chip->unmask(virq); | 241 | chip->irq_unmask(idata); |
250 | raw_spin_unlock(&desc->lock); | 242 | raw_spin_unlock(&desc->lock); |
251 | } | 243 | } |
252 | 244 | ||
@@ -335,8 +327,8 @@ void __init uic_init_tree(void) | |||
335 | 327 | ||
336 | cascade_virq = irq_of_parse_and_map(np, 0); | 328 | cascade_virq = irq_of_parse_and_map(np, 0); |
337 | 329 | ||
338 | set_irq_data(cascade_virq, uic); | 330 | irq_set_handler_data(cascade_virq, uic); |
339 | set_irq_chained_handler(cascade_virq, uic_irq_cascade); | 331 | irq_set_chained_handler(cascade_virq, uic_irq_cascade); |
340 | 332 | ||
341 | /* FIXME: setup critical cascade?? */ | 333 | /* FIXME: setup critical cascade?? */ |
342 | } | 334 | } |