aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r--arch/sparc64/kernel/irq.c74
1 files changed, 24 insertions, 50 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index db31bf6b42db..384abf410cf0 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -929,7 +929,7 @@ static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type
929 } 929 }
930} 930}
931 931
932static void __cpuinit sun4v_register_mondo_queues(int this_cpu) 932void __cpuinit sun4v_register_mondo_queues(int this_cpu)
933{ 933{
934 struct trap_per_cpu *tb = &trap_block[this_cpu]; 934 struct trap_per_cpu *tb = &trap_block[this_cpu];
935 935
@@ -943,20 +943,10 @@ static void __cpuinit sun4v_register_mondo_queues(int this_cpu)
943 tb->nonresum_qmask); 943 tb->nonresum_qmask);
944} 944}
945 945
946static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem) 946static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask)
947{ 947{
948 unsigned long size = PAGE_ALIGN(qmask + 1); 948 unsigned long size = PAGE_ALIGN(qmask + 1);
949 unsigned long order = get_order(size); 949 void *p = __alloc_bootmem_low(size, size, 0);
950 void *p = NULL;
951
952 if (use_bootmem) {
953 p = __alloc_bootmem_low(size, size, 0);
954 } else {
955 struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
956 if (page)
957 p = page_address(page);
958 }
959
960 if (!p) { 950 if (!p) {
961 prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); 951 prom_printf("SUN4V: Error, cannot allocate mondo queue.\n");
962 prom_halt(); 952 prom_halt();
@@ -965,19 +955,10 @@ static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask
965 *pa_ptr = __pa(p); 955 *pa_ptr = __pa(p);
966} 956}
967 957
968static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem) 958static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask)
969{ 959{
970 unsigned long size = PAGE_ALIGN(qmask + 1); 960 unsigned long size = PAGE_ALIGN(qmask + 1);
971 unsigned long order = get_order(size); 961 void *p = __alloc_bootmem_low(size, size, 0);
972 void *p = NULL;
973
974 if (use_bootmem) {
975 p = __alloc_bootmem_low(size, size, 0);
976 } else {
977 struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order);
978 if (page)
979 p = page_address(page);
980 }
981 962
982 if (!p) { 963 if (!p) {
983 prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); 964 prom_printf("SUN4V: Error, cannot allocate kbuf page.\n");
@@ -987,18 +968,14 @@ static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask,
987 *pa_ptr = __pa(p); 968 *pa_ptr = __pa(p);
988} 969}
989 970
990static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem) 971static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb)
991{ 972{
992#ifdef CONFIG_SMP 973#ifdef CONFIG_SMP
993 void *page; 974 void *page;
994 975
995 BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); 976 BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
996 977
997 if (use_bootmem) 978 page = alloc_bootmem_low_pages(PAGE_SIZE);
998 page = alloc_bootmem_low_pages(PAGE_SIZE);
999 else
1000 page = (void *) get_zeroed_page(GFP_ATOMIC);
1001
1002 if (!page) { 979 if (!page) {
1003 prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); 980 prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
1004 prom_halt(); 981 prom_halt();
@@ -1009,30 +986,27 @@ static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_
1009#endif 986#endif
1010} 987}
1011 988
1012/* Allocate and register the mondo and error queues for this cpu. */ 989/* Allocate mondo and error queues for all possible cpus. */
1013void __cpuinit sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int load) 990static void __init sun4v_init_mondo_queues(void)
1014{ 991{
1015 struct trap_per_cpu *tb = &trap_block[cpu]; 992 int cpu;
1016 993
1017 if (alloc) { 994 for_each_possible_cpu(cpu) {
1018 alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask, use_bootmem); 995 struct trap_per_cpu *tb = &trap_block[cpu];
1019 alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask, use_bootmem);
1020 alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask, use_bootmem);
1021 alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask, use_bootmem);
1022 alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask, use_bootmem);
1023 alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, tb->nonresum_qmask, use_bootmem);
1024 996
1025 init_cpu_send_mondo_info(tb, use_bootmem); 997 alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask);
1026 } 998 alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask);
999 alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask);
1000 alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask);
1001 alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask);
1002 alloc_one_kbuf(&tb->nonresum_kernel_buf_pa,
1003 tb->nonresum_qmask);
1027 1004
1028 if (load) { 1005 init_cpu_send_mondo_info(tb);
1029 if (cpu != hard_smp_processor_id()) {
1030 prom_printf("SUN4V: init mondo on cpu %d not %d\n",
1031 cpu, hard_smp_processor_id());
1032 prom_halt();
1033 }
1034 sun4v_register_mondo_queues(cpu);
1035 } 1006 }
1007
1008 /* Load up the boot cpu's entries. */
1009 sun4v_register_mondo_queues(hard_smp_processor_id());
1036} 1010}
1037 1011
1038static struct irqaction timer_irq_action = { 1012static struct irqaction timer_irq_action = {
@@ -1047,7 +1021,7 @@ void __init init_IRQ(void)
1047 memset(&ivector_table[0], 0, sizeof(ivector_table)); 1021 memset(&ivector_table[0], 0, sizeof(ivector_table));
1048 1022
1049 if (tlb_type == hypervisor) 1023 if (tlb_type == hypervisor)
1050 sun4v_init_mondo_queues(1, hard_smp_processor_id(), 1, 1); 1024 sun4v_init_mondo_queues();
1051 1025
1052 /* We need to clear any IRQ's pending in the soft interrupt 1026 /* We need to clear any IRQ's pending in the soft interrupt
1053 * registers, a spurious one could be left around from the 1027 * registers, a spurious one could be left around from the