Skip to content

Commit 239708a

Browse files
Ashwin Chaugulerafaeljw
authored andcommitted
ACPI: Split out ACPI PSS from ACPI Processor driver
The ACPI processor driver is currently tied too closely to the ACPI P-states (PSS) and other related constructs for controlling CPU performance. The newer ACPI specification (v5.1 onwards) introduces alternative methods to PSS. These new mechanisms are described within each ACPI Processor object and so they need to be scanned whenever a new Processor object is detected. This patch introduces a new Kconfig symbol to allow for finer configurability among the two options for controlling performance states. There is no change in functionality and the option is auto-selected by the architectures which support it. A future commit will introduce support for CPPC: A newer method of controlling CPU performance. The OS is not expected to support CPPC and PSS at the same time, so the Kconfig option lets us make the two mutually exclusive at compile time. Signed-off-by: Ashwin Chaugule <[email protected]> [ rjw: Changelog ] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent d3c68f2 commit 239708a

File tree

4 files changed

+96
-38
lines changed

4 files changed

+96
-38
lines changed

drivers/acpi/Kconfig

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,20 @@ config ACPI_DOCK
189189
This driver supports ACPI-controlled docking stations and removable
190190
drive bays such as the IBM Ultrabay and the Dell Module Bay.
191191

192+
config ACPI_CPU_FREQ_PSS
193+
bool
194+
select THERMAL
195+
192196
config ACPI_PROCESSOR
193197
tristate "Processor"
194-
select THERMAL
195-
select CPU_IDLE
196198
depends on X86 || IA64
199+
select CPU_IDLE
200+
select ACPI_CPU_FREQ_PSS
197201
default y
198202
help
199-
This driver installs ACPI as the idle handler for Linux and uses
200-
ACPI C2 and C3 processor states to save power on systems that
201-
support it. It is required by several flavors of cpufreq
202-
performance-state drivers.
203+
This driver adds support for the ACPI Processor package. It is required
204+
by several flavors of cpufreq performance-state, thermal, throttling and
205+
idle drivers.
203206

204207
To compile this driver as a module, choose M here:
205208
the module will be called processor.

drivers/acpi/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
8080
obj-$(CONFIG_ACPI_BGRT) += bgrt.o
8181

8282
# processor has its own "processor." module_param namespace
83-
processor-y := processor_driver.o processor_throttling.o
84-
processor-y += processor_idle.o processor_thermal.o
83+
processor-y := processor_driver.o processor_idle.o
84+
processor-$(CONFIG_ACPI_CPU_FREQ_PSS) += processor_throttling.o \
85+
processor_thermal.o
8586
processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
8687

8788
obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o

drivers/acpi/processor_driver.c

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,34 +163,24 @@ static struct notifier_block acpi_cpu_notifier = {
163163
.notifier_call = acpi_cpu_soft_notify,
164164
};
165165

166-
static int __acpi_processor_start(struct acpi_device *device)
166+
#ifdef CONFIG_ACPI_CPU_FREQ_PSS
167+
static int acpi_pss_perf_init(struct acpi_processor *pr,
168+
struct acpi_device *device)
167169
{
168-
struct acpi_processor *pr = acpi_driver_data(device);
169-
acpi_status status;
170170
int result = 0;
171171

172-
if (!pr)
173-
return -ENODEV;
174-
175-
if (pr->flags.need_hotplug_init)
176-
return 0;
177-
178-
#ifdef CONFIG_CPU_FREQ
179172
acpi_processor_ppc_has_changed(pr, 0);
180-
#endif
173+
181174
acpi_processor_get_throttling_info(pr);
182175

183176
if (pr->flags.throttling)
184177
pr->flags.limit = 1;
185178

186-
if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
187-
acpi_processor_power_init(pr);
188-
189179
pr->cdev = thermal_cooling_device_register("Processor", device,
190180
&processor_cooling_ops);
191181
if (IS_ERR(pr->cdev)) {
192182
result = PTR_ERR(pr->cdev);
193-
goto err_power_exit;
183+
return result;
194184
}
195185

196186
dev_dbg(&device->dev, "registered as cooling_device%d\n",
@@ -204,6 +194,7 @@ static int __acpi_processor_start(struct acpi_device *device)
204194
"Failed to create sysfs link 'thermal_cooling'\n");
205195
goto err_thermal_unregister;
206196
}
197+
207198
result = sysfs_create_link(&pr->cdev->device.kobj,
208199
&device->dev.kobj,
209200
"device");
@@ -213,17 +204,61 @@ static int __acpi_processor_start(struct acpi_device *device)
213204
goto err_remove_sysfs_thermal;
214205
}
215206

