Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+45 -45
-8
drivers/acpi/video_detect.c
··· 135 135 DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), 136 136 }, 137 137 }, 138 - { 139 - .callback = video_detect_force_vendor, 140 - .ident = "Dell Inspiron 5737", 141 - .matches = { 142 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 143 - DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"), 144 - }, 145 - }, 146 138 147 139 /* 148 140 * These models have a working acpi_video backlight control, and using
+20 -17
drivers/base/power/domain.c
··· 162 162 163 163 /** 164 164 * genpd_queue_power_off_work - Queue up the execution of genpd_poweroff(). 165 - * @genpd: PM domait to power off. 165 + * @genpd: PM domain to power off. 166 166 * 167 167 * Queue up the execution of genpd_poweroff() unless it's already been done 168 168 * before. ··· 172 172 queue_work(pm_wq, &genpd->power_off_work); 173 173 } 174 174 175 - static int genpd_poweron(struct generic_pm_domain *genpd); 176 - 177 175 /** 178 176 * __genpd_poweron - Restore power to a given PM domain and its masters. 179 177 * @genpd: PM domain to power up. 178 + * @depth: nesting count for lockdep. 180 179 * 181 180 * Restore power to @genpd and all of its masters so that it is possible to 182 181 * resume a device belonging to it. 183 182 */ 184 - static int __genpd_poweron(struct generic_pm_domain *genpd) 183 + static int __genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth) 185 184 { 186 185 struct gpd_link *link; 187 186 int ret = 0; ··· 195 196 * with it. 196 197 */ 197 198 list_for_each_entry(link, &genpd->slave_links, slave_node) { 198 - genpd_sd_counter_inc(link->master); 199 + struct generic_pm_domain *master = link->master; 199 200 200 - ret = genpd_poweron(link->master); 201 + genpd_sd_counter_inc(master); 202 + 203 + mutex_lock_nested(&master->lock, depth + 1); 204 + ret = __genpd_poweron(master, depth + 1); 205 + mutex_unlock(&master->lock); 206 + 201 207 if (ret) { 202 - genpd_sd_counter_dec(link->master); 208 + genpd_sd_counter_dec(master); 203 209 goto err; 204 210 } 205 211 } ··· 236 232 int ret; 237 233 238 234 mutex_lock(&genpd->lock); 239 - ret = __genpd_poweron(genpd); 235 + ret = __genpd_poweron(genpd, 0); 240 236 mutex_unlock(&genpd->lock); 241 237 return ret; 242 238 } 239 + 243 240 244 241 static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) 245 242 { ··· 489 484 } 490 485 491 486 mutex_lock(&genpd->lock); 492 - ret = __genpd_poweron(genpd); 487 + ret = __genpd_poweron(genpd, 0); 493 488 mutex_unlock(&genpd->lock); 494 489 495 490 if (ret) ··· 1344 1339 if (!link) 1345 1340 return -ENOMEM; 1346 1341 1347 - mutex_lock(&genpd->lock); 1348 - mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); 1342 + mutex_lock(&subdomain->lock); 1343 + mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING); 1349 1344 1350 1345 if (genpd->status == GPD_STATE_POWER_OFF 1351 1346 && subdomain->status != GPD_STATE_POWER_OFF) { ··· 1368 1363 genpd_sd_counter_inc(genpd); 1369 1364 1370 1365 out: 1371 - mutex_unlock(&subdomain->lock); 1372 1366 mutex_unlock(&genpd->lock); 1367 + mutex_unlock(&subdomain->lock); 1373 1368 if (ret) 1374 1369 kfree(link); 1375 1370 return ret; ··· 1390 1385 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) 1391 1386 return -EINVAL; 1392 1387 1393 - mutex_lock(&genpd->lock); 1388 + mutex_lock(&subdomain->lock); 1389 + mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING); 1394 1390 1395 1391 if (!list_empty(&subdomain->slave_links) || subdomain->device_count) { 1396 1392 pr_warn("%s: unable to remove subdomain %s\n", genpd->name, ··· 1404 1398 if (link->slave != subdomain) 1405 1399 continue; 1406 1400 1407 - mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); 1408 - 1409 1401 list_del(&link->master_node); 1410 1402 list_del(&link->slave_node); 1411 1403 kfree(link); 1412 1404 if (subdomain->status != GPD_STATE_POWER_OFF) 1413 1405 genpd_sd_counter_dec(genpd); 1414 - 1415 - mutex_unlock(&subdomain->lock); 1416 1406 1417 1407 ret = 0; 1418 1408 break; ··· 1416 1414 1417 1415 out: 1418 1416 mutex_unlock(&genpd->lock); 1417 + mutex_unlock(&subdomain->lock); 1419 1418 1420 1419 return ret; 1421 1420 }
+7 -8
drivers/cpufreq/cpufreq-dt.c
··· 142 142 143 143 try_again: 144 144 cpu_reg = regulator_get_optional(cpu_dev, reg); 145 - if (IS_ERR(cpu_reg)) { 145 + ret = PTR_ERR_OR_ZERO(cpu_reg); 146 + if (ret) { 146 147 /* 147 148 * If cpu's regulator supply node is present, but regulator is 148 149 * not yet registered, we should try defering probe. 149 150 */ 150 - if (PTR_ERR(cpu_reg) == -EPROBE_DEFER) { 151 + if (ret == -EPROBE_DEFER) { 151 152 dev_dbg(cpu_dev, "cpu%d regulator not ready, retry\n", 152 153 cpu); 153 - return -EPROBE_DEFER; 154 + return ret; 154 155 } 155 156 156 157 /* Try with "cpu-supply" */ ··· 160 159 goto try_again; 161 160 } 162 161 163 - dev_dbg(cpu_dev, "no regulator for cpu%d: %ld\n", 164 - cpu, PTR_ERR(cpu_reg)); 162 + dev_dbg(cpu_dev, "no regulator for cpu%d: %d\n", cpu, ret); 165 163 } 166 164 167 165 cpu_clk = clk_get(cpu_dev, NULL); 168 - if (IS_ERR(cpu_clk)) { 166 + ret = PTR_ERR_OR_ZERO(cpu_clk); 167 + if (ret) { 169 168 /* put regulator */ 170 169 if (!IS_ERR(cpu_reg)) 171 170 regulator_put(cpu_reg); 172 - 173 - ret = PTR_ERR(cpu_clk); 174 171 175 172 /* 176 173 * If cpu's clk node is present, but clock is not yet
+3 -3
drivers/cpufreq/cpufreq.c
··· 48 48 bool active) 49 49 { 50 50 do { 51 - policy = list_next_entry(policy, policy_list); 52 - 53 51 /* No more policies in the list */ 54 - if (&policy->policy_list == &cpufreq_policy_list) 52 + if (list_is_last(&policy->policy_list, &cpufreq_policy_list)) 55 53 return NULL; 54 + 55 + policy = list_next_entry(policy, policy_list); 56 56 } while (!suitable_policy(policy, active)); 57 57 58 58 return policy;
+8 -3
drivers/cpufreq/cpufreq_governor.c
··· 387 387 if (!have_governor_per_policy()) 388 388 cdata->gdbs_data = dbs_data; 389 389 390 + policy->governor_data = dbs_data; 391 + 390 392 ret = sysfs_create_group(get_governor_parent_kobj(policy), 391 393 get_sysfs_attr(dbs_data)); 392 394 if (ret) 393 395 goto reset_gdbs_data; 394 396 395 - policy->governor_data = dbs_data; 396 - 397 397 return 0; 398 398 399 399 reset_gdbs_data: 400 + policy->governor_data = NULL; 401 + 400 402 if (!have_governor_per_policy()) 401 403 cdata->gdbs_data = NULL; 402 404 cdata->exit(dbs_data, !policy->governor->initialized); ··· 419 417 if (!cdbs->shared || cdbs->shared->policy) 420 418 return -EBUSY; 421 419 422 - policy->governor_data = NULL; 423 420 if (!--dbs_data->usage_count) { 424 421 sysfs_remove_group(get_governor_parent_kobj(policy), 425 422 get_sysfs_attr(dbs_data)); 423 + 424 + policy->governor_data = NULL; 426 425 427 426 if (!have_governor_per_policy()) 428 427 cdata->gdbs_data = NULL; 429 428 430 429 cdata->exit(dbs_data, policy->governor->initialized == 1); 431 430 kfree(dbs_data); 431 + } else { 432 + policy->governor_data = NULL; 432 433 } 433 434 434 435 free_common_dbs_info(policy, cdata);
+1 -1
drivers/cpufreq/pxa2xx-cpufreq.c
··· 202 202 } 203 203 } 204 204 #else 205 - static int pxa_cpufreq_change_voltage(struct pxa_freqs *pxa_freq) 205 + static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) 206 206 { 207 207 return 0; 208 208 }
-1
drivers/cpuidle/coupled.c
··· 119 119 120 120 #define CPUIDLE_COUPLED_NOT_IDLE (-1) 121 121 122 - static DEFINE_MUTEX(cpuidle_coupled_lock); 123 122 static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb); 124 123 125 124 /*
+1 -1
drivers/cpuidle/cpuidle.c
··· 153 153 * be frozen safely. 154 154 */ 155 155 index = find_deepest_state(drv, dev, UINT_MAX, 0, true); 156 - if (index >= 0) 156 + if (index > 0) 157 157 enter_freeze_proper(drv, dev, index); 158 158 159 159 return index;
+3 -1
drivers/pci/hotplug/acpiphp_glue.c
··· 953 953 { 954 954 pci_lock_rescan_remove(); 955 955 956 - if (slot->flags & SLOT_IS_GOING_AWAY) 956 + if (slot->flags & SLOT_IS_GOING_AWAY) { 957 + pci_unlock_rescan_remove(); 957 958 return -ENODEV; 959 + } 958 960 959 961 /* configure all functions */ 960 962 if (!(slot->flags & SLOT_ENABLED))
+1 -1
kernel/power/Kconfig
··· 235 235 236 236 config APM_EMULATION 237 237 tristate "Advanced Power Management Emulation" 238 - depends on PM && SYS_SUPPORTS_APM_EMULATION 238 + depends on SYS_SUPPORTS_APM_EMULATION 239 239 help 240 240 APM is a BIOS specification for saving power using several different 241 241 techniques. This is mostly useful for battery powered laptops with
+1 -1
kernel/sched/idle.c
··· 162 162 */ 163 163 if (idle_should_freeze()) { 164 164 entered_state = cpuidle_enter_freeze(drv, dev); 165 - if (entered_state >= 0) { 165 + if (entered_state > 0) { 166 166 local_irq_enable(); 167 167 goto exit_idle; 168 168 }