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); |