mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-15 07:04:44 +00:00
Power management and ACPI fixes for v4.3-rc6
- Fix a regression introduced by a recent ACPICA cleanup that uncovered a latent bug (Lv Zheng). - Fix a recent regression in the generic power domains framework that may cause it to violate PM QoS latency constraints in some cases (Ulf Hansson). - Fix an intel_pstate driver crash on the Knights Landing chips that do not update the MPERF counter as often as expected by the driver which may result in a divide by 0 (Srinivas Pandruvada). / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJWIPwyAAoJEILEb/54YlRx4OYP/ivVGcwUYVLbb9c7ePX220pb QlkwQH/uTh1tSwSCNq2X4e6hgPdVKYx3/Buc0t89bVFwV+upqUcfNMfj0GWvXO3e 2fLgb/27Zg3ZKBe8XqeHbibN7HQ9Wz/s9rJRLVCWLUY/5WHRCyyO2JfELjuX4pNq tJTH7WIFIJ3riuV97DfO55ZrpKL2msnFvItv+pKVuuVWJMJKpHg+NQKQ5UWegDed IYaT1FlvVwGwlrvGvUNi8qWTwrziNDKd460qrOZFLTTdMwg4UZPI991euK6ZEot7 refZPtrDIrPBD3tPOWjxERVuleIL+Bw7sq+JKUX9IdM4m69UcAOz63oXRLYm/ilV nAvo6eDFc37FVQHGv1JzzbZIyvZOeFMfvRN3R06Qfm9Kdu2wjjTd/fYd63IabHe+ HwpgZbEhGRarwZ3VOJzQrLaa/gMTltpRKEiMQeHSnUmSCVJiKK/q5b9RBFfAOpfa wIlaFxsx1GC8QBatL4I8X2M0w9UQpY4N48NZX+FTRx1zCEkocugHbn6vIHW7USVu 5mBoghdnPcfZJS66cSPa508LZOdfhw4vB8jQXzlG+v1PBdw7ISf6wnEyTawYMpiB pnIciv18WYTk/MmVdkf97TLHMbuiMVkyOaSZ1SpdE+leN8dGOhCscBb/P088ellk A9N4dzCeaSo6uHY6OMhZ =+ku3 -----END PGP SIGNATURE----- Merge tag 'pm+acpi-4.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull power management and ACPI fixes from Rafael Wysocki: "These fix two recent regressions (ACPICA, the generic power domains framework) and one crash that may happen on specific hardware supported since 4.1 (intel_pstate). Specifics: - Fix a regression introduced by a recent ACPICA cleanup that uncovered a latent bug (Lv Zheng). - Fix a recent regression in the generic power domains framework that may cause it to violate PM QoS latency constraints in some cases (Ulf Hansson). - Fix an intel_pstate driver crash on the Knights Landing chips that do not update the MPERF counter as often as expected by the driver which may result in a divide by 0 (Srinivas Pandruvada)" * tag 'pm+acpi-4.3-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpufreq: intel_pstate: Fix divide by zero on Knights Landing (KNL) ACPICA: Tables: Fix FADT dependency regression PM / Domains: Fix validation of latency constraints in genpd governor
This commit is contained in:
commit
a4c4c49a61
7 changed files with 21 additions and 49 deletions
|
@ -61,6 +61,7 @@ ACPI_GLOBAL(struct acpi_table_header, acpi_gbl_original_dsdt_header);
|
||||||
ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX);
|
ACPI_INIT_GLOBAL(u32, acpi_gbl_dsdt_index, ACPI_INVALID_TABLE_INDEX);
|
||||||
ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX);
|
ACPI_INIT_GLOBAL(u32, acpi_gbl_facs_index, ACPI_INVALID_TABLE_INDEX);
|
||||||
ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX);
|
ACPI_INIT_GLOBAL(u32, acpi_gbl_xfacs_index, ACPI_INVALID_TABLE_INDEX);
|
||||||
|
ACPI_INIT_GLOBAL(u32, acpi_gbl_fadt_index, ACPI_INVALID_TABLE_INDEX);
|
||||||
|
|
||||||
#if (!ACPI_REDUCED_HARDWARE)
|
#if (!ACPI_REDUCED_HARDWARE)
|
||||||
ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS);
|
ACPI_GLOBAL(struct acpi_table_facs *, acpi_gbl_FACS);
|
||||||
|
|
|
@ -85,7 +85,7 @@ void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded);
|
||||||
/*
|
/*
|
||||||
* tbfadt - FADT parse/convert/validate
|
* tbfadt - FADT parse/convert/validate
|
||||||
*/
|
*/
|
||||||
void acpi_tb_parse_fadt(u32 table_index);
|
void acpi_tb_parse_fadt(void);
|
||||||
|
|
||||||
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
|
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
|
||||||
|
|
||||||
|
@ -138,8 +138,6 @@ acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id);
|
||||||
*/
|
*/
|
||||||
acpi_status acpi_tb_initialize_facs(void);
|
acpi_status acpi_tb_initialize_facs(void);
|
||||||
|
|
||||||
u8 acpi_tb_tables_loaded(void);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
acpi_tb_print_table_header(acpi_physical_address address,
|
acpi_tb_print_table_header(acpi_physical_address address,
|
||||||
struct acpi_table_header *header);
|
struct acpi_table_header *header);
|
||||||
|
|
|
@ -71,7 +71,7 @@ acpi_status acpi_enable(void)
|
||||||
|
|
||||||
/* ACPI tables must be present */
|
/* ACPI tables must be present */
|
||||||
|
|
||||||
if (!acpi_tb_tables_loaded()) {
|
if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) {
|
||||||
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
|
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,7 @@ acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_tb_parse_fadt
|
* FUNCTION: acpi_tb_parse_fadt
|
||||||
*
|
*
|
||||||
* PARAMETERS: table_index - Index for the FADT
|
* PARAMETERS: None
|
||||||
*
|
*
|
||||||
* RETURN: None
|
* RETURN: None
|
||||||
*
|
*
|
||||||
|
@ -307,7 +307,7 @@ acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void acpi_tb_parse_fadt(u32 table_index)
|
void acpi_tb_parse_fadt(void)
|
||||||
{
|
{
|
||||||
u32 length;
|
u32 length;
|
||||||
struct acpi_table_header *table;
|
struct acpi_table_header *table;
|
||||||
|
@ -319,11 +319,11 @@ void acpi_tb_parse_fadt(u32 table_index)
|
||||||
* Get a local copy of the FADT and convert it to a common format
|
* Get a local copy of the FADT and convert it to a common format
|
||||||
* Map entire FADT, assumed to be smaller than one page.
|
* Map entire FADT, assumed to be smaller than one page.
|
||||||
*/
|
*/
|
||||||
length = acpi_gbl_root_table_list.tables[table_index].length;
|
length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;
|
||||||
|
|
||||||
table =
|
table =
|
||||||
acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
|
acpi_os_map_memory(acpi_gbl_root_table_list.
|
||||||
address, length);
|
tables[acpi_gbl_fadt_index].address, length);
|
||||||
if (!table) {
|
if (!table) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,29 +97,6 @@ acpi_status acpi_tb_initialize_facs(void)
|
||||||
}
|
}
|
||||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_tb_tables_loaded
|
|
||||||
*
|
|
||||||
* PARAMETERS: None
|
|
||||||
*
|
|
||||||
* RETURN: TRUE if required ACPI tables are loaded
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Determine if the minimum required ACPI tables are present
|
|
||||||
* (FADT, FACS, DSDT)
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
u8 acpi_tb_tables_loaded(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (acpi_gbl_root_table_list.current_table_count >= 4) {
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_tb_check_dsdt_header
|
* FUNCTION: acpi_tb_check_dsdt_header
|
||||||
|
@ -392,7 +369,8 @@ acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
|
||||||
ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
|
ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
|
||||||
tables[table_index].signature,
|
tables[table_index].signature,
|
||||||
ACPI_SIG_FADT)) {
|
ACPI_SIG_FADT)) {
|
||||||
acpi_tb_parse_fadt(table_index);
|
acpi_gbl_fadt_index = table_index;
|
||||||
|
acpi_tb_parse_fadt();
|
||||||
}
|
}
|
||||||
|
|
||||||
next_table:
|
next_table:
|
||||||
|
|
|
@ -77,13 +77,16 @@ static bool default_stop_ok(struct device *dev)
|
||||||
dev_update_qos_constraint);
|
dev_update_qos_constraint);
|
||||||
|
|
||||||
if (constraint_ns > 0) {
|
if (constraint_ns > 0) {
|
||||||
constraint_ns -= td->start_latency_ns;
|
constraint_ns -= td->save_state_latency_ns +
|
||||||
|
td->stop_latency_ns +
|
||||||
|
td->start_latency_ns +
|
||||||
|
td->restore_state_latency_ns;
|
||||||
if (constraint_ns == 0)
|
if (constraint_ns == 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
td->effective_constraint_ns = constraint_ns;
|
td->effective_constraint_ns = constraint_ns;
|
||||||
td->cached_stop_ok = constraint_ns > td->stop_latency_ns ||
|
td->cached_stop_ok = constraint_ns >= 0;
|
||||||
constraint_ns == 0;
|
|
||||||
/*
|
/*
|
||||||
* The children have been suspended already, so we don't need to take
|
* The children have been suspended already, so we don't need to take
|
||||||
* their stop latencies into account here.
|
* their stop latencies into account here.
|
||||||
|
@ -126,18 +129,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
|
||||||
|
|
||||||
off_on_time_ns = genpd->power_off_latency_ns +
|
off_on_time_ns = genpd->power_off_latency_ns +
|
||||||
genpd->power_on_latency_ns;
|
genpd->power_on_latency_ns;
|
||||||
/*
|
|
||||||
* It doesn't make sense to remove power from the domain if saving
|
|
||||||
* the state of all devices in it and the power off/power on operations
|
|
||||||
* take too much time.
|
|
||||||
*
|
|
||||||
* All devices in this domain have been stopped already at this point.
|
|
||||||
*/
|
|
||||||
list_for_each_entry(pdd, &genpd->dev_list, list_node) {
|
|
||||||
if (pdd->dev->driver)
|
|
||||||
off_on_time_ns +=
|
|
||||||
to_gpd_data(pdd)->td.save_state_latency_ns;
|
|
||||||
}
|
|
||||||
|
|
||||||
min_off_time_ns = -1;
|
min_off_time_ns = -1;
|
||||||
/*
|
/*
|
||||||
|
@ -193,7 +184,6 @@ static bool default_power_down_ok(struct dev_pm_domain *pd)
|
||||||
* constraint_ns cannot be negative here, because the device has
|
* constraint_ns cannot be negative here, because the device has
|
||||||
* been suspended.
|
* been suspended.
|
||||||
*/
|
*/
|
||||||
constraint_ns -= td->restore_state_latency_ns;
|
|
||||||
if (constraint_ns <= off_on_time_ns)
|
if (constraint_ns <= off_on_time_ns)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -776,6 +776,11 @@ static inline void intel_pstate_sample(struct cpudata *cpu)
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
rdmsrl(MSR_IA32_APERF, aperf);
|
rdmsrl(MSR_IA32_APERF, aperf);
|
||||||
rdmsrl(MSR_IA32_MPERF, mperf);
|
rdmsrl(MSR_IA32_MPERF, mperf);
|
||||||
|
if (cpu->prev_mperf == mperf) {
|
||||||
|
local_irq_restore(flags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tsc = rdtsc();
|
tsc = rdtsc();
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue