Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
effe55ad
Commit
effe55ad
authored
Feb 02, 2021
by
Hans de Goede
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'linux-pm/acpi-platform' into review-hans
parents
cfa75cca
041142d7
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
303 additions
and
0 deletions
+303
-0
Documentation/ABI/testing/sysfs-platform_profile
Documentation/ABI/testing/sysfs-platform_profile
+24
-0
Documentation/userspace-api/index.rst
Documentation/userspace-api/index.rst
+1
-0
Documentation/userspace-api/sysfs-platform_profile.rst
Documentation/userspace-api/sysfs-platform_profile.rst
+42
-0
drivers/acpi/Kconfig
drivers/acpi/Kconfig
+17
-0
drivers/acpi/Makefile
drivers/acpi/Makefile
+1
-0
drivers/acpi/platform_profile.c
drivers/acpi/platform_profile.c
+177
-0
include/linux/platform_profile.h
include/linux/platform_profile.h
+41
-0
No files found.
Documentation/ABI/testing/sysfs-platform_profile
0 → 100644
View file @
effe55ad
What: /sys/firmware/acpi/platform_profile_choices
Date: October 2020
Contact: Hans de Goede <hdegoede@redhat.com>
Description: This file contains a space-separated list of profiles supported for this device.
Drivers must use the following standard profile-names:
============ ============================================
low-power Low power consumption
cool Cooler operation
quiet Quieter operation
balanced Balance between low power consumption and performance
performance High performance operation
============ ============================================
Userspace may expect drivers to offer more than one of these
standard profile names.
What: /sys/firmware/acpi/platform_profile
Date: October 2020
Contact: Hans de Goede <hdegoede@redhat.com>
Description: Reading this file gives the current selected profile for this
device. Writing this file with one of the strings from
platform_profile_choices changes the profile to the new value.
Documentation/userspace-api/index.rst
View file @
effe55ad
...
...
@@ -24,6 +24,7 @@ place where this information is gathered.
ioctl/index
iommu
media/index
sysfs-platform_profile
.. only:: subproject and html
...
...
Documentation/userspace-api/sysfs-platform_profile.rst
0 → 100644
View file @
effe55ad
=====================================================================
Platform Profile Selection (e.g. /sys/firmware/acpi/platform_profile)
=====================================================================
On modern systems the platform performance, temperature, fan and other
hardware related characteristics are often dynamically configurable. The
platform configuration is often automatically adjusted to the current
conditions by some automatic mechanism (which may very well live outside
the kernel).
These auto platform adjustment mechanisms often can be configured with
one of several platform profiles, with either a bias towards low power
operation or towards performance.
The purpose of the platform_profile attribute is to offer a generic sysfs
API for selecting the platform profile of these automatic mechanisms.
Note that this API is only for selecting the platform profile, it is
NOT a goal of this API to allow monitoring the resulting performance
characteristics. Monitoring performance is best done with device/vendor
specific tools such as e.g. turbostat.
Specifically when selecting a high performance profile the actual achieved
performance may be limited by various factors such as: the heat generated
by other components, room temperature, free air flow at the bottom of a
laptop, etc. It is explicitly NOT a goal of this API to let userspace know
about any sub-optimal conditions which are impeding reaching the requested
performance level.
Since numbers on their own cannot represent the multiple variables that a
profile will adjust (power consumption, heat generation, etc) this API
uses strings to describe the various profiles. To make sure that userspace
gets a consistent experience the sysfs-platform_profile ABI document defines
a fixed set of profile names. Drivers *must* map their internal profile
representation onto this fixed set.
If there is no good match when mapping then a new profile name may be
added. Drivers which wish to introduce new profile names must:
1. Explain why the existing profile names canot be used.
2. Add the new profile name, along with a clear description of the
expected behaviour, to the sysfs-platform_profile ABI documentation.
drivers/acpi/Kconfig
View file @
effe55ad
...
...
@@ -326,6 +326,23 @@ config ACPI_THERMAL
To compile this driver as a module, choose M here:
the module will be called thermal.
config ACPI_PLATFORM_PROFILE
tristate "ACPI Platform Profile Driver"
default m
help
This driver adds support for platform-profiles on platforms that
support it.
Platform-profiles can be used to control the platform behaviour. For
example whether to operate in a lower power mode, in a higher
power performance mode or between the two.
This driver provides the sysfs interface and is used as the registration
point for platform specific drivers.
Which profiles are supported is determined on a per-platform basis and
should be obtained from the platform specific driver.
config ACPI_CUSTOM_DSDT_FILE
string "Custom DSDT Table file to include"
default ""
...
...
drivers/acpi/Makefile
View file @
effe55ad
...
...
@@ -79,6 +79,7 @@ obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
obj-$(CONFIG_ACPI_PROCESSOR)
+=
processor.o
obj-$(CONFIG_ACPI)
+=
container.o
obj-$(CONFIG_ACPI_THERMAL)
+=
thermal.o
obj-$(CONFIG_ACPI_PLATFORM_PROFILE)
+=
platform_profile.o
obj-$(CONFIG_ACPI_NFIT)
+=
nfit/
obj-$(CONFIG_ACPI_NUMA)
+=
numa/
obj-$(CONFIG_ACPI)
+=
acpi_memhotplug.o
...
...
drivers/acpi/platform_profile.c
0 → 100644
View file @
effe55ad
// SPDX-License-Identifier: GPL-2.0-or-later
/* Platform profile sysfs interface */
#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/platform_profile.h>
#include <linux/sysfs.h>
static
struct
platform_profile_handler
*
cur_profile
;
static
DEFINE_MUTEX
(
profile_lock
);
static
const
char
*
const
profile_names
[]
=
{
[
PLATFORM_PROFILE_LOW_POWER
]
=
"low-power"
,
[
PLATFORM_PROFILE_COOL
]
=
"cool"
,
[
PLATFORM_PROFILE_QUIET
]
=
"quiet"
,
[
PLATFORM_PROFILE_BALANCED
]
=
"balanced"
,
[
PLATFORM_PROFILE_PERFORMANCE
]
=
"performance"
,
};
static_assert
(
ARRAY_SIZE
(
profile_names
)
==
PLATFORM_PROFILE_LAST
);
static
ssize_t
platform_profile_choices_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
int
len
=
0
;
int
err
,
i
;
err
=
mutex_lock_interruptible
(
&
profile_lock
);
if
(
err
)
return
err
;
if
(
!
cur_profile
)
{
mutex_unlock
(
&
profile_lock
);
return
-
ENODEV
;
}
for_each_set_bit
(
i
,
cur_profile
->
choices
,
PLATFORM_PROFILE_LAST
)
{
if
(
len
==
0
)
len
+=
sysfs_emit_at
(
buf
,
len
,
"%s"
,
profile_names
[
i
]);
else
len
+=
sysfs_emit_at
(
buf
,
len
,
" %s"
,
profile_names
[
i
]);
}
len
+=
sysfs_emit_at
(
buf
,
len
,
"
\n
"
);
mutex_unlock
(
&
profile_lock
);
return
len
;
}
static
ssize_t
platform_profile_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
enum
platform_profile_option
profile
=
PLATFORM_PROFILE_BALANCED
;
int
err
;
err
=
mutex_lock_interruptible
(
&
profile_lock
);
if
(
err
)
return
err
;
if
(
!
cur_profile
)
{
mutex_unlock
(
&
profile_lock
);
return
-
ENODEV
;
}
err
=
cur_profile
->
profile_get
(
cur_profile
,
&
profile
);
mutex_unlock
(
&
profile_lock
);
if
(
err
)
return
err
;
/* Check that profile is valid index */
if
(
WARN_ON
((
profile
<
0
)
||
(
profile
>=
ARRAY_SIZE
(
profile_names
))))
return
-
EIO
;
return
sysfs_emit
(
buf
,
"%s
\n
"
,
profile_names
[
profile
]);
}
static
ssize_t
platform_profile_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
int
err
,
i
;
err
=
mutex_lock_interruptible
(
&
profile_lock
);
if
(
err
)
return
err
;
if
(
!
cur_profile
)
{
mutex_unlock
(
&
profile_lock
);
return
-
ENODEV
;
}
/* Scan for a matching profile */
i
=
sysfs_match_string
(
profile_names
,
buf
);
if
(
i
<
0
)
{
mutex_unlock
(
&
profile_lock
);
return
-
EINVAL
;
}
/* Check that platform supports this profile choice */
if
(
!
test_bit
(
i
,
cur_profile
->
choices
))
{
mutex_unlock
(
&
profile_lock
);
return
-
EOPNOTSUPP
;
}
err
=
cur_profile
->
profile_set
(
cur_profile
,
i
);
mutex_unlock
(
&
profile_lock
);
if
(
err
)
return
err
;
return
count
;
}
static
DEVICE_ATTR_RO
(
platform_profile_choices
);
static
DEVICE_ATTR_RW
(
platform_profile
);
static
struct
attribute
*
platform_profile_attrs
[]
=
{
&
dev_attr_platform_profile_choices
.
attr
,
&
dev_attr_platform_profile
.
attr
,
NULL
};
static
const
struct
attribute_group
platform_profile_group
=
{
.
attrs
=
platform_profile_attrs
};
void
platform_profile_notify
(
void
)
{
if
(
!
cur_profile
)
return
;
sysfs_notify
(
acpi_kobj
,
NULL
,
"platform_profile"
);
}
EXPORT_SYMBOL_GPL
(
platform_profile_notify
);
int
platform_profile_register
(
struct
platform_profile_handler
*
pprof
)
{
int
err
;
mutex_lock
(
&
profile_lock
);
/* We can only have one active profile */
if
(
cur_profile
)
{
mutex_unlock
(
&
profile_lock
);
return
-
EEXIST
;
}
/* Sanity check the profile handler field are set */
if
(
!
pprof
||
bitmap_empty
(
pprof
->
choices
,
PLATFORM_PROFILE_LAST
)
||
!
pprof
->
profile_set
||
!
pprof
->
profile_get
)
{
mutex_unlock
(
&
profile_lock
);
return
-
EINVAL
;
}
err
=
sysfs_create_group
(
acpi_kobj
,
&
platform_profile_group
);
if
(
err
)
{
mutex_unlock
(
&
profile_lock
);
return
err
;
}
cur_profile
=
pprof
;
mutex_unlock
(
&
profile_lock
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
platform_profile_register
);
int
platform_profile_remove
(
void
)
{
sysfs_remove_group
(
acpi_kobj
,
&
platform_profile_group
);
mutex_lock
(
&
profile_lock
);
cur_profile
=
NULL
;
mutex_unlock
(
&
profile_lock
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
platform_profile_remove
);
MODULE_AUTHOR
(
"Mark Pearson <markpearson@lenovo.com>"
);
MODULE_LICENSE
(
"GPL"
);
include/linux/platform_profile.h
0 → 100644
View file @
effe55ad
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Platform profile sysfs interface
*
* See Documentation/ABI/testing/sysfs-platform_profile.rst for more
* information.
*/
#ifndef _PLATFORM_PROFILE_H_
#define _PLATFORM_PROFILE_H_
#include <linux/bitops.h>
/*
* If more options are added please update profile_names
* array in platform-profile.c and sysfs-platform-profile.rst
* documentation.
*/
enum
platform_profile_option
{
PLATFORM_PROFILE_LOW_POWER
,
PLATFORM_PROFILE_COOL
,
PLATFORM_PROFILE_QUIET
,
PLATFORM_PROFILE_BALANCED
,
PLATFORM_PROFILE_PERFORMANCE
,
PLATFORM_PROFILE_LAST
,
/*must always be last */
};
struct
platform_profile_handler
{
unsigned
long
choices
[
BITS_TO_LONGS
(
PLATFORM_PROFILE_LAST
)];
int
(
*
profile_get
)(
struct
platform_profile_handler
*
pprof
,
enum
platform_profile_option
*
profile
);
int
(
*
profile_set
)(
struct
platform_profile_handler
*
pprof
,
enum
platform_profile_option
profile
);
};
int
platform_profile_register
(
struct
platform_profile_handler
*
pprof
);
int
platform_profile_remove
(
void
);
void
platform_profile_notify
(
void
);
#endif
/*_PLATFORM_PROFILE_H_*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment