mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
ACPI / processor_idle: Add support for Low Power Idle(LPI) states
ACPI 6.0 introduced an optional object _LPI that provides an alternate method to describe Low Power Idle states. It defines the local power states for each node in a hierarchical processor topology. The OSPM can use _LPI object to select a local power state for each level of processor hierarchy in the system. They used to produce a composite power state request that is presented to the platform by the OSPM. Since multiple processors affect the idle state for any non-leaf hierarchy node, coordination of idle state requests between the processors is required. ACPI supports two different coordination schemes: Platform coordinated and OS initiated. This patch adds initial support for Platform coordination scheme of 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:
committed by
Rafael J. Wysocki
parent
35ae713355
commit
a36a7fecfe
@@ -302,6 +302,14 @@ out_kfree:
|
||||
EXPORT_SYMBOL(acpi_run_osc);
|
||||
|
||||
bool osc_sb_apei_support_acked;
|
||||
|
||||
/*
|
||||
* ACPI 6.0 Section 8.4.4.2 Idle State Coordination
|
||||
* OSPM supports platform coordinated low power idle(LPI) states
|
||||
*/
|
||||
bool osc_pc_lpi_support_confirmed;
|
||||
EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
|
||||
|
||||
static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
|
||||
static void acpi_bus_osc_support(void)
|
||||
{
|
||||
@@ -322,6 +330,7 @@ static void acpi_bus_osc_support(void)
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT;
|
||||
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
|
||||
|
||||
if (!ghes_disable)
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT;
|
||||
@@ -329,9 +338,12 @@ static void acpi_bus_osc_support(void)
|
||||
return;
|
||||
if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) {
|
||||
u32 *capbuf_ret = context.ret.pointer;
|
||||
if (context.ret.length > OSC_SUPPORT_DWORD)
|
||||
if (context.ret.length > OSC_SUPPORT_DWORD) {
|
||||
osc_sb_apei_support_acked =
|
||||
capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
|
||||
osc_pc_lpi_support_confirmed =
|
||||
capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
|
||||
}
|
||||
kfree(context.ret.pointer);
|
||||
}
|
||||
/* do we need to check other returned cap? Sounds no */
|
||||
|
||||
@@ -90,7 +90,7 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
|
||||
pr->performance_platform_limit);
|
||||
break;
|
||||
case ACPI_PROCESSOR_NOTIFY_POWER:
|
||||
acpi_processor_cst_has_changed(pr);
|
||||
acpi_processor_power_state_has_changed(pr);
|
||||
acpi_bus_generate_netlink_event(device->pnp.device_class,
|
||||
dev_name(&device->dev), event, 0);
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,7 @@
|
||||
#define ACPI_CSTATE_SYSTEMIO 0
|
||||
#define ACPI_CSTATE_FFH 1
|
||||
#define ACPI_CSTATE_HALT 2
|
||||
#define ACPI_CSTATE_INTEGER 3
|
||||
|
||||
#define ACPI_CX_DESC_LEN 32
|
||||
|
||||
@@ -67,9 +68,25 @@ struct acpi_processor_cx {
|
||||
char desc[ACPI_CX_DESC_LEN];
|
||||
};
|
||||
|
||||
struct acpi_lpi_state {
|
||||
u32 min_residency;
|
||||
u32 wake_latency; /* worst case */
|
||||
u32 flags;
|
||||
u32 arch_flags;
|
||||
u32 res_cnt_freq;
|
||||
u32 enable_parent_state;
|
||||
u64 address;
|
||||
u8 index;
|
||||
u8 entry_method;
|
||||
char desc[ACPI_CX_DESC_LEN];
|
||||
};
|
||||
|
||||
struct acpi_processor_power {
|
||||
int count;
|
||||
struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
|
||||
union {
|
||||
struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
|
||||
struct acpi_lpi_state lpi_states[ACPI_PROCESSOR_MAX_POWER];
|
||||
};
|
||||
int timer_broadcast_on_state;
|
||||
};
|
||||
|
||||
@@ -189,6 +206,7 @@ struct acpi_processor_flags {
|
||||
u8 bm_control:1;
|
||||
u8 bm_check:1;
|
||||
u8 has_cst:1;
|
||||
u8 has_lpi:1;
|
||||
u8 power_setup_done:1;
|
||||
u8 bm_rld_set:1;
|
||||
u8 need_hotplug_init:1;
|
||||
@@ -371,7 +389,7 @@ extern struct cpuidle_driver acpi_idle_driver;
|
||||
#ifdef CONFIG_ACPI_PROCESSOR_IDLE
|
||||
int acpi_processor_power_init(struct acpi_processor *pr);
|
||||
int acpi_processor_power_exit(struct acpi_processor *pr);
|
||||
int acpi_processor_cst_has_changed(struct acpi_processor *pr);
|
||||
int acpi_processor_power_state_has_changed(struct acpi_processor *pr);
|
||||
int acpi_processor_hotplug(struct acpi_processor *pr);
|
||||
#else
|
||||
static inline int acpi_processor_power_init(struct acpi_processor *pr)
|
||||
@@ -384,7 +402,7 @@ static inline int acpi_processor_power_exit(struct acpi_processor *pr)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int acpi_processor_cst_has_changed(struct acpi_processor *pr)
|
||||
static inline int acpi_processor_power_state_has_changed(struct acpi_processor *pr)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -444,8 +444,12 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
|
||||
#define OSC_SB_HOTPLUG_OST_SUPPORT 0x00000008
|
||||
#define OSC_SB_APEI_SUPPORT 0x00000010
|
||||
#define OSC_SB_CPC_SUPPORT 0x00000020
|
||||
#define OSC_SB_CPCV2_SUPPORT 0x00000040
|
||||
#define OSC_SB_PCLPI_SUPPORT 0x00000080
|
||||
#define OSC_SB_OSLPI_SUPPORT 0x00000100
|
||||
|
||||
extern bool osc_sb_apei_support_acked;
|
||||
extern bool osc_pc_lpi_support_confirmed;
|
||||
|
||||
/* PCI Host Bridge _OSC: Capabilities DWORD 2: Support Field */
|
||||
#define OSC_PCI_EXT_CONFIG_SUPPORT 0x00000001
|
||||
|
||||
Reference in New Issue
Block a user