diff options
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r-- | arch/sparc64/kernel/irq.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 634194e7d2d6..a1c916f35baa 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -293,6 +293,11 @@ static void sun4u_irq_enable(unsigned int virt_irq) | |||
293 | } | 293 | } |
294 | } | 294 | } |
295 | 295 | ||
296 | static void sun4u_set_affinity(unsigned int virt_irq, cpumask_t mask) | ||
297 | { | ||
298 | sun4u_irq_enable(virt_irq); | ||
299 | } | ||
300 | |||
296 | static void sun4u_irq_disable(unsigned int virt_irq) | 301 | static void sun4u_irq_disable(unsigned int virt_irq) |
297 | { | 302 | { |
298 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); | 303 | struct irq_handler_data *data = get_irq_chip_data(virt_irq); |
@@ -344,6 +349,24 @@ static void sun4v_irq_enable(unsigned int virt_irq) | |||
344 | } | 349 | } |
345 | } | 350 | } |
346 | 351 | ||
352 | static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask) | ||
353 | { | ||
354 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | ||
355 | unsigned int ino = bucket - &ivector_table[0]; | ||
356 | |||
357 | if (likely(bucket)) { | ||
358 | unsigned long cpuid; | ||
359 | int err; | ||
360 | |||
361 | cpuid = irq_choose_cpu(virt_irq); | ||
362 | |||
363 | err = sun4v_intr_settarget(ino, cpuid); | ||
364 | if (err != HV_EOK) | ||
365 | printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", | ||
366 | ino, cpuid, err); | ||
367 | } | ||
368 | } | ||
369 | |||
347 | static void sun4v_irq_disable(unsigned int virt_irq) | 370 | static void sun4v_irq_disable(unsigned int virt_irq) |
348 | { | 371 | { |
349 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 372 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
@@ -426,6 +449,28 @@ static void sun4v_virq_enable(unsigned int virt_irq) | |||
426 | } | 449 | } |
427 | } | 450 | } |
428 | 451 | ||
452 | static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) | ||
453 | { | ||
454 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | ||
455 | unsigned int ino = bucket - &ivector_table[0]; | ||
456 | |||
457 | if (likely(bucket)) { | ||
458 | unsigned long cpuid, dev_handle, dev_ino; | ||
459 | int err; | ||
460 | |||
461 | cpuid = irq_choose_cpu(virt_irq); | ||
462 | |||
463 | dev_handle = ino & IMAP_IGN; | ||
464 | dev_ino = ino & IMAP_INO; | ||
465 | |||
466 | err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); | ||
467 | if (err != HV_EOK) | ||
468 | printk("sun4v_vintr_set_target(%lx,%lx,%lu): " | ||
469 | "err(%d)\n", | ||
470 | dev_handle, dev_ino, cpuid, err); | ||
471 | } | ||
472 | } | ||
473 | |||
429 | static void sun4v_virq_disable(unsigned int virt_irq) | 474 | static void sun4v_virq_disable(unsigned int virt_irq) |
430 | { | 475 | { |
431 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 476 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
@@ -489,6 +534,7 @@ static struct irq_chip sun4u_irq = { | |||
489 | .enable = sun4u_irq_enable, | 534 | .enable = sun4u_irq_enable, |
490 | .disable = sun4u_irq_disable, | 535 | .disable = sun4u_irq_disable, |
491 | .end = sun4u_irq_end, | 536 | .end = sun4u_irq_end, |
537 | .set_affinity = sun4u_set_affinity, | ||
492 | }; | 538 | }; |
493 | 539 | ||
494 | static struct irq_chip sun4u_irq_ack = { | 540 | static struct irq_chip sun4u_irq_ack = { |
@@ -497,6 +543,7 @@ static struct irq_chip sun4u_irq_ack = { | |||
497 | .disable = sun4u_irq_disable, | 543 | .disable = sun4u_irq_disable, |
498 | .ack = run_pre_handler, | 544 | .ack = run_pre_handler, |
499 | .end = sun4u_irq_end, | 545 | .end = sun4u_irq_end, |
546 | .set_affinity = sun4u_set_affinity, | ||
500 | }; | 547 | }; |
501 | 548 | ||
502 | static struct irq_chip sun4v_irq = { | 549 | static struct irq_chip sun4v_irq = { |
@@ -504,6 +551,7 @@ static struct irq_chip sun4v_irq = { | |||
504 | .enable = sun4v_irq_enable, | 551 | .enable = sun4v_irq_enable, |
505 | .disable = sun4v_irq_disable, | 552 | .disable = sun4v_irq_disable, |
506 | .end = sun4v_irq_end, | 553 | .end = sun4v_irq_end, |
554 | .set_affinity = sun4v_set_affinity, | ||
507 | }; | 555 | }; |
508 | 556 | ||
509 | static struct irq_chip sun4v_irq_ack = { | 557 | static struct irq_chip sun4v_irq_ack = { |
@@ -512,6 +560,7 @@ static struct irq_chip sun4v_irq_ack = { | |||
512 | .disable = sun4v_irq_disable, | 560 | .disable = sun4v_irq_disable, |
513 | .ack = run_pre_handler, | 561 | .ack = run_pre_handler, |
514 | .end = sun4v_irq_end, | 562 | .end = sun4v_irq_end, |
563 | .set_affinity = sun4v_set_affinity, | ||
515 | }; | 564 | }; |
516 | 565 | ||
517 | #ifdef CONFIG_PCI_MSI | 566 | #ifdef CONFIG_PCI_MSI |
@@ -523,6 +572,7 @@ static struct irq_chip sun4v_msi = { | |||
523 | .disable = sun4v_msi_disable, | 572 | .disable = sun4v_msi_disable, |
524 | .ack = run_pre_handler, | 573 | .ack = run_pre_handler, |
525 | .end = sun4v_irq_end, | 574 | .end = sun4v_irq_end, |
575 | .set_affinity = sun4v_set_affinity, | ||
526 | }; | 576 | }; |
527 | #endif | 577 | #endif |
528 | 578 | ||
@@ -531,6 +581,7 @@ static struct irq_chip sun4v_virq = { | |||
531 | .enable = sun4v_virq_enable, | 581 | .enable = sun4v_virq_enable, |
532 | .disable = sun4v_virq_disable, | 582 | .disable = sun4v_virq_disable, |
533 | .end = sun4v_virq_end, | 583 | .end = sun4v_virq_end, |
584 | .set_affinity = sun4v_virt_set_affinity, | ||
534 | }; | 585 | }; |
535 | 586 | ||
536 | static struct irq_chip sun4v_virq_ack = { | 587 | static struct irq_chip sun4v_virq_ack = { |
@@ -539,6 +590,7 @@ static struct irq_chip sun4v_virq_ack = { | |||
539 | .disable = sun4v_virq_disable, | 590 | .disable = sun4v_virq_disable, |
540 | .ack = run_pre_handler, | 591 | .ack = run_pre_handler, |
541 | .end = sun4v_virq_end, | 592 | .end = sun4v_virq_end, |
593 | .set_affinity = sun4v_virt_set_affinity, | ||
542 | }; | 594 | }; |
543 | 595 | ||
544 | void irq_install_pre_handler(int virt_irq, | 596 | void irq_install_pre_handler(int virt_irq, |