diff options
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
| -rw-r--r-- | arch/powerpc/kernel/irq.c | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index c2b84c64db20..2fc87862146c 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | * Copyright (C) 1996-2001 Cort Dougan | 7 | * Copyright (C) 1996-2001 Cort Dougan |
| 8 | * Adapted for Power Macintosh by Paul Mackerras | 8 | * Adapted for Power Macintosh by Paul Mackerras |
| 9 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) | 9 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) |
| 10 | * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). | ||
| 11 | * | 10 | * |
| 12 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
| @@ -337,7 +336,8 @@ void do_IRQ(struct pt_regs *regs) | |||
| 337 | 336 | ||
| 338 | void __init init_IRQ(void) | 337 | void __init init_IRQ(void) |
| 339 | { | 338 | { |
| 340 | ppc_md.init_IRQ(); | 339 | if (ppc_md.init_IRQ) |
| 340 | ppc_md.init_IRQ(); | ||
| 341 | #ifdef CONFIG_PPC64 | 341 | #ifdef CONFIG_PPC64 |
| 342 | irq_ctx_init(); | 342 | irq_ctx_init(); |
| 343 | #endif | 343 | #endif |
| @@ -597,6 +597,49 @@ static void irq_radix_rdunlock(unsigned long flags) | |||
| 597 | local_irq_restore(flags); | 597 | local_irq_restore(flags); |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | static int irq_setup_virq(struct irq_host *host, unsigned int virq, | ||
| 601 | irq_hw_number_t hwirq) | ||
| 602 | { | ||
| 603 | /* Clear IRQ_NOREQUEST flag */ | ||
| 604 | get_irq_desc(virq)->status &= ~IRQ_NOREQUEST; | ||
| 605 | |||
| 606 | /* map it */ | ||
| 607 | smp_wmb(); | ||
| 608 | irq_map[virq].hwirq = hwirq; | ||
| 609 | smp_mb(); | ||
| 610 | |||
| 611 | if (host->ops->map(host, virq, hwirq)) { | ||
| 612 | pr_debug("irq: -> mapping failed, freeing\n"); | ||
| 613 | irq_free_virt(virq, 1); | ||
| 614 | return -1; | ||
| 615 | } | ||
| 616 | |||
| 617 | return 0; | ||
| 618 | } | ||
| 619 | |||
| 620 | unsigned int irq_create_direct_mapping(struct irq_host *host) | ||
| 621 | { | ||
| 622 | unsigned int virq; | ||
| 623 | |||
| 624 | if (host == NULL) | ||
| 625 | host = irq_default_host; | ||
| 626 | |||
| 627 | BUG_ON(host == NULL); | ||
| 628 | WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP); | ||
| 629 | |||
| 630 | virq = irq_alloc_virt(host, 1, 0); | ||
| 631 | if (virq == NO_IRQ) { | ||
| 632 | pr_debug("irq: create_direct virq allocation failed\n"); | ||
| 633 | return NO_IRQ; | ||
| 634 | } | ||
| 635 | |||
| 636 | pr_debug("irq: create_direct obtained virq %d\n", virq); | ||
| 637 | |||
| 638 | if (irq_setup_virq(host, virq, virq)) | ||
| 639 | return NO_IRQ; | ||
| 640 | |||
| 641 | return virq; | ||
| 642 | } | ||
| 600 | 643 | ||
| 601 | unsigned int irq_create_mapping(struct irq_host *host, | 644 | unsigned int irq_create_mapping(struct irq_host *host, |
| 602 | irq_hw_number_t hwirq) | 645 | irq_hw_number_t hwirq) |
| @@ -645,18 +688,9 @@ unsigned int irq_create_mapping(struct irq_host *host, | |||
| 645 | } | 688 | } |
| 646 | pr_debug("irq: -> obtained virq %d\n", virq); | 689 | pr_debug("irq: -> obtained virq %d\n", virq); |
| 647 | 690 | ||
| 648 | /* Clear IRQ_NOREQUEST flag */ | 691 | if (irq_setup_virq(host, virq, hwirq)) |
| 649 | get_irq_desc(virq)->status &= ~IRQ_NOREQUEST; | ||
| 650 | |||
| 651 | /* map it */ | ||
| 652 | smp_wmb(); | ||
| 653 | irq_map[virq].hwirq = hwirq; | ||
| 654 | smp_mb(); | ||
| 655 | if (host->ops->map(host, virq, hwirq)) { | ||
| 656 | pr_debug("irq: -> mapping failed, freeing\n"); | ||
| 657 | irq_free_virt(virq, 1); | ||
| 658 | return NO_IRQ; | 692 | return NO_IRQ; |
| 659 | } | 693 | |
| 660 | return virq; | 694 | return virq; |
| 661 | } | 695 | } |
| 662 | EXPORT_SYMBOL_GPL(irq_create_mapping); | 696 | EXPORT_SYMBOL_GPL(irq_create_mapping); |