216-
status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
217-
acpi_processor_notify, device);
218-
if (ACPI_SUCCESS(status))
219-
return 0;
220-
221207
sysfs_remove_link(&pr->cdev->device.kobj, "device");
222208
err_remove_sysfs_thermal:
223209
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
224210
err_thermal_unregister:
225211
thermal_cooling_device_unregister(pr->cdev);
226-
err_power_exit:
212+
213+
return result;
214+
}
215+
216+
static void acpi_pss_perf_exit(struct acpi_processor *pr,
217+
struct acpi_device *device)
218+
{
219+
if (pr->cdev) {
220+
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
221+
sysfs_remove_link(&pr->cdev->device.kobj, "device");
222+
thermal_cooling_device_unregister(pr->cdev);
223+
pr->cdev = NULL;
224+
}
225+
}
226+
#else
227+
static inline int acpi_pss_perf_init(struct acpi_processor *pr,
228+
struct acpi_device *device)
229+
{
230+
return 0;
231+
}
232+
233+
static inline void acpi_pss_perf_exit(struct acpi_processor *pr,
234+
struct acpi_device *device) {}
235+
#endif /* CONFIG_ACPI_CPU_FREQ_PSS */
236+
237+
static int __acpi_processor_start(struct acpi_device *device)
238+
{
239+
struct acpi_processor *pr = acpi_driver_data(device);
240+
acpi_status status;
241+
int result = 0;
242+
243+
if (!pr)
244+
return -ENODEV;
245+
246+
if (pr->flags.need_hotplug_init)
247+
return 0;
248+
249+
if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
250+
acpi_processor_power_init(pr);
251+
252+
result = acpi_pss_perf_init(pr, device);
253+
if (result)
254+
goto err_power_exit;
255+
256+
status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
257+
acpi_processor_notify, device);
258+
if (ACPI_SUCCESS(status))
259+
return 0;
260+
261+
err_power_exit:
227262
acpi_processor_power_exit(pr);
228263
return result;
229264
}
@@ -252,15 +287,10 @@ static int acpi_processor_stop(struct device *dev)
252287
pr = acpi_driver_data(device);
253288
if (!pr)
254289
return 0;
255-
256290
acpi_processor_power_exit(pr);
257291

258-
if (pr->cdev) {
259-
sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
260-
sysfs_remove_link(&pr->cdev->device.kobj, "device");
261-
thermal_cooling_device_unregister(pr->cdev);
262-
pr->cdev = NULL;
263-
}
292+
acpi_pss_perf_exit(pr, device);
293+
264294
return 0;
265295
}
266296

include/acpi/processor.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
318318
void acpi_processor_set_pdc(acpi_handle handle);
319319

320320
/* in processor_throttling.c */
321+
#ifdef CONFIG_ACPI_CPU_FREQ_PSS
321322
int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
322323
int acpi_processor_get_throttling_info(struct acpi_processor *pr);
323324
extern int acpi_processor_set_throttling(struct acpi_processor *pr,
@@ -330,6 +331,29 @@ extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
330331
unsigned long action);
331332
extern const struct file_operations acpi_processor_throttling_fops;
332333
extern void acpi_processor_throttling_init(void);
334+
#else
335+
static inline int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
336+
{
337+
return 0;
338+
}
339+
340+
static inline int acpi_processor_get_throttling_info(struct acpi_processor *pr)
341+
{
342+
return -ENODEV;
343+
}
344+
345+
static inline int acpi_processor_set_throttling(struct acpi_processor *pr,
346+
int state, bool force)
347+
{
348+
return -ENODEV;
349+
}
350+
351+
static inline void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
352+
unsigned long action) {}
353+
354+
static inline void acpi_processor_throttling_init(void) {}
355+
#endif /* CONFIG_ACPI_CPU_FREQ_PSS */
356+
333357
/* in processor_idle.c */
334358
int acpi_processor_power_init(struct acpi_processor *pr);
335359
int acpi_processor_power_exit(struct acpi_processor *pr);
@@ -348,7 +372,7 @@ static inline void acpi_processor_syscore_exit(void) {}
348372
/* in processor_thermal.c */
349373
int acpi_processor_get_limit_info(struct acpi_processor *pr);
350374
extern const struct thermal_cooling_device_ops processor_cooling_ops;
351-
#ifdef CONFIG_CPU_FREQ
375+
#if defined(CONFIG_ACPI_CPU_FREQ_PSS) & defined(CONFIG_CPU_FREQ)
352376
void acpi_thermal_cpufreq_init(void);
353377
void acpi_thermal_cpufreq_exit(void);
354378
#else
@@ -360,6 +384,6 @@ static inline void acpi_thermal_cpufreq_exit(void)
360384
{
361385
return;
362386
}
363-
#endif
387+
#endif /* CONFIG_ACPI_CPU_FREQ_PSS */
364388

365389
#endif

0 commit comments

Comments
 (0)