Blame view

drivers/acpi/processor_driver.c 8.51 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
ac212b698   Rafael J. Wysocki   ACPI / processor:...
2
   * processor_driver.c - ACPI Processor Driver
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
   *
   *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
   *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
   *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
   *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
   *  			- Added processor hotplug support
ac212b698   Rafael J. Wysocki   ACPI / processor:...
9
10
   *  Copyright (C) 2013, Intel Corporation
   *                      Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
16
17
18
19
20
21
22
23
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; either version 2 of the License, or (at
   *  your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful, but
   *  WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   *  General Public License for more details.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
28
29
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
  #include <linux/cpufreq.h>
  #include <linux/cpu.h>
4f86d3a8e   Len Brown   cpuidle: consolid...
32
  #include <linux/cpuidle.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
33
  #include <linux/slab.h>
47db4547f   Toshi Kani   ACPI: Update CPU ...
34
  #include <linux/acpi.h>
ac212b698   Rafael J. Wysocki   ACPI / processor:...
35

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
  #include <acpi/processor.h>
ac212b698   Rafael J. Wysocki   ACPI / processor:...
37
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
  #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
  #define ACPI_PROCESSOR_NOTIFY_POWER	0x81
01854e697   Luming Yu   ACPI: add ACPI 3....
40
  #define ACPI_PROCESSOR_NOTIFY_THROTTLING	0x82
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
  #define _COMPONENT		ACPI_PROCESSOR_COMPONENT
0131aa3dd   Alex Chiang   ACPI: processor: ...
43
  ACPI_MODULE_NAME("processor_driver");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

f52fd66d2   Len Brown   ACPI: clean up AC...
45
  MODULE_AUTHOR("Paul Diefenbaugh");
7cda93e00   Len Brown   ACPI: delete extr...
46
  MODULE_DESCRIPTION("ACPI Processor Driver");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47
  MODULE_LICENSE("GPL");
ac212b698   Rafael J. Wysocki   ACPI / processor:...
48
49
  static int acpi_processor_start(struct device *dev);
  static int acpi_processor_stop(struct device *dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50

1ba90e3a8   Thomas Renninger   ACPI: autoload mo...
51
  static const struct acpi_device_id processor_device_ids[] = {
ad93a765c   Myron Stowe   ACPI: Disambiguat...
52
  	{ACPI_PROCESSOR_OBJECT_HID, 0},
9f324bda9   Toshi Kani   ACPI: Add CPU hot...
53
  	{ACPI_PROCESSOR_DEVICE_HID, 0},
1ba90e3a8   Thomas Renninger   ACPI: autoload mo...
54
55
56
  	{"", 0},
  };
  MODULE_DEVICE_TABLE(acpi, processor_device_ids);
ac212b698   Rafael J. Wysocki   ACPI / processor:...
57
  static struct device_driver acpi_processor_driver = {
c2b6705b7   Len Brown   ACPI: fix acpi_dr...
58
  	.name = "processor",
ac212b698   Rafael J. Wysocki   ACPI / processor:...
59
60
61
62
  	.bus = &cpu_subsys,
  	.acpi_match_table = processor_device_ids,
  	.probe = acpi_processor_start,
  	.remove = acpi_processor_stop,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  };
ac212b698   Rafael J. Wysocki   ACPI / processor:...
64
  static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
  {
ac212b698   Rafael J. Wysocki   ACPI / processor:...
66
  	struct acpi_device *device = data;
b26e9286f   Myron Stowe   ACPI: Behave uniq...
67
  	struct acpi_processor *pr;
e790cc8bb   Alexey Starikovskiy   ACPI: EC: Workaro...
68
  	int saved;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69

ac212b698   Rafael J. Wysocki   ACPI / processor:...
70
71
72
73
  	if (device->handle != handle)
  		return;
  
  	pr = acpi_driver_data(device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  	if (!pr)
d550d98d3   Patrick Mochel   ACPI: delete trac...
75
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
  	switch (event) {
  	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
e790cc8bb   Alexey Starikovskiy   ACPI: EC: Workaro...
79
  		saved = pr->performance_platform_limit;
d81c45e1c   Zhao Yakui   ACPI: Notify the ...
80
  		acpi_processor_ppc_has_changed(pr, 1);
e790cc8bb   Alexey Starikovskiy   ACPI: EC: Workaro...
81
82
  		if (saved == pr->performance_platform_limit)
  			break;
962ce8ca0   Zhang Rui   ACPI: don't dupli...
83
  		acpi_bus_generate_netlink_event(device->pnp.device_class,
0794469da   Kay Sievers   ACPI: struct devi...
84
  						  dev_name(&device->dev), event,
962ce8ca0   Zhang Rui   ACPI: don't dupli...
85
  						  pr->performance_platform_limit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
  		break;
  	case ACPI_PROCESSOR_NOTIFY_POWER:
  		acpi_processor_cst_has_changed(pr);
962ce8ca0   Zhang Rui   ACPI: don't dupli...
89
  		acpi_bus_generate_netlink_event(device->pnp.device_class,
0794469da   Kay Sievers   ACPI: struct devi...
90
  						  dev_name(&device->dev), event, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
  		break;
01854e697   Luming Yu   ACPI: add ACPI 3....
92
93
  	case ACPI_PROCESSOR_NOTIFY_THROTTLING:
  		acpi_processor_tstate_has_changed(pr);
962ce8ca0   Zhang Rui   ACPI: don't dupli...
94
  		acpi_bus_generate_netlink_event(device->pnp.device_class,
0794469da   Kay Sievers   ACPI: struct devi...
95
  						  dev_name(&device->dev), event, 0);
879dca019   Alan Cox   ACPI: missing break
96
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
  	default:
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
99
100
  				  "Unsupported event [0x%x]
  ", event));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
  		break;
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
103
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
  }
fe7bf106e   Paul Gortmaker   acpi: delete __cp...
105
  static int __acpi_processor_start(struct acpi_device *device);
ac212b698   Rafael J. Wysocki   ACPI / processor:...
106

fe7bf106e   Paul Gortmaker   acpi: delete __cp...
107
  static int acpi_cpu_soft_notify(struct notifier_block *nfb,
ac212b698   Rafael J. Wysocki   ACPI / processor:...
108
  					  unsigned long action, void *hcpu)
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
109
110
  {
  	unsigned int cpu = (unsigned long)hcpu;
706546d02   Mike Travis   ACPI: change proc...
111
  	struct acpi_processor *pr = per_cpu(processors, cpu);
ac212b698   Rafael J. Wysocki   ACPI / processor:...
112
  	struct acpi_device *device;
ea9c167d9   Lan Tianyu   ACPI / processor:...
113
  	action &= ~CPU_TASKS_FROZEN;
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
114

8da837344   Toshi Kani   ACPI / processor:...
115
116
117
118
119
120
  	/*
  	 * CPU_STARTING and CPU_DYING must not sleep. Return here since
  	 * acpi_bus_get_device() may sleep.
  	 */
  	if (action == CPU_STARTING || action == CPU_DYING)
  		return NOTIFY_DONE;
ac212b698   Rafael J. Wysocki   ACPI / processor:...
121
122
123
124
125
126
127
  	if (!pr || acpi_bus_get_device(pr->handle, &device))
  		return NOTIFY_DONE;
  
  	if (action == CPU_ONLINE) {
  		/*
  		 * CPU got physically hotplugged and onlined for the first time:
  		 * Initialize missing things.
99b725084   Thomas Renninger   ACPI processor ho...
128
129
  		 */
  		if (pr->flags.need_hotplug_init) {
ac212b698   Rafael J. Wysocki   ACPI / processor:...
130
  			int ret;
47db4547f   Toshi Kani   ACPI: Update CPU ...
131
132
133
  			pr_info("Will online and init hotplugged CPU: %d
  ",
  				pr->id);
99b725084   Thomas Renninger   ACPI processor ho...
134
  			pr->flags.need_hotplug_init = 0;
ac212b698   Rafael J. Wysocki   ACPI / processor:...
135
136
137
  			ret = __acpi_processor_start(device);
  			WARN(ret, "Failed to start CPU: %d
  ", pr->id);
99b725084   Thomas Renninger   ACPI processor ho...
138
  		} else {
ac212b698   Rafael J. Wysocki   ACPI / processor:...
139
  			/* Normal CPU soft online event. */
99b725084   Thomas Renninger   ACPI processor ho...
140
  			acpi_processor_ppc_has_changed(pr, 0);
b7db60f45   Feng Tang   ACPI processor: F...
141
  			acpi_processor_hotplug(pr);
99b725084   Thomas Renninger   ACPI processor ho...
142
143
144
  			acpi_processor_reevaluate_tstate(pr, action);
  			acpi_processor_tstate_has_changed(pr);
  		}
ac212b698   Rafael J. Wysocki   ACPI / processor:...
145
146
  	} else if (action == CPU_DEAD) {
  		/* Invalidate flag.throttling after the CPU is offline. */
5a344a505   Zhao Yakui   ACPI: Reevaluate ...
147
148
  		acpi_processor_reevaluate_tstate(pr, action);
  	}
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
149
150
  	return NOTIFY_OK;
  }
8ce344c66   Mathias Krause   ACPI / processor:...
151
  static struct notifier_block acpi_cpu_notifier = {
729c6ba33   Venkatesh Pallipadi   ACPI: Reevaluate ...
152
153
  	    .notifier_call = acpi_cpu_soft_notify,
  };
239708a3a   Ashwin Chaugule   ACPI: Split out A...
154
155
156
  #ifdef CONFIG_ACPI_CPU_FREQ_PSS
  static int acpi_pss_perf_init(struct acpi_processor *pr,
  		struct acpi_device *device)
54d5dcc45   Thomas Renninger   ACPI processor ho...
157
  {
54d5dcc45   Thomas Renninger   ACPI processor ho...
158
  	int result = 0;
54d5dcc45   Thomas Renninger   ACPI processor ho...
159
  	acpi_processor_ppc_has_changed(pr, 0);
239708a3a   Ashwin Chaugule   ACPI: Split out A...
160

54d5dcc45   Thomas Renninger   ACPI processor ho...
161
  	acpi_processor_get_throttling_info(pr);
22e7551eb   Lan Tianyu   ACPI / processor:...
162
163
164
  
  	if (pr->flags.throttling)
  		pr->flags.limit = 1;
54d5dcc45   Thomas Renninger   ACPI processor ho...
165

54d5dcc45   Thomas Renninger   ACPI processor ho...
166
167
168
169
  	pr->cdev = thermal_cooling_device_register("Processor", device,
  						   &processor_cooling_ops);
  	if (IS_ERR(pr->cdev)) {
  		result = PTR_ERR(pr->cdev);
239708a3a   Ashwin Chaugule   ACPI: Split out A...
170
  		return result;
54d5dcc45   Thomas Renninger   ACPI processor ho...
171
172
173
174
175
176
177
178
179
180
  	}
  
  	dev_dbg(&device->dev, "registered as cooling_device%d
  ",
  		pr->cdev->id);
  
  	result = sysfs_create_link(&device->dev.kobj,
  				   &pr->cdev->device.kobj,
  				   "thermal_cooling");
  	if (result) {
47db4547f   Toshi Kani   ACPI: Update CPU ...
181
182
183
  		dev_err(&device->dev,
  			"Failed to create sysfs link 'thermal_cooling'
  ");
54d5dcc45   Thomas Renninger   ACPI processor ho...
184
185
  		goto err_thermal_unregister;
  	}
239708a3a   Ashwin Chaugule   ACPI: Split out A...
186

54d5dcc45   Thomas Renninger   ACPI processor ho...
187
188
189
190
  	result = sysfs_create_link(&pr->cdev->device.kobj,
  				   &device->dev.kobj,
  				   "device");
  	if (result) {
47db4547f   Toshi Kani   ACPI: Update CPU ...
191
192
193
  		dev_err(&pr->cdev->device,
  			"Failed to create sysfs link 'device'
  ");
54d5dcc45   Thomas Renninger   ACPI processor ho...
194
195
  		goto err_remove_sysfs_thermal;
  	}
ce360db70   Srinivas Pandruvada   ACPI / processor:...
196
  	return 0;
ac212b698   Rafael J. Wysocki   ACPI / processor:...
197
   err_remove_sysfs_thermal:
54d5dcc45   Thomas Renninger   ACPI processor ho...
198
  	sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
ac212b698   Rafael J. Wysocki   ACPI / processor:...
199
   err_thermal_unregister:
54d5dcc45   Thomas Renninger   ACPI processor ho...
200
  	thermal_cooling_device_unregister(pr->cdev);
239708a3a   Ashwin Chaugule   ACPI: Split out A...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  
  	return result;
  }
  
  static void acpi_pss_perf_exit(struct acpi_processor *pr,
  		struct acpi_device *device)
  {
  	if (pr->cdev) {
  		sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
  		sysfs_remove_link(&pr->cdev->device.kobj, "device");
  		thermal_cooling_device_unregister(pr->cdev);
  		pr->cdev = NULL;
  	}
  }
  #else
  static inline int acpi_pss_perf_init(struct acpi_processor *pr,
  		struct acpi_device *device)
  {
  	return 0;
  }
  
  static inline void acpi_pss_perf_exit(struct acpi_processor *pr,
  		struct acpi_device *device) {}
  #endif /* CONFIG_ACPI_CPU_FREQ_PSS */
  
  static int __acpi_processor_start(struct acpi_device *device)
  {
  	struct acpi_processor *pr = acpi_driver_data(device);
  	acpi_status status;
  	int result = 0;
  
  	if (!pr)
  		return -ENODEV;
  
  	if (pr->flags.need_hotplug_init)
  		return 0;
4f2f75735   Ashwin Chaugule   CPPC: Probe for C...
237
238
239
  	result = acpi_cppc_processor_probe(pr);
  	if (result)
  		return -ENODEV;
239708a3a   Ashwin Chaugule   ACPI: Split out A...
240
241
242
243
244
245
246
247
248
249
250
251
252
  	if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
  		acpi_processor_power_init(pr);
  
  	result = acpi_pss_perf_init(pr, device);
  	if (result)
  		goto err_power_exit;
  
  	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
  					     acpi_processor_notify, device);
  	if (ACPI_SUCCESS(status))
  		return 0;
  
  err_power_exit:
38a991b62   Daniel Lezcano   ACPI / processor:...
253
  	acpi_processor_power_exit(pr);
54d5dcc45   Thomas Renninger   ACPI processor ho...
254
255
  	return result;
  }
fe7bf106e   Paul Gortmaker   acpi: delete __cp...
256
  static int acpi_processor_start(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
  {
d0a7edbb6   Lan Tianyu   ACPI / processor:...
258
  	struct acpi_device *device = ACPI_COMPANION(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259

d0a7edbb6   Lan Tianyu   ACPI / processor:...
260
  	if (!device)
ac212b698   Rafael J. Wysocki   ACPI / processor:...
261
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262

ac212b698   Rafael J. Wysocki   ACPI / processor:...
263
  	return __acpi_processor_start(device);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
  }
ac212b698   Rafael J. Wysocki   ACPI / processor:...
265
  static int acpi_processor_stop(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
  {
d0a7edbb6   Lan Tianyu   ACPI / processor:...
267
  	struct acpi_device *device = ACPI_COMPANION(dev);
ac212b698   Rafael J. Wysocki   ACPI / processor:...
268
  	struct acpi_processor *pr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269

d0a7edbb6   Lan Tianyu   ACPI / processor:...
270
  	if (!device)
ac212b698   Rafael J. Wysocki   ACPI / processor:...
271
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272

ac212b698   Rafael J. Wysocki   ACPI / processor:...
273
274
  	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
  				   acpi_processor_notify);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275

50dd09697   Jan Engelhardt   ACPI: Remove unne...
276
  	pr = acpi_driver_data(device);
ac212b698   Rafael J. Wysocki   ACPI / processor:...
277
278
  	if (!pr)
  		return 0;
38a991b62   Daniel Lezcano   ACPI / processor:...
279
  	acpi_processor_power_exit(pr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280

239708a3a   Ashwin Chaugule   ACPI: Split out A...
281
  	acpi_pss_perf_exit(pr, device);
4f2f75735   Ashwin Chaugule   CPPC: Probe for C...
282
  	acpi_cppc_processor_exit(pr);
d550d98d3   Patrick Mochel   ACPI: delete trac...
283
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
289
  /*
   * We keep the driver loaded even when ACPI is not running.
   * This is needed for the powernow-k8 driver, that works even without
   * ACPI, but needs symbols from this driver
   */
ac212b698   Rafael J. Wysocki   ACPI / processor:...
290
  static int __init acpi_processor_driver_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
292
  	int result = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293

ce8442b55   Yinghai Lu   acpi: don't call ...
294
295
  	if (acpi_disabled)
  		return 0;
ac212b698   Rafael J. Wysocki   ACPI / processor:...
296
  	result = driver_register(&acpi_processor_driver);
4f86d3a8e   Len Brown   cpuidle: consolid...
297
  	if (result < 0)
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
298
  		return result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299

ac212b698   Rafael J. Wysocki   ACPI / processor:...
300
  	register_hotcpu_notifier(&acpi_cpu_notifier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  	acpi_thermal_cpufreq_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  	acpi_processor_ppc_init();
1180509f6   Zhao Yakui   ACPI : Update T-s...
303
  	acpi_processor_throttling_init();
d550d98d3   Patrick Mochel   ACPI: delete trac...
304
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305
  }
ac212b698   Rafael J. Wysocki   ACPI / processor:...
306
  static void __exit acpi_processor_driver_exit(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  {
ce8442b55   Yinghai Lu   acpi: don't call ...
308
309
  	if (acpi_disabled)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  	acpi_processor_ppc_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
  	acpi_thermal_cpufreq_exit();
ac212b698   Rafael J. Wysocki   ACPI / processor:...
312
  	unregister_hotcpu_notifier(&acpi_cpu_notifier);
ac212b698   Rafael J. Wysocki   ACPI / processor:...
313
  	driver_unregister(&acpi_processor_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
  }
ac212b698   Rafael J. Wysocki   ACPI / processor:...
315
316
  module_init(acpi_processor_driver_init);
  module_exit(acpi_processor_driver_exit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
  MODULE_ALIAS("processor");