]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/ppc64/kernel/sysfs.c
ppc64: move stack switching up in interrupt processing
[karo-tx-linux.git] / arch / ppc64 / kernel / sysfs.c
index c8fa6569b2fd789fc3476a3c5ab86c3bf6b3c203..e99ec62c2c52abba20b1e4f36da62e70f4d925bc 100644 (file)
 #include <asm/current.h>
 #include <asm/processor.h>
 #include <asm/cputable.h>
+#include <asm/firmware.h>
 #include <asm/hvcall.h>
 #include <asm/prom.h>
 #include <asm/systemcfg.h>
 #include <asm/paca.h>
 #include <asm/lppaca.h>
 #include <asm/machdep.h>
+#include <asm/smp.h>
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
@@ -100,6 +102,8 @@ static int __init setup_smt_snooze_delay(char *str)
 }
 __setup("smt-snooze-delay=", setup_smt_snooze_delay);
 
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
 /*
  * Enabling PMCs will slow partition context switch times so we only do
  * it the first time we write to the PMCs.
@@ -109,77 +113,15 @@ static DEFINE_PER_CPU(char, pmcs_enabled);
 
 void ppc64_enable_pmcs(void)
 {
-       unsigned long hid0;
-#ifdef CONFIG_PPC_PSERIES
-       unsigned long set, reset;
-       int ret;
-#endif /* CONFIG_PPC_PSERIES */
-
        /* Only need to enable them once */
        if (__get_cpu_var(pmcs_enabled))
                return;
 
        __get_cpu_var(pmcs_enabled) = 1;
 
-       switch (systemcfg->platform) {
-       case PLATFORM_PSERIES:
-       case PLATFORM_POWERMAC:
-               hid0 = mfspr(HID0);
-               hid0 |= 1UL << (63 - 20);
-
-               /* POWER4 requires the following sequence */
-               asm volatile(
-                            "sync\n"
-                            "mtspr     %1, %0\n"
-                            "mfspr     %0, %1\n"
-                            "mfspr     %0, %1\n"
-                            "mfspr     %0, %1\n"
-                            "mfspr     %0, %1\n"
-                            "mfspr     %0, %1\n"
-                            "mfspr     %0, %1\n"
-                            "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0):
-                            "memory");
-               break;
-
-#ifdef CONFIG_PPC_PSERIES
-       case PLATFORM_PSERIES_LPAR:
-               set = 1UL << 63;
-               reset = 0;
-               ret = plpar_hcall_norets(H_PERFMON, set, reset);
-               if (ret)
-                       printk(KERN_ERR "H_PERFMON call on cpu %u "
-                              "returned %d\n",
-                              smp_processor_id(), ret);
-               break;
-#endif /* CONFIG_PPC_PSERIES */
-
-       default:
-               break;
-       }
-
-#ifdef CONFIG_PPC_PSERIES
-       /* instruct hypervisor to maintain PMCs */
-       if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
-               get_paca()->lppaca.pmcregs_in_use = 1;
-
-       /*
-        * On SMT machines we have to set the run latch in the ctrl register
-        * in order to make PMC6 spin.
-        */
-       if (cpu_has_feature(CPU_FTR_SMT))
-               ppc64_runlatch_on();
-#endif /* CONFIG_PPC_PSERIES */
-}
-
-#else
-
-/* PMC stuff */
-void ppc64_enable_pmcs(void)
-{
-       /* XXX Implement for iseries */
+       if (ppc_md.enable_pmcs)
+               ppc_md.enable_pmcs();
 }
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
 EXPORT_SYMBOL(ppc64_enable_pmcs);
 
 /* XXX convert to rusty's on_one_cpu */
@@ -274,18 +216,23 @@ static void register_cpu_online(unsigned int cpu)
        if (cpu_has_feature(CPU_FTR_MMCRA))
                sysdev_create_file(s, &attr_mmcra);
 
