ACPI updates for 5.2-rc1
- Convert the ACPI documentation in the kernel source tree to the .rst format and split it into the admin guide, driver API and firmware guide parts (Changbin Du). - Add a PRP0001 usage example to the ACPI documentation (Thomas Preston). - Switch over the users of the acpi_dev_get_first_match_name() library function which turned out to be problematic to a new, better one called acpi_dev_get_first_match_dev() (Andy Shevchenko, YueHaibing). - Update the ACPICA code in the kernel to upstream release 20190405 including: * Null pointer dereference check in acpi_ns_delete_node() (Erik Schmauss). * Multiple macro and function name changes (Bob Moore). * Predefined operation region name fix (Erik Schmauss). - Fix hibernation issue on systems using the Baytrail and Cherrytrail Intel SoCs introduced during the 4.20 development cycle (Hans de Goede). - Add Sony VPCEH3U1E to the backlight quirk list (Zhang Rui). - Fix button handling during system resume (Zhang Rui). - Add a device PM diagnostic message (Rafael Wysocki). - Clean up the code, comments and white space in multiple places (Bjorn Helgaas, Gustavo Silva, Kefeng Wang). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAlzQEdcSHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRxVKEP/ijfyNbe2s21nZXdEmL2mEFlkK3jvN/P d9jDkM9u3iJzFHTjwbMrYa7uXQpLtlhsE3QrcRcfkumOf8XWH1kSY1pDfb3W701w 3Zy1zJyiH4SA5xwipDgiqLsHneV3NqtyYHjWh0u52zM8S5aL58ZPlgxwY/qywt94 CMCfs+QCR+MKHvJVjo8EjlF3pwOgZpIFpIHtzo5A87yzwnG3kWls0UVfJGHSAKsX q+m3RhglqeVYVabXU/d5B9PnZiN5SmZdI864D2a5Dh4D/puv+k9hhBdCaMMi2F25 GZwFsBh3ymbcPCfaKe422488ERh1l8Ov1JsLUbFRcYw8euFXkaoOYtugETIy2XR9 3JNWu3TiuBhA4EkQdpiWY+CIcUmXDUzmEDhJBG1e6hhzlqZknIcfXVp6qu3bxoA/ OvlC3Lcaw9cHXQLGRk5S3u3F/NzdkSTD1A5bNSdHpbRqj1Ale8H8R9TUfqMX5Nsj r4V5m+2bFsArOdVEit9kUw0MdFq/ew6eO75lBK8sUJLfQ2utiMZW8FuJBeNWRahE bTsfOtxazDl0mcavROfzf4XFaBBQ0YUJvPIgVFhUPGOhlq96OAFgZYYemq7NOpQo EvS8OQD0+k7hFg1/z+JUr8rDa1NRlLypz4iXa/wIU1a/sE0Odv4xwTH1XLhoaQKv nVkGW4GD0WMX =LtlV -----END PGP SIGNATURE----- Merge tag 'acpi-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI updates from Rafael Wysocki: "These rearrange the ACPI documentation by converting it to the .rst format and splitting it into clear categories (admin guide, driver API, firmware guide), switch over multiple users of a problematic library function to a new better one, update the ACPICA code in the kernel to a new upstream release, fix a few issues, improve power device management diagnostics and do some cleanups. Specifics: - Convert the ACPI documentation in the kernel source tree to the .rst format and split it into the admin guide, driver API and firmware guide parts (Changbin Du). - Add a PRP0001 usage example to the ACPI documentation (Thomas Preston). - Switch over the users of the acpi_dev_get_first_match_name() library function which turned out to be problematic to a new, better one called acpi_dev_get_first_match_dev() (Andy Shevchenko, YueHaibing). - Update the ACPICA code in the kernel to upstream release 20190405 including: * Null pointer dereference check in acpi_ns_delete_node() (Erik Schmauss). * Multiple macro and function name changes (Bob Moore). * Predefined operation region name fix (Erik Schmauss). - Fix hibernation issue on systems using the Baytrail and Cherrytrail Intel SoCs introduced during the 4.20 development cycle (Hans de Goede). - Add Sony VPCEH3U1E to the backlight quirk list (Zhang Rui). - Fix button handling during system resume (Zhang Rui). - Add a device PM diagnostic message (Rafael Wysocki). - Clean up the code, comments and white space in multiple places (Bjorn Helgaas, Gustavo Silva, Kefeng Wang)" * tag 'acpi-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (53 commits) Documentation: ACPI: move video_extension.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move ssdt-overlays.txt to admin-guide/acpi and convert to reST Documentation: ACPI: move lpit.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move cppc_sysfs.txt to admin-guide/acpi and convert to reST Documentation: ACPI: move apei/einj.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move apei/output_format.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move aml-debugger.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move method-tracing.txt to firmware-guide/acpi and convert to rsST Documentation: ACPI: move debug.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move dsd/data-node-references.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move dsd/graph.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move acpi-lid.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move i2c-muxes.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move dsdt-override.txt to admin-guide/acpi and convert to reST Documentation: ACPI: move initrd_table_override.txt to admin-guide/acpi and convert to reST Documentation: ACPI: move method-customizing.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move gpio-properties.txt to firmware-guide/acpi and convert to reST Documentation: ACPI: move DSD-properties-rules.txt to firmware-guide/acpi and covert to reST Documentation: ACPI: move scan_handlers.txt to driver-api/acpi and convert to reST Documentation: ACPI: move linuxized-acpica.txt to driver-api/acpi and convert to reST ...
This commit is contained in:
commit
59df1c2bde
@ -1,66 +0,0 @@
|
|||||||
The AML Debugger
|
|
||||||
|
|
||||||
Copyright (C) 2016, Intel Corporation
|
|
||||||
Author: Lv Zheng <lv.zheng@intel.com>
|
|
||||||
|
|
||||||
|
|
||||||
This document describes the usage of the AML debugger embedded in the Linux
|
|
||||||
kernel.
|
|
||||||
|
|
||||||
1. Build the debugger
|
|
||||||
|
|
||||||
The following kernel configuration items are required to enable the AML
|
|
||||||
debugger interface from the Linux kernel:
|
|
||||||
|
|
||||||
CONFIG_ACPI_DEBUGGER=y
|
|
||||||
CONFIG_ACPI_DEBUGGER_USER=m
|
|
||||||
|
|
||||||
The userspace utilities can be built from the kernel source tree using
|
|
||||||
the following commands:
|
|
||||||
|
|
||||||
$ cd tools
|
|
||||||
$ make acpi
|
|
||||||
|
|
||||||
The resultant userspace tool binary is then located at:
|
|
||||||
|
|
||||||
tools/power/acpi/acpidbg
|
|
||||||
|
|
||||||
It can be installed to system directories by running "make install" (as a
|
|
||||||
sufficiently privileged user).
|
|
||||||
|
|
||||||
2. Start the userspace debugger interface
|
|
||||||
|
|
||||||
After booting the kernel with the debugger built-in, the debugger can be
|
|
||||||
started by using the following commands:
|
|
||||||
|
|
||||||
# mount -t debugfs none /sys/kernel/debug
|
|
||||||
# modprobe acpi_dbg
|
|
||||||
# tools/power/acpi/acpidbg
|
|
||||||
|
|
||||||
That spawns the interactive AML debugger environment where you can execute
|
|
||||||
debugger commands.
|
|
||||||
|
|
||||||
The commands are documented in the "ACPICA Overview and Programmer Reference"
|
|
||||||
that can be downloaded from
|
|
||||||
|
|
||||||
https://acpica.org/documentation
|
|
||||||
|
|
||||||
The detailed debugger commands reference is located in Chapter 12 "ACPICA
|
|
||||||
Debugger Reference". The "help" command can be used for a quick reference.
|
|
||||||
|
|
||||||
3. Stop the userspace debugger interface
|
|
||||||
|
|
||||||
The interactive debugger interface can be closed by pressing Ctrl+C or using
|
|
||||||
the "quit" or "exit" commands. When finished, unload the module with:
|
|
||||||
|
|
||||||
# rmmod acpi_dbg
|
|
||||||
|
|
||||||
The module unloading may fail if there is an acpidbg instance running.
|
|
||||||
|
|
||||||
4. Run the debugger in a script
|
|
||||||
|
|
||||||
It may be useful to run the AML debugger in a test script. "acpidbg" supports
|
|
||||||
this in a special "batch" mode. For example, the following command outputs
|
|
||||||
the entire ACPI namespace:
|
|
||||||
|
|
||||||
# acpidbg -b "namespace"
|
|
@ -1,147 +0,0 @@
|
|||||||
APEI output format
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
APEI uses printk as hardware error reporting interface, the output
|
|
||||||
format is as follow.
|
|
||||||
|
|
||||||
<error record> :=
|
|
||||||
APEI generic hardware error status
|
|
||||||
severity: <integer>, <severity string>
|
|
||||||
section: <integer>, severity: <integer>, <severity string>
|
|
||||||
flags: <integer>
|
|
||||||
<section flags strings>
|
|
||||||
fru_id: <uuid string>
|
|
||||||
fru_text: <string>
|
|
||||||
section_type: <section type string>
|
|
||||||
<section data>
|
|
||||||
|
|
||||||
<severity string>* := recoverable | fatal | corrected | info
|
|
||||||
|
|
||||||
<section flags strings># :=
|
|
||||||
[primary][, containment warning][, reset][, threshold exceeded]\
|
|
||||||
[, resource not accessible][, latent error]
|
|
||||||
|
|
||||||
<section type string> := generic processor error | memory error | \
|
|
||||||
PCIe error | unknown, <uuid string>
|
|
||||||
|
|
||||||
<section data> :=
|
|
||||||
<generic processor section data> | <memory section data> | \
|
|
||||||
<pcie section data> | <null>
|
|
||||||
|
|
||||||
<generic processor section data> :=
|
|
||||||
[processor_type: <integer>, <proc type string>]
|
|
||||||
[processor_isa: <integer>, <proc isa string>]
|
|
||||||
[error_type: <integer>
|
|
||||||
<proc error type strings>]
|
|
||||||
[operation: <integer>, <proc operation string>]
|
|
||||||
[flags: <integer>
|
|
||||||
<proc flags strings>]
|
|
||||||
[level: <integer>]
|
|
||||||
[version_info: <integer>]
|
|
||||||
[processor_id: <integer>]
|
|
||||||
[target_address: <integer>]
|
|
||||||
[requestor_id: <integer>]
|
|
||||||
[responder_id: <integer>]
|
|
||||||
[IP: <integer>]
|
|
||||||
|
|
||||||
<proc type string>* := IA32/X64 | IA64
|
|
||||||
|
|
||||||
<proc isa string>* := IA32 | IA64 | X64
|
|
||||||
|
|
||||||
<processor error type strings># :=
|
|
||||||
[cache error][, TLB error][, bus error][, micro-architectural error]
|
|
||||||
|
|
||||||
<proc operation string>* := unknown or generic | data read | data write | \
|
|
||||||
instruction execution
|
|
||||||
|
|
||||||
<proc flags strings># :=
|
|
||||||
[restartable][, precise IP][, overflow][, corrected]
|
|
||||||
|
|
||||||
<memory section data> :=
|
|
||||||
[error_status: <integer>]
|
|
||||||
[physical_address: <integer>]
|
|
||||||
[physical_address_mask: <integer>]
|
|
||||||
[node: <integer>]
|
|
||||||
[card: <integer>]
|
|
||||||
[module: <integer>]
|
|
||||||
[bank: <integer>]
|
|
||||||
[device: <integer>]
|
|
||||||
[row: <integer>]
|
|
||||||
[column: <integer>]
|
|
||||||
[bit_position: <integer>]
|
|
||||||
[requestor_id: <integer>]
|
|
||||||
[responder_id: <integer>]
|
|
||||||
[target_id: <integer>]
|
|
||||||
[error_type: <integer>, <mem error type string>]
|
|
||||||
|
|
||||||
<mem error type string>* :=
|
|
||||||
unknown | no error | single-bit ECC | multi-bit ECC | \
|
|
||||||
single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \
|
|
||||||
target abort | parity error | watchdog timeout | invalid address | \
|
|
||||||
mirror Broken | memory sparing | scrub corrected error | \
|
|
||||||
scrub uncorrected error
|
|
||||||
|
|
||||||
<pcie section data> :=
|
|
||||||
[port_type: <integer>, <pcie port type string>]
|
|
||||||
[version: <integer>.<integer>]
|
|
||||||
[command: <integer>, status: <integer>]
|
|
||||||
[device_id: <integer>:<integer>:<integer>.<integer>
|
|
||||||
slot: <integer>
|
|
||||||
secondary_bus: <integer>
|
|
||||||
vendor_id: <integer>, device_id: <integer>
|
|
||||||
class_code: <integer>]
|
|
||||||
[serial number: <integer>, <integer>]
|
|
||||||
[bridge: secondary_status: <integer>, control: <integer>]
|
|
||||||
[aer_status: <integer>, aer_mask: <integer>
|
|
||||||
<aer status string>
|
|
||||||
[aer_uncor_severity: <integer>]
|
|
||||||
aer_layer=<aer layer string>, aer_agent=<aer agent string>
|
|
||||||
aer_tlp_header: <integer> <integer> <integer> <integer>]
|
|
||||||
|
|
||||||
<pcie port type string>* := PCIe end point | legacy PCI end point | \
|
|
||||||
unknown | unknown | root port | upstream switch port | \
|
|
||||||
downstream switch port | PCIe to PCI/PCI-X bridge | \
|
|
||||||
PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \
|
|
||||||
root complex event collector
|
|
||||||
|
|
||||||
if section severity is fatal or recoverable
|
|
||||||
<aer status string># :=
|
|
||||||
unknown | unknown | unknown | unknown | Data Link Protocol | \
|
|
||||||
unknown | unknown | unknown | unknown | unknown | unknown | unknown | \
|
|
||||||
Poisoned TLP | Flow Control Protocol | Completion Timeout | \
|
|
||||||
Completer Abort | Unexpected Completion | Receiver Overflow | \
|
|
||||||
Malformed TLP | ECRC | Unsupported Request
|
|
||||||
else
|
|
||||||
<aer status string># :=
|
|
||||||
Receiver Error | unknown | unknown | unknown | unknown | unknown | \
|
|
||||||
Bad TLP | Bad DLLP | RELAY_NUM Rollover | unknown | unknown | unknown | \
|
|
||||||
Replay Timer Timeout | Advisory Non-Fatal
|
|
||||||
fi
|
|
||||||
|
|
||||||
<aer layer string> :=
|
|
||||||
Physical Layer | Data Link Layer | Transaction Layer
|
|
||||||
|
|
||||||
<aer agent string> :=
|
|
||||||
Receiver ID | Requester ID | Completer ID | Transmitter ID
|
|
||||||
|
|
||||||
Where, [] designate corresponding content is optional
|
|
||||||
|
|
||||||
All <field string> description with * has the following format:
|
|
||||||
|
|
||||||
field: <integer>, <field string>
|
|
||||||
|
|
||||||
Where value of <integer> should be the position of "string" in <field
|
|
||||||
string> description. Otherwise, <field string> will be "unknown".
|
|
||||||
|
|
||||||
All <field strings> description with # has the following format:
|
|
||||||
|
|
||||||
field: <integer>
|
|
||||||
<field strings>
|
|
||||||
|
|
||||||
Where each string in <fields strings> corresponding to one set bit of
|
|
||||||
<integer>. The bit position is the position of "string" in <field
|
|
||||||
strings> description.
|
|
||||||
|
|
||||||
For more detailed explanation of every field, please refer to UEFI
|
|
||||||
specification version 2.3 or later, section Appendix N: Common
|
|
||||||
Platform Error Record.
|
|
@ -1,58 +0,0 @@
|
|||||||
ACPI I2C Muxes
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Describing an I2C device hierarchy that includes I2C muxes requires an ACPI
|
|
||||||
Device () scope per mux channel.
|
|
||||||
|
|
||||||
Consider this topology:
|
|
||||||
|
|
||||||
+------+ +------+
|
|
||||||
| SMB1 |-->| MUX0 |--CH00--> i2c client A (0x50)
|
|
||||||
| | | 0x70 |--CH01--> i2c client B (0x50)
|
|
||||||
+------+ +------+
|
|
||||||
|
|
||||||
which corresponds to the following ASL:
|
|
||||||
|
|
||||||
Device (SMB1)
|
|
||||||
{
|
|
||||||
Name (_HID, ...)
|
|
||||||
Device (MUX0)
|
|
||||||
{
|
|
||||||
Name (_HID, ...)
|
|
||||||
Name (_CRS, ResourceTemplate () {
|
|
||||||
I2cSerialBus (0x70, ControllerInitiated, I2C_SPEED,
|
|
||||||
AddressingMode7Bit, "^SMB1", 0x00,
|
|
||||||
ResourceConsumer,,)
|
|
||||||
}
|
|
||||||
|
|
||||||
Device (CH00)
|
|
||||||
{
|
|
||||||
Name (_ADR, 0)
|
|
||||||
|
|
||||||
Device (CLIA)
|
|
||||||
{
|
|
||||||
Name (_HID, ...)
|
|
||||||
Name (_CRS, ResourceTemplate () {
|
|
||||||
I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED,
|
|
||||||
AddressingMode7Bit, "^CH00", 0x00,
|
|
||||||
ResourceConsumer,,)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Device (CH01)
|
|
||||||
{
|
|
||||||
Name (_ADR, 1)
|
|
||||||
|
|
||||||
Device (CLIB)
|
|
||||||
{
|
|
||||||
Name (_HID, ...)
|
|
||||||
Name (_CRS, ResourceTemplate () {
|
|
||||||
I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED,
|
|
||||||
AddressingMode7Bit, "^CH01", 0x00,
|
|
||||||
ResourceConsumer,,)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
Upgrading ACPI tables via initrd
|
|
||||||
================================
|
|
||||||
|
|
||||||
1) Introduction (What is this about)
|
|
||||||
2) What is this for
|
|
||||||
3) How does it work
|
|
||||||
4) References (Where to retrieve userspace tools)
|
|
||||||
|
|
||||||
1) What is this about
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
If the ACPI_TABLE_UPGRADE compile option is true, it is possible to
|
|
||||||
upgrade the ACPI execution environment that is defined by the ACPI tables
|
|
||||||
via upgrading the ACPI tables provided by the BIOS with an instrumented,
|
|
||||||
modified, more recent version one, or installing brand new ACPI tables.
|
|
||||||
|
|
||||||
When building initrd with kernel in a single image, option
|
|
||||||
ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD should also be true for this
|
|
||||||
feature to work.
|
|
||||||
|
|
||||||
For a full list of ACPI tables that can be upgraded/installed, take a look
|
|
||||||
at the char *table_sigs[MAX_ACPI_SIGNATURE]; definition in
|
|
||||||
drivers/acpi/tables.c.
|
|
||||||
All ACPI tables iasl (Intel's ACPI compiler and disassembler) knows should
|
|
||||||
be overridable, except:
|
|
||||||
- ACPI_SIG_RSDP (has a signature of 6 bytes)
|
|
||||||
- ACPI_SIG_FACS (does not have an ordinary ACPI table header)
|
|
||||||
Both could get implemented as well.
|
|
||||||
|
|
||||||
|
|
||||||
2) What is this for
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Complain to your platform/BIOS vendor if you find a bug which is so severe
|
|
||||||
that a workaround is not accepted in the Linux kernel. And this facility
|
|
||||||
allows you to upgrade the buggy tables before your platform/BIOS vendor
|
|
||||||
releases an upgraded BIOS binary.
|
|
||||||
|
|
||||||
This facility can be used by platform/BIOS vendors to provide a Linux
|
|
||||||
compatible environment without modifying the underlying platform firmware.
|
|
||||||
|
|
||||||
This facility also provides a powerful feature to easily debug and test
|
|
||||||
ACPI BIOS table compatibility with the Linux kernel by modifying old
|
|
||||||
platform provided ACPI tables or inserting new ACPI tables.
|
|
||||||
|
|
||||||
It can and should be enabled in any kernel because there is no functional
|
|
||||||
change with not instrumented initrds.
|
|
||||||
|
|
||||||
|
|
||||||
3) How does it work
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
# Extract the machine's ACPI tables:
|
|
||||||
cd /tmp
|
|
||||||
acpidump >acpidump
|
|
||||||
acpixtract -a acpidump
|
|
||||||
# Disassemble, modify and recompile them:
|
|
||||||
iasl -d *.dat
|
|
||||||
# For example add this statement into a _PRT (PCI Routing Table) function
|
|
||||||
# of the DSDT:
|
|
||||||
Store("HELLO WORLD", debug)
|
|
||||||
# And increase the OEM Revision. For example, before modification:
|
|
||||||
DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000000)
|
|
||||||
# After modification:
|
|
||||||
DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000001)
|
|
||||||
iasl -sa dsdt.dsl
|
|
||||||
# Add the raw ACPI tables to an uncompressed cpio archive.
|
|
||||||
# They must be put into a /kernel/firmware/acpi directory inside the cpio
|
|
||||||
# archive. Note that if the table put here matches a platform table
|
|
||||||
# (similar Table Signature, and similar OEMID, and similar OEM Table ID)
|
|
||||||
# with a more recent OEM Revision, the platform table will be upgraded by
|
|
||||||
# this table. If the table put here doesn't match a platform table
|
|
||||||
# (dissimilar Table Signature, or dissimilar OEMID, or dissimilar OEM Table
|
|
||||||
# ID), this table will be appended.
|
|
||||||
mkdir -p kernel/firmware/acpi
|
|
||||||
cp dsdt.aml kernel/firmware/acpi
|
|
||||||
# A maximum of "NR_ACPI_INITRD_TABLES (64)" tables are currently allowed
|
|
||||||
# (see osl.c):
|
|
||||||
iasl -sa facp.dsl
|
|
||||||
iasl -sa ssdt1.dsl
|
|
||||||
cp facp.aml kernel/firmware/acpi
|
|
||||||
cp ssdt1.aml kernel/firmware/acpi
|
|
||||||
# The uncompressed cpio archive must be the first. Other, typically
|
|
||||||
# compressed cpio archives, must be concatenated on top of the uncompressed
|
|
||||||
# one. Following command creates the uncompressed cpio archive and
|
|
||||||
# concatenates the original initrd on top:
|
|
||||||
find kernel | cpio -H newc --create > /boot/instrumented_initrd
|
|
||||||
cat /boot/initrd >>/boot/instrumented_initrd
|
|
||||||
# reboot with increased acpi debug level, e.g. boot params:
|
|
||||||
acpi.debug_level=0x2 acpi.debug_layer=0xFFFFFFFF
|
|
||||||
# and check your syslog:
|
|
||||||
[ 1.268089] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
|
|
||||||
[ 1.272091] [ACPI Debug] String [0x0B] "HELLO WORLD"
|
|
||||||
|
|
||||||
iasl is able to disassemble and recompile quite a lot different,
|
|
||||||
also static ACPI tables.
|
|
||||||
|
|
||||||
|
|
||||||
4) Where to retrieve userspace tools
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
iasl and acpixtract are part of Intel's ACPICA project:
|
|
||||||
http://acpica.org/
|
|
||||||
and should be packaged by distributions (for example in the acpica package
|
|
||||||
on SUSE).
|
|
||||||
|
|
||||||
acpidump can be found in Len Browns pmtools:
|
|
||||||
ftp://kernel.org/pub/linux/kernel/people/lenb/acpi/utils/pmtools/acpidump
|
|
||||||
This tool is also part of the acpica package on SUSE.
|
|
||||||
Alternatively, used ACPI tables can be retrieved via sysfs in latest kernels:
|
|
||||||
/sys/firmware/acpi/tables
|
|
@ -1,73 +0,0 @@
|
|||||||
Linux ACPI Custom Control Method How To
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
Written by Zhang Rui <rui.zhang@intel.com>
|
|
||||||
|
|
||||||
|
|
||||||
Linux supports customizing ACPI control methods at runtime.
|
|
||||||
|
|
||||||
Users can use this to
|
|
||||||
1. override an existing method which may not work correctly,
|
|
||||||
or just for debugging purposes.
|
|
||||||
2. insert a completely new method in order to create a missing
|
|
||||||
method such as _OFF, _ON, _STA, _INI, etc.
|
|
||||||
For these cases, it is far simpler to dynamically install a single
|
|
||||||
control method rather than override the entire DSDT, because kernel
|
|
||||||
rebuild/reboot is not needed and test result can be got in minutes.
|
|
||||||
|
|
||||||
Note: Only ACPI METHOD can be overridden, any other object types like
|
|
||||||
"Device", "OperationRegion", are not recognized. Methods
|
|
||||||
declared inside scope operators are also not supported.
|
|
||||||
Note: The same ACPI control method can be overridden for many times,
|
|
||||||
and it's always the latest one that used by Linux/kernel.
|
|
||||||
Note: To get the ACPI debug object output (Store (AAAA, Debug)),
|
|
||||||
please run "echo 1 > /sys/module/acpi/parameters/aml_debug_output".
|
|
||||||
|
|
||||||
1. override an existing method
|
|
||||||
a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT,
|
|
||||||
just run "cat /sys/firmware/acpi/tables/DSDT > /tmp/dsdt.dat"
|
|
||||||
b) disassemble the table by running "iasl -d dsdt.dat".
|
|
||||||
c) rewrite the ASL code of the method and save it in a new file,
|
|
||||||
d) package the new file (psr.asl) to an ACPI table format.
|
|
||||||
Here is an example of a customized \_SB._AC._PSR method,
|
|
||||||
|
|
||||||
DefinitionBlock ("", "SSDT", 1, "", "", 0x20080715)
|
|
||||||
{
|
|
||||||
Method (\_SB_.AC._PSR, 0, NotSerialized)
|
|
||||||
{
|
|
||||||
Store ("In AC _PSR", Debug)
|
|
||||||
Return (ACON)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Note that the full pathname of the method in ACPI namespace
|
|
||||||
should be used.
|
|
||||||
e) assemble the file to generate the AML code of the method.
|
|
||||||
e.g. "iasl -vw 6084 psr.asl" (psr.aml is generated as a result)
|
|
||||||
If parameter "-vw 6084" is not supported by your iASL compiler,
|
|
||||||
please try a newer version.
|
|
||||||
f) mount debugfs by "mount -t debugfs none /sys/kernel/debug"
|
|
||||||
g) override the old method via the debugfs by running
|
|
||||||
"cat /tmp/psr.aml > /sys/kernel/debug/acpi/custom_method"
|
|
||||||
|
|
||||||
2. insert a new method
|
|
||||||
This is easier than overriding an existing method.
|
|
||||||
We just need to create the ASL code of the method we want to
|
|
||||||
insert and then follow the step c) ~ g) in section 1.
|
|
||||||
|
|
||||||
3. undo your changes
|
|
||||||
The "undo" operation is not supported for a new inserted method
|
|
||||||
right now, i.e. we can not remove a method currently.
|
|
||||||
For an overridden method, in order to undo your changes, please
|
|
||||||
save a copy of the method original ASL code in step c) section 1,
|
|
||||||
and redo step c) ~ g) to override the method with the original one.
|
|
||||||
|
|
||||||
|
|
||||||
Note: We can use a kernel with multiple custom ACPI method running,
|
|
||||||
But each individual write to debugfs can implement a SINGLE
|
|
||||||
method override. i.e. if we want to insert/override multiple
|
|
||||||
ACPI methods, we need to redo step c) ~ g) for multiple times.
|
|
||||||
|
|
||||||
Note: Be aware that root can mis-use this driver to modify arbitrary
|
|
||||||
memory and gain additional rights, if root's privileges got
|
|
||||||
restricted (for example if root is not allowed to load additional
|
|
||||||
modules after boot).
|
|
@ -1,192 +0,0 @@
|
|||||||
ACPICA Trace Facility
|
|
||||||
|
|
||||||
Copyright (C) 2015, Intel Corporation
|
|
||||||
Author: Lv Zheng <lv.zheng@intel.com>
|
|
||||||
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
This document describes the functions and the interfaces of the method
|
|
||||||
tracing facility.
|
|
||||||
|
|
||||||
1. Functionalities and usage examples:
|
|
||||||
|
|
||||||
ACPICA provides method tracing capability. And two functions are
|
|
||||||
currently implemented using this capability.
|
|
||||||
|
|
||||||
A. Log reducer
|
|
||||||
ACPICA subsystem provides debugging outputs when CONFIG_ACPI_DEBUG is
|
|
||||||
enabled. The debugging messages which are deployed via
|
|
||||||
ACPI_DEBUG_PRINT() macro can be reduced at 2 levels - per-component
|
|
||||||
level (known as debug layer, configured via
|
|
||||||
/sys/module/acpi/parameters/debug_layer) and per-type level (known as
|
|
||||||
debug level, configured via /sys/module/acpi/parameters/debug_level).
|
|
||||||
|
|
||||||
But when the particular layer/level is applied to the control method
|
|
||||||
evaluations, the quantity of the debugging outputs may still be too
|
|
||||||
large to be put into the kernel log buffer. The idea thus is worked out
|
|
||||||
to only enable the particular debug layer/level (normally more detailed)
|
|
||||||
logs when the control method evaluation is started, and disable the
|
|
||||||
detailed logging when the control method evaluation is stopped.
|
|
||||||
|
|
||||||
The following command examples illustrate the usage of the "log reducer"
|
|
||||||
functionality:
|
|
||||||
a. Filter out the debug layer/level matched logs when control methods
|
|
||||||
are being evaluated:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0xXXXXXXXX" > trace_debug_layer
|
|
||||||
# echo "0xYYYYYYYY" > trace_debug_level
|
|
||||||
# echo "enable" > trace_state
|
|
||||||
b. Filter out the debug layer/level matched logs when the specified
|
|
||||||
control method is being evaluated:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0xXXXXXXXX" > trace_debug_layer
|
|
||||||
# echo "0xYYYYYYYY" > trace_debug_level
|
|
||||||
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
|
||||||
# echo "method" > /sys/module/acpi/parameters/trace_state
|
|
||||||
c. Filter out the debug layer/level matched logs when the specified
|
|
||||||
control method is being evaluated for the first time:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0xXXXXXXXX" > trace_debug_layer
|
|
||||||
# echo "0xYYYYYYYY" > trace_debug_level
|
|
||||||
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
|
||||||
# echo "method-once" > /sys/module/acpi/parameters/trace_state
|
|
||||||
Where:
|
|
||||||
0xXXXXXXXX/0xYYYYYYYY: Refer to Documentation/acpi/debug.txt for
|
|
||||||
possible debug layer/level masking values.
|
|
||||||
\PPPP.AAAA.TTTT.HHHH: Full path of a control method that can be found
|
|
||||||
in the ACPI namespace. It needn't be an entry
|
|
||||||
of a control method evaluation.
|
|
||||||
|
|
||||||
B. AML tracer
|
|
||||||
|
|
||||||
There are special log entries added by the method tracing facility at
|
|
||||||
the "trace points" the AML interpreter starts/stops to execute a control
|
|
||||||
method, or an AML opcode. Note that the format of the log entries are
|
|
||||||
subject to change:
|
|
||||||
[ 0.186427] exdebug-0398 ex_trace_point : Method Begin [0xf58394d8:\_SB.PCI0.LPCB.ECOK] execution.
|
|
||||||
[ 0.186630] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905c88:If] execution.
|
|
||||||
[ 0.186820] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905cc0:LEqual] execution.
|
|
||||||
[ 0.187010] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905a20:-NamePath-] execution.
|
|
||||||
[ 0.187214] exdebug-0398 ex_trace_point : Opcode End [0xf5905a20:-NamePath-] execution.
|
|
||||||
[ 0.187407] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905f60:One] execution.
|
|
||||||
[ 0.187594] exdebug-0398 ex_trace_point : Opcode End [0xf5905f60:One] execution.
|
|
||||||
[ 0.187789] exdebug-0398 ex_trace_point : Opcode End [0xf5905cc0:LEqual] execution.
|
|
||||||
[ 0.187980] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905cc0:Return] execution.
|
|
||||||
[ 0.188146] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905f60:One] execution.
|
|
||||||
[ 0.188334] exdebug-0398 ex_trace_point : Opcode End [0xf5905f60:One] execution.
|
|
||||||
[ 0.188524] exdebug-0398 ex_trace_point : Opcode End [0xf5905cc0:Return] execution.
|
|
||||||
[ 0.188712] exdebug-0398 ex_trace_point : Opcode End [0xf5905c88:If] execution.
|
|
||||||
[ 0.188903] exdebug-0398 ex_trace_point : Method End [0xf58394d8:\_SB.PCI0.LPCB.ECOK] execution.
|
|
||||||
|
|
||||||
Developers can utilize these special log entries to track the AML
|
|
||||||
interpretion, thus can aid issue debugging and performance tuning. Note
|
|
||||||
that, as the "AML tracer" logs are implemented via ACPI_DEBUG_PRINT()
|
|
||||||
macro, CONFIG_ACPI_DEBUG is also required to be enabled for enabling
|
|
||||||
"AML tracer" logs.
|
|
||||||
|
|
||||||
The following command examples illustrate the usage of the "AML tracer"
|
|
||||||
functionality:
|
|
||||||
a. Filter out the method start/stop "AML tracer" logs when control
|
|
||||||
methods are being evaluated:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0x80" > trace_debug_layer
|
|
||||||
# echo "0x10" > trace_debug_level
|
|
||||||
# echo "enable" > trace_state
|
|
||||||
b. Filter out the method start/stop "AML tracer" when the specified
|
|
||||||
control method is being evaluated:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0x80" > trace_debug_layer
|
|
||||||
# echo "0x10" > trace_debug_level
|
|
||||||
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
|
||||||
# echo "method" > trace_state
|
|
||||||
c. Filter out the method start/stop "AML tracer" logs when the specified
|
|
||||||
control method is being evaluated for the first time:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0x80" > trace_debug_layer
|
|
||||||
# echo "0x10" > trace_debug_level
|
|
||||||
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
|
||||||
# echo "method-once" > trace_state
|
|
||||||
d. Filter out the method/opcode start/stop "AML tracer" when the
|
|
||||||
specified control method is being evaluated:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0x80" > trace_debug_layer
|
|
||||||
# echo "0x10" > trace_debug_level
|
|
||||||
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
|
||||||
# echo "opcode" > trace_state
|
|
||||||
e. Filter out the method/opcode start/stop "AML tracer" when the
|
|
||||||
specified control method is being evaluated for the first time:
|
|
||||||
# cd /sys/module/acpi/parameters
|
|
||||||
# echo "0x80" > trace_debug_layer
|
|
||||||
# echo "0x10" > trace_debug_level
|
|
||||||
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
|
||||||
# echo "opcode-opcode" > trace_state
|
|
||||||
|
|
||||||
Note that all above method tracing facility related module parameters can
|
|
||||||
be used as the boot parameters, for example:
|
|
||||||
acpi.trace_debug_layer=0x80 acpi.trace_debug_level=0x10 \
|
|
||||||
acpi.trace_method_name=\_SB.LID0._LID acpi.trace_state=opcode-once
|
|
||||||
|
|
||||||
2. Interface descriptions:
|
|
||||||
|
|
||||||
All method tracing functions can be configured via ACPI module
|
|
||||||
parameters that are accessible at /sys/module/acpi/parameters/:
|
|
||||||
|
|
||||||
trace_method_name
|
|
||||||
The full path of the AML method that the user wants to trace.
|
|
||||||
Note that the full path shouldn't contain the trailing "_"s in its
|
|
||||||
name segments but may contain "\" to form an absolute path.
|
|
||||||
|
|
||||||
trace_debug_layer
|
|
||||||
The temporary debug_layer used when the tracing feature is enabled.
|
|
||||||
Using ACPI_EXECUTER (0x80) by default, which is the debug_layer
|
|
||||||
used to match all "AML tracer" logs.
|
|
||||||
|
|
||||||
trace_debug_level
|
|
||||||
The temporary debug_level used when the tracing feature is enabled.
|
|
||||||
Using ACPI_LV_TRACE_POINT (0x10) by default, which is the
|
|
||||||
debug_level used to match all "AML tracer" logs.
|
|
||||||
|
|
||||||
trace_state
|
|
||||||
The status of the tracing feature.
|
|
||||||
Users can enable/disable this debug tracing feature by executing
|
|
||||||
the following command:
|
|
||||||
# echo string > /sys/module/acpi/parameters/trace_state
|
|
||||||
Where "string" should be one of the following:
|
|
||||||
"disable"
|
|
||||||
Disable the method tracing feature.
|
|
||||||
"enable"
|
|
||||||
Enable the method tracing feature.
|
|
||||||
ACPICA debugging messages matching
|
|
||||||
"trace_debug_layer/trace_debug_level" during any method
|
|
||||||
execution will be logged.
|
|
||||||
"method"
|
|
||||||
Enable the method tracing feature.
|
|
||||||
ACPICA debugging messages matching
|
|
||||||
"trace_debug_layer/trace_debug_level" during method execution
|
|
||||||
of "trace_method_name" will be logged.
|
|
||||||
"method-once"
|
|
||||||
Enable the method tracing feature.
|
|
||||||
ACPICA debugging messages matching
|
|
||||||
"trace_debug_layer/trace_debug_level" during method execution
|
|
||||||
of "trace_method_name" will be logged only once.
|
|
||||||
"opcode"
|
|
||||||
Enable the method tracing feature.
|
|
||||||
ACPICA debugging messages matching
|
|
||||||
"trace_debug_layer/trace_debug_level" during method/opcode
|
|
||||||
execution of "trace_method_name" will be logged.
|
|
||||||
"opcode-once"
|
|
||||||
Enable the method tracing feature.
|
|
||||||
ACPICA debugging messages matching
|
|
||||||
"trace_debug_layer/trace_debug_level" during method/opcode
|
|
||||||
execution of "trace_method_name" will be logged only once.
|
|
||||||
Note that, the difference between the "enable" and other feature
|
|
||||||
enabling options are:
|
|
||||||
1. When "enable" is specified, since
|
|
||||||
"trace_debug_layer/trace_debug_level" shall apply to all control
|
|
||||||
method evaluations, after configuring "trace_state" to "enable",
|
|
||||||
"trace_method_name" will be reset to NULL.
|
|
||||||
2. When "method/opcode" is specified, if
|
|
||||||
"trace_method_name" is NULL when "trace_state" is configured to
|
|
||||||
these options, the "trace_debug_layer/trace_debug_level" will
|
|
||||||
apply to all control method evaluations.
|
|
@ -1,172 +0,0 @@
|
|||||||
|
|
||||||
In order to support ACPI open-ended hardware configurations (e.g. development
|
|
||||||
boards) we need a way to augment the ACPI configuration provided by the firmware
|
|
||||||
image. A common example is connecting sensors on I2C / SPI buses on development
|
|
||||||
boards.
|
|
||||||
|
|
||||||
Although this can be accomplished by creating a kernel platform driver or
|
|
||||||
recompiling the firmware image with updated ACPI tables, neither is practical:
|
|
||||||
the former proliferates board specific kernel code while the latter requires
|
|
||||||
access to firmware tools which are often not publicly available.
|
|
||||||
|
|
||||||
Because ACPI supports external references in AML code a more practical
|
|
||||||
way to augment firmware ACPI configuration is by dynamically loading
|
|
||||||
user defined SSDT tables that contain the board specific information.
|
|
||||||
|
|
||||||
For example, to enumerate a Bosch BMA222E accelerometer on the I2C bus of the
|
|
||||||
Minnowboard MAX development board exposed via the LSE connector [1], the
|
|
||||||
following ASL code can be used:
|
|
||||||
|
|
||||||
DefinitionBlock ("minnowmax.aml", "SSDT", 1, "Vendor", "Accel", 0x00000003)
|
|
||||||
{
|
|
||||||
External (\_SB.I2C6, DeviceObj)
|
|
||||||
|
|
||||||
Scope (\_SB.I2C6)
|
|
||||||
{
|
|
||||||
Device (STAC)
|
|
||||||
{
|
|
||||||
Name (_ADR, Zero)
|
|
||||||
Name (_HID, "BMA222E")
|
|
||||||
|
|
||||||
Method (_CRS, 0, Serialized)
|
|
||||||
{
|
|
||||||
Name (RBUF, ResourceTemplate ()
|
|
||||||
{
|
|
||||||
I2cSerialBus (0x0018, ControllerInitiated, 0x00061A80,
|
|
||||||
AddressingMode7Bit, "\\_SB.I2C6", 0x00,
|
|
||||||
ResourceConsumer, ,)
|
|
||||||
GpioInt (Edge, ActiveHigh, Exclusive, PullDown, 0x0000,
|
|
||||||
"\\_SB.GPO2", 0x00, ResourceConsumer, , )
|
|
||||||
{ // Pin list
|
|
||||||
0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Return (RBUF)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
which can then be compiled to AML binary format:
|
|
||||||
|
|
||||||
$ iasl minnowmax.asl
|
|
||||||
|
|
||||||
Intel ACPI Component Architecture
|
|
||||||
ASL Optimizing Compiler version 20140214-64 [Mar 29 2014]
|
|
||||||
Copyright (c) 2000 - 2014 Intel Corporation
|
|
||||||
|
|
||||||
ASL Input: minnomax.asl - 30 lines, 614 bytes, 7 keywords
|
|
||||||
AML Output: minnowmax.aml - 165 bytes, 6 named objects, 1 executable opcodes
|
|
||||||
|
|
||||||
[1] http://wiki.minnowboard.org/MinnowBoard_MAX#Low_Speed_Expansion_Connector_.28Top.29
|
|
||||||
|
|
||||||
The resulting AML code can then be loaded by the kernel using one of the methods
|
|
||||||
below.
|
|
||||||
|
|
||||||
== Loading ACPI SSDTs from initrd ==
|
|
||||||
|
|
||||||
This option allows loading of user defined SSDTs from initrd and it is useful
|
|
||||||
when the system does not support EFI or when there is not enough EFI storage.
|
|
||||||
|
|
||||||
It works in a similar way with initrd based ACPI tables override/upgrade: SSDT
|
|
||||||
aml code must be placed in the first, uncompressed, initrd under the
|
|
||||||
"kernel/firmware/acpi" path. Multiple files can be used and this will translate
|
|
||||||
in loading multiple tables. Only SSDT and OEM tables are allowed. See
|
|
||||||
initrd_table_override.txt for more details.
|
|
||||||
|
|
||||||
Here is an example:
|
|
||||||
|
|
||||||
# Add the raw ACPI tables to an uncompressed cpio archive.
|
|
||||||
# They must be put into a /kernel/firmware/acpi directory inside the
|
|
||||||
# cpio archive.
|
|
||||||
# The uncompressed cpio archive must be the first.
|
|
||||||
# Other, typically compressed cpio archives, must be
|
|
||||||
# concatenated on top of the uncompressed one.
|
|
||||||
mkdir -p kernel/firmware/acpi
|
|
||||||
cp ssdt.aml kernel/firmware/acpi
|
|
||||||
|
|
||||||
# Create the uncompressed cpio archive and concatenate the original initrd
|
|
||||||
# on top:
|
|
||||||
find kernel | cpio -H newc --create > /boot/instrumented_initrd
|
|
||||||
cat /boot/initrd >>/boot/instrumented_initrd
|
|
||||||
|
|
||||||
== Loading ACPI SSDTs from EFI variables ==
|
|
||||||
|
|
||||||
This is the preferred method, when EFI is supported on the platform, because it
|
|
||||||
allows a persistent, OS independent way of storing the user defined SSDTs. There
|
|
||||||
is also work underway to implement EFI support for loading user defined SSDTs
|
|
||||||
and using this method will make it easier to convert to the EFI loading
|
|
||||||
mechanism when that will arrive.
|
|
||||||
|
|
||||||
In order to load SSDTs from an EFI variable the efivar_ssdt kernel command line
|
|
||||||
parameter can be used. The argument for the option is the variable name to
|
|
||||||
use. If there are multiple variables with the same name but with different
|
|
||||||
vendor GUIDs, all of them will be loaded.
|
|
||||||
|
|
||||||
In order to store the AML code in an EFI variable the efivarfs filesystem can be
|
|
||||||
used. It is enabled and mounted by default in /sys/firmware/efi/efivars in all
|
|
||||||
recent distribution.
|
|
||||||
|
|
||||||
Creating a new file in /sys/firmware/efi/efivars will automatically create a new
|
|
||||||
EFI variable. Updating a file in /sys/firmware/efi/efivars will update the EFI
|
|
||||||
variable. Please note that the file name needs to be specially formatted as
|
|
||||||
"Name-GUID" and that the first 4 bytes in the file (little-endian format)
|
|
||||||
represent the attributes of the EFI variable (see EFI_VARIABLE_MASK in
|
|
||||||
include/linux/efi.h). Writing to the file must also be done with one write
|
|
||||||
operation.
|
|
||||||
|
|
||||||
For example, you can use the following bash script to create/update an EFI
|
|
||||||
variable with the content from a given file:
|
|
||||||
|
|
||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
while ! [ -z "$1" ]; do
|
|
||||||
case "$1" in
|
|
||||||
"-f") filename="$2"; shift;;
|
|
||||||
"-g") guid="$2"; shift;;
|
|
||||||
*) name="$1";;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
usage()
|
|
||||||
{
|
|
||||||
echo "Syntax: ${0##*/} -f filename [ -g guid ] name"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
[ -n "$name" -a -f "$filename" ] || usage
|
|
||||||
|
|
||||||
EFIVARFS="/sys/firmware/efi/efivars"
|
|
||||||
|
|
||||||
[ -d "$EFIVARFS" ] || exit 2
|
|
||||||
|
|
||||||
if stat -tf $EFIVARFS | grep -q -v de5e81e4; then
|
|
||||||
mount -t efivarfs none $EFIVARFS
|
|
||||||
fi
|
|
||||||
|
|
||||||
# try to pick up an existing GUID
|
|
||||||
[ -n "$guid" ] || guid=$(find "$EFIVARFS" -name "$name-*" | head -n1 | cut -f2- -d-)
|
|
||||||
|
|
||||||
# use a randomly generated GUID
|
|
||||||
[ -n "$guid" ] || guid="$(cat /proc/sys/kernel/random/uuid)"
|
|
||||||
|
|
||||||
# efivarfs expects all of the data in one write
|
|
||||||
tmp=$(mktemp)
|
|
||||||
/bin/echo -ne "\007\000\000\000" | cat - $filename > $tmp
|
|
||||||
dd if=$tmp of="$EFIVARFS/$name-$guid" bs=$(stat -c %s $tmp)
|
|
||||||
rm $tmp
|
|
||||||
|
|
||||||
== Loading ACPI SSDTs from configfs ==
|
|
||||||
|
|
||||||
This option allows loading of user defined SSDTs from userspace via the configfs
|
|
||||||
interface. The CONFIG_ACPI_CONFIGFS option must be select and configfs must be
|
|
||||||
mounted. In the following examples, we assume that configfs has been mounted in
|
|
||||||
/config.
|
|
||||||
|
|
||||||
New tables can be loading by creating new directories in /config/acpi/table/ and
|
|
||||||
writing the SSDT aml code in the aml attribute:
|
|
||||||
|
|
||||||
cd /config/acpi/table
|
|
||||||
mkdir my_ssdt
|
|
||||||
cat ~/ssdt.aml > my_ssdt/aml
|
|
@ -1,5 +1,11 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
Collaborative Processor Performance Control (CPPC)
|
==================================================
|
||||||
|
Collaborative Processor Performance Control (CPPC)
|
||||||
|
==================================================
|
||||||
|
|
||||||
|
CPPC
|
||||||
|
====
|
||||||
|
|
||||||
CPPC defined in the ACPI spec describes a mechanism for the OS to manage the
|
CPPC defined in the ACPI spec describes a mechanism for the OS to manage the
|
||||||
performance of a logical processor on a contigious and abstract performance
|
performance of a logical processor on a contigious and abstract performance
|
||||||
@ -10,31 +16,28 @@ For more details on CPPC please refer to the ACPI specification at:
|
|||||||
|
|
||||||
http://uefi.org/specifications
|
http://uefi.org/specifications
|
||||||
|
|
||||||
Some of the CPPC registers are exposed via sysfs under:
|
Some of the CPPC registers are exposed via sysfs under::
|
||||||
|
|
||||||
/sys/devices/system/cpu/cpuX/acpi_cppc/
|
/sys/devices/system/cpu/cpuX/acpi_cppc/
|
||||||
|
|
||||||
for each cpu X
|
for each cpu X::
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
$ ls -lR /sys/devices/system/cpu/cpu0/acpi_cppc/
|
||||||
|
/sys/devices/system/cpu/cpu0/acpi_cppc/:
|
||||||
$ ls -lR /sys/devices/system/cpu/cpu0/acpi_cppc/
|
total 0
|
||||||
/sys/devices/system/cpu/cpu0/acpi_cppc/:
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 feedback_ctrs
|
||||||
total 0
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 highest_perf
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 feedback_ctrs
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_freq
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 highest_perf
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_nonlinear_perf
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_freq
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_perf
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_nonlinear_perf
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_freq
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 lowest_perf
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_perf
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_freq
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 reference_perf
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 nominal_perf
|
-r--r--r-- 1 root root 65536 Mar 5 19:38 wraparound_time
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 reference_perf
|
|
||||||
-r--r--r-- 1 root root 65536 Mar 5 19:38 wraparound_time
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
* highest_perf : Highest performance of this processor (abstract scale).
|
* highest_perf : Highest performance of this processor (abstract scale).
|
||||||
* nominal_perf : Highest sustained performance of this processor (abstract scale).
|
* nominal_perf : Highest sustained performance of this processor
|
||||||
|
(abstract scale).
|
||||||
* lowest_nonlinear_perf : Lowest performance of this processor with nonlinear
|
* lowest_nonlinear_perf : Lowest performance of this processor with nonlinear
|
||||||
power savings (abstract scale).
|
power savings (abstract scale).
|
||||||
* lowest_perf : Lowest performance of this processor (abstract scale).
|
* lowest_perf : Lowest performance of this processor (abstract scale).
|
||||||
@ -48,22 +51,26 @@ total 0
|
|||||||
* feedback_ctrs : Includes both Reference and delivered performance counter.
|
* feedback_ctrs : Includes both Reference and delivered performance counter.
|
||||||
Reference counter ticks up proportional to processor's reference performance.
|
Reference counter ticks up proportional to processor's reference performance.
|
||||||
Delivered counter ticks up proportional to processor's delivered performance.
|
Delivered counter ticks up proportional to processor's delivered performance.
|
||||||
* wraparound_time: Minimum time for the feedback counters to wraparound (seconds).
|
* wraparound_time: Minimum time for the feedback counters to wraparound
|
||||||
|
(seconds).
|
||||||
* reference_perf : Performance level at which reference performance counter
|
* reference_perf : Performance level at which reference performance counter
|
||||||
accumulates (abstract scale).
|
accumulates (abstract scale).
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Computing Average Delivered Performance
|
Computing Average Delivered Performance
|
||||||
|
=======================================
|
||||||
|
|
||||||
Below describes the steps to compute the average performance delivered by taking
|
Below describes the steps to compute the average performance delivered by
|
||||||
two different snapshots of feedback counters at time T1 and T2.
|
taking two different snapshots of feedback counters at time T1 and T2.
|
||||||
|
|
||||||
T1: Read feedback_ctrs as fbc_t1
|
T1: Read feedback_ctrs as fbc_t1
|
||||||
Wait or run some workload
|
Wait or run some workload
|
||||||
T2: Read feedback_ctrs as fbc_t2
|
|
||||||
|
|
||||||
delivered_counter_delta = fbc_t2[del] - fbc_t1[del]
|
T2: Read feedback_ctrs as fbc_t2
|
||||||
reference_counter_delta = fbc_t2[ref] - fbc_t1[ref]
|
|
||||||
|
|
||||||
delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta
|
::
|
||||||
|
|
||||||
|
delivered_counter_delta = fbc_t2[del] - fbc_t1[del]
|
||||||
|
reference_counter_delta = fbc_t2[ref] - fbc_t1[ref]
|
||||||
|
|
||||||
|
delivered_perf = (refernce_perf x delivered_counter_delta) / reference_counter_delta
|
@ -1,6 +1,12 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
===============
|
||||||
|
Overriding DSDT
|
||||||
|
===============
|
||||||
|
|
||||||
Linux supports a method of overriding the BIOS DSDT:
|
Linux supports a method of overriding the BIOS DSDT:
|
||||||
|
|
||||||
CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel.
|
CONFIG_ACPI_CUSTOM_DSDT - builds the image into the kernel.
|
||||||
|
|
||||||
When to use this method is described in detail on the
|
When to use this method is described in detail on the
|
||||||
Linux/ACPI home page:
|
Linux/ACPI home page:
|
14
Documentation/admin-guide/acpi/index.rst
Normal file
14
Documentation/admin-guide/acpi/index.rst
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
============
|
||||||
|
ACPI Support
|
||||||
|
============
|
||||||
|
|
||||||
|
Here we document in detail how to interact with various mechanisms in
|
||||||
|
the Linux ACPI support.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
initrd_table_override
|
||||||
|
dsdt-override
|
||||||
|
ssdt-overlays
|
||||||
|
cppc_sysfs
|
115
Documentation/admin-guide/acpi/initrd_table_override.rst
Normal file
115
Documentation/admin-guide/acpi/initrd_table_override.rst
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
================================
|
||||||
|
Upgrading ACPI tables via initrd
|
||||||
|
================================
|
||||||
|
|
||||||
|
What is this about
|
||||||
|
==================
|
||||||
|
|
||||||
|
If the ACPI_TABLE_UPGRADE compile option is true, it is possible to
|
||||||
|
upgrade the ACPI execution environment that is defined by the ACPI tables
|
||||||
|
via upgrading the ACPI tables provided by the BIOS with an instrumented,
|
||||||
|
modified, more recent version one, or installing brand new ACPI tables.
|
||||||
|
|
||||||
|
When building initrd with kernel in a single image, option
|
||||||
|
ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD should also be true for this
|
||||||
|
feature to work.
|
||||||
|
|
||||||
|
For a full list of ACPI tables that can be upgraded/installed, take a look
|
||||||
|
at the char `*table_sigs[MAX_ACPI_SIGNATURE];` definition in
|
||||||
|
drivers/acpi/tables.c.
|
||||||
|
|
||||||
|
All ACPI tables iasl (Intel's ACPI compiler and disassembler) knows should
|
||||||
|
be overridable, except:
|
||||||
|
|
||||||
|
- ACPI_SIG_RSDP (has a signature of 6 bytes)
|
||||||
|
- ACPI_SIG_FACS (does not have an ordinary ACPI table header)
|
||||||
|
|
||||||
|
Both could get implemented as well.
|
||||||
|
|
||||||
|
|
||||||
|
What is this for
|
||||||
|
================
|
||||||
|
|
||||||
|
Complain to your platform/BIOS vendor if you find a bug which is so severe
|
||||||
|
that a workaround is not accepted in the Linux kernel. And this facility
|
||||||
|
allows you to upgrade the buggy tables before your platform/BIOS vendor
|
||||||
|
releases an upgraded BIOS binary.
|
||||||
|
|
||||||
|
This facility can be used by platform/BIOS vendors to provide a Linux
|
||||||
|
compatible environment without modifying the underlying platform firmware.
|
||||||
|
|
||||||
|
This facility also provides a powerful feature to easily debug and test
|
||||||
|
ACPI BIOS table compatibility with the Linux kernel by modifying old
|
||||||
|
platform provided ACPI tables or inserting new ACPI tables.
|
||||||
|
|
||||||
|
It can and should be enabled in any kernel because there is no functional
|
||||||
|
change with not instrumented initrds.
|
||||||
|
|
||||||
|
|
||||||
|
How does it work
|
||||||
|
================
|
||||||
|
::
|
||||||
|
|
||||||
|
# Extract the machine's ACPI tables:
|
||||||
|
cd /tmp
|
||||||
|
acpidump >acpidump
|
||||||
|
acpixtract -a acpidump
|
||||||
|
# Disassemble, modify and recompile them:
|
||||||
|
iasl -d *.dat
|
||||||
|
# For example add this statement into a _PRT (PCI Routing Table) function
|
||||||
|
# of the DSDT:
|
||||||
|
Store("HELLO WORLD", debug)
|
||||||
|
# And increase the OEM Revision. For example, before modification:
|
||||||
|
DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000000)
|
||||||
|
# After modification:
|
||||||
|
DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000001)
|
||||||
|
iasl -sa dsdt.dsl
|
||||||
|
# Add the raw ACPI tables to an uncompressed cpio archive.
|
||||||
|
# They must be put into a /kernel/firmware/acpi directory inside the cpio
|
||||||
|
# archive. Note that if the table put here matches a platform table
|
||||||
|
# (similar Table Signature, and similar OEMID, and similar OEM Table ID)
|
||||||
|
# with a more recent OEM Revision, the platform table will be upgraded by
|
||||||
|
# this table. If the table put here doesn't match a platform table
|
||||||
|
# (dissimilar Table Signature, or dissimilar OEMID, or dissimilar OEM Table
|
||||||
|
# ID), this table will be appended.
|
||||||
|
mkdir -p kernel/firmware/acpi
|
||||||
|
cp dsdt.aml kernel/firmware/acpi
|
||||||
|
# A maximum of "NR_ACPI_INITRD_TABLES (64)" tables are currently allowed
|
||||||
|
# (see osl.c):
|
||||||
|
iasl -sa facp.dsl
|
||||||
|
iasl -sa ssdt1.dsl
|
||||||
|
cp facp.aml kernel/firmware/acpi
|
||||||
|
cp ssdt1.aml kernel/firmware/acpi
|
||||||
|
# The uncompressed cpio archive must be the first. Other, typically
|
||||||
|
# compressed cpio archives, must be concatenated on top of the uncompressed
|
||||||
|
# one. Following command creates the uncompressed cpio archive and
|
||||||
|
# concatenates the original initrd on top:
|
||||||
|
find kernel | cpio -H newc --create > /boot/instrumented_initrd
|
||||||
|
cat /boot/initrd >>/boot/instrumented_initrd
|
||||||
|
# reboot with increased acpi debug level, e.g. boot params:
|
||||||
|
acpi.debug_level=0x2 acpi.debug_layer=0xFFFFFFFF
|
||||||
|
# and check your syslog:
|
||||||
|
[ 1.268089] ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
|
||||||
|
[ 1.272091] [ACPI Debug] String [0x0B] "HELLO WORLD"
|
||||||
|
|
||||||
|
iasl is able to disassemble and recompile quite a lot different,
|
||||||
|
also static ACPI tables.
|
||||||
|
|
||||||
|
|
||||||
|
Where to retrieve userspace tools
|
||||||
|
=================================
|
||||||
|
|
||||||
|
iasl and acpixtract are part of Intel's ACPICA project:
|
||||||
|
http://acpica.org/
|
||||||
|
|
||||||
|
and should be packaged by distributions (for example in the acpica package
|
||||||
|
on SUSE).
|
||||||
|
|
||||||
|
acpidump can be found in Len Browns pmtools:
|
||||||
|
ftp://kernel.org/pub/linux/kernel/people/lenb/acpi/utils/pmtools/acpidump
|
||||||
|
|
||||||
|
This tool is also part of the acpica package on SUSE.
|
||||||
|
Alternatively, used ACPI tables can be retrieved via sysfs in latest kernels:
|
||||||
|
/sys/firmware/acpi/tables
|
180
Documentation/admin-guide/acpi/ssdt-overlays.rst
Normal file
180
Documentation/admin-guide/acpi/ssdt-overlays.rst
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
=============
|
||||||
|
SSDT Overlays
|
||||||
|
=============
|
||||||
|
|
||||||
|
In order to support ACPI open-ended hardware configurations (e.g. development
|
||||||
|
boards) we need a way to augment the ACPI configuration provided by the firmware
|
||||||
|
image. A common example is connecting sensors on I2C / SPI buses on development
|
||||||
|
boards.
|
||||||
|
|
||||||
|
Although this can be accomplished by creating a kernel platform driver or
|
||||||
|
recompiling the firmware image with updated ACPI tables, neither is practical:
|
||||||
|
the former proliferates board specific kernel code while the latter requires
|
||||||
|
access to firmware tools which are often not publicly available.
|
||||||
|
|
||||||
|
Because ACPI supports external references in AML code a more practical
|
||||||
|
way to augment firmware ACPI configuration is by dynamically loading
|
||||||
|
user defined SSDT tables that contain the board specific information.
|
||||||
|
|
||||||
|
For example, to enumerate a Bosch BMA222E accelerometer on the I2C bus of the
|
||||||
|
Minnowboard MAX development board exposed via the LSE connector [1], the
|
||||||
|
following ASL code can be used::
|
||||||
|
|
||||||
|
DefinitionBlock ("minnowmax.aml", "SSDT", 1, "Vendor", "Accel", 0x00000003)
|
||||||
|
{
|
||||||
|
External (\_SB.I2C6, DeviceObj)
|
||||||
|
|
||||||
|
Scope (\_SB.I2C6)
|
||||||
|
{
|
||||||
|
Device (STAC)
|
||||||
|
{
|
||||||
|
Name (_ADR, Zero)
|
||||||
|
Name (_HID, "BMA222E")
|
||||||
|
|
||||||
|
Method (_CRS, 0, Serialized)
|
||||||
|
{
|
||||||
|
Name (RBUF, ResourceTemplate ()
|
||||||
|
{
|
||||||
|
I2cSerialBus (0x0018, ControllerInitiated, 0x00061A80,
|
||||||
|
AddressingMode7Bit, "\\_SB.I2C6", 0x00,
|
||||||
|
ResourceConsumer, ,)
|
||||||
|
GpioInt (Edge, ActiveHigh, Exclusive, PullDown, 0x0000,
|
||||||
|
"\\_SB.GPO2", 0x00, ResourceConsumer, , )
|
||||||
|
{ // Pin list
|
||||||
|
0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Return (RBUF)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
which can then be compiled to AML binary format::
|
||||||
|
|
||||||
|
$ iasl minnowmax.asl
|
||||||
|
|
||||||
|
Intel ACPI Component Architecture
|
||||||
|
ASL Optimizing Compiler version 20140214-64 [Mar 29 2014]
|
||||||
|
Copyright (c) 2000 - 2014 Intel Corporation
|
||||||
|
|
||||||
|
ASL Input: minnomax.asl - 30 lines, 614 bytes, 7 keywords
|
||||||
|
AML Output: minnowmax.aml - 165 bytes, 6 named objects, 1 executable opcodes
|
||||||
|
|
||||||
|
[1] http://wiki.minnowboard.org/MinnowBoard_MAX#Low_Speed_Expansion_Connector_.28Top.29
|
||||||
|
|
||||||
|
The resulting AML code can then be loaded by the kernel using one of the methods
|
||||||
|
below.
|
||||||
|
|
||||||
|
Loading ACPI SSDTs from initrd
|
||||||
|
==============================
|
||||||
|
|
||||||
|
This option allows loading of user defined SSDTs from initrd and it is useful
|
||||||
|
when the system does not support EFI or when there is not enough EFI storage.
|
||||||
|
|
||||||
|
It works in a similar way with initrd based ACPI tables override/upgrade: SSDT
|
||||||
|
aml code must be placed in the first, uncompressed, initrd under the
|
||||||
|
"kernel/firmware/acpi" path. Multiple files can be used and this will translate
|
||||||
|
in loading multiple tables. Only SSDT and OEM tables are allowed. See
|
||||||
|
initrd_table_override.txt for more details.
|
||||||
|
|
||||||
|
Here is an example::
|
||||||
|
|
||||||
|
# Add the raw ACPI tables to an uncompressed cpio archive.
|
||||||
|
# They must be put into a /kernel/firmware/acpi directory inside the
|
||||||
|
# cpio archive.
|
||||||
|
# The uncompressed cpio archive must be the first.
|
||||||
|
# Other, typically compressed cpio archives, must be
|
||||||
|
# concatenated on top of the uncompressed one.
|
||||||
|
mkdir -p kernel/firmware/acpi
|
||||||
|
cp ssdt.aml kernel/firmware/acpi
|
||||||
|
|
||||||
|
# Create the uncompressed cpio archive and concatenate the original initrd
|
||||||
|
# on top:
|
||||||
|
find kernel | cpio -H newc --create > /boot/instrumented_initrd
|
||||||
|
cat /boot/initrd >>/boot/instrumented_initrd
|
||||||
|
|
||||||
|
Loading ACPI SSDTs from EFI variables
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
This is the preferred method, when EFI is supported on the platform, because it
|
||||||
|
allows a persistent, OS independent way of storing the user defined SSDTs. There
|
||||||
|
is also work underway to implement EFI support for loading user defined SSDTs
|
||||||
|
and using this method will make it easier to convert to the EFI loading
|
||||||
|
mechanism when that will arrive.
|
||||||
|
|
||||||
|
In order to load SSDTs from an EFI variable the efivar_ssdt kernel command line
|
||||||
|
parameter can be used. The argument for the option is the variable name to
|
||||||
|
use. If there are multiple variables with the same name but with different
|
||||||
|
vendor GUIDs, all of them will be loaded.
|
||||||
|
|
||||||
|
In order to store the AML code in an EFI variable the efivarfs filesystem can be
|
||||||
|
used. It is enabled and mounted by default in /sys/firmware/efi/efivars in all
|
||||||
|
recent distribution.
|
||||||
|
|
||||||
|
Creating a new file in /sys/firmware/efi/efivars will automatically create a new
|
||||||
|
EFI variable. Updating a file in /sys/firmware/efi/efivars will update the EFI
|
||||||
|
variable. Please note that the file name needs to be specially formatted as
|
||||||
|
"Name-GUID" and that the first 4 bytes in the file (little-endian format)
|
||||||
|
represent the attributes of the EFI variable (see EFI_VARIABLE_MASK in
|
||||||
|
include/linux/efi.h). Writing to the file must also be done with one write
|
||||||
|
operation.
|
||||||
|
|
||||||
|
For example, you can use the following bash script to create/update an EFI
|
||||||
|
variable with the content from a given file::
|
||||||
|
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
while ! [ -z "$1" ]; do
|
||||||
|
case "$1" in
|
||||||
|
"-f") filename="$2"; shift;;
|
||||||
|
"-g") guid="$2"; shift;;
|
||||||
|
*) name="$1";;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
echo "Syntax: ${0##*/} -f filename [ -g guid ] name"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -n "$name" -a -f "$filename" ] || usage
|
||||||
|
|
||||||
|
EFIVARFS="/sys/firmware/efi/efivars"
|
||||||
|
|
||||||
|
[ -d "$EFIVARFS" ] || exit 2
|
||||||
|
|
||||||
|
if stat -tf $EFIVARFS | grep -q -v de5e81e4; then
|
||||||
|
mount -t efivarfs none $EFIVARFS
|
||||||
|
fi
|
||||||
|
|
||||||
|
# try to pick up an existing GUID
|
||||||
|
[ -n "$guid" ] || guid=$(find "$EFIVARFS" -name "$name-*" | head -n1 | cut -f2- -d-)
|
||||||
|
|
||||||
|
# use a randomly generated GUID
|
||||||
|
[ -n "$guid" ] || guid="$(cat /proc/sys/kernel/random/uuid)"
|
||||||
|
|
||||||
|
# efivarfs expects all of the data in one write
|
||||||
|
tmp=$(mktemp)
|
||||||
|
/bin/echo -ne "\007\000\000\000" | cat - $filename > $tmp
|
||||||
|
dd if=$tmp of="$EFIVARFS/$name-$guid" bs=$(stat -c %s $tmp)
|
||||||
|
rm $tmp
|
||||||
|
|
||||||
|
Loading ACPI SSDTs from configfs
|
||||||
|
================================
|
||||||
|
|
||||||
|
This option allows loading of user defined SSDTs from userspace via the configfs
|
||||||
|
interface. The CONFIG_ACPI_CONFIGFS option must be select and configfs must be
|
||||||
|
mounted. In the following examples, we assume that configfs has been mounted in
|
||||||
|
/config.
|
||||||
|
|
||||||
|
New tables can be loading by creating new directories in /config/acpi/table/ and
|
||||||
|
writing the SSDT aml code in the aml attribute::
|
||||||
|
|
||||||
|
cd /config/acpi/table
|
||||||
|
mkdir my_ssdt
|
||||||
|
cat ~/ssdt.aml > my_ssdt/aml
|
@ -77,6 +77,7 @@ configure specific aspects of kernel behavior to your liking.
|
|||||||
LSM/index
|
LSM/index
|
||||||
mm/index
|
mm/index
|
||||||
perf-security
|
perf-security
|
||||||
|
acpi/index
|
||||||
|
|
||||||
.. only:: subproject and html
|
.. only:: subproject and html
|
||||||
|
|
||||||
|
9
Documentation/driver-api/acpi/index.rst
Normal file
9
Documentation/driver-api/acpi/index.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
============
|
||||||
|
ACPI Support
|
||||||
|
============
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
linuxized-acpica
|
||||||
|
scan_handlers
|
@ -1,31 +1,37 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
============================================================
|
||||||
Linuxized ACPICA - Introduction to ACPICA Release Automation
|
Linuxized ACPICA - Introduction to ACPICA Release Automation
|
||||||
|
============================================================
|
||||||
|
|
||||||
Copyright (C) 2013-2016, Intel Corporation
|
:Copyright: |copy| 2013-2016, Intel Corporation
|
||||||
Author: Lv Zheng <lv.zheng@intel.com>
|
|
||||||
|
:Author: Lv Zheng <lv.zheng@intel.com>
|
||||||
|
|
||||||
|
|
||||||
Abstract:
|
Abstract
|
||||||
|
========
|
||||||
This document describes the ACPICA project and the relationship between
|
This document describes the ACPICA project and the relationship between
|
||||||
ACPICA and Linux. It also describes how ACPICA code in drivers/acpi/acpica,
|
ACPICA and Linux. It also describes how ACPICA code in drivers/acpi/acpica,
|
||||||
include/acpi and tools/power/acpi is automatically updated to follow the
|
include/acpi and tools/power/acpi is automatically updated to follow the
|
||||||
upstream.
|
upstream.
|
||||||
|
|
||||||
|
ACPICA Project
|
||||||
|
==============
|
||||||
|
|
||||||
1. ACPICA Project
|
The ACPI Component Architecture (ACPICA) project provides an operating
|
||||||
|
system (OS)-independent reference implementation of the Advanced
|
||||||
|
Configuration and Power Interface Specification (ACPI). It has been
|
||||||
|
adapted by various host OSes. By directly integrating ACPICA, Linux can
|
||||||
|
also benefit from the application experiences of ACPICA from other host
|
||||||
|
OSes.
|
||||||
|
|
||||||
The ACPI Component Architecture (ACPICA) project provides an operating
|
The homepage of ACPICA project is: www.acpica.org, it is maintained and
|
||||||
system (OS)-independent reference implementation of the Advanced
|
supported by Intel Corporation.
|
||||||
Configuration and Power Interface Specification (ACPI). It has been
|
|
||||||
adapted by various host OSes. By directly integrating ACPICA, Linux can
|
|
||||||
also benefit from the application experiences of ACPICA from other host
|
|
||||||
OSes.
|
|
||||||
|
|
||||||
The homepage of ACPICA project is: www.acpica.org, it is maintained and
|
The following figure depicts the Linux ACPI subsystem where the ACPICA
|
||||||
supported by Intel Corporation.
|
adaptation is included::
|
||||||
|
|
||||||
The following figure depicts the Linux ACPI subsystem where the ACPICA
|
|
||||||
adaptation is included:
|
|
||||||
|
|
||||||
+---------------------------------------------------------+
|
+---------------------------------------------------------+
|
||||||
| |
|
| |
|
||||||
@ -71,21 +77,27 @@ upstream.
|
|||||||
|
|
||||||
Figure 1. Linux ACPI Software Components
|
Figure 1. Linux ACPI Software Components
|
||||||
|
|
||||||
NOTE:
|
.. note::
|
||||||
A. OS Service Layer - Provided by Linux to offer OS dependent
|
A. OS Service Layer - Provided by Linux to offer OS dependent
|
||||||
implementation of the predefined ACPICA interfaces (acpi_os_*).
|
implementation of the predefined ACPICA interfaces (acpi_os_*).
|
||||||
|
::
|
||||||
|
|
||||||
include/acpi/acpiosxf.h
|
include/acpi/acpiosxf.h
|
||||||
drivers/acpi/osl.c
|
drivers/acpi/osl.c
|
||||||
include/acpi/platform
|
include/acpi/platform
|
||||||
include/asm/acenv.h
|
include/asm/acenv.h
|
||||||
B. ACPICA Functionality - Released from ACPICA code base to offer
|
B. ACPICA Functionality - Released from ACPICA code base to offer
|
||||||
OS independent implementation of the ACPICA interfaces (acpi_*).
|
OS independent implementation of the ACPICA interfaces (acpi_*).
|
||||||
|
::
|
||||||
|
|
||||||
drivers/acpi/acpica
|
drivers/acpi/acpica
|
||||||
include/acpi/ac*.h
|
include/acpi/ac*.h
|
||||||
tools/power/acpi
|
tools/power/acpi
|
||||||
C. Linux/ACPI Functionality - Providing Linux specific ACPI
|
C. Linux/ACPI Functionality - Providing Linux specific ACPI
|
||||||
functionality to the other Linux kernel subsystems and user space
|
functionality to the other Linux kernel subsystems and user space
|
||||||
programs.
|
programs.
|
||||||
|
::
|
||||||
|
|
||||||
drivers/acpi
|
drivers/acpi
|
||||||
include/linux/acpi.h
|
include/linux/acpi.h
|
||||||
include/linux/acpi*.h
|
include/linux/acpi*.h
|
||||||
@ -95,24 +107,27 @@ upstream.
|
|||||||
ACPI subsystem to offer architecture specific implementation of the
|
ACPI subsystem to offer architecture specific implementation of the
|
||||||
ACPI interfaces. They are Linux specific components and are out of
|
ACPI interfaces. They are Linux specific components and are out of
|
||||||
the scope of this document.
|
the scope of this document.
|
||||||
|
::
|
||||||
|
|
||||||
include/asm/acpi.h
|
include/asm/acpi.h
|
||||||
include/asm/acpi*.h
|
include/asm/acpi*.h
|
||||||
arch/*/acpi
|
arch/*/acpi
|
||||||
|
|
||||||
2. ACPICA Release
|
ACPICA Release
|
||||||
|
==============
|
||||||
|
|
||||||
The ACPICA project maintains its code base at the following repository URL:
|
The ACPICA project maintains its code base at the following repository URL:
|
||||||
https://github.com/acpica/acpica.git. As a rule, a release is made every
|
https://github.com/acpica/acpica.git. As a rule, a release is made every
|
||||||
month.
|
month.
|
||||||
|
|
||||||
As the coding style adopted by the ACPICA project is not acceptable by
|
As the coding style adopted by the ACPICA project is not acceptable by
|
||||||
Linux, there is a release process to convert the ACPICA git commits into
|
Linux, there is a release process to convert the ACPICA git commits into
|
||||||
Linux patches. The patches generated by this process are referred to as
|
Linux patches. The patches generated by this process are referred to as
|
||||||
"linuxized ACPICA patches". The release process is carried out on a local
|
"linuxized ACPICA patches". The release process is carried out on a local
|
||||||
copy the ACPICA git repository. Each commit in the monthly release is
|
copy the ACPICA git repository. Each commit in the monthly release is
|
||||||
converted into a linuxized ACPICA patch. Together, they form the monthly
|
converted into a linuxized ACPICA patch. Together, they form the monthly
|
||||||
ACPICA release patchset for the Linux ACPI community. This process is
|
ACPICA release patchset for the Linux ACPI community. This process is
|
||||||
illustrated in the following figure:
|
illustrated in the following figure::
|
||||||
|
|
||||||
+-----------------------------+
|
+-----------------------------+
|
||||||
| acpica / master (-) commits |
|
| acpica / master (-) commits |
|
||||||
@ -153,7 +168,7 @@ upstream.
|
|||||||
|
|
||||||
Figure 2. ACPICA -> Linux Upstream Process
|
Figure 2. ACPICA -> Linux Upstream Process
|
||||||
|
|
||||||
NOTE:
|
.. note::
|
||||||
A. Linuxize Utilities - Provided by the ACPICA repository, including a
|
A. Linuxize Utilities - Provided by the ACPICA repository, including a
|
||||||
utility located in source/tools/acpisrc folder and a number of
|
utility located in source/tools/acpisrc folder and a number of
|
||||||
scripts located in generate/linux folder.
|
scripts located in generate/linux folder.
|
||||||
@ -170,19 +185,20 @@ upstream.
|
|||||||
following kernel configuration options:
|
following kernel configuration options:
|
||||||
CONFIG_ACPI/CONFIG_ACPI_DEBUG/CONFIG_ACPI_DEBUGGER
|
CONFIG_ACPI/CONFIG_ACPI_DEBUG/CONFIG_ACPI_DEBUGGER
|
||||||
|
|
||||||
3. ACPICA Divergences
|
ACPICA Divergences
|
||||||
|
==================
|
||||||
|
|
||||||
Ideally, all of the ACPICA commits should be converted into Linux patches
|
Ideally, all of the ACPICA commits should be converted into Linux patches
|
||||||
automatically without manual modifications, the "linux / master" tree should
|
automatically without manual modifications, the "linux / master" tree should
|
||||||
contain the ACPICA code that exactly corresponds to the ACPICA code
|
contain the ACPICA code that exactly corresponds to the ACPICA code
|
||||||
contained in "new linuxized acpica" tree and it should be possible to run
|
contained in "new linuxized acpica" tree and it should be possible to run
|
||||||
the release process fully automatically.
|
the release process fully automatically.
|
||||||
|
|
||||||
As a matter of fact, however, there are source code differences between
|
As a matter of fact, however, there are source code differences between
|
||||||
the ACPICA code in Linux and the upstream ACPICA code, referred to as
|
the ACPICA code in Linux and the upstream ACPICA code, referred to as
|
||||||
"ACPICA Divergences".
|
"ACPICA Divergences".
|
||||||
|
|
||||||
The various sources of ACPICA divergences include:
|
The various sources of ACPICA divergences include:
|
||||||
1. Legacy divergences - Before the current ACPICA release process was
|
1. Legacy divergences - Before the current ACPICA release process was
|
||||||
established, there already had been divergences between Linux and
|
established, there already had been divergences between Linux and
|
||||||
ACPICA. Over the past several years those divergences have been greatly
|
ACPICA. Over the past several years those divergences have been greatly
|
||||||
@ -213,11 +229,12 @@ upstream.
|
|||||||
rebased on the ACPICA side in order to offer better solutions, new ACPICA
|
rebased on the ACPICA side in order to offer better solutions, new ACPICA
|
||||||
divergences are generated.
|
divergences are generated.
|
||||||
|
|
||||||
4. ACPICA Development
|
ACPICA Development
|
||||||
|
==================
|
||||||
|
|
||||||
This paragraph guides Linux developers to use the ACPICA upstream release
|
This paragraph guides Linux developers to use the ACPICA upstream release
|
||||||
utilities to obtain Linux patches corresponding to upstream ACPICA commits
|
utilities to obtain Linux patches corresponding to upstream ACPICA commits
|
||||||
before they become available from the ACPICA release process.
|
before they become available from the ACPICA release process.
|
||||||
|
|
||||||
1. Cherry-pick an ACPICA commit
|
1. Cherry-pick an ACPICA commit
|
||||||
|
|
||||||
@ -225,7 +242,7 @@ upstream.
|
|||||||
you want to cherry pick must be committed into the local repository.
|
you want to cherry pick must be committed into the local repository.
|
||||||
|
|
||||||
Then the gen-patch.sh command can help to cherry-pick an ACPICA commit
|
Then the gen-patch.sh command can help to cherry-pick an ACPICA commit
|
||||||
from the ACPICA local repository:
|
from the ACPICA local repository::
|
||||||
|
|
||||||
$ git clone https://github.com/acpica/acpica
|
$ git clone https://github.com/acpica/acpica
|
||||||
$ cd acpica
|
$ cd acpica
|
||||||
@ -240,7 +257,7 @@ upstream.
|
|||||||
changes that haven't been applied to Linux yet.
|
changes that haven't been applied to Linux yet.
|
||||||
|
|
||||||
You can generate the ACPICA release series yourself and rebase your code on
|
You can generate the ACPICA release series yourself and rebase your code on
|
||||||
top of the generated ACPICA release patches:
|
top of the generated ACPICA release patches::
|
||||||
|
|
||||||
$ git clone https://github.com/acpica/acpica
|
$ git clone https://github.com/acpica/acpica
|
||||||
$ cd acpica
|
$ cd acpica
|
||||||
@ -254,7 +271,7 @@ upstream.
|
|||||||
3. Inspect the current divergences
|
3. Inspect the current divergences
|
||||||
|
|
||||||
If you have local copies of both Linux and upstream ACPICA, you can generate
|
If you have local copies of both Linux and upstream ACPICA, you can generate
|
||||||
a diff file indicating the state of the current divergences:
|
a diff file indicating the state of the current divergences::
|
||||||
|
|
||||||
# git clone https://github.com/acpica/acpica
|
# git clone https://github.com/acpica/acpica
|
||||||
# git clone http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
# git clone http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
@ -1,7 +1,13 @@
|
|||||||
ACPI Scan Handlers
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
Copyright (C) 2012, Intel Corporation
|
==================
|
||||||
Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
ACPI Scan Handlers
|
||||||
|
==================
|
||||||
|
|
||||||
|
:Copyright: |copy| 2012, Intel Corporation
|
||||||
|
|
||||||
|
:Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||||
|
|
||||||
During system initialization and ACPI-based device hot-add, the ACPI namespace
|
During system initialization and ACPI-based device hot-add, the ACPI namespace
|
||||||
is scanned in search of device objects that generally represent various pieces
|
is scanned in search of device objects that generally represent various pieces
|
||||||
@ -30,14 +36,14 @@ to configure that link so that the kernel can use it.
|
|||||||
Those additional configuration tasks usually depend on the type of the hardware
|
Those additional configuration tasks usually depend on the type of the hardware
|
||||||
component represented by the given device node which can be determined on the
|
component represented by the given device node which can be determined on the
|
||||||
basis of the device node's hardware ID (HID). They are performed by objects
|
basis of the device node's hardware ID (HID). They are performed by objects
|
||||||
called ACPI scan handlers represented by the following structure:
|
called ACPI scan handlers represented by the following structure::
|
||||||
|
|
||||||
struct acpi_scan_handler {
|
struct acpi_scan_handler {
|
||||||
const struct acpi_device_id *ids;
|
const struct acpi_device_id *ids;
|
||||||
struct list_head list_node;
|
struct list_head list_node;
|
||||||
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
|
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
|
||||||
void (*detach)(struct acpi_device *dev);
|
void (*detach)(struct acpi_device *dev);
|
||||||
};
|
};
|
||||||
|
|
||||||
where ids is the list of IDs of device nodes the given handler is supposed to
|
where ids is the list of IDs of device nodes the given handler is supposed to
|
||||||
take care of, list_node is the hook to the global list of ACPI scan handlers
|
take care of, list_node is the hook to the global list of ACPI scan handlers
|
@ -56,6 +56,7 @@ available subsections can be seen below.
|
|||||||
slimbus
|
slimbus
|
||||||
soundwire/index
|
soundwire/index
|
||||||
fpga/index
|
fpga/index
|
||||||
|
acpi/index
|
||||||
|
|
||||||
.. only:: subproject and html
|
.. only:: subproject and html
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
==================================
|
||||||
_DSD Device Properties Usage Rules
|
_DSD Device Properties Usage Rules
|
||||||
----------------------------------
|
==================================
|
||||||
|
|
||||||
Properties, Property Sets and Property Subsets
|
Properties, Property Sets and Property Subsets
|
||||||
----------------------------------------------
|
==============================================
|
||||||
|
|
||||||
The _DSD (Device Specific Data) configuration object, introduced in ACPI 5.1,
|
The _DSD (Device Specific Data) configuration object, introduced in ACPI 5.1,
|
||||||
allows any type of device configuration data to be provided via the ACPI
|
allows any type of device configuration data to be provided via the ACPI
|
||||||
@ -18,7 +21,7 @@ specific type) associated with it.
|
|||||||
|
|
||||||
In the ACPI _DSD context it is an element of the sub-package following the
|
In the ACPI _DSD context it is an element of the sub-package following the
|
||||||
generic Device Properties UUID in the _DSD return package as specified in the
|
generic Device Properties UUID in the _DSD return package as specified in the
|
||||||
Device Properties UUID definition document [1].
|
Device Properties UUID definition document [1]_.
|
||||||
|
|
||||||
It also may be regarded as the definition of a key and the associated data type
|
It also may be regarded as the definition of a key and the associated data type
|
||||||
that can be returned by _DSD in the Device Properties UUID sub-package for a
|
that can be returned by _DSD in the Device Properties UUID sub-package for a
|
||||||
@ -33,14 +36,14 @@ Property subsets are nested collections of properties. Each of them is
|
|||||||
associated with an additional key (name) allowing the subset to be referred
|
associated with an additional key (name) allowing the subset to be referred
|
||||||
to as a whole (and to be treated as a separate entity). The canonical
|
to as a whole (and to be treated as a separate entity). The canonical
|
||||||
representation of property subsets is via the mechanism specified in the
|
representation of property subsets is via the mechanism specified in the
|
||||||
Hierarchical Properties Extension UUID definition document [2].
|
Hierarchical Properties Extension UUID definition document [2]_.
|
||||||
|
|
||||||
Property sets may be hierarchical. That is, a property set may contain
|
Property sets may be hierarchical. That is, a property set may contain
|
||||||
multiple property subsets that each may contain property subsets of its
|
multiple property subsets that each may contain property subsets of its
|
||||||
own and so on.
|
own and so on.
|
||||||
|
|
||||||
General Validity Rule for Property Sets
|
General Validity Rule for Property Sets
|
||||||
---------------------------------------
|
=======================================
|
||||||
|
|
||||||
Valid property sets must follow the guidance given by the Device Properties UUID
|
Valid property sets must follow the guidance given by the Device Properties UUID
|
||||||
definition document [1].
|
definition document [1].
|
||||||
@ -73,7 +76,7 @@ suitable for the ACPI environment and consequently they cannot belong to a valid
|
|||||||
property set.
|
property set.
|
||||||
|
|
||||||
Property Sets and Device Tree Bindings
|
Property Sets and Device Tree Bindings
|
||||||
--------------------------------------
|
======================================
|
||||||
|
|
||||||
It often is useful to make _DSD return property sets that follow Device Tree
|
It often is useful to make _DSD return property sets that follow Device Tree
|
||||||
bindings.
|
bindings.
|
||||||
@ -91,7 +94,7 @@ expected to automatically work in the ACPI environment regardless of their
|
|||||||
contents.
|
contents.
|
||||||
|
|
||||||
References
|
References
|
||||||
----------
|
==========
|
||||||
|
|
||||||
[1] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
|
.. [1] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
|
||||||
[2] http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf
|
.. [2] http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf
|
@ -1,13 +1,18 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
=========================================================
|
||||||
Special Usage Model of the ACPI Control Method Lid Device
|
Special Usage Model of the ACPI Control Method Lid Device
|
||||||
|
=========================================================
|
||||||
|
|
||||||
Copyright (C) 2016, Intel Corporation
|
:Copyright: |copy| 2016, Intel Corporation
|
||||||
Author: Lv Zheng <lv.zheng@intel.com>
|
|
||||||
|
|
||||||
|
:Author: Lv Zheng <lv.zheng@intel.com>
|
||||||
|
|
||||||
Abstract:
|
Abstract
|
||||||
|
========
|
||||||
Platforms containing lids convey lid state (open/close) to OSPMs using a
|
Platforms containing lids convey lid state (open/close) to OSPMs
|
||||||
control method lid device. To implement this, the AML tables issue
|
using a control method lid device. To implement this, the AML tables issue
|
||||||
Notify(lid_device, 0x80) to notify the OSPMs whenever the lid state has
|
Notify(lid_device, 0x80) to notify the OSPMs whenever the lid state has
|
||||||
changed. The _LID control method for the lid device must be implemented to
|
changed. The _LID control method for the lid device must be implemented to
|
||||||
report the "current" state of the lid as either "opened" or "closed".
|
report the "current" state of the lid as either "opened" or "closed".
|
||||||
@ -19,7 +24,8 @@ taken into account. This document describes the restrictions and the
|
|||||||
expections of the Linux ACPI lid device driver.
|
expections of the Linux ACPI lid device driver.
|
||||||
|
|
||||||
|
|
||||||
1. Restrictions of the returning value of the _LID control method
|
Restrictions of the returning value of the _LID control method
|
||||||
|
==============================================================
|
||||||
|
|
||||||
The _LID control method is described to return the "current" lid state.
|
The _LID control method is described to return the "current" lid state.
|
||||||
However the word of "current" has ambiguity, some buggy AML tables return
|
However the word of "current" has ambiguity, some buggy AML tables return
|
||||||
@ -30,7 +36,8 @@ initial returning value. When the AML tables implement this control method
|
|||||||
with cached value, the initial returning value is likely not reliable.
|
with cached value, the initial returning value is likely not reliable.
|
||||||
There are platforms always retun "closed" as initial lid state.
|
There are platforms always retun "closed" as initial lid state.
|
||||||
|
|
||||||
2. Restrictions of the lid state change notifications
|
Restrictions of the lid state change notifications
|
||||||
|
==================================================
|
||||||
|
|
||||||
There are buggy AML tables never notifying when the lid device state is
|
There are buggy AML tables never notifying when the lid device state is
|
||||||
changed to "opened". Thus the "opened" notification is not guaranteed. But
|
changed to "opened". Thus the "opened" notification is not guaranteed. But
|
||||||
@ -39,18 +46,22 @@ state is changed to "closed". The "closed" notification is normally used to
|
|||||||
trigger some system power saving operations on Windows. Since it is fully
|
trigger some system power saving operations on Windows. Since it is fully
|
||||||
tested, it is reliable from all AML tables.
|
tested, it is reliable from all AML tables.
|
||||||
|
|
||||||
3. Expections for the userspace users of the ACPI lid device driver
|
Expections for the userspace users of the ACPI lid device driver
|
||||||
|
================================================================
|
||||||
|
|
||||||
The ACPI button driver exports the lid state to the userspace via the
|
The ACPI button driver exports the lid state to the userspace via the
|
||||||
following file:
|
following file::
|
||||||
|
|
||||||
/proc/acpi/button/lid/LID0/state
|
/proc/acpi/button/lid/LID0/state
|
||||||
|
|
||||||
This file actually calls the _LID control method described above. And given
|
This file actually calls the _LID control method described above. And given
|
||||||
the previous explanation, it is not reliable enough on some platforms. So
|
the previous explanation, it is not reliable enough on some platforms. So
|
||||||
it is advised for the userspace program to not to solely rely on this file
|
it is advised for the userspace program to not to solely rely on this file
|
||||||
to determine the actual lid state.
|
to determine the actual lid state.
|
||||||
|
|
||||||
The ACPI button driver emits the following input event to the userspace:
|
The ACPI button driver emits the following input event to the userspace:
|
||||||
SW_LID
|
* SW_LID
|
||||||
|
|
||||||
The ACPI lid device driver is implemented to try to deliver the platform
|
The ACPI lid device driver is implemented to try to deliver the platform
|
||||||
triggered events to the userspace. However, given the fact that the buggy
|
triggered events to the userspace. However, given the fact that the buggy
|
||||||
firmware cannot make sure "opened"/"closed" events are paired, the ACPI
|
firmware cannot make sure "opened"/"closed" events are paired, the ACPI
|
||||||
@ -59,20 +70,25 @@ button driver uses the following 3 modes in order not to trigger issues.
|
|||||||
If the userspace hasn't been prepared to ignore the unreliable "opened"
|
If the userspace hasn't been prepared to ignore the unreliable "opened"
|
||||||
events and the unreliable initial state notification, Linux users can use
|
events and the unreliable initial state notification, Linux users can use
|
||||||
the following kernel parameters to handle the possible issues:
|
the following kernel parameters to handle the possible issues:
|
||||||
|
|
||||||
A. button.lid_init_state=method:
|
A. button.lid_init_state=method:
|
||||||
When this option is specified, the ACPI button driver reports the
|
When this option is specified, the ACPI button driver reports the
|
||||||
initial lid state using the returning value of the _LID control method
|
initial lid state using the returning value of the _LID control method
|
||||||
and whether the "opened"/"closed" events are paired fully relies on the
|
and whether the "opened"/"closed" events are paired fully relies on the
|
||||||
firmware implementation.
|
firmware implementation.
|
||||||
|
|
||||||
This option can be used to fix some platforms where the returning value
|
This option can be used to fix some platforms where the returning value
|
||||||
of the _LID control method is reliable but the initial lid state
|
of the _LID control method is reliable but the initial lid state
|
||||||
notification is missing.
|
notification is missing.
|
||||||
|
|
||||||
This option is the default behavior during the period the userspace
|
This option is the default behavior during the period the userspace
|
||||||
isn't ready to handle the buggy AML tables.
|
isn't ready to handle the buggy AML tables.
|
||||||
|
|
||||||
B. button.lid_init_state=open:
|
B. button.lid_init_state=open:
|
||||||
When this option is specified, the ACPI button driver always reports the
|
When this option is specified, the ACPI button driver always reports the
|
||||||
initial lid state as "opened" and whether the "opened"/"closed" events
|
initial lid state as "opened" and whether the "opened"/"closed" events
|
||||||
are paired fully relies on the firmware implementation.
|
are paired fully relies on the firmware implementation.
|
||||||
|
|
||||||
This may fix some platforms where the returning value of the _LID
|
This may fix some platforms where the returning value of the _LID
|
||||||
control method is not reliable and the initial lid state notification is
|
control method is not reliable and the initial lid state notification is
|
||||||
missing.
|
missing.
|
||||||
@ -80,6 +96,7 @@ B. button.lid_init_state=open:
|
|||||||
If the userspace has been prepared to ignore the unreliable "opened" events
|
If the userspace has been prepared to ignore the unreliable "opened" events
|
||||||
and the unreliable initial state notification, Linux users should always
|
and the unreliable initial state notification, Linux users should always
|
||||||
use the following kernel parameter:
|
use the following kernel parameter:
|
||||||
|
|
||||||
C. button.lid_init_state=ignore:
|
C. button.lid_init_state=ignore:
|
||||||
When this option is specified, the ACPI button driver never reports the
|
When this option is specified, the ACPI button driver never reports the
|
||||||
initial lid state and there is a compensation mechanism implemented to
|
initial lid state and there is a compensation mechanism implemented to
|
||||||
@ -89,6 +106,7 @@ C. button.lid_init_state=ignore:
|
|||||||
notifications can be delivered to the userspace when the lid is actually
|
notifications can be delivered to the userspace when the lid is actually
|
||||||
opens given that some AML tables do not send "opened" notifications
|
opens given that some AML tables do not send "opened" notifications
|
||||||
reliably.
|
reliably.
|
||||||
|
|
||||||
In this mode, if everything is correctly implemented by the platform
|
In this mode, if everything is correctly implemented by the platform
|
||||||
firmware, the old userspace programs should still work. Otherwise, the
|
firmware, the old userspace programs should still work. Otherwise, the
|
||||||
new userspace programs are required to work with the ACPI button driver.
|
new userspace programs are required to work with the ACPI button driver.
|
75
Documentation/firmware-guide/acpi/aml-debugger.rst
Normal file
75
Documentation/firmware-guide/acpi/aml-debugger.rst
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
================
|
||||||
|
The AML Debugger
|
||||||
|
================
|
||||||
|
|
||||||
|
:Copyright: |copy| 2016, Intel Corporation
|
||||||
|
:Author: Lv Zheng <lv.zheng@intel.com>
|
||||||
|
|
||||||
|
|
||||||
|
This document describes the usage of the AML debugger embedded in the Linux
|
||||||
|
kernel.
|
||||||
|
|
||||||
|
1. Build the debugger
|
||||||
|
=====================
|
||||||
|
|
||||||
|
The following kernel configuration items are required to enable the AML
|
||||||
|
debugger interface from the Linux kernel::
|
||||||
|
|
||||||
|
CONFIG_ACPI_DEBUGGER=y
|
||||||
|
CONFIG_ACPI_DEBUGGER_USER=m
|
||||||
|
|
||||||
|
The userspace utilities can be built from the kernel source tree using
|
||||||
|
the following commands::
|
||||||
|
|
||||||
|
$ cd tools
|
||||||
|
$ make acpi
|
||||||
|
|
||||||
|
The resultant userspace tool binary is then located at::
|
||||||
|
|
||||||
|
tools/power/acpi/acpidbg
|
||||||
|
|
||||||
|
It can be installed to system directories by running "make install" (as a
|
||||||
|
sufficiently privileged user).
|
||||||
|
|
||||||
|
2. Start the userspace debugger interface
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
After booting the kernel with the debugger built-in, the debugger can be
|
||||||
|
started by using the following commands::
|
||||||
|
|
||||||
|
# mount -t debugfs none /sys/kernel/debug
|
||||||
|
# modprobe acpi_dbg
|
||||||
|
# tools/power/acpi/acpidbg
|
||||||
|
|
||||||
|
That spawns the interactive AML debugger environment where you can execute
|
||||||
|
debugger commands.
|
||||||
|
|
||||||
|
The commands are documented in the "ACPICA Overview and Programmer Reference"
|
||||||
|
that can be downloaded from
|
||||||
|
|
||||||
|
https://acpica.org/documentation
|
||||||
|
|
||||||
|
The detailed debugger commands reference is located in Chapter 12 "ACPICA
|
||||||
|
Debugger Reference". The "help" command can be used for a quick reference.
|
||||||
|
|
||||||
|
3. Stop the userspace debugger interface
|
||||||
|
========================================
|
||||||
|
|
||||||
|
The interactive debugger interface can be closed by pressing Ctrl+C or using
|
||||||
|
the "quit" or "exit" commands. When finished, unload the module with::
|
||||||
|
|
||||||
|
# rmmod acpi_dbg
|
||||||
|
|
||||||
|
The module unloading may fail if there is an acpidbg instance running.
|
||||||
|
|
||||||
|
4. Run the debugger in a script
|
||||||
|
===============================
|
||||||
|
|
||||||
|
It may be useful to run the AML debugger in a test script. "acpidbg" supports
|
||||||
|
this in a special "batch" mode. For example, the following command outputs
|
||||||
|
the entire ACPI namespace::
|
||||||
|
|
||||||
|
# acpidbg -b "namespace"
|
@ -1,13 +1,16 @@
|
|||||||
APEI Error INJection
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
====================
|
||||||
|
APEI Error INJection
|
||||||
|
====================
|
||||||
|
|
||||||
EINJ provides a hardware error injection mechanism. It is very useful
|
EINJ provides a hardware error injection mechanism. It is very useful
|
||||||
for debugging and testing APEI and RAS features in general.
|
for debugging and testing APEI and RAS features in general.
|
||||||
|
|
||||||
You need to check whether your BIOS supports EINJ first. For that, look
|
You need to check whether your BIOS supports EINJ first. For that, look
|
||||||
for early boot messages similar to this one:
|
for early boot messages similar to this one::
|
||||||
|
|
||||||
ACPI: EINJ 0x000000007370A000 000150 (v01 INTEL 00000001 INTL 00000001)
|
ACPI: EINJ 0x000000007370A000 000150 (v01 INTEL 00000001 INTL 00000001)
|
||||||
|
|
||||||
which shows that the BIOS is exposing an EINJ table - it is the
|
which shows that the BIOS is exposing an EINJ table - it is the
|
||||||
mechanism through which the injection is done.
|
mechanism through which the injection is done.
|
||||||
@ -23,11 +26,11 @@ order to see the APEI,EINJ,... functionality supported and exposed by
|
|||||||
the BIOS menu.
|
the BIOS menu.
|
||||||
|
|
||||||
To use EINJ, make sure the following are options enabled in your kernel
|
To use EINJ, make sure the following are options enabled in your kernel
|
||||||
configuration:
|
configuration::
|
||||||
|
|
||||||
CONFIG_DEBUG_FS
|
CONFIG_DEBUG_FS
|
||||||
CONFIG_ACPI_APEI
|
CONFIG_ACPI_APEI
|
||||||
CONFIG_ACPI_APEI_EINJ
|
CONFIG_ACPI_APEI_EINJ
|
||||||
|
|
||||||
The EINJ user interface is in <debugfs mount point>/apei/einj.
|
The EINJ user interface is in <debugfs mount point>/apei/einj.
|
||||||
|
|
||||||
@ -37,20 +40,22 @@ The following files belong to it:
|
|||||||
|
|
||||||
This file shows which error types are supported:
|
This file shows which error types are supported:
|
||||||
|
|
||||||
|
================ ===================================
|
||||||
Error Type Value Error Description
|
Error Type Value Error Description
|
||||||
================ =================
|
================ ===================================
|
||||||
0x00000001 Processor Correctable
|
0x00000001 Processor Correctable
|
||||||
0x00000002 Processor Uncorrectable non-fatal
|
0x00000002 Processor Uncorrectable non-fatal
|
||||||
0x00000004 Processor Uncorrectable fatal
|
0x00000004 Processor Uncorrectable fatal
|
||||||
0x00000008 Memory Correctable
|
0x00000008 Memory Correctable
|
||||||
0x00000010 Memory Uncorrectable non-fatal
|
0x00000010 Memory Uncorrectable non-fatal
|
||||||
0x00000020 Memory Uncorrectable fatal
|
0x00000020 Memory Uncorrectable fatal
|
||||||
0x00000040 PCI Express Correctable
|
0x00000040 PCI Express Correctable
|
||||||
0x00000080 PCI Express Uncorrectable fatal
|
0x00000080 PCI Express Uncorrectable fatal
|
||||||
0x00000100 PCI Express Uncorrectable non-fatal
|
0x00000100 PCI Express Uncorrectable non-fatal
|
||||||
0x00000200 Platform Correctable
|
0x00000200 Platform Correctable
|
||||||
0x00000400 Platform Uncorrectable non-fatal
|
0x00000400 Platform Uncorrectable non-fatal
|
||||||
0x00000800 Platform Uncorrectable fatal
|
0x00000800 Platform Uncorrectable fatal
|
||||||
|
================ ===================================
|
||||||
|
|
||||||
The format of the file contents are as above, except present are only
|
The format of the file contents are as above, except present are only
|
||||||
the available error types.
|
the available error types.
|
||||||
@ -73,9 +78,12 @@ The following files belong to it:
|
|||||||
injection. Value is a bitmask as specified in ACPI5.0 spec for the
|
injection. Value is a bitmask as specified in ACPI5.0 spec for the
|
||||||
SET_ERROR_TYPE_WITH_ADDRESS data structure:
|
SET_ERROR_TYPE_WITH_ADDRESS data structure:
|
||||||
|
|
||||||
Bit 0 - Processor APIC field valid (see param3 below).
|
Bit 0
|
||||||
Bit 1 - Memory address and mask valid (param1 and param2).
|
Processor APIC field valid (see param3 below).
|
||||||
Bit 2 - PCIe (seg,bus,dev,fn) valid (see param4 below).
|
Bit 1
|
||||||
|
Memory address and mask valid (param1 and param2).
|
||||||
|
Bit 2
|
||||||
|
PCIe (seg,bus,dev,fn) valid (see param4 below).
|
||||||
|
|
||||||
If set to zero, legacy behavior is mimicked where the type of
|
If set to zero, legacy behavior is mimicked where the type of
|
||||||
injection specifies just one bit set, and param1 is multiplexed.
|
injection specifies just one bit set, and param1 is multiplexed.
|
||||||
@ -121,7 +129,7 @@ BIOS versions based on the ACPI 5.0 specification have more control over
|
|||||||
the target of the injection. For processor-related errors (type 0x1, 0x2
|
the target of the injection. For processor-related errors (type 0x1, 0x2
|
||||||
and 0x4), you can set flags to 0x3 (param3 for bit 0, and param1 and
|
and 0x4), you can set flags to 0x3 (param3 for bit 0, and param1 and
|
||||||
param2 for bit 1) so that you have more information added to the error
|
param2 for bit 1) so that you have more information added to the error
|
||||||
signature being injected. The actual data passed is this:
|
signature being injected. The actual data passed is this::
|
||||||
|
|
||||||
memory_address = param1;
|
memory_address = param1;
|
||||||
memory_address_range = param2;
|
memory_address_range = param2;
|
||||||
@ -131,7 +139,7 @@ signature being injected. The actual data passed is this:
|
|||||||
For memory errors (type 0x8, 0x10 and 0x20) the address is set using
|
For memory errors (type 0x8, 0x10 and 0x20) the address is set using
|
||||||
param1 with a mask in param2 (0x0 is equivalent to all ones). For PCI
|
param1 with a mask in param2 (0x0 is equivalent to all ones). For PCI
|
||||||
express errors (type 0x40, 0x80 and 0x100) the segment, bus, device and
|
express errors (type 0x40, 0x80 and 0x100) the segment, bus, device and
|
||||||
function are specified using param1:
|
function are specified using param1::
|
||||||
|
|
||||||
31 24 23 16 15 11 10 8 7 0
|
31 24 23 16 15 11 10 8 7 0
|
||||||
+-------------------------------------------------+
|
+-------------------------------------------------+
|
||||||
@ -152,26 +160,26 @@ documentation for details (and expect changes to this API if vendors
|
|||||||
creativity in using this feature expands beyond our expectations).
|
creativity in using this feature expands beyond our expectations).
|
||||||
|
|
||||||
|
|
||||||
An error injection example:
|
An error injection example::
|
||||||
|
|
||||||
# cd /sys/kernel/debug/apei/einj
|
# cd /sys/kernel/debug/apei/einj
|
||||||
# cat available_error_type # See which errors can be injected
|
# cat available_error_type # See which errors can be injected
|
||||||
0x00000002 Processor Uncorrectable non-fatal
|
0x00000002 Processor Uncorrectable non-fatal
|
||||||
0x00000008 Memory Correctable
|
0x00000008 Memory Correctable
|
||||||
0x00000010 Memory Uncorrectable non-fatal
|
0x00000010 Memory Uncorrectable non-fatal
|
||||||
# echo 0x12345000 > param1 # Set memory address for injection
|
# echo 0x12345000 > param1 # Set memory address for injection
|
||||||
# echo $((-1 << 12)) > param2 # Mask 0xfffffffffffff000 - anywhere in this page
|
# echo $((-1 << 12)) > param2 # Mask 0xfffffffffffff000 - anywhere in this page
|
||||||
# echo 0x8 > error_type # Choose correctable memory error
|
# echo 0x8 > error_type # Choose correctable memory error
|
||||||
# echo 1 > error_inject # Inject now
|
# echo 1 > error_inject # Inject now
|
||||||
|
|
||||||
You should see something like this in dmesg:
|
You should see something like this in dmesg::
|
||||||
|
|
||||||
[22715.830801] EDAC sbridge MC3: HANDLING MCE MEMORY ERROR
|
[22715.830801] EDAC sbridge MC3: HANDLING MCE MEMORY ERROR
|
||||||
[22715.834759] EDAC sbridge MC3: CPU 0: Machine Check Event: 0 Bank 7: 8c00004000010090
|
[22715.834759] EDAC sbridge MC3: CPU 0: Machine Check Event: 0 Bank 7: 8c00004000010090
|
||||||
[22715.834759] EDAC sbridge MC3: TSC 0
|
[22715.834759] EDAC sbridge MC3: TSC 0
|
||||||
[22715.834759] EDAC sbridge MC3: ADDR 12345000 EDAC sbridge MC3: MISC 144780c86
|
[22715.834759] EDAC sbridge MC3: ADDR 12345000 EDAC sbridge MC3: MISC 144780c86
|
||||||
[22715.834759] EDAC sbridge MC3: PROCESSOR 0:306e7 TIME 1422553404 SOCKET 0 APIC 0
|
[22715.834759] EDAC sbridge MC3: PROCESSOR 0:306e7 TIME 1422553404 SOCKET 0 APIC 0
|
||||||
[22716.616173] EDAC MC3: 1 CE memory read error on CPU_SrcID#0_Channel#0_DIMM#0 (channel:0 slot:0 page:0x12345 offset:0x0 grain:32 syndrome:0x0 - area:DRAM err_code:0001:0090 socket:0 channel_mask:1 rank:0)
|
[22716.616173] EDAC MC3: 1 CE memory read error on CPU_SrcID#0_Channel#0_DIMM#0 (channel:0 slot:0 page:0x12345 offset:0x0 grain:32 syndrome:0x0 - area:DRAM err_code:0001:0090 socket:0 channel_mask:1 rank:0)
|
||||||
|
|
||||||
For more information about EINJ, please refer to ACPI specification
|
For more information about EINJ, please refer to ACPI specification
|
||||||
version 4.0, section 17.5 and ACPI 5.0, section 18.6.
|
version 4.0, section 17.5 and ACPI 5.0, section 18.6.
|
150
Documentation/firmware-guide/acpi/apei/output_format.rst
Normal file
150
Documentation/firmware-guide/acpi/apei/output_format.rst
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
==================
|
||||||
|
APEI output format
|
||||||
|
==================
|
||||||
|
|
||||||
|
APEI uses printk as hardware error reporting interface, the output
|
||||||
|
format is as follow::
|
||||||
|
|
||||||
|
<error record> :=
|
||||||
|
APEI generic hardware error status
|
||||||
|
severity: <integer>, <severity string>
|
||||||
|
section: <integer>, severity: <integer>, <severity string>
|
||||||
|
flags: <integer>
|
||||||
|
<section flags strings>
|
||||||
|
fru_id: <uuid string>
|
||||||
|
fru_text: <string>
|
||||||
|
section_type: <section type string>
|
||||||
|
<section data>
|
||||||
|
|
||||||
|
<severity string>* := recoverable | fatal | corrected | info
|
||||||
|
|
||||||
|
<section flags strings># :=
|
||||||
|
[primary][, containment warning][, reset][, threshold exceeded]\
|
||||||
|
[, resource not accessible][, latent error]
|
||||||
|
|
||||||
|
<section type string> := generic processor error | memory error | \
|
||||||
|
PCIe error | unknown, <uuid string>
|
||||||
|
|
||||||
|
<section data> :=
|
||||||
|
<generic processor section data> | <memory section data> | \
|
||||||
|
<pcie section data> | <null>
|
||||||
|
|
||||||
|
<generic processor section data> :=
|
||||||
|
[processor_type: <integer>, <proc type string>]
|
||||||
|
[processor_isa: <integer>, <proc isa string>]
|
||||||
|
[error_type: <integer>
|
||||||
|
<proc error type strings>]
|
||||||
|
[operation: <integer>, <proc operation string>]
|
||||||
|
[flags: <integer>
|
||||||
|
<proc flags strings>]
|
||||||
|
[level: <integer>]
|
||||||
|
[version_info: <integer>]
|
||||||
|
[processor_id: <integer>]
|
||||||
|
[target_address: <integer>]
|
||||||
|
[requestor_id: <integer>]
|
||||||
|
[responder_id: <integer>]
|
||||||
|
[IP: <integer>]
|
||||||
|
|
||||||
|
<proc type string>* := IA32/X64 | IA64
|
||||||
|
|
||||||
|
<proc isa string>* := IA32 | IA64 | X64
|
||||||
|
|
||||||
|
<processor error type strings># :=
|
||||||
|
[cache error][, TLB error][, bus error][, micro-architectural error]
|
||||||
|
|
||||||
|
<proc operation string>* := unknown or generic | data read | data write | \
|
||||||
|
instruction execution
|
||||||
|
|
||||||
|
<proc flags strings># :=
|
||||||
|
[restartable][, precise IP][, overflow][, corrected]
|
||||||
|
|
||||||
|
<memory section data> :=
|
||||||
|
[error_status: <integer>]
|
||||||
|
[physical_address: <integer>]
|
||||||
|
[physical_address_mask: <integer>]
|
||||||
|
[node: <integer>]
|
||||||
|
[card: <integer>]
|
||||||
|
[module: <integer>]
|
||||||
|
[bank: <integer>]
|
||||||
|
[device: <integer>]
|
||||||
|
[row: <integer>]
|
||||||
|
[column: <integer>]
|
||||||
|
[bit_position: <integer>]
|
||||||
|
[requestor_id: <integer>]
|
||||||
|
[responder_id: <integer>]
|
||||||
|
[target_id: <integer>]
|
||||||
|
[error_type: <integer>, <mem error type string>]
|
||||||
|
|
||||||
|
<mem error type string>* :=
|
||||||
|
unknown | no error | single-bit ECC | multi-bit ECC | \
|
||||||
|
single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \
|
||||||
|
target abort | parity error | watchdog timeout | invalid address | \
|
||||||
|
mirror Broken | memory sparing | scrub corrected error | \
|
||||||
|
scrub uncorrected error
|
||||||
|
|
||||||
|
<pcie section data> :=
|
||||||
|
[port_type: <integer>, <pcie port type string>]
|
||||||
|
[version: <integer>.<integer>]
|
||||||
|
[command: <integer>, status: <integer>]
|
||||||
|
[device_id: <integer>:<integer>:<integer>.<integer>
|
||||||
|
slot: <integer>
|
||||||
|
secondary_bus: <integer>
|
||||||
|
vendor_id: <integer>, device_id: <integer>
|
||||||
|
class_code: <integer>]
|
||||||
|
[serial number: <integer>, <integer>]
|
||||||
|
[bridge: secondary_status: <integer>, control: <integer>]
|
||||||
|
[aer_status: <integer>, aer_mask: <integer>
|
||||||
|
<aer status string>
|
||||||
|
[aer_uncor_severity: <integer>]
|
||||||
|
aer_layer=<aer layer string>, aer_agent=<aer agent string>
|
||||||
|
aer_tlp_header: <integer> <integer> <integer> <integer>]
|
||||||
|
|
||||||
|
<pcie port type string>* := PCIe end point | legacy PCI end point | \
|
||||||
|
unknown | unknown | root port | upstream switch port | \
|
||||||
|
downstream switch port | PCIe to PCI/PCI-X bridge | \
|
||||||
|
PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \
|
||||||
|
root complex event collector
|
||||||
|
|
||||||
|
if section severity is fatal or recoverable
|
||||||
|
<aer status string># :=
|
||||||
|
unknown | unknown | unknown | unknown | Data Link Protocol | \
|
||||||
|
unknown | unknown | unknown | unknown | unknown | unknown | unknown | \
|
||||||
|
Poisoned TLP | Flow Control Protocol | Completion Timeout | \
|
||||||
|
Completer Abort | Unexpected Completion | Receiver Overflow | \
|
||||||
|
Malformed TLP | ECRC | Unsupported Request
|
||||||
|
else
|
||||||
|
<aer status string># :=
|
||||||
|
Receiver Error | unknown | unknown | unknown | unknown | unknown | \
|
||||||
|
Bad TLP | Bad DLLP | RELAY_NUM Rollover | unknown | unknown | unknown | \
|
||||||
|
Replay Timer Timeout | Advisory Non-Fatal
|
||||||
|
fi
|
||||||
|
|
||||||
|
<aer layer string> :=
|
||||||
|
Physical Layer | Data Link Layer | Transaction Layer
|
||||||
|
|
||||||
|
<aer agent string> :=
|
||||||
|
Receiver ID | Requester ID | Completer ID | Transmitter ID
|
||||||
|
|
||||||
|
Where, [] designate corresponding content is optional
|
||||||
|
|
||||||
|
All <field string> description with * has the following format::
|
||||||
|
|
||||||
|
field: <integer>, <field string>
|
||||||
|
|
||||||
|
Where value of <integer> should be the position of "string" in <field
|
||||||
|
string> description. Otherwise, <field string> will be "unknown".
|
||||||
|
|
||||||
|
All <field strings> description with # has the following format::
|
||||||
|
|
||||||
|
field: <integer>
|
||||||
|
<field strings>
|
||||||
|
|
||||||
|
Where each string in <fields strings> corresponding to one set bit of
|
||||||
|
<integer>. The bit position is the position of "string" in <field
|
||||||
|
strings> description.
|
||||||
|
|
||||||
|
For more detailed explanation of every field, please refer to UEFI
|
||||||
|
specification version 2.3 or later, section Appendix N: Common
|
||||||
|
Platform Error Record.
|
@ -1,18 +1,21 @@
|
|||||||
ACPI Debug Output
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
=================
|
||||||
|
ACPI Debug Output
|
||||||
|
=================
|
||||||
|
|
||||||
The ACPI CA, the Linux ACPI core, and some ACPI drivers can generate debug
|
The ACPI CA, the Linux ACPI core, and some ACPI drivers can generate debug
|
||||||
output. This document describes how to use this facility.
|
output. This document describes how to use this facility.
|
||||||
|
|
||||||
Compile-time configuration
|
Compile-time configuration
|
||||||
--------------------------
|
==========================
|
||||||
|
|
||||||
ACPI debug output is globally enabled by CONFIG_ACPI_DEBUG. If this config
|
ACPI debug output is globally enabled by CONFIG_ACPI_DEBUG. If this config
|
||||||
option is turned off, the debug messages are not even built into the
|
option is turned off, the debug messages are not even built into the
|
||||||
kernel.
|
kernel.
|
||||||
|
|
||||||
Boot- and run-time configuration
|
Boot- and run-time configuration
|
||||||
--------------------------------
|
================================
|
||||||
|
|
||||||
When CONFIG_ACPI_DEBUG=y, you can select the component and level of messages
|
When CONFIG_ACPI_DEBUG=y, you can select the component and level of messages
|
||||||
you're interested in. At boot-time, use the acpi.debug_layer and
|
you're interested in. At boot-time, use the acpi.debug_layer and
|
||||||
@ -21,7 +24,7 @@ debug_layer and debug_level files in /sys/module/acpi/parameters/ to control
|
|||||||
the debug messages.
|
the debug messages.
|
||||||
|
|
||||||
debug_layer (component)
|
debug_layer (component)
|
||||||
-----------------------
|
=======================
|
||||||
|
|
||||||
The "debug_layer" is a mask that selects components of interest, e.g., a
|
The "debug_layer" is a mask that selects components of interest, e.g., a
|
||||||
specific driver or part of the ACPI interpreter. To build the debug_layer
|
specific driver or part of the ACPI interpreter. To build the debug_layer
|
||||||
@ -33,7 +36,7 @@ to /sys/module/acpi/parameters/debug_layer.
|
|||||||
|
|
||||||
The possible components are defined in include/acpi/acoutput.h and
|
The possible components are defined in include/acpi/acoutput.h and
|
||||||
include/acpi/acpi_drivers.h. Reading /sys/module/acpi/parameters/debug_layer
|
include/acpi/acpi_drivers.h. Reading /sys/module/acpi/parameters/debug_layer
|
||||||
shows the supported mask values, currently these:
|
shows the supported mask values, currently these::
|
||||||
|
|
||||||
ACPI_UTILITIES 0x00000001
|
ACPI_UTILITIES 0x00000001
|
||||||
ACPI_HARDWARE 0x00000002
|
ACPI_HARDWARE 0x00000002
|
||||||
@ -65,7 +68,7 @@ shows the supported mask values, currently these:
|
|||||||
ACPI_PROCESSOR_COMPONENT 0x20000000
|
ACPI_PROCESSOR_COMPONENT 0x20000000
|
||||||
|
|
||||||
debug_level
|
debug_level
|
||||||
-----------
|
===========
|
||||||
|
|
||||||
The "debug_level" is a mask that selects different types of messages, e.g.,
|
The "debug_level" is a mask that selects different types of messages, e.g.,
|
||||||
those related to initialization, method execution, informational messages, etc.
|
those related to initialization, method execution, informational messages, etc.
|
||||||
@ -81,7 +84,7 @@ to /sys/module/acpi/parameters/debug_level.
|
|||||||
|
|
||||||
The possible levels are defined in include/acpi/acoutput.h. Reading
|
The possible levels are defined in include/acpi/acoutput.h. Reading
|
||||||
/sys/module/acpi/parameters/debug_level shows the supported mask values,
|
/sys/module/acpi/parameters/debug_level shows the supported mask values,
|
||||||
currently these:
|
currently these::
|
||||||
|
|
||||||
ACPI_LV_INIT 0x00000001
|
ACPI_LV_INIT 0x00000001
|
||||||
ACPI_LV_DEBUG_OBJECT 0x00000002
|
ACPI_LV_DEBUG_OBJECT 0x00000002
|
||||||
@ -113,9 +116,9 @@ currently these:
|
|||||||
ACPI_LV_EVENTS 0x80000000
|
ACPI_LV_EVENTS 0x80000000
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
--------
|
========
|
||||||
|
|
||||||
For example, drivers/acpi/bus.c contains this:
|
For example, drivers/acpi/bus.c contains this::
|
||||||
|
|
||||||
#define _COMPONENT ACPI_BUS_COMPONENT
|
#define _COMPONENT ACPI_BUS_COMPONENT
|
||||||
...
|
...
|
||||||
@ -127,22 +130,22 @@ statement uses ACPI_DB_INFO, which is macro based on the ACPI_LV_INFO
|
|||||||
definition.)
|
definition.)
|
||||||
|
|
||||||
Enable all AML "Debug" output (stores to the Debug object while interpreting
|
Enable all AML "Debug" output (stores to the Debug object while interpreting
|
||||||
AML) during boot:
|
AML) during boot::
|
||||||
|
|
||||||
acpi.debug_layer=0xffffffff acpi.debug_level=0x2
|
acpi.debug_layer=0xffffffff acpi.debug_level=0x2
|
||||||
|
|
||||||
Enable PCI and PCI interrupt routing debug messages:
|
Enable PCI and PCI interrupt routing debug messages::
|
||||||
|
|
||||||
acpi.debug_layer=0x400000 acpi.debug_level=0x4
|
acpi.debug_layer=0x400000 acpi.debug_level=0x4
|
||||||
|
|
||||||
Enable all ACPI hardware-related messages:
|
Enable all ACPI hardware-related messages::
|
||||||
|
|
||||||
acpi.debug_layer=0x2 acpi.debug_level=0xffffffff
|
acpi.debug_layer=0x2 acpi.debug_level=0xffffffff
|
||||||
|
|
||||||
Enable all ACPI_DB_INFO messages after boot:
|
Enable all ACPI_DB_INFO messages after boot::
|
||||||
|
|
||||||
# echo 0x4 > /sys/module/acpi/parameters/debug_level
|
# echo 0x4 > /sys/module/acpi/parameters/debug_level
|
||||||
|
|
||||||
Show all valid component values:
|
Show all valid component values::
|
||||||
|
|
||||||
# cat /sys/module/acpi/parameters/debug_layer
|
# cat /sys/module/acpi/parameters/debug_layer
|
@ -1,9 +1,12 @@
|
|||||||
Copyright (C) 2018 Intel Corporation
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
Author: Sakari Ailus <sakari.ailus@linux.intel.com>
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
|
||||||
|
===================================
|
||||||
Referencing hierarchical data nodes
|
Referencing hierarchical data nodes
|
||||||
-----------------------------------
|
===================================
|
||||||
|
|
||||||
|
:Copyright: |copy| 2018 Intel Corporation
|
||||||
|
:Author: Sakari Ailus <sakari.ailus@linux.intel.com>
|
||||||
|
|
||||||
ACPI in general allows referring to device objects in the tree only.
|
ACPI in general allows referring to device objects in the tree only.
|
||||||
Hierarchical data extension nodes may not be referred to directly, hence this
|
Hierarchical data extension nodes may not be referred to directly, hence this
|
||||||
@ -28,13 +31,14 @@ extension key.
|
|||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
=======
|
||||||
|
|
||||||
In the ASL snippet below, the "reference" _DSD property [2] contains a
|
In the ASL snippet below, the "reference" _DSD property [2] contains a
|
||||||
device object reference to DEV0 and under that device object, a
|
device object reference to DEV0 and under that device object, a
|
||||||
hierarchical data extension key "node@1" referring to the NOD1 object
|
hierarchical data extension key "node@1" referring to the NOD1 object
|
||||||
and lastly, a hierarchical data extension key "anothernode" referring to
|
and lastly, a hierarchical data extension key "anothernode" referring to
|
||||||
the ANOD object which is also the final target node of the reference.
|
the ANOD object which is also the final target node of the reference.
|
||||||
|
::
|
||||||
|
|
||||||
Device (DEV0)
|
Device (DEV0)
|
||||||
{
|
{
|
||||||
@ -75,15 +79,15 @@ Example
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Please also see a graph example in graph.txt .
|
Please also see a graph example in :doc:`graph`.
|
||||||
|
|
||||||
References
|
References
|
||||||
----------
|
==========
|
||||||
|
|
||||||
[1] Hierarchical Data Extension UUID For _DSD.
|
[1] Hierarchical Data Extension UUID For _DSD.
|
||||||
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf>,
|
<http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf>,
|
||||||
referenced 2018-07-17.
|
referenced 2018-07-17.
|
||||||
|
|
||||||
[2] Device Properties UUID For _DSD.
|
[2] Device Properties UUID For _DSD.
|
||||||
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf>,
|
<http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf>,
|
||||||
referenced 2016-10-04.
|
referenced 2016-10-04.
|
@ -1,8 +1,11 @@
|
|||||||
Graphs
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
======
|
||||||
|
Graphs
|
||||||
|
======
|
||||||
|
|
||||||
_DSD
|
_DSD
|
||||||
----
|
====
|
||||||
|
|
||||||
_DSD (Device Specific Data) [7] is a predefined ACPI device
|
_DSD (Device Specific Data) [7] is a predefined ACPI device
|
||||||
configuration object that can be used to convey information on
|
configuration object that can be used to convey information on
|
||||||
@ -30,7 +33,7 @@ hierarchical data extension array on each depth.
|
|||||||
|
|
||||||
|
|
||||||
Ports and endpoints
|
Ports and endpoints
|
||||||
-------------------
|
===================
|
||||||
|
|
||||||
The port and endpoint concepts are very similar to those in Devicetree
|
The port and endpoint concepts are very similar to those in Devicetree
|
||||||
[3]. A port represents an interface in a device, and an endpoint
|
[3]. A port represents an interface in a device, and an endpoint
|
||||||
@ -38,9 +41,9 @@ represents a connection to that interface.
|
|||||||
|
|
||||||
All port nodes are located under the device's "_DSD" node in the hierarchical
|
All port nodes are located under the device's "_DSD" node in the hierarchical
|
||||||
data extension tree. The data extension related to each port node must begin
|
data extension tree. The data extension related to each port node must begin
|
||||||
with "port" and must be followed by the "@" character and the number of the port
|
with "port" and must be followed by the "@" character and the number of the
|
||||||
as its key. The target object it refers to should be called "PRTX", where "X" is
|
port as its key. The target object it refers to should be called "PRTX", where
|
||||||
the number of the port. An example of such a package would be:
|
"X" is the number of the port. An example of such a package would be::
|
||||||
|
|
||||||
Package() { "port@4", PRT4 }
|
Package() { "port@4", PRT4 }
|
||||||
|
|
||||||
@ -49,7 +52,7 @@ data extension key of the endpoint nodes must begin with
|
|||||||
"endpoint" and must be followed by the "@" character and the number of the
|
"endpoint" and must be followed by the "@" character and the number of the
|
||||||
endpoint. The object it refers to should be called "EPXY", where "X" is the
|
endpoint. The object it refers to should be called "EPXY", where "X" is the
|
||||||
number of the port and "Y" is the number of the endpoint. An example of such a
|
number of the port and "Y" is the number of the endpoint. An example of such a
|
||||||
package would be:
|
package would be::
|
||||||
|
|
||||||
Package() { "endpoint@0", EP40 }
|
Package() { "endpoint@0", EP40 }
|
||||||
|
|
||||||
@ -62,85 +65,85 @@ of that port shall be zero. Similarly, if a port may only have a single
|
|||||||
endpoint, the number of that endpoint shall be zero.
|
endpoint, the number of that endpoint shall be zero.
|
||||||
|
|
||||||
The endpoint reference uses property extension with "remote-endpoint" property
|
The endpoint reference uses property extension with "remote-endpoint" property
|
||||||
name followed by a reference in the same package. Such references consist of the
|
name followed by a reference in the same package. Such references consist of
|
||||||
the remote device reference, the first package entry of the port data extension
|
the remote device reference, the first package entry of the port data extension
|
||||||
reference under the device and finally the first package entry of the endpoint
|
reference under the device and finally the first package entry of the endpoint
|
||||||
data extension reference under the port. Individual references thus appear as:
|
data extension reference under the port. Individual references thus appear as::
|
||||||
|
|
||||||
Package() { device, "port@X", "endpoint@Y" }
|
Package() { device, "port@X", "endpoint@Y" }
|
||||||
|
|
||||||
In the above example, "X" is the number of the port and "Y" is the number of the
|
In the above example, "X" is the number of the port and "Y" is the number of
|
||||||
endpoint.
|
the endpoint.
|
||||||
|
|
||||||
The references to endpoints must be always done both ways, to the
|
The references to endpoints must be always done both ways, to the
|
||||||
remote endpoint and back from the referred remote endpoint node.
|
remote endpoint and back from the referred remote endpoint node.
|
||||||
|
|
||||||
A simple example of this is show below:
|
A simple example of this is show below::
|
||||||
|
|
||||||
Scope (\_SB.PCI0.I2C2)
|
Scope (\_SB.PCI0.I2C2)
|
||||||
{
|
{
|
||||||
Device (CAM0)
|
Device (CAM0)
|
||||||
{
|
{
|
||||||
Name (_DSD, Package () {
|
Name (_DSD, Package () {
|
||||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "compatible", Package () { "nokia,smia" } },
|
Package () { "compatible", Package () { "nokia,smia" } },
|
||||||
},
|
},
|
||||||
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "port@0", PRT0 },
|
Package () { "port@0", PRT0 },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Name (PRT0, Package() {
|
Name (PRT0, Package() {
|
||||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "reg", 0 },
|
Package () { "reg", 0 },
|
||||||
},
|
},
|
||||||
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "endpoint@0", EP00 },
|
Package () { "endpoint@0", EP00 },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Name (EP00, Package() {
|
Name (EP00, Package() {
|
||||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "reg", 0 },
|
Package () { "reg", 0 },
|
||||||
Package () { "remote-endpoint", Package() { \_SB.PCI0.ISP, "port@4", "endpoint@0" } },
|
Package () { "remote-endpoint", Package() { \_SB.PCI0.ISP, "port@4", "endpoint@0" } },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope (\_SB.PCI0)
|
Scope (\_SB.PCI0)
|
||||||
{
|
{
|
||||||
Device (ISP)
|
Device (ISP)
|
||||||
{
|
{
|
||||||
Name (_DSD, Package () {
|
Name (_DSD, Package () {
|
||||||
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "port@4", PRT4 },
|
Package () { "port@4", PRT4 },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Name (PRT4, Package() {
|
Name (PRT4, Package() {
|
||||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "reg", 4 }, /* CSI-2 port number */
|
Package () { "reg", 4 }, /* CSI-2 port number */
|
||||||
},
|
},
|
||||||
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "endpoint@0", EP40 },
|
Package () { "endpoint@0", EP40 },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Name (EP40, Package() {
|
Name (EP40, Package() {
|
||||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||||
Package () {
|
Package () {
|
||||||
Package () { "reg", 0 },
|
Package () { "reg", 0 },
|
||||||
Package () { "remote-endpoint", Package () { \_SB.PCI0.I2C2.CAM0, "port@0", "endpoint@0" } },
|
Package () { "remote-endpoint", Package () { \_SB.PCI0.I2C2.CAM0, "port@0", "endpoint@0" } },
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Here, the port 0 of the "CAM0" device is connected to the port 4 of
|
Here, the port 0 of the "CAM0" device is connected to the port 4 of
|
||||||
@ -148,27 +151,27 @@ the "ISP" device and vice versa.
|
|||||||
|
|
||||||
|
|
||||||
References
|
References
|
||||||
----------
|
==========
|
||||||
|
|
||||||
[1] _DSD (Device Specific Data) Implementation Guide.
|
[1] _DSD (Device Specific Data) Implementation Guide.
|
||||||
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel-1_1.htm>,
|
http://www.uefi.org/sites/default/files/resources/_DSD-implementation-guide-toplevel-1_1.htm,
|
||||||
referenced 2016-10-03.
|
referenced 2016-10-03.
|
||||||
|
|
||||||
[2] Devicetree. <URL:http://www.devicetree.org>, referenced 2016-10-03.
|
[2] Devicetree. http://www.devicetree.org, referenced 2016-10-03.
|
||||||
|
|
||||||
[3] Documentation/devicetree/bindings/graph.txt
|
[3] Documentation/devicetree/bindings/graph.txt
|
||||||
|
|
||||||
[4] Device Properties UUID For _DSD.
|
[4] Device Properties UUID For _DSD.
|
||||||
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf>,
|
http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf,
|
||||||
referenced 2016-10-04.
|
referenced 2016-10-04.
|
||||||
|
|
||||||
[5] Hierarchical Data Extension UUID For _DSD.
|
[5] Hierarchical Data Extension UUID For _DSD.
|
||||||
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf>,
|
http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf,
|
||||||
referenced 2016-10-04.
|
referenced 2016-10-04.
|
||||||
|
|
||||||
[6] Advanced Configuration and Power Interface Specification.
|
[6] Advanced Configuration and Power Interface Specification.
|
||||||
<URL:http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf>,
|
http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf,
|
||||||
referenced 2016-10-04.
|
referenced 2016-10-04.
|
||||||
|
|
||||||
[7] _DSD Device Properties Usage Rules.
|
[7] _DSD Device Properties Usage Rules.
|
||||||
Documentation/acpi/DSD-properties-rules.txt
|
:doc:`../DSD-properties-rules`
|
@ -1,5 +1,9 @@
|
|||||||
ACPI based device enumeration
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
=============================
|
||||||
|
ACPI Based Device Enumeration
|
||||||
|
=============================
|
||||||
|
|
||||||
ACPI 5 introduced a set of new resources (UartTSerialBus, I2cSerialBus,
|
ACPI 5 introduced a set of new resources (UartTSerialBus, I2cSerialBus,
|
||||||
SpiSerialBus, GpioIo and GpioInt) which can be used in enumerating slave
|
SpiSerialBus, GpioIo and GpioInt) which can be used in enumerating slave
|
||||||
devices behind serial bus controllers.
|
devices behind serial bus controllers.
|
||||||
@ -11,12 +15,12 @@ that are accessed through memory-mapped registers.
|
|||||||
In order to support this and re-use the existing drivers as much as
|
In order to support this and re-use the existing drivers as much as
|
||||||
possible we decided to do following:
|
possible we decided to do following:
|
||||||
|
|
||||||
o Devices that have no bus connector resource are represented as
|
- Devices that have no bus connector resource are represented as
|
||||||
platform devices.
|
platform devices.
|
||||||
|
|
||||||
o Devices behind real busses where there is a connector resource
|
- Devices behind real busses where there is a connector resource
|
||||||
are represented as struct spi_device or struct i2c_device
|
are represented as struct spi_device or struct i2c_device
|
||||||
(standard UARTs are not busses so there is no struct uart_device).
|
(standard UARTs are not busses so there is no struct uart_device).
|
||||||
|
|
||||||
As both ACPI and Device Tree represent a tree of devices (and their
|
As both ACPI and Device Tree represent a tree of devices (and their
|
||||||
resources) this implementation follows the Device Tree way as much as
|
resources) this implementation follows the Device Tree way as much as
|
||||||
@ -31,7 +35,8 @@ enumerated from ACPI namespace. This handle can be used to extract other
|
|||||||
device-specific configuration. There is an example of this below.
|
device-specific configuration. There is an example of this below.
|
||||||
|
|
||||||
Platform bus support
|
Platform bus support
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
====================
|
||||||
|
|
||||||
Since we are using platform devices to represent devices that are not
|
Since we are using platform devices to represent devices that are not
|
||||||
connected to any physical bus we only need to implement a platform driver
|
connected to any physical bus we only need to implement a platform driver
|
||||||
for the device and add supported ACPI IDs. If this same IP-block is used on
|
for the device and add supported ACPI IDs. If this same IP-block is used on
|
||||||
@ -39,7 +44,7 @@ some other non-ACPI platform, the driver might work out of the box or needs
|
|||||||
some minor changes.
|
some minor changes.
|
||||||
|
|
||||||
Adding ACPI support for an existing driver should be pretty
|
Adding ACPI support for an existing driver should be pretty
|
||||||
straightforward. Here is the simplest example:
|
straightforward. Here is the simplest example::
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
static const struct acpi_device_id mydrv_acpi_match[] = {
|
static const struct acpi_device_id mydrv_acpi_match[] = {
|
||||||
@ -61,12 +66,13 @@ configuring GPIOs it can get its ACPI handle and extract this information
|
|||||||
from ACPI tables.
|
from ACPI tables.
|
||||||
|
|
||||||
DMA support
|
DMA support
|
||||||
~~~~~~~~~~~
|
===========
|
||||||
|
|
||||||
DMA controllers enumerated via ACPI should be registered in the system to
|
DMA controllers enumerated via ACPI should be registered in the system to
|
||||||
provide generic access to their resources. For example, a driver that would
|
provide generic access to their resources. For example, a driver that would
|
||||||
like to be accessible to slave devices via generic API call
|
like to be accessible to slave devices via generic API call
|
||||||
dma_request_slave_channel() must register itself at the end of the probe
|
dma_request_slave_channel() must register itself at the end of the probe
|
||||||
function like this:
|
function like this::
|
||||||
|
|
||||||
err = devm_acpi_dma_controller_register(dev, xlate_func, dw);
|
err = devm_acpi_dma_controller_register(dev, xlate_func, dw);
|
||||||
/* Handle the error if it's not a case of !CONFIG_ACPI */
|
/* Handle the error if it's not a case of !CONFIG_ACPI */
|
||||||
@ -74,7 +80,7 @@ function like this:
|
|||||||
and implement custom xlate function if needed (usually acpi_dma_simple_xlate()
|
and implement custom xlate function if needed (usually acpi_dma_simple_xlate()
|
||||||
is enough) which converts the FixedDMA resource provided by struct
|
is enough) which converts the FixedDMA resource provided by struct
|
||||||
acpi_dma_spec into the corresponding DMA channel. A piece of code for that case
|
acpi_dma_spec into the corresponding DMA channel. A piece of code for that case
|
||||||
could look like:
|
could look like::
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
struct filter_args {
|
struct filter_args {
|
||||||
@ -114,7 +120,7 @@ provided by struct acpi_dma.
|
|||||||
Clients must call dma_request_slave_channel() with the string parameter that
|
Clients must call dma_request_slave_channel() with the string parameter that
|
||||||
corresponds to a specific FixedDMA resource. By default "tx" means the first
|
corresponds to a specific FixedDMA resource. By default "tx" means the first
|
||||||
entry of the FixedDMA resource array, "rx" means the second entry. The table
|
entry of the FixedDMA resource array, "rx" means the second entry. The table
|
||||||
below shows a layout:
|
below shows a layout::
|
||||||
|
|
||||||
Device (I2C0)
|
Device (I2C0)
|
||||||
{
|
{
|
||||||
@ -138,12 +144,13 @@ acpi_dma_request_slave_chan_by_index() directly and therefore choose the
|
|||||||
specific FixedDMA resource by its index.
|
specific FixedDMA resource by its index.
|
||||||
|
|
||||||
SPI serial bus support
|
SPI serial bus support
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
======================
|
||||||
|
|
||||||
Slave devices behind SPI bus have SpiSerialBus resource attached to them.
|
Slave devices behind SPI bus have SpiSerialBus resource attached to them.
|
||||||
This is extracted automatically by the SPI core and the slave devices are
|
This is extracted automatically by the SPI core and the slave devices are
|
||||||
enumerated once spi_register_master() is called by the bus driver.
|
enumerated once spi_register_master() is called by the bus driver.
|
||||||
|
|
||||||
Here is what the ACPI namespace for a SPI slave might look like:
|
Here is what the ACPI namespace for a SPI slave might look like::
|
||||||
|
|
||||||
Device (EEP0)
|
Device (EEP0)
|
||||||
{
|
{
|
||||||
@ -163,7 +170,7 @@ Here is what the ACPI namespace for a SPI slave might look like:
|
|||||||
|
|
||||||
The SPI device drivers only need to add ACPI IDs in a similar way than with
|
The SPI device drivers only need to add ACPI IDs in a similar way than with
|
||||||
the platform device drivers. Below is an example where we add ACPI support
|
the platform device drivers. Below is an example where we add ACPI support
|
||||||
to at25 SPI eeprom driver (this is meant for the above ACPI snippet):
|
to at25 SPI eeprom driver (this is meant for the above ACPI snippet)::
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
static const struct acpi_device_id at25_acpi_match[] = {
|
static const struct acpi_device_id at25_acpi_match[] = {
|
||||||
@ -182,7 +189,7 @@ to at25 SPI eeprom driver (this is meant for the above ACPI snippet):
|
|||||||
|
|
||||||
Note that this driver actually needs more information like page size of the
|
Note that this driver actually needs more information like page size of the
|
||||||
eeprom etc. but at the time writing this there is no standard way of
|
eeprom etc. but at the time writing this there is no standard way of
|
||||||
passing those. One idea is to return this in _DSM method like:
|
passing those. One idea is to return this in _DSM method like::
|
||||||
|
|
||||||
Device (EEP0)
|
Device (EEP0)
|
||||||
{
|
{
|
||||||
@ -202,7 +209,7 @@ passing those. One idea is to return this in _DSM method like:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Then the at25 SPI driver can get this configuration by calling _DSM on its
|
Then the at25 SPI driver can get this configuration by calling _DSM on its
|
||||||
ACPI handle like:
|
ACPI handle like::
|
||||||
|
|
||||||
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
struct acpi_object_list input;
|
struct acpi_object_list input;
|
||||||
@ -220,14 +227,15 @@ ACPI handle like:
|
|||||||
kfree(output.pointer);
|
kfree(output.pointer);
|
||||||
|
|
||||||
I2C serial bus support
|
I2C serial bus support
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
======================
|
||||||
|
|
||||||
The slaves behind I2C bus controller only need to add the ACPI IDs like
|
The slaves behind I2C bus controller only need to add the ACPI IDs like
|
||||||
with the platform and SPI drivers. The I2C core automatically enumerates
|
with the platform and SPI drivers. The I2C core automatically enumerates
|
||||||
any slave devices behind the controller device once the adapter is
|
any slave devices behind the controller device once the adapter is
|
||||||
registered.
|
registered.
|
||||||
|
|
||||||
Below is an example of how to add ACPI support to the existing mpu3050
|
Below is an example of how to add ACPI support to the existing mpu3050
|
||||||
input driver:
|
input driver::
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
static const struct acpi_device_id mpu3050_acpi_match[] = {
|
static const struct acpi_device_id mpu3050_acpi_match[] = {
|
||||||
@ -251,56 +259,57 @@ input driver:
|
|||||||
};
|
};
|
||||||
|
|
||||||
GPIO support
|
GPIO support
|
||||||
~~~~~~~~~~~~
|
============
|
||||||
|
|
||||||
ACPI 5 introduced two new resources to describe GPIO connections: GpioIo
|
ACPI 5 introduced two new resources to describe GPIO connections: GpioIo
|
||||||
and GpioInt. These resources can be used to pass GPIO numbers used by
|
and GpioInt. These resources can be used to pass GPIO numbers used by
|
||||||
the device to the driver. ACPI 5.1 extended this with _DSD (Device
|
the device to the driver. ACPI 5.1 extended this with _DSD (Device
|
||||||
Specific Data) which made it possible to name the GPIOs among other things.
|
Specific Data) which made it possible to name the GPIOs among other things.
|
||||||
|
|
||||||
For example:
|
For example::
|
||||||
|
|
||||||
Device (DEV)
|
Device (DEV)
|
||||||
{
|
|
||||||
Method (_CRS, 0, NotSerialized)
|
|
||||||
{
|
{
|
||||||
Name (SBUF, ResourceTemplate()
|
Method (_CRS, 0, NotSerialized)
|
||||||
{
|
{
|
||||||
...
|
Name (SBUF, ResourceTemplate()
|
||||||
// Used to power on/off the device
|
|
||||||
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000,
|
|
||||||
IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
|
|
||||||
0x00, ResourceConsumer,,)
|
|
||||||
{
|
{
|
||||||
// Pin List
|
...
|
||||||
0x0055
|
// Used to power on/off the device
|
||||||
|
GpioIo (Exclusive, PullDefault, 0x0000, 0x0000,
|
||||||
|
IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0",
|
||||||
|
0x00, ResourceConsumer,,)
|
||||||
|
{
|
||||||
|
// Pin List
|
||||||
|
0x0055
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interrupt for the device
|
||||||
|
GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone,
|
||||||
|
0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,)
|
||||||
|
{
|
||||||
|
// Pin list
|
||||||
|
0x0058
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt for the device
|
Return (SBUF)
|
||||||
GpioInt (Edge, ActiveHigh, ExclusiveAndWake, PullNone,
|
|
||||||
0x0000, "\\_SB.PCI0.GPI0", 0x00, ResourceConsumer,,)
|
|
||||||
{
|
|
||||||
// Pin list
|
|
||||||
0x0058
|
|
||||||
}
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Return (SBUF)
|
// ACPI 5.1 _DSD used for naming the GPIOs
|
||||||
}
|
Name (_DSD, Package ()
|
||||||
|
|
||||||
// ACPI 5.1 _DSD used for naming the GPIOs
|
|
||||||
Name (_DSD, Package ()
|
|
||||||
{
|
|
||||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
|
||||||
Package ()
|
|
||||||
{
|
{
|
||||||
Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }},
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||||
Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }},
|
Package ()
|
||||||
}
|
{
|
||||||
})
|
Package () {"power-gpios", Package() {^DEV, 0, 0, 0 }},
|
||||||
...
|
Package () {"irq-gpios", Package() {^DEV, 1, 0, 0 }},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
...
|
||||||
|
|
||||||
These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
|
These GPIO numbers are controller relative and path "\\_SB.PCI0.GPI0"
|
||||||
specifies the path to the controller. In order to use these GPIOs in Linux
|
specifies the path to the controller. In order to use these GPIOs in Linux
|
||||||
@ -310,7 +319,7 @@ There is a standard GPIO API for that and is documented in
|
|||||||
Documentation/gpio/.
|
Documentation/gpio/.
|
||||||
|
|
||||||
In the above example we can get the corresponding two GPIO descriptors with
|
In the above example we can get the corresponding two GPIO descriptors with
|
||||||
a code like this:
|
a code like this::
|
||||||
|
|
||||||
#include <linux/gpio/consumer.h>
|
#include <linux/gpio/consumer.h>
|
||||||
...
|
...
|
||||||
@ -334,21 +343,22 @@ See Documentation/acpi/gpio-properties.txt for more information about the
|
|||||||
_DSD binding related to GPIOs.
|
_DSD binding related to GPIOs.
|
||||||
|
|
||||||
MFD devices
|
MFD devices
|
||||||
~~~~~~~~~~~
|
===========
|
||||||
|
|
||||||
The MFD devices register their children as platform devices. For the child
|
The MFD devices register their children as platform devices. For the child
|
||||||
devices there needs to be an ACPI handle that they can use to reference
|
devices there needs to be an ACPI handle that they can use to reference
|
||||||
parts of the ACPI namespace that relate to them. In the Linux MFD subsystem
|
parts of the ACPI namespace that relate to them. In the Linux MFD subsystem
|
||||||
we provide two ways:
|
we provide two ways:
|
||||||
|
|
||||||
o The children share the parent ACPI handle.
|
- The children share the parent ACPI handle.
|
||||||
o The MFD cell can specify the ACPI id of the device.
|
- The MFD cell can specify the ACPI id of the device.
|
||||||
|
|
||||||
For the first case, the MFD drivers do not need to do anything. The
|
For the first case, the MFD drivers do not need to do anything. The
|
||||||
resulting child platform device will have its ACPI_COMPANION() set to point
|
resulting child platform device will have its ACPI_COMPANION() set to point
|
||||||
to the parent device.
|
to the parent device.
|
||||||
|
|
||||||
If the ACPI namespace has a device that we can match using an ACPI id or ACPI
|
If the ACPI namespace has a device that we can match using an ACPI id or ACPI
|
||||||
adr, the cell should be set like:
|
adr, the cell should be set like::
|
||||||
|
|
||||||
static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = {
|
static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = {
|
||||||
.pnpid = "XYZ0001",
|
.pnpid = "XYZ0001",
|
||||||
@ -366,7 +376,8 @@ the MFD device and if found, that ACPI companion device is bound to the
|
|||||||
resulting child platform device.
|
resulting child platform device.
|
||||||
|
|
||||||
Device Tree namespace link device ID
|
Device Tree namespace link device ID
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
====================================
|
||||||
|
|
||||||
The Device Tree protocol uses device identification based on the "compatible"
|
The Device Tree protocol uses device identification based on the "compatible"
|
||||||
property whose value is a string or an array of strings recognized as device
|
property whose value is a string or an array of strings recognized as device
|
||||||
identifiers by drivers and the driver core. The set of all those strings may be
|
identifiers by drivers and the driver core. The set of all those strings may be
|
||||||
@ -410,6 +421,32 @@ Specifically, the device IDs returned by _HID and preceding PRP0001 in the _CID
|
|||||||
return package will be checked first. Also in that case the bus type the device
|
return package will be checked first. Also in that case the bus type the device
|
||||||
will be enumerated to depends on the device ID returned by _HID.
|
will be enumerated to depends on the device ID returned by _HID.
|
||||||
|
|
||||||
|
For example, the following ACPI sample might be used to enumerate an lm75-type
|
||||||
|
I2C temperature sensor and match it to the driver using the Device Tree
|
||||||
|
namespace link:
|
||||||
|
|
||||||
|
Device (TMP0)
|
||||||
|
{
|
||||||
|
Name (_HID, "PRP0001")
|
||||||
|
Name (_DSD, Package() {
|
||||||
|
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||||
|
Package () {
|
||||||
|
Package (2) { "compatible", "ti,tmp75" },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Method (_CRS, 0, Serialized)
|
||||||
|
{
|
||||||
|
Name (SBUF, ResourceTemplate ()
|
||||||
|
{
|
||||||
|
I2cSerialBusV2 (0x48, ControllerInitiated,
|
||||||
|
400000, AddressingMode7Bit,
|
||||||
|
"\\_SB.PCI0.I2C1", 0x00,
|
||||||
|
ResourceConsumer, , Exclusive,)
|
||||||
|
})
|
||||||
|
Return (SBUF)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
It is valid to define device objects with a _HID returning PRP0001 and without
|
It is valid to define device objects with a _HID returning PRP0001 and without
|
||||||
the "compatible" property in the _DSD or a _CID as long as one of their
|
the "compatible" property in the _DSD or a _CID as long as one of their
|
||||||
ancestors provides a _DSD with a valid "compatible" property. Such device
|
ancestors provides a _DSD with a valid "compatible" property. Such device
|
||||||
@ -423,4 +460,4 @@ the _DSD of the device object itself or the _DSD of its ancestor in the
|
|||||||
Otherwise, the _DSD itself is regarded as invalid and therefore the "compatible"
|
Otherwise, the _DSD itself is regarded as invalid and therefore the "compatible"
|
||||||
property returned by it is meaningless.
|
property returned by it is meaningless.
|
||||||
|
|
||||||
Refer to DSD-properties-rules.txt for more information.
|
Refer to :doc:`DSD-properties-rules` for more information.
|
@ -1,5 +1,8 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
======================================
|
||||||
_DSD Device Properties Related to GPIO
|
_DSD Device Properties Related to GPIO
|
||||||
--------------------------------------
|
======================================
|
||||||
|
|
||||||
With the release of ACPI 5.1, the _DSD configuration object finally
|
With the release of ACPI 5.1, the _DSD configuration object finally
|
||||||
allows names to be given to GPIOs (and other things as well) returned
|
allows names to be given to GPIOs (and other things as well) returned
|
||||||
@ -8,7 +11,7 @@ the corresponding GPIO, which is pretty error prone (it depends on
|
|||||||
the _CRS output ordering, for example).
|
the _CRS output ordering, for example).
|
||||||
|
|
||||||
With _DSD we can now query GPIOs using a name instead of an integer
|
With _DSD we can now query GPIOs using a name instead of an integer
|
||||||
index, like the ASL example below shows:
|
index, like the ASL example below shows::
|
||||||
|
|
||||||
// Bluetooth device with reset and shutdown GPIOs
|
// Bluetooth device with reset and shutdown GPIOs
|
||||||
Device (BTH)
|
Device (BTH)
|
||||||
@ -34,15 +37,19 @@ index, like the ASL example below shows:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
The format of the supported GPIO property is:
|
The format of the supported GPIO property is::
|
||||||
|
|
||||||
Package () { "name", Package () { ref, index, pin, active_low }}
|
Package () { "name", Package () { ref, index, pin, active_low }}
|
||||||
|
|
||||||
ref - The device that has _CRS containing GpioIo()/GpioInt() resources,
|
ref
|
||||||
typically this is the device itself (BTH in our case).
|
The device that has _CRS containing GpioIo()/GpioInt() resources,
|
||||||
index - Index of the GpioIo()/GpioInt() resource in _CRS starting from zero.
|
typically this is the device itself (BTH in our case).
|
||||||
pin - Pin in the GpioIo()/GpioInt() resource. Typically this is zero.
|
index
|
||||||
active_low - If 1 the GPIO is marked as active_low.
|
Index of the GpioIo()/GpioInt() resource in _CRS starting from zero.
|
||||||
|
pin
|
||||||
|
Pin in the GpioIo()/GpioInt() resource. Typically this is zero.
|
||||||
|
active_low
|
||||||
|
If 1 the GPIO is marked as active_low.
|
||||||
|
|
||||||
Since ACPI GpioIo() resource does not have a field saying whether it is
|
Since ACPI GpioIo() resource does not have a field saying whether it is
|
||||||
active low or high, the "active_low" argument can be used here. Setting
|
active low or high, the "active_low" argument can be used here. Setting
|
||||||
@ -55,7 +62,7 @@ It is possible to leave holes in the array of GPIOs. This is useful in
|
|||||||
cases like with SPI host controllers where some chip selects may be
|
cases like with SPI host controllers where some chip selects may be
|
||||||
implemented as GPIOs and some as native signals. For example a SPI host
|
implemented as GPIOs and some as native signals. For example a SPI host
|
||||||
controller can have chip selects 0 and 2 implemented as GPIOs and 1 as
|
controller can have chip selects 0 and 2 implemented as GPIOs and 1 as
|
||||||
native:
|
native::
|
||||||
|
|
||||||
Package () {
|
Package () {
|
||||||
"cs-gpios",
|
"cs-gpios",
|
||||||
@ -67,7 +74,7 @@ native:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Other supported properties
|
Other supported properties
|
||||||
--------------------------
|
==========================
|
||||||
|
|
||||||
Following Device Tree compatible device properties are also supported by
|
Following Device Tree compatible device properties are also supported by
|
||||||
_DSD device properties for GPIO controllers:
|
_DSD device properties for GPIO controllers:
|
||||||
@ -78,7 +85,7 @@ _DSD device properties for GPIO controllers:
|
|||||||
- input
|
- input
|
||||||
- line-name
|
- line-name
|
||||||
|
|
||||||
Example:
|
Example::
|
||||||
|
|
||||||
Name (_DSD, Package () {
|
Name (_DSD, Package () {
|
||||||
// _DSD Hierarchical Properties Extension UUID
|
// _DSD Hierarchical Properties Extension UUID
|
||||||
@ -100,7 +107,7 @@ Example:
|
|||||||
|
|
||||||
- gpio-line-names
|
- gpio-line-names
|
||||||
|
|
||||||
Example:
|
Example::
|
||||||
|
|
||||||
Package () {
|
Package () {
|
||||||
"gpio-line-names",
|
"gpio-line-names",
|
||||||
@ -114,7 +121,7 @@ See Documentation/devicetree/bindings/gpio/gpio.txt for more information
|
|||||||
about these properties.
|
about these properties.
|
||||||
|
|
||||||
ACPI GPIO Mappings Provided by Drivers
|
ACPI GPIO Mappings Provided by Drivers
|
||||||
--------------------------------------
|
======================================
|
||||||
|
|
||||||
There are systems in which the ACPI tables do not contain _DSD but provide _CRS
|
There are systems in which the ACPI tables do not contain _DSD but provide _CRS
|
||||||
with GpioIo()/GpioInt() resources and device drivers still need to work with
|
with GpioIo()/GpioInt() resources and device drivers still need to work with
|
||||||
@ -139,16 +146,16 @@ line in that resource starting from zero, and the active-low flag for that line,
|
|||||||
respectively, in analogy with the _DSD GPIO property format specified above.
|
respectively, in analogy with the _DSD GPIO property format specified above.
|
||||||
|
|
||||||
For the example Bluetooth device discussed previously the data structures in
|
For the example Bluetooth device discussed previously the data structures in
|
||||||
question would look like this:
|
question would look like this::
|
||||||
|
|
||||||
static const struct acpi_gpio_params reset_gpio = { 1, 1, false };
|
static const struct acpi_gpio_params reset_gpio = { 1, 1, false };
|
||||||
static const struct acpi_gpio_params shutdown_gpio = { 0, 0, false };
|
static const struct acpi_gpio_params shutdown_gpio = { 0, 0, false };
|
||||||
|
|
||||||
static const struct acpi_gpio_mapping bluetooth_acpi_gpios[] = {
|
static const struct acpi_gpio_mapping bluetooth_acpi_gpios[] = {
|
||||||
{ "reset-gpios", &reset_gpio, 1 },
|
{ "reset-gpios", &reset_gpio, 1 },
|
||||||
{ "shutdown-gpios", &shutdown_gpio, 1 },
|
{ "shutdown-gpios", &shutdown_gpio, 1 },
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
Next, the mapping table needs to be passed as the second argument to
|
Next, the mapping table needs to be passed as the second argument to
|
||||||
acpi_dev_add_driver_gpios() that will register it with the ACPI device object
|
acpi_dev_add_driver_gpios() that will register it with the ACPI device object
|
||||||
@ -158,12 +165,12 @@ calling acpi_dev_remove_driver_gpios() on the ACPI device object where that
|
|||||||
table was previously registered.
|
table was previously registered.
|
||||||
|
|
||||||
Using the _CRS fallback
|
Using the _CRS fallback
|
||||||
-----------------------
|
=======================
|
||||||
|
|
||||||
If a device does not have _DSD or the driver does not create ACPI GPIO
|
If a device does not have _DSD or the driver does not create ACPI GPIO
|
||||||
mapping, the Linux GPIO framework refuses to return any GPIOs. This is
|
mapping, the Linux GPIO framework refuses to return any GPIOs. This is
|
||||||
because the driver does not know what it actually gets. For example if we
|
because the driver does not know what it actually gets. For example if we
|
||||||
have a device like below:
|
have a device like below::
|
||||||
|
|
||||||
Device (BTH)
|
Device (BTH)
|
||||||
{
|
{
|
||||||
@ -177,7 +184,7 @@ have a device like below:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
The driver might expect to get the right GPIO when it does:
|
The driver might expect to get the right GPIO when it does::
|
||||||
|
|
||||||
desc = gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
desc = gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||||
|
|
||||||
@ -193,22 +200,25 @@ the ACPI GPIO mapping tables are hardly linked to ACPI ID and certain
|
|||||||
objects, as listed in the above chapter, of the device in question.
|
objects, as listed in the above chapter, of the device in question.
|
||||||
|
|
||||||
Getting GPIO descriptor
|
Getting GPIO descriptor
|
||||||
-----------------------
|
=======================
|
||||||
|
|
||||||
There are two main approaches to get GPIO resource from ACPI:
|
There are two main approaches to get GPIO resource from ACPI::
|
||||||
desc = gpiod_get(dev, connection_id, flags);
|
|
||||||
desc = gpiod_get_index(dev, connection_id, index, flags);
|
desc = gpiod_get(dev, connection_id, flags);
|
||||||
|
desc = gpiod_get_index(dev, connection_id, index, flags);
|
||||||
|
|
||||||
We may consider two different cases here, i.e. when connection ID is
|
We may consider two different cases here, i.e. when connection ID is
|
||||||
provided and otherwise.
|
provided and otherwise.
|
||||||
|
|
||||||
Case 1:
|
Case 1::
|
||||||
desc = gpiod_get(dev, "non-null-connection-id", flags);
|
|
||||||
desc = gpiod_get_index(dev, "non-null-connection-id", index, flags);
|
|
||||||
|
|
||||||
Case 2:
|
desc = gpiod_get(dev, "non-null-connection-id", flags);
|
||||||
desc = gpiod_get(dev, NULL, flags);
|
desc = gpiod_get_index(dev, "non-null-connection-id", index, flags);
|
||||||
desc = gpiod_get_index(dev, NULL, index, flags);
|
|
||||||
|
Case 2::
|
||||||
|
|
||||||
|
desc = gpiod_get(dev, NULL, flags);
|
||||||
|
desc = gpiod_get_index(dev, NULL, index, flags);
|
||||||
|
|
||||||
Case 1 assumes that corresponding ACPI device description must have
|
Case 1 assumes that corresponding ACPI device description must have
|
||||||
defined device properties and will prevent to getting any GPIO resources
|
defined device properties and will prevent to getting any GPIO resources
|
61
Documentation/firmware-guide/acpi/i2c-muxes.rst
Normal file
61
Documentation/firmware-guide/acpi/i2c-muxes.rst
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
==============
|
||||||
|
ACPI I2C Muxes
|
||||||
|
==============
|
||||||
|
|
||||||
|
Describing an I2C device hierarchy that includes I2C muxes requires an ACPI
|
||||||
|
Device () scope per mux channel.
|
||||||
|
|
||||||
|
Consider this topology::
|
||||||
|
|
||||||
|
+------+ +------+
|
||||||
|
| SMB1 |-->| MUX0 |--CH00--> i2c client A (0x50)
|
||||||
|
| | | 0x70 |--CH01--> i2c client B (0x50)
|
||||||
|
+------+ +------+
|
||||||
|
|
||||||
|
which corresponds to the following ASL::
|
||||||
|
|
||||||
|
Device (SMB1)
|
||||||
|
{
|
||||||
|
Name (_HID, ...)
|
||||||
|
Device (MUX0)
|
||||||
|
{
|
||||||
|
Name (_HID, ...)
|
||||||
|
Name (_CRS, ResourceTemplate () {
|
||||||
|
I2cSerialBus (0x70, ControllerInitiated, I2C_SPEED,
|
||||||
|
AddressingMode7Bit, "^SMB1", 0x00,
|
||||||
|
ResourceConsumer,,)
|
||||||
|
}
|
||||||
|
|
||||||
|
Device (CH00)
|
||||||
|
{
|
||||||
|
Name (_ADR, 0)
|
||||||
|
|
||||||
|
Device (CLIA)
|
||||||
|
{
|
||||||
|
Name (_HID, ...)
|
||||||
|
Name (_CRS, ResourceTemplate () {
|
||||||
|
I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED,
|
||||||
|
AddressingMode7Bit, "^CH00", 0x00,
|
||||||
|
ResourceConsumer,,)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Device (CH01)
|
||||||
|
{
|
||||||
|
Name (_ADR, 1)
|
||||||
|
|
||||||
|
Device (CLIB)
|
||||||
|
{
|
||||||
|
Name (_HID, ...)
|
||||||
|
Name (_CRS, ResourceTemplate () {
|
||||||
|
I2cSerialBus (0x50, ControllerInitiated, I2C_SPEED,
|
||||||
|
AddressingMode7Bit, "^CH01", 0x00,
|
||||||
|
ResourceConsumer,,)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
Documentation/firmware-guide/acpi/index.rst
Normal file
26
Documentation/firmware-guide/acpi/index.rst
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
============
|
||||||
|
ACPI Support
|
||||||
|
============
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
namespace
|
||||||
|
dsd/graph
|
||||||
|
dsd/data-node-references
|
||||||
|
enumeration
|
||||||
|
osi
|
||||||
|
method-customizing
|
||||||
|
method-tracing
|
||||||
|
DSD-properties-rules
|
||||||
|
debug
|
||||||
|
aml-debugger
|
||||||
|
apei/output_format
|
||||||
|
apei/einj
|
||||||
|
gpio-properties
|
||||||
|
i2c-muxes
|
||||||
|
acpi-lid
|
||||||
|
lpit
|
||||||
|
video_extension
|
@ -1,3 +1,9 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
===========================
|
||||||
|
Low Power Idle Table (LPIT)
|
||||||
|
===========================
|
||||||
|
|
||||||
To enumerate platform Low Power Idle states, Intel platforms are using
|
To enumerate platform Low Power Idle states, Intel platforms are using
|
||||||
“Low Power Idle Table” (LPIT). More details about this table can be
|
“Low Power Idle Table” (LPIT). More details about this table can be
|
||||||
downloaded from:
|
downloaded from:
|
||||||
@ -8,13 +14,15 @@ Residencies for each low power state can be read via FFH
|
|||||||
|
|
||||||
On platforms supporting S0ix sleep states, there can be two types of
|
On platforms supporting S0ix sleep states, there can be two types of
|
||||||
residencies:
|
residencies:
|
||||||
- CPU PKG C10 (Read via FFH interface)
|
|
||||||
- Platform Controller Hub (PCH) SLP_S0 (Read via memory mapped interface)
|
- CPU PKG C10 (Read via FFH interface)
|
||||||
|
- Platform Controller Hub (PCH) SLP_S0 (Read via memory mapped interface)
|
||||||
|
|
||||||
The following attributes are added dynamically to the cpuidle
|
The following attributes are added dynamically to the cpuidle
|
||||||
sysfs attribute group:
|
sysfs attribute group::
|
||||||
/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
|
|
||||||
/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us
|
/sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
|
||||||
|
/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us
|
||||||
|
|
||||||
The "low_power_idle_cpu_residency_us" attribute shows time spent
|
The "low_power_idle_cpu_residency_us" attribute shows time spent
|
||||||
by the CPU package in PKG C10
|
by the CPU package in PKG C10
|
89
Documentation/firmware-guide/acpi/method-customizing.rst
Normal file
89
Documentation/firmware-guide/acpi/method-customizing.rst
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
=======================================
|
||||||
|
Linux ACPI Custom Control Method How To
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
:Author: Zhang Rui <rui.zhang@intel.com>
|
||||||
|
|
||||||
|
|
||||||
|
Linux supports customizing ACPI control methods at runtime.
|
||||||
|
|
||||||
|
Users can use this to:
|
||||||
|
|
||||||
|
1. override an existing method which may not work correctly,
|
||||||
|
or just for debugging purposes.
|
||||||
|
2. insert a completely new method in order to create a missing
|
||||||
|
method such as _OFF, _ON, _STA, _INI, etc.
|
||||||
|
|
||||||
|
For these cases, it is far simpler to dynamically install a single
|
||||||
|
control method rather than override the entire DSDT, because kernel
|
||||||
|
rebuild/reboot is not needed and test result can be got in minutes.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
- Only ACPI METHOD can be overridden, any other object types like
|
||||||
|
"Device", "OperationRegion", are not recognized. Methods
|
||||||
|
declared inside scope operators are also not supported.
|
||||||
|
|
||||||
|
- The same ACPI control method can be overridden for many times,
|
||||||
|
and it's always the latest one that used by Linux/kernel.
|
||||||
|
|
||||||
|
- To get the ACPI debug object output (Store (AAAA, Debug)),
|
||||||
|
please run::
|
||||||
|
|
||||||
|
echo 1 > /sys/module/acpi/parameters/aml_debug_output
|
||||||
|
|
||||||
|
|
||||||
|
1. override an existing method
|
||||||
|
==============================
|
||||||
|
a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT,
|
||||||
|
just run "cat /sys/firmware/acpi/tables/DSDT > /tmp/dsdt.dat"
|
||||||
|
b) disassemble the table by running "iasl -d dsdt.dat".
|
||||||
|
c) rewrite the ASL code of the method and save it in a new file,
|
||||||
|
d) package the new file (psr.asl) to an ACPI table format.
|
||||||
|
Here is an example of a customized \_SB._AC._PSR method::
|
||||||
|
|
||||||
|
DefinitionBlock ("", "SSDT", 1, "", "", 0x20080715)
|
||||||
|
{
|
||||||
|
Method (\_SB_.AC._PSR, 0, NotSerialized)
|
||||||
|
{
|
||||||
|
Store ("In AC _PSR", Debug)
|
||||||
|
Return (ACON)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Note that the full pathname of the method in ACPI namespace
|
||||||
|
should be used.
|
||||||
|
e) assemble the file to generate the AML code of the method.
|
||||||
|
e.g. "iasl -vw 6084 psr.asl" (psr.aml is generated as a result)
|
||||||
|
If parameter "-vw 6084" is not supported by your iASL compiler,
|
||||||
|
please try a newer version.
|
||||||
|
f) mount debugfs by "mount -t debugfs none /sys/kernel/debug"
|
||||||
|
g) override the old method via the debugfs by running
|
||||||
|
"cat /tmp/psr.aml > /sys/kernel/debug/acpi/custom_method"
|
||||||
|
|
||||||
|
2. insert a new method
|
||||||
|
======================
|
||||||
|
This is easier than overriding an existing method.
|
||||||
|
We just need to create the ASL code of the method we want to
|
||||||
|
insert and then follow the step c) ~ g) in section 1.
|
||||||
|
|
||||||
|
3. undo your changes
|
||||||
|
====================
|
||||||
|
The "undo" operation is not supported for a new inserted method
|
||||||
|
right now, i.e. we can not remove a method currently.
|
||||||
|
For an overridden method, in order to undo your changes, please
|
||||||
|
save a copy of the method original ASL code in step c) section 1,
|
||||||
|
and redo step c) ~ g) to override the method with the original one.
|
||||||
|
|
||||||
|
|
||||||
|
.. note:: We can use a kernel with multiple custom ACPI method running,
|
||||||
|
But each individual write to debugfs can implement a SINGLE
|
||||||
|
method override. i.e. if we want to insert/override multiple
|
||||||
|
ACPI methods, we need to redo step c) ~ g) for multiple times.
|
||||||
|
|
||||||
|
.. note:: Be aware that root can mis-use this driver to modify arbitrary
|
||||||
|
memory and gain additional rights, if root's privileges got
|
||||||
|
restricted (for example if root is not allowed to load additional
|
||||||
|
modules after boot).
|
238
Documentation/firmware-guide/acpi/method-tracing.rst
Normal file
238
Documentation/firmware-guide/acpi/method-tracing.rst
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
=====================
|
||||||
|
ACPICA Trace Facility
|
||||||
|
=====================
|
||||||
|
|
||||||
|
:Copyright: |copy| 2015, Intel Corporation
|
||||||
|
:Author: Lv Zheng <lv.zheng@intel.com>
|
||||||
|
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
========
|
||||||
|
This document describes the functions and the interfaces of the
|
||||||
|
method tracing facility.
|
||||||
|
|
||||||
|
Functionalities and usage examples
|
||||||
|
==================================
|
||||||
|
|
||||||
|
ACPICA provides method tracing capability. And two functions are
|
||||||
|
currently implemented using this capability.
|
||||||
|
|
||||||
|
Log reducer
|
||||||
|
-----------
|
||||||
|
|
||||||
|
ACPICA subsystem provides debugging outputs when CONFIG_ACPI_DEBUG is
|
||||||
|
enabled. The debugging messages which are deployed via
|
||||||
|
ACPI_DEBUG_PRINT() macro can be reduced at 2 levels - per-component
|
||||||
|
level (known as debug layer, configured via
|
||||||
|
/sys/module/acpi/parameters/debug_layer) and per-type level (known as
|
||||||
|
debug level, configured via /sys/module/acpi/parameters/debug_level).
|
||||||
|
|
||||||
|
But when the particular layer/level is applied to the control method
|
||||||
|
evaluations, the quantity of the debugging outputs may still be too
|
||||||
|
large to be put into the kernel log buffer. The idea thus is worked out
|
||||||
|
to only enable the particular debug layer/level (normally more detailed)
|
||||||
|
logs when the control method evaluation is started, and disable the
|
||||||
|
detailed logging when the control method evaluation is stopped.
|
||||||
|
|
||||||
|
The following command examples illustrate the usage of the "log reducer"
|
||||||
|
functionality:
|
||||||
|
|
||||||
|
a. Filter out the debug layer/level matched logs when control methods
|
||||||
|
are being evaluated::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0xXXXXXXXX" > trace_debug_layer
|
||||||
|
# echo "0xYYYYYYYY" > trace_debug_level
|
||||||
|
# echo "enable" > trace_state
|
||||||
|
|
||||||
|
b. Filter out the debug layer/level matched logs when the specified
|
||||||
|
control method is being evaluated::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0xXXXXXXXX" > trace_debug_layer
|
||||||
|
# echo "0xYYYYYYYY" > trace_debug_level
|
||||||
|
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
||||||
|
# echo "method" > /sys/module/acpi/parameters/trace_state
|
||||||
|
|
||||||
|
c. Filter out the debug layer/level matched logs when the specified
|
||||||
|
control method is being evaluated for the first time::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0xXXXXXXXX" > trace_debug_layer
|
||||||
|
# echo "0xYYYYYYYY" > trace_debug_level
|
||||||
|
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
||||||
|
# echo "method-once" > /sys/module/acpi/parameters/trace_state
|
||||||
|
|
||||||
|
Where:
|
||||||
|
0xXXXXXXXX/0xYYYYYYYY
|
||||||
|
Refer to Documentation/acpi/debug.txt for possible debug layer/level
|
||||||
|
masking values.
|
||||||
|
\PPPP.AAAA.TTTT.HHHH
|
||||||
|
Full path of a control method that can be found in the ACPI namespace.
|
||||||
|
It needn't be an entry of a control method evaluation.
|
||||||
|
|
||||||
|
AML tracer
|
||||||
|
----------
|
||||||
|
|
||||||
|
There are special log entries added by the method tracing facility at
|
||||||
|
the "trace points" the AML interpreter starts/stops to execute a control
|
||||||
|
method, or an AML opcode. Note that the format of the log entries are
|
||||||
|
subject to change::
|
||||||
|
|
||||||
|
[ 0.186427] exdebug-0398 ex_trace_point : Method Begin [0xf58394d8:\_SB.PCI0.LPCB.ECOK] execution.
|
||||||
|
[ 0.186630] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905c88:If] execution.
|
||||||
|
[ 0.186820] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905cc0:LEqual] execution.
|
||||||
|
[ 0.187010] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905a20:-NamePath-] execution.
|
||||||
|
[ 0.187214] exdebug-0398 ex_trace_point : Opcode End [0xf5905a20:-NamePath-] execution.
|
||||||
|
[ 0.187407] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905f60:One] execution.
|
||||||
|
[ 0.187594] exdebug-0398 ex_trace_point : Opcode End [0xf5905f60:One] execution.
|
||||||
|
[ 0.187789] exdebug-0398 ex_trace_point : Opcode End [0xf5905cc0:LEqual] execution.
|
||||||
|
[ 0.187980] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905cc0:Return] execution.
|
||||||
|
[ 0.188146] exdebug-0398 ex_trace_point : Opcode Begin [0xf5905f60:One] execution.
|
||||||
|
[ 0.188334] exdebug-0398 ex_trace_point : Opcode End [0xf5905f60:One] execution.
|
||||||
|
[ 0.188524] exdebug-0398 ex_trace_point : Opcode End [0xf5905cc0:Return] execution.
|
||||||
|
[ 0.188712] exdebug-0398 ex_trace_point : Opcode End [0xf5905c88:If] execution.
|
||||||
|
[ 0.188903] exdebug-0398 ex_trace_point : Method End [0xf58394d8:\_SB.PCI0.LPCB.ECOK] execution.
|
||||||
|
|
||||||
|
Developers can utilize these special log entries to track the AML
|
||||||
|
interpretion, thus can aid issue debugging and performance tuning. Note
|
||||||
|
that, as the "AML tracer" logs are implemented via ACPI_DEBUG_PRINT()
|
||||||
|
macro, CONFIG_ACPI_DEBUG is also required to be enabled for enabling
|
||||||
|
"AML tracer" logs.
|
||||||
|
|
||||||
|
The following command examples illustrate the usage of the "AML tracer"
|
||||||
|
functionality:
|
||||||
|
|
||||||
|
a. Filter out the method start/stop "AML tracer" logs when control
|
||||||
|
methods are being evaluated::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0x80" > trace_debug_layer
|
||||||
|
# echo "0x10" > trace_debug_level
|
||||||
|
# echo "enable" > trace_state
|
||||||
|
|
||||||
|
b. Filter out the method start/stop "AML tracer" when the specified
|
||||||
|
control method is being evaluated::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0x80" > trace_debug_layer
|
||||||
|
# echo "0x10" > trace_debug_level
|
||||||
|
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
||||||
|
# echo "method" > trace_state
|
||||||
|
|
||||||
|
c. Filter out the method start/stop "AML tracer" logs when the specified
|
||||||
|
control method is being evaluated for the first time::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0x80" > trace_debug_layer
|
||||||
|
# echo "0x10" > trace_debug_level
|
||||||
|
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
||||||
|
# echo "method-once" > trace_state
|
||||||
|
|
||||||
|
d. Filter out the method/opcode start/stop "AML tracer" when the
|
||||||
|
specified control method is being evaluated::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0x80" > trace_debug_layer
|
||||||
|
# echo "0x10" > trace_debug_level
|
||||||
|
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
||||||
|
# echo "opcode" > trace_state
|
||||||
|
|
||||||
|
e. Filter out the method/opcode start/stop "AML tracer" when the
|
||||||
|
specified control method is being evaluated for the first time::
|
||||||
|
|
||||||
|
# cd /sys/module/acpi/parameters
|
||||||
|
# echo "0x80" > trace_debug_layer
|
||||||
|
# echo "0x10" > trace_debug_level
|
||||||
|
# echo "\PPPP.AAAA.TTTT.HHHH" > trace_method_name
|
||||||
|
# echo "opcode-opcode" > trace_state
|
||||||
|
|
||||||
|
Note that all above method tracing facility related module parameters can
|
||||||
|
be used as the boot parameters, for example::
|
||||||
|
|
||||||
|
acpi.trace_debug_layer=0x80 acpi.trace_debug_level=0x10 \
|
||||||
|
acpi.trace_method_name=\_SB.LID0._LID acpi.trace_state=opcode-once
|
||||||
|
|
||||||
|
|
||||||
|
Interface descriptions
|
||||||
|
======================
|
||||||
|
|
||||||
|
All method tracing functions can be configured via ACPI module
|
||||||
|
parameters that are accessible at /sys/module/acpi/parameters/:
|
||||||
|
|
||||||
|
trace_method_name
|
||||||
|
The full path of the AML method that the user wants to trace.
|
||||||
|
|
||||||
|
Note that the full path shouldn't contain the trailing "_"s in its
|
||||||
|
name segments but may contain "\" to form an absolute path.
|
||||||
|
|
||||||
|
trace_debug_layer
|
||||||
|
The temporary debug_layer used when the tracing feature is enabled.
|
||||||
|
|
||||||
|
Using ACPI_EXECUTER (0x80) by default, which is the debug_layer
|
||||||
|
used to match all "AML tracer" logs.
|
||||||
|
|
||||||
|
trace_debug_level
|
||||||
|
The temporary debug_level used when the tracing feature is enabled.
|
||||||
|
|
||||||
|
Using ACPI_LV_TRACE_POINT (0x10) by default, which is the
|
||||||
|
debug_level used to match all "AML tracer" logs.
|
||||||
|
|
||||||
|
trace_state
|
||||||
|
The status of the tracing feature.
|
||||||
|
|
||||||
|
Users can enable/disable this debug tracing feature by executing
|
||||||
|
the following command::
|
||||||
|
|
||||||
|
# echo string > /sys/module/acpi/parameters/trace_state
|
||||||
|
|
||||||
|
Where "string" should be one of the following:
|
||||||
|
|
||||||
|
"disable"
|
||||||
|
Disable the method tracing feature.
|
||||||
|
|
||||||
|
"enable"
|
||||||
|
Enable the method tracing feature.
|
||||||
|
|
||||||
|
ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
|
||||||
|
during any method execution will be logged.
|
||||||
|
|
||||||
|
"method"
|
||||||
|
Enable the method tracing feature.
|
||||||
|
|
||||||
|
ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
|
||||||
|
during method execution of "trace_method_name" will be logged.
|
||||||
|
|
||||||
|
"method-once"
|
||||||
|
Enable the method tracing feature.
|
||||||
|
|
||||||
|
ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
|
||||||
|
during method execution of "trace_method_name" will be logged only once.
|
||||||
|
|
||||||
|
"opcode"
|
||||||
|
Enable the method tracing feature.
|
||||||
|
|
||||||
|
ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
|
||||||
|
during method/opcode execution of "trace_method_name" will be logged.
|
||||||
|
|
||||||
|
"opcode-once"
|
||||||
|
Enable the method tracing feature.
|
||||||
|
|
||||||
|
ACPICA debugging messages matching "trace_debug_layer/trace_debug_level"
|
||||||
|
during method/opcode execution of "trace_method_name" will be logged only
|
||||||
|
once.
|
||||||
|
|
||||||
|
Note that, the difference between the "enable" and other feature
|
||||||
|
enabling options are:
|
||||||
|
|
||||||
|
1. When "enable" is specified, since
|
||||||
|
"trace_debug_layer/trace_debug_level" shall apply to all control
|
||||||
|
method evaluations, after configuring "trace_state" to "enable",
|
||||||
|
"trace_method_name" will be reset to NULL.
|
||||||
|
2. When "method/opcode" is specified, if
|
||||||
|
"trace_method_name" is NULL when "trace_state" is configured to
|
||||||
|
these options, the "trace_debug_layer/trace_debug_level" will
|
||||||
|
apply to all control method evaluations.
|
@ -1,85 +1,90 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
.. include:: <isonum.txt>
|
||||||
|
|
||||||
|
===================================================
|
||||||
ACPI Device Tree - Representation of ACPI Namespace
|
ACPI Device Tree - Representation of ACPI Namespace
|
||||||
|
===================================================
|
||||||
|
|
||||||
Copyright (C) 2013, Intel Corporation
|
:Copyright: |copy| 2013, Intel Corporation
|
||||||
Author: Lv Zheng <lv.zheng@intel.com>
|
|
||||||
|
|
||||||
|
:Author: Lv Zheng <lv.zheng@intel.com>
|
||||||
|
|
||||||
Abstract:
|
:Credit: Thanks for the help from Zhang Rui <rui.zhang@intel.com> and
|
||||||
|
Rafael J.Wysocki <rafael.j.wysocki@intel.com>.
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
========
|
||||||
The Linux ACPI subsystem converts ACPI namespace objects into a Linux
|
The Linux ACPI subsystem converts ACPI namespace objects into a Linux
|
||||||
device tree under the /sys/devices/LNXSYSTEM:00 and updates it upon
|
device tree under the /sys/devices/LNXSYSTEM:00 and updates it upon
|
||||||
receiving ACPI hotplug notification events. For each device object in this
|
receiving ACPI hotplug notification events. For each device object
|
||||||
hierarchy there is a corresponding symbolic link in the
|
in this hierarchy there is a corresponding symbolic link in the
|
||||||
/sys/bus/acpi/devices.
|
/sys/bus/acpi/devices.
|
||||||
|
|
||||||
This document illustrates the structure of the ACPI device tree.
|
This document illustrates the structure of the ACPI device tree.
|
||||||
|
|
||||||
|
ACPI Definition Blocks
|
||||||
|
======================
|
||||||
|
|
||||||
Credit:
|
The ACPI firmware sets up RSDP (Root System Description Pointer) in the
|
||||||
|
system memory address space pointing to the XSDT (Extended System
|
||||||
|
Description Table). The XSDT always points to the FADT (Fixed ACPI
|
||||||
|
Description Table) using its first entry, the data within the FADT
|
||||||
|
includes various fixed-length entries that describe fixed ACPI features
|
||||||
|
of the hardware. The FADT contains a pointer to the DSDT
|
||||||
|
(Differentiated System Descripition Table). The XSDT also contains
|
||||||
|
entries pointing to possibly multiple SSDTs (Secondary System
|
||||||
|
Description Table).
|
||||||
|
|
||||||
Thanks for the help from Zhang Rui <rui.zhang@intel.com> and Rafael J.
|
The DSDT and SSDT data is organized in data structures called definition
|
||||||
Wysocki <rafael.j.wysocki@intel.com>.
|
blocks that contain definitions of various objects, including ACPI
|
||||||
|
control methods, encoded in AML (ACPI Machine Language). The data block
|
||||||
|
of the DSDT along with the contents of SSDTs represents a hierarchical
|
||||||
|
data structure called the ACPI namespace whose topology reflects the
|
||||||
|
structure of the underlying hardware platform.
|
||||||
|
|
||||||
|
The relationships between ACPI System Definition Tables described above
|
||||||
|
are illustrated in the following diagram::
|
||||||
|
|
||||||
|
+---------+ +-------+ +--------+ +------------------------+
|
||||||
|
| RSDP | +->| XSDT | +->| FADT | | +-------------------+ |
|
||||||
|
+---------+ | +-------+ | +--------+ +-|->| DSDT | |
|
||||||
|
| Pointer | | | Entry |-+ | ...... | | | +-------------------+ |
|
||||||
|
+---------+ | +-------+ | X_DSDT |--+ | | Definition Blocks | |
|
||||||
|
| Pointer |-+ | ..... | | ...... | | +-------------------+ |
|
||||||
|
+---------+ +-------+ +--------+ | +-------------------+ |
|
||||||
|
| Entry |------------------|->| SSDT | |
|
||||||
|
+- - - -+ | +-------------------| |
|
||||||
|
| Entry | - - - - - - - -+ | | Definition Blocks | |
|
||||||
|
+- - - -+ | | +-------------------+ |
|
||||||
|
| | +- - - - - - - - - -+ |
|
||||||
|
+-|->| SSDT | |
|
||||||
|
| +-------------------+ |
|
||||||
|
| | Definition Blocks | |
|
||||||
|
| +- - - - - - - - - -+ |
|
||||||
|
+------------------------+
|
||||||
|
|
|
||||||
|
OSPM Loading |
|
||||||
|
\|/
|
||||||
|
+----------------+
|
||||||
|
| ACPI Namespace |
|
||||||
|
+----------------+
|
||||||
|
|
||||||
|
Figure 1. ACPI Definition Blocks
|
||||||
|
|
||||||
|
.. note:: RSDP can also contain a pointer to the RSDT (Root System
|
||||||
|
Description Table). Platforms provide RSDT to enable
|
||||||
|
compatibility with ACPI 1.0 operating systems. The OS is expected
|
||||||
|
to use XSDT, if present.
|
||||||
|
|
||||||
|
|
||||||
1. ACPI Definition Blocks
|
Example ACPI Namespace
|
||||||
|
======================
|
||||||
|
|
||||||
The ACPI firmware sets up RSDP (Root System Description Pointer) in the
|
All definition blocks are loaded into a single namespace. The namespace
|
||||||
system memory address space pointing to the XSDT (Extended System
|
is a hierarchy of objects identified by names and paths.
|
||||||
Description Table). The XSDT always points to the FADT (Fixed ACPI
|
The following naming conventions apply to object names in the ACPI
|
||||||
Description Table) using its first entry, the data within the FADT
|
namespace:
|
||||||
includes various fixed-length entries that describe fixed ACPI features
|
|
||||||
of the hardware. The FADT contains a pointer to the DSDT
|
|
||||||
(Differentiated System Descripition Table). The XSDT also contains
|
|
||||||
entries pointing to possibly multiple SSDTs (Secondary System
|
|
||||||
Description Table).
|
|
||||||
|
|
||||||
The DSDT and SSDT data is organized in data structures called definition
|
|
||||||
blocks that contain definitions of various objects, including ACPI
|
|
||||||
control methods, encoded in AML (ACPI Machine Language). The data block
|
|
||||||
of the DSDT along with the contents of SSDTs represents a hierarchical
|
|
||||||
data structure called the ACPI namespace whose topology reflects the
|
|
||||||
structure of the underlying hardware platform.
|
|
||||||
|
|
||||||
The relationships between ACPI System Definition Tables described above
|
|
||||||
are illustrated in the following diagram.
|
|
||||||
|
|
||||||
+---------+ +-------+ +--------+ +------------------------+
|
|
||||||
| RSDP | +->| XSDT | +->| FADT | | +-------------------+ |
|
|
||||||
+---------+ | +-------+ | +--------+ +-|->| DSDT | |
|
|
||||||
| Pointer | | | Entry |-+ | ...... | | | +-------------------+ |
|
|
||||||
+---------+ | +-------+ | X_DSDT |--+ | | Definition Blocks | |
|
|
||||||
| Pointer |-+ | ..... | | ...... | | +-------------------+ |
|
|
||||||
+---------+ +-------+ +--------+ | +-------------------+ |
|
|
||||||
| Entry |------------------|->| SSDT | |
|
|
||||||
+- - - -+ | +-------------------| |
|
|
||||||
| Entry | - - - - - - - -+ | | Definition Blocks | |
|
|
||||||
+- - - -+ | | +-------------------+ |
|
|
||||||
| | +- - - - - - - - - -+ |
|
|
||||||
+-|->| SSDT | |
|
|
||||||
| +-------------------+ |
|
|
||||||
| | Definition Blocks | |
|
|
||||||
| +- - - - - - - - - -+ |
|
|
||||||
+------------------------+
|
|
||||||
|
|
|
||||||
OSPM Loading |
|
|
||||||
\|/
|
|
||||||
+----------------+
|
|
||||||
| ACPI Namespace |
|
|
||||||
+----------------+
|
|
||||||
|
|
||||||
Figure 1. ACPI Definition Blocks
|
|
||||||
|
|
||||||
NOTE: RSDP can also contain a pointer to the RSDT (Root System
|
|
||||||
Description Table). Platforms provide RSDT to enable
|
|
||||||
compatibility with ACPI 1.0 operating systems. The OS is expected
|
|
||||||
to use XSDT, if present.
|
|
||||||
|
|
||||||
|
|
||||||
2. Example ACPI Namespace
|
|
||||||
|
|
||||||
All definition blocks are loaded into a single namespace. The namespace
|
|
||||||
is a hierarchy of objects identified by names and paths.
|
|
||||||
The following naming conventions apply to object names in the ACPI
|
|
||||||
namespace:
|
|
||||||
1. All names are 32 bits long.
|
1. All names are 32 bits long.
|
||||||
2. The first byte of a name must be one of 'A' - 'Z', '_'.
|
2. The first byte of a name must be one of 'A' - 'Z', '_'.
|
||||||
3. Each of the remaining bytes of a name must be one of 'A' - 'Z', '0'
|
3. Each of the remaining bytes of a name must be one of 'A' - 'Z', '0'
|
||||||
@ -91,7 +96,7 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
|||||||
(i.e. names prepended with '^' are relative to the parent of the
|
(i.e. names prepended with '^' are relative to the parent of the
|
||||||
current namespace node).
|
current namespace node).
|
||||||
|
|
||||||
The figure below shows an example ACPI namespace.
|
The figure below shows an example ACPI namespace::
|
||||||
|
|
||||||
+------+
|
+------+
|
||||||
| \ | Root
|
| \ | Root
|
||||||
@ -184,19 +189,20 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
|||||||
Figure 2. Example ACPI Namespace
|
Figure 2. Example ACPI Namespace
|
||||||
|
|
||||||
|
|
||||||
3. Linux ACPI Device Objects
|
Linux ACPI Device Objects
|
||||||
|
=========================
|
||||||
|
|
||||||
The Linux kernel's core ACPI subsystem creates struct acpi_device
|
The Linux kernel's core ACPI subsystem creates struct acpi_device
|
||||||
objects for ACPI namespace objects representing devices, power resources
|
objects for ACPI namespace objects representing devices, power resources
|
||||||
processors, thermal zones. Those objects are exported to user space via
|
processors, thermal zones. Those objects are exported to user space via
|
||||||
sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00. The
|
sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00. The
|
||||||
format of their names is <bus_id:instance>, where 'bus_id' refers to the
|
format of their names is <bus_id:instance>, where 'bus_id' refers to the
|
||||||
ACPI namespace representation of the given object and 'instance' is used
|
ACPI namespace representation of the given object and 'instance' is used
|
||||||
for distinguishing different object of the same 'bus_id' (it is
|
for distinguishing different object of the same 'bus_id' (it is
|
||||||
two-digit decimal representation of an unsigned integer).
|
two-digit decimal representation of an unsigned integer).
|
||||||
|
|
||||||
The value of 'bus_id' depends on the type of the object whose name it is
|
The value of 'bus_id' depends on the type of the object whose name it is
|
||||||
part of as listed in the table below.
|
part of as listed in the table below::
|
||||||
|
|
||||||
+---+-----------------+-------+----------+
|
+---+-----------------+-------+----------+
|
||||||
| | Object/Feature | Table | bus_id |
|
| | Object/Feature | Table | bus_id |
|
||||||
@ -226,10 +232,11 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
|||||||
|
|
||||||
Table 1. ACPI Namespace Objects Mapping
|
Table 1. ACPI Namespace Objects Mapping
|
||||||
|
|
||||||
The following rules apply when creating struct acpi_device objects on
|
The following rules apply when creating struct acpi_device objects on
|
||||||
the basis of the contents of ACPI System Description Tables (as
|
the basis of the contents of ACPI System Description Tables (as
|
||||||
indicated by the letter in the first column and the notation in the
|
indicated by the letter in the first column and the notation in the
|
||||||
second column of the table above):
|
second column of the table above):
|
||||||
|
|
||||||
N:
|
N:
|
||||||
The object's source is an ACPI namespace node (as indicated by the
|
The object's source is an ACPI namespace node (as indicated by the
|
||||||
named object's type in the second column). In that case the object's
|
named object's type in the second column). In that case the object's
|
||||||
@ -249,13 +256,14 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
|||||||
struct acpi_device object with LNXVIDEO 'bus_id' will be created for
|
struct acpi_device object with LNXVIDEO 'bus_id' will be created for
|
||||||
it.
|
it.
|
||||||
|
|
||||||
The third column of the above table indicates which ACPI System
|
The third column of the above table indicates which ACPI System
|
||||||
Description Tables contain information used for the creation of the
|
Description Tables contain information used for the creation of the
|
||||||
struct acpi_device objects represented by the given row (xSDT means DSDT
|
struct acpi_device objects represented by the given row (xSDT means DSDT
|
||||||
or SSDT).
|
or SSDT).
|
||||||
|
|
||||||
|
The forth column of the above table indicates the 'bus_id' generation
|
||||||
|
rule of the struct acpi_device object:
|
||||||
|
|
||||||
The forth column of the above table indicates the 'bus_id' generation
|
|
||||||
rule of the struct acpi_device object:
|
|
||||||
_HID:
|
_HID:
|
||||||
_HID in the last column of the table means that the object's bus_id
|
_HID in the last column of the table means that the object's bus_id
|
||||||
is derived from the _HID/_CID identification objects present under
|
is derived from the _HID/_CID identification objects present under
|
||||||
@ -275,45 +283,47 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
|||||||
object's bus_id.
|
object's bus_id.
|
||||||
|
|
||||||
|
|
||||||
4. Linux ACPI Physical Device Glue
|
Linux ACPI Physical Device Glue
|
||||||
|
===============================
|
||||||
|
|
||||||
ACPI device (i.e. struct acpi_device) objects may be linked to other
|
ACPI device (i.e. struct acpi_device) objects may be linked to other
|
||||||
objects in the Linux' device hierarchy that represent "physical" devices
|
objects in the Linux' device hierarchy that represent "physical" devices
|
||||||
(for example, devices on the PCI bus). If that happens, it means that
|
(for example, devices on the PCI bus). If that happens, it means that
|
||||||
the ACPI device object is a "companion" of a device otherwise
|
the ACPI device object is a "companion" of a device otherwise
|
||||||
represented in a different way and is used (1) to provide configuration
|
represented in a different way and is used (1) to provide configuration
|
||||||
information on that device which cannot be obtained by other means and
|
information on that device which cannot be obtained by other means and
|
||||||
(2) to do specific things to the device with the help of its ACPI
|
(2) to do specific things to the device with the help of its ACPI
|
||||||
control methods. One ACPI device object may be linked this way to
|
control methods. One ACPI device object may be linked this way to
|
||||||
multiple "physical" devices.
|
multiple "physical" devices.
|
||||||
|
|
||||||
If an ACPI device object is linked to a "physical" device, its sysfs
|
If an ACPI device object is linked to a "physical" device, its sysfs
|
||||||
directory contains the "physical_node" symbolic link to the sysfs
|
directory contains the "physical_node" symbolic link to the sysfs
|
||||||
directory of the target device object. In turn, the target device's
|
directory of the target device object. In turn, the target device's
|
||||||
sysfs directory will then contain the "firmware_node" symbolic link to
|
sysfs directory will then contain the "firmware_node" symbolic link to
|
||||||
the sysfs directory of the companion ACPI device object.
|
the sysfs directory of the companion ACPI device object.
|
||||||
The linking mechanism relies on device identification provided by the
|
The linking mechanism relies on device identification provided by the
|
||||||
ACPI namespace. For example, if there's an ACPI namespace object
|
ACPI namespace. For example, if there's an ACPI namespace object
|
||||||
representing a PCI device (i.e. a device object under an ACPI namespace
|
representing a PCI device (i.e. a device object under an ACPI namespace
|
||||||
object representing a PCI bridge) whose _ADR returns 0x00020000 and the
|
object representing a PCI bridge) whose _ADR returns 0x00020000 and the
|
||||||
bus number of the parent PCI bridge is 0, the sysfs directory
|
bus number of the parent PCI bridge is 0, the sysfs directory
|
||||||
representing the struct acpi_device object created for that ACPI
|
representing the struct acpi_device object created for that ACPI
|
||||||
namespace object will contain the 'physical_node' symbolic link to the
|
namespace object will contain the 'physical_node' symbolic link to the
|
||||||
/sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the
|
/sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the
|
||||||
corresponding PCI device.
|
corresponding PCI device.
|
||||||
|
|
||||||
The linking mechanism is generally bus-specific. The core of its
|
The linking mechanism is generally bus-specific. The core of its
|
||||||
implementation is located in the drivers/acpi/glue.c file, but there are
|
implementation is located in the drivers/acpi/glue.c file, but there are
|
||||||
complementary parts depending on the bus types in question located
|
complementary parts depending on the bus types in question located
|
||||||
elsewhere. For example, the PCI-specific part of it is located in
|
elsewhere. For example, the PCI-specific part of it is located in
|
||||||
drivers/pci/pci-acpi.c.
|
drivers/pci/pci-acpi.c.
|
||||||
|
|
||||||
|
|
||||||
5. Example Linux ACPI Device Tree
|
Example Linux ACPI Device Tree
|
||||||
|
=================================
|
||||||
|
|
||||||
The sysfs hierarchy of struct acpi_device objects corresponding to the
|
The sysfs hierarchy of struct acpi_device objects corresponding to the
|
||||||
example ACPI namespace illustrated in Figure 2 with the addition of
|
example ACPI namespace illustrated in Figure 2 with the addition of
|
||||||
fixed PWR_BUTTON/SLP_BUTTON devices is shown below.
|
fixed PWR_BUTTON/SLP_BUTTON devices is shown below::
|
||||||
|
|
||||||
+--------------+---+-----------------+
|
+--------------+---+-----------------+
|
||||||
| LNXSYSTEM:00 | \ | acpi:LNXSYSTEM: |
|
| LNXSYSTEM:00 | \ | acpi:LNXSYSTEM: |
|
||||||
@ -377,12 +387,14 @@ Wysocki <rafael.j.wysocki@intel.com>.
|
|||||||
|
|
||||||
Figure 3. Example Linux ACPI Device Tree
|
Figure 3. Example Linux ACPI Device Tree
|
||||||
|
|
||||||
NOTE: Each node is represented as "object/path/modalias", where:
|
.. note:: Each node is represented as "object/path/modalias", where:
|
||||||
1. 'object' is the name of the object's directory in sysfs.
|
|
||||||
2. 'path' is the ACPI namespace path of the corresponding
|
1. 'object' is the name of the object's directory in sysfs.
|
||||||
ACPI namespace object, as returned by the object's 'path'
|
2. 'path' is the ACPI namespace path of the corresponding
|
||||||
sysfs attribute.
|
ACPI namespace object, as returned by the object's 'path'
|
||||||
3. 'modalias' is the value of the object's 'modalias' sysfs
|
sysfs attribute.
|
||||||
attribute (as described earlier in this document).
|
3. 'modalias' is the value of the object's 'modalias' sysfs
|
||||||
NOTE: N/A indicates the device object does not have the 'path' or the
|
attribute (as described earlier in this document).
|
||||||
'modalias' attribute.
|
|
||||||
|
.. note:: N/A indicates the device object does not have the 'path' or the
|
||||||
|
'modalias' attribute.
|
@ -1,5 +1,8 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
==========================
|
||||||
ACPI _OSI and _REV methods
|
ACPI _OSI and _REV methods
|
||||||
--------------------------
|
==========================
|
||||||
|
|
||||||
An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
|
An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
|
||||||
to find out what the operating system supports. Eg. If BIOS
|
to find out what the operating system supports. Eg. If BIOS
|
||||||
@ -14,7 +17,7 @@ This document explains how and why the BIOS and Linux should use these methods.
|
|||||||
It also explains how and why they are widely misused.
|
It also explains how and why they are widely misused.
|
||||||
|
|
||||||
How to use _OSI
|
How to use _OSI
|
||||||
---------------
|
===============
|
||||||
|
|
||||||
Linux runs on two groups of machines -- those that are tested by the OEM
|
Linux runs on two groups of machines -- those that are tested by the OEM
|
||||||
to be compatible with Linux, and those that were never tested with Linux,
|
to be compatible with Linux, and those that were never tested with Linux,
|
||||||
@ -62,7 +65,7 @@ the string when that support is added to the kernel.
|
|||||||
That was easy. Read on, to find out how to do it wrong.
|
That was easy. Read on, to find out how to do it wrong.
|
||||||
|
|
||||||
Before _OSI, there was _OS
|
Before _OSI, there was _OS
|
||||||
--------------------------
|
==========================
|
||||||
|
|
||||||
ACPI 1.0 specified "_OS" as an
|
ACPI 1.0 specified "_OS" as an
|
||||||
"object that evaluates to a string that identifies the operating system."
|
"object that evaluates to a string that identifies the operating system."
|
||||||
@ -96,7 +99,7 @@ That is the *only* viable strategy, as that is what modern Windows does,
|
|||||||
and so doing otherwise could steer the BIOS down an untested path.
|
and so doing otherwise could steer the BIOS down an untested path.
|
||||||
|
|
||||||
_OSI is born, and immediately misused
|
_OSI is born, and immediately misused
|
||||||
--------------------------------------
|
=====================================
|
||||||
|
|
||||||
With _OSI, the *BIOS* provides the string describing an interface,
|
With _OSI, the *BIOS* provides the string describing an interface,
|
||||||
and asks the OS: "YES/NO, are you compatible with this interface?"
|
and asks the OS: "YES/NO, are you compatible with this interface?"
|
||||||
@ -144,7 +147,7 @@ catastrophic failure resulting from the BIOS taking paths that
|
|||||||
were never validated under *any* OS.
|
were never validated under *any* OS.
|
||||||
|
|
||||||
Do not use _REV
|
Do not use _REV
|
||||||
---------------
|
===============
|
||||||
|
|
||||||
Since _OSI("Linux") went away, some BIOS writers used _REV
|
Since _OSI("Linux") went away, some BIOS writers used _REV
|
||||||
to support Linux and Windows differences in the same BIOS.
|
to support Linux and Windows differences in the same BIOS.
|
||||||
@ -164,7 +167,7 @@ from mid-2015 onward. The ACPI specification will also be updated
|
|||||||
to reflect that _REV is deprecated, and always returns 2.
|
to reflect that _REV is deprecated, and always returns 2.
|
||||||
|
|
||||||
Apple Mac and _OSI("Darwin")
|
Apple Mac and _OSI("Darwin")
|
||||||
----------------------------
|
============================
|
||||||
|
|
||||||
On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
|
On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
|
||||||
to determine if the machine is running Apple OSX.
|
to determine if the machine is running Apple OSX.
|
@ -1,5 +1,8 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
=====================
|
||||||
ACPI video extensions
|
ACPI video extensions
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
=====================
|
||||||
|
|
||||||
This driver implement the ACPI Extensions For Display Adapters for
|
This driver implement the ACPI Extensions For Display Adapters for
|
||||||
integrated graphics devices on motherboard, as specified in ACPI 2.0
|
integrated graphics devices on motherboard, as specified in ACPI 2.0
|
||||||
@ -8,9 +11,10 @@ defining the video POST device, retrieving EDID information or to
|
|||||||
setup a video output, etc. Note that this is an ref. implementation
|
setup a video output, etc. Note that this is an ref. implementation
|
||||||
only. It may or may not work for your integrated video device.
|
only. It may or may not work for your integrated video device.
|
||||||
|
|
||||||
The ACPI video driver does 3 things regarding backlight control:
|
The ACPI video driver does 3 things regarding backlight control.
|
||||||
|
|
||||||
1 Export a sysfs interface for user space to control backlight level
|
Export a sysfs interface for user space to control backlight level
|
||||||
|
==================================================================
|
||||||
|
|
||||||
If the ACPI table has a video device, and acpi_backlight=vendor kernel
|
If the ACPI table has a video device, and acpi_backlight=vendor kernel
|
||||||
command line is not present, the driver will register a backlight device
|
command line is not present, the driver will register a backlight device
|
||||||
@ -22,36 +26,41 @@ The backlight sysfs interface has a standard definition here:
|
|||||||
Documentation/ABI/stable/sysfs-class-backlight.
|
Documentation/ABI/stable/sysfs-class-backlight.
|
||||||
|
|
||||||
And what ACPI video driver does is:
|
And what ACPI video driver does is:
|
||||||
actual_brightness: on read, control method _BQC will be evaluated to
|
|
||||||
get the brightness level the firmware thinks it is at;
|
actual_brightness:
|
||||||
bl_power: not implemented, will set the current brightness instead;
|
on read, control method _BQC will be evaluated to
|
||||||
brightness: on write, control method _BCM will run to set the requested
|
get the brightness level the firmware thinks it is at;
|
||||||
brightness level;
|
bl_power:
|
||||||
max_brightness: Derived from the _BCL package(see below);
|
not implemented, will set the current brightness instead;
|
||||||
type: firmware
|
brightness:
|
||||||
|
on write, control method _BCM will run to set the requested brightness level;
|
||||||
|
max_brightness:
|
||||||
|
Derived from the _BCL package(see below);
|
||||||
|
type:
|
||||||
|
firmware
|
||||||
|
|
||||||
Note that ACPI video backlight driver will always use index for
|
Note that ACPI video backlight driver will always use index for
|
||||||
brightness, actual_brightness and max_brightness. So if we have
|
brightness, actual_brightness and max_brightness. So if we have
|
||||||
the following _BCL package:
|
the following _BCL package::
|
||||||
|
|
||||||
Method (_BCL, 0, NotSerialized)
|
Method (_BCL, 0, NotSerialized)
|
||||||
{
|
|
||||||
Return (Package (0x0C)
|
|
||||||
{
|
{
|
||||||
0x64,
|
Return (Package (0x0C)
|
||||||
0x32,
|
{
|
||||||
0x0A,
|
0x64,
|
||||||
0x14,
|
0x32,
|
||||||
0x1E,
|
0x0A,
|
||||||
0x28,
|
0x14,
|
||||||
0x32,
|
0x1E,
|
||||||
0x3C,
|
0x28,
|
||||||
0x46,
|
0x32,
|
||||||
0x50,
|
0x3C,
|
||||||
0x5A,
|
0x46,
|
||||||
0x64
|
0x50,
|
||||||
})
|
0x5A,
|
||||||
}
|
0x64
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
The first two levels are for when laptop are on AC or on battery and are
|
The first two levels are for when laptop are on AC or on battery and are
|
||||||
not used by Linux currently. The remaining 10 levels are supported levels
|
not used by Linux currently. The remaining 10 levels are supported levels
|
||||||
@ -62,13 +71,15 @@ as a "brightness level" indicator. Thus from the user space perspective
|
|||||||
the range of available brightness levels is from 0 to 9 (max_brightness)
|
the range of available brightness levels is from 0 to 9 (max_brightness)
|
||||||
inclusive.
|
inclusive.
|
||||||
|
|
||||||
2 Notify user space about hotkey event
|
Notify user space about hotkey event
|
||||||
|
====================================
|
||||||
|
|
||||||
There are generally two cases for hotkey event reporting:
|
There are generally two cases for hotkey event reporting:
|
||||||
|
|
||||||
i) For some laptops, when user presses the hotkey, a scancode will be
|
i) For some laptops, when user presses the hotkey, a scancode will be
|
||||||
generated and sent to user space through the input device created by
|
generated and sent to user space through the input device created by
|
||||||
the keyboard driver as a key type input event, with proper remap, the
|
the keyboard driver as a key type input event, with proper remap, the
|
||||||
following key code will appear to user space:
|
following key code will appear to user space::
|
||||||
|
|
||||||
EV_KEY, KEY_BRIGHTNESSUP
|
EV_KEY, KEY_BRIGHTNESSUP
|
||||||
EV_KEY, KEY_BRIGHTNESSDOWN
|
EV_KEY, KEY_BRIGHTNESSDOWN
|
||||||
@ -84,23 +95,27 @@ ii) For some laptops, the press of the hotkey will not generate the
|
|||||||
notify value it received and send the event to user space through the
|
notify value it received and send the event to user space through the
|
||||||
input device it created:
|
input device it created:
|
||||||
|
|
||||||
|
===== ==================
|
||||||
event keycode
|
event keycode
|
||||||
|
===== ==================
|
||||||
0x86 KEY_BRIGHTNESSUP
|
0x86 KEY_BRIGHTNESSUP
|
||||||
0x87 KEY_BRIGHTNESSDOWN
|
0x87 KEY_BRIGHTNESSDOWN
|
||||||
etc.
|
etc.
|
||||||
|
===== ==================
|
||||||
|
|
||||||
so this would lead to the same effect as case i) now.
|
so this would lead to the same effect as case i) now.
|
||||||
|
|
||||||
Once user space tool receives this event, it can modify the backlight
|
Once user space tool receives this event, it can modify the backlight
|
||||||
level through the sysfs interface.
|
level through the sysfs interface.
|
||||||
|
|
||||||
3 Change backlight level in the kernel
|
Change backlight level in the kernel
|
||||||
|
====================================
|
||||||
|
|
||||||
This works for machines covered by case ii) in Section 2. Once the driver
|
This works for machines covered by case ii) in Section 2. Once the driver
|
||||||
received a notification, it will set the backlight level accordingly. This does
|
received a notification, it will set the backlight level accordingly. This does
|
||||||
not affect the sending of event to user space, they are always sent to user
|
not affect the sending of event to user space, they are always sent to user
|
||||||
space regardless of whether or not the video module controls the backlight level
|
space regardless of whether or not the video module controls the backlight level
|
||||||
directly. This behaviour can be controlled through the brightness_switch_enabled
|
directly. This behaviour can be controlled through the brightness_switch_enabled
|
||||||
module parameter as documented in admin-guide/kernel-parameters.rst. It is recommended to
|
module parameter as documented in admin-guide/kernel-parameters.rst. It is
|
||||||
disable this behaviour once a GUI environment starts up and wants to have full
|
recommended to disable this behaviour once a GUI environment starts up and
|
||||||
control of the backlight level.
|
wants to have full control of the backlight level.
|
13
Documentation/firmware-guide/index.rst
Normal file
13
Documentation/firmware-guide/index.rst
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
===============================
|
||||||
|
The Linux kernel firmware guide
|
||||||
|
===============================
|
||||||
|
|
||||||
|
This section describes the ACPI subsystem in Linux from firmware perspective.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
acpi/index
|
||||||
|
|
@ -35,6 +35,16 @@ trying to get it to work optimally on a given system.
|
|||||||
|
|
||||||
admin-guide/index
|
admin-guide/index
|
||||||
|
|
||||||
|
Firmware-related documentation
|
||||||
|
------------------------------
|
||||||
|
The following holds information on the kernel's expectations regarding the
|
||||||
|
platform firmwares.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
firmware-guide/index
|
||||||
|
|
||||||
Application-developer documentation
|
Application-developer documentation
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
@ -6594,7 +6594,7 @@ M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
|||||||
L: linux-gpio@vger.kernel.org
|
L: linux-gpio@vger.kernel.org
|
||||||
L: linux-acpi@vger.kernel.org
|
L: linux-acpi@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/acpi/gpio-properties.txt
|
F: Documentation/firmware-guide/acpi/gpio-properties.rst
|
||||||
F: drivers/gpio/gpiolib-acpi.c
|
F: drivers/gpio/gpiolib-acpi.c
|
||||||
|
|
||||||
GPIO IR Transmitter
|
GPIO IR Transmitter
|
||||||
|
@ -276,7 +276,7 @@ static unsigned long get_acpi_srat_table(void)
|
|||||||
if (acpi_table) {
|
if (acpi_table) {
|
||||||
header = (struct acpi_table_header *)acpi_table;
|
header = (struct acpi_table_header *)acpi_table;
|
||||||
|
|
||||||
if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_SRAT))
|
if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_SRAT))
|
||||||
return acpi_table;
|
return acpi_table;
|
||||||
}
|
}
|
||||||
entry += size;
|
entry += size;
|
||||||
|
@ -109,7 +109,7 @@ static ssize_t acpi_table_signature_show(struct config_item *cfg, char *str)
|
|||||||
if (!h)
|
if (!h)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return sprintf(str, "%.*s\n", ACPI_NAME_SIZE, h->signature);
|
return sprintf(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t acpi_table_length_show(struct config_item *cfg, char *str)
|
static ssize_t acpi_table_length_show(struct config_item *cfg, char *str)
|
||||||
@ -170,7 +170,7 @@ static ssize_t acpi_table_asl_compiler_id_show(struct config_item *cfg,
|
|||||||
if (!h)
|
if (!h)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return sprintf(str, "%.*s\n", ACPI_NAME_SIZE, h->asl_compiler_id);
|
return sprintf(str, "%.*s\n", ACPI_NAMESEG_SIZE, h->asl_compiler_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t acpi_table_asl_compiler_revision_show(struct config_item *cfg,
|
static ssize_t acpi_table_asl_compiler_revision_show(struct config_item *cfg,
|
||||||
|
@ -390,7 +390,7 @@ again:
|
|||||||
return size > 0 ? size : ret;
|
return size > 0 ? size : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acpi_aml_thread(void *unsed)
|
static int acpi_aml_thread(void *unused)
|
||||||
{
|
{
|
||||||
acpi_osd_exec_callback function = NULL;
|
acpi_osd_exec_callback function = NULL;
|
||||||
void *context;
|
void *context;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* LPAT conversion table
|
* LPAT conversion table
|
||||||
*
|
*
|
||||||
* @lpat_table: the temperature_raw mapping table structure
|
* @lpat_table: the temperature_raw mapping table structure
|
||||||
* @raw: the raw value, used as a key to get the temerature from the
|
* @raw: the raw value, used as a key to get the temperature from the
|
||||||
* above mapping table
|
* above mapping table
|
||||||
*
|
*
|
||||||
* A positive converted temperature value will be returned on success,
|
* A positive converted temperature value will be returned on success,
|
||||||
|
@ -1142,8 +1142,8 @@ static struct dev_pm_domain acpi_lpss_pm_domain = {
|
|||||||
.thaw_noirq = acpi_subsys_thaw_noirq,
|
.thaw_noirq = acpi_subsys_thaw_noirq,
|
||||||
.poweroff = acpi_subsys_suspend,
|
.poweroff = acpi_subsys_suspend,
|
||||||
.poweroff_late = acpi_lpss_suspend_late,
|
.poweroff_late = acpi_lpss_suspend_late,
|
||||||
.poweroff_noirq = acpi_subsys_suspend_noirq,
|
.poweroff_noirq = acpi_lpss_suspend_noirq,
|
||||||
.restore_noirq = acpi_subsys_resume_noirq,
|
.restore_noirq = acpi_lpss_resume_noirq,
|
||||||
.restore_early = acpi_lpss_resume_early,
|
.restore_early = acpi_lpss_resume_early,
|
||||||
#endif
|
#endif
|
||||||
.runtime_suspend = acpi_lpss_runtime_suspend,
|
.runtime_suspend = acpi_lpss_runtime_suspend,
|
||||||
|
@ -293,7 +293,7 @@ acpi_status (*acpi_internal_method) (struct acpi_walk_state * walk_state);
|
|||||||
* expected_return_btypes - Allowed type(s) for the return value
|
* expected_return_btypes - Allowed type(s) for the return value
|
||||||
*/
|
*/
|
||||||
struct acpi_name_info {
|
struct acpi_name_info {
|
||||||
char name[ACPI_NAME_SIZE];
|
char name[ACPI_NAMESEG_SIZE];
|
||||||
u16 argument_list;
|
u16 argument_list;
|
||||||
u8 expected_btypes;
|
u8 expected_btypes;
|
||||||
};
|
};
|
||||||
@ -370,7 +370,7 @@ typedef acpi_status (*acpi_object_converter) (struct acpi_namespace_node *
|
|||||||
converted_object);
|
converted_object);
|
||||||
|
|
||||||
struct acpi_simple_repair_info {
|
struct acpi_simple_repair_info {
|
||||||
char name[ACPI_NAME_SIZE];
|
char name[ACPI_NAMESEG_SIZE];
|
||||||
u32 unexpected_btypes;
|
u32 unexpected_btypes;
|
||||||
u32 package_index;
|
u32 package_index;
|
||||||
acpi_object_converter object_converter;
|
acpi_object_converter object_converter;
|
||||||
|
@ -453,7 +453,7 @@ acpi_db_execute(char *name, char **args, acpi_object_type *types, u32 flags)
|
|||||||
|
|
||||||
/* Dump a _PLD buffer if present */
|
/* Dump a _PLD buffer if present */
|
||||||
|
|
||||||
if (ACPI_COMPARE_NAME
|
if (ACPI_COMPARE_NAMESEG
|
||||||
((ACPI_CAST_PTR
|
((ACPI_CAST_PTR
|
||||||
(struct acpi_namespace_node,
|
(struct acpi_namespace_node,
|
||||||
acpi_gbl_db_method_info.method)->name.ascii),
|
acpi_gbl_db_method_info.method)->name.ascii),
|
||||||
|
@ -354,7 +354,7 @@ acpi_status acpi_db_find_name_in_namespace(char *name_arg)
|
|||||||
char acpi_name[5] = "____";
|
char acpi_name[5] = "____";
|
||||||
char *acpi_name_ptr = acpi_name;
|
char *acpi_name_ptr = acpi_name;
|
||||||
|
|
||||||
if (strlen(name_arg) > ACPI_NAME_SIZE) {
|
if (strlen(name_arg) > ACPI_NAMESEG_SIZE) {
|
||||||
acpi_os_printf("Name must be no longer than 4 characters\n");
|
acpi_os_printf("Name must be no longer than 4 characters\n");
|
||||||
return (AE_OK);
|
return (AE_OK);
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ acpi_ds_initialize_objects(u32 table_index,
|
|||||||
|
|
||||||
/* DSDT is always the first AML table */
|
/* DSDT is always the first AML table */
|
||||||
|
|
||||||
if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT)) {
|
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT)) {
|
||||||
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
|
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
|
||||||
"\nInitializing Namespace objects:\n"));
|
"\nInitializing Namespace objects:\n"));
|
||||||
}
|
}
|
||||||
|
@ -292,7 +292,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
|||||||
acpi_status status;
|
acpi_status status;
|
||||||
u32 gpe_number;
|
u32 gpe_number;
|
||||||
u8 temp_gpe_number;
|
u8 temp_gpe_number;
|
||||||
char name[ACPI_NAME_SIZE + 1];
|
char name[ACPI_NAMESEG_SIZE + 1];
|
||||||
u8 type;
|
u8 type;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ev_match_gpe_method);
|
ACPI_FUNCTION_TRACE(ev_match_gpe_method);
|
||||||
@ -310,7 +310,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
|||||||
* 1) Extract the method name and null terminate it
|
* 1) Extract the method name and null terminate it
|
||||||
*/
|
*/
|
||||||
ACPI_MOVE_32_TO_32(name, &method_node->name.integer);
|
ACPI_MOVE_32_TO_32(name, &method_node->name.integer);
|
||||||
name[ACPI_NAME_SIZE] = 0;
|
name[ACPI_NAMESEG_SIZE] = 0;
|
||||||
|
|
||||||
/* 2) Name must begin with an underscore */
|
/* 2) Name must begin with an underscore */
|
||||||
|
|
||||||
|
@ -53,10 +53,10 @@ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs)
|
|||||||
|
|
||||||
/* Special case for root */
|
/* Special case for root */
|
||||||
|
|
||||||
size_needed = 1 + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
|
size_needed = 1 + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1;
|
||||||
} else {
|
} else {
|
||||||
size_needed =
|
size_needed =
|
||||||
prefix_count + (ACPI_NAME_SIZE * num_name_segs) + 2 + 1;
|
prefix_count + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -141,7 +141,7 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (index = 0;
|
for (index = 0;
|
||||||
(index < ACPI_NAME_SIZE)
|
(index < ACPI_NAMESEG_SIZE)
|
||||||
&& (acpi_ut_valid_name_char(*aml_address, 0)); index++) {
|
&& (acpi_ut_valid_name_char(*aml_address, 0)); index++) {
|
||||||
char_buf[index] = *aml_address++;
|
char_buf[index] = *aml_address++;
|
||||||
}
|
}
|
||||||
|
@ -683,7 +683,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
|
|||||||
|
|
||||||
/* Point to next name segment and make this node current */
|
/* Point to next name segment and make this node current */
|
||||||
|
|
||||||
path += ACPI_NAME_SIZE;
|
path += ACPI_NAMESEG_SIZE;
|
||||||
current_node = this_node;
|
current_node = this_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,10 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
|
|||||||
|
|
||||||
ACPI_FUNCTION_NAME(ns_delete_node);
|
ACPI_FUNCTION_NAME(ns_delete_node);
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
return_VOID;
|
||||||
|
}
|
||||||
|
|
||||||
/* Detach an object if there is one */
|
/* Detach an object if there is one */
|
||||||
|
|
||||||
acpi_ns_detach_object(node);
|
acpi_ns_detach_object(node);
|
||||||
|
@ -70,7 +70,7 @@ void acpi_ns_print_pathname(u32 num_segments, const char *pathname)
|
|||||||
acpi_os_printf("?");
|
acpi_os_printf("?");
|
||||||
}
|
}
|
||||||
|
|
||||||
pathname += ACPI_NAME_SIZE;
|
pathname += ACPI_NAMESEG_SIZE;
|
||||||
num_segments--;
|
num_segments--;
|
||||||
if (num_segments) {
|
if (num_segments) {
|
||||||
acpi_os_printf(".");
|
acpi_os_printf(".");
|
||||||
|
@ -478,7 +478,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle,
|
|||||||
|
|
||||||
/* We are only looking for methods named _INI */
|
/* We are only looking for methods named _INI */
|
||||||
|
|
||||||
if (!ACPI_COMPARE_NAME(node->name.ascii, METHOD_NAME__INI)) {
|
if (!ACPI_COMPARE_NAMESEG(node->name.ascii, METHOD_NAME__INI)) {
|
||||||
return (AE_OK);
|
return (AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,7 +641,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
|
|||||||
* Note: We know there is an _INI within this subtree, but it may not be
|
* Note: We know there is an _INI within this subtree, but it may not be
|
||||||
* under this particular device, it may be lower in the branch.
|
* under this particular device, it may be lower in the branch.
|
||||||
*/
|
*/
|
||||||
if (!ACPI_COMPARE_NAME(device_node->name.ascii, "_SB_") ||
|
if (!ACPI_COMPARE_NAMESEG(device_node->name.ascii, "_SB_") ||
|
||||||
device_node->parent != acpi_gbl_root_node) {
|
device_node->parent != acpi_gbl_root_node) {
|
||||||
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
|
ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
|
||||||
(ACPI_TYPE_METHOD, device_node,
|
(ACPI_TYPE_METHOD, device_node,
|
||||||
|
@ -108,8 +108,8 @@ acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer)
|
|||||||
/* Just copy the ACPI name from the Node and zero terminate it */
|
/* Just copy the ACPI name from the Node and zero terminate it */
|
||||||
|
|
||||||
node_name = acpi_ut_get_node_name(node);
|
node_name = acpi_ut_get_node_name(node);
|
||||||
ACPI_MOVE_NAME(buffer->pointer, node_name);
|
ACPI_COPY_NAMESEG(buffer->pointer, node_name);
|
||||||
((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
|
((char *)buffer->pointer)[ACPI_NAMESEG_SIZE] = 0;
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%4.4s\n", (char *)buffer->pointer));
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%4.4s\n", (char *)buffer->pointer));
|
||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
@ -198,7 +198,7 @@ acpi_ns_build_normalized_path(struct acpi_namespace_node *node,
|
|||||||
char *full_path, u32 path_size, u8 no_trailing)
|
char *full_path, u32 path_size, u8 no_trailing)
|
||||||
{
|
{
|
||||||
u32 length = 0, i;
|
u32 length = 0, i;
|
||||||
char name[ACPI_NAME_SIZE];
|
char name[ACPI_NAMESEG_SIZE];
|
||||||
u8 do_no_trailing;
|
u8 do_no_trailing;
|
||||||
char c, *left, *right;
|
char c, *left, *right;
|
||||||
struct acpi_namespace_node *next_node;
|
struct acpi_namespace_node *next_node;
|
||||||
@ -446,7 +446,7 @@ static void acpi_ns_normalize_pathname(char *original_path)
|
|||||||
|
|
||||||
/* Do one nameseg at a time */
|
/* Do one nameseg at a time */
|
||||||
|
|
||||||
for (i = 0; (i < ACPI_NAME_SIZE) && *input_path; i++) {
|
for (i = 0; (i < ACPI_NAMESEG_SIZE) && *input_path; i++) {
|
||||||
if ((i == 0) || (*input_path != '_')) { /* First char is allowed to be underscore */
|
if ((i == 0) || (*input_path != '_')) { /* First char is allowed to be underscore */
|
||||||
*new_path = *input_path;
|
*new_path = *input_path;
|
||||||
new_path++;
|
new_path++;
|
||||||
|
@ -203,7 +203,7 @@ acpi_ns_one_complete_parse(u32 pass_number,
|
|||||||
|
|
||||||
/* Found OSDT table, enable the namespace override feature */
|
/* Found OSDT table, enable the namespace override feature */
|
||||||
|
|
||||||
if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT) &&
|
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) &&
|
||||||
pass_number == ACPI_IMODE_LOAD_PASS1) {
|
pass_number == ACPI_IMODE_LOAD_PASS1) {
|
||||||
walk_state->namespace_override = TRUE;
|
walk_state->namespace_override = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -316,7 +316,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
|
|||||||
|
|
||||||
this_name = acpi_object_repair_info;
|
this_name = acpi_object_repair_info;
|
||||||
while (this_name->object_converter) {
|
while (this_name->object_converter) {
|
||||||
if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
|
if (ACPI_COMPARE_NAMESEG(node->name.ascii, this_name->name)) {
|
||||||
|
|
||||||
/* Check if we can actually repair this name/type combination */
|
/* Check if we can actually repair this name/type combination */
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ acpi_status (*acpi_repair_function) (struct acpi_evaluate_info * info,
|
|||||||
return_object_ptr);
|
return_object_ptr);
|
||||||
|
|
||||||
typedef struct acpi_repair_info {
|
typedef struct acpi_repair_info {
|
||||||
char name[ACPI_NAME_SIZE];
|
char name[ACPI_NAMESEG_SIZE];
|
||||||
acpi_repair_function repair_function;
|
acpi_repair_function repair_function;
|
||||||
|
|
||||||
} acpi_repair_info;
|
} acpi_repair_info;
|
||||||
@ -188,7 +188,7 @@ static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct
|
|||||||
|
|
||||||
this_name = acpi_ns_repairable_names;
|
this_name = acpi_ns_repairable_names;
|
||||||
while (this_name->repair_function) {
|
while (this_name->repair_function) {
|
||||||
if (ACPI_COMPARE_NAME(node->name.ascii, this_name->name)) {
|
if (ACPI_COMPARE_NAMESEG(node->name.ascii, this_name->name)) {
|
||||||
return (this_name);
|
return (this_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info->length = (ACPI_NAME_SIZE * info->num_segments) +
|
info->length = (ACPI_NAMESEG_SIZE * info->num_segments) +
|
||||||
4 + info->num_carats;
|
4 + info->num_carats;
|
||||||
|
|
||||||
info->next_external_char = next_external_char;
|
info->next_external_char = next_external_char;
|
||||||
@ -249,7 +249,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
|
|||||||
/* Build the name (minus path separators) */
|
/* Build the name (minus path separators) */
|
||||||
|
|
||||||
for (; num_segments; num_segments--) {
|
for (; num_segments; num_segments--) {
|
||||||
for (i = 0; i < ACPI_NAME_SIZE; i++) {
|
for (i = 0; i < ACPI_NAMESEG_SIZE; i++) {
|
||||||
if (ACPI_IS_PATH_SEPARATOR(*external_name) ||
|
if (ACPI_IS_PATH_SEPARATOR(*external_name) ||
|
||||||
(*external_name == 0)) {
|
(*external_name == 0)) {
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info)
|
|||||||
/* Move on the next segment */
|
/* Move on the next segment */
|
||||||
|
|
||||||
external_name++;
|
external_name++;
|
||||||
result += ACPI_NAME_SIZE;
|
result += ACPI_NAMESEG_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the string */
|
/* Terminate the string */
|
||||||
@ -489,12 +489,12 @@ acpi_ns_externalize_name(u32 internal_name_length,
|
|||||||
|
|
||||||
/* Copy and validate the 4-char name segment */
|
/* Copy and validate the 4-char name segment */
|
||||||
|
|
||||||
ACPI_MOVE_NAME(&(*converted_name)[j],
|
ACPI_COPY_NAMESEG(&(*converted_name)[j],
|
||||||
&internal_name[names_index]);
|
&internal_name[names_index]);
|
||||||
acpi_ut_repair_name(&(*converted_name)[j]);
|
acpi_ut_repair_name(&(*converted_name)[j]);
|
||||||
|
|
||||||
j += ACPI_NAME_SIZE;
|
j += ACPI_NAMESEG_SIZE;
|
||||||
names_index += ACPI_NAME_SIZE;
|
names_index += ACPI_NAMESEG_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,8 +495,8 @@ acpi_status acpi_install_method(u8 *buffer)
|
|||||||
|
|
||||||
/* Table must be a DSDT or SSDT */
|
/* Table must be a DSDT or SSDT */
|
||||||
|
|
||||||
if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) &&
|
if (!ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) &&
|
||||||
!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
|
!ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT)) {
|
||||||
return (AE_BAD_HEADER);
|
return (AE_BAD_HEADER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,21 +150,21 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state)
|
|||||||
|
|
||||||
/* Two name segments */
|
/* Two name segments */
|
||||||
|
|
||||||
end += 1 + (2 * ACPI_NAME_SIZE);
|
end += 1 + (2 * ACPI_NAMESEG_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AML_MULTI_NAME_PREFIX:
|
case AML_MULTI_NAME_PREFIX:
|
||||||
|
|
||||||
/* Multiple name segments, 4 chars each, count in next byte */
|
/* Multiple name segments, 4 chars each, count in next byte */
|
||||||
|
|
||||||
end += 2 + (*(end + 1) * ACPI_NAME_SIZE);
|
end += 2 + (*(end + 1) * ACPI_NAMESEG_SIZE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
/* Single name segment */
|
/* Single name segment */
|
||||||
|
|
||||||
end += ACPI_NAME_SIZE;
|
end += ACPI_NAMESEG_SIZE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,7 +522,7 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
|
|||||||
|
|
||||||
ACPI_MOVE_32_TO_32(&name, parser_state->aml);
|
ACPI_MOVE_32_TO_32(&name, parser_state->aml);
|
||||||
acpi_ps_set_name(field, name);
|
acpi_ps_set_name(field, name);
|
||||||
parser_state->aml += ACPI_NAME_SIZE;
|
parser_state->aml += ACPI_NAMESEG_SIZE;
|
||||||
|
|
||||||
ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
|
ASL_CV_CAPTURE_COMMENTS_ONLY(parser_state);
|
||||||
|
|
||||||
|
@ -603,10 +603,10 @@ acpi_walk_resources(acpi_handle device_handle,
|
|||||||
/* Parameter validation */
|
/* Parameter validation */
|
||||||
|
|
||||||
if (!device_handle || !user_function || !name ||
|
if (!device_handle || !user_function || !name ||
|
||||||
(!ACPI_COMPARE_NAME(name, METHOD_NAME__CRS) &&
|
(!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__CRS) &&
|
||||||
!ACPI_COMPARE_NAME(name, METHOD_NAME__PRS) &&
|
!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__PRS) &&
|
||||||
!ACPI_COMPARE_NAME(name, METHOD_NAME__AEI) &&
|
!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__AEI) &&
|
||||||
!ACPI_COMPARE_NAME(name, METHOD_NAME__DMA))) {
|
!ACPI_COMPARE_NAMESEG(name, METHOD_NAME__DMA))) {
|
||||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +480,8 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc,
|
|||||||
|
|
||||||
/* If a particular signature is expected (DSDT/FACS), it must match */
|
/* If a particular signature is expected (DSDT/FACS), it must match */
|
||||||
|
|
||||||
if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) {
|
if (signature &&
|
||||||
|
!ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) {
|
||||||
ACPI_BIOS_ERROR((AE_INFO,
|
ACPI_BIOS_ERROR((AE_INFO,
|
||||||
"Invalid signature 0x%X for ACPI table, expected [%s]",
|
"Invalid signature 0x%X for ACPI table, expected [%s]",
|
||||||
table_desc->signature.integer, signature));
|
table_desc->signature.integer, signature));
|
||||||
|
@ -56,7 +56,7 @@ acpi_tb_find_table(char *signature,
|
|||||||
/* Normalize the input strings */
|
/* Normalize the input strings */
|
||||||
|
|
||||||
memset(&header, 0, sizeof(struct acpi_table_header));
|
memset(&header, 0, sizeof(struct acpi_table_header));
|
||||||
ACPI_MOVE_NAME(header.signature, signature);
|
ACPI_COPY_NAMESEG(header.signature, signature);
|
||||||
strncpy(header.oem_id, oem_id, ACPI_OEM_ID_SIZE);
|
strncpy(header.oem_id, oem_id, ACPI_OEM_ID_SIZE);
|
||||||
strncpy(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
|
strncpy(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ acpi_tb_find_table(char *signature,
|
|||||||
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
|
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
|
||||||
for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
|
for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
|
||||||
if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature),
|
if (memcmp(&(acpi_gbl_root_table_list.tables[i].signature),
|
||||||
header.signature, ACPI_NAME_SIZE)) {
|
header.signature, ACPI_NAMESEG_SIZE)) {
|
||||||
|
|
||||||
/* Not the requested table */
|
/* Not the requested table */
|
||||||
|
|
||||||
@ -94,14 +94,14 @@ acpi_tb_find_table(char *signature,
|
|||||||
|
|
||||||
if (!memcmp
|
if (!memcmp
|
||||||
(acpi_gbl_root_table_list.tables[i].pointer->signature,
|
(acpi_gbl_root_table_list.tables[i].pointer->signature,
|
||||||
header.signature, ACPI_NAME_SIZE) && (!oem_id[0]
|
header.signature, ACPI_NAMESEG_SIZE) && (!oem_id[0]
|
||||||
||
|
||
|
||||||
!memcmp
|
!memcmp
|
||||||
(acpi_gbl_root_table_list.
|
(acpi_gbl_root_table_list.
|
||||||
tables[i].pointer->
|
tables[i].
|
||||||
oem_id,
|
pointer->oem_id,
|
||||||
header.oem_id,
|
header.oem_id,
|
||||||
ACPI_OEM_ID_SIZE))
|
ACPI_OEM_ID_SIZE))
|
||||||
&& (!oem_table_id[0]
|
&& (!oem_table_id[0]
|
||||||
|| !memcmp(acpi_gbl_root_table_list.tables[i].pointer->
|
|| !memcmp(acpi_gbl_root_table_list.tables[i].pointer->
|
||||||
oem_table_id, header.oem_table_id,
|
oem_table_id, header.oem_table_id,
|
||||||
|
@ -120,7 +120,7 @@ acpi_tb_install_standard_table(acpi_physical_address address,
|
|||||||
*/
|
*/
|
||||||
if (!reload &&
|
if (!reload &&
|
||||||
acpi_gbl_disable_ssdt_table_install &&
|
acpi_gbl_disable_ssdt_table_install &&
|
||||||
ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) {
|
ACPI_COMPARE_NAMESEG(&new_table_desc.signature, ACPI_SIG_SSDT)) {
|
||||||
ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X",
|
ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X",
|
||||||
new_table_desc.signature.ascii,
|
new_table_desc.signature.ascii,
|
||||||
ACPI_FORMAT_UINT64(address)));
|
ACPI_FORMAT_UINT64(address)));
|
||||||
|
@ -69,10 +69,10 @@ acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
|
|||||||
|
|
||||||
memcpy(out_header, header, sizeof(struct acpi_table_header));
|
memcpy(out_header, header, sizeof(struct acpi_table_header));
|
||||||
|
|
||||||
acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE);
|
acpi_tb_fix_string(out_header->signature, ACPI_NAMESEG_SIZE);
|
||||||
acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
|
acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
|
||||||
acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
|
acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
|
||||||
acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE);
|
acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAMESEG_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -94,7 +94,7 @@ acpi_tb_print_table_header(acpi_physical_address address,
|
|||||||
{
|
{
|
||||||
struct acpi_table_header local_header;
|
struct acpi_table_header local_header;
|
||||||
|
|
||||||
if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
|
if (ACPI_COMPARE_NAMESEG(header->signature, ACPI_SIG_FACS)) {
|
||||||
|
|
||||||
/* FACS only has signature and length fields */
|
/* FACS only has signature and length fields */
|
||||||
|
|
||||||
@ -158,8 +158,8 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
|
|||||||
* They are the odd tables, have no standard ACPI header and no checksum
|
* They are the odd tables, have no standard ACPI header and no checksum
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_S3PT) ||
|
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_S3PT) ||
|
||||||
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FACS)) {
|
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_FACS)) {
|
||||||
return (AE_OK);
|
return (AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,9 +332,9 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
|
|||||||
&table_index);
|
&table_index);
|
||||||
|
|
||||||
if (ACPI_SUCCESS(status) &&
|
if (ACPI_SUCCESS(status) &&
|
||||||
ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
|
ACPI_COMPARE_NAMESEG(&acpi_gbl_root_table_list.
|
||||||
tables[table_index].signature,
|
tables[table_index].signature,
|
||||||
ACPI_SIG_FADT)) {
|
ACPI_SIG_FADT)) {
|
||||||
acpi_gbl_fadt_index = table_index;
|
acpi_gbl_fadt_index = table_index;
|
||||||
acpi_tb_parse_fadt();
|
acpi_tb_parse_fadt();
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ acpi_get_table_header(char *signature,
|
|||||||
|
|
||||||
for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
|
for (i = 0, j = 0; i < acpi_gbl_root_table_list.current_table_count;
|
||||||
i++) {
|
i++) {
|
||||||
if (!ACPI_COMPARE_NAME
|
if (!ACPI_COMPARE_NAMESEG
|
||||||
(&(acpi_gbl_root_table_list.tables[i].signature),
|
(&(acpi_gbl_root_table_list.tables[i].signature),
|
||||||
signature)) {
|
signature)) {
|
||||||
continue;
|
continue;
|
||||||
@ -323,7 +323,7 @@ acpi_get_table(char *signature,
|
|||||||
i++) {
|
i++) {
|
||||||
table_desc = &acpi_gbl_root_table_list.tables[i];
|
table_desc = &acpi_gbl_root_table_list.tables[i];
|
||||||
|
|
||||||
if (!ACPI_COMPARE_NAME(&table_desc->signature, signature)) {
|
if (!ACPI_COMPARE_NAMESEG(&table_desc->signature, signature)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ acpi_status acpi_tb_load_namespace(void)
|
|||||||
table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index];
|
table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index];
|
||||||
|
|
||||||
if (!acpi_gbl_root_table_list.current_table_count ||
|
if (!acpi_gbl_root_table_list.current_table_count ||
|
||||||
!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_DSDT) ||
|
!ACPI_COMPARE_NAMESEG(table->signature.ascii, ACPI_SIG_DSDT) ||
|
||||||
ACPI_FAILURE(acpi_tb_validate_table(table))) {
|
ACPI_FAILURE(acpi_tb_validate_table(table))) {
|
||||||
status = AE_NO_ACPI_TABLES;
|
status = AE_NO_ACPI_TABLES;
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
@ -170,11 +170,12 @@ acpi_status acpi_tb_load_namespace(void)
|
|||||||
table = &acpi_gbl_root_table_list.tables[i];
|
table = &acpi_gbl_root_table_list.tables[i];
|
||||||
|
|
||||||
if (!table->address ||
|
if (!table->address ||
|
||||||
(!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT)
|
(!ACPI_COMPARE_NAMESEG
|
||||||
&& !ACPI_COMPARE_NAME(table->signature.ascii,
|
(table->signature.ascii, ACPI_SIG_SSDT)
|
||||||
ACPI_SIG_PSDT)
|
&& !ACPI_COMPARE_NAMESEG(table->signature.ascii,
|
||||||
&& !ACPI_COMPARE_NAME(table->signature.ascii,
|
ACPI_SIG_PSDT)
|
||||||
ACPI_SIG_OSDT))
|
&& !ACPI_COMPARE_NAMESEG(table->signature.ascii,
|
||||||
|
ACPI_SIG_OSDT))
|
||||||
|| ACPI_FAILURE(acpi_tb_validate_table(table))) {
|
|| ACPI_FAILURE(acpi_tb_validate_table(table))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -364,7 +365,7 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
|
|||||||
* only these types can contain AML and thus are the only types
|
* only these types can contain AML and thus are the only types
|
||||||
* that can create namespace objects.
|
* that can create namespace objects.
|
||||||
*/
|
*/
|
||||||
if (ACPI_COMPARE_NAME
|
if (ACPI_COMPARE_NAMESEG
|
||||||
(acpi_gbl_root_table_list.tables[i].signature.ascii,
|
(acpi_gbl_root_table_list.tables[i].signature.ascii,
|
||||||
ACPI_SIG_DSDT)) {
|
ACPI_SIG_DSDT)) {
|
||||||
status = AE_TYPE;
|
status = AE_TYPE;
|
||||||
|
@ -30,7 +30,7 @@ u8 acpi_ut_valid_nameseg(char *name)
|
|||||||
|
|
||||||
/* Validate each character in the signature */
|
/* Validate each character in the signature */
|
||||||
|
|
||||||
for (i = 0; i < ACPI_NAME_SIZE; i++) {
|
for (i = 0; i < ACPI_NAMESEG_SIZE; i++) {
|
||||||
if (!acpi_ut_valid_name_char(name[i], i)) {
|
if (!acpi_ut_valid_name_char(name[i], i)) {
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
|
|||||||
"IPMI", /* 0x07 */
|
"IPMI", /* 0x07 */
|
||||||
"GeneralPurposeIo", /* 0x08 */
|
"GeneralPurposeIo", /* 0x08 */
|
||||||
"GenericSerialBus", /* 0x09 */
|
"GenericSerialBus", /* 0x09 */
|
||||||
"PCC" /* 0x0A */
|
"PlatformCommChannel" /* 0x0A */
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *acpi_ut_get_region_name(u8 space_id)
|
const char *acpi_ut_get_region_name(u8 space_id)
|
||||||
@ -239,7 +239,7 @@ const char *acpi_ut_get_node_name(void *object)
|
|||||||
{
|
{
|
||||||
struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
|
struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
|
||||||
|
|
||||||
/* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
|
/* Must return a string of exactly 4 characters == ACPI_NAMESEG_SIZE */
|
||||||
|
|
||||||
if (!object) {
|
if (!object) {
|
||||||
return ("NULL");
|
return ("NULL");
|
||||||
|
@ -59,10 +59,10 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
|
|||||||
|
|
||||||
/* These are the only tables that contain executable AML */
|
/* These are the only tables that contain executable AML */
|
||||||
|
|
||||||
if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) ||
|
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) ||
|
||||||
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) ||
|
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_PSDT) ||
|
||||||
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT) ||
|
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT) ||
|
||||||
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT) ||
|
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) ||
|
||||||
ACPI_IS_OEM_SIG(table->signature)) {
|
ACPI_IS_OEM_SIG(table->signature)) {
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ const union acpi_predefined_info *acpi_ut_match_predefined_method(char *name)
|
|||||||
|
|
||||||
this_name = acpi_gbl_predefined_methods;
|
this_name = acpi_gbl_predefined_methods;
|
||||||
while (this_name->info.name[0]) {
|
while (this_name->info.name[0]) {
|
||||||
if (ACPI_COMPARE_NAME(name, this_name->info.name)) {
|
if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) {
|
||||||
return (this_name);
|
return (this_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ const union acpi_predefined_info *acpi_ut_match_resource_name(char *name)
|
|||||||
|
|
||||||
this_name = acpi_gbl_resource_names;
|
this_name = acpi_gbl_resource_names;
|
||||||
while (this_name->info.name[0]) {
|
while (this_name->info.name[0]) {
|
||||||
if (ACPI_COMPARE_NAME(name, this_name->info.name)) {
|
if (ACPI_COMPARE_NAMESEG(name, this_name->info.name)) {
|
||||||
return (this_name);
|
return (this_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,15 +141,15 @@ void acpi_ut_repair_name(char *name)
|
|||||||
* Special case for the root node. This can happen if we get an
|
* Special case for the root node. This can happen if we get an
|
||||||
* error during the execution of module-level code.
|
* error during the execution of module-level code.
|
||||||
*/
|
*/
|
||||||
if (ACPI_COMPARE_NAME(name, ACPI_ROOT_PATHNAME)) {
|
if (ACPI_COMPARE_NAMESEG(name, ACPI_ROOT_PATHNAME)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_MOVE_NAME(&original_name, name);
|
ACPI_COPY_NAMESEG(&original_name, name);
|
||||||
|
|
||||||
/* Check each character in the name */
|
/* Check each character in the name */
|
||||||
|
|
||||||
for (i = 0; i < ACPI_NAME_SIZE; i++) {
|
for (i = 0; i < ACPI_NAMESEG_SIZE; i++) {
|
||||||
if (acpi_ut_valid_name_char(name[i], i)) {
|
if (acpi_ut_valid_name_char(name[i], i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -456,8 +456,11 @@ static int acpi_button_resume(struct device *dev)
|
|||||||
struct acpi_button *button = acpi_driver_data(device);
|
struct acpi_button *button = acpi_driver_data(device);
|
||||||
|
|
||||||
button->suspended = false;
|
button->suspended = false;
|
||||||
if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users)
|
if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) {
|
||||||
|
button->last_state = !!acpi_lid_evaluate_state(device);
|
||||||
|
button->last_time = ktime_get();
|
||||||
acpi_lid_initialize_state(device);
|
acpi_lid_initialize_state(device);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,9 +81,9 @@ struct cppc_pcc_data {
|
|||||||
int refcount;
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Array to represent the PCC channel per subspace id */
|
/* Array to represent the PCC channel per subspace ID */
|
||||||
static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES];
|
static struct cppc_pcc_data *pcc_data[MAX_PCC_SUBSPACES];
|
||||||
/* The cpu_pcc_subspace_idx containsper CPU subspace id */
|
/* The cpu_pcc_subspace_idx contains per CPU subspace ID */
|
||||||
static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
|
static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -436,7 +436,7 @@ int acpi_get_psd_map(struct cppc_cpudata **all_cpu_data)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that we have _PSD data from all CPUs, lets setup P-state
|
* Now that we have _PSD data from all CPUs, let's setup P-state
|
||||||
* domain info.
|
* domain info.
|
||||||
*/
|
*/
|
||||||
for_each_possible_cpu(i) {
|
for_each_possible_cpu(i) {
|
||||||
@ -588,7 +588,7 @@ static int register_pcc_channel(int pcc_ss_idx)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set flag so that we dont come here for each CPU. */
|
/* Set flag so that we don't come here for each CPU. */
|
||||||
pcc_data[pcc_ss_idx]->pcc_channel_acquired = true;
|
pcc_data[pcc_ss_idx]->pcc_channel_acquired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,7 +613,7 @@ bool __weak cpc_ffh_supported(void)
|
|||||||
*
|
*
|
||||||
* Check and allocate the cppc_pcc_data memory.
|
* Check and allocate the cppc_pcc_data memory.
|
||||||
* In some processor configurations it is possible that same subspace
|
* In some processor configurations it is possible that same subspace
|
||||||
* is shared between multiple CPU's. This is seen especially in CPU's
|
* is shared between multiple CPUs. This is seen especially in CPUs
|
||||||
* with hardware multi-threading support.
|
* with hardware multi-threading support.
|
||||||
*
|
*
|
||||||
* Return: 0 for success, errno for failure
|
* Return: 0 for success, errno for failure
|
||||||
@ -711,7 +711,7 @@ static bool is_cppc_supported(int revision, int num_ent)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* acpi_cppc_processor_probe - Search for per CPU _CPC objects.
|
* acpi_cppc_processor_probe - Search for per CPU _CPC objects.
|
||||||
* @pr: Ptr to acpi_processor containing this CPUs logical Id.
|
* @pr: Ptr to acpi_processor containing this CPU's logical ID.
|
||||||
*
|
*
|
||||||
* Return: 0 for success or negative value for err.
|
* Return: 0 for success or negative value for err.
|
||||||
*/
|
*/
|
||||||
@ -728,7 +728,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
|
|||||||
acpi_status status;
|
acpi_status status;
|
||||||
int ret = -EFAULT;
|
int ret = -EFAULT;
|
||||||
|
|
||||||
/* Parse the ACPI _CPC table for this cpu. */
|
/* Parse the ACPI _CPC table for this CPU. */
|
||||||
status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
|
status = acpi_evaluate_object_typed(handle, "_CPC", NULL, &output,
|
||||||
ACPI_TYPE_PACKAGE);
|
ACPI_TYPE_PACKAGE);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
@ -840,7 +840,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
/* Register PCC channel once for all PCC subspace id. */
|
/* Register PCC channel once for all PCC subspace ID. */
|
||||||
if (pcc_subspace_id >= 0 && !pcc_data[pcc_subspace_id]->pcc_channel_acquired) {
|
if (pcc_subspace_id >= 0 && !pcc_data[pcc_subspace_id]->pcc_channel_acquired) {
|
||||||
ret = register_pcc_channel(pcc_subspace_id);
|
ret = register_pcc_channel(pcc_subspace_id);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -860,7 +860,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
|
|||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Plug PSD data into this CPUs CPC descriptor. */
|
/* Plug PSD data into this CPU's CPC descriptor. */
|
||||||
per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
|
per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
|
||||||
|
|
||||||
ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
|
ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
|
||||||
@ -891,7 +891,7 @@ EXPORT_SYMBOL_GPL(acpi_cppc_processor_probe);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* acpi_cppc_processor_exit - Cleanup CPC structs.
|
* acpi_cppc_processor_exit - Cleanup CPC structs.
|
||||||
* @pr: Ptr to acpi_processor containing this CPUs logical Id.
|
* @pr: Ptr to acpi_processor containing this CPU's logical ID.
|
||||||
*
|
*
|
||||||
* Return: Void
|
* Return: Void
|
||||||
*/
|
*/
|
||||||
@ -931,7 +931,7 @@ EXPORT_SYMBOL_GPL(acpi_cppc_processor_exit);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* cpc_read_ffh() - Read FFH register
|
* cpc_read_ffh() - Read FFH register
|
||||||
* @cpunum: cpu number to read
|
* @cpunum: CPU number to read
|
||||||
* @reg: cppc register information
|
* @reg: cppc register information
|
||||||
* @val: place holder for return value
|
* @val: place holder for return value
|
||||||
*
|
*
|
||||||
@ -946,7 +946,7 @@ int __weak cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* cpc_write_ffh() - Write FFH register
|
* cpc_write_ffh() - Write FFH register
|
||||||
* @cpunum: cpu number to write
|
* @cpunum: CPU number to write
|
||||||
* @reg: cppc register information
|
* @reg: cppc register information
|
||||||
* @val: value to write
|
* @val: value to write
|
||||||
*
|
*
|
||||||
@ -1093,7 +1093,7 @@ int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
|
|||||||
EXPORT_SYMBOL_GPL(cppc_get_desired_perf);
|
EXPORT_SYMBOL_GPL(cppc_get_desired_perf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cppc_get_perf_caps - Get a CPUs performance capabilities.
|
* cppc_get_perf_caps - Get a CPU's performance capabilities.
|
||||||
* @cpunum: CPU from which to get capabilities info.
|
* @cpunum: CPU from which to get capabilities info.
|
||||||
* @perf_caps: ptr to cppc_perf_caps. See cppc_acpi.h
|
* @perf_caps: ptr to cppc_perf_caps. See cppc_acpi.h
|
||||||
*
|
*
|
||||||
@ -1183,7 +1183,7 @@ out_err:
|
|||||||
EXPORT_SYMBOL_GPL(cppc_get_perf_caps);
|
EXPORT_SYMBOL_GPL(cppc_get_perf_caps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cppc_get_perf_ctrs - Read a CPUs performance feedback counters.
|
* cppc_get_perf_ctrs - Read a CPU's performance feedback counters.
|
||||||
* @cpunum: CPU from which to read counters.
|
* @cpunum: CPU from which to read counters.
|
||||||
* @perf_fb_ctrs: ptr to cppc_perf_fb_ctrs. See cppc_acpi.h
|
* @perf_fb_ctrs: ptr to cppc_perf_fb_ctrs. See cppc_acpi.h
|
||||||
*
|
*
|
||||||
@ -1210,7 +1210,7 @@ int cppc_get_perf_ctrs(int cpunum, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
|
|||||||
ctr_wrap_reg = &cpc_desc->cpc_regs[CTR_WRAP_TIME];
|
ctr_wrap_reg = &cpc_desc->cpc_regs[CTR_WRAP_TIME];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If refernce perf register is not supported then we should
|
* If reference perf register is not supported then we should
|
||||||
* use the nominal perf value
|
* use the nominal perf value
|
||||||
*/
|
*/
|
||||||
if (!CPC_SUPPORTED(ref_perf_reg))
|
if (!CPC_SUPPORTED(ref_perf_reg))
|
||||||
@ -1263,7 +1263,7 @@ out_err:
|
|||||||
EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs);
|
EXPORT_SYMBOL_GPL(cppc_get_perf_ctrs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cppc_set_perf - Set a CPUs performance controls.
|
* cppc_set_perf - Set a CPU's performance controls.
|
||||||
* @cpu: CPU for which to set performance controls.
|
* @cpu: CPU for which to set performance controls.
|
||||||
* @perf_ctrls: ptr to cppc_perf_ctrls. See cppc_acpi.h
|
* @perf_ctrls: ptr to cppc_perf_ctrls. See cppc_acpi.h
|
||||||
*
|
*
|
||||||
@ -1344,7 +1344,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
|
|||||||
* executing the Phase-II.
|
* executing the Phase-II.
|
||||||
* 2. Some other CPU has beaten this CPU to successfully execute the
|
* 2. Some other CPU has beaten this CPU to successfully execute the
|
||||||
* write_trylock and has already acquired the write_lock. We know for a
|
* write_trylock and has already acquired the write_lock. We know for a
|
||||||
* fact it(other CPU acquiring the write_lock) couldn't have happened
|
* fact it (other CPU acquiring the write_lock) couldn't have happened
|
||||||
* before this CPU's Phase-I as we held the read_lock.
|
* before this CPU's Phase-I as we held the read_lock.
|
||||||
* 3. Some other CPU executing pcc CMD_READ has stolen the
|
* 3. Some other CPU executing pcc CMD_READ has stolen the
|
||||||
* down_write, in which case, send_pcc_cmd will check for pending
|
* down_write, in which case, send_pcc_cmd will check for pending
|
||||||
|
@ -728,6 +728,9 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acpi_handle_debug(adev->handle, "GPE%2X enabled for wakeup\n",
|
||||||
|
(unsigned int)wakeup->gpe_number);
|
||||||
|
|
||||||
inc:
|
inc:
|
||||||
wakeup->enable_count++;
|
wakeup->enable_count++;
|
||||||
|
|
||||||
|
@ -31,8 +31,7 @@ static ssize_t name##_show(struct device *dev,\
|
|||||||
struct device_attribute *attr,\
|
struct device_attribute *attr,\
|
||||||
char *buf)\
|
char *buf)\
|
||||||
{\
|
{\
|
||||||
struct platform_device *pdev = to_platform_device(dev);\
|
struct acpi_device *acpi_dev = dev_get_drvdata(dev);\
|
||||||
struct acpi_device *acpi_dev = platform_get_drvdata(pdev);\
|
|
||||||
unsigned long long val;\
|
unsigned long long val;\
|
||||||
acpi_status status;\
|
acpi_status status;\
|
||||||
\
|
\
|
||||||
|
@ -131,8 +131,8 @@ int acpi_bus_generate_netlink_event(const char *device_class,
|
|||||||
event = nla_data(attr);
|
event = nla_data(attr);
|
||||||
memset(event, 0, sizeof(struct acpi_genl_event));
|
memset(event, 0, sizeof(struct acpi_genl_event));
|
||||||
|
|
||||||
strcpy(event->device_class, device_class);
|
strscpy(event->device_class, device_class, sizeof(event->device_class));
|
||||||
strcpy(event->bus_id, bus_id);
|
strscpy(event->bus_id, bus_id, sizeof(event->bus_id));
|
||||||
event->type = type;
|
event->type = type;
|
||||||
event->data = data;
|
event->data = data;
|
||||||
|
|
||||||
|
@ -535,12 +535,12 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
|
|||||||
/*
|
/*
|
||||||
* Try to execute _DSW first.
|
* Try to execute _DSW first.
|
||||||
*
|
*
|
||||||
* Three agruments are needed for the _DSW object:
|
* Three arguments are needed for the _DSW object:
|
||||||
* Argument 0: enable/disable the wake capabilities
|
* Argument 0: enable/disable the wake capabilities
|
||||||
* Argument 1: target system state
|
* Argument 1: target system state
|
||||||
* Argument 2: target device state
|
* Argument 2: target device state
|
||||||
* When _DSW object is called to disable the wake capabilities, maybe
|
* When _DSW object is called to disable the wake capabilities, maybe
|
||||||
* the first argument is filled. The values of the other two agruments
|
* the first argument is filled. The values of the other two arguments
|
||||||
* are meaningless.
|
* are meaningless.
|
||||||
*/
|
*/
|
||||||
in_arg[0].type = ACPI_TYPE_INTEGER;
|
in_arg[0].type = ACPI_TYPE_INTEGER;
|
||||||
|
@ -164,7 +164,7 @@ static struct acpi_pptt_cache *acpi_find_cache_level(struct acpi_table_header *t
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* acpi_count_levels() - Given a PPTT table, and a cpu node, count the caches
|
* acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches
|
||||||
* @table_hdr: Pointer to the head of the PPTT table
|
* @table_hdr: Pointer to the head of the PPTT table
|
||||||
* @cpu_node: processor node we wish to count caches for
|
* @cpu_node: processor node we wish to count caches for
|
||||||
*
|
*
|
||||||
@ -235,7 +235,7 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr,
|
|||||||
/**
|
/**
|
||||||
* acpi_find_processor_node() - Given a PPTT table find the requested processor
|
* acpi_find_processor_node() - Given a PPTT table find the requested processor
|
||||||
* @table_hdr: Pointer to the head of the PPTT table
|
* @table_hdr: Pointer to the head of the PPTT table
|
||||||
* @acpi_cpu_id: cpu we are searching for
|
* @acpi_cpu_id: CPU we are searching for
|
||||||
*
|
*
|
||||||
* Find the subtable entry describing the provided processor.
|
* Find the subtable entry describing the provided processor.
|
||||||
* This is done by iterating the PPTT table looking for processor nodes
|
* This is done by iterating the PPTT table looking for processor nodes
|
||||||
@ -456,21 +456,21 @@ static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_ta
|
|||||||
|
|
||||||
static void acpi_pptt_warn_missing(void)
|
static void acpi_pptt_warn_missing(void)
|
||||||
{
|
{
|
||||||
pr_warn_once("No PPTT table found, cpu and cache topology may be inaccurate\n");
|
pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
|
* topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
|
||||||
* @table: Pointer to the head of the PPTT table
|
* @table: Pointer to the head of the PPTT table
|
||||||
* @cpu: Kernel logical cpu number
|
* @cpu: Kernel logical CPU number
|
||||||
* @level: A level that terminates the search
|
* @level: A level that terminates the search
|
||||||
* @flag: A flag which terminates the search
|
* @flag: A flag which terminates the search
|
||||||
*
|
*
|
||||||
* Get a unique value given a cpu, and a topology level, that can be
|
* Get a unique value given a CPU, and a topology level, that can be
|
||||||
* matched to determine which cpus share common topological features
|
* matched to determine which cpus share common topological features
|
||||||
* at that level.
|
* at that level.
|
||||||
*
|
*
|
||||||
* Return: Unique value, or -ENOENT if unable to locate cpu
|
* Return: Unique value, or -ENOENT if unable to locate CPU
|
||||||
*/
|
*/
|
||||||
static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
|
static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
|
||||||
unsigned int cpu, int level, int flag)
|
unsigned int cpu, int level, int flag)
|
||||||
@ -510,7 +510,7 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
retval = topology_get_acpi_cpu_tag(table, cpu, level, flag);
|
retval = topology_get_acpi_cpu_tag(table, cpu, level, flag);
|
||||||
pr_debug("Topology Setup ACPI cpu %d, level %d ret = %d\n",
|
pr_debug("Topology Setup ACPI CPU %d, level %d ret = %d\n",
|
||||||
cpu, level, retval);
|
cpu, level, retval);
|
||||||
acpi_put_table(table);
|
acpi_put_table(table);
|
||||||
|
|
||||||
@ -519,9 +519,9 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* acpi_find_last_cache_level() - Determines the number of cache levels for a PE
|
* acpi_find_last_cache_level() - Determines the number of cache levels for a PE
|
||||||
* @cpu: Kernel logical cpu number
|
* @cpu: Kernel logical CPU number
|
||||||
*
|
*
|
||||||
* Given a logical cpu number, returns the number of levels of cache represented
|
* Given a logical CPU number, returns the number of levels of cache represented
|
||||||
* in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
|
* in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
|
||||||
* indicating we didn't find any cache levels.
|
* indicating we didn't find any cache levels.
|
||||||
*
|
*
|
||||||
@ -534,7 +534,7 @@ int acpi_find_last_cache_level(unsigned int cpu)
|
|||||||
int number_of_levels = 0;
|
int number_of_levels = 0;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
pr_debug("Cache Setup find last level cpu=%d\n", cpu);
|
pr_debug("Cache Setup find last level CPU=%d\n", cpu);
|
||||||
|
|
||||||
acpi_cpu_id = get_acpi_id_for_cpu(cpu);
|
acpi_cpu_id = get_acpi_id_for_cpu(cpu);
|
||||||
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
||||||
@ -551,14 +551,14 @@ int acpi_find_last_cache_level(unsigned int cpu)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* cache_setup_acpi() - Override CPU cache topology with data from the PPTT
|
* cache_setup_acpi() - Override CPU cache topology with data from the PPTT
|
||||||
* @cpu: Kernel logical cpu number
|
* @cpu: Kernel logical CPU number
|
||||||
*
|
*
|
||||||
* Updates the global cache info provided by cpu_get_cacheinfo()
|
* Updates the global cache info provided by cpu_get_cacheinfo()
|
||||||
* when there are valid properties in the acpi_pptt_cache nodes. A
|
* when there are valid properties in the acpi_pptt_cache nodes. A
|
||||||
* successful parse may not result in any updates if none of the
|
* successful parse may not result in any updates if none of the
|
||||||
* cache levels have any valid flags set. Futher, a unique value is
|
* cache levels have any valid flags set. Further, a unique value is
|
||||||
* associated with each known CPU cache entry. This unique value
|
* associated with each known CPU cache entry. This unique value
|
||||||
* can be used to determine whether caches are shared between cpus.
|
* can be used to determine whether caches are shared between CPUs.
|
||||||
*
|
*
|
||||||
* Return: -ENOENT on failure to find table, or 0 on success
|
* Return: -ENOENT on failure to find table, or 0 on success
|
||||||
*/
|
*/
|
||||||
@ -567,7 +567,7 @@ int cache_setup_acpi(unsigned int cpu)
|
|||||||
struct acpi_table_header *table;
|
struct acpi_table_header *table;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
pr_debug("Cache Setup ACPI cpu %d\n", cpu);
|
pr_debug("Cache Setup ACPI CPU %d\n", cpu);
|
||||||
|
|
||||||
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
@ -582,8 +582,8 @@ int cache_setup_acpi(unsigned int cpu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find_acpi_cpu_topology() - Determine a unique topology value for a given cpu
|
* find_acpi_cpu_topology() - Determine a unique topology value for a given CPU
|
||||||
* @cpu: Kernel logical cpu number
|
* @cpu: Kernel logical CPU number
|
||||||
* @level: The topological level for which we would like a unique ID
|
* @level: The topological level for which we would like a unique ID
|
||||||
*
|
*
|
||||||
* Determine a topology unique ID for each thread/core/cluster/mc_grouping
|
* Determine a topology unique ID for each thread/core/cluster/mc_grouping
|
||||||
@ -596,7 +596,7 @@ int cache_setup_acpi(unsigned int cpu)
|
|||||||
* other levels beyond this use a generated value to uniquely identify
|
* other levels beyond this use a generated value to uniquely identify
|
||||||
* a topological feature.
|
* a topological feature.
|
||||||
*
|
*
|
||||||
* Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
|
* Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
|
||||||
* Otherwise returns a value which represents a unique topological feature.
|
* Otherwise returns a value which represents a unique topological feature.
|
||||||
*/
|
*/
|
||||||
int find_acpi_cpu_topology(unsigned int cpu, int level)
|
int find_acpi_cpu_topology(unsigned int cpu, int level)
|
||||||
@ -606,12 +606,12 @@ int find_acpi_cpu_topology(unsigned int cpu, int level)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* find_acpi_cpu_cache_topology() - Determine a unique cache topology value
|
* find_acpi_cpu_cache_topology() - Determine a unique cache topology value
|
||||||
* @cpu: Kernel logical cpu number
|
* @cpu: Kernel logical CPU number
|
||||||
* @level: The cache level for which we would like a unique ID
|
* @level: The cache level for which we would like a unique ID
|
||||||
*
|
*
|
||||||
* Determine a unique ID for each unified cache in the system
|
* Determine a unique ID for each unified cache in the system
|
||||||
*
|
*
|
||||||
* Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
|
* Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
|
||||||
* Otherwise returns a value which represents a unique topological feature.
|
* Otherwise returns a value which represents a unique topological feature.
|
||||||
*/
|
*/
|
||||||
int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
|
int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
|
||||||
@ -643,17 +643,17 @@ int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find_acpi_cpu_topology_package() - Determine a unique cpu package value
|
* find_acpi_cpu_topology_package() - Determine a unique CPU package value
|
||||||
* @cpu: Kernel logical cpu number
|
* @cpu: Kernel logical CPU number
|
||||||
*
|
*
|
||||||
* Determine a topology unique package ID for the given cpu.
|
* Determine a topology unique package ID for the given CPU.
|
||||||
* This ID can then be used to group peers, which will have matching ids.
|
* This ID can then be used to group peers, which will have matching ids.
|
||||||
*
|
*
|
||||||
* The search terminates when either a level is found with the PHYSICAL_PACKAGE
|
* The search terminates when either a level is found with the PHYSICAL_PACKAGE
|
||||||
* flag set or we reach a root node.
|
* flag set or we reach a root node.
|
||||||
*
|
*
|
||||||
* Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
|
* Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
|
||||||
* Otherwise returns a value which represents the package for this cpu.
|
* Otherwise returns a value which represents the package for this CPU.
|
||||||
*/
|
*/
|
||||||
int find_acpi_cpu_topology_package(unsigned int cpu)
|
int find_acpi_cpu_topology_package(unsigned int cpu)
|
||||||
{
|
{
|
||||||
|
@ -763,18 +763,16 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
|
EXPORT_SYMBOL_GPL(acpi_bus_get_ejd);
|
||||||
|
|
||||||
static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
|
static int acpi_bus_extract_wakeup_device_power_package(struct acpi_device *dev)
|
||||||
struct acpi_device_wakeup *wakeup)
|
|
||||||
{
|
{
|
||||||
|
acpi_handle handle = dev->handle;
|
||||||
|
struct acpi_device_wakeup *wakeup = &dev->wakeup;
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||||
union acpi_object *package = NULL;
|
union acpi_object *package = NULL;
|
||||||
union acpi_object *element = NULL;
|
union acpi_object *element = NULL;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
int err = -ENODATA;
|
int err = -ENODATA;
|
||||||
|
|
||||||
if (!wakeup)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&wakeup->resources);
|
INIT_LIST_HEAD(&wakeup->resources);
|
||||||
|
|
||||||
/* _PRW */
|
/* _PRW */
|
||||||
@ -848,9 +846,9 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
|
|||||||
static bool acpi_wakeup_gpe_init(struct acpi_device *device)
|
static bool acpi_wakeup_gpe_init(struct acpi_device *device)
|
||||||
{
|
{
|
||||||
static const struct acpi_device_id button_device_ids[] = {
|
static const struct acpi_device_id button_device_ids[] = {
|
||||||
{"PNP0C0C", 0},
|
{"PNP0C0C", 0}, /* Power button */
|
||||||
{"PNP0C0D", 0},
|
{"PNP0C0D", 0}, /* Lid */
|
||||||
{"PNP0C0E", 0},
|
{"PNP0C0E", 0}, /* Sleep button */
|
||||||
{"", 0},
|
{"", 0},
|
||||||
};
|
};
|
||||||
struct acpi_device_wakeup *wakeup = &device->wakeup;
|
struct acpi_device_wakeup *wakeup = &device->wakeup;
|
||||||
@ -883,8 +881,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
|
|||||||
if (!acpi_has_method(device->handle, "_PRW"))
|
if (!acpi_has_method(device->handle, "_PRW"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err = acpi_bus_extract_wakeup_device_power_package(device->handle,
|
err = acpi_bus_extract_wakeup_device_power_package(device);
|
||||||
&device->wakeup);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&device->dev, "_PRW evaluation error: %d\n", err);
|
dev_err(&device->dev, "_PRW evaluation error: %d\n", err);
|
||||||
return;
|
return;
|
||||||
@ -895,7 +892,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
|
|||||||
/*
|
/*
|
||||||
* Call _PSW/_DSW object to disable its ability to wake the sleeping
|
* Call _PSW/_DSW object to disable its ability to wake the sleeping
|
||||||
* system for the ACPI device with the _PRW object.
|
* system for the ACPI device with the _PRW object.
|
||||||
* The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
|
* The _PSW object is deprecated in ACPI 3.0 and is replaced by _DSW.
|
||||||
* So it is necessary to call _DSW object first. Only when it is not
|
* So it is necessary to call _DSW object first. Only when it is not
|
||||||
* present will the _PSW object used.
|
* present will the _PSW object used.
|
||||||
*/
|
*/
|
||||||
@ -2260,7 +2257,7 @@ int __init __acpi_probe_device_table(struct acpi_probe_entry *ap_head, int nr)
|
|||||||
|
|
||||||
mutex_lock(&acpi_probe_mutex);
|
mutex_lock(&acpi_probe_mutex);
|
||||||
for (ape = ap_head; nr; ape++, nr--) {
|
for (ape = ap_head; nr; ape++, nr--) {
|
||||||
if (ACPI_COMPARE_NAME(ACPI_SIG_MADT, ape->id)) {
|
if (ACPI_COMPARE_NAMESEG(ACPI_SIG_MADT, ape->id)) {
|
||||||
acpi_probe_count = 0;
|
acpi_probe_count = 0;
|
||||||
acpi_table_parse_madt(ape->type, acpi_match_madt, 0);
|
acpi_table_parse_madt(ape->type, acpi_match_madt, 0);
|
||||||
count += acpi_probe_count;
|
count += acpi_probe_count;
|
||||||
|
@ -28,7 +28,7 @@ EXPORT_SYMBOL(qdf2400_e44_present);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
|
* Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
|
||||||
* Detect them by examining the OEM fields in the SPCR header, similiar to PCI
|
* Detect them by examining the OEM fields in the SPCR header, similar to PCI
|
||||||
* quirk detection in pci_mcfg.c.
|
* quirk detection in pci_mcfg.c.
|
||||||
*/
|
*/
|
||||||
static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
|
static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
|
||||||
|
@ -327,9 +327,9 @@ static struct kobject *hotplug_kobj;
|
|||||||
|
|
||||||
struct acpi_table_attr {
|
struct acpi_table_attr {
|
||||||
struct bin_attribute attr;
|
struct bin_attribute attr;
|
||||||
char name[ACPI_NAME_SIZE];
|
char name[ACPI_NAMESEG_SIZE];
|
||||||
int instance;
|
int instance;
|
||||||
char filename[ACPI_NAME_SIZE+ACPI_INST_SIZE];
|
char filename[ACPI_NAMESEG_SIZE+ACPI_INST_SIZE];
|
||||||
struct list_head node;
|
struct list_head node;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -368,10 +368,10 @@ static int acpi_table_attr_init(struct kobject *tables_obj,
|
|||||||
char instance_str[ACPI_INST_SIZE];
|
char instance_str[ACPI_INST_SIZE];
|
||||||
|
|
||||||
sysfs_attr_init(&table_attr->attr.attr);
|
sysfs_attr_init(&table_attr->attr.attr);
|
||||||
ACPI_MOVE_NAME(table_attr->name, table_header->signature);
|
ACPI_COPY_NAMESEG(table_attr->name, table_header->signature);
|
||||||
|
|
||||||
list_for_each_entry(attr, &acpi_table_attr_list, node) {
|
list_for_each_entry(attr, &acpi_table_attr_list, node) {
|
||||||
if (ACPI_COMPARE_NAME(table_attr->name, attr->name))
|
if (ACPI_COMPARE_NAMESEG(table_attr->name, attr->name))
|
||||||
if (table_attr->instance < attr->instance)
|
if (table_attr->instance < attr->instance)
|
||||||
table_attr->instance = attr->instance;
|
table_attr->instance = attr->instance;
|
||||||
}
|
}
|
||||||
@ -382,8 +382,8 @@ static int acpi_table_attr_init(struct kobject *tables_obj,
|
|||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_MOVE_NAME(table_attr->filename, table_header->signature);
|
ACPI_COPY_NAMESEG(table_attr->filename, table_header->signature);
|
||||||
table_attr->filename[ACPI_NAME_SIZE] = '\0';
|
table_attr->filename[ACPI_NAMESEG_SIZE] = '\0';
|
||||||
if (table_attr->instance > 1 || (table_attr->instance == 1 &&
|
if (table_attr->instance > 1 || (table_attr->instance == 1 &&
|
||||||
!acpi_get_table
|
!acpi_get_table
|
||||||
(table_header->signature, 2, &header))) {
|
(table_header->signature, 2, &header))) {
|
||||||
@ -484,7 +484,7 @@ static int acpi_table_data_init(struct acpi_table_header *th)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_ACPI_DATA_OBJS; i++) {
|
for (i = 0; i < NUM_ACPI_DATA_OBJS; i++) {
|
||||||
if (ACPI_COMPARE_NAME(th->signature, acpi_data_objs[i].name)) {
|
if (ACPI_COMPARE_NAMESEG(th->signature, acpi_data_objs[i].name)) {
|
||||||
data_attr = kzalloc(sizeof(*data_attr), GFP_KERNEL);
|
data_attr = kzalloc(sizeof(*data_attr), GFP_KERNEL);
|
||||||
if (!data_attr)
|
if (!data_attr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -240,8 +240,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
|
|||||||
* On success returns sum of all matching entries for all proc handlers.
|
* On success returns sum of all matching entries for all proc handlers.
|
||||||
* Otherwise, -ENODEV or -EINVAL is returned.
|
* Otherwise, -ENODEV or -EINVAL is returned.
|
||||||
*/
|
*/
|
||||||
static int __init
|
static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
|
||||||
acpi_parse_entries_array(char *id, unsigned long table_size,
|
|
||||||
struct acpi_table_header *table_header,
|
struct acpi_table_header *table_header,
|
||||||
struct acpi_subtable_proc *proc, int proc_num,
|
struct acpi_subtable_proc *proc, int proc_num,
|
||||||
unsigned int max_entries)
|
unsigned int max_entries)
|
||||||
@ -314,8 +313,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
|
|||||||
return errs ? -EINVAL : count;
|
return errs ? -EINVAL : count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init
|
int __init acpi_table_parse_entries_array(char *id,
|
||||||
acpi_table_parse_entries_array(char *id,
|
|
||||||
unsigned long table_size,
|
unsigned long table_size,
|
||||||
struct acpi_subtable_proc *proc, int proc_num,
|
struct acpi_subtable_proc *proc, int proc_num,
|
||||||
unsigned int max_entries)
|
unsigned int max_entries)
|
||||||
@ -346,8 +344,7 @@ acpi_table_parse_entries_array(char *id,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init
|
int __init acpi_table_parse_entries(char *id,
|
||||||
acpi_table_parse_entries(char *id,
|
|
||||||
unsigned long table_size,
|
unsigned long table_size,
|
||||||
int entry_id,
|
int entry_id,
|
||||||
acpi_tbl_entry_handler handler,
|
acpi_tbl_entry_handler handler,
|
||||||
@ -362,8 +359,7 @@ acpi_table_parse_entries(char *id,
|
|||||||
max_entries);
|
max_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init
|
int __init acpi_table_parse_madt(enum acpi_madt_type id,
|
||||||
acpi_table_parse_madt(enum acpi_madt_type id,
|
|
||||||
acpi_tbl_entry_handler handler, unsigned int max_entries)
|
acpi_tbl_entry_handler handler, unsigned int max_entries)
|
||||||
{
|
{
|
||||||
return acpi_table_parse_entries(ACPI_SIG_MADT,
|
return acpi_table_parse_entries(ACPI_SIG_MADT,
|
||||||
@ -670,8 +666,8 @@ static void __init acpi_table_initrd_scan(void)
|
|||||||
table_length = table->length;
|
table_length = table->length;
|
||||||
|
|
||||||
/* Skip RSDT/XSDT which should only be used for override */
|
/* Skip RSDT/XSDT which should only be used for override */
|
||||||
if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_RSDT) ||
|
if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_RSDT) ||
|
||||||
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_XSDT)) {
|
ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_XSDT)) {
|
||||||
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
|
||||||
goto next_table;
|
goto next_table;
|
||||||
}
|
}
|
||||||
@ -725,8 +721,7 @@ static void *amlcode __attribute__ ((weakref("AmlCode")));
|
|||||||
static void *dsdt_amlcode __attribute__ ((weakref("dsdt_aml_code")));
|
static void *dsdt_amlcode __attribute__ ((weakref("dsdt_aml_code")));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
acpi_status
|
acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
|
||||||
acpi_os_table_override(struct acpi_table_header *existing_table,
|
|
||||||
struct acpi_table_header **new_table)
|
struct acpi_table_header **new_table)
|
||||||
{
|
{
|
||||||
if (!existing_table || !new_table)
|
if (!existing_table || !new_table)
|
||||||
@ -788,7 +783,6 @@ static int __init acpi_parse_apic_instance(char *str)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
early_param("acpi_apic_instance", acpi_parse_apic_instance);
|
early_param("acpi_apic_instance", acpi_parse_apic_instance);
|
||||||
|
|
||||||
static int __init acpi_force_table_verification_setup(char *s)
|
static int __init acpi_force_table_verification_setup(char *s)
|
||||||
@ -797,7 +791,6 @@ static int __init acpi_force_table_verification_setup(char *s)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
early_param("acpi_force_table_verification", acpi_force_table_verification_setup);
|
early_param("acpi_force_table_verification", acpi_force_table_verification_setup);
|
||||||
|
|
||||||
static int __init acpi_force_32bit_fadt_addr(char *s)
|
static int __init acpi_force_32bit_fadt_addr(char *s)
|
||||||
@ -807,5 +800,4 @@ static int __init acpi_force_32bit_fadt_addr(char *s)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
early_param("acpi_force_32bit_fadt_addr", acpi_force_32bit_fadt_addr);
|
early_param("acpi_force_32bit_fadt_addr", acpi_force_32bit_fadt_addr);
|
||||||
|
@ -739,6 +739,7 @@ EXPORT_SYMBOL(acpi_dev_found);
|
|||||||
|
|
||||||
struct acpi_dev_match_info {
|
struct acpi_dev_match_info {
|
||||||
const char *dev_name;
|
const char *dev_name;
|
||||||
|
struct acpi_device *adev;
|
||||||
struct acpi_device_id hid[2];
|
struct acpi_device_id hid[2];
|
||||||
const char *uid;
|
const char *uid;
|
||||||
s64 hrv;
|
s64 hrv;
|
||||||
@ -759,6 +760,7 @@ static int acpi_dev_match_cb(struct device *dev, void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
match->dev_name = acpi_dev_name(adev);
|
match->dev_name = acpi_dev_name(adev);
|
||||||
|
match->adev = adev;
|
||||||
|
|
||||||
if (match->hrv == -1)
|
if (match->hrv == -1)
|
||||||
return 1;
|
return 1;
|
||||||
@ -806,18 +808,20 @@ bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
|
|||||||
EXPORT_SYMBOL(acpi_dev_present);
|
EXPORT_SYMBOL(acpi_dev_present);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* acpi_dev_get_first_match_name - Return name of first match of ACPI device
|
* acpi_dev_get_first_match_dev - Return the first match of ACPI device
|
||||||
* @hid: Hardware ID of the device.
|
* @hid: Hardware ID of the device.
|
||||||
* @uid: Unique ID of the device, pass NULL to not check _UID
|
* @uid: Unique ID of the device, pass NULL to not check _UID
|
||||||
* @hrv: Hardware Revision of the device, pass -1 to not check _HRV
|
* @hrv: Hardware Revision of the device, pass -1 to not check _HRV
|
||||||
*
|
*
|
||||||
* Return device name if a matching device was present
|
* Return the first match of ACPI device if a matching device was present
|
||||||
* at the moment of invocation, or NULL otherwise.
|
* at the moment of invocation, or NULL otherwise.
|
||||||
*
|
*
|
||||||
|
* The caller is responsible to call put_device() on the returned device.
|
||||||
|
*
|
||||||
* See additional information in acpi_dev_present() as well.
|
* See additional information in acpi_dev_present() as well.
|
||||||
*/
|
*/
|
||||||
const char *
|
struct acpi_device *
|
||||||
acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv)
|
acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
|
||||||
{
|
{
|
||||||
struct acpi_dev_match_info match = {};
|
struct acpi_dev_match_info match = {};
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
@ -827,9 +831,9 @@ acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv)
|
|||||||
match.hrv = hrv;
|
match.hrv = hrv;
|
||||||
|
|
||||||
dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb);
|
dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb);
|
||||||
return dev ? match.dev_name : NULL;
|
return dev ? match.adev : NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(acpi_dev_get_first_match_name);
|
EXPORT_SYMBOL(acpi_dev_get_first_match_dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* acpi_backlight= handling, this is done here rather then in video_detect.c
|
* acpi_backlight= handling, this is done here rather then in video_detect.c
|
||||||
|
@ -112,7 +112,7 @@ static int video_detect_force_none(const struct dmi_system_id *d)
|
|||||||
static const struct dmi_system_id video_detect_dmi_table[] = {
|
static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||||
/* On Samsung X360, the BIOS will set a flag (VDRV) if generic
|
/* On Samsung X360, the BIOS will set a flag (VDRV) if generic
|
||||||
* ACPI backlight device is used. This flag will definitively break
|
* ACPI backlight device is used. This flag will definitively break
|
||||||
* the backlight interface (even the vendor interface) untill next
|
* the backlight interface (even the vendor interface) until next
|
||||||
* reboot. It's why we should prevent video.ko from being used here
|
* reboot. It's why we should prevent video.ko from being used here
|
||||||
* and we can't rely on a later call to acpi_video_unregister().
|
* and we can't rely on a later call to acpi_video_unregister().
|
||||||
*/
|
*/
|
||||||
@ -141,6 +141,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.callback = video_detect_force_vendor,
|
||||||
|
.ident = "Sony VPCEH3U1E",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These models have a working acpi_video backlight control, and using
|
* These models have a working acpi_video backlight control, and using
|
||||||
|
@ -333,7 +333,7 @@ static int axp288_extcon_probe(struct platform_device *pdev)
|
|||||||
struct axp288_extcon_info *info;
|
struct axp288_extcon_info *info;
|
||||||
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
const char *name;
|
struct acpi_device *adev;
|
||||||
int ret, i, pirq;
|
int ret, i, pirq;
|
||||||
|
|
||||||
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
||||||
@ -357,9 +357,10 @@ static int axp288_extcon_probe(struct platform_device *pdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
name = acpi_dev_get_first_match_name("INT3496", NULL, -1);
|
adev = acpi_dev_get_first_match_dev("INT3496", NULL, -1);
|
||||||
if (name) {
|
if (adev) {
|
||||||
info->id_extcon = extcon_get_extcon_dev(name);
|
info->id_extcon = extcon_get_extcon_dev(acpi_dev_name(adev));
|
||||||
|
put_device(&adev->dev);
|
||||||
if (!info->id_extcon)
|
if (!info->id_extcon)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ static ssize_t ibft_attr_show_acpitbl(void *data, int type, char *buf)
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ISCSI_BOOT_ACPITBL_SIGNATURE:
|
case ISCSI_BOOT_ACPITBL_SIGNATURE:
|
||||||
str += sprintf_string(str, ACPI_NAME_SIZE,
|
str += sprintf_string(str, ACPI_NAMESEG_SIZE,
|
||||||
entry->header->header.signature);
|
entry->header->header.signature);
|
||||||
break;
|
break;
|
||||||
case ISCSI_BOOT_ACPITBL_OEM_ID:
|
case ISCSI_BOOT_ACPITBL_OEM_ID:
|
||||||
|
@ -377,10 +377,20 @@ static void mrfld_irq_init_hw(struct mrfld_gpio *priv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mrfld_gpio_get_pinctrl_dev_name(void)
|
static const char *mrfld_gpio_get_pinctrl_dev_name(struct mrfld_gpio *priv)
|
||||||
{
|
{
|
||||||
const char *dev_name = acpi_dev_get_first_match_name("INTC1002", NULL, -1);
|
struct acpi_device *adev;
|
||||||
return dev_name ? dev_name : "pinctrl-merrifield";
|
const char *name;
|
||||||
|
|
||||||
|
adev = acpi_dev_get_first_match_dev("INTC1002", NULL, -1);
|
||||||
|
if (adev) {
|
||||||
|
name = devm_kstrdup(priv->dev, acpi_dev_name(adev), GFP_KERNEL);
|
||||||
|
acpi_dev_put(adev);
|
||||||
|
} else {
|
||||||
|
name = "pinctrl-merrifield";
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
@ -441,7 +451,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name();
|
pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(priv);
|
||||||
for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) {
|
for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) {
|
||||||
range = &mrfld_gpio_ranges[i];
|
range = &mrfld_gpio_ranges[i];
|
||||||
retval = gpiochip_add_pin_range(&priv->chip,
|
retval = gpiochip_add_pin_range(&priv->chip,
|
||||||
|
@ -230,7 +230,7 @@ static void get_single_name(acpi_handle handle, char *name)
|
|||||||
if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)))
|
if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)))
|
||||||
pr_warn("Failed to get device name from acpi handle\n");
|
pr_warn("Failed to get device name from acpi handle\n");
|
||||||
else {
|
else {
|
||||||
memcpy(name, buffer.pointer, ACPI_NAME_SIZE);
|
memcpy(name, buffer.pointer, ACPI_NAMESEG_SIZE);
|
||||||
kfree(buffer.pointer);
|
kfree(buffer.pointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,8 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev,
|
|||||||
bool acpi_dev_found(const char *hid);
|
bool acpi_dev_found(const char *hid);
|
||||||
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
|
bool acpi_dev_present(const char *hid, const char *uid, s64 hrv);
|
||||||
|
|
||||||
const char *
|
struct acpi_device *
|
||||||
acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv);
|
acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv);
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
|
|
||||||
@ -687,6 +687,10 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
|||||||
adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set);
|
adev->power.states[ACPI_STATE_D3_HOT].flags.explicit_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void acpi_dev_put(struct acpi_device *adev)
|
||||||
|
{
|
||||||
|
put_device(&adev->dev);
|
||||||
|
}
|
||||||
#else /* CONFIG_ACPI */
|
#else /* CONFIG_ACPI */
|
||||||
|
|
||||||
static inline int register_acpi_bus_type(void *bus) { return 0; }
|
static inline int register_acpi_bus_type(void *bus) { return 0; }
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||||
|
|
||||||
#define ACPI_CA_VERSION 0x20190215
|
#define ACPI_CA_VERSION 0x20190405
|
||||||
|
|
||||||
#include <acpi/acconfig.h>
|
#include <acpi/acconfig.h>
|
||||||
#include <acpi/actypes.h>
|
#include <acpi/actypes.h>
|
||||||
|
@ -66,14 +66,14 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
struct acpi_table_header {
|
struct acpi_table_header {
|
||||||
char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
|
char signature[ACPI_NAMESEG_SIZE]; /* ASCII table signature */
|
||||||
u32 length; /* Length of table in bytes, including this header */
|
u32 length; /* Length of table in bytes, including this header */
|
||||||
u8 revision; /* ACPI Specification minor version number */
|
u8 revision; /* ACPI Specification minor version number */
|
||||||
u8 checksum; /* To make sum of entire table == 0 */
|
u8 checksum; /* To make sum of entire table == 0 */
|
||||||
char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
|
char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
|
||||||
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
|
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
|
||||||
u32 oem_revision; /* OEM revision number */
|
u32 oem_revision; /* OEM revision number */
|
||||||
char asl_compiler_id[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */
|
char asl_compiler_id[ACPI_NAMESEG_SIZE]; /* ASCII ASL compiler vendor ID */
|
||||||
u32 asl_compiler_revision; /* ASL compiler version */
|
u32 asl_compiler_revision; /* ASL compiler version */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ typedef u64 acpi_physical_address;
|
|||||||
|
|
||||||
/* Names within the namespace are 4 bytes long */
|
/* Names within the namespace are 4 bytes long */
|
||||||
|
|
||||||
#define ACPI_NAME_SIZE 4
|
#define ACPI_NAMESEG_SIZE 4 /* Fixed by ACPI spec */
|
||||||
#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
|
#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
|
||||||
#define ACPI_PATH_SEPARATOR '.'
|
#define ACPI_PATH_SEPARATOR '.'
|
||||||
|
|
||||||
@ -515,11 +515,11 @@ typedef u64 acpi_integer;
|
|||||||
/* Optimizations for 4-character (32-bit) acpi_name manipulation */
|
/* Optimizations for 4-character (32-bit) acpi_name manipulation */
|
||||||
|
|
||||||
#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
|
#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
|
||||||
#define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b)))
|
#define ACPI_COMPARE_NAMESEG(a,b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b)))
|
||||||
#define ACPI_MOVE_NAME(dest,src) (*ACPI_CAST_PTR (u32, (dest)) = *ACPI_CAST_PTR (u32, (src)))
|
#define ACPI_COPY_NAMESEG(dest,src) (*ACPI_CAST_PTR (u32, (dest)) = *ACPI_CAST_PTR (u32, (src)))
|
||||||
#else
|
#else
|
||||||
#define ACPI_COMPARE_NAME(a,b) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE))
|
#define ACPI_COMPARE_NAMESEG(a,b) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAMESEG_SIZE))
|
||||||
#define ACPI_MOVE_NAME(dest,src) (strncpy (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE))
|
#define ACPI_COPY_NAMESEG(dest,src) (strncpy (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAMESEG_SIZE))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Support for the special RSDP signature (8 characters) */
|
/* Support for the special RSDP signature (8 characters) */
|
||||||
@ -529,7 +529,7 @@ typedef u64 acpi_integer;
|
|||||||
|
|
||||||
/* Support for OEMx signature (x can be any character) */
|
/* Support for OEMx signature (x can be any character) */
|
||||||
#define ACPI_IS_OEM_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_OEM_NAME, 3) &&\
|
#define ACPI_IS_OEM_SIG(a) (!strncmp (ACPI_CAST_PTR (char, (a)), ACPI_OEM_NAME, 3) &&\
|
||||||
strnlen (a, ACPI_NAME_SIZE) == ACPI_NAME_SIZE)
|
strnlen (a, ACPI_NAMESEG_SIZE) == ACPI_NAMESEG_SIZE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Algorithm to obtain access bit width.
|
* Algorithm to obtain access bit width.
|
||||||
|
@ -669,12 +669,14 @@ static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *
|
static inline struct acpi_device *
|
||||||
acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv)
|
acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void acpi_dev_put(struct acpi_device *adev) {}
|
||||||
|
|
||||||
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
|
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -226,7 +226,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
|
|||||||
struct snd_soc_card *card;
|
struct snd_soc_card *card;
|
||||||
struct snd_soc_acpi_mach *mach;
|
struct snd_soc_acpi_mach *mach;
|
||||||
const char *platform_name;
|
const char *platform_name;
|
||||||
const char *i2c_name = NULL;
|
struct acpi_device *adev;
|
||||||
int dai_index = 0;
|
int dai_index = 0;
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -244,10 +244,11 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fixup codec name based on HID */
|
/* fixup codec name based on HID */
|
||||||
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
|
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
|
||||||
if (i2c_name) {
|
if (adev) {
|
||||||
snprintf(codec_name, sizeof(codec_name),
|
snprintf(codec_name, sizeof(codec_name),
|
||||||
"%s%s", "i2c-", i2c_name);
|
"i2c-%s", acpi_dev_name(adev));
|
||||||
|
put_device(&adev->dev);
|
||||||
dailink[dai_index].codec_name = codec_name;
|
dailink[dai_index].codec_name = codec_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
|
|||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct snd_soc_acpi_mach *mach;
|
struct snd_soc_acpi_mach *mach;
|
||||||
const char *platform_name;
|
const char *platform_name;
|
||||||
const char *i2c_name = NULL;
|
struct acpi_device *adev;
|
||||||
struct device *codec_dev;
|
struct device *codec_dev;
|
||||||
int dai_index = 0;
|
int dai_index = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -463,10 +463,11 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fixup codec name based on HID */
|
/* fixup codec name based on HID */
|
||||||
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
|
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
|
||||||
if (i2c_name) {
|
if (adev) {
|
||||||
snprintf(codec_name, sizeof(codec_name),
|
snprintf(codec_name, sizeof(codec_name),
|
||||||
"%s%s", "i2c-", i2c_name);
|
"i2c-%s", acpi_dev_name(adev));
|
||||||
|
put_device(&adev->dev);
|
||||||
byt_cht_es8316_dais[dai_index].codec_name = codec_name;
|
byt_cht_es8316_dais[dai_index].codec_name = codec_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1154,7 +1154,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
|||||||
struct byt_rt5640_private *priv;
|
struct byt_rt5640_private *priv;
|
||||||
struct snd_soc_acpi_mach *mach;
|
struct snd_soc_acpi_mach *mach;
|
||||||
const char *platform_name;
|
const char *platform_name;
|
||||||
const char *i2c_name = NULL;
|
struct acpi_device *adev;
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
int dai_index = 0;
|
int dai_index = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -1178,11 +1178,11 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fixup codec name based on HID */
|
/* fixup codec name based on HID */
|
||||||
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
|
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
|
||||||
if (i2c_name) {
|
if (adev) {
|
||||||
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
|
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
|
||||||
"%s%s", "i2c-", i2c_name);
|
"i2c-%s", acpi_dev_name(adev));
|
||||||
|
put_device(&adev->dev);
|
||||||
byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
|
byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,8 +867,8 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
|
|||||||
struct byt_rt5651_private *priv;
|
struct byt_rt5651_private *priv;
|
||||||
struct snd_soc_acpi_mach *mach;
|
struct snd_soc_acpi_mach *mach;
|
||||||
const char *platform_name;
|
const char *platform_name;
|
||||||
|
struct acpi_device *adev;
|
||||||
struct device *codec_dev;
|
struct device *codec_dev;
|
||||||
const char *i2c_name = NULL;
|
|
||||||
const char *hp_swapped;
|
const char *hp_swapped;
|
||||||
bool is_bytcr = false;
|
bool is_bytcr = false;
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
@ -894,14 +894,16 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fixup codec name based on HID */
|
/* fixup codec name based on HID */
|
||||||
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
|
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
|
||||||
if (!i2c_name) {
|
if (adev) {
|
||||||
|
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
|
||||||
|
"i2c-%s", acpi_dev_name(adev));
|
||||||
|
put_device(&adev->dev);
|
||||||
|
byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
|
||||||
|
} else {
|
||||||
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
|
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
|
|
||||||
"%s%s", "i2c-", i2c_name);
|
|
||||||
byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
|
|
||||||
|
|
||||||
codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
|
codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
|
||||||
byt_rt5651_codec_name);
|
byt_rt5651_codec_name);
|
||||||
|
@ -532,7 +532,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
|||||||
struct snd_soc_acpi_mach *mach;
|
struct snd_soc_acpi_mach *mach;
|
||||||
const char *platform_name;
|
const char *platform_name;
|
||||||
struct cht_mc_private *drv;
|
struct cht_mc_private *drv;
|
||||||
const char *i2c_name = NULL;
|
struct acpi_device *adev;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
bool is_bytcr = false;
|
bool is_bytcr = false;
|
||||||
int dai_index = 0;
|
int dai_index = 0;
|
||||||
@ -573,10 +573,11 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fixup codec name based on HID */
|
/* fixup codec name based on HID */
|
||||||
i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
|
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
|
||||||
if (i2c_name) {
|
if (adev) {
|
||||||
snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name),
|
snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name),
|
||||||
"%s%s", "i2c-", i2c_name);
|
"i2c-%s", acpi_dev_name(adev));
|
||||||
|
put_device(&adev->dev);
|
||||||
cht_dailink[dai_index].codec_name = cht_rt5645_codec_name;
|
cht_dailink[dai_index].codec_name = cht_rt5645_codec_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user