diff options
-rw-r--r-- | arch/sparc64/kernel/irq.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index c3d068c7a412..2873835e2626 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -268,8 +268,7 @@ static int irq_choose_cpu(unsigned int virt_irq) | |||
268 | 268 | ||
269 | static void sun4u_irq_enable(unsigned int virt_irq) | 269 | static void sun4u_irq_enable(unsigned int virt_irq) |
270 | { | 270 | { |
271 | irq_desc_t *desc = irq_desc + virt_irq; | 271 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
272 | struct irq_handler_data *data = desc->handler_data; | ||
273 | 272 | ||
274 | if (likely(data)) { | 273 | if (likely(data)) { |
275 | unsigned long cpuid, imap; | 274 | unsigned long cpuid, imap; |
@@ -286,8 +285,7 @@ static void sun4u_irq_enable(unsigned int virt_irq) | |||
286 | 285 | ||
287 | static void sun4u_irq_disable(unsigned int virt_irq) | 286 | static void sun4u_irq_disable(unsigned int virt_irq) |
288 | { | 287 | { |
289 | irq_desc_t *desc = irq_desc + virt_irq; | 288 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
290 | struct irq_handler_data *data = desc->handler_data; | ||
291 | 289 | ||
292 | if (likely(data)) { | 290 | if (likely(data)) { |
293 | unsigned long imap = data->imap; | 291 | unsigned long imap = data->imap; |
@@ -300,8 +298,7 @@ static void sun4u_irq_disable(unsigned int virt_irq) | |||
300 | 298 | ||
301 | static void sun4u_irq_end(unsigned int virt_irq) | 299 | static void sun4u_irq_end(unsigned int virt_irq) |
302 | { | 300 | { |
303 | irq_desc_t *desc = irq_desc + virt_irq; | 301 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
304 | struct irq_handler_data *data = desc->handler_data; | ||
305 | 302 | ||
306 | if (likely(data)) | 303 | if (likely(data)) |
307 | upa_writel(ICLR_IDLE, data->iclr); | 304 | upa_writel(ICLR_IDLE, data->iclr); |
@@ -362,8 +359,7 @@ static void sun4v_irq_end(unsigned int virt_irq) | |||
362 | static void run_pre_handler(unsigned int virt_irq) | 359 | static void run_pre_handler(unsigned int virt_irq) |
363 | { | 360 | { |
364 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 361 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
365 | irq_desc_t *desc = irq_desc + virt_irq; | 362 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
366 | struct irq_handler_data *data = desc->handler_data; | ||
367 | 363 | ||
368 | if (likely(data->pre_handler)) { | 364 | if (likely(data->pre_handler)) { |
369 | data->pre_handler(__irq_ino(__irq(bucket)), | 365 | data->pre_handler(__irq_ino(__irq(bucket)), |
@@ -406,26 +402,27 @@ void irq_install_pre_handler(int virt_irq, | |||
406 | void (*func)(unsigned int, void *, void *), | 402 | void (*func)(unsigned int, void *, void *), |
407 | void *arg1, void *arg2) | 403 | void *arg1, void *arg2) |
408 | { | 404 | { |
409 | irq_desc_t *desc = irq_desc + virt_irq; | 405 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
410 | struct irq_handler_data *data = desc->handler_data; | 406 | struct irq_chip *chip; |
411 | 407 | ||
412 | data->pre_handler = func; | 408 | data->pre_handler = func; |
413 | data->pre_handler_arg1 = arg1; | 409 | data->pre_handler_arg1 = arg1; |
414 | data->pre_handler_arg2 = arg2; | 410 | data->pre_handler_arg2 = arg2; |
415 | 411 | ||
416 | if (desc->chip == &sun4u_irq_ack || | 412 | chip = get_irq_chip(virt_irq); |
417 | desc->chip == &sun4v_irq_ack) | 413 | if (chip == &sun4u_irq_ack || |
414 | chip == &sun4v_irq_ack) | ||
418 | return; | 415 | return; |
419 | 416 | ||
420 | desc->chip = (desc->chip == &sun4u_irq ? | 417 | chip = (chip == &sun4u_irq ? |
421 | &sun4u_irq_ack : &sun4v_irq_ack); | 418 | &sun4u_irq_ack : &sun4v_irq_ack); |
419 | set_irq_chip(virt_irq, chip); | ||
422 | } | 420 | } |
423 | 421 | ||
424 | unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) | 422 | unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) |
425 | { | 423 | { |
426 | struct ino_bucket *bucket; | 424 | struct ino_bucket *bucket; |
427 | struct irq_handler_data *data; | 425 | struct irq_handler_data *data; |
428 | irq_desc_t *desc; | ||
429 | int ino; | 426 | int ino; |
430 | 427 | ||
431 | BUG_ON(tlb_type == hypervisor); | 428 | BUG_ON(tlb_type == hypervisor); |
@@ -434,11 +431,11 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) | |||
434 | bucket = &ivector_table[ino]; | 431 | bucket = &ivector_table[ino]; |
435 | if (!bucket->virt_irq) { | 432 | if (!bucket->virt_irq) { |
436 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | 433 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); |
437 | irq_desc[bucket->virt_irq].chip = &sun4u_irq; | 434 | set_irq_chip(bucket->virt_irq, &sun4u_irq); |
438 | } | 435 | } |
439 | 436 | ||
440 | desc = irq_desc + bucket->virt_irq; | 437 | data = get_irq_chip_data(bucket->virt_irq); |
441 | if (unlikely(desc->handler_data)) | 438 | if (unlikely(data)) |
442 | goto out; | 439 | goto out; |
443 | 440 | ||
444 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); | 441 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); |
@@ -446,7 +443,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) | |||
446 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); | 443 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); |
447 | prom_halt(); | 444 | prom_halt(); |
448 | } | 445 | } |
449 | desc->handler_data = data; | 446 | set_irq_chip_data(bucket->virt_irq, data); |
450 | 447 | ||
451 | data->imap = imap; | 448 | data->imap = imap; |
452 | data->iclr = iclr; | 449 | data->iclr = iclr; |
@@ -460,7 +457,6 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | |||
460 | struct ino_bucket *bucket; | 457 | struct ino_bucket *bucket; |
461 | struct irq_handler_data *data; | 458 | struct irq_handler_data *data; |
462 | unsigned long sysino; | 459 | unsigned long sysino; |
463 | irq_desc_t *desc; | ||
464 | 460 | ||
465 | BUG_ON(tlb_type != hypervisor); | 461 | BUG_ON(tlb_type != hypervisor); |
466 | 462 | ||
@@ -468,11 +464,11 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | |||
468 | bucket = &ivector_table[sysino]; | 464 | bucket = &ivector_table[sysino]; |
469 | if (!bucket->virt_irq) { | 465 | if (!bucket->virt_irq) { |
470 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | 466 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); |
471 | irq_desc[bucket->virt_irq].chip = &sun4v_irq; | 467 | set_irq_chip(bucket->virt_irq, &sun4v_irq); |
472 | } | 468 | } |
473 | 469 | ||
474 | desc = irq_desc + bucket->virt_irq; | 470 | data = get_irq_chip_data(bucket->virt_irq); |
475 | if (unlikely(desc->handler_data)) | 471 | if (unlikely(data)) |
476 | goto out; | 472 | goto out; |
477 | 473 | ||
478 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); | 474 | data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); |
@@ -480,7 +476,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | |||
480 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); | 476 | prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); |
481 | prom_halt(); | 477 | prom_halt(); |
482 | } | 478 | } |
483 | desc->handler_data = data; | 479 | set_irq_chip_data(bucket->virt_irq, data); |
484 | 480 | ||
485 | /* Catch accidental accesses to these things. IMAP/ICLR handling | 481 | /* Catch accidental accesses to these things. IMAP/ICLR handling |
486 | * is done by hypervisor calls on sun4v platforms, not by direct | 482 | * is done by hypervisor calls on sun4v platforms, not by direct |