-       sysdev_create_file(s, &attr_pmc1);
-       sysdev_create_file(s, &attr_pmc2);
-       sysdev_create_file(s, &attr_pmc3);
-       sysdev_create_file(s, &attr_pmc4);
-       sysdev_create_file(s, &attr_pmc5);
-       sysdev_create_file(s, &attr_pmc6);
-
-       if (cpu_has_feature(CPU_FTR_PMC8)) {
+       if (cur_cpu_spec->num_pmcs >= 1)
+               sysdev_create_file(s, &attr_pmc1);
+       if (cur_cpu_spec->num_pmcs >= 2)
+               sysdev_create_file(s, &attr_pmc2);
+       if (cur_cpu_spec->num_pmcs >= 3)
+               sysdev_create_file(s, &attr_pmc3);
+       if (cur_cpu_spec->num_pmcs >= 4)
+               sysdev_create_file(s, &attr_pmc4);
+       if (cur_cpu_spec->num_pmcs >= 5)
+               sysdev_create_file(s, &attr_pmc5);
+       if (cur_cpu_spec->num_pmcs >= 6)
+               sysdev_create_file(s, &attr_pmc6);
+       if (cur_cpu_spec->num_pmcs >= 7)
                sysdev_create_file(s, &attr_pmc7);
+       if (cur_cpu_spec->num_pmcs >= 8)
                sysdev_create_file(s, &attr_pmc8);
-       }
-
+  
        if (cpu_has_feature(CPU_FTR_SMT))
                sysdev_create_file(s, &attr_purr);
 }
@@ -311,17 +258,22 @@ static void unregister_cpu_online(unsigned int cpu)
        if (cpu_has_feature(CPU_FTR_MMCRA))
                sysdev_remove_file(s, &attr_mmcra);
 
-       sysdev_remove_file(s, &attr_pmc1);
-       sysdev_remove_file(s, &attr_pmc2);
-       sysdev_remove_file(s, &attr_pmc3);
-       sysdev_remove_file(s, &attr_pmc4);
-       sysdev_remove_file(s, &attr_pmc5);
-       sysdev_remove_file(s, &attr_pmc6);
-
-       if (cpu_has_feature(CPU_FTR_PMC8)) {
+       if (cur_cpu_spec->num_pmcs >= 1)
+               sysdev_remove_file(s, &attr_pmc1);
+       if (cur_cpu_spec->num_pmcs >= 2)
+               sysdev_remove_file(s, &attr_pmc2);
+       if (cur_cpu_spec->num_pmcs >= 3)
+               sysdev_remove_file(s, &attr_pmc3);
+       if (cur_cpu_spec->num_pmcs >= 4)
+               sysdev_remove_file(s, &attr_pmc4);
+       if (cur_cpu_spec->num_pmcs >= 5)
+               sysdev_remove_file(s, &attr_pmc5);
+       if (cur_cpu_spec->num_pmcs >= 6)
+               sysdev_remove_file(s, &attr_pmc6);
+       if (cur_cpu_spec->num_pmcs >= 7)
                sysdev_remove_file(s, &attr_pmc7);
+       if (cur_cpu_spec->num_pmcs >= 8)
                sysdev_remove_file(s, &attr_pmc8);
-       }
 
        if (cpu_has_feature(CPU_FTR_SMT))
                sysdev_remove_file(s, &attr_purr);
@@ -400,7 +352,12 @@ static int __init topology_init(void)
                struct cpu *c = &per_cpu(cpu_devices, cpu);
 
 #ifdef CONFIG_NUMA
-               parent = &node_devices[cpu_to_node(cpu)];
+               /* The node to which a cpu belongs can't be known
+                * until the cpu is made present.
+                */
+               parent = NULL;
+               if (cpu_present(cpu))
+                       parent = &node_devices[cpu_to_node(cpu)];
 #endif
                /*
                 * For now, we just see if the system supports making