diff options
| author | David S. Miller <davem@sunset.davemloft.net> | 2007-07-14 06:16:13 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-16 07:05:11 -0400 |
| commit | b53bcb6799f8f2c0f385f24a8bb054f142c7d83a (patch) | |
| tree | fd1ec8145337937769c484c843047a23f34187a4 | |
| parent | bd0e11ff221d929b2b711ce3e5712e097e9dd1d8 (diff) | |
[SPARC64]: Add ->set_affinity IRQ handlers.
dr-cpu unconfigure requests will walk throught he enabled
IRQs and trigger ->set_affinity so that the going-down
cpu no longer has INOs targetted to it.
Signed-off-by: David S. Miller <davem@davemloft.net>
| -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, |
