License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2020-02-12 07:35:39 +08:00
|
|
|
/*
|
|
|
|
* Definitions related to Power Management Quality of Service (PM QoS).
|
pm qos infrastructure and interface
The following patch is a generalization of the latency.c implementation done
by Arjan last year. It provides infrastructure for more than one parameter,
and exposes a user mode interface for processes to register pm_qos
expectations of processes.
This interface provides a kernel and user mode interface for registering
performance expectations by drivers, subsystems and user space applications on
one of the parameters.
Currently we have {cpu_dma_latency, network_latency, network_throughput} as
the initial set of pm_qos parameters.
The infrastructure exposes multiple misc device nodes one per implemented
parameter. The set of parameters implement is defined by pm_qos_power_init()
and pm_qos_params.h. This is done because having the available parameters
being runtime configurable or changeable from a driver was seen as too easy to
abuse.
For each parameter a list of performance requirements is maintained along with
an aggregated target value. The aggregated target value is updated with
changes to the requirement list or elements of the list. Typically the
aggregated target value is simply the max or min of the requirement values
held in the parameter list elements.
>From kernel mode the use of this interface is simple:
pm_qos_add_requirement(param_id, name, target_value):
Will insert a named element in the list for that identified PM_QOS
parameter with the target value. Upon change to this list the new target is
recomputed and any registered notifiers are called only if the target value
is now different.
pm_qos_update_requirement(param_id, name, new_target_value):
Will search the list identified by the param_id for the named list element
and then update its target value, calling the notification tree if the
aggregated target is changed. with that name is already registered.
pm_qos_remove_requirement(param_id, name):
Will search the identified list for the named element and remove it, after
removal it will update the aggregate target and call the notification tree
if the target was changed as a result of removing the named requirement.
>From user mode:
Only processes can register a pm_qos requirement. To provide for
automatic cleanup for process the interface requires the process to register
its parameter requirements in the following way:
To register the default pm_qos target for the specific parameter, the
process must open one of /dev/[cpu_dma_latency, network_latency,
network_throughput]
As long as the device node is held open that process has a registered
requirement on the parameter. The name of the requirement is
"process_<PID>" derived from the current->pid from within the open system
call.
To change the requested target value the process needs to write a s32
value to the open device node. This translates to a
pm_qos_update_requirement call.
To remove the user mode request for a target value simply close the device
node.
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foundation.org: fix build]
[akpm@linux-foundation.org: fix build again]
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: mark gross <mgross@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jaroslav Kysela <perex@suse.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Venki Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Adam Belay <abelay@novell.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-05 14:30:08 +08:00
|
|
|
*
|
2020-02-12 07:35:39 +08:00
|
|
|
* Copyright (C) 2020 Intel Corporation
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Mark Gross <mgross@linux.intel.com>
|
|
|
|
* Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
pm qos infrastructure and interface
The following patch is a generalization of the latency.c implementation done
by Arjan last year. It provides infrastructure for more than one parameter,
and exposes a user mode interface for processes to register pm_qos
expectations of processes.
This interface provides a kernel and user mode interface for registering
performance expectations by drivers, subsystems and user space applications on
one of the parameters.
Currently we have {cpu_dma_latency, network_latency, network_throughput} as
the initial set of pm_qos parameters.
The infrastructure exposes multiple misc device nodes one per implemented
parameter. The set of parameters implement is defined by pm_qos_power_init()
and pm_qos_params.h. This is done because having the available parameters
being runtime configurable or changeable from a driver was seen as too easy to
abuse.
For each parameter a list of performance requirements is maintained along with
an aggregated target value. The aggregated target value is updated with
changes to the requirement list or elements of the list. Typically the
aggregated target value is simply the max or min of the requirement values
held in the parameter list elements.
>From kernel mode the use of this interface is simple:
pm_qos_add_requirement(param_id, name, target_value):
Will insert a named element in the list for that identified PM_QOS
parameter with the target value. Upon change to this list the new target is
recomputed and any registered notifiers are called only if the target value
is now different.
pm_qos_update_requirement(param_id, name, new_target_value):
Will search the list identified by the param_id for the named list element
and then update its target value, calling the notification tree if the
aggregated target is changed. with that name is already registered.
pm_qos_remove_requirement(param_id, name):
Will search the identified list for the named element and remove it, after
removal it will update the aggregate target and call the notification tree
if the target was changed as a result of removing the named requirement.
>From user mode:
Only processes can register a pm_qos requirement. To provide for
automatic cleanup for process the interface requires the process to register
its parameter requirements in the following way:
To register the default pm_qos target for the specific parameter, the
process must open one of /dev/[cpu_dma_latency, network_latency,
network_throughput]
As long as the device node is held open that process has a registered
requirement on the parameter. The name of the requirement is
"process_<PID>" derived from the current->pid from within the open system
call.
To change the requested target value the process needs to write a s32
value to the open device node. This translates to a
pm_qos_update_requirement call.
To remove the user mode request for a target value simply close the device
node.
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foundation.org: fix build]
[akpm@linux-foundation.org: fix build again]
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: mark gross <mgross@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jaroslav Kysela <perex@suse.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Venki Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Adam Belay <abelay@novell.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-05 14:30:08 +08:00
|
|
|
*/
|
2020-02-12 07:35:39 +08:00
|
|
|
|
|
|
|
#ifndef _LINUX_PM_QOS_H
|
|
|
|
#define _LINUX_PM_QOS_H
|
|
|
|
|
2010-07-06 04:53:06 +08:00
|
|
|
#include <linux/plist.h>
|
pm qos infrastructure and interface
The following patch is a generalization of the latency.c implementation done
by Arjan last year. It provides infrastructure for more than one parameter,
and exposes a user mode interface for processes to register pm_qos
expectations of processes.
This interface provides a kernel and user mode interface for registering
performance expectations by drivers, subsystems and user space applications on
one of the parameters.
Currently we have {cpu_dma_latency, network_latency, network_throughput} as
the initial set of pm_qos parameters.
The infrastructure exposes multiple misc device nodes one per implemented
parameter. The set of parameters implement is defined by pm_qos_power_init()
and pm_qos_params.h. This is done because having the available parameters
being runtime configurable or changeable from a driver was seen as too easy to
abuse.
For each parameter a list of performance requirements is maintained along with
an aggregated target value. The aggregated target value is updated with
changes to the requirement list or elements of the list. Typically the
aggregated target value is simply the max or min of the requirement values
held in the parameter list elements.
>From kernel mode the use of this interface is simple:
pm_qos_add_requirement(param_id, name, target_value):
Will insert a named element in the list for that identified PM_QOS
parameter with the target value. Upon change to this list the new target is
recomputed and any registered notifiers are called only if the target value
is now different.
pm_qos_update_requirement(param_id, name, new_target_value):
Will search the list identified by the param_id for the named list element
and then update its target value, calling the notification tree if the
aggregated target is changed. with that name is already registered.
pm_qos_remove_requirement(param_id, name):
Will search the identified list for the named element and remove it, after
removal it will update the aggregate target and call the notification tree
if the target was changed as a result of removing the named requirement.
>From user mode:
Only processes can register a pm_qos requirement. To provide for
automatic cleanup for process the interface requires the process to register
its parameter requirements in the following way:
To register the default pm_qos target for the specific parameter, the
process must open one of /dev/[cpu_dma_latency, network_latency,
network_throughput]
As long as the device node is held open that process has a registered
requirement on the parameter. The name of the requirement is
"process_<PID>" derived from the current->pid from within the open system
call.
To change the requested target value the process needs to write a s32
value to the open device node. This translates to a
pm_qos_update_requirement call.
To remove the user mode request for a target value simply close the device
node.
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foundation.org: fix build]
[akpm@linux-foundation.org: fix build again]
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: mark gross <mgross@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jaroslav Kysela <perex@suse.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Venki Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Adam Belay <abelay@novell.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-05 14:30:08 +08:00
|
|
|
#include <linux/notifier.h>
|
2011-09-30 04:29:44 +08:00
|
|
|
#include <linux/device.h>
|
pm qos infrastructure and interface
The following patch is a generalization of the latency.c implementation done
by Arjan last year. It provides infrastructure for more than one parameter,
and exposes a user mode interface for processes to register pm_qos
expectations of processes.
This interface provides a kernel and user mode interface for registering
performance expectations by drivers, subsystems and user space applications on
one of the parameters.
Currently we have {cpu_dma_latency, network_latency, network_throughput} as
the initial set of pm_qos parameters.
The infrastructure exposes multiple misc device nodes one per implemented
parameter. The set of parameters implement is defined by pm_qos_power_init()
and pm_qos_params.h. This is done because having the available parameters
being runtime configurable or changeable from a driver was seen as too easy to
abuse.
For each parameter a list of performance requirements is maintained along with
an aggregated target value. The aggregated target value is updated with
changes to the requirement list or elements of the list. Typically the
aggregated target value is simply the max or min of the requirement values
held in the parameter list elements.
>From kernel mode the use of this interface is simple:
pm_qos_add_requirement(param_id, name, target_value):
Will insert a named element in the list for that identified PM_QOS
parameter with the target value. Upon change to this list the new target is
recomputed and any registered notifiers are called only if the target value
is now different.
pm_qos_update_requirement(param_id, name, new_target_value):
Will search the list identified by the param_id for the named list element
and then update its target value, calling the notification tree if the
aggregated target is changed. with that name is already registered.
pm_qos_remove_requirement(param_id, name):
Will search the identified list for the named element and remove it, after
removal it will update the aggregate target and call the notification tree
if the target was changed as a result of removing the named requirement.
>From user mode:
Only processes can register a pm_qos requirement. To provide for
automatic cleanup for process the interface requires the process to register
its parameter requirements in the following way:
To register the default pm_qos target for the specific parameter, the
process must open one of /dev/[cpu_dma_latency, network_latency,
network_throughput]
As long as the device node is held open that process has a registered
requirement on the parameter. The name of the requirement is
"process_<PID>" derived from the current->pid from within the open system
call.
To change the requested target value the process needs to write a s32
value to the open device node. This translates to a
pm_qos_update_requirement call.
To remove the user mode request for a target value simply close the device
node.
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foundation.org: fix build]
[akpm@linux-foundation.org: fix build again]
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: mark gross <mgross@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jaroslav Kysela <perex@suse.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Venki Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Adam Belay <abelay@novell.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-05 14:30:08 +08:00
|
|
|
|
2012-10-23 07:09:12 +08:00
|
|
|
enum pm_qos_flags_status {
|
|
|
|
PM_QOS_FLAGS_UNDEFINED = -1,
|
|
|
|
PM_QOS_FLAGS_NONE,
|
|
|
|
PM_QOS_FLAGS_SOME,
|
|
|
|
PM_QOS_FLAGS_ALL,
|
|
|
|
};
|
|
|
|
|
2017-11-07 18:33:49 +08:00
|
|
|
#define PM_QOS_DEFAULT_VALUE (-1)
|
|
|
|
#define PM_QOS_LATENCY_ANY S32_MAX
|
|
|
|
#define PM_QOS_LATENCY_ANY_NS ((s64)PM_QOS_LATENCY_ANY * NSEC_PER_USEC)
|
pm qos infrastructure and interface
The following patch is a generalization of the latency.c implementation done
by Arjan last year. It provides infrastructure for more than one parameter,
and exposes a user mode interface for processes to register pm_qos
expectations of processes.
This interface provides a kernel and user mode interface for registering
performance expectations by drivers, subsystems and user space applications on
one of the parameters.
Currently we have {cpu_dma_latency, network_latency, network_throughput} as
the initial set of pm_qos parameters.
The infrastructure exposes multiple misc device nodes one per implemented
parameter. The set of parameters implement is defined by pm_qos_power_init()
and pm_qos_params.h. This is done because having the available parameters
being runtime configurable or changeable from a driver was seen as too easy to
abuse.
For each parameter a list of performance requirements is maintained along with
an aggregated target value. The aggregated target value is updated with
changes to the requirement list or elements of the list. Typically the
aggregated target value is simply the max or min of the requirement values
held in the parameter list elements.
>From kernel mode the use of this interface is simple:
pm_qos_add_requirement(param_id, name, target_value):
Will insert a named element in the list for that identified PM_QOS
parameter with the target value. Upon change to this list the new target is
recomputed and any registered notifiers are called only if the target value
is now different.
pm_qos_update_requirement(param_id, name, new_target_value):
Will search the list identified by the param_id for the named list element
and then update its target value, calling the notification tree if the
aggregated target is changed. with that name is already registered.
pm_qos_remove_requirement(param_id, name):
Will search the identified list for the named element and remove it, after
removal it will update the aggregate target and call the notification tree
if the target was changed as a result of removing the named requirement.
>From user mode:
Only processes can register a pm_qos requirement. To provide for
automatic cleanup for process the interface requires the process to register
its parameter requirements in the following way:
To register the default pm_qos target for the specific parameter, the
process must open one of /dev/[cpu_dma_latency, network_latency,
network_throughput]
As long as the device node is held open that process has a registered
requirement on the parameter. The name of the requirement is
"process_<PID>" derived from the current->pid from within the open system
call.
To change the requested target value the process needs to write a s32
value to the open device node. This translates to a
pm_qos_update_requirement call.
To remove the user mode request for a target value simply close the device
node.
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foundation.org: fix build]
[akpm@linux-foundation.org: fix build again]
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: mark gross <mgross@linux.intel.com>
Cc: "John W. Linville" <linville@tuxdriver.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Jaroslav Kysela <perex@suse.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Arjan van de Ven <arjan@infradead.org>
Cc: Venki Pallipadi <venkatesh.pallipadi@intel.com>
Cc: Adam Belay <abelay@novell.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-05 14:30:08 +08:00
|
|
|
|
2020-02-12 07:04:31 +08:00
|
|
|
#define PM_QOS_CPU_LATENCY_DEFAULT_VALUE (2000 * USEC_PER_SEC)
|
2017-11-07 18:33:49 +08:00
|
|
|
#define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE PM_QOS_LATENCY_ANY
|
|
|
|
#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT PM_QOS_LATENCY_ANY
|
|
|
|
#define PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS PM_QOS_LATENCY_ANY_NS
|
PM / QoS: Introcuce latency tolerance device PM QoS type
Add a new latency tolerance device PM QoS type to be use for
specifying active state (RPM_ACTIVE) memory access (DMA) latency
tolerance requirements for devices. It may be used to prevent
hardware from choosing overly aggressive energy-saving operation
modes (causing too much latency to appear) for the whole platform.
This feature reqiures hardware support, so it only will be
available for devices having a new .set_latency_tolerance()
callback in struct dev_pm_info populated, in which case the
routine pointed to by it should implement whatever is necessary
to transfer the effective requirement value to the hardware.
Whenever the effective latency tolerance changes for the device,
its .set_latency_tolerance() callback will be executed and the
effective value will be passed to it. If that value is negative,
which means that the list of latency tolerance requirements for
the device is empty, the callback is expected to switch the
underlying hardware latency tolerance control mechanism to an
autonomous mode if available. If that value is PM_QOS_LATENCY_ANY,
in turn, and the hardware supports a special "no requirement"
setting, the callback is expected to use it. That allows software
to prevent the hardware from automatically updating the device's
latency tolerance in response to its power state changes (e.g. during
transitions from D3cold to D0), which generally may be done in the
autonomous latency tolerance control mode.
If .set_latency_tolerance() is present for the device, a new
pm_qos_latency_tolerance_us attribute will be present in the
devivce's power directory in sysfs. Then, user space can use
that attribute to specify its latency tolerance requirement for
the device, if any. Writing "any" to it means "no requirement, but
do not let the hardware control latency tolerance" and writing
"auto" to it allows the hardware to be switched to the autonomous
mode if there are no other requirements from the kernel side in the
device's list.
This changeset includes a fix from Mika Westerberg.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-11 07:35:38 +08:00
|
|
|
#define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0
|
2019-11-26 23:17:13 +08:00
|
|
|
#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE 0
|
|
|
|
#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE FREQ_QOS_MAX_DEFAULT_VALUE
|
PM / QoS: Introcuce latency tolerance device PM QoS type
Add a new latency tolerance device PM QoS type to be use for
specifying active state (RPM_ACTIVE) memory access (DMA) latency
tolerance requirements for devices. It may be used to prevent
hardware from choosing overly aggressive energy-saving operation
modes (causing too much latency to appear) for the whole platform.
This feature reqiures hardware support, so it only will be
available for devices having a new .set_latency_tolerance()
callback in struct dev_pm_info populated, in which case the
routine pointed to by it should implement whatever is necessary
to transfer the effective requirement value to the hardware.
Whenever the effective latency tolerance changes for the device,
its .set_latency_tolerance() callback will be executed and the
effective value will be passed to it. If that value is negative,
which means that the list of latency tolerance requirements for
the device is empty, the callback is expected to switch the
underlying hardware latency tolerance control mechanism to an
autonomous mode if available. If that value is PM_QOS_LATENCY_ANY,
in turn, and the hardware supports a special "no requirement"
setting, the callback is expected to use it. That allows software
to prevent the hardware from automatically updating the device's
latency tolerance in response to its power state changes (e.g. during
transitions from D3cold to D0), which generally may be done in the
autonomous latency tolerance control mode.
If .set_latency_tolerance() is present for the device, a new
pm_qos_latency_tolerance_us attribute will be present in the
devivce's power directory in sysfs. Then, user space can use
that attribute to specify its latency tolerance requirement for
the device, if any. Writing "any" to it means "no requirement, but
do not let the hardware control latency tolerance" and writing
"auto" to it allows the hardware to be switched to the autonomous
mode if there are no other requirements from the kernel side in the
device's list.
This changeset includes a fix from Mika Westerberg.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-11 07:35:38 +08:00
|
|
|
#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
|
2011-02-12 04:49:04 +08:00
|
|
|
|
2012-10-24 08:08:18 +08:00
|
|
|
#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
|
|
|
|
|
2011-08-25 21:35:27 +08:00
|
|
|
enum pm_qos_type {
|
|
|
|
PM_QOS_UNITIALIZED,
|
|
|
|
PM_QOS_MAX, /* return the largest value */
|
2014-09-03 23:49:32 +08:00
|
|
|
PM_QOS_MIN, /* return the smallest value */
|
2011-08-25 21:35:27 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2012-10-23 07:07:46 +08:00
|
|
|
* Note: The lockless read path depends on the CPU accessing target_value
|
|
|
|
* or effective_flags atomically. Atomic access is only guaranteed on all CPU
|
2011-08-25 21:35:27 +08:00
|
|
|
* types linux supports for 32 bit quantites
|
|
|
|
*/
|
|
|
|
struct pm_qos_constraints {
|
|
|
|
struct plist_head list;
|
|
|
|
s32 target_value; /* Do not change to 64 bit */
|
|
|
|
s32 default_value;
|
2014-02-11 07:35:29 +08:00
|
|
|
s32 no_constraint_value;
|
2011-08-25 21:35:27 +08:00
|
|
|
enum pm_qos_type type;
|
|
|
|
struct blocking_notifier_head *notifiers;
|
|
|
|
};
|
|
|
|
|
2020-02-12 07:01:18 +08:00
|
|
|
struct pm_qos_request {
|
|
|
|
struct plist_node node;
|
|
|
|
struct pm_qos_constraints *qos;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct pm_qos_flags_request {
|
|
|
|
struct list_head node;
|
|
|
|
s32 flags; /* Do not change to 64 bit */
|
|
|
|
};
|
|
|
|
|
2012-10-23 07:07:46 +08:00
|
|
|
struct pm_qos_flags {
|
|
|
|
struct list_head list;
|
|
|
|
s32 effective_flags; /* Do not change to 64 bit */
|
|
|
|
};
|
|
|
|
|
2019-11-26 23:17:12 +08:00
|
|
|
|
|
|
|
#define FREQ_QOS_MIN_DEFAULT_VALUE 0
|
|
|
|
#define FREQ_QOS_MAX_DEFAULT_VALUE S32_MAX
|
|
|
|
|
|
|
|
enum freq_qos_req_type {
|
|
|
|
FREQ_QOS_MIN = 1,
|
|
|
|
FREQ_QOS_MAX,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct freq_constraints {
|
|
|
|
struct pm_qos_constraints min_freq;
|
|
|
|
struct blocking_notifier_head min_freq_notifiers;
|
|
|
|
struct pm_qos_constraints max_freq;
|
|
|
|
struct blocking_notifier_head max_freq_notifiers;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct freq_qos_request {
|
|
|
|
enum freq_qos_req_type type;
|
|
|
|
struct plist_node pnode;
|
|
|
|
struct freq_constraints *qos;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum dev_pm_qos_req_type {
|
|
|
|
DEV_PM_QOS_RESUME_LATENCY = 1,
|
|
|
|
DEV_PM_QOS_LATENCY_TOLERANCE,
|
2019-11-26 23:17:13 +08:00
|
|
|
DEV_PM_QOS_MIN_FREQUENCY,
|
|
|
|
DEV_PM_QOS_MAX_FREQUENCY,
|
2019-11-26 23:17:12 +08:00
|
|
|
DEV_PM_QOS_FLAGS,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct dev_pm_qos_request {
|
|
|
|
enum dev_pm_qos_req_type type;
|
|
|
|
union {
|
|
|
|
struct plist_node pnode;
|
|
|
|
struct pm_qos_flags_request flr;
|
2019-11-26 23:17:13 +08:00
|
|
|
struct freq_qos_request freq;
|
2019-11-26 23:17:12 +08:00
|
|
|
} data;
|
|
|
|
struct device *dev;
|
|
|
|
};
|
|
|
|
|
2012-10-23 07:07:27 +08:00
|
|
|
struct dev_pm_qos {
|
2014-02-11 07:35:23 +08:00
|
|
|
struct pm_qos_constraints resume_latency;
|
PM / QoS: Introcuce latency tolerance device PM QoS type
Add a new latency tolerance device PM QoS type to be use for
specifying active state (RPM_ACTIVE) memory access (DMA) latency
tolerance requirements for devices. It may be used to prevent
hardware from choosing overly aggressive energy-saving operation
modes (causing too much latency to appear) for the whole platform.
This feature reqiures hardware support, so it only will be
available for devices having a new .set_latency_tolerance()
callback in struct dev_pm_info populated, in which case the
routine pointed to by it should implement whatever is necessary
to transfer the effective requirement value to the hardware.
Whenever the effective latency tolerance changes for the device,
its .set_latency_tolerance() callback will be executed and the
effective value will be passed to it. If that value is negative,
which means that the list of latency tolerance requirements for
the device is empty, the callback is expected to switch the
underlying hardware latency tolerance control mechanism to an
autonomous mode if available. If that value is PM_QOS_LATENCY_ANY,
in turn, and the hardware supports a special "no requirement"
setting, the callback is expected to use it. That allows software
to prevent the hardware from automatically updating the device's
latency tolerance in response to its power state changes (e.g. during
transitions from D3cold to D0), which generally may be done in the
autonomous latency tolerance control mode.
If .set_latency_tolerance() is present for the device, a new
pm_qos_latency_tolerance_us attribute will be present in the
devivce's power directory in sysfs. Then, user space can use
that attribute to specify its latency tolerance requirement for
the device, if any. Writing "any" to it means "no requirement, but
do not let the hardware control latency tolerance" and writing
"auto" to it allows the hardware to be switched to the autonomous
mode if there are no other requirements from the kernel side in the
device's list.
This changeset includes a fix from Mika Westerberg.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-11 07:35:38 +08:00
|
|
|
struct pm_qos_constraints latency_tolerance;
|
2019-11-26 23:17:13 +08:00
|
|
|
struct freq_constraints freq;
|
2012-10-23 07:09:12 +08:00
|
|
|
struct pm_qos_flags flags;
|
2014-02-11 07:35:23 +08:00
|
|
|
struct dev_pm_qos_request *resume_latency_req;
|
PM / QoS: Introcuce latency tolerance device PM QoS type
Add a new latency tolerance device PM QoS type to be use for
specifying active state (RPM_ACTIVE) memory access (DMA) latency
tolerance requirements for devices. It may be used to prevent
hardware from choosing overly aggressive energy-saving operation
modes (causing too much latency to appear) for the whole platform.
This feature reqiures hardware support, so it only will be
available for devices having a new .set_latency_tolerance()
callback in struct dev_pm_info populated, in which case the
routine pointed to by it should implement whatever is necessary
to transfer the effective requirement value to the hardware.
Whenever the effective latency tolerance changes for the device,
its .set_latency_tolerance() callback will be executed and the
effective value will be passed to it. If that value is negative,
which means that the list of latency tolerance requirements for
the device is empty, the callback is expected to switch the
underlying hardware latency tolerance control mechanism to an
autonomous mode if available. If that value is PM_QOS_LATENCY_ANY,
in turn, and the hardware supports a special "no requirement"
setting, the callback is expected to use it. That allows software
to prevent the hardware from automatically updating the device's
latency tolerance in response to its power state changes (e.g. during
transitions from D3cold to D0), which generally may be done in the
autonomous latency tolerance control mode.
If .set_latency_tolerance() is present for the device, a new
pm_qos_latency_tolerance_us attribute will be present in the
devivce's power directory in sysfs. Then, user space can use
that attribute to specify its latency tolerance requirement for
the device, if any. Writing "any" to it means "no requirement, but
do not let the hardware control latency tolerance" and writing
"auto" to it allows the hardware to be switched to the autonomous
mode if there are no other requirements from the kernel side in the
device's list.
This changeset includes a fix from Mika Westerberg.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-11 07:35:38 +08:00
|
|
|
struct dev_pm_qos_request *latency_tolerance_req;
|
2012-10-24 08:08:18 +08:00
|
|
|
struct dev_pm_qos_request *flags_req;
|
2012-10-23 07:07:27 +08:00
|
|
|
};
|
|
|
|
|
2011-08-25 21:35:34 +08:00
|
|
|
/* Action requested to pm_qos_update_target */
|
|
|
|
enum pm_qos_req_action {
|
|
|
|
PM_QOS_ADD_REQ, /* Add a new request */
|
|
|
|
PM_QOS_UPDATE_REQ, /* Update an existing request */
|
|
|
|
PM_QOS_REMOVE_REQ /* Remove an existing request */
|
|
|
|
};
|
|
|
|
|
2011-08-25 21:35:41 +08:00
|
|
|
static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req)
|
|
|
|
{
|
2012-07-18 04:38:18 +08:00
|
|
|
return req->dev != NULL;
|
2011-08-25 21:35:41 +08:00
|
|
|
}
|
|
|
|
|
2020-02-12 07:07:01 +08:00
|
|
|
s32 pm_qos_read_value(struct pm_qos_constraints *c);
|
2011-08-25 21:35:34 +08:00
|
|
|
int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
|
|
|
|
enum pm_qos_req_action action, int value);
|
2012-10-23 07:07:46 +08:00
|
|
|
bool pm_qos_update_flags(struct pm_qos_flags *pqf,
|
|
|
|
struct pm_qos_flags_request *req,
|
|
|
|
enum pm_qos_req_action action, s32 val);
|
2020-02-12 07:07:01 +08:00
|
|
|
|
2020-02-12 07:37:11 +08:00
|
|
|
#ifdef CONFIG_CPU_IDLE
|
PM: QoS: Drop PM_QOS_CPU_DMA_LATENCY and rename related functions
Drop the PM QoS classes enum including PM_QOS_CPU_DMA_LATENCY,
drop the wrappers around pm_qos_request(), pm_qos_request_active(),
and pm_qos_add/update/remove_request() introduced previously, rename
these functions, respectively, to cpu_latency_qos_limit(),
cpu_latency_qos_request_active(), and
cpu_latency_qos_add/update/remove_request(), and update their
kerneldoc comments. [While at it, drop some useless comments from
these functions.]
No intentional functional impact.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org>
Tested-by: Amit Kucheria <amit.kucheria@linaro.org>
2020-02-12 07:35:04 +08:00
|
|
|
s32 cpu_latency_qos_limit(void);
|
|
|
|
bool cpu_latency_qos_request_active(struct pm_qos_request *req);
|
|
|
|
void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value);
|
|
|
|
void cpu_latency_qos_update_request(struct pm_qos_request *req, s32 new_value);
|
|
|
|
void cpu_latency_qos_remove_request(struct pm_qos_request *req);
|
2020-02-12 07:37:11 +08:00
|
|
|
#else
|
|
|
|
static inline s32 cpu_latency_qos_limit(void) { return INT_MAX; }
|
|
|
|
static inline bool cpu_latency_qos_request_active(struct pm_qos_request *req)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
static inline void cpu_latency_qos_add_request(struct pm_qos_request *req,
|
|
|
|
s32 value) {}
|
|
|
|
static inline void cpu_latency_qos_update_request(struct pm_qos_request *req,
|
|
|
|
s32 new_value) {}
|
|
|
|
static inline void cpu_latency_qos_remove_request(struct pm_qos_request *req) {}
|
|
|
|
#endif
|
2020-02-12 07:07:42 +08:00
|
|
|
|
2012-02-13 23:23:42 +08:00
|
|
|
#ifdef CONFIG_PM
|
2012-10-23 07:09:12 +08:00
|
|
|
enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask);
|
|
|
|
enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask);
|
2019-07-04 15:36:18 +08:00
|
|
|
s32 __dev_pm_qos_resume_latency(struct device *dev);
|
2019-07-04 15:36:19 +08:00
|
|
|
s32 dev_pm_qos_read_value(struct device *dev, enum dev_pm_qos_req_type type);
|
2011-08-25 21:35:41 +08:00
|
|
|
int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
|
2012-10-23 07:09:12 +08:00
|
|
|
enum dev_pm_qos_req_type type, s32 value);
|
2011-08-25 21:35:41 +08:00
|
|
|
int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value);
|
|
|
|
int dev_pm_qos_remove_request(struct dev_pm_qos_request *req);
|
|
|
|
int dev_pm_qos_add_notifier(struct device *dev,
|
2019-07-04 15:36:17 +08:00
|
|
|
struct notifier_block *notifier,
|
|
|
|
enum dev_pm_qos_req_type type);
|
2011-08-25 21:35:41 +08:00
|
|
|
int dev_pm_qos_remove_notifier(struct device *dev,
|
2019-07-04 15:36:17 +08:00
|
|
|
struct notifier_block *notifier,
|
|
|
|
enum dev_pm_qos_req_type type);
|
2011-08-25 21:35:41 +08:00
|
|
|
void dev_pm_qos_constraints_init(struct device *dev);
|
|
|
|
void dev_pm_qos_constraints_destroy(struct device *dev);
|
PM / QoS: Introduce dev_pm_qos_add_ancestor_request()
Some devices, like the I2C controller on SH7372, are not
necessary for providing power to their children or forwarding
wakeup signals (and generally interrupts) from them. They are
only needed by their children when there's some data to transfer,
so they may be suspended for the majority of time and resumed
on demand, when the children have data to send or receive. For this
purpose, however, their power.ignore_children flags have to be set,
or the PM core wouldn't allow them to be suspended while their
children were active.
Unfortunately, in some situations it may take too much time to
resume such devices so that they can assist their children in
transferring data. For example, if such a device belongs to a PM
domain which goes to the "power off" state when that device is
suspended, it may take too much time to restore power to the
domain in response to the request from one of the device's
children. In that case, if the parent's resume time is critical,
the domain should stay in the "power on" state, although it still may
be desirable to power manage the parent itself (e.g. by manipulating
its clock).
In general, device PM QoS may be used to address this problem.
Namely, if the device's children added PM QoS latency constraints
for it, they would be able to prevent it from being put into an
overly deep low-power state. However, in some cases the devices
needing to be serviced are not the immediate children of a
"children-ignoring" device, but its grandchildren or even less
direct descendants. In those cases, the entity wanting to add a
PM QoS request for a given device's ancestor that ignores its
children will have to find it in the first place, so introduce a new
helper function that may be used to achieve that. This function,
dev_pm_qos_add_ancestor_request(), will search for the first
ancestor of the given device whose power.ignore_children flag is
set and will add a device PM QoS latency request for that ancestor
on behalf of the caller. The request added this way may be removed
with the help of dev_pm_qos_remove_request() in the future, like
any other device PM QoS latency request.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-12-23 08:23:52 +08:00
|
|
|
int dev_pm_qos_add_ancestor_request(struct device *dev,
|
2014-02-11 07:36:00 +08:00
|
|
|
struct dev_pm_qos_request *req,
|
|
|
|
enum dev_pm_qos_req_type type, s32 value);
|
2014-11-28 05:38:05 +08:00
|
|
|
int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value);
|
|
|
|
void dev_pm_qos_hide_latency_limit(struct device *dev);
|
|
|
|
int dev_pm_qos_expose_flags(struct device *dev, s32 value);
|
|
|
|
void dev_pm_qos_hide_flags(struct device *dev);
|
|
|
|
int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set);
|
|
|
|
s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev);
|
|
|
|
int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val);
|
2015-07-27 23:03:56 +08:00
|
|
|
int dev_pm_qos_expose_latency_tolerance(struct device *dev);
|
|
|
|
void dev_pm_qos_hide_latency_tolerance(struct device *dev);
|
2014-11-28 05:38:05 +08:00
|
|
|
|
|
|
|
static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->power.qos->resume_latency_req->data.pnode.prio;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline s32 dev_pm_qos_requested_flags(struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->power.qos->flags_req->data.flr.flags;
|
|
|
|
}
|
2017-02-24 20:25:14 +08:00
|
|
|
|
2019-07-04 15:36:18 +08:00
|
|
|
static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev)
|
2017-02-24 20:25:14 +08:00
|
|
|
{
|
|
|
|
return IS_ERR_OR_NULL(dev->power.qos) ?
|
2017-11-07 18:33:49 +08:00
|
|
|
PM_QOS_RESUME_LATENCY_NO_CONSTRAINT :
|
|
|
|
pm_qos_read_value(&dev->power.qos->resume_latency);
|
2017-02-24 20:25:14 +08:00
|
|
|
}
|
2011-08-25 21:35:03 +08:00
|
|
|
#else
|
2012-10-23 07:09:12 +08:00
|
|
|
static inline enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev,
|
|
|
|
s32 mask)
|
|
|
|
{ return PM_QOS_FLAGS_UNDEFINED; }
|
|
|
|
static inline enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev,
|
|
|
|
s32 mask)
|
|
|
|
{ return PM_QOS_FLAGS_UNDEFINED; }
|
2019-07-04 15:36:18 +08:00
|
|
|
static inline s32 __dev_pm_qos_resume_latency(struct device *dev)
|
2017-11-07 18:33:49 +08:00
|
|
|
{ return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; }
|
2019-07-04 15:36:19 +08:00
|
|
|
static inline s32 dev_pm_qos_read_value(struct device *dev,
|
|
|
|
enum dev_pm_qos_req_type type)
|
|
|
|
{
|
|
|
|
switch (type) {
|
|
|
|
case DEV_PM_QOS_RESUME_LATENCY:
|
|
|
|
return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
|
2019-11-26 23:17:13 +08:00
|
|
|
case DEV_PM_QOS_MIN_FREQUENCY:
|
|
|
|
return PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE;
|
|
|
|
case DEV_PM_QOS_MAX_FREQUENCY:
|
|
|
|
return PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE;
|
2019-07-04 15:36:19 +08:00
|
|
|
default:
|
|
|
|
WARN_ON(1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-25 21:35:41 +08:00
|
|
|
static inline int dev_pm_qos_add_request(struct device *dev,
|
|
|
|
struct dev_pm_qos_request *req,
|
2012-10-23 07:09:12 +08:00
|
|
|
enum dev_pm_qos_req_type type,
|
2011-08-25 21:35:41 +08:00
|
|
|
s32 value)
|
|
|
|
{ return 0; }
|
|
|
|
static inline int dev_pm_qos_update_request(struct dev_pm_qos_request *req,
|
|
|
|
s32 new_value)
|
|
|
|
{ return 0; }
|
|
|
|
static inline int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
|
|
|
|
{ return 0; }
|
|
|
|
static inline int dev_pm_qos_add_notifier(struct device *dev,
|
2019-07-04 15:36:17 +08:00
|
|
|
struct notifier_block *notifier,
|
|
|
|
enum dev_pm_qos_req_type type)
|
2011-08-25 21:35:41 +08:00
|
|
|
{ return 0; }
|
|
|
|
static inline int dev_pm_qos_remove_notifier(struct device *dev,
|
2019-07-04 15:36:17 +08:00
|
|
|
struct notifier_block *notifier,
|
|
|
|
enum dev_pm_qos_req_type type)
|
2011-08-25 21:35:41 +08:00
|
|
|
{ return 0; }
|
|
|
|
static inline void dev_pm_qos_constraints_init(struct device *dev)
|
2011-09-30 04:29:44 +08:00
|
|
|
{
|
|
|
|
dev->power.power_state = PMSG_ON;
|
|
|
|
}
|
2011-08-25 21:35:41 +08:00
|
|
|
static inline void dev_pm_qos_constraints_destroy(struct device *dev)
|
2011-09-30 04:29:44 +08:00
|
|
|
{
|
|
|
|
dev->power.power_state = PMSG_INVALID;
|
|
|
|
}
|
PM / QoS: Introduce dev_pm_qos_add_ancestor_request()
Some devices, like the I2C controller on SH7372, are not
necessary for providing power to their children or forwarding
wakeup signals (and generally interrupts) from them. They are
only needed by their children when there's some data to transfer,
so they may be suspended for the majority of time and resumed
on demand, when the children have data to send or receive. For this
purpose, however, their power.ignore_children flags have to be set,
or the PM core wouldn't allow them to be suspended while their
children were active.
Unfortunately, in some situations it may take too much time to
resume such devices so that they can assist their children in
transferring data. For example, if such a device belongs to a PM
domain which goes to the "power off" state when that device is
suspended, it may take too much time to restore power to the
domain in response to the request from one of the device's
children. In that case, if the parent's resume time is critical,
the domain should stay in the "power on" state, although it still may
be desirable to power manage the parent itself (e.g. by manipulating
its clock).
In general, device PM QoS may be used to address this problem.
Namely, if the device's children added PM QoS latency constraints
for it, they would be able to prevent it from being put into an
overly deep low-power state. However, in some cases the devices
needing to be serviced are not the immediate children of a
"children-ignoring" device, but its grandchildren or even less
direct descendants. In those cases, the entity wanting to add a
PM QoS request for a given device's ancestor that ignores its
children will have to find it in the first place, so introduce a new
helper function that may be used to achieve that. This function,
dev_pm_qos_add_ancestor_request(), will search for the first
ancestor of the given device whose power.ignore_children flag is
set and will add a device PM QoS latency request for that ancestor
on behalf of the caller. The request added this way may be removed
with the help of dev_pm_qos_remove_request() in the future, like
any other device PM QoS latency request.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-12-23 08:23:52 +08:00
|
|
|
static inline int dev_pm_qos_add_ancestor_request(struct device *dev,
|
2014-02-11 07:36:00 +08:00
|
|
|
struct dev_pm_qos_request *req,
|
|
|
|
enum dev_pm_qos_req_type type,
|
|
|
|
s32 value)
|
PM / QoS: Introduce dev_pm_qos_add_ancestor_request()
Some devices, like the I2C controller on SH7372, are not
necessary for providing power to their children or forwarding
wakeup signals (and generally interrupts) from them. They are
only needed by their children when there's some data to transfer,
so they may be suspended for the majority of time and resumed
on demand, when the children have data to send or receive. For this
purpose, however, their power.ignore_children flags have to be set,
or the PM core wouldn't allow them to be suspended while their
children were active.
Unfortunately, in some situations it may take too much time to
resume such devices so that they can assist their children in
transferring data. For example, if such a device belongs to a PM
domain which goes to the "power off" state when that device is
suspended, it may take too much time to restore power to the
domain in response to the request from one of the device's
children. In that case, if the parent's resume time is critical,
the domain should stay in the "power on" state, although it still may
be desirable to power manage the parent itself (e.g. by manipulating
its clock).
In general, device PM QoS may be used to address this problem.
Namely, if the device's children added PM QoS latency constraints
for it, they would be able to prevent it from being put into an
overly deep low-power state. However, in some cases the devices
needing to be serviced are not the immediate children of a
"children-ignoring" device, but its grandchildren or even less
direct descendants. In those cases, the entity wanting to add a
PM QoS request for a given device's ancestor that ignores its
children will have to find it in the first place, so introduce a new
helper function that may be used to achieve that. This function,
dev_pm_qos_add_ancestor_request(), will search for the first
ancestor of the given device whose power.ignore_children flag is
set and will add a device PM QoS latency request for that ancestor
on behalf of the caller. The request added this way may be removed
with the help of dev_pm_qos_remove_request() in the future, like
any other device PM QoS latency request.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-12-23 08:23:52 +08:00
|
|
|
{ return 0; }
|
PM / QoS: Make it possible to expose PM QoS latency constraints
A runtime suspend of a device (e.g. an MMC controller) belonging to
a power domain or, in a more complicated scenario, a runtime suspend
of another device in the same power domain, may cause power to be
removed from the entire domain. In that case, the amount of time
necessary to runtime-resume the given device (e.g. the MMC
controller) is often substantially greater than the time needed to
run its driver's runtime resume callback. That may hurt performance
in some situations, because user data may need to wait for the
device to become operational, so we should make it possible to
prevent that from happening.
For this reason, introduce a new sysfs attribute for devices,
power/pm_qos_resume_latency_us, allowing user space to specify the
upper bound of the time necessary to bring the (runtime-suspended)
device up after the resume of it has been requested. However, make
that attribute appear only for the devices whose drivers declare
support for it by calling the (new) dev_pm_qos_expose_latency_limit()
helper function with the appropriate initial value of the attribute.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
2012-03-13 08:01:39 +08:00
|
|
|
static inline int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
|
|
|
|
{ return 0; }
|
|
|
|
static inline void dev_pm_qos_hide_latency_limit(struct device *dev) {}
|
2012-10-24 08:08:18 +08:00
|
|
|
static inline int dev_pm_qos_expose_flags(struct device *dev, s32 value)
|
|
|
|
{ return 0; }
|
|
|
|
static inline void dev_pm_qos_hide_flags(struct device *dev) {}
|
|
|
|
static inline int dev_pm_qos_update_flags(struct device *dev, s32 m, bool set)
|
|
|
|
{ return 0; }
|
PM / QoS: Introcuce latency tolerance device PM QoS type
Add a new latency tolerance device PM QoS type to be use for
specifying active state (RPM_ACTIVE) memory access (DMA) latency
tolerance requirements for devices. It may be used to prevent
hardware from choosing overly aggressive energy-saving operation
modes (causing too much latency to appear) for the whole platform.
This feature reqiures hardware support, so it only will be
available for devices having a new .set_latency_tolerance()
callback in struct dev_pm_info populated, in which case the
routine pointed to by it should implement whatever is necessary
to transfer the effective requirement value to the hardware.
Whenever the effective latency tolerance changes for the device,
its .set_latency_tolerance() callback will be executed and the
effective value will be passed to it. If that value is negative,
which means that the list of latency tolerance requirements for
the device is empty, the callback is expected to switch the
underlying hardware latency tolerance control mechanism to an
autonomous mode if available. If that value is PM_QOS_LATENCY_ANY,
in turn, and the hardware supports a special "no requirement"
setting, the callback is expected to use it. That allows software
to prevent the hardware from automatically updating the device's
latency tolerance in response to its power state changes (e.g. during
transitions from D3cold to D0), which generally may be done in the
autonomous latency tolerance control mode.
If .set_latency_tolerance() is present for the device, a new
pm_qos_latency_tolerance_us attribute will be present in the
devivce's power directory in sysfs. Then, user space can use
that attribute to specify its latency tolerance requirement for
the device, if any. Writing "any" to it means "no requirement, but
do not let the hardware control latency tolerance" and writing
"auto" to it allows the hardware to be switched to the autonomous
mode if there are no other requirements from the kernel side in the
device's list.
This changeset includes a fix from Mika Westerberg.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
2014-02-11 07:35:38 +08:00
|
|
|
static inline s32 dev_pm_qos_get_user_latency_tolerance(struct device *dev)
|
|
|
|
{ return PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT; }
|
|
|
|
static inline int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val)
|
|
|
|
{ return 0; }
|
2015-07-27 23:03:56 +08:00
|
|
|
static inline int dev_pm_qos_expose_latency_tolerance(struct device *dev)
|
|
|
|
{ return 0; }
|
|
|
|
static inline void dev_pm_qos_hide_latency_tolerance(struct device *dev) {}
|
2012-10-24 08:08:18 +08:00
|
|
|
|
2017-11-07 18:33:49 +08:00
|
|
|
static inline s32 dev_pm_qos_requested_resume_latency(struct device *dev)
|
|
|
|
{
|
|
|
|
return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
|
|
|
|
}
|
2012-10-24 08:08:18 +08:00
|
|
|
static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; }
|
2019-07-04 15:36:18 +08:00
|
|
|
static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev)
|
2017-11-07 18:33:49 +08:00
|
|
|
{
|
|
|
|
return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
|
|
|
|
}
|
PM / QoS: Make it possible to expose PM QoS latency constraints
A runtime suspend of a device (e.g. an MMC controller) belonging to
a power domain or, in a more complicated scenario, a runtime suspend
of another device in the same power domain, may cause power to be
removed from the entire domain. In that case, the amount of time
necessary to runtime-resume the given device (e.g. the MMC
controller) is often substantially greater than the time needed to
run its driver's runtime resume callback. That may hurt performance
in some situations, because user data may need to wait for the
device to become operational, so we should make it possible to
prevent that from happening.
For this reason, introduce a new sysfs attribute for devices,
power/pm_qos_resume_latency_us, allowing user space to specify the
upper bound of the time necessary to bring the (runtime-suspended)
device up after the resume of it has been requested. However, make
that attribute appear only for the devices whose drivers declare
support for it by calling the (new) dev_pm_qos_expose_latency_limit()
helper function with the appropriate initial value of the attribute.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Reviewed-by: Kevin Hilman <khilman@ti.com>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
2012-03-13 08:01:39 +08:00
|
|
|
#endif
|
|
|
|
|
2019-10-16 18:41:24 +08:00
|
|
|
static inline int freq_qos_request_active(struct freq_qos_request *req)
|
|
|
|
{
|
|
|
|
return !IS_ERR_OR_NULL(req->qos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void freq_constraints_init(struct freq_constraints *qos);
|
|
|
|
|
|
|
|
s32 freq_qos_read_value(struct freq_constraints *qos,
|
|
|
|
enum freq_qos_req_type type);
|
|
|
|
|
|
|
|
int freq_qos_add_request(struct freq_constraints *qos,
|
|
|
|
struct freq_qos_request *req,
|
|
|
|
enum freq_qos_req_type type, s32 value);
|
|
|
|
int freq_qos_update_request(struct freq_qos_request *req, s32 new_value);
|
|
|
|
int freq_qos_remove_request(struct freq_qos_request *req);
|
2019-11-26 23:17:13 +08:00
|
|
|
int freq_qos_apply(struct freq_qos_request *req,
|
|
|
|
enum pm_qos_req_action action, s32 value);
|
2019-10-16 18:41:24 +08:00
|
|
|
|
|
|
|
int freq_qos_add_notifier(struct freq_constraints *qos,
|
|
|
|
enum freq_qos_req_type type,
|
|
|
|
struct notifier_block *notifier);
|
|
|
|
int freq_qos_remove_notifier(struct freq_constraints *qos,
|
|
|
|
enum freq_qos_req_type type,
|
|
|
|
struct notifier_block *notifier);
|
|
|
|
|
2010-07-06 04:53:06 +08:00
|
|
|
#endif
|