struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
                if (!p)
                        return -ENOMEM;
-               register_cpu(p, i, NULL);
+               register_cpu(p, i);
        }
        return 0;
 }
 
        int cpu;
 
        for_each_possible_cpu(cpu)
-               register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL);
+               register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu);
 
        return 0;
 }
 
 
 static struct i386_cpu cpu_devices[NR_CPUS];
 
-int arch_register_cpu(int num){
-       struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
-       int node = cpu_to_node(num);
-       if (node_online(node))
-               parent = &node_devices[parent_node(node)];
-#endif /* CONFIG_NUMA */
-
+int arch_register_cpu(int num)
+{
        /*
         * CPU0 cannot be offlined due to several
         * restrictions and assumptions in kernel. This basically
        if (!num)
                cpu_devices[num].cpu.no_control = 1;
 
-       return register_cpu(&cpu_devices[num].cpu, num, parent);
+       return register_cpu(&cpu_devices[num].cpu, num);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
 
 void arch_unregister_cpu(int num) {
-       struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
-       int node = cpu_to_node(num);
-       if (node_online(node))
-               parent = &node_devices[parent_node(node)];
-#endif /* CONFIG_NUMA */
-
-       return unregister_cpu(&cpu_devices[num].cpu, parent);
+       return unregister_cpu(&cpu_devices[num].cpu);
 }
 EXPORT_SYMBOL(arch_register_cpu);
 EXPORT_SYMBOL(arch_unregister_cpu);
 
 
 int arch_register_cpu(int num)
 {
-       struct node *parent = NULL;
-       
-#ifdef CONFIG_NUMA
-       parent = &node_devices[cpu_to_node(num)];
-#endif /* CONFIG_NUMA */
-
 #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
        /*
         * If CPEI cannot be re-targetted, and this is
                sysfs_cpus[num].cpu.no_control = 1;
 #endif
 
-       return register_cpu(&sysfs_cpus[num].cpu, num, parent);
+       return register_cpu(&sysfs_cpus[num].cpu, num);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
 
 void arch_unregister_cpu(int num)
 {
-       struct node *parent = NULL;
-
-#ifdef CONFIG_NUMA
-       int node = cpu_to_node(num);
-       parent = &node_devices[node];
-#endif /* CONFIG_NUMA */
-
-       return unregister_cpu(&sysfs_cpus[num].cpu, parent);
+       return unregister_cpu(&sysfs_cpus[num].cpu);
 }
 EXPORT_SYMBOL(arch_register_cpu);
 EXPORT_SYMBOL(arch_unregister_cpu);
 
        int i;
 
        for_each_present_cpu(i)
-               register_cpu(&cpu_devices[i], i, NULL);
+               register_cpu(&cpu_devices[i], i);
 
        return 0;
 }
 
        int ret;
 
        for_each_present_cpu(cpu) {
-               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
+               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu);
                if (ret)
                        printk(KERN_WARNING "topology_init: register_cpu %d "
                               "failed (%d)\n", cpu, ret);
 
 
 static int __init topology_init(void)
 {
-       struct node *parent = NULL;
        int num;
 
        for_each_present_cpu(num) {
-               register_cpu(&cpu_devices[num], num, parent);
+               register_cpu(&cpu_devices[num], num);
        }
        return 0;
 }
 
 
        /* register CPU devices */
        for_each_possible_cpu(i)
-               register_cpu(&cpu_devices[i], i, NULL);
+               register_cpu(&cpu_devices[i], i);
 
        /* call platform init */
        if (ppc_md.init != NULL) {
 
 static int __init topology_init(void)
 {
        int cpu;
-       struct node *parent = NULL;
 
        register_nodes();
-
        register_cpu_notifier(&sysfs_cpu_nb);
 
        for_each_possible_cpu(cpu) {
                struct cpu *c = &per_cpu(cpu_devices, cpu);
 
-#ifdef CONFIG_NUMA
-               /* 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
                 * the RTAS calls for CPU hotplug.  But, there may be a
                        c->no_control = 1;
 
                if (cpu_online(cpu) || (c->no_control == 0)) {
-                       register_cpu(c, cpu, parent);
+                       register_cpu(c, cpu);
 
                        sysdev_create_file(&c->sysdev, &attr_physical_id);
                }
 
 
        /* register CPU devices */
        for_each_possible_cpu(i)
-               register_cpu(&cpu_devices[i], i, NULL);
+               register_cpu(&cpu_devices[i], i);
 
        /* call platform init */
        if (ppc_md.init != NULL) {
 
        int ret;
 
        for_each_possible_cpu(cpu) {
-               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
+               ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu);
                if (ret)
                        printk(KERN_WARNING "topology_init: register_cpu %d "
                               "failed (%d)\n", cpu, ret);
 
        int cpu_id;
 
        for_each_possible_cpu(cpu_id)
-               register_cpu(&cpu[cpu_id], cpu_id, NULL);
+               register_cpu(&cpu[cpu_id], cpu_id);
 
        return 0;
 }
 
 
 static int __init topology_init(void)
 {
-       return register_cpu(cpu, 0, NULL);
+       return register_cpu(cpu, 0);
 }
 
 subsys_initcall(topology_init);
 
        for_each_possible_cpu(i) {
                struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
                if (p) {
-                       register_cpu(p, i, NULL);
+                       register_cpu(p, i);
                        err = 0;
                }
        }
 
 #include <linux/cpu.h>
 #include <linux/topology.h>
 #include <linux/device.h>
+#include <linux/node.h>
 
 #include "base.h"
 
 {
        sysdev_create_file(&cpu->sysdev, &attr_online);
 }
-void unregister_cpu(struct cpu *cpu, struct node *root)
+void unregister_cpu(struct cpu *cpu)
 {
        int logical_cpu = cpu->sysdev.id;
 
-       if (root)
-               sysfs_remove_link(&root->sysdev.kobj,
-                                 kobject_name(&cpu->sysdev.kobj));
+       unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
+
        sysdev_remove_file(&cpu->sysdev, &attr_online);
 
        sysdev_unregister(&cpu->sysdev);
  *
  * Initialize and register the CPU device.
  */
-int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
+int __devinit register_cpu(struct cpu *cpu, int num)
 {
        int error;
-
        cpu->node_id = cpu_to_node(num);
        cpu->sysdev.id = num;
        cpu->sysdev.cls = &cpu_sysdev_class;
 
        error = sysdev_register(&cpu->sysdev);
-       if (!error && root)
-               error = sysfs_create_link(&root->sysdev.kobj,
-                                         &cpu->sysdev.kobj,
-                                         kobject_name(&cpu->sysdev.kobj));
+
        if (!error && !cpu->no_control)
                register_cpu_control(cpu);
        if (!error)
                cpu_sys_devices[num] = &cpu->sysdev;
+       if (!error)
+               register_cpu_under_node(num, cpu_to_node(num));
 
 #ifdef CONFIG_KEXEC
        if (!error)
 
 #include <linux/cpumask.h>
 #include <linux/topology.h>
 #include <linux/nodemask.h>
+#include <linux/cpu.h>
 
 static struct sysdev_class node_class = {
        set_kset_name("node"),
 
 struct node node_devices[MAX_NUMNODES];
 
+/*
+ * register cpu under node
+ */
+int register_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       if (node_online(nid)) {
+               struct sys_device *obj = get_cpu_sysdev(cpu);
+               if (!obj)
+                       return 0;
+               return sysfs_create_link(&node_devices[nid].sysdev.kobj,
+                                        &obj->kobj,
+                                        kobject_name(&obj->kobj));
+        }
+
+       return 0;
+}
+
+int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       if (node_online(nid)) {
+               struct sys_device *obj = get_cpu_sysdev(cpu);
+               if (obj)
+                       sysfs_remove_link(&node_devices[nid].sysdev.kobj,
+                                        kobject_name(&obj->kobj));
+       }
+       return 0;
+}
+
 int register_one_node(int nid)
 {
        int error = 0;
+       int cpu;
 
        if (node_online(nid)) {
                int p_node = parent_node(nid);
                        parent = &node_devices[p_node];
 
                error = register_node(&node_devices[nid], nid, parent);
+
+               /* link cpu under this node */
+               for_each_present_cpu(cpu) {
+                       if (cpu_to_node(cpu) == nid)
+                               register_cpu_under_node(cpu, nid);
+               }
        }
 
        return error;
 
        struct sys_device sysdev;
 };
 
-extern int register_cpu(struct cpu *, int, struct node *);
+extern int register_cpu(struct cpu *cpu, int num);
 extern struct sys_device *get_cpu_sysdev(unsigned cpu);
 #ifdef CONFIG_HOTPLUG_CPU
-extern void unregister_cpu(struct cpu *, struct node *);
+extern void unregister_cpu(struct cpu *cpu);
 #endif
 struct notifier_block;
 
 
 extern void unregister_node(struct node *node);
 extern int register_one_node(int nid);
 extern void unregister_one_node(int nid);
+#ifdef CONFIG_NUMA
+extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
+extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
+#else
+static inline int register_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       return 0;
+}
+static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
+{
+       return 0;
+}
+#endif
 
 #define to_node(sys_device) container_of(sys_device, struct node, sysdev)