diff options
Diffstat (limited to 'arch/powerpc/platforms/pseries/xics.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/xics.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index e1904774a70f..f7a69021b7bf 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -579,7 +579,7 @@ static void xics_update_irq_servers(void) | |||
579 | int i, j; | 579 | int i, j; |
580 | struct device_node *np; | 580 | struct device_node *np; |
581 | u32 ilen; | 581 | u32 ilen; |
582 | const u32 *ireg, *isize; | 582 | const u32 *ireg; |
583 | u32 hcpuid; | 583 | u32 hcpuid; |
584 | 584 | ||
585 | /* Find the server numbers for the boot cpu. */ | 585 | /* Find the server numbers for the boot cpu. */ |
@@ -607,11 +607,6 @@ static void xics_update_irq_servers(void) | |||
607 | } | 607 | } |
608 | } | 608 | } |
609 | 609 | ||
610 | /* get the bit size of server numbers */ | ||
611 | isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); | ||
612 | if (isize) | ||
613 | interrupt_server_size = *isize; | ||
614 | |||
615 | of_node_put(np); | 610 | of_node_put(np); |
616 | } | 611 | } |
617 | 612 | ||
@@ -682,6 +677,7 @@ void __init xics_init_IRQ(void) | |||
682 | struct device_node *np; | 677 | struct device_node *np; |
683 | u32 indx = 0; | 678 | u32 indx = 0; |
684 | int found = 0; | 679 | int found = 0; |
680 | const u32 *isize; | ||
685 | 681 | ||
686 | ppc64_boot_msg(0x20, "XICS Init"); | 682 | ppc64_boot_msg(0x20, "XICS Init"); |
687 | 683 | ||
@@ -701,6 +697,26 @@ void __init xics_init_IRQ(void) | |||
701 | if (found == 0) | 697 | if (found == 0) |
702 | return; | 698 | return; |
703 | 699 | ||
700 | /* get the bit size of server numbers */ | ||
701 | found = 0; | ||
702 | |||
703 | for_each_compatible_node(np, NULL, "ibm,ppc-xics") { | ||
704 | isize = of_get_property(np, "ibm,interrupt-server#-size", NULL); | ||
705 | |||
706 | if (!isize) | ||
707 | continue; | ||
708 | |||
709 | if (!found) { | ||
710 | interrupt_server_size = *isize; | ||
711 | found = 1; | ||
712 | } else if (*isize != interrupt_server_size) { | ||
713 | printk(KERN_WARNING "XICS: " | ||
714 | "mismatched ibm,interrupt-server#-size\n"); | ||
715 | interrupt_server_size = max(*isize, | ||
716 | interrupt_server_size); | ||
717 | } | ||
718 | } | ||
719 | |||
704 | xics_update_irq_servers(); | 720 | xics_update_irq_servers(); |
705 | xics_init_host(); | 721 | xics_init_host(); |
706 | 722 | ||
@@ -728,9 +744,18 @@ static void xics_set_cpu_priority(unsigned char cppr) | |||
728 | /* Have the calling processor join or leave the specified global queue */ | 744 | /* Have the calling processor join or leave the specified global queue */ |
729 | static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) | 745 | static void xics_set_cpu_giq(unsigned int gserver, unsigned int join) |
730 | { | 746 | { |
731 | int status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, | 747 | int index; |
732 | (1UL << interrupt_server_size) - 1 - gserver, join); | 748 | int status; |
733 | WARN_ON(status < 0); | 749 | |
750 | if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL)) | ||
751 | return; | ||
752 | |||
753 | index = (1UL << interrupt_server_size) - 1 - gserver; | ||
754 | |||
755 | status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join); | ||
756 | |||
757 | WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n", | ||
758 | GLOBAL_INTERRUPT_QUEUE, index, join, status); | ||
734 | } | 759 | } |
735 | 760 | ||
736 | void xics_setup_cpu(void) | 761 | void xics_setup_cpu(void) |