Merge branch 'processor-procfs-2.6.32' into release
[sfrench/cifs-2.6.git] / drivers / acpi / processor_core.c
index 2cc4b3033872979bd7a1fbeeae055ca077aba227..c2d4d6e0936469a8ef5e80a11dd36a99d7be761e 100644 (file)
@@ -59,6 +59,8 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/processor.h>
 
+#define PREFIX "ACPI: "
+
 #define ACPI_PROCESSOR_CLASS           "processor"
 #define ACPI_PROCESSOR_DEVICE_NAME     "Processor"
 #define ACPI_PROCESSOR_FILE_INFO       "info"
@@ -79,9 +81,10 @@ MODULE_DESCRIPTION("ACPI Processor Driver");
 MODULE_LICENSE("GPL");
 
 static int acpi_processor_add(struct acpi_device *device);
-static int acpi_processor_start(struct acpi_device *device);
 static int acpi_processor_remove(struct acpi_device *device, int type);
+#ifdef CONFIG_ACPI_PROCFS
 static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
+#endif
 static void acpi_processor_notify(struct acpi_device *device, u32 event);
 static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
 static int acpi_processor_handle_eject(struct acpi_processor *pr);
@@ -101,7 +104,6 @@ static struct acpi_driver acpi_processor_driver = {
        .ops = {
                .add = acpi_processor_add,
                .remove = acpi_processor_remove,
-               .start = acpi_processor_start,
                .suspend = acpi_processor_suspend,
                .resume = acpi_processor_resume,
                .notify = acpi_processor_notify,
@@ -110,7 +112,7 @@ static struct acpi_driver acpi_processor_driver = {
 
 #define INSTALL_NOTIFY_HANDLER         1
 #define UNINSTALL_NOTIFY_HANDLER       2
-
+#ifdef CONFIG_ACPI_PROCFS
 static const struct file_operations acpi_processor_info_fops = {
        .owner = THIS_MODULE,
        .open = acpi_processor_info_open_fs,
@@ -118,6 +120,7 @@ static const struct file_operations acpi_processor_info_fops = {
        .llseek = seq_lseek,
        .release = single_release,
 };
+#endif
 
 DEFINE_PER_CPU(struct acpi_processor *, processors);
 struct acpi_processor_errata errata __read_mostly;
@@ -316,6 +319,7 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr)
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ACPI_PROCFS
 static struct proc_dir_entry *acpi_processor_dir = NULL;
 
 static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
@@ -388,7 +392,6 @@ static int acpi_processor_add_fs(struct acpi_device *device)
                return -EIO;
        return 0;
 }
-
 static int acpi_processor_remove_fs(struct acpi_device *device)
 {
 
@@ -405,6 +408,16 @@ static int acpi_processor_remove_fs(struct acpi_device *device)
 
        return 0;
 }
+#else
+static inline int acpi_processor_add_fs(struct acpi_device *device)
+{
+       return 0;
+}
+static inline int acpi_processor_remove_fs(struct acpi_device *device)
+{
+       return 0;
+}
+#endif
 
 /* Use the acpiid in MADT to map cpus in case of SMP */
 
@@ -698,92 +711,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
 
 static DEFINE_PER_CPU(void *, processor_device_array);
 
-static int __cpuinit acpi_processor_start(struct acpi_device *device)
-{
-       int result = 0;
-       struct acpi_processor *pr;
-       struct sys_device *sysdev;
-
-       pr = acpi_driver_data(device);
-
-       result = acpi_processor_get_info(device);
-       if (result) {
-               /* Processor is physically not present */
-               return 0;
-       }
-
-       BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
-
-       /*
-        * Buggy BIOS check
-        * ACPI id of processors can be reported wrongly by the BIOS.
-        * Don't trust it blindly
-        */
-       if (per_cpu(processor_device_array, pr->id) != NULL &&
-           per_cpu(processor_device_array, pr->id) != device) {
-               printk(KERN_WARNING "BIOS reported wrong ACPI id "
-                       "for the processor\n");
-               return -ENODEV;
-       }
-       per_cpu(processor_device_array, pr->id) = device;
-
-       per_cpu(processors, pr->id) = pr;
-
-       result = acpi_processor_add_fs(device);
-       if (result)
-               goto end;
-
-       sysdev = get_cpu_sysdev(pr->id);
-       if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
-               return -EFAULT;
-
-       /* _PDC call should be done before doing anything else (if reqd.). */
-       arch_acpi_processor_init_pdc(pr);
-       acpi_processor_set_pdc(pr);
-       arch_acpi_processor_cleanup_pdc(pr);
-
-#ifdef CONFIG_CPU_FREQ
-       acpi_processor_ppc_has_changed(pr);
-#endif
-       acpi_processor_get_throttling_info(pr);
-       acpi_processor_get_limit_info(pr);
-
-
-       acpi_processor_power_init(pr, device);
-
-       pr->cdev = thermal_cooling_device_register("Processor", device,
-                                               &processor_cooling_ops);
-       if (IS_ERR(pr->cdev)) {
-               result = PTR_ERR(pr->cdev);
-               goto end;
-       }
-
-       dev_info(&device->dev, "registered as cooling_device%d\n",
-                pr->cdev->id);
-
-       result = sysfs_create_link(&device->dev.kobj,
-                                  &pr->cdev->device.kobj,
-                                  "thermal_cooling");
-       if (result)
-               printk(KERN_ERR PREFIX "Create sysfs link\n");
-       result = sysfs_create_link(&pr->cdev->device.kobj,
-                                  &device->dev.kobj,
-                                  "device");
-       if (result)
-               printk(KERN_ERR PREFIX "Create sysfs link\n");
-
-       if (pr->flags.throttling) {
-               printk(KERN_INFO PREFIX "%s [%s] (supports",
-                      acpi_device_name(device), acpi_device_bid(device));
-               printk(" %d throttling states", pr->throttling.state_count);
-               printk(")\n");
-       }
-
-      end:
-
-       return result;
-}
-
 static void acpi_processor_notify(struct acpi_device *device, u32 event)
 {
        struct acpi_processor *pr = acpi_driver_data(device);
@@ -846,10 +773,8 @@ static struct notifier_block acpi_cpu_notifier =
 static int acpi_processor_add(struct acpi_device *device)
 {
        struct acpi_processor *pr = NULL;
-
-
-       if (!device)
-               return -EINVAL;
+       int result = 0;
+       struct sys_device *sysdev;
 
        pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
        if (!pr)
@@ -865,7 +790,100 @@ static int acpi_processor_add(struct acpi_device *device)
        strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
        device->driver_data = pr;
 
+       result = acpi_processor_get_info(device);
+       if (result) {
+               /* Processor is physically not present */
+               return 0;
+       }
+
+       BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+
+       /*
+        * Buggy BIOS check
+        * ACPI id of processors can be reported wrongly by the BIOS.
+        * Don't trust it blindly
+        */
+       if (per_cpu(processor_device_array, pr->id) != NULL &&
+           per_cpu(processor_device_array, pr->id) != device) {
+               printk(KERN_WARNING "BIOS reported wrong ACPI id "
+                       "for the processor\n");
+               result = -ENODEV;
+               goto err_free_cpumask;
+       }
+       per_cpu(processor_device_array, pr->id) = device;
+
+       per_cpu(processors, pr->id) = pr;
+
+       result = acpi_processor_add_fs(device);
+       if (result)
+               goto err_free_cpumask;
+
+       sysdev = get_cpu_sysdev(pr->id);
+       if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
+               result = -EFAULT;
+               goto err_remove_fs;
+       }
+
+       /* _PDC call should be done before doing anything else (if reqd.). */
+       arch_acpi_processor_init_pdc(pr);
+       acpi_processor_set_pdc(pr);
+       arch_acpi_processor_cleanup_pdc(pr);
+
+#ifdef CONFIG_CPU_FREQ
+       acpi_processor_ppc_has_changed(pr);
+#endif
+       acpi_processor_get_throttling_info(pr);
+       acpi_processor_get_limit_info(pr);
+
+
+       acpi_processor_power_init(pr, device);
+
+       pr->cdev = thermal_cooling_device_register("Processor", device,
+                                               &processor_cooling_ops);
+       if (IS_ERR(pr->cdev)) {
+               result = PTR_ERR(pr->cdev);
+               goto err_power_exit;
+       }
+
+       dev_info(&device->dev, "registered as cooling_device%d\n",
+                pr->cdev->id);
+
+       result = sysfs_create_link(&device->dev.kobj,
+                                  &pr->cdev->device.kobj,
+                                  "thermal_cooling");
+       if (result) {
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
+               goto err_thermal_unregister;
+       }
+       result = sysfs_create_link(&pr->cdev->device.kobj,
+                                  &device->dev.kobj,
+                                  "device");
+       if (result) {
+               printk(KERN_ERR PREFIX "Create sysfs link\n");
+               goto err_remove_sysfs;
+       }
+
+       if (pr->flags.throttling) {
+               printk(KERN_INFO PREFIX "%s [%s] (supports",
+                      acpi_device_name(device), acpi_device_bid(device));
+               printk(" %d throttling states", pr->throttling.state_count);
+               printk(")\n");
+       }
+
        return 0;
+
+err_remove_sysfs:
+       sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
+err_thermal_unregister:
+       thermal_cooling_device_unregister(pr->cdev);
+err_power_exit:
+       acpi_processor_power_exit(pr, device);
+err_remove_fs:
+       acpi_processor_remove_fs(device);
+err_free_cpumask:
+       free_cpumask_var(pr->throttling.shared_cpu_map);
+
+       return result;
 }
 
 static int acpi_processor_remove(struct acpi_device *device, int type)
@@ -942,7 +960,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
 {
        acpi_handle phandle;
        struct acpi_device *pdev;
-       struct acpi_processor *pr;
 
 
        if (acpi_get_parent(handle, &phandle)) {
@@ -957,15 +974,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
                return -ENODEV;
        }
 
-       acpi_bus_start(*device);
-
-       pr = acpi_driver_data(*device);
-       if (!pr)
-               return -ENODEV;
-
-       if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) {
-               kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE);
-       }
        return 0;
 }
 
