ACPI / processor_idle: introduce ACPI_PROCESSOR_CSTATE

ACPI 6.0 adds a new method to specify the CPU idle states(C-states)
called Low Power Idle(LPI) states. Since new architectures like ARM64
use only LPIs, introduce ACPI_PROCESSOR_CSTATE to encapsulate all the
code supporting the old style C-states(_CST).

This patch will help to extend the processor_idle module to support
LPI.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Sudeep Holla 2016-07-19 18:52:53 +01:00 committed by Rafael J. Wysocki
parent 92d21ac74a
commit 35ae713355
3 changed files with 58 additions and 28 deletions

View file

@ -213,6 +213,10 @@ config ACPI_CPU_FREQ_PSS
bool bool
select THERMAL select THERMAL
config ACPI_PROCESSOR_CSTATE
def_bool y
depends on IA64 || X86
config ACPI_PROCESSOR_IDLE config ACPI_PROCESSOR_IDLE
bool bool
select CPU_IDLE select CPU_IDLE

View file

@ -59,6 +59,12 @@ module_param(latency_factor, uint, 0644);
static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device);
struct cpuidle_driver acpi_idle_driver = {
.name = "acpi_idle",
.owner = THIS_MODULE,
};
#ifdef CONFIG_ACPI_PROCESSOR_CSTATE
static static
DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], acpi_cstate); DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], acpi_cstate);
@ -804,11 +810,6 @@ static void acpi_idle_enter_freeze(struct cpuidle_device *dev,
acpi_idle_do_entry(cx); acpi_idle_do_entry(cx);
} }
struct cpuidle_driver acpi_idle_driver = {
.name = "acpi_idle",
.owner = THIS_MODULE,
};
/** /**
* acpi_processor_setup_cpuidle_cx - prepares and configures CPUIDLE * acpi_processor_setup_cpuidle_cx - prepares and configures CPUIDLE
* device i.e. per-cpu data * device i.e. per-cpu data
@ -925,6 +926,50 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
return 0; return 0;
} }
static inline void acpi_processor_cstate_first_run_checks(void)
{
acpi_status status;
static int first_run;
if (first_run)
return;
dmi_check_system(processor_power_dmi_table);
max_cstate = acpi_processor_cstate_check(max_cstate);
if (max_cstate < ACPI_C_STATES_MAX)
pr_notice("ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
if (acpi_gbl_FADT.cst_control && !nocst) {
status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
acpi_gbl_FADT.cst_control, 8);
if (ACPI_FAILURE(status))
ACPI_EXCEPTION((AE_INFO, status,
"Notifying BIOS of _CST ability failed"));
}
}
#else
static inline int disabled_by_idle_boot_param(void) { return 0; }
static inline void acpi_processor_cstate_first_run_checks(void) { }
static int acpi_processor_get_power_info(struct acpi_processor *pr)
{
return -ENODEV;
}
static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
struct cpuidle_device *dev)
{
return -EINVAL;
}
static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
{
return -EINVAL;
}
#endif /* CONFIG_ACPI_PROCESSOR_CSTATE */
int acpi_processor_hotplug(struct acpi_processor *pr) int acpi_processor_hotplug(struct acpi_processor *pr)
{ {
int ret = 0; int ret = 0;
@ -1015,35 +1060,16 @@ static int acpi_processor_registered;
int acpi_processor_power_init(struct acpi_processor *pr) int acpi_processor_power_init(struct acpi_processor *pr)
{ {
acpi_status status;
int retval; int retval;
struct cpuidle_device *dev; struct cpuidle_device *dev;
static int first_run;
if (disabled_by_idle_boot_param()) if (disabled_by_idle_boot_param())
return 0; return 0;
if (!first_run) { acpi_processor_cstate_first_run_checks();
dmi_check_system(processor_power_dmi_table);
max_cstate = acpi_processor_cstate_check(max_cstate);
if (max_cstate < ACPI_C_STATES_MAX)
printk(KERN_NOTICE
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
}
if (acpi_gbl_FADT.cst_control && !nocst) { if (!acpi_processor_get_power_info(pr))
status = pr->flags.power_setup_done = 1;
acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Notifying BIOS of _CST ability failed"));
}
}
acpi_processor_get_power_info(pr);
pr->flags.power_setup_done = 1;
/* /*
* Install the idle handler if processor power management is supported. * Install the idle handler if processor power management is supported.

View file

@ -242,7 +242,7 @@ extern int acpi_processor_get_performance_info(struct acpi_processor *pr);
DECLARE_PER_CPU(struct acpi_processor *, processors); DECLARE_PER_CPU(struct acpi_processor *, processors);
extern struct acpi_processor_errata errata; extern struct acpi_processor_errata errata;
#ifdef ARCH_HAS_POWER_INIT #if defined(ARCH_HAS_POWER_INIT) && defined(CONFIG_ACPI_PROCESSOR_CSTATE)
void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
unsigned int cpu); unsigned int cpu);
int acpi_processor_ffh_cstate_probe(unsigned int cpu, int acpi_processor_ffh_cstate_probe(unsigned int cpu,