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 Original line Diff line number Diff line
@@ -114,18 +114,26 @@ Required properties:
 - power-domains : A list of PM domain specifiers, as defined by bindings of
 - power-domains : A list of PM domain specifiers, as defined by bindings of
		the power controller that is the PM domain provider.
		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:
Example:


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


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


The first example above defines a typical PM domain consumer device, which is
The first example above defines a typical PM domain consumer device, which is
+8 −4
Original line number Original line Diff line number Diff line
@@ -81,10 +81,14 @@ integration is desired.
Two other flags are specifically targeted at use cases where the device
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``
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
can be specified to runtime resume the supplier upon addition of the
device link.  ``DL_FLAG_AUTOREMOVE`` causes the device link to be automatically
device link.  ``DL_FLAG_AUTOREMOVE_CONSUMER`` causes the device link to be
purged when the consumer fails to probe or later unbinds.  This obviates
automatically purged when the consumer fails to probe or later unbinds.
the need to explicitly delete the link in the ``->remove`` callback or in
This obviates the need to explicitly delete the link in the ``->remove``
the error path of the ``->probe`` callback.
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
Limitations
===========
===========
+6 −6
Original line number Original line Diff line number Diff line
@@ -204,26 +204,26 @@ VI. Are there any precautions to be taken to prevent freezing failures?


Yes, there are.
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.
from system-wide sleep such as suspend/hibernation is not encouraged.
If possible, that piece of code must instead hook onto the suspend/hibernation
If possible, that piece of code must instead hook onto the suspend/hibernation
notifiers to achieve mutual exclusion. Look at the CPU-Hotplug code
notifiers to achieve mutual exclusion. Look at the CPU-Hotplug code
(kernel/cpu.c) for an example.
(kernel/cpu.c) for an example.


However, if that is not feasible, and grabbing 'pm_mutex' is deemed necessary,
However, if that is not feasible, and grabbing 'system_transition_mutex' is deemed necessary,
it is strongly discouraged to directly call mutex_[un]lock(&pm_mutex) since
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
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
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,
state. As a consequence, the freezer would not be able to freeze that task,
leading to freezing failure.
leading to freezing failure.


However, the [un]lock_system_sleep() APIs are safe to use in this scenario,
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
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.
only after the entire suspend/hibernation sequence is complete.
So, to summarize, use [un]lock_system_sleep() instead of directly using
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
V. Miscellaneous
/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
+3 −3
Original line number Original line Diff line number Diff line
@@ -32,7 +32,7 @@ More details follow:
                                    sysfs file
                                    sysfs file
                                        |
                                        |
                                        v
                                        v
                               Acquire pm_mutex lock
                               Acquire system_transition_mutex lock
                                        |
                                        |
                                        v
                                        v
                             Send PM_SUSPEND_PREPARE
                             Send PM_SUSPEND_PREPARE
@@ -96,10 +96,10 @@ execution during resume):


* thaw tasks
* thaw tasks
* send PM_POST_SUSPEND notifications
* 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
beginning, when we are just starting out to suspend, and then released only
after the entire cycle is complete (i.e., suspend + resume).
after the entire cycle is complete (i.e., suspend + resume).


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


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


	{
	desc = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(tfm),
		AHASH_REQUEST_ON_STACK(req, tfm);
		       GFP_KERNEL);
		size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry) * table->nr_entries;
	if (!desc) {
		ahash_request_set_tfm(req, tfm);
		ret = -ENOMEM;
		sg_init_one(&sg, (u8 *)table, size);
		goto free_tfm;
		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);
	}
	}
	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;
	return ret;
}
}


Loading