]> err.no Git - linux-2.6/blobdiff - drivers/base/cpu.c
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
[linux-2.6] / drivers / base / cpu.c
index 6ef3069b57107f2e12c5d2c7f238b77f5dacd97c..281d26784d251107bc6b158ba3ce5f5904a157fd 100644 (file)
@@ -9,13 +9,21 @@
 #include <linux/topology.h>
 #include <linux/device.h>
 
+#include "base.h"
 
 struct sysdev_class cpu_sysdev_class = {
        set_kset_name("cpu"),
 };
 EXPORT_SYMBOL(cpu_sysdev_class);
 
+static struct sys_device *cpu_sys_devices[NR_CPUS];
+
 #ifdef CONFIG_HOTPLUG_CPU
+int __attribute__((weak)) smp_prepare_cpu (int cpu)
+{
+       return 0;
+}
+
 static ssize_t show_online(struct sys_device *dev, char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
@@ -33,10 +41,14 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
        case '0':
                ret = cpu_down(cpu->sysdev.id);
                if (!ret)
-                       kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
+                       kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
                break;
        case '1':
-               ret = cpu_up(cpu->sysdev.id);
+               ret = smp_prepare_cpu(cpu->sysdev.id);
+               if (!ret)
+                       ret = cpu_up(cpu->sysdev.id);
+               if (!ret)
+                       kobject_uevent(&dev->kobj, KOBJ_ONLINE);
                break;
        default:
                ret = -EINVAL;
@@ -54,6 +66,7 @@ static void __devinit register_cpu_control(struct cpu *cpu)
 }
 void unregister_cpu(struct cpu *cpu, struct node *root)
 {
+       int logical_cpu = cpu->sysdev.id;
 
        if (root)
                sysfs_remove_link(&root->sysdev.kobj,
@@ -61,7 +74,7 @@ void unregister_cpu(struct cpu *cpu, struct node *root)
        sysdev_remove_file(&cpu->sysdev, &attr_online);
 
        sysdev_unregister(&cpu->sysdev);
-
+       cpu_sys_devices[logical_cpu] = NULL;
        return;
 }
 #else /* ... !CONFIG_HOTPLUG_CPU */
@@ -93,10 +106,19 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
                                          kobject_name(&cpu->sysdev.kobj));
        if (!error && !cpu->no_control)
                register_cpu_control(cpu);
+       if (!error)
+               cpu_sys_devices[num] = &cpu->sysdev;
        return error;
 }
 
-
+struct sys_device *get_cpu_sysdev(int cpu)
+{
+       if (cpu < NR_CPUS)
+               return cpu_sys_devices[cpu];
+       else
+               return NULL;
+}
+EXPORT_SYMBOL_GPL(get_cpu_sysdev);
 
 int __init cpu_dev_init(void)
 {