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:
Linus Torvalds 2016-01-29 15:40:59 -08:00
Родитель ad233aca21 ad1ac94767
Коммит 46552e68ac
11 изменённых файлов: 45 добавлений и 45 удалений

Просмотреть файл

@ -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;
}