@@ -995,25 +1003,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
                                            "Unable to add the device\n");
                        break;
                }
-
-               pr = acpi_driver_data(device);
-               if (!pr) {
-                       printk(KERN_ERR PREFIX "Driver data is NULL\n");
-                       break;
-               }
-
-               if (pr->id >= 0 && (pr->id < nr_cpu_ids)) {
-                       kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
-                       break;
-               }
-
-               result = acpi_processor_start(device);
-               if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) {
-                       kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
-               } else {
-                       printk(KERN_ERR PREFIX "Device [%s] failed to start\n",
-                                   acpi_device_bid(device));
-               }
                break;
        case ACPI_NOTIFY_EJECT_REQUEST:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -1030,9 +1019,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
                                    "Driver data is NULL, dropping EJECT\n");
                        return;
                }
-
-               if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id)))
-                       kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
                break;
        default:
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -1161,11 +1147,11 @@ static int __init acpi_processor_init(void)
                                (struct acpi_table_header **)&madt)))
                madt = NULL;
 #endif
-
+#ifdef CONFIG_ACPI_PROCFS
        acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
        if (!acpi_processor_dir)
                return -ENOMEM;
-
+#endif
        /*
         * Check whether the system is DMI table. If yes, OSPM
         * should not use mwait for CPU-states.
@@ -1193,7 +1179,9 @@ out_cpuidle:
        cpuidle_unregister_driver(&acpi_idle_driver);
 
 out_proc:
+#ifdef CONFIG_ACPI_PROCFS
        remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+#endif
 
        return result;
 }
@@ -1213,7 +1201,9 @@ static void __exit acpi_processor_exit(void)
 
        cpuidle_unregister_driver(&acpi_idle_driver);
 
+#ifdef CONFIG_ACPI_PROCFS
        remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+#endif
 
        return;
 }