diff options
Diffstat (limited to 'arch/powerpc/kernel/prom.c')
-rw-r--r-- | arch/powerpc/kernel/prom.c | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index d63cd562d9d5..5a24415a2e3c 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -854,35 +854,70 @@ void __init unflatten_device_tree(void) | |||
854 | DBG(" <- unflatten_device_tree()\n"); | 854 | DBG(" <- unflatten_device_tree()\n"); |
855 | } | 855 | } |
856 | 856 | ||
857 | |||
858 | static int __init early_init_dt_scan_cpus(unsigned long node, | 857 | static int __init early_init_dt_scan_cpus(unsigned long node, |
859 | const char *uname, int depth, void *data) | 858 | const char *uname, int depth, |
859 | void *data) | ||
860 | { | 860 | { |
861 | u32 *prop; | 861 | static int logical_cpuid = 0; |
862 | unsigned long size; | 862 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); |
863 | char *type = of_get_flat_dt_prop(node, "device_type", &size); | 863 | u32 *prop, *intserv; |
864 | int i, nthreads; | ||
865 | unsigned long len; | ||
866 | int found = 0; | ||
864 | 867 | ||
865 | /* We are scanning "cpu" nodes only */ | 868 | /* We are scanning "cpu" nodes only */ |
866 | if (type == NULL || strcmp(type, "cpu") != 0) | 869 | if (type == NULL || strcmp(type, "cpu") != 0) |
867 | return 0; | 870 | return 0; |
868 | 871 | ||
869 | boot_cpuid = 0; | 872 | /* Get physical cpuid */ |
870 | boot_cpuid_phys = 0; | 873 | intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len); |
871 | if (initial_boot_params && initial_boot_params->version >= 2) { | 874 | if (intserv) { |
872 | /* version 2 of the kexec param format adds the phys cpuid | 875 | nthreads = len / sizeof(int); |
873 | * of booted proc. | ||
874 | */ | ||
875 | boot_cpuid_phys = initial_boot_params->boot_cpuid_phys; | ||
876 | } else { | 876 | } else { |
877 | /* Check if it's the boot-cpu, set it's hw index now */ | 877 | intserv = of_get_flat_dt_prop(node, "reg", NULL); |
878 | if (of_get_flat_dt_prop(node, | 878 | nthreads = 1; |
879 | } | ||
880 | |||
881 | /* | ||
882 | * Now see if any of these threads match our boot cpu. | ||
883 | * NOTE: This must match the parsing done in smp_setup_cpu_maps. | ||
884 | */ | ||
885 | for (i = 0; i < nthreads; i++) { | ||
886 | /* | ||
887 | * version 2 of the kexec param format adds the phys cpuid of | ||
888 | * booted proc. | ||
889 | */ | ||
890 | if (initial_boot_params && initial_boot_params->version >= 2) { | ||
891 | if (intserv[i] == | ||
892 | initial_boot_params->boot_cpuid_phys) { | ||
893 | found = 1; | ||
894 | break; | ||
895 | } | ||
896 | } else { | ||
897 | /* | ||
898 | * Check if it's the boot-cpu, set it's hw index now, | ||
899 | * unfortunately this format did not support booting | ||
900 | * off secondary threads. | ||
901 | */ | ||
902 | if (of_get_flat_dt_prop(node, | ||
879 | "linux,boot-cpu", NULL) != NULL) { | 903 | "linux,boot-cpu", NULL) != NULL) { |
880 | prop = of_get_flat_dt_prop(node, "reg", NULL); | 904 | found = 1; |
881 | if (prop != NULL) | 905 | break; |
882 | boot_cpuid_phys = *prop; | 906 | } |
883 | } | 907 | } |
908 | |||
909 | #ifdef CONFIG_SMP | ||
910 | /* logical cpu id is always 0 on UP kernels */ | ||
911 | logical_cpuid++; | ||
912 | #endif | ||
913 | } | ||
914 | |||
915 | if (found) { | ||
916 | DBG("boot cpu: logical %d physical %d\n", logical_cpuid, | ||
917 | intserv[i]); | ||
918 | boot_cpuid = logical_cpuid; | ||
919 | set_hard_smp_processor_id(boot_cpuid, intserv[i]); | ||
884 | } | 920 | } |
885 | set_hard_smp_processor_id(0, boot_cpuid_phys); | ||
886 | 921 | ||
887 | #ifdef CONFIG_ALTIVEC | 922 | #ifdef CONFIG_ALTIVEC |
888 | /* Check if we have a VMX and eventually update CPU features */ | 923 | /* Check if we have a VMX and eventually update CPU features */ |
@@ -901,16 +936,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
901 | #endif /* CONFIG_ALTIVEC */ | 936 | #endif /* CONFIG_ALTIVEC */ |
902 | 937 | ||
903 | #ifdef CONFIG_PPC_PSERIES | 938 | #ifdef CONFIG_PPC_PSERIES |
904 | /* | 939 | if (nthreads > 1) |
905 | * Check for an SMT capable CPU and set the CPU feature. We do | ||
906 | * this by looking at the size of the ibm,ppc-interrupt-server#s | ||
907 | * property | ||
908 | */ | ||
909 | prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", | ||
910 | &size); | ||
911 | cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; | ||
912 | if (prop && ((size / sizeof(u32)) > 1)) | ||
913 | cur_cpu_spec->cpu_features |= CPU_FTR_SMT; | 940 | cur_cpu_spec->cpu_features |= CPU_FTR_SMT; |
941 | else | ||
942 | cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; | ||
914 | #endif | 943 | #endif |
915 | 944 | ||
916 | return 0; | 945 | return 0; |