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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm+acpi-3.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI and power management fixes from Rafael Wysocki:
"These are three regression fixes, two recent (generic power domains,
suspend-to-idle) and one older (cpufreq), an ACPI blacklist entry for
one more machine having problems with Windows 8 compatibility, a minor
cpufreq driver fix (cpufreq-dt) and a fixup for new callback
definitions (generic power domains).

Specifics:

- Fix a crash in the suspend-to-idle code path introduced by a recent
commit that forgot to check a pointer against NULL before
dereferencing it (Dmitry Eremin-Solenikov).

- Fix a boot crash on Exynos5 introduced by a recent commit making
that platform use generic Device Tree bindings for power domains
which exposed a weakness in the generic power domains framework
leading to that crash (Ulf Hansson).

- Fix a crash during system resume on systems where cpufreq depends
on Operation Performance Points (OPP) for functionality, but
CONFIG_OPP is not set. This leads the cpufreq driver registration
to fail, but the resume code attempts to restore the pre-suspend
cpufreq configuration (which does not exist) nevertheless and
crashes. From Geert Uytterhoeven.

- Add a new ACPI blacklist entry for Dell Vostro 3546 that has
problems if it is reported as Windows 8 compatible to the BIOS
(Adam Lee).

- Fix swapped arguments in an error message in the cpufreq-dt driver
(Abhilash Kesavan).

- Fix up the prototypes of new callbacks in struct generic_pm_domain
to make them more useful. Users of those callbacks will be added
in 3.19 and it's better for them to be based on the correct struct
definition in mainline from the start. From Ulf Hansson and Kevin
Hilman"

* tag 'pm+acpi-3.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM / Domains: Fix initial default state of the need_restore flag
PM / sleep: Fix entering suspend-to-IDLE if no freeze_oops is set
PM / Domains: Change prototype for the attach and detach callbacks
cpufreq: Avoid crash in resume on SMP without OPP
cpufreq: cpufreq-dt: Fix arguments in clock failure error message
ACPI / blacklist: blacklist Win8 OSI for Dell Vostro 3546

