Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17bc3432 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pm-core', 'pm-domains', 'pm-sleep', 'acpi-pm' and 'pm-cpuidle'

Merge changes in the PM core, system-wide PM infrastructure, generic
power domains (genpd) framework, ACPI PM infrastructure and cpuidle
for 4.19.

* pm-core:
  driver core: Add flag to autoremove device link on supplier unbind
  driver core: Rename flag AUTOREMOVE to AUTOREMOVE_CONSUMER

* pm-domains:
  PM / Domains: Introduce dev_pm_domain_attach_by_name()
  PM / Domains: Introduce option to attach a device by name to genpd
  PM / Domains: dt: Add a power-domain-names property

* pm-sleep:
  PM / reboot: Eliminate race between reboot and suspend
  PM / hibernate: Mark expected switch fall-through
  x86/power/hibernate_64: Remove VLA usage
  PM / hibernate: cast PAGE_SIZE to int when comparing with error code

* acpi-pm:
  ACPI / PM: save NVS memory for ASUS 1025C laptop
  ACPI / PM: Default to s2idle in all machines supporting LP S0

* pm-cpuidle:
  ARM: cpuidle: silence error on driver registration failure
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -114,18 +114,26 @@ Required properties:
 - power-domains : A list of PM domain specifiers, as defined by bindings of
		the power controller that is the PM domain provider.

Optional properties:
 - power-domain-names : A list of power domain name strings sorted in the same
		order as the power-domains property. Consumers drivers will use
		power-domain-names to match power domains with power-domains
		specifiers.

Example:

	leaky-device@12350000 {
		compatible = "foo,i-leak-current";
		reg = <0x12350000 0x1000>;
		power-domains = <&power 0>;
		power-domain-names = "io";
	};

	leaky-device@12351000 {
		compatible = "foo,i-leak-current";
		reg = <0x12351000 0x1000>;
		power-domains = <&power 0>, <&power 1> ;
		power-domain-names = "io", "clk";
	};

The first example above defines a typical PM domain consumer device, which is
+8 −4
Original line number Diff line number Diff line
@@ -81,10 +81,14 @@ integration is desired.
Two other flags are specifically targeted at use cases where the device
link is added from the consumer's ``->probe`` callback:  ``DL_FLAG_RPM_ACTIVE``
can be specified to runtime resume the supplier upon addition of the
device link.  ``DL_FLAG_AUTOREMOVE`` causes the device link to be automatically
purged when the consumer fails to probe or later unbinds.  This obviates
the need to explicitly delete the link in the ``->remove`` callback or in
the error path of the ``->probe`` callback.
device link.  ``DL_FLAG_AUTOREMOVE_CONSUMER`` causes the device link to be
automatically purged when the consumer fails to probe or later unbinds.
This obviates the need to explicitly delete the link in the ``->remove``
callback or in the error path of the ``->probe`` callback.

Similarly, when the device link is added from supplier's ``->probe`` callback,
``DL_FLAG_AUTOREMOVE_SUPPLIER`` causes the device link to be automatically
purged when the supplier fails to probe or later unbinds.

Limitations
===========
+6 −6
Original line number Diff line number Diff line
@@ -204,26 +204,26 @@ VI. Are there any precautions to be taken to prevent freezing failures?

Yes, there are.

First of all, grabbing the 'pm_mutex' lock to mutually exclude a piece of code
First of all, grabbing the 'system_transition_mutex' lock to mutually exclude a piece of code
from system-wide sleep such as suspend/hibernation is not encouraged.
If possible, that piece of code must instead hook onto the suspend/hibernation
notifiers to achieve mutual exclusion. Look at the CPU-Hotplug code
(kernel/cpu.c) for an example.

However, if that is not feasible, and grabbing 'pm_mutex' is deemed necessary,
it is strongly discouraged to directly call mutex_[un]lock(&pm_mutex) since
However, if that is not feasible, and grabbing 'system_transition_mutex' is deemed necessary,
it is strongly discouraged to directly call mutex_[un]lock(&system_transition_mutex) since
that could lead to freezing failures, because if the suspend/hibernate code
successfully acquired the 'pm_mutex' lock, and hence that other entity failed
successfully acquired the 'system_transition_mutex' lock, and hence that other entity failed
to acquire the lock, then that task would get blocked in TASK_UNINTERRUPTIBLE
state. As a consequence, the freezer would not be able to freeze that task,
leading to freezing failure.

However, the [un]lock_system_sleep() APIs are safe to use in this scenario,
since they ask the freezer to skip freezing this task, since it is anyway
"frozen enough" as it is blocked on 'pm_mutex', which will be released
"frozen enough" as it is blocked on 'system_transition_mutex', which will be released
only after the entire suspend/hibernation sequence is complete.
So, to summarize, use [un]lock_system_sleep() instead of directly using
mutex_[un]lock(&pm_mutex). That would prevent freezing failures.
mutex_[un]lock(&system_transition_mutex). That would prevent freezing failures.

V. Miscellaneous
/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
+3 −3
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ More details follow:
                                    sysfs file
                                        |
                                        v
                               Acquire pm_mutex lock
                               Acquire system_transition_mutex lock
                                        |
                                        v
                             Send PM_SUSPEND_PREPARE
@@ -96,10 +96,10 @@ execution during resume):

* thaw tasks
* send PM_POST_SUSPEND notifications
* Release pm_mutex lock.
* Release system_transition_mutex lock.


It is to be noted here that the pm_mutex lock is acquired at the very
It is to be noted here that the system_transition_mutex lock is acquired at the very
beginning, when we are just starting out to suspend, and then released only
after the entire cycle is complete (i.e., suspend + resume).

+21 −15
Original line number Diff line number Diff line
@@ -233,29 +233,35 @@ struct restore_data_record {
 */
static int get_e820_md5(struct e820_table *table, void *buf)
{
	struct scatterlist sg;
	struct crypto_ahash *tfm;
	struct crypto_shash *tfm;
	struct shash_desc *desc;
	int size;
	int ret = 0;

	tfm = crypto_alloc_ahash("md5", 0, CRYPTO_ALG_ASYNC);
	tfm = crypto_alloc_shash("md5", 0, 0);
	if (IS_ERR(tfm))
		return -ENOMEM;

	{
		AHASH_REQUEST_ON_STACK(req, tfm);
		size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry) * table->nr_entries;
		ahash_request_set_tfm(req, tfm);
		sg_init_one(&sg, (u8 *)table, size);
		ahash_request_set_callback(req, 0, NULL, NULL);
		ahash_request_set_crypt(req, &sg, buf, size);

		if (crypto_ahash_digest(req))
			ret = -EINVAL;
		ahash_request_zero(req);
	desc = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(tfm),
		       GFP_KERNEL);
	if (!desc) {
		ret = -ENOMEM;
		goto free_tfm;
	}
	crypto_free_ahash(tfm);

	desc->tfm = tfm;
	desc->flags = 0;

	size = offsetof(struct e820_table, entries) +
		sizeof(struct e820_entry) * table->nr_entries;

	if (crypto_shash_digest(desc, (u8 *)table, size, buf))
		ret = -EINVAL;

	kzfree(desc);

free_tfm:
	crypto_free_shash(tfm);
	return ret;
}

Loading