diff options
Diffstat (limited to 'drivers/acpi/processor_core.c')
| -rw-r--r-- | drivers/acpi/processor_core.c | 246 |
1 files changed, 118 insertions, 128 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 2cc4b3033872..c2d4d6e09364 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
| @@ -59,6 +59,8 @@ | |||
| 59 | #include <acpi/acpi_drivers.h> | 59 | #include <acpi/acpi_drivers.h> |
| 60 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
| 61 | 61 | ||
| 62 | #define PREFIX "ACPI: " | ||
| 63 | |||
| 62 | #define ACPI_PROCESSOR_CLASS "processor" | 64 | #define ACPI_PROCESSOR_CLASS "processor" |
| 63 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" | 65 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" |
| 64 | #define ACPI_PROCESSOR_FILE_INFO "info" | 66 | #define ACPI_PROCESSOR_FILE_INFO "info" |
| @@ -79,9 +81,10 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); | |||
| 79 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
| 80 | 82 | ||
| 81 | static int acpi_processor_add(struct acpi_device *device); | 83 | static int acpi_processor_add(struct acpi_device *device); |
| 82 | static int acpi_processor_start(struct acpi_device *device); | ||
| 83 | static int acpi_processor_remove(struct acpi_device *device, int type); | 84 | static int acpi_processor_remove(struct acpi_device *device, int type); |
| 85 | #ifdef CONFIG_ACPI_PROCFS | ||
| 84 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | 86 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); |
| 87 | #endif | ||
| 85 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | 88 | static void acpi_processor_notify(struct acpi_device *device, u32 event); |
| 86 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 89 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
| 87 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 90 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
| @@ -101,7 +104,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
| 101 | .ops = { | 104 | .ops = { |
| 102 | .add = acpi_processor_add, | 105 | .add = acpi_processor_add, |
| 103 | .remove = acpi_processor_remove, | 106 | .remove = acpi_processor_remove, |
| 104 | .start = acpi_processor_start, | ||
| 105 | .suspend = acpi_processor_suspend, | 107 | .suspend = acpi_processor_suspend, |
| 106 | .resume = acpi_processor_resume, | 108 | .resume = acpi_processor_resume, |
| 107 | .notify = acpi_processor_notify, | 109 | .notify = acpi_processor_notify, |
| @@ -110,7 +112,7 @@ static struct acpi_driver acpi_processor_driver = { | |||
| 110 | 112 | ||
| 111 | #define INSTALL_NOTIFY_HANDLER 1 | 113 | #define INSTALL_NOTIFY_HANDLER 1 |
| 112 | #define UNINSTALL_NOTIFY_HANDLER 2 | 114 | #define UNINSTALL_NOTIFY_HANDLER 2 |
| 113 | 115 | #ifdef CONFIG_ACPI_PROCFS | |
| 114 | static const struct file_operations acpi_processor_info_fops = { | 116 | static const struct file_operations acpi_processor_info_fops = { |
| 115 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
| 116 | .open = acpi_processor_info_open_fs, | 118 | .open = acpi_processor_info_open_fs, |
| @@ -118,6 +120,7 @@ static const struct file_operations acpi_processor_info_fops = { | |||
| 118 | .llseek = seq_lseek, | 120 | .llseek = seq_lseek, |
| 119 | .release = single_release, | 121 | .release = single_release, |
| 120 | }; | 122 | }; |
| 123 | #endif | ||
| 121 | 124 | ||
| 122 | DEFINE_PER_CPU(struct acpi_processor *, processors); | 125 | DEFINE_PER_CPU(struct acpi_processor *, processors); |
| 123 | struct acpi_processor_errata errata __read_mostly; | 126 | struct acpi_processor_errata errata __read_mostly; |
| @@ -316,6 +319,7 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr) | |||
| 316 | FS Interface (/proc) | 319 | FS Interface (/proc) |
| 317 | -------------------------------------------------------------------------- */ | 320 | -------------------------------------------------------------------------- */ |
| 318 | 321 | ||
| 322 | #ifdef CONFIG_ACPI_PROCFS | ||
| 319 | static struct proc_dir_entry *acpi_processor_dir = NULL; | 323 | static struct proc_dir_entry *acpi_processor_dir = NULL; |
| 320 | 324 | ||
| 321 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | 325 | 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) | |||
| 388 | return -EIO; | 392 | return -EIO; |
| 389 | return 0; | 393 | return 0; |
| 390 | } | 394 | } |
| 391 | |||
| 392 | static int acpi_processor_remove_fs(struct acpi_device *device) | 395 | static int acpi_processor_remove_fs(struct acpi_device *device) |
| 393 | { | 396 | { |
| 394 | 397 | ||
| @@ -405,6 +408,16 @@ static int acpi_processor_remove_fs(struct acpi_device *device) | |||
| 405 | 408 | ||
| 406 | return 0; | 409 | return 0; |
| 407 | } | 410 | } |
| 411 | #else | ||
| 412 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
| 413 | { | ||
| 414 | return 0; | ||
| 415 | } | ||
| 416 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
| 417 | { | ||
| 418 | return 0; | ||
| 419 | } | ||
| 420 | #endif | ||
| 408 | 421 | ||
| 409 | /* Use the acpiid in MADT to map cpus in case of SMP */ | 422 | /* Use the acpiid in MADT to map cpus in case of SMP */ |
| 410 | 423 | ||
| @@ -698,92 +711,6 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
| 698 | 711 | ||
| 699 | static DEFINE_PER_CPU(void *, processor_device_array); | 712 | static DEFINE_PER_CPU(void *, processor_device_array); |
| 700 | 713 | ||
| 701 | static int __cpuinit acpi_processor_start(struct acpi_device *device) | ||
| 702 | { | ||
| 703 | int result = 0; | ||
| 704 | struct acpi_processor *pr; | ||
| 705 | struct sys_device *sysdev; | ||
| 706 | |||
| 707 | pr = acpi_driver_data(device); | ||
| 708 | |||
| 709 | result = acpi_processor_get_info(device); | ||
| 710 | if (result) { | ||
| 711 | /* Processor is physically not present */ | ||
| 712 | return 0; | ||
| 713 | } | ||
| 714 | |||
| 715 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
| 716 | |||
| 717 | /* | ||
| 718 | * Buggy BIOS check | ||
| 719 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
| 720 | * Don't trust it blindly | ||
| 721 | */ | ||
| 722 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
| 723 | per_cpu(processor_device_array, pr->id) != device) { | ||
| 724 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
| 725 | "for the processor\n"); | ||
| 726 | return -ENODEV; | ||
| 727 | } | ||
| 728 | per_cpu(processor_device_array, pr->id) = device; | ||
| 729 | |||
| 730 | per_cpu(processors, pr->id) = pr; | ||
| 731 | |||
| 732 | result = acpi_processor_add_fs(device); | ||
| 733 | if (result) | ||
| 734 | goto end; | ||
| 735 | |||
| 736 | sysdev = get_cpu_sysdev(pr->id); | ||
| 737 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) | ||
| 738 | return -EFAULT; | ||
| 739 | |||
| 740 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
| 741 | arch_acpi_processor_init_pdc(pr); | ||
| 742 | acpi_processor_set_pdc(pr); | ||
| 743 | arch_acpi_processor_cleanup_pdc(pr); | ||
| 744 | |||
| 745 | #ifdef CONFIG_CPU_FREQ | ||
| 746 | acpi_processor_ppc_has_changed(pr); | ||
| 747 | #endif | ||
| 748 | acpi_processor_get_throttling_info(pr); | ||
| 749 | acpi_processor_get_limit_info(pr); | ||
| 750 | |||
| 751 | |||
| 752 | acpi_processor_power_init(pr, device); | ||
| 753 | |||
| 754 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
| 755 | &processor_cooling_ops); | ||
| 756 | if (IS_ERR(pr->cdev)) { | ||
| 757 | result = PTR_ERR(pr->cdev); | ||
| 758 | goto end; | ||
| 759 | } | ||
| 760 | |||
| 761 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
| 762 | pr->cdev->id); | ||
| 763 | |||
| 764 | result = sysfs_create_link(&device->dev.kobj, | ||
| 765 | &pr->cdev->device.kobj, | ||
| 766 | "thermal_cooling"); | ||
| 767 | if (result) | ||
| 768 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
| 769 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
| 770 | &device->dev.kobj, | ||
| 771 | "device"); | ||
| 772 | if (result) | ||
| 773 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
| 774 | |||
| 775 | if (pr->flags.throttling) { | ||
| 776 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
| 777 | acpi_device_name(device), acpi_device_bid(device)); | ||
| 778 | printk(" %d throttling states", pr->throttling.state_count); | ||
| 779 | printk(")\n"); | ||
| 780 | } | ||
| 781 | |||
| 782 | end: | ||
| 783 | |||
| 784 | return result; | ||
| 785 | } | ||
| 786 | |||
| 787 | static void acpi_processor_notify(struct acpi_device *device, u32 event) | 714 | static void acpi_processor_notify(struct acpi_device *device, u32 event) |
| 788 | { | 715 | { |
| 789 | struct acpi_processor *pr = acpi_driver_data(device); | 716 | struct acpi_processor *pr = acpi_driver_data(device); |
| @@ -846,10 +773,8 @@ static struct notifier_block acpi_cpu_notifier = | |||
| 846 | static int acpi_processor_add(struct acpi_device *device) | 773 | static int acpi_processor_add(struct acpi_device *device) |
| 847 | { | 774 | { |
| 848 | struct acpi_processor *pr = NULL; | 775 | struct acpi_processor *pr = NULL; |
| 849 | 776 | int result = 0; | |
| 850 | 777 | struct sys_device *sysdev; | |
| 851 | if (!device) | ||
| 852 | return -EINVAL; | ||
| 853 | 778 | ||
| 854 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | 779 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); |
| 855 | if (!pr) | 780 | if (!pr) |
| @@ -865,7 +790,100 @@ static int acpi_processor_add(struct acpi_device *device) | |||
| 865 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | 790 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); |
| 866 | device->driver_data = pr; | 791 | device->driver_data = pr; |
| 867 | 792 | ||
| 793 | result = acpi_processor_get_info(device); | ||
| 794 | if (result) { | ||
| 795 | /* Processor is physically not present */ | ||
| 796 | return 0; | ||
| 797 | } | ||
| 798 | |||
| 799 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
| 800 | |||
| 801 | /* | ||
| 802 | * Buggy BIOS check | ||
| 803 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
| 804 | * Don't trust it blindly | ||
| 805 | */ | ||
| 806 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
| 807 | per_cpu(processor_device_array, pr->id) != device) { | ||
| 808 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
| 809 | "for the processor\n"); | ||
| 810 | result = -ENODEV; | ||
| 811 | goto err_free_cpumask; | ||
| 812 | } | ||
| 813 | per_cpu(processor_device_array, pr->id) = device; | ||
| 814 | |||
| 815 | per_cpu(processors, pr->id) = pr; | ||
| 816 | |||
| 817 | result = acpi_processor_add_fs(device); | ||
| 818 | if (result) | ||
| 819 | goto err_free_cpumask; | ||
| 820 | |||
| 821 | sysdev = get_cpu_sysdev(pr->id); | ||
| 822 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { | ||
| 823 | result = -EFAULT; | ||
| 824 | goto err_remove_fs; | ||
| 825 | } | ||
| 826 | |||
| 827 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
| 828 | arch_acpi_processor_init_pdc(pr); | ||
| 829 | acpi_processor_set_pdc(pr); | ||
| 830 | arch_acpi_processor_cleanup_pdc(pr); | ||
| 831 | |||
| 832 | #ifdef CONFIG_CPU_FREQ | ||
| 833 | acpi_processor_ppc_has_changed(pr); | ||
| 834 | #endif | ||
| 835 | acpi_processor_get_throttling_info(pr); | ||
| 836 | acpi_processor_get_limit_info(pr); | ||
| 837 | |||
| 838 | |||
| 839 | acpi_processor_power_init(pr, device); | ||
| 840 | |||
| 841 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
| 842 | &processor_cooling_ops); | ||
| 843 | if (IS_ERR(pr->cdev)) { | ||
| 844 | result = PTR_ERR(pr->cdev); | ||
| 845 | goto err_power_exit; | ||
| 846 | } | ||
| 847 | |||
| 848 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
| 849 | pr->cdev->id); | ||
| 850 | |||
| 851 | result = sysfs_create_link(&device->dev.kobj, | ||
| 852 | &pr->cdev->device.kobj, | ||
| 853 | "thermal_cooling"); | ||
| 854 | if (result) { | ||
| 855 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
| 856 | goto err_thermal_unregister; | ||
| 857 | } | ||
| 858 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
| 859 | &device->dev.kobj, | ||
| 860 | "device"); | ||
| 861 | if (result) { | ||
| 862 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
| 863 | goto err_remove_sysfs; | ||
| 864 | } | ||
| 865 | |||
| 866 | if (pr->flags.throttling) { | ||
| 867 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
| 868 | acpi_device_name(device), acpi_device_bid(device)); | ||
| 869 | printk(" %d throttling states", pr->throttling.state_count); | ||
| 870 | printk(")\n"); | ||
| 871 | } | ||
| 872 | |||
| 868 | return 0; | 873 | return 0; |
| 874 | |||
| 875 | err_remove_sysfs: | ||
| 876 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
| 877 | err_thermal_unregister: | ||
| 878 | thermal_cooling_device_unregister(pr->cdev); | ||
| 879 | err_power_exit: | ||
| 880 | acpi_processor_power_exit(pr, device); | ||
| 881 | err_remove_fs: | ||
| 882 | acpi_processor_remove_fs(device); | ||
| 883 | err_free_cpumask: | ||
| 884 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
| 885 | |||
| 886 | return result; | ||
| 869 | } | 887 | } |
| 870 | 888 | ||
| 871 | static int acpi_processor_remove(struct acpi_device *device, int type) | 889 | 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) | |||
| 942 | { | 960 | { |
| 943 | acpi_handle phandle; | 961 | acpi_handle phandle; |
| 944 | struct acpi_device *pdev; | 962 | struct acpi_device *pdev; |
| 945 | struct acpi_processor *pr; | ||
| 946 | 963 | ||
| 947 | 964 | ||
| 948 | if (acpi_get_parent(handle, &phandle)) { | 965 | if (acpi_get_parent(handle, &phandle)) { |
| @@ -957,15 +974,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
| 957 | return -ENODEV; | 974 | return -ENODEV; |
| 958 | } | 975 | } |
| 959 | 976 | ||
| 960 | acpi_bus_start(*device); | ||
| 961 | |||
| 962 | pr = acpi_driver_data(*device); | ||
| 963 | if (!pr) | ||
| 964 | return -ENODEV; | ||
| 965 | |||
| 966 | if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { | ||
| 967 | kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); | ||
| 968 | } | ||
| 969 | return 0; | 977 | return 0; |
| 970 | } | 978 | } |
| 971 | 979 | ||
| @@ -995,25 +1003,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
| 995 | "Unable to add the device\n"); | 1003 | "Unable to add the device\n"); |
| 996 | break; | 1004 | break; |
| 997 | } | 1005 | } |
| 998 | |||
| 999 | pr = acpi_driver_data(device); | ||
| 1000 | if (!pr) { | ||
| 1001 | printk(KERN_ERR PREFIX "Driver data is NULL\n"); | ||
| 1002 | break; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { | ||
| 1006 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
| 1007 | break; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | result = acpi_processor_start(device); | ||
| 1011 | if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { | ||
| 1012 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); | ||
| 1013 | } else { | ||
| 1014 | printk(KERN_ERR PREFIX "Device [%s] failed to start\n", | ||
| 1015 | acpi_device_bid(device)); | ||
| 1016 | } | ||
| 1017 | break; | 1006 | break; |
| 1018 | case ACPI_NOTIFY_EJECT_REQUEST: | 1007 | case ACPI_NOTIFY_EJECT_REQUEST: |
| 1019 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1008 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| @@ -1030,9 +1019,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
| 1030 | "Driver data is NULL, dropping EJECT\n"); | 1019 | "Driver data is NULL, dropping EJECT\n"); |
| 1031 | return; | 1020 | return; |
| 1032 | } | 1021 | } |
| 1033 | |||
| 1034 | if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) | ||
| 1035 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
| 1036 | break; | 1022 | break; |
| 1037 | default: | 1023 | default: |
| 1038 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1024 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| @@ -1161,11 +1147,11 @@ static int __init acpi_processor_init(void) | |||
| 1161 | (struct acpi_table_header **)&madt))) | 1147 | (struct acpi_table_header **)&madt))) |
| 1162 | madt = NULL; | 1148 | madt = NULL; |
| 1163 | #endif | 1149 | #endif |
| 1164 | 1150 | #ifdef CONFIG_ACPI_PROCFS | |
| 1165 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1151 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
| 1166 | if (!acpi_processor_dir) | 1152 | if (!acpi_processor_dir) |
| 1167 | return -ENOMEM; | 1153 | return -ENOMEM; |
| 1168 | 1154 | #endif | |
| 1169 | /* | 1155 | /* |
| 1170 | * Check whether the system is DMI table. If yes, OSPM | 1156 | * Check whether the system is DMI table. If yes, OSPM |
| 1171 | * should not use mwait for CPU-states. | 1157 | * should not use mwait for CPU-states. |
| @@ -1193,7 +1179,9 @@ out_cpuidle: | |||
| 1193 | cpuidle_unregister_driver(&acpi_idle_driver); | 1179 | cpuidle_unregister_driver(&acpi_idle_driver); |
| 1194 | 1180 | ||
| 1195 | out_proc: | 1181 | out_proc: |
| 1182 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1196 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1183 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
| 1184 | #endif | ||
| 1197 | 1185 | ||
| 1198 | return result; | 1186 | return result; |
| 1199 | } | 1187 | } |
| @@ -1213,7 +1201,9 @@ static void __exit acpi_processor_exit(void) | |||
| 1213 | 1201 | ||
| 1214 | cpuidle_unregister_driver(&acpi_idle_driver); | 1202 | cpuidle_unregister_driver(&acpi_idle_driver); |
| 1215 | 1203 | ||
| 1204 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1216 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1205 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
| 1206 | #endif | ||
| 1217 | 1207 | ||
| 1218 | return; | 1208 | return; |
| 1219 | } | 1209 | } |