+53 -16
+8
drivers/acpi/blacklist.c
··· 290 290 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"), 291 291 }, 292 292 }, 293 + { 294 + .callback = dmi_disable_osi_win8, 295 + .ident = "Dell Vostro 3546", 296 + .matches = { 297 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 298 + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"), 299 + }, 300 + }, 293 301 294 302 /* 295 303 * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
+34 -8
drivers/base/power/domain.c
··· 361 361 struct device *dev = pdd->dev; 362 362 int ret = 0; 363 363 364 - if (gpd_data->need_restore) 364 + if (gpd_data->need_restore > 0) 365 365 return 0; 366 + 367 + /* 368 + * If the value of the need_restore flag is still unknown at this point, 369 + * we trust that pm_genpd_poweroff() has verified that the device is 370 + * already runtime PM suspended. 371 + */ 372 + if (gpd_data->need_restore < 0) { 373 + gpd_data->need_restore = 1; 374 + return 0; 375 + } 366 376 367 377 mutex_unlock(&genpd->lock); 368 378 ··· 383 373 mutex_lock(&genpd->lock); 384 374 385 375 if (!ret) 386 - gpd_data->need_restore = true; 376 + gpd_data->need_restore = 1; 387 377 388 378 return ret; 389 379 } ··· 399 389 { 400 390 struct generic_pm_domain_data *gpd_data = to_gpd_data(pdd); 401 391 struct device *dev = pdd->dev; 402 - bool need_restore = gpd_data->need_restore; 392 + int need_restore = gpd_data->need_restore; 403 393 404 - gpd_data->need_restore = false; 394 + gpd_data->need_restore = 0; 405 395 mutex_unlock(&genpd->lock); 406 396 407 397 genpd_start_dev(genpd, dev); 398 + 399 + /* 400 + * Call genpd_restore_dev() for recently added devices too (need_restore 401 + * is negative then). 402 + */ 408 403 if (need_restore) 409 404 genpd_restore_dev(genpd, dev); 410 405 ··· 618 603 static int pm_genpd_runtime_suspend(struct device *dev) 619 604 { 620 605 struct generic_pm_domain *genpd; 606 + struct generic_pm_domain_data *gpd_data; 621 607 bool (*stop_ok)(struct device *__dev); 622 608 int ret; 623 609 ··· 644 628 return 0; 645 629 646 630 mutex_lock(&genpd->lock); 631 + 632 + /* 633 + * If we have an unknown state of the need_restore flag, it means none 634 + * of the runtime PM callbacks has been invoked yet. Let's update the 635 + * flag to reflect that the current state is active. 636 + */ 637 + gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); 638 + if (gpd_data->need_restore < 0) 639 + gpd_data->need_restore = 0; 640 + 647 641 genpd->in_progress++; 648 642 pm_genpd_poweroff(genpd); 649 643 genpd->in_progress--; ··· 1463 1437 spin_unlock_irq(&dev->power.lock); 1464 1438 1465 1439 if (genpd->attach_dev) 1466 - genpd->attach_dev(dev); 1440 + genpd->attach_dev(genpd, dev); 1467 1441 1468 1442 mutex_lock(&gpd_data->lock); 1469 1443 gpd_data->base.dev = dev; 1470 1444 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); 1471 - gpd_data->need_restore = genpd->status == GPD_STATE_POWER_OFF; 1445 + gpd_data->need_restore = -1; 1472 1446 gpd_data->td.constraint_changed = true; 1473 1447 gpd_data->td.effective_constraint_ns = -1; 1474 1448 mutex_unlock(&gpd_data->lock); ··· 1525 1499 genpd->max_off_time_changed = true; 1526 1500 1527 1501 if (genpd->detach_dev) 1528 - genpd->detach_dev(dev); 1502 + genpd->detach_dev(genpd, dev); 1529 1503 1530 1504 spin_lock_irq(&dev->power.lock); 1531 1505 ··· 1572 1546 1573 1547 psd = dev_to_psd(dev); 1574 1548 if (psd && psd->domain_data) 1575 - to_gpd_data(psd->domain_data)->need_restore = val; 1549 + to_gpd_data(psd->domain_data)->need_restore = val ? 1 : 0; 1576 1550 1577 1551 spin_unlock_irqrestore(&dev->power.lock, flags); 1578 1552 }
+2 -2
drivers/cpufreq/cpufreq-dt.c
··· 166 166 if (ret == -EPROBE_DEFER) 167 167 dev_dbg(cpu_dev, "cpu%d clock not ready, retry\n", cpu); 168 168 else 169 - dev_err(cpu_dev, "failed to get cpu%d clock: %d\n", ret, 170 - cpu); 169 + dev_err(cpu_dev, "failed to get cpu%d clock: %d\n", cpu, 170 + ret); 171 171 } else { 172 172 *cdev = cpu_dev; 173 173 *creg = cpu_reg;
+2 -1
drivers/cpufreq/cpufreq.c
··· 1022 1022 1023 1023 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1024 1024 1025 - policy->governor = NULL; 1025 + if (policy) 1026 + policy->governor = NULL; 1026 1027 1027 1028 return policy; 1028 1029 }
+5 -3
include/linux/pm_domain.h
··· 72 72 bool max_off_time_changed; 73 73 bool cached_power_down_ok; 74 74 struct gpd_cpuidle_data *cpuidle_data; 75 - void (*attach_dev)(struct device *dev); 76 - void (*detach_dev)(struct device *dev); 75 + int (*attach_dev)(struct generic_pm_domain *domain, 76 + struct device *dev); 77 + void (*detach_dev)(struct generic_pm_domain *domain, 78 + struct device *dev); 77 79 }; 78 80 79 81 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd) ··· 106 104 struct notifier_block nb; 107 105 struct mutex lock; 108 106 unsigned int refcount; 109 - bool need_restore; 107 + int need_restore; 110 108 }; 111 109 112 110 #ifdef CONFIG_PM_GENERIC_DOMAINS
+2 -2
kernel/power/suspend.c
··· 146 146 147 147 static int platform_suspend_prepare_late(suspend_state_t state) 148 148 { 149 - return state == PM_SUSPEND_FREEZE && freeze_ops->prepare ? 149 + return state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->prepare ? 150 150 freeze_ops->prepare() : 0; 151 151 } 152 152 ··· 164 164 165 165 static void platform_resume_early(suspend_state_t state) 166 166 { 167 - if (state == PM_SUSPEND_FREEZE && freeze_ops->restore) 167 + if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->restore) 168 168 freeze_ops->restore(); 169 169 } 170 170