More power management and ACPI fixes for v4.5-rc2
- Fix a recent cpuidle core regression that broke suspend-to-idle on all systems where cpuidle drivers don't provide ->enter_freeze callbacks for any states (Sudeep Holla). - Drop an unnecessary symbol definition from the cpuidle core code handling coupled CPU cores (Anders Roxell). - Fix a race condition related to governor initialization and removal in the cpufreq core (Viresh Kumar). - Clean up the cpufreq core to use list_is_last() for checking if the given policy object is the last element of a list instead of open coding that in a clumsy way (Gautham R Shenoy). - Fix compiler warnings in the pxa2xx and cpufreq-dt cpufreq drivers (Arnd Bergmann). - Fix two locking issues and clean up a comment in the generic power domains framework (Ulf Hansson, Marek Szyprowski, Moritz Fischer). - Fix the error code path of one function in the ACPI-based PCI hotplug framework (ACPIPHP) that forgets to release a lock acquired previously (Insu Yun). - Drop the ACPI backlight blacklist entry for Dell Inspiron 5737 that is not necessary any more (Hans de Goede). - Clean up the top-level PM Kconfig to stop requiring APM emulation to depend on PM which in fact isn't necessary (Arnd Bergmann). / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJWq9bUAAoJEILEb/54YlRxDIIP/2SPB8xYUAhMDRoPnl70+yqk CSQ7R0xNT48dKRK76+swqMqxF3IFm7/Khm9JI0gp4fdRhRRIhRIGvMEs95LdwEN/ oaNA+gwnDKfYYFKHYYUcbmA4JmNa7jBrZ2bDZUOYA9U1KApRdotA3JZ+uYjNdgXq J+LoQdfHEzRo8/jmwjfYd3CPbmT8FR3lN2ndMq0sW9e4QpMjof70al99aiJbXwRh 4eDqkQMnmKPk6vMLKfK/ZcbQ8SSrxq71FbwTfvvXfG9RMA0QsJtrN6u7fvHjNO4G nm+BuRtuAIwchQ+DiAKvm5/OM3zJbNLsS9CY8W563/gYjfztyZCDylr6whhb2cpz 3cu6WA6kz9yPtHmJAw1Guv+RbFvqsMee/3mLE7ZCLwtAxD7ztXhoy6D/VhXV9lNb 6YBbhWFTRhYPAU7uHk6CT67qa4vJXy/+kHvgpxwSqH+Bm9zB5hCAKquKEVcp6aYU Y6DOMi2Tx1wQgqp74rM4Nw6uoF84yKY63S+Ahdx345tKUq0KM98mWhs98nRtIiaE hyTdMHL4OSAkvQCPZBSQ4nkQXe4waozyQuBJ9q97Nd425bx6S5bGBhUq3siT7xFG tBznZQchn5V2iRXdmnjXLCZuB8W7SeXpNVJ/W1vX2ejMkGIcM/1PO/wAO3SMuuLN T6tDb6RJa16DVjollV3j =s0dR -----END PGP SIGNATURE----- Merge tag 'pm+acpi-4.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull power management and ACPI fixes from Rafael Wysocki: "These are: cpuidle fixes (including one fix for a recent regression), cpufreq fixes (including fixes for two issues introduced during the 4.2 cycle), generic power domains framework fixes (two locking fixes and one cleanup), one locking fix in the ACPI-based PCI hotplug framework (ACPIPHP), removal of one ACPI backlight blacklist entry that isn't necessary any more and a PM Kconfig cleanup. Specifics: - Fix a recent cpuidle core regression that broke suspend-to-idle on all systems where cpuidle drivers don't provide ->enter_freeze callbacks for any states (Sudeep Holla). - Drop an unnecessary symbol definition from the cpuidle core code handling coupled CPU cores (Anders Roxell). - Fix a race condition related to governor initialization and removal in the cpufreq core (Viresh Kumar). - Clean up the cpufreq core to use list_is_last() for checking if the given policy object is the last element of a list instead of open coding that in a clumsy way (Gautham R Shenoy). - Fix compiler warnings in the pxa2xx and cpufreq-dt cpufreq drivers (Arnd Bergmann). - Fix two locking issues and clean up a comment in the generic power domains framework (Ulf Hansson, Marek Szyprowski, Moritz Fischer). - Fix the error code path of one function in the ACPI-based PCI hotplug framework (ACPIPHP) that forgets to release a lock acquired previously (Insu Yun). - Drop the ACPI backlight blacklist entry for Dell Inspiron 5737 that is not necessary any more (Hans de Goede). - Clean up the top-level PM Kconfig to stop requiring APM emulation to depend on PM which in fact isn't necessary (Arnd Bergmann)" * tag 'pm+acpi-4.5-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: cpufreq: cpufreq-dt: avoid uninitialized variable warnings: cpufreq: pxa2xx: fix pxa_cpufreq_change_voltage prototype PM: APM_EMULATION does not depend on PM cpufreq: Use list_is_last() to check last entry of the policy list cpufreq: Fix NULL reference crash while accessing policy->governor_data cpuidle: coupled: remove unused define cpuidle_coupled_lock PM / Domains: Fix typo in comment PM / Domains: Fix potential deadlock while adding/removing subdomains ACPI / PCI / hotplug: unlock in error path in acpiphp_enable_slot() ACPI: Revert "ACPI / video: Add Dell Inspiron 5737 to the blacklist" cpuidle: fix fallback mechanism for suspend to idle in absence of enter_freeze PM / domains: fix lockdep issue for all subdomains
This commit is contained in:
Коммит
46552e68ac
|
@ -135,14 +135,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = video_detect_force_vendor,
|
||||
.ident = "Dell Inspiron 5737",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"),
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
* These models have a working acpi_video backlight control, and using
|
||||
|
|
|
@ -162,7 +162,7 @@ static int genpd_power_off(struct generic_pm_domain *genpd, bool timed)
|
|||
|
||||
/**
|
||||
* genpd_queue_power_off_work - Queue up the execution of genpd_poweroff().
|
||||
* @genpd: PM domait to power off.
|
||||
* @genpd: PM domain to power off.
|
||||
*
|
||||
* Queue up the execution of genpd_poweroff() unless it's already been done
|
||||
* before.
|
||||
|
@ -172,16 +172,15 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
|
|||
queue_work(pm_wq, &genpd->power_off_work);
|
||||
}
|
||||
|
||||
static int genpd_poweron(struct generic_pm_domain *genpd);
|
||||
|
||||
/**
|
||||
* __genpd_poweron - Restore power to a given PM domain and its masters.
|
||||
* @genpd: PM domain to power up.
|
||||
* @depth: nesting count for lockdep.
|
||||
*
|
||||
* Restore power to @genpd and all of its masters so that it is possible to
|
||||
* resume a device belonging to it.
|
||||
*/
|
||||
static int __genpd_poweron(struct generic_pm_domain *genpd)
|
||||
static int __genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth)
|
||||
{
|
||||
struct gpd_link *link;
|
||||
int ret = 0;
|
||||
|
@ -196,11 +195,16 @@ static int __genpd_poweron(struct generic_pm_domain *genpd)
|
|||
* with it.
|
||||
*/
|
||||
list_for_each_entry(link, &genpd->slave_links, slave_node) {
|
||||
genpd_sd_counter_inc(link->master);
|
||||
struct generic_pm_domain *master = link->master;
|
||||
|
||||
genpd_sd_counter_inc(master);
|
||||
|
||||
mutex_lock_nested(&master->lock, depth + 1);
|
||||
ret = __genpd_poweron(master, depth + 1);
|
||||
mutex_unlock(&master->lock);
|
||||
|
||||
ret = genpd_poweron(link->master);
|
||||
if (ret) {
|
||||
genpd_sd_counter_dec(link->master);
|
||||
genpd_sd_counter_dec(master);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -232,11 +236,12 @@ static int genpd_poweron(struct generic_pm_domain *genpd)
|
|||
int ret;
|
||||
|
||||
mutex_lock(&genpd->lock);
|
||||
ret = __genpd_poweron(genpd);
|
||||
ret = __genpd_poweron(genpd, 0);
|
||||
mutex_unlock(&genpd->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev)
|
||||
{
|
||||
return GENPD_DEV_CALLBACK(genpd, int, save_state, dev);
|
||||
|
@ -484,7 +489,7 @@ static int pm_genpd_runtime_resume(struct device *dev)
|
|||
}
|
||||
|
||||
mutex_lock(&genpd->lock);
|
||||
ret = __genpd_poweron(genpd);
|
||||
ret = __genpd_poweron(genpd, 0);
|
||||
mutex_unlock(&genpd->lock);
|
||||
|
||||
if (ret)
|
||||
|
@ -1339,8 +1344,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
|
|||
if (!link)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&genpd->lock);
|
||||
mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
|
||||
mutex_lock(&subdomain->lock);
|
||||
mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
|
||||
|
||||
if (genpd->status == GPD_STATE_POWER_OFF
|
||||
&& subdomain->status != GPD_STATE_POWER_OFF) {
|
||||
|
@ -1363,8 +1368,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
|
|||
genpd_sd_counter_inc(genpd);
|
||||
|
||||
out:
|
||||
mutex_unlock(&subdomain->lock);
|
||||
mutex_unlock(&genpd->lock);
|
||||
mutex_unlock(&subdomain->lock);
|
||||
if (ret)
|
||||
kfree(link);
|
||||
return ret;
|
||||
|
@ -1385,7 +1390,8 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
|
|||
if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&genpd->lock);
|
||||
mutex_lock(&subdomain->lock);
|
||||
mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING);
|
||||
|
||||
if (!list_empty(&subdomain->slave_links) || subdomain->device_count) {
|
||||
pr_warn("%s: unable to remove subdomain %s\n", genpd->name,
|
||||
|
@ -1398,22 +1404,19 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
|
|||
if (link->slave != subdomain)
|
||||
continue;
|
||||
|
||||
mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
|
||||
|
||||
list_del(&link->master_node);
|
||||
list_del(&link->slave_node);
|
||||
kfree(link);
|
||||
if (subdomain->status != GPD_STATE_POWER_OFF)
|
||||
genpd_sd_counter_dec(genpd);
|
||||
|
||||
mutex_unlock(&subdomain->lock);
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&genpd->lock);
|
||||
mutex_unlock(&subdomain->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -142,15 +142,16 @@ static int allocate_resources(int cpu, struct device **cdev,
|
|||
|
||||
try_again:
|
||||
cpu_reg = regulator_get_optional(cpu_dev, reg);
|
||||
if (IS_ERR(cpu_reg)) {
|
||||
ret = PTR_ERR_OR_ZERO(cpu_reg);
|
||||
if (ret) {
|
||||
/*
|
||||
* If cpu's regulator supply node is present, but regulator is
|
||||
* not yet registered, we should try defering probe.
|
||||
*/
|
||||
if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) {
|
||||
if (ret == -EPROBE_DEFER) {
|
||||
dev_dbg(cpu_dev, "cpu%d regulator not ready, retry\n",
|
||||
cpu);
|
||||
return -EPROBE_DEFER;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Try with "cpu-supply" */
|
||||
|
@ -159,18 +160,16 @@ try_again:
|
|||
goto try_again;
|
||||
}
|
||||
|
||||
dev_dbg(cpu_dev, "no regulator for cpu%d: %ld\n",
|
||||
cpu, PTR_ERR(cpu_reg));
|
||||
dev_dbg(cpu_dev, "no regulator for cpu%d: %d\n", cpu, ret);
|
||||
}
|
||||
|
||||
cpu_clk = clk_get(cpu_dev, NULL);
|
||||
if (IS_ERR(cpu_clk)) {
|
||||
ret = PTR_ERR_OR_ZERO(cpu_clk);
|
||||
if (ret) {
|
||||
/* put regulator */
|
||||
if (!IS_ERR(cpu_reg))
|
||||
regulator_put(cpu_reg);
|
||||
|
||||
ret = PTR_ERR(cpu_clk);
|
||||
|
||||
/*
|
||||
* If cpu's clk node is present, but clock is not yet
|
||||
* registered, we should try defering probe.
|
||||
|
|
|
@ -48,11 +48,11 @@ static struct cpufreq_policy *next_policy(struct cpufreq_policy *policy,
|
|||
bool active)
|
||||
{
|
||||
do {
|
||||
policy = list_next_entry(policy, policy_list);
|
||||
|
||||
/* No more policies in the list */
|
||||
if (&policy->policy_list == &cpufreq_policy_list)
|
||||
if (list_is_last(&policy->policy_list, &cpufreq_policy_list))
|
||||
return NULL;
|
||||
|
||||
policy = list_next_entry(policy, policy_list);
|
||||
} while (!suitable_policy(policy, active));
|
||||
|
||||
return policy;
|
||||
|
|
|
@ -387,16 +387,18 @@ static int cpufreq_governor_init(struct cpufreq_policy *policy,
|
|||
if (!have_governor_per_policy())
|
||||
cdata->gdbs_data = dbs_data;
|
||||
|
||||
policy->governor_data = dbs_data;
|
||||
|
||||
ret = sysfs_create_group(get_governor_parent_kobj(policy),
|
||||
get_sysfs_attr(dbs_data));
|
||||
if (ret)
|
||||
goto reset_gdbs_data;
|
||||
|
||||
policy->governor_data = dbs_data;
|
||||
|
||||
return 0;
|
||||
|
||||
reset_gdbs_data:
|
||||
policy->governor_data = NULL;
|
||||
|
||||
if (!have_governor_per_policy())
|
||||
cdata->gdbs_data = NULL;
|
||||
cdata->exit(dbs_data, !policy->governor->initialized);
|
||||
|
@ -417,16 +419,19 @@ static int cpufreq_governor_exit(struct cpufreq_policy *policy,
|
|||
if (!cdbs->shared || cdbs->shared->policy)
|
||||
return -EBUSY;
|
||||
|
||||
policy->governor_data = NULL;
|
||||
if (!--dbs_data->usage_count) {
|
||||
sysfs_remove_group(get_governor_parent_kobj(policy),
|
||||
get_sysfs_attr(dbs_data));
|
||||
|
||||
policy->governor_data = NULL;
|
||||
|
||||
if (!have_governor_per_policy())
|
||||
cdata->gdbs_data = NULL;
|
||||
|
||||
cdata->exit(dbs_data, policy->governor->initialized == 1);
|
||||
kfree(dbs_data);
|
||||
} else {
|
||||
policy->governor_data = NULL;
|
||||
}
|
||||
|
||||
free_common_dbs_info(policy, cdata);
|
||||
|
|
|
@ -202,7 +202,7 @@ static void __init pxa_cpufreq_init_voltages(void)
|
|||
}
|
||||
}
|
||||
#else
|
||||
static int pxa_cpufreq_change_voltage(struct pxa_freqs *pxa_freq)
|
||||
static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,6 @@ struct cpuidle_coupled {
|
|||
|
||||
#define CPUIDLE_COUPLED_NOT_IDLE (-1)
|
||||
|
||||
static DEFINE_MUTEX(cpuidle_coupled_lock);
|
||||
static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb);
|
||||
|
||||
/*
|
||||
|
|
|
@ -153,7 +153,7 @@ int cpuidle_enter_freeze(struct cpuidle_driver *drv, struct cpuidle_device *dev)
|
|||
* be frozen safely.
|
||||
*/
|
||||
index = find_deepest_state(drv, dev, UINT_MAX, 0, true);
|
||||
if (index >= 0)
|
||||
if (index > 0)
|
||||
enter_freeze_proper(drv, dev, index);
|
||||
|
||||
return index;
|
||||
|
|
|
@ -953,8 +953,10 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
|
|||
{
|
||||
pci_lock_rescan_remove();
|
||||
|
||||
if (slot->flags & SLOT_IS_GOING_AWAY)
|
||||
if (slot->flags & SLOT_IS_GOING_AWAY) {
|
||||
pci_unlock_rescan_remove();
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* configure all functions */
|
||||
if (!(slot->flags & SLOT_ENABLED))
|
||||
|
|
|
@ -235,7 +235,7 @@ config PM_TRACE_RTC
|
|||
|
||||
config APM_EMULATION
|
||||
tristate "Advanced Power Management Emulation"
|
||||
depends on PM && SYS_SUPPORTS_APM_EMULATION
|
||||
depends on SYS_SUPPORTS_APM_EMULATION
|
||||
help
|
||||
APM is a BIOS specification for saving power using several different
|
||||
techniques. This is mostly useful for battery powered laptops with
|
||||
|
|
|
@ -162,7 +162,7 @@ static void cpuidle_idle_call(void)
|
|||
*/
|
||||
if (idle_should_freeze()) {
|
||||
entered_state = cpuidle_enter_freeze(drv, dev);
|
||||
if (entered_state >= 0) {
|
||||
if (entered_state > 0) {
|
||||
local_irq_enable();
|
||||
goto exit_idle;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче