diff options
author | Michael Ellerman <michael@ellerman.id.au> | 2009-10-13 15:45:03 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-10-30 02:21:31 -0400 |
commit | cd015707176820b86d07b5dffdecfefdd539a497 (patch) | |
tree | c71a90d99a1dee4d5a24f883230c201c43cd8c0d /arch/powerpc | |
parent | 750ab112919220a1d14491ae210b689bcb7d6d66 (diff) |
powerpc: Enable sparse irq_descs on powerpc
Defining CONFIG_SPARSE_IRQ enables generic code that gets rid of the
static irq_desc array, and replaces it with an array of pointers to
irq_descs.
It also allows node local allocation of irq_descs, however we
currently don't have the information available to do that, so we just
allocate them on all on node 0.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/Kconfig | 13 | ||||
-rw-r--r-- | arch/powerpc/include/asm/irq.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/irq.c | 40 | ||||
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 5 |
5 files changed, 49 insertions, 13 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3aa79f8e39e4..61abde11a45e 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -377,6 +377,19 @@ config IRQ_ALL_CPUS | |||
377 | CPU. Generally saying Y is safe, although some problems have been | 377 | CPU. Generally saying Y is safe, although some problems have been |
378 | reported with SMP Power Macintoshes with this option enabled. | 378 | reported with SMP Power Macintoshes with this option enabled. |
379 | 379 | ||
380 | config SPARSE_IRQ | ||
381 | bool "Support sparse irq numbering" | ||
382 | default y | ||
383 | help | ||
384 | This enables support for sparse irqs. This is useful for distro | ||
385 | kernels that want to define a high CONFIG_NR_CPUS value but still | ||
386 | want to have low kernel memory footprint on smaller machines. | ||
387 | |||
388 | ( Sparse IRQs can also be beneficial on NUMA boxes, as they spread | ||
389 | out the irq_desc[] array in a more NUMA-friendly way. ) | ||
390 | |||
391 | If you don't know what to do here, say Y. | ||
392 | |||
380 | config NUMA | 393 | config NUMA |
381 | bool "NUMA support" | 394 | bool "NUMA support" |
382 | depends on PPC64 | 395 | depends on PPC64 |
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index 03dc28cdb4da..c85a32f1a17f 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h | |||
@@ -38,6 +38,9 @@ extern atomic_t ppc_n_lost_interrupts; | |||
38 | /* Number of irqs reserved for the legacy controller */ | 38 | /* Number of irqs reserved for the legacy controller */ |
39 | #define NUM_ISA_INTERRUPTS 16 | 39 | #define NUM_ISA_INTERRUPTS 16 |
40 | 40 | ||
41 | /* Same thing, used by the generic IRQ code */ | ||
42 | #define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS | ||
43 | |||
41 | /* This type is the placeholder for a hardware interrupt number. It has to | 44 | /* This type is the placeholder for a hardware interrupt number. It has to |
42 | * be big enough to enclose whatever representation is used by a given | 45 | * be big enough to enclose whatever representation is used by a given |
43 | * platform. | 46 | * platform. |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 63e27d5c52de..eba53923630f 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -85,7 +85,10 @@ extern int tau_interrupts(int); | |||
85 | #endif /* CONFIG_PPC32 */ | 85 | #endif /* CONFIG_PPC32 */ |
86 | 86 | ||
87 | #ifdef CONFIG_PPC64 | 87 | #ifdef CONFIG_PPC64 |
88 | |||
89 | #ifndef CONFIG_SPARSE_IRQ | ||
88 | EXPORT_SYMBOL(irq_desc); | 90 | EXPORT_SYMBOL(irq_desc); |
91 | #endif | ||
89 | 92 | ||
90 | int distribute_irqs = 1; | 93 | int distribute_irqs = 1; |
91 | 94 | ||
@@ -613,8 +616,16 @@ void irq_set_virq_count(unsigned int count) | |||
613 | static int irq_setup_virq(struct irq_host *host, unsigned int virq, | 616 | static int irq_setup_virq(struct irq_host *host, unsigned int virq, |
614 | irq_hw_number_t hwirq) | 617 | irq_hw_number_t hwirq) |
615 | { | 618 | { |
619 | struct irq_desc *desc; | ||
620 | |||
621 | desc = irq_to_desc_alloc_node(virq, 0); | ||
622 | if (!desc) { | ||
623 | pr_debug("irq: -> allocating desc failed\n"); | ||
624 | goto error; | ||
625 | } | ||
626 | |||
616 | /* Clear IRQ_NOREQUEST flag */ | 627 | /* Clear IRQ_NOREQUEST flag */ |
617 | irq_to_desc(virq)->status &= ~IRQ_NOREQUEST; | 628 | desc->status &= ~IRQ_NOREQUEST; |
618 | 629 | ||
619 | /* map it */ | 630 | /* map it */ |
620 | smp_wmb(); | 631 | smp_wmb(); |
@@ -623,11 +634,14 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq, | |||
623 | 634 | ||
624 | if (host->ops->map(host, virq, hwirq)) { | 635 | if (host->ops->map(host, virq, hwirq)) { |
625 | pr_debug("irq: -> mapping failed, freeing\n"); | 636 | pr_debug("irq: -> mapping failed, freeing\n"); |
626 | irq_free_virt(virq, 1); | 637 | goto error; |
627 | return -1; | ||
628 | } | 638 | } |
629 | 639 | ||
630 | return 0; | 640 | return 0; |
641 | |||
642 | error: | ||
643 | irq_free_virt(virq, 1); | ||
644 | return -1; | ||
631 | } | 645 | } |
632 | 646 | ||
633 | unsigned int irq_create_direct_mapping(struct irq_host *host) | 647 | unsigned int irq_create_direct_mapping(struct irq_host *host) |
@@ -1008,12 +1022,24 @@ void irq_free_virt(unsigned int virq, unsigned int count) | |||
1008 | spin_unlock_irqrestore(&irq_big_lock, flags); | 1022 | spin_unlock_irqrestore(&irq_big_lock, flags); |
1009 | } | 1023 | } |
1010 | 1024 | ||
1011 | void irq_early_init(void) | 1025 | int arch_early_irq_init(void) |
1012 | { | 1026 | { |
1013 | unsigned int i; | 1027 | struct irq_desc *desc; |
1028 | int i; | ||
1014 | 1029 | ||
1015 | for (i = 0; i < NR_IRQS; i++) | 1030 | for (i = 0; i < NR_IRQS; i++) { |
1016 | irq_to_desc(i)->status |= IRQ_NOREQUEST; | 1031 | desc = irq_to_desc(i); |
1032 | if (desc) | ||
1033 | desc->status |= IRQ_NOREQUEST; | ||
1034 | } | ||
1035 | |||
1036 | return 0; | ||
1037 | } | ||
1038 | |||
1039 | int arch_init_chip_data(struct irq_desc *desc, int node) | ||
1040 | { | ||
1041 | desc->status |= IRQ_NOREQUEST; | ||
1042 | return 0; | ||
1017 | } | 1043 | } |
1018 | 1044 | ||
1019 | /* We need to create the radix trees late */ | 1045 | /* We need to create the radix trees late */ |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index c8b27bb4dbde..07115d6cd4ba 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -162,7 +162,6 @@ EXPORT_SYMBOL(screen_info); | |||
162 | 162 | ||
163 | #ifdef CONFIG_PPC32 | 163 | #ifdef CONFIG_PPC32 |
164 | EXPORT_SYMBOL(timer_interrupt); | 164 | EXPORT_SYMBOL(timer_interrupt); |
165 | EXPORT_SYMBOL(irq_desc); | ||
166 | EXPORT_SYMBOL(tb_ticks_per_jiffy); | 165 | EXPORT_SYMBOL(tb_ticks_per_jiffy); |
167 | EXPORT_SYMBOL(cacheable_memcpy); | 166 | EXPORT_SYMBOL(cacheable_memcpy); |
168 | EXPORT_SYMBOL(cacheable_memzero); | 167 | EXPORT_SYMBOL(cacheable_memzero); |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 04f638d82fb3..fd785f7a279b 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -356,11 +356,6 @@ void __init setup_system(void) | |||
356 | */ | 356 | */ |
357 | initialize_cache_info(); | 357 | initialize_cache_info(); |
358 | 358 | ||
359 | /* | ||
360 | * Initialize irq remapping subsystem | ||
361 | */ | ||
362 | irq_early_init(); | ||
363 | |||
364 | #ifdef CONFIG_PPC_RTAS | 359 | #ifdef CONFIG_PPC_RTAS |
365 | /* | 360 | /* |
366 | * Initialize RTAS if available | 361 | * Initialize RTAS if available |