aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Levand <geoffrey.levand@am.sony.com>2007-04-30 17:01:01 -0400
committerPaul Mackerras <paulus@samba.org>2007-05-02 06:04:31 -0400
commitdc4f60c25ae71e8278dcf909486e4aa34de7eecb (patch)
treeb6715d447588d05038cc1f655874df513d312f86
parent12828856630e616742e092c8ccbda6ebc56a9375 (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.c234
-rw-r--r--arch/powerpc/platforms/ps3/smp.c6
-rw-r--r--arch/powerpc/platforms/ps3/spu.c16
-rw-r--r--drivers/ps3/vuart.c8
-rw-r--r--drivers/usb/host/ehci-ps3.c4
-rw-r--r--drivers/usb/host/ohci-ps3.c4
-rw-r--r--drivers/video/ps3fb.c12
-rw-r--r--include/asm-powerpc/ps3.h33
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
90static DEFINE_PER_CPU(struct ps3_private, ps3_private); 90static DEFINE_PER_CPU(struct ps3_private, ps3_private);
91 91
92int 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
103int 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
138fail_set: 138fail_set:
139 lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq);
140fail_connect:
141 irq_dispose_mapping(*virq); 139 irq_dispose_mapping(*virq);
142fail_create: 140fail_create:
143 return result; 141 return result;
144} 142}
145EXPORT_SYMBOL_GPL(ps3_alloc_irq);
146 143
147int 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
151int 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}
165EXPORT_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
178int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, 175int 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
203fail_connect:
204 ps3_virq_destroy(*virq);
205fail_setup:
195 return result; 206 return result;
196} 207}
197EXPORT_SYMBOL_GPL(ps3_alloc_io_irq); 208EXPORT_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
199int ps3_free_io_irq(unsigned int virq) 219int 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}
213EXPORT_SYMBOL_GPL(ps3_free_io_irq); 237EXPORT_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
226int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq) 250int 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}
269EXPORT_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
246int ps3_free_event_irq(unsigned int virq) 280int 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}
302EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
263 303
264int ps3_send_event_locally(unsigned int virq) 304int 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
281int ps3_connect_event_irq(enum ps3_cpu_binding cpu, 321int 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}
351EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
309 352
310int ps3_disconnect_event_irq(const struct ps3_device_id *did, 353int 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}
377EXPORT_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
390int 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}
409EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
410
411int 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}
426EXPORT_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
343int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, 439int 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
368int ps3_free_vuart_irq(unsigned int virq) 464int 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
395int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, 492int 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
417int ps3_free_spe_irq(unsigned int virq) 514int 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
253fail_alloc_2: 253fail_alloc_2:
254 ps3_free_spe_irq(spu->irqs[1]); 254 ps3_spe_irq_destroy(spu->irqs[1]);
255fail_alloc_1: 255fail_alloc_1:
256 ps3_free_spe_irq(spu->irqs[0]); 256 ps3_spe_irq_destroy(spu->irqs[0]);
257fail_alloc_0: 257fail_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)
937fail_probe: 937fail_probe:
938 ps3_vuart_set_interrupt_mask(dev, 0); 938 ps3_vuart_set_interrupt_mask(dev, 0);
939fail_request_irq: 939fail_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;
942fail_alloc_irq: 942fail_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:
162fail_ioremap: 162fail_ioremap:
163 usb_put_hcd(hcd); 163 usb_put_hcd(hcd);
164fail_create_hcd: 164fail_create_hcd:
165 ps3_free_io_irq(virq); 165 ps3_io_irq_destroy(virq);
166fail_irq: 166fail_irq:
167 ps3_free_mmio_region(dev->m_region); 167 ps3_free_mmio_region(dev->m_region);
168fail_mmio: 168fail_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:
165fail_ioremap: 165fail_ioremap:
166 usb_put_hcd(hcd); 166 usb_put_hcd(hcd);
167fail_create_hcd: 167fail_create_hcd:
168 ps3_free_io_irq(virq); 168 ps3_io_irq_destroy(virq);
169fail_irq: 169fail_irq:
170 ps3_free_mmio_region(dev->m_region); 170 ps3_free_mmio_region(dev->m_region);
171fail_mmio: 171fail_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);
1060err_free_irq: 1060err_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);
1063err_iounmap_dinfo: 1063err_iounmap_dinfo:
1064 iounmap((u8 __iomem *)ps3fb.dinfo); 1064 iounmap((u8 __iomem *)ps3fb.dinfo);
1065err_gpu_context_free: 1065err_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
170int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, 170int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
171 unsigned int *virq); 171 unsigned int *virq);
172int ps3_free_io_irq(unsigned int virq); 172int ps3_virq_destroy(unsigned int virq);
173int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq); 173int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
174int ps3_free_event_irq(unsigned int virq); 174 unsigned int *virq);
175int ps3_irq_plug_destroy(unsigned int virq);
176int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq);
177int ps3_event_receive_port_destroy(unsigned int virq);
175int ps3_send_event_locally(unsigned int virq); 178int ps3_send_event_locally(unsigned int virq);
176int ps3_connect_event_irq(enum ps3_cpu_binding cpu, 179
177 const struct ps3_device_id *did, unsigned int interrupt_id, 180int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
178 unsigned int *virq); 181 unsigned int *virq);
179int ps3_disconnect_event_irq(const struct ps3_device_id *did, 182int ps3_io_irq_destroy(unsigned int virq);
180 unsigned int interrupt_id, unsigned int virq); 183int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
181int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
182 unsigned int *virq); 184 unsigned int *virq);
183int ps3_free_vuart_irq(unsigned int virq); 185int ps3_vuart_irq_destroy(unsigned int virq);
184int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, 186int 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);
186int ps3_free_spe_irq(unsigned int virq); 188int ps3_spe_irq_destroy(unsigned int virq);
187int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, 189
190int 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);
189int ps3_free_irq(unsigned int virq); 193int 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