0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/init.h>
0017 #include <linux/cpufreq.h>
0018 #include <linux/cpu.h>
0019 #include <linux/cpuidle.h>
0020 #include <linux/slab.h>
0021 #include <linux/acpi.h>
0022
0023 #include <acpi/processor.h>
0024
0025 #include "internal.h"
0026
0027 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
0028 #define ACPI_PROCESSOR_NOTIFY_POWER 0x81
0029 #define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
0030
0031 MODULE_AUTHOR("Paul Diefenbaugh");
0032 MODULE_DESCRIPTION("ACPI Processor Driver");
0033 MODULE_LICENSE("GPL");
0034
0035 static int acpi_processor_start(struct device *dev);
0036 static int acpi_processor_stop(struct device *dev);
0037
0038 static const struct acpi_device_id processor_device_ids[] = {
0039 {ACPI_PROCESSOR_OBJECT_HID, 0},
0040 {ACPI_PROCESSOR_DEVICE_HID, 0},
0041 {"", 0},
0042 };
0043 MODULE_DEVICE_TABLE(acpi, processor_device_ids);
0044
0045 static struct device_driver acpi_processor_driver = {
0046 .name = "processor",
0047 .bus = &cpu_subsys,
0048 .acpi_match_table = processor_device_ids,
0049 .probe = acpi_processor_start,
0050 .remove = acpi_processor_stop,
0051 };
0052
0053 static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
0054 {
0055 struct acpi_device *device = data;
0056 struct acpi_processor *pr;
0057 int saved;
0058
0059 if (device->handle != handle)
0060 return;
0061
0062 pr = acpi_driver_data(device);
0063 if (!pr)
0064 return;
0065
0066 switch (event) {
0067 case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
0068 saved = pr->performance_platform_limit;
0069 acpi_processor_ppc_has_changed(pr, 1);
0070 if (saved == pr->performance_platform_limit)
0071 break;
0072 acpi_bus_generate_netlink_event(device->pnp.device_class,
0073 dev_name(&device->dev), event,
0074 pr->performance_platform_limit);
0075 break;
0076 case ACPI_PROCESSOR_NOTIFY_POWER:
0077 acpi_processor_power_state_has_changed(pr);
0078 acpi_bus_generate_netlink_event(device->pnp.device_class,
0079 dev_name(&device->dev), event, 0);
0080 break;
0081 case ACPI_PROCESSOR_NOTIFY_THROTTLING:
0082 acpi_processor_tstate_has_changed(pr);
0083 acpi_bus_generate_netlink_event(device->pnp.device_class,
0084 dev_name(&device->dev), event, 0);
0085 break;
0086 default:
0087 acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event);
0088 break;
0089 }
0090
0091 return;
0092 }
0093
0094 static int __acpi_processor_start(struct acpi_device *device);
0095
0096 static int acpi_soft_cpu_online(unsigned int cpu)
0097 {
0098 struct acpi_processor *pr = per_cpu(processors, cpu);
0099 struct acpi_device *device;
0100
0101 if (!pr)
0102 return 0;
0103
0104 device = acpi_fetch_acpi_dev(pr->handle);
0105 if (!device)
0106 return 0;
0107
0108
0109
0110
0111
0112 if (pr->flags.need_hotplug_init) {
0113 int ret;
0114
0115 pr_info("Will online and init hotplugged CPU: %d\n",
0116 pr->id);
0117 pr->flags.need_hotplug_init = 0;
0118 ret = __acpi_processor_start(device);
0119 WARN(ret, "Failed to start CPU: %d\n", pr->id);
0120 } else {
0121
0122 acpi_processor_ppc_has_changed(pr, 0);
0123 acpi_processor_hotplug(pr);
0124 acpi_processor_reevaluate_tstate(pr, false);
0125 acpi_processor_tstate_has_changed(pr);
0126 }
0127 return 0;
0128 }
0129
0130 static int acpi_soft_cpu_dead(unsigned int cpu)
0131 {
0132 struct acpi_processor *pr = per_cpu(processors, cpu);
0133
0134 if (!pr || !acpi_fetch_acpi_dev(pr->handle))
0135 return 0;
0136
0137 acpi_processor_reevaluate_tstate(pr, true);
0138 return 0;
0139 }
0140
0141 #ifdef CONFIG_ACPI_CPU_FREQ_PSS
0142 static void acpi_pss_perf_init(struct acpi_processor *pr)
0143 {
0144 acpi_processor_ppc_has_changed(pr, 0);
0145
0146 acpi_processor_get_throttling_info(pr);
0147
0148 if (pr->flags.throttling)
0149 pr->flags.limit = 1;
0150 }
0151 #else
0152 static inline void acpi_pss_perf_init(struct acpi_processor *pr) {}
0153 #endif
0154
0155 static int __acpi_processor_start(struct acpi_device *device)
0156 {
0157 struct acpi_processor *pr = acpi_driver_data(device);
0158 acpi_status status;
0159 int result = 0;
0160
0161 if (!pr)
0162 return -ENODEV;
0163
0164 if (pr->flags.need_hotplug_init)
0165 return 0;
0166
0167 result = acpi_cppc_processor_probe(pr);
0168 if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS))
0169 dev_dbg(&device->dev, "CPPC data invalid or not present\n");
0170
0171 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
0172 acpi_processor_power_init(pr);
0173
0174 acpi_pss_perf_init(pr);
0175
0176 result = acpi_processor_thermal_init(pr, device);
0177 if (result)
0178 goto err_power_exit;
0179
0180 status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
0181 acpi_processor_notify, device);
0182 if (ACPI_SUCCESS(status))
0183 return 0;
0184
0185 result = -ENODEV;
0186 acpi_processor_thermal_exit(pr, device);
0187
0188 err_power_exit:
0189 acpi_processor_power_exit(pr);
0190 return result;
0191 }
0192
0193 static int acpi_processor_start(struct device *dev)
0194 {
0195 struct acpi_device *device = ACPI_COMPANION(dev);
0196 int ret;
0197
0198 if (!device)
0199 return -ENODEV;
0200
0201
0202 cpu_hotplug_disable();
0203 ret = __acpi_processor_start(device);
0204 cpu_hotplug_enable();
0205 return ret;
0206 }
0207
0208 static int acpi_processor_stop(struct device *dev)
0209 {
0210 struct acpi_device *device = ACPI_COMPANION(dev);
0211 struct acpi_processor *pr;
0212
0213 if (!device)
0214 return 0;
0215
0216 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
0217 acpi_processor_notify);
0218
0219 pr = acpi_driver_data(device);
0220 if (!pr)
0221 return 0;
0222 acpi_processor_power_exit(pr);
0223
0224 acpi_cppc_processor_exit(pr);
0225
0226 acpi_processor_thermal_exit(pr, device);
0227
0228 return 0;
0229 }
0230
0231 bool acpi_processor_cpufreq_init;
0232
0233 static int acpi_processor_notifier(struct notifier_block *nb,
0234 unsigned long event, void *data)
0235 {
0236 struct cpufreq_policy *policy = data;
0237
0238 if (event == CPUFREQ_CREATE_POLICY) {
0239 acpi_thermal_cpufreq_init(policy);
0240 acpi_processor_ppc_init(policy);
0241 } else if (event == CPUFREQ_REMOVE_POLICY) {
0242 acpi_processor_ppc_exit(policy);
0243 acpi_thermal_cpufreq_exit(policy);
0244 }
0245
0246 return 0;
0247 }
0248
0249 static struct notifier_block acpi_processor_notifier_block = {
0250 .notifier_call = acpi_processor_notifier,
0251 };
0252
0253
0254
0255
0256
0257
0258 static enum cpuhp_state hp_online;
0259 static int __init acpi_processor_driver_init(void)
0260 {
0261 int result = 0;
0262
0263 if (acpi_disabled)
0264 return 0;
0265
0266 result = driver_register(&acpi_processor_driver);
0267 if (result < 0)
0268 return result;
0269
0270 result = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
0271 "acpi/cpu-drv:online",
0272 acpi_soft_cpu_online, NULL);
0273 if (result < 0)
0274 goto err;
0275 hp_online = result;
0276 cpuhp_setup_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD, "acpi/cpu-drv:dead",
0277 NULL, acpi_soft_cpu_dead);
0278
0279 if (!cpufreq_register_notifier(&acpi_processor_notifier_block,
0280 CPUFREQ_POLICY_NOTIFIER)) {
0281 acpi_processor_cpufreq_init = true;
0282 acpi_processor_ignore_ppc_init();
0283 }
0284
0285 acpi_processor_throttling_init();
0286 return 0;
0287 err:
0288 driver_unregister(&acpi_processor_driver);
0289 return result;
0290 }
0291
0292 static void __exit acpi_processor_driver_exit(void)
0293 {
0294 if (acpi_disabled)
0295 return;
0296
0297 if (acpi_processor_cpufreq_init) {
0298 cpufreq_unregister_notifier(&acpi_processor_notifier_block,
0299 CPUFREQ_POLICY_NOTIFIER);
0300 acpi_processor_cpufreq_init = false;
0301 }
0302
0303 cpuhp_remove_state_nocalls(hp_online);
0304 cpuhp_remove_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD);
0305 driver_unregister(&acpi_processor_driver);
0306 }
0307
0308 module_init(acpi_processor_driver_init);
0309 module_exit(acpi_processor_driver_exit);
0310
0311 MODULE_ALIAS("processor");