diff options
author | Geoff Levand <geoffrey.levand@am.sony.com> | 2007-04-30 17:01:01 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-05-02 06:04:31 -0400 |
commit | dc4f60c25ae71e8278dcf909486e4aa34de7eecb (patch) | |
tree | b6715d447588d05038cc1f655874df513d312f86 | |
parent | 12828856630e616742e092c8ccbda6ebc56a9375 (diff) |
[POWERPC] PS3: Interrupt routine fixups.
Fixups for the ps3 interrupt routines to support all HV device
in a generic way.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/platforms/ps3/interrupt.c | 234 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/smp.c | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/spu.c | 16 | ||||
-rw-r--r-- | drivers/ps3/vuart.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/ehci-ps3.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ohci-ps3.c | 4 | ||||
-rw-r--r-- | drivers/video/ps3fb.c | 12 | ||||
-rw-r--r-- | include/asm-powerpc/ps3.h | 33 |
8 files changed, 211 insertions, 106 deletions
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 631c30095617..9da82c266ba9 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c | |||
@@ -89,7 +89,18 @@ struct ps3_private { | |||
89 | 89 | ||
90 | static DEFINE_PER_CPU(struct ps3_private, ps3_private); | 90 | static DEFINE_PER_CPU(struct ps3_private, ps3_private); |
91 | 91 | ||
92 | int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, | 92 | /** |
93 | * ps3_virq_setup - virq related setup. | ||
94 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be | ||
95 | * serviced on. | ||
96 | * @outlet: The HV outlet from the various create outlet routines. | ||
97 | * @virq: The assigned Linux virq. | ||
98 | * | ||
99 | * Calls irq_create_mapping() to get a virq and sets the chip data to | ||
100 | * ps3_private data. | ||
101 | */ | ||
102 | |||
103 | int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, | ||
93 | unsigned int *virq) | 104 | unsigned int *virq) |
94 | { | 105 | { |
95 | int result; | 106 | int result; |
@@ -111,17 +122,6 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
111 | goto fail_create; | 122 | goto fail_create; |
112 | } | 123 | } |
113 | 124 | ||
114 | /* Binds outlet to cpu + virq. */ | ||
115 | |||
116 | result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); | ||
117 | |||
118 | if (result) { | ||
119 | pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", | ||
120 | __func__, __LINE__, ps3_result(result)); | ||
121 | result = -EPERM; | ||
122 | goto fail_connect; | ||
123 | } | ||
124 | |||
125 | pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, | 125 | pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, |
126 | outlet, cpu, *virq); | 126 | outlet, cpu, *virq); |
127 | 127 | ||
@@ -136,94 +136,118 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, | |||
136 | return result; | 136 | return result; |
137 | 137 | ||
138 | fail_set: | 138 | fail_set: |
139 | lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq); | ||
140 | fail_connect: | ||
141 | irq_dispose_mapping(*virq); | 139 | irq_dispose_mapping(*virq); |
142 | fail_create: | 140 | fail_create: |
143 | return result; | 141 | return result; |
144 | } | 142 | } |
145 | EXPORT_SYMBOL_GPL(ps3_alloc_irq); | ||
146 | 143 | ||
147 | int ps3_free_irq(unsigned int virq) | 144 | /** |
145 | * ps3_virq_destroy - virq related teardown. | ||
146 | * @virq: The assigned Linux virq. | ||
147 | * | ||
148 | * Clears chip data and calls irq_dispose_mapping() for the virq. | ||
149 | */ | ||
150 | |||
151 | int ps3_virq_destroy(unsigned int virq) | ||
148 | { | 152 | { |
149 | int result; | ||
150 | const struct ps3_private *pd = get_irq_chip_data(virq); | 153 | const struct ps3_private *pd = get_irq_chip_data(virq); |
151 | 154 | ||
152 | pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, | 155 | pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, |
153 | pd->node, pd->cpu, virq); | 156 | pd->node, pd->cpu, virq); |
154 | 157 | ||
155 | result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); | ||
156 | |||
157 | if (result) | ||
158 | pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", | ||
159 | __func__, __LINE__, ps3_result(result)); | ||
160 | |||
161 | set_irq_chip_data(virq, NULL); | 158 | set_irq_chip_data(virq, NULL); |
162 | irq_dispose_mapping(virq); | 159 | irq_dispose_mapping(virq); |
163 | return result; | 160 | |
161 | pr_debug("%s:%d <-\n", __func__, __LINE__); | ||
162 | return 0; | ||
164 | } | 163 | } |
165 | EXPORT_SYMBOL_GPL(ps3_free_irq); | ||
166 | 164 | ||
167 | /** | 165 | /** |
168 | * ps3_alloc_io_irq - Assign a virq to a system bus device. | 166 | * ps3_irq_plug_setup - Generic outlet and virq related setup. |
169 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be | 167 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be |
170 | * serviced on. | 168 | * serviced on. |
171 | * @interrupt_id: The device interrupt id read from the system repository. | 169 | * @outlet: The HV outlet from the various create outlet routines. |
172 | * @virq: The assigned Linux virq. | 170 | * @virq: The assigned Linux virq. |
173 | * | 171 | * |
174 | * An io irq represents a non-virtualized device interrupt. interrupt_id | 172 | * Sets up virq and connects the irq plug. |
175 | * coresponds to the interrupt number of the interrupt controller. | ||
176 | */ | 173 | */ |
177 | 174 | ||
178 | int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, | 175 | int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, |
179 | unsigned int *virq) | 176 | unsigned int *virq) |
180 | { | 177 | { |
181 | int result; | 178 | int result; |
182 | unsigned long outlet; | 179 | struct ps3_private *pd; |
183 | 180 | ||
184 | result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); | 181 | result = ps3_virq_setup(cpu, outlet, virq); |
185 | 182 | ||
186 | if (result) { | 183 | if (result) { |
187 | pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", | 184 | pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); |
188 | __func__, __LINE__, ps3_result(result)); | 185 | goto fail_setup; |
189 | return result; | ||
190 | } | 186 | } |
191 | 187 | ||
192 | result = ps3_alloc_irq(cpu, outlet, virq); | 188 | pd = get_irq_chip_data(*virq); |
193 | BUG_ON(result); | 189 | |
190 | /* Binds outlet to cpu + virq. */ | ||
191 | |||
192 | result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); | ||
194 | 193 | ||
194 | if (result) { | ||
195 | pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", | ||
196 | __func__, __LINE__, ps3_result(result)); | ||
197 | result = -EPERM; | ||
198 | goto fail_connect; | ||
199 | } | ||
200 | |||
201 | return result; | ||
202 | |||
203 | fail_connect: | ||
204 | ps3_virq_destroy(*virq); | ||
205 | fail_setup: | ||
195 | return result; | 206 | return result; |
196 | } | 207 | } |
197 | EXPORT_SYMBOL_GPL(ps3_alloc_io_irq); | 208 | EXPORT_SYMBOL_GPL(ps3_irq_plug_setup); |
209 | |||
210 | /** | ||
211 | * ps3_irq_plug_destroy - Generic outlet and virq related teardown. | ||
212 | * @virq: The assigned Linux virq. | ||
213 | * | ||
214 | * Disconnects the irq plug and tears down virq. | ||
215 | * Do not call for system bus event interrupts setup with | ||
216 | * ps3_sb_event_receive_port_setup(). | ||
217 | */ | ||
198 | 218 | ||
199 | int ps3_free_io_irq(unsigned int virq) | 219 | int ps3_irq_plug_destroy(unsigned int virq) |
200 | { | 220 | { |
201 | int result; | 221 | int result; |
222 | const struct ps3_private *pd = get_irq_chip_data(virq); | ||
202 | 223 | ||
203 | result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); | 224 | pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, |
225 | pd->node, pd->cpu, virq); | ||
226 | |||
227 | result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); | ||
204 | 228 | ||
205 | if (result) | 229 | if (result) |
206 | pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", | 230 | pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", |
207 | __func__, __LINE__, ps3_result(result)); | 231 | __func__, __LINE__, ps3_result(result)); |
208 | 232 | ||
209 | ps3_free_irq(virq); | 233 | ps3_virq_destroy(virq); |
210 | 234 | ||
211 | return result; | 235 | return result; |
212 | } | 236 | } |
213 | EXPORT_SYMBOL_GPL(ps3_free_io_irq); | 237 | EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy); |
214 | 238 | ||
215 | /** | 239 | /** |
216 | * ps3_alloc_event_irq - Allocate a virq for use with a system event. | 240 | * ps3_event_receive_port_setup - Setup an event receive port. |
217 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be | 241 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be |
218 | * serviced on. | 242 | * serviced on. |
219 | * @virq: The assigned Linux virq. | 243 | * @virq: The assigned Linux virq. |
220 | * | 244 | * |
221 | * The virq can be used with lv1_connect_interrupt_event_receive_port() to | 245 | * The virq can be used with lv1_connect_interrupt_event_receive_port() to |
222 | * arrange to receive events, or with ps3_send_event_locally() to signal | 246 | * arrange to receive interrupts from system-bus devices, or with |
223 | * events. | 247 | * ps3_send_event_locally() to signal events. |
224 | */ | 248 | */ |
225 | 249 | ||
226 | int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq) | 250 | int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) |
227 | { | 251 | { |
228 | int result; | 252 | int result; |
229 | unsigned long outlet; | 253 | unsigned long outlet; |
@@ -237,17 +261,27 @@ int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq) | |||
237 | return result; | 261 | return result; |
238 | } | 262 | } |
239 | 263 | ||
240 | result = ps3_alloc_irq(cpu, outlet, virq); | 264 | result = ps3_irq_plug_setup(cpu, outlet, virq); |
241 | BUG_ON(result); | 265 | BUG_ON(result); |
242 | 266 | ||
243 | return result; | 267 | return result; |
244 | } | 268 | } |
269 | EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup); | ||
270 | |||
271 | /** | ||
272 | * ps3_event_receive_port_destroy - Destroy an event receive port. | ||
273 | * @virq: The assigned Linux virq. | ||
274 | * | ||
275 | * Since ps3_event_receive_port_destroy destroys the receive port outlet, | ||
276 | * SB devices need to call disconnect_interrupt_event_receive_port() before | ||
277 | * this. | ||
278 | */ | ||
245 | 279 | ||
246 | int ps3_free_event_irq(unsigned int virq) | 280 | int ps3_event_receive_port_destroy(unsigned int virq) |
247 | { | 281 | { |
248 | int result; | 282 | int result; |
249 | 283 | ||
250 | pr_debug(" -> %s:%d\n", __func__, __LINE__); | 284 | pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); |
251 | 285 | ||
252 | result = lv1_destruct_event_receive_port(virq_to_hw(virq)); | 286 | result = lv1_destruct_event_receive_port(virq_to_hw(virq)); |
253 | 287 | ||
@@ -255,11 +289,17 @@ int ps3_free_event_irq(unsigned int virq) | |||
255 | pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", | 289 | pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", |
256 | __func__, __LINE__, ps3_result(result)); | 290 | __func__, __LINE__, ps3_result(result)); |
257 | 291 | ||
258 | ps3_free_irq(virq); | 292 | /* lv1_destruct_event_receive_port() destroys the IRQ plug, |
293 | * so don't call ps3_irq_plug_destroy() here. | ||
294 | */ | ||
295 | |||
296 | result = ps3_virq_destroy(virq); | ||
297 | BUG_ON(result); | ||
259 | 298 | ||
260 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 299 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
261 | return result; | 300 | return result; |
262 | } | 301 | } |
302 | EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy); | ||
263 | 303 | ||
264 | int ps3_send_event_locally(unsigned int virq) | 304 | int ps3_send_event_locally(unsigned int virq) |
265 | { | 305 | { |
@@ -267,7 +307,7 @@ int ps3_send_event_locally(unsigned int virq) | |||
267 | } | 307 | } |
268 | 308 | ||
269 | /** | 309 | /** |
270 | * ps3_connect_event_irq - Assign a virq to a system bus device. | 310 | * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. |
271 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be | 311 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be |
272 | * serviced on. | 312 | * serviced on. |
273 | * @did: The HV device identifier read from the system repository. | 313 | * @did: The HV device identifier read from the system repository. |
@@ -278,13 +318,15 @@ int ps3_send_event_locally(unsigned int virq) | |||
278 | * coresponds to the software interrupt number. | 318 | * coresponds to the software interrupt number. |
279 | */ | 319 | */ |
280 | 320 | ||
281 | int ps3_connect_event_irq(enum ps3_cpu_binding cpu, | 321 | int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, |
282 | const struct ps3_device_id *did, unsigned int interrupt_id, | 322 | const struct ps3_device_id *did, unsigned int interrupt_id, |
283 | unsigned int *virq) | 323 | unsigned int *virq) |
284 | { | 324 | { |
325 | /* this should go in system-bus.c */ | ||
326 | |||
285 | int result; | 327 | int result; |
286 | 328 | ||
287 | result = ps3_alloc_event_irq(cpu, virq); | 329 | result = ps3_event_receive_port_setup(cpu, virq); |
288 | 330 | ||
289 | if (result) | 331 | if (result) |
290 | return result; | 332 | return result; |
@@ -296,7 +338,7 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu, | |||
296 | pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" | 338 | pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" |
297 | " failed: %s\n", __func__, __LINE__, | 339 | " failed: %s\n", __func__, __LINE__, |
298 | ps3_result(result)); | 340 | ps3_result(result)); |
299 | ps3_free_event_irq(*virq); | 341 | ps3_event_receive_port_destroy(*virq); |
300 | *virq = NO_IRQ; | 342 | *virq = NO_IRQ; |
301 | return result; | 343 | return result; |
302 | } | 344 | } |
@@ -306,10 +348,13 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu, | |||
306 | 348 | ||
307 | return 0; | 349 | return 0; |
308 | } | 350 | } |
351 | EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); | ||
309 | 352 | ||
310 | int ps3_disconnect_event_irq(const struct ps3_device_id *did, | 353 | int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, |
311 | unsigned int interrupt_id, unsigned int virq) | 354 | unsigned int interrupt_id, unsigned int virq) |
312 | { | 355 | { |
356 | /* this should go in system-bus.c */ | ||
357 | |||
313 | int result; | 358 | int result; |
314 | 359 | ||
315 | pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, | 360 | pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, |
@@ -323,14 +368,65 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did, | |||
323 | " failed: %s\n", __func__, __LINE__, | 368 | " failed: %s\n", __func__, __LINE__, |
324 | ps3_result(result)); | 369 | ps3_result(result)); |
325 | 370 | ||
326 | ps3_free_event_irq(virq); | 371 | result = ps3_event_receive_port_destroy(virq); |
372 | BUG_ON(result); | ||
327 | 373 | ||
328 | pr_debug(" <- %s:%d\n", __func__, __LINE__); | 374 | pr_debug(" <- %s:%d\n", __func__, __LINE__); |
329 | return result; | 375 | return result; |
330 | } | 376 | } |
377 | EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); | ||
331 | 378 | ||
332 | /** | 379 | /** |
333 | * ps3_alloc_vuart_irq - Configure the system virtual uart virq. | 380 | * ps3_io_irq_setup - Setup a system bus io irq. |
381 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be | ||
382 | * serviced on. | ||
383 | * @interrupt_id: The device interrupt id read from the system repository. | ||
384 | * @virq: The assigned Linux virq. | ||
385 | * | ||
386 | * An io irq represents a non-virtualized device interrupt. interrupt_id | ||
387 | * coresponds to the interrupt number of the interrupt controller. | ||
388 | */ | ||
389 | |||
390 | int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, | ||
391 | unsigned int *virq) | ||
392 | { | ||
393 | int result; | ||
394 | unsigned long outlet; | ||
395 | |||
396 | result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); | ||
397 | |||
398 | if (result) { | ||
399 | pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", | ||
400 | __func__, __LINE__, ps3_result(result)); | ||
401 | return result; | ||
402 | } | ||
403 | |||
404 | result = ps3_irq_plug_setup(cpu, outlet, virq); | ||
405 | BUG_ON(result); | ||
406 | |||
407 | return result; | ||
408 | } | ||
409 | EXPORT_SYMBOL_GPL(ps3_io_irq_setup); | ||
410 | |||
411 | int ps3_io_irq_destroy(unsigned int virq) | ||
412 | { | ||
413 | int result; | ||
414 | |||
415 | result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); | ||
416 | |||
417 | if (result) | ||
418 | pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", | ||
419 | __func__, __LINE__, ps3_result(result)); | ||
420 | |||
421 | result = ps3_irq_plug_destroy(virq); | ||
422 | BUG_ON(result); | ||
423 | |||
424 | return result; | ||
425 | } | ||
426 | EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); | ||
427 | |||
428 | /** | ||
429 | * ps3_vuart_irq_setup - Setup the system virtual uart virq. | ||
334 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be | 430 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be |
335 | * serviced on. | 431 | * serviced on. |
336 | * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap. | 432 | * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap. |
@@ -340,7 +436,7 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did, | |||
340 | * freeing the interrupt will return a wrong state error. | 436 | * freeing the interrupt will return a wrong state error. |
341 | */ | 437 | */ |
342 | 438 | ||
343 | int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, | 439 | int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, |
344 | unsigned int *virq) | 440 | unsigned int *virq) |
345 | { | 441 | { |
346 | int result; | 442 | int result; |
@@ -359,13 +455,13 @@ int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, | |||
359 | return result; | 455 | return result; |
360 | } | 456 | } |
361 | 457 | ||
362 | result = ps3_alloc_irq(cpu, outlet, virq); | 458 | result = ps3_irq_plug_setup(cpu, outlet, virq); |
363 | BUG_ON(result); | 459 | BUG_ON(result); |
364 | 460 | ||
365 | return result; | 461 | return result; |
366 | } | 462 | } |
367 | 463 | ||
368 | int ps3_free_vuart_irq(unsigned int virq) | 464 | int ps3_vuart_irq_destroy(unsigned int virq) |
369 | { | 465 | { |
370 | int result; | 466 | int result; |
371 | 467 | ||
@@ -377,13 +473,14 @@ int ps3_free_vuart_irq(unsigned int virq) | |||
377 | return result; | 473 | return result; |
378 | } | 474 | } |
379 | 475 | ||
380 | ps3_free_irq(virq); | 476 | result = ps3_irq_plug_destroy(virq); |
477 | BUG_ON(result); | ||
381 | 478 | ||
382 | return result; | 479 | return result; |
383 | } | 480 | } |
384 | 481 | ||
385 | /** | 482 | /** |
386 | * ps3_alloc_spe_irq - Configure an spe virq. | 483 | * ps3_spe_irq_setup - Setup an spe virq. |
387 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be | 484 | * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be |
388 | * serviced on. | 485 | * serviced on. |
389 | * @spe_id: The spe_id returned from lv1_construct_logical_spe(). | 486 | * @spe_id: The spe_id returned from lv1_construct_logical_spe(). |
@@ -392,7 +489,7 @@ int ps3_free_vuart_irq(unsigned int virq) | |||
392 | * | 489 | * |
393 | */ | 490 | */ |
394 | 491 | ||
395 | int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, | 492 | int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, |
396 | unsigned int class, unsigned int *virq) | 493 | unsigned int class, unsigned int *virq) |
397 | { | 494 | { |
398 | int result; | 495 | int result; |
@@ -408,15 +505,16 @@ int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, | |||
408 | return result; | 505 | return result; |
409 | } | 506 | } |
410 | 507 | ||
411 | result = ps3_alloc_irq(cpu, outlet, virq); | 508 | result = ps3_irq_plug_setup(cpu, outlet, virq); |
412 | BUG_ON(result); | 509 | BUG_ON(result); |
413 | 510 | ||
414 | return result; | 511 | return result; |
415 | } | 512 | } |
416 | 513 | ||
417 | int ps3_free_spe_irq(unsigned int virq) | 514 | int ps3_spe_irq_destroy(unsigned int virq) |
418 | { | 515 | { |
419 | ps3_free_irq(virq); | 516 | int result = ps3_irq_plug_destroy(virq); |
517 | BUG_ON(result); | ||
420 | return 0; | 518 | return 0; |
421 | } | 519 | } |
422 | 520 | ||
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index 6fb887961a6d..8729348c0608 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c | |||
@@ -110,7 +110,7 @@ static void __init ps3_smp_setup_cpu(int cpu) | |||
110 | BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); | 110 | BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); |
111 | 111 | ||
112 | for (i = 0; i < MSG_COUNT; i++) { | 112 | for (i = 0; i < MSG_COUNT; i++) { |
113 | result = ps3_alloc_event_irq(cpu, &virqs[i]); | 113 | result = ps3_event_receive_port_setup(cpu, &virqs[i]); |
114 | 114 | ||
115 | if (result) | 115 | if (result) |
116 | continue; | 116 | continue; |
@@ -134,11 +134,13 @@ void ps3_smp_cleanup_cpu(int cpu) | |||
134 | int i; | 134 | int i; |
135 | 135 | ||
136 | DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); | 136 | DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); |
137 | |||
137 | for (i = 0; i < MSG_COUNT; i++) { | 138 | for (i = 0; i < MSG_COUNT; i++) { |
138 | ps3_free_event_irq(virqs[i]); | ||
139 | free_irq(virqs[i], (void*)(long)i); | 139 | free_irq(virqs[i], (void*)(long)i); |
140 | ps3_event_receive_port_destroy(virqs[i]); | ||
140 | virqs[i] = NO_IRQ; | 141 | virqs[i] = NO_IRQ; |
141 | } | 142 | } |
143 | |||
142 | DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu); | 144 | DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu); |
143 | } | 145 | } |
144 | 146 | ||
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index af8efe3c459a..651437cb2c18 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c | |||
@@ -230,19 +230,19 @@ static int __init setup_interrupts(struct spu *spu) | |||
230 | { | 230 | { |
231 | int result; | 231 | int result; |
232 | 232 | ||
233 | result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, | 233 | result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, |
234 | 0, &spu->irqs[0]); | 234 | 0, &spu->irqs[0]); |
235 | 235 | ||
236 | if (result) | 236 | if (result) |
237 | goto fail_alloc_0; | 237 | goto fail_alloc_0; |
238 | 238 | ||
239 | result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, | 239 | result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, |
240 | 1, &spu->irqs[1]); | 240 | 1, &spu->irqs[1]); |
241 | 241 | ||
242 | if (result) | 242 | if (result) |
243 | goto fail_alloc_1; | 243 | goto fail_alloc_1; |
244 | 244 | ||
245 | result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, | 245 | result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, |
246 | 2, &spu->irqs[2]); | 246 | 2, &spu->irqs[2]); |
247 | 247 | ||
248 | if (result) | 248 | if (result) |
@@ -251,9 +251,9 @@ static int __init setup_interrupts(struct spu *spu) | |||
251 | return result; | 251 | return result; |
252 | 252 | ||
253 | fail_alloc_2: | 253 | fail_alloc_2: |
254 | ps3_free_spe_irq(spu->irqs[1]); | 254 | ps3_spe_irq_destroy(spu->irqs[1]); |
255 | fail_alloc_1: | 255 | fail_alloc_1: |
256 | ps3_free_spe_irq(spu->irqs[0]); | 256 | ps3_spe_irq_destroy(spu->irqs[0]); |
257 | fail_alloc_0: | 257 | fail_alloc_0: |
258 | spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; | 258 | spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; |
259 | return result; | 259 | return result; |
@@ -301,9 +301,9 @@ static int ps3_destroy_spu(struct spu *spu) | |||
301 | result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); | 301 | result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); |
302 | BUG_ON(result); | 302 | BUG_ON(result); |
303 | 303 | ||
304 | ps3_free_spe_irq(spu->irqs[2]); | 304 | ps3_spe_irq_destroy(spu->irqs[2]); |
305 | ps3_free_spe_irq(spu->irqs[1]); | 305 | ps3_spe_irq_destroy(spu->irqs[1]); |
306 | ps3_free_spe_irq(spu->irqs[0]); | 306 | ps3_spe_irq_destroy(spu->irqs[0]); |
307 | 307 | ||
308 | spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; | 308 | spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; |
309 | 309 | ||
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c index 7d7cab1d91b4..ec2d36a1bc67 100644 --- a/drivers/ps3/vuart.c +++ b/drivers/ps3/vuart.c | |||
@@ -886,12 +886,12 @@ static int ps3_vuart_probe(struct device *_dev) | |||
886 | 886 | ||
887 | if (++vuart_bus_priv.use_count == 1) { | 887 | if (++vuart_bus_priv.use_count == 1) { |
888 | 888 | ||
889 | result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY, | 889 | result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY, |
890 | (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq); | 890 | (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq); |
891 | 891 | ||
892 | if (result) { | 892 | if (result) { |
893 | dev_dbg(&dev->core, | 893 | dev_dbg(&dev->core, |
894 | "%s:%d: ps3_alloc_vuart_irq failed (%d)\n", | 894 | "%s:%d: ps3_vuart_irq_setup failed (%d)\n", |
895 | __func__, __LINE__, result); | 895 | __func__, __LINE__, result); |
896 | result = -EPERM; | 896 | result = -EPERM; |
897 | goto fail_alloc_irq; | 897 | goto fail_alloc_irq; |
@@ -937,7 +937,7 @@ static int ps3_vuart_probe(struct device *_dev) | |||
937 | fail_probe: | 937 | fail_probe: |
938 | ps3_vuart_set_interrupt_mask(dev, 0); | 938 | ps3_vuart_set_interrupt_mask(dev, 0); |
939 | fail_request_irq: | 939 | fail_request_irq: |
940 | ps3_free_vuart_irq(vuart_bus_priv.virq); | 940 | ps3_vuart_irq_destroy(vuart_bus_priv.virq); |
941 | vuart_bus_priv.virq = NO_IRQ; | 941 | vuart_bus_priv.virq = NO_IRQ; |
942 | fail_alloc_irq: | 942 | fail_alloc_irq: |
943 | --vuart_bus_priv.use_count; | 943 | --vuart_bus_priv.use_count; |
@@ -975,7 +975,7 @@ static int ps3_vuart_remove(struct device *_dev) | |||
975 | if (--vuart_bus_priv.use_count == 0) { | 975 | if (--vuart_bus_priv.use_count == 0) { |
976 | BUG(); | 976 | BUG(); |
977 | free_irq(vuart_bus_priv.virq, &vuart_bus_priv); | 977 | free_irq(vuart_bus_priv.virq, &vuart_bus_priv); |
978 | ps3_free_vuart_irq(vuart_bus_priv.virq); | 978 | ps3_vuart_irq_destroy(vuart_bus_priv.virq); |
979 | vuart_bus_priv.virq = NO_IRQ; | 979 | vuart_bus_priv.virq = NO_IRQ; |
980 | } | 980 | } |
981 | 981 | ||
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 4d781a2a9807..29dcd27b55de 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -104,7 +104,7 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) | |||
104 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | 104 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, |
105 | __LINE__, dev->m_region->lpar_addr); | 105 | __LINE__, dev->m_region->lpar_addr); |
106 | 106 | ||
107 | result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); | 107 | result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); |
108 | 108 | ||
109 | if (result) { | 109 | if (result) { |
110 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | 110 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", |
@@ -162,7 +162,7 @@ fail_add_hcd: | |||
162 | fail_ioremap: | 162 | fail_ioremap: |
163 | usb_put_hcd(hcd); | 163 | usb_put_hcd(hcd); |
164 | fail_create_hcd: | 164 | fail_create_hcd: |
165 | ps3_free_io_irq(virq); | 165 | ps3_io_irq_destroy(virq); |
166 | fail_irq: | 166 | fail_irq: |
167 | ps3_free_mmio_region(dev->m_region); | 167 | ps3_free_mmio_region(dev->m_region); |
168 | fail_mmio: | 168 | fail_mmio: |
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index 62283a3926de..93a6eb0de2d1 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c | |||
@@ -107,7 +107,7 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) | |||
107 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | 107 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, |
108 | __LINE__, dev->m_region->lpar_addr); | 108 | __LINE__, dev->m_region->lpar_addr); |
109 | 109 | ||
110 | result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); | 110 | result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); |
111 | 111 | ||
112 | if (result) { | 112 | if (result) { |
113 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | 113 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", |
@@ -165,7 +165,7 @@ fail_add_hcd: | |||
165 | fail_ioremap: | 165 | fail_ioremap: |
166 | usb_put_hcd(hcd); | 166 | usb_put_hcd(hcd); |
167 | fail_create_hcd: | 167 | fail_create_hcd: |
168 | ps3_free_io_irq(virq); | 168 | ps3_io_irq_destroy(virq); |
169 | fail_irq: | 169 | fail_irq: |
170 | ps3_free_mmio_region(dev->m_region); | 170 | ps3_free_mmio_region(dev->m_region); |
171 | fail_mmio: | 171 | fail_mmio: |
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 81e43cda7d8b..a9ca4986645c 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c | |||
@@ -885,8 +885,8 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev) | |||
885 | } | 885 | } |
886 | 886 | ||
887 | ps3fb.dev = dev; | 887 | ps3fb.dev = dev; |
888 | error = ps3_alloc_irq(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, | 888 | error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, |
889 | &ps3fb.irq_no); | 889 | &ps3fb.irq_no); |
890 | if (error) { | 890 | if (error) { |
891 | printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __FUNCTION__, | 891 | printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __FUNCTION__, |
892 | error); | 892 | error); |
@@ -898,7 +898,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev) | |||
898 | if (error) { | 898 | if (error) { |
899 | printk(KERN_ERR "%s: request_irq failed %d\n", __FUNCTION__, | 899 | printk(KERN_ERR "%s: request_irq failed %d\n", __FUNCTION__, |
900 | error); | 900 | error); |
901 | ps3_free_irq(ps3fb.irq_no); | 901 | ps3_irq_plug_destroy(ps3fb.irq_no); |
902 | return error; | 902 | return error; |
903 | } | 903 | } |
904 | 904 | ||
@@ -1059,7 +1059,7 @@ err_framebuffer_release: | |||
1059 | framebuffer_release(info); | 1059 | framebuffer_release(info); |
1060 | err_free_irq: | 1060 | err_free_irq: |
1061 | free_irq(ps3fb.irq_no, ps3fb.dev); | 1061 | free_irq(ps3fb.irq_no, ps3fb.dev); |
1062 | ps3_free_irq(ps3fb.irq_no); | 1062 | ps3_irq_plug_destroy(ps3fb.irq_no); |
1063 | err_iounmap_dinfo: | 1063 | err_iounmap_dinfo: |
1064 | iounmap((u8 __iomem *)ps3fb.dinfo); | 1064 | iounmap((u8 __iomem *)ps3fb.dinfo); |
1065 | err_gpu_context_free: | 1065 | err_gpu_context_free: |
@@ -1075,7 +1075,7 @@ static void ps3fb_shutdown(struct platform_device *dev) | |||
1075 | ps3fb_flip_ctl(0); /* flip off */ | 1075 | ps3fb_flip_ctl(0); /* flip off */ |
1076 | ps3fb.dinfo->irq.mask = 0; | 1076 | ps3fb.dinfo->irq.mask = 0; |
1077 | free_irq(ps3fb.irq_no, ps3fb.dev); | 1077 | free_irq(ps3fb.irq_no, ps3fb.dev); |
1078 | ps3_free_irq(ps3fb.irq_no); | 1078 | ps3_irq_plug_destroy(ps3fb.irq_no); |
1079 | iounmap((u8 __iomem *)ps3fb.dinfo); | 1079 | iounmap((u8 __iomem *)ps3fb.dinfo); |
1080 | } | 1080 | } |
1081 | 1081 | ||
@@ -1085,7 +1085,7 @@ void ps3fb_cleanup(void) | |||
1085 | 1085 | ||
1086 | if (ps3fb.irq_no) { | 1086 | if (ps3fb.irq_no) { |
1087 | free_irq(ps3fb.irq_no, ps3fb.dev); | 1087 | free_irq(ps3fb.irq_no, ps3fb.dev); |
1088 | ps3_free_irq(ps3fb.irq_no); | 1088 | ps3_irq_plug_destroy(ps3fb.irq_no); |
1089 | } | 1089 | } |
1090 | iounmap((u8 __iomem *)ps3fb.dinfo); | 1090 | iounmap((u8 __iomem *)ps3fb.dinfo); |
1091 | 1091 | ||
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h index 821581a8b643..13c372df99e8 100644 --- a/include/asm-powerpc/ps3.h +++ b/include/asm-powerpc/ps3.h | |||
@@ -167,26 +167,31 @@ enum ps3_cpu_binding { | |||
167 | PS3_BINDING_CPU_1 = 1, | 167 | PS3_BINDING_CPU_1 = 1, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, | 170 | int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, |
171 | unsigned int *virq); | 171 | unsigned int *virq); |
172 | int ps3_free_io_irq(unsigned int virq); | 172 | int ps3_virq_destroy(unsigned int virq); |
173 | int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq); | 173 | int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, |
174 | int ps3_free_event_irq(unsigned int virq); | 174 | unsigned int *virq); |
175 | int ps3_irq_plug_destroy(unsigned int virq); | ||
176 | int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq); | ||
177 | int ps3_event_receive_port_destroy(unsigned int virq); | ||
175 | int ps3_send_event_locally(unsigned int virq); | 178 | int ps3_send_event_locally(unsigned int virq); |
176 | int ps3_connect_event_irq(enum ps3_cpu_binding cpu, | 179 | |
177 | const struct ps3_device_id *did, unsigned int interrupt_id, | 180 | int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, |
178 | unsigned int *virq); | 181 | unsigned int *virq); |
179 | int ps3_disconnect_event_irq(const struct ps3_device_id *did, | 182 | int ps3_io_irq_destroy(unsigned int virq); |
180 | unsigned int interrupt_id, unsigned int virq); | 183 | int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, |
181 | int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, | ||
182 | unsigned int *virq); | 184 | unsigned int *virq); |
183 | int ps3_free_vuart_irq(unsigned int virq); | 185 | int ps3_vuart_irq_destroy(unsigned int virq); |
184 | int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, | 186 | int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, |
185 | unsigned int class, unsigned int *virq); | 187 | unsigned int class, unsigned int *virq); |
186 | int ps3_free_spe_irq(unsigned int virq); | 188 | int ps3_spe_irq_destroy(unsigned int virq); |
187 | int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, | 189 | |
190 | int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, | ||
191 | const struct ps3_device_id *did, unsigned int interrupt_id, | ||
188 | unsigned int *virq); | 192 | unsigned int *virq); |
189 | int ps3_free_irq(unsigned int virq); | 193 | int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, |
194 | unsigned int interrupt_id, unsigned int virq); | ||
190 | 195 | ||
191 | /* lv1 result codes */ | 196 | /* lv1 result codes */ |
192 | 197 | ||