|
@@ -81,7 +81,6 @@ MODULE_DESCRIPTION("ACPI Processor Driver");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
|
|
static int acpi_processor_add(struct acpi_device *device);
|
|
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);
|
|
static int acpi_processor_remove(struct acpi_device *device, int type);
|
|
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
|
|
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
|
|
static void acpi_processor_notify(struct acpi_device *device, u32 event);
|
|
static void acpi_processor_notify(struct acpi_device *device, u32 event);
|
|
@@ -103,7 +102,6 @@ static struct acpi_driver acpi_processor_driver = {
|
|
.ops = {
|
|
.ops = {
|
|
.add = acpi_processor_add,
|
|
.add = acpi_processor_add,
|
|
.remove = acpi_processor_remove,
|
|
.remove = acpi_processor_remove,
|
|
- .start = acpi_processor_start,
|
|
|
|
.suspend = acpi_processor_suspend,
|
|
.suspend = acpi_processor_suspend,
|
|
.resume = acpi_processor_resume,
|
|
.resume = acpi_processor_resume,
|
|
.notify = acpi_processor_notify,
|
|
.notify = acpi_processor_notify,
|
|
@@ -700,92 +698,6 @@ static int acpi_processor_get_info(struct acpi_device *device)
|
|
|
|
|
|
static DEFINE_PER_CPU(void *, processor_device_array);
|
|
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)
|
|
static void acpi_processor_notify(struct acpi_device *device, u32 event)
|
|
{
|
|
{
|
|
struct acpi_processor *pr = acpi_driver_data(device);
|
|
struct acpi_processor *pr = acpi_driver_data(device);
|
|
@@ -848,10 +760,8 @@ static struct notifier_block acpi_cpu_notifier =
|
|
static int acpi_processor_add(struct acpi_device *device)
|
|
static int acpi_processor_add(struct acpi_device *device)
|
|
{
|
|
{
|
|
struct acpi_processor *pr = NULL;
|
|
struct acpi_processor *pr = NULL;
|
|
-
|
|
|
|
-
|
|
|
|
- if (!device)
|
|
|
|
- return -EINVAL;
|
|
|
|
|
|
+ int result = 0;
|
|
|
|
+ struct sys_device *sysdev;
|
|
|
|
|
|
pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
|
|
pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
|
|
if (!pr)
|
|
if (!pr)
|
|
@@ -867,7 +777,100 @@ static int acpi_processor_add(struct acpi_device *device)
|
|
strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
|
|
strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
|
|
device->driver_data = pr;
|
|
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;
|
|
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)
|
|
static int acpi_processor_remove(struct acpi_device *device, int type)
|
|
@@ -944,7 +947,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
|
|
{
|
|
{
|
|
acpi_handle phandle;
|
|
acpi_handle phandle;
|
|
struct acpi_device *pdev;
|
|
struct acpi_device *pdev;
|
|
- struct acpi_processor *pr;
|
|
|
|
|
|
|
|
|
|
|
|
if (acpi_get_parent(handle, &phandle)) {
|
|
if (acpi_get_parent(handle, &phandle)) {
|
|
@@ -959,15 +961,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
|
|
return -ENODEV;
|
|
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;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -997,25 +990,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
|
|
"Unable to add the device\n");
|
|
"Unable to add the device\n");
|
|
break;
|
|
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;
|
|
break;
|
|
case ACPI_NOTIFY_EJECT_REQUEST:
|
|
case ACPI_NOTIFY_EJECT_REQUEST:
|
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
@@ -1032,9 +1006,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
|
|
"Driver data is NULL, dropping EJECT\n");
|
|
"Driver data is NULL, dropping EJECT\n");
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
-
|
|
|
|
- if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id)))
|
|
|
|
- kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
|
|
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|