diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-08-05 17:04:01 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2015-08-05 17:04:01 -0300 |
commit | 57f0f512b273f60d52568b8c6b77e17f5636edc0 (patch) | |
tree | 5e910f0e82173f4ef4f51111366a3f1299037a7b /Documentation/acpi |
Initial import
Diffstat (limited to 'Documentation/acpi')
-rw-r--r-- | Documentation/acpi/apei/einj.txt | 177 | ||||
-rw-r--r-- | Documentation/acpi/apei/output_format.txt | 147 | ||||
-rw-r--r-- | Documentation/acpi/debug.txt | 148 | ||||
-rw-r--r-- | Documentation/acpi/dsdt-override.txt | 7 | ||||
-rw-r--r-- | Documentation/acpi/enumeration.txt | 361 | ||||
-rw-r--r-- | Documentation/acpi/gpio-properties.txt | 96 | ||||
-rw-r--r-- | Documentation/acpi/initrd_table_override.txt | 94 | ||||
-rw-r--r-- | Documentation/acpi/method-customizing.txt | 73 | ||||
-rw-r--r-- | Documentation/acpi/method-tracing.txt | 26 | ||||
-rw-r--r-- | Documentation/acpi/namespace.txt | 388 | ||||
-rw-r--r-- | Documentation/acpi/scan_handlers.txt | 77 | ||||
-rw-r--r-- | Documentation/acpi/video_extension.txt | 106 |
12 files changed, 1700 insertions, 0 deletions
diff --git a/Documentation/acpi/apei/einj.txt b/Documentation/acpi/apei/einj.txt new file mode 100644 index 000000000..e550c8b98 --- /dev/null +++ b/Documentation/acpi/apei/einj.txt @@ -0,0 +1,177 @@ + APEI Error INJection + ~~~~~~~~~~~~~~~~~~~~ + +EINJ provides a hardware error injection mechanism. It is very useful +for debugging and testing APEI and RAS features in general. + +You need to check whether your BIOS supports EINJ first. For that, look +for early boot messages similar to this one: + +ACPI: EINJ 0x000000007370A000 000150 (v01 INTEL 00000001 INTL 00000001) + +which shows that the BIOS is exposing an EINJ table - it is the +mechanism through which the injection is done. + +Alternatively, look in /sys/firmware/acpi/tables for an "EINJ" file, +which is a different representation of the same thing. + +It doesn't necessarily mean that EINJ is not supported if those above +don't exist: before you give up, go into BIOS setup to see if the BIOS +has an option to enable error injection. Look for something called WHEA +or similar. Often, you need to enable an ACPI5 support option prior, in +order to see the APEI,EINJ,... functionality supported and exposed by +the BIOS menu. + +To use EINJ, make sure the following are options enabled in your kernel +configuration: + +CONFIG_DEBUG_FS +CONFIG_ACPI_APEI +CONFIG_ACPI_APEI_EINJ + +The EINJ user interface is in <debugfs mount point>/apei/einj. + +The following files belong to it: + +- available_error_type + + This file shows which error types are supported: + + Error Type Value Error Description + ================ ================= + 0x00000001 Processor Correctable + 0x00000002 Processor Uncorrectable non-fatal + 0x00000004 Processor Uncorrectable fatal + 0x00000008 Memory Correctable + 0x00000010 Memory Uncorrectable non-fatal + 0x00000020 Memory Uncorrectable fatal + 0x00000040 PCI Express Correctable + 0x00000080 PCI Express Uncorrectable fatal + 0x00000100 PCI Express Uncorrectable non-fatal + 0x00000200 Platform Correctable + 0x00000400 Platform Uncorrectable non-fatal + 0x00000800 Platform Uncorrectable fatal + + The format of the file contents are as above, except present are only + the available error types. + +- error_type + + Set the value of the error type being injected. Possible error types + are defined in the file available_error_type above. + +- error_inject + + Write any integer to this file to trigger the error injection. Make + sure you have specified all necessary error parameters, i.e. this + write should be the last step when injecting errors. + +- flags + + Present for kernel versions 3.13 and above. Used to specify which + of param{1..4} are valid and should be used by the firmware during + injection. Value is a bitmask as specified in ACPI5.0 spec for the + SET_ERROR_TYPE_WITH_ADDRESS data structure: + + Bit 0 - Processor APIC field valid (see param3 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 + injection specifies just one bit set, and param1 is multiplexed. + +- param1 + + This file is used to set the first error parameter value. Its effect + depends on the error type specified in error_type. For example, if + error type is memory related type, the param1 should be a valid + physical memory address. [Unless "flag" is set - see above] + +- param2 + + Same use as param1 above. For example, if error type is of memory + related type, then param2 should be a physical memory address mask. + Linux requires page or narrower granularity, say, 0xfffffffffffff000. + +- param3 + + Used when the 0x1 bit is set in "flags" to specify the APIC id + +- param4 + Used when the 0x4 bit is set in "flags" to specify target PCIe device + +- notrigger + + The error injection mechanism is a two-step process. First inject the + error, then perform some actions to trigger it. Setting "notrigger" + to 1 skips the trigger phase, which *may* allow the user to cause the + error in some other context by a simple access to the CPU, memory + location, or device that is the target of the error injection. Whether + this actually works depends on what operations the BIOS actually + includes in the trigger phase. + +BIOS versions based on the ACPI 4.0 specification have limited options +in controlling where the errors are injected. Your BIOS may support an +extension (enabled with the param_extension=1 module parameter, or boot +command line einj.param_extension=1). This allows the address and mask +for memory injections to be specified by the param1 and param2 files in +apei/einj. + +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 +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 +signature being injected. The actual data passed is this: + + memory_address = param1; + memory_address_range = param2; + apicid = param3; + pcie_sbdf = param4; + +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 +express errors (type 0x40, 0x80 and 0x100) the segment, bus, device and +function are specified using param1: + + 31 24 23 16 15 11 10 8 7 0 + +-------------------------------------------------+ + | segment | bus | device | function | reserved | + +-------------------------------------------------+ + +Anyway, you get the idea, if there's doubt just take a look at the code +in drivers/acpi/apei/einj.c. + +An ACPI 5.0 BIOS may also allow vendor-specific errors to be injected. +In this case a file named vendor will contain identifying information +from the BIOS that hopefully will allow an application wishing to use +the vendor-specific extension to tell that they are running on a BIOS +that supports it. All vendor extensions have the 0x80000000 bit set in +error_type. A file vendor_flags controls the interpretation of param1 +and param2 (1 = PROCESSOR, 2 = MEMORY, 4 = PCI). See your BIOS vendor +documentation for details (and expect changes to this API if vendors +creativity in using this feature expands beyond our expectations). + + +An error injection example: + +# cd /sys/kernel/debug/apei/einj +# cat available_error_type # See which errors can be injected +0x00000002 Processor Uncorrectable non-fatal +0x00000008 Memory Correctable +0x00000010 Memory Uncorrectable non-fatal +# echo 0x12345000 > param1 # Set memory address for injection +# echo $((-1 << 12)) > param2 # Mask 0xfffffffffffff000 - anywhere in this page +# echo 0x8 > error_type # Choose correctable memory error +# echo 1 > error_inject # Inject now + +You should see something like this in dmesg: + +[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: TSC 0 +[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 +[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 +version 4.0, section 17.5 and ACPI 5.0, section 18.6. diff --git a/Documentation/acpi/apei/output_format.txt b/Documentation/acpi/apei/output_format.txt new file mode 100644 index 000000000..0c49c197c --- /dev/null +++ b/Documentation/acpi/apei/output_format.txt @@ -0,0 +1,147 @@ + 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. diff --git a/Documentation/acpi/debug.txt b/Documentation/acpi/debug.txt new file mode 100644 index 000000000..65bf47c46 --- /dev/null +++ b/Documentation/acpi/debug.txt @@ -0,0 +1,148 @@ + ACPI Debug Output + + +The ACPI CA, the Linux ACPI core, and some ACPI drivers can generate debug +output. This document describes how to use this facility. + +Compile-time configuration +-------------------------- + +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 +kernel. + +Boot- and run-time configuration +-------------------------------- + +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 +acpi.debug_level kernel command line options. After boot, you can use the +debug_layer and debug_level files in /sys/module/acpi/parameters/ to control +the debug messages. + +debug_layer (component) +----------------------- + +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 +bitmask, look for the "#define _COMPONENT" in an ACPI source file. + +You can set the debug_layer mask at boot-time using the acpi.debug_layer +command line argument, and you can change it after boot by writing values +to /sys/module/acpi/parameters/debug_layer. + +The possible components are defined in include/acpi/acoutput.h and +include/acpi/acpi_drivers.h. Reading /sys/module/acpi/parameters/debug_layer +shows the supported mask values, currently these: + + ACPI_UTILITIES 0x00000001 + ACPI_HARDWARE 0x00000002 + ACPI_EVENTS 0x00000004 + ACPI_TABLES 0x00000008 + ACPI_NAMESPACE 0x00000010 + ACPI_PARSER 0x00000020 + ACPI_DISPATCHER 0x00000040 + ACPI_EXECUTER 0x00000080 + ACPI_RESOURCES 0x00000100 + ACPI_CA_DEBUGGER 0x00000200 + ACPI_OS_SERVICES 0x00000400 + ACPI_CA_DISASSEMBLER 0x00000800 + ACPI_COMPILER 0x00001000 + ACPI_TOOLS 0x00002000 + ACPI_BUS_COMPONENT 0x00010000 + ACPI_AC_COMPONENT 0x00020000 + ACPI_BATTERY_COMPONENT 0x00040000 + ACPI_BUTTON_COMPONENT 0x00080000 + ACPI_SBS_COMPONENT 0x00100000 + ACPI_FAN_COMPONENT 0x00200000 + ACPI_PCI_COMPONENT 0x00400000 + ACPI_POWER_COMPONENT 0x00800000 + ACPI_CONTAINER_COMPONENT 0x01000000 + ACPI_SYSTEM_COMPONENT 0x02000000 + ACPI_THERMAL_COMPONENT 0x04000000 + ACPI_MEMORY_DEVICE_COMPONENT 0x08000000 + ACPI_VIDEO_COMPONENT 0x10000000 + ACPI_PROCESSOR_COMPONENT 0x20000000 + +debug_level +----------- + +The "debug_level" is a mask that selects different types of messages, e.g., +those related to initialization, method execution, informational messages, etc. +To build debug_level, look at the level specified in an ACPI_DEBUG_PRINT() +statement. + +The ACPI interpreter uses several different levels, but the Linux +ACPI core and ACPI drivers generally only use ACPI_LV_INFO. + +You can set the debug_level mask at boot-time using the acpi.debug_level +command line argument, and you can change it after boot by writing values +to /sys/module/acpi/parameters/debug_level. + +The possible levels are defined in include/acpi/acoutput.h. Reading +/sys/module/acpi/parameters/debug_level shows the supported mask values, +currently these: + + ACPI_LV_INIT 0x00000001 + ACPI_LV_DEBUG_OBJECT 0x00000002 + ACPI_LV_INFO 0x00000004 + ACPI_LV_INIT_NAMES 0x00000020 + ACPI_LV_PARSE 0x00000040 + ACPI_LV_LOAD 0x00000080 + ACPI_LV_DISPATCH 0x00000100 + ACPI_LV_EXEC 0x00000200 + ACPI_LV_NAMES 0x00000400 + ACPI_LV_OPREGION 0x00000800 + ACPI_LV_BFIELD 0x00001000 + ACPI_LV_TABLES 0x00002000 + ACPI_LV_VALUES 0x00004000 + ACPI_LV_OBJECTS 0x00008000 + ACPI_LV_RESOURCES 0x00010000 + ACPI_LV_USER_REQUESTS 0x00020000 + ACPI_LV_PACKAGE 0x00040000 + ACPI_LV_ALLOCATIONS 0x00100000 + ACPI_LV_FUNCTIONS 0x00200000 + ACPI_LV_OPTIMIZATIONS 0x00400000 + ACPI_LV_MUTEX 0x01000000 + ACPI_LV_THREADS 0x02000000 + ACPI_LV_IO 0x04000000 + ACPI_LV_INTERRUPTS 0x08000000 + ACPI_LV_AML_DISASSEMBLE 0x10000000 + ACPI_LV_VERBOSE_INFO 0x20000000 + ACPI_LV_FULL_TABLES 0x40000000 + ACPI_LV_EVENTS 0x80000000 + +Examples +-------- + +For example, drivers/acpi/bus.c contains this: + + #define _COMPONENT ACPI_BUS_COMPONENT + ... + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n")); + +To turn on this message, set the ACPI_BUS_COMPONENT bit in acpi.debug_layer +and the ACPI_LV_INFO bit in acpi.debug_level. (The ACPI_DEBUG_PRINT +statement uses ACPI_DB_INFO, which is macro based on the ACPI_LV_INFO +definition.) + +Enable all AML "Debug" output (stores to the Debug object while interpreting +AML) during boot: + + acpi.debug_layer=0xffffffff acpi.debug_level=0x2 + +Enable PCI and PCI interrupt routing debug messages: + + acpi.debug_layer=0x400000 acpi.debug_level=0x4 + +Enable all ACPI hardware-related messages: + + acpi.debug_layer=0x2 acpi.debug_level=0xffffffff + +Enable all ACPI_DB_INFO messages after boot: + + # echo 0x4 > /sys/module/acpi/parameters/debug_level + +Show all valid component values: + + # cat /sys/module/acpi/parameters/debug_layer diff --git a/Documentation/acpi/dsdt-override.txt b/Documentation/acpi/dsdt-override.txt new file mode 100644 index 000000000..784841caa --- /dev/null +++ b/Documentation/acpi/dsdt-override.txt @@ -0,0 +1,7 @@ +Linux supports a method of overriding the BIOS DSDT: + +CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel. + +When to use this method is described in detail on the +Linux/ACPI home page: +https://01.org/linux-acpi/documentation/overriding-dsdt diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt new file mode 100644 index 000000000..15dfce708 --- /dev/null +++ b/Documentation/acpi/enumeration.txt @@ -0,0 +1,361 @@ +ACPI based device enumeration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ACPI 5 introduced a set of new resources (UartTSerialBus, I2cSerialBus, +SpiSerialBus, GpioIo and GpioInt) which can be used in enumerating slave +devices behind serial bus controllers. + +In addition we are starting to see peripherals integrated in the +SoC/Chipset to appear only in ACPI namespace. These are typically devices +that are accessed through memory-mapped registers. + +In order to support this and re-use the existing drivers as much as +possible we decided to do following: + + o Devices that have no bus connector resource are represented as + platform devices. + + o Devices behind real busses where there is a connector resource + are represented as struct spi_device or struct i2c_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 +resources) this implementation follows the Device Tree way as much as +possible. + +The ACPI implementation enumerates devices behind busses (platform, SPI and +I2C), creates the physical devices and binds them to their ACPI handle in +the ACPI namespace. + +This means that when ACPI_HANDLE(dev) returns non-NULL the device was +enumerated from ACPI namespace. This handle can be used to extract other +device-specific configuration. There is an example of this below. + +Platform bus support +~~~~~~~~~~~~~~~~~~~~ +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 +for the device and add supported ACPI IDs. If this same IP-block is used on +some other non-ACPI platform, the driver might work out of the box or needs +some minor changes. + +Adding ACPI support for an existing driver should be pretty +straightforward. Here is the simplest example: + + #ifdef CONFIG_ACPI + static struct acpi_device_id mydrv_acpi_match[] = { + /* ACPI IDs here */ + { } + }; + MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match); + #endif + + static struct platform_driver my_driver = { + ... + .driver = { + .acpi_match_table = ACPI_PTR(mydrv_acpi_match), + }, + }; + +If the driver needs to perform more complex initialization like getting and +configuring GPIOs it can get its ACPI handle and extract this information +from ACPI tables. + +DMA support +~~~~~~~~~~~ +DMA controllers enumerated via ACPI should be registered in the system to +provide generic access to their resources. For example, a driver that would +like to be accessible to slave devices via generic API call +dma_request_slave_channel() must register itself at the end of the probe +function like this: + + err = devm_acpi_dma_controller_register(dev, xlate_func, dw); + /* Handle the error if it's not a case of !CONFIG_ACPI */ + +and implement custom xlate function if needed (usually acpi_dma_simple_xlate() +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 +could look like: + + #ifdef CONFIG_ACPI + struct filter_args { + /* Provide necessary information for the filter_func */ + ... + }; + + static bool filter_func(struct dma_chan *chan, void *param) + { + /* Choose the proper channel */ + ... + } + + static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec, + struct acpi_dma *adma) + { + dma_cap_mask_t cap; + struct filter_args args; + + /* Prepare arguments for filter_func */ + ... + return dma_request_channel(cap, filter_func, &args); + } + #else + static struct dma_chan *xlate_func(struct acpi_dma_spec *dma_spec, + struct acpi_dma *adma) + { + return NULL; + } + #endif + +dma_request_slave_channel() will call xlate_func() for each registered DMA +controller. In the xlate function the proper channel must be chosen based on +information in struct acpi_dma_spec and the properties of the controller +provided by struct acpi_dma. + +Clients must call dma_request_slave_channel() with the string parameter that +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 +below shows a layout: + + Device (I2C0) + { + ... + Method (_CRS, 0, NotSerialized) + { + Name (DBUF, ResourceTemplate () + { + FixedDMA (0x0018, 0x0004, Width32bit, _Y48) + FixedDMA (0x0019, 0x0005, Width32bit, ) + }) + ... + } + } + +So, the FixedDMA with request line 0x0018 is "tx" and next one is "rx" in +this example. + +In robust cases the client unfortunately needs to call +acpi_dma_request_slave_chan_by_index() directly and therefore choose the +specific FixedDMA resource by its index. + +SPI serial bus support +~~~~~~~~~~~~~~~~~~~~~~ +Slave devices behind SPI bus have SpiSerialBus resource attached to them. +This is extracted automatically by the SPI core and the slave devices are +enumerated once spi_register_master() is called by the bus driver. + +Here is what the ACPI namespace for a SPI slave might look like: + + Device (EEP0) + { + Name (_ADR, 1) + Name (_CID, Package() { + "ATML0025", + "AT25", + }) + ... + Method (_CRS, 0, NotSerialized) + { + SPISerialBus(1, PolarityLow, FourWireMode, 8, + ControllerInitiated, 1000000, ClockPolarityLow, + ClockPhaseFirst, "\\_SB.PCI0.SPI1",) + } + ... + +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 +to at25 SPI eeprom driver (this is meant for the above ACPI snippet): + + #ifdef CONFIG_ACPI + static struct acpi_device_id at25_acpi_match[] = { + { "AT25", 0 }, + { }, + }; + MODULE_DEVICE_TABLE(acpi, at25_acpi_match); + #endif + + static struct spi_driver at25_driver = { + .driver = { + ... + .acpi_match_table = ACPI_PTR(at25_acpi_match), + }, + }; + +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 +passing those. One idea is to return this in _DSM method like: + + Device (EEP0) + { + ... + Method (_DSM, 4, NotSerialized) + { + Store (Package (6) + { + "byte-len", 1024, + "addr-mode", 2, + "page-size, 32 + }, Local0) + + // Check UUIDs etc. + + Return (Local0) + } + +Then the at25 SPI driver can get this configuration by calling _DSM on its +ACPI handle like: + + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_object_list input; + acpi_status status; + + /* Fill in the input buffer */ + + status = acpi_evaluate_object(ACPI_HANDLE(&spi->dev), "_DSM", + &input, &output); + if (ACPI_FAILURE(status)) + /* Handle the error */ + + /* Extract the data here */ + + kfree(output.pointer); + +I2C serial bus support +~~~~~~~~~~~~~~~~~~~~~~ +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 +any slave devices behind the controller device once the adapter is +registered. + +Below is an example of how to add ACPI support to the existing mpu3050 +input driver: + + #ifdef CONFIG_ACPI + static struct acpi_device_id mpu3050_acpi_match[] = { + { "MPU3050", 0 }, + { }, + }; + MODULE_DEVICE_TABLE(acpi, mpu3050_acpi_match); + #endif + + static struct i2c_driver mpu3050_i2c_driver = { + .driver = { + .name = "mpu3050", + .owner = THIS_MODULE, + .pm = &mpu3050_pm, + .of_match_table = mpu3050_of_match, + .acpi_match_table = ACPI_PTR(mpu3050_acpi_match), + }, + .probe = mpu3050_probe, + .remove = mpu3050_remove, + .id_table = mpu3050_ids, + }; + +GPIO support +~~~~~~~~~~~~ +ACPI 5 introduced two new resources to describe GPIO connections: GpioIo +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 +Specific Data) which made it possible to name the GPIOs among other things. + +For example: + +Device (DEV) +{ + 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 + } + + // Interrupt for the device + 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 () + { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + 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" +specifies the path to the controller. In order to use these GPIOs in Linux +we need to translate them to the corresponding Linux GPIO descriptors. + +There is a standard GPIO API for that and is documented in +Documentation/gpio/. + +In the above example we can get the corresponding two GPIO descriptors with +a code like this: + + #include <linux/gpio/consumer.h> + ... + + struct gpio_desc *irq_desc, *power_desc; + + irq_desc = gpiod_get(dev, "irq"); + if (IS_ERR(irq_desc)) + /* handle error */ + + power_desc = gpiod_get(dev, "power"); + if (IS_ERR(power_desc)) + /* handle error */ + + /* Now we can use the GPIO descriptors */ + +There are also devm_* versions of these functions which release the +descriptors once the device is released. + +See Documentation/acpi/gpio-properties.txt for more information about the +_DSD binding related to GPIOs. + +MFD devices +~~~~~~~~~~~ +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 +parts of the ACPI namespace that relate to them. In the Linux MFD subsystem +we provide two ways: + + o The children share the parent ACPI handle. + o 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 +resulting child platform device will have its ACPI_COMPANION() set to point +to the parent device. + +If the ACPI namespace has a device that we can match using an ACPI id, +the id should be set like: + + static struct mfd_cell my_subdevice_cell = { + .name = "my_subdevice", + /* set the resources relative to the parent */ + .acpi_pnpid = "XYZ0001", + }; + +The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under +the MFD device and if found, that ACPI companion device is bound to the +resulting child platform device. diff --git a/Documentation/acpi/gpio-properties.txt b/Documentation/acpi/gpio-properties.txt new file mode 100644 index 000000000..f35dad11f --- /dev/null +++ b/Documentation/acpi/gpio-properties.txt @@ -0,0 +1,96 @@ +_DSD Device Properties Related to GPIO +-------------------------------------- + +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 +by _CRS. Previously, we were only able to use an integer index to find +the corresponding GPIO, which is pretty error prone (it depends on +the _CRS output ordering, for example). + +With _DSD we can now query GPIOs using a name instead of an integer +index, like the ASL example below shows: + + // Bluetooth device with reset and shutdown GPIOs + Device (BTH) + { + Name (_HID, ...) + + Name (_CRS, ResourceTemplate () + { + GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, + "\\_SB.GPO0", 0, ResourceConsumer) {15} + GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionInputOnly, + "\\_SB.GPO0", 0, ResourceConsumer) {27, 31} + }) + + Name (_DSD, Package () + { + ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package () {"reset-gpio", Package() {^BTH, 1, 1, 0 }}, + Package () {"shutdown-gpio", Package() {^BTH, 0, 0, 0 }}, + } + }) + } + +The format of the supported GPIO property is: + + Package () { "name", Package () { ref, index, pin, active_low }} + + ref - The device that has _CRS containing GpioIo()/GpioInt() resources, + typically this is the device itself (BTH in our case). + index - 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 +active low or high, the "active_low" argument can be used here. Setting +it to 1 marks the GPIO as active low. + +In our Bluetooth example the "reset-gpio" refers to the second GpioIo() +resource, second pin in that resource with the GPIO number of 31. + +ACPI GPIO Mappings Provided by Drivers +-------------------------------------- + +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 +them. + +In those cases ACPI device identification objects, _HID, _CID, _CLS, _SUB, _HRV, +available to the driver can be used to identify the device and that is supposed +to be sufficient to determine the meaning and purpose of all of the GPIO lines +listed by the GpioIo()/GpioInt() resources returned by _CRS. In other words, +the driver is supposed to know what to use the GpioIo()/GpioInt() resources for +once it has identified the device. Having done that, it can simply assign names +to the GPIO lines it is going to use and provide the GPIO subsystem with a +mapping between those names and the ACPI GPIO resources corresponding to them. + +To do that, the driver needs to define a mapping table as a NULL-terminated +array of struct acpi_gpio_mapping objects that each contain a name, a pointer +to an array of line data (struct acpi_gpio_params) objects and the size of that +array. Each struct acpi_gpio_params object consists of three fields, +crs_entry_index, line_index, active_low, representing the index of the target +GpioIo()/GpioInt() resource in _CRS starting from zero, the index of the target +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. + +For the example Bluetooth device discussed previously the data structures in +question would look like this: + +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_mapping bluetooth_acpi_gpios[] = { + { "reset-gpio", &reset_gpio, 1 }, + { "shutdown-gpio", &shutdown_gpio, 1 }, + { }, +}; + +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 +pointed to by its first argument. That should be done in the driver's .probe() +routine. On removal, the driver should unregister its GPIO mapping table by +calling acpi_dev_remove_driver_gpios() on the ACPI device object where that +table was previously registered. diff --git a/Documentation/acpi/initrd_table_override.txt b/Documentation/acpi/initrd_table_override.txt new file mode 100644 index 000000000..35c3f5415 --- /dev/null +++ b/Documentation/acpi/initrd_table_override.txt @@ -0,0 +1,94 @@ +Overriding 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_INITRD_TABLE_OVERRIDE compile option is true, it is possible to +override nearly any ACPI table provided by the BIOS with an instrumented, +modified one. + +For a full list of ACPI tables that can be overridden, take a look at +the char *table_sigs[MAX_ACPI_SIGNATURE]; definition in drivers/acpi/osl.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 +------------------- + +Please keep in mind that this is a debug option. +ACPI tables should not get overridden for productive use. +If BIOS ACPI tables are overridden the kernel will get tainted with the +TAINT_OVERRIDDEN_ACPI_TABLE flag. +Complain to your platform/BIOS vendor if you find a bug which is so sever +that a workaround is not accepted in the Linux kernel. + +Still, it can and should be enabled in any kernel, because: + - There is no functional change with not instrumented initrds + - It provides a powerful feature to easily debug and test ACPI BIOS table + compatibility with the Linux kernel. + + +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) +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. +# 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 dsdt.aml kernel/firmware/acpi +# A maximum of: #define ACPI_OVERRIDE_TABLES 10 +# 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 +# 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 +# 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 diff --git a/Documentation/acpi/method-customizing.txt b/Documentation/acpi/method-customizing.txt new file mode 100644 index 000000000..5f55373dd --- /dev/null +++ b/Documentation/acpi/method-customizing.txt @@ -0,0 +1,73 @@ +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. +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) + { + External (ACON) + + 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. + And remember to use "External" to declare external objects. + e) assemble the file to generate the AML code of the method. + e.g. "iasl psr.asl" (psr.aml is generated as a result) + 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 overrided 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). diff --git a/Documentation/acpi/method-tracing.txt b/Documentation/acpi/method-tracing.txt new file mode 100644 index 000000000..f6efb1ea5 --- /dev/null +++ b/Documentation/acpi/method-tracing.txt @@ -0,0 +1,26 @@ +/sys/module/acpi/parameters/: + +trace_method_name + The AML method name that the user wants to trace + +trace_debug_layer + The temporary debug_layer used when tracing the method. + Using 0xffffffff by default if it is 0. + +trace_debug_level + The temporary debug_level used when tracing the method. + Using 0x00ffffff by default if it is 0. + +trace_state + The status of the tracing feature. + + "enabled" means this feature is enabled + and the AML method is traced every time it's executed. + + "1" means this feature is enabled and the AML method + will only be traced during the next execution. + + "disabled" means this feature is disabled. + Users can enable/disable this debug tracing feature by + "echo string > /sys/module/acpi/parameters/trace_state". + "string" should be one of "enable", "disable" and "1". diff --git a/Documentation/acpi/namespace.txt b/Documentation/acpi/namespace.txt new file mode 100644 index 000000000..1860cb386 --- /dev/null +++ b/Documentation/acpi/namespace.txt @@ -0,0 +1,388 @@ +ACPI Device Tree - Representation of ACPI Namespace + +Copyright (C) 2013, Intel Corporation +Author: Lv Zheng <lv.zheng@intel.com> + + +Abstract: + +The Linux ACPI subsystem converts ACPI namespace objects into a Linux +device tree under the /sys/devices/LNXSYSTEM:00 and updates it upon +receiving ACPI hotplug notification events. For each device object in this +hierarchy there is a corresponding symbolic link in the +/sys/bus/acpi/devices. +This document illustrates the structure of the ACPI device tree. + + +Credit: + +Thanks for the help from Zhang Rui <rui.zhang@intel.com> and Rafael J. +Wysocki <rafael.j.wysocki@intel.com>. + + +1. ACPI Definition Blocks + + 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). + + 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. + 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' + - '9', '_'. + 4. Names starting with '_' are reserved by the ACPI specification. + 5. The '\' symbol represents the root of the namespace (i.e. names + prepended with '\' are relative to the namespace root). + 6. The '^' symbol represents the parent of the current namespace node + (i.e. names prepended with '^' are relative to the parent of the + current namespace node). + + The figure below shows an example ACPI namespace. + + +------+ + | \ | Root + +------+ + | + | +------+ + +-| _PR | Scope(_PR): the processor namespace + | +------+ + | | + | | +------+ + | +-| CPU0 | Processor(CPU0): the first processor + | +------+ + | + | +------+ + +-| _SB | Scope(_SB): the system bus namespace + | +------+ + | | + | | +------+ + | +-| LID0 | Device(LID0); the lid device + | | +------+ + | | | + | | | +------+ + | | +-| _HID | Name(_HID, "PNP0C0D"): the hardware ID + | | | +------+ + | | | + | | | +------+ + | | +-| _STA | Method(_STA): the status control method + | | +------+ + | | + | | +------+ + | +-| PCI0 | Device(PCI0); the PCI root bridge + | +------+ + | | + | | +------+ + | +-| _HID | Name(_HID, "PNP0A08"): the hardware ID + | | +------+ + | | + | | +------+ + | +-| _CID | Name(_CID, "PNP0A03"): the compatible ID + | | +------+ + | | + | | +------+ + | +-| RP03 | Scope(RP03): the PCI0 power scope + | | +------+ + | | | + | | | +------+ + | | +-| PXP3 | PowerResource(PXP3): the PCI0 power resource + | | +------+ + | | + | | +------+ + | +-| GFX0 | Device(GFX0): the graphics adapter + | +------+ + | | + | | +------+ + | +-| _ADR | Name(_ADR, 0x00020000): the PCI bus address + | | +------+ + | | + | | +------+ + | +-| DD01 | Device(DD01): the LCD output device + | +------+ + | | + | | +------+ + | +-| _BCL | Method(_BCL): the backlight control method + | +------+ + | + | +------+ + +-| _TZ | Scope(_TZ): the thermal zone namespace + | +------+ + | | + | | +------+ + | +-| FN00 | PowerResource(FN00): the FAN0 power resource + | | +------+ + | | + | | +------+ + | +-| FAN0 | Device(FAN0): the FAN0 cooling device + | | +------+ + | | | + | | | +------+ + | | +-| _HID | Name(_HID, "PNP0A0B"): the hardware ID + | | +------+ + | | + | | +------+ + | +-| TZ00 | ThermalZone(TZ00); the FAN thermal zone + | +------+ + | + | +------+ + +-| _GPE | Scope(_GPE): the GPE namespace + +------+ + + Figure 2. Example ACPI Namespace + + +3. Linux ACPI Device Objects + + The Linux kernel's core ACPI subsystem creates struct acpi_device + objects for ACPI namespace objects representing devices, power resources + processors, thermal zones. Those objects are exported to user space via + 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 + ACPI namespace representation of the given object and 'instance' is used + for distinguishing different object of the same 'bus_id' (it is + two-digit decimal representation of an unsigned integer). + + The value of 'bus_id' depends on the type of the object whose name it is + part of as listed in the table below. + + +---+-----------------+-------+----------+ + | | Object/Feature | Table | bus_id | + +---+-----------------+-------+----------+ + | N | Root | xSDT | LNXSYSTM | + +---+-----------------+-------+----------+ + | N | Device | xSDT | _HID | + +---+-----------------+-------+----------+ + | N | Processor | xSDT | LNXCPU | + +---+-----------------+-------+----------+ + | N | ThermalZone | xSDT | LNXTHERM | + +---+-----------------+-------+----------+ + | N | PowerResource | xSDT | LNXPOWER | + +---+-----------------+-------+----------+ + | N | Other Devices | xSDT | device | + +---+-----------------+-------+----------+ + | F | PWR_BUTTON | FADT | LNXPWRBN | + +---+-----------------+-------+----------+ + | F | SLP_BUTTON | FADT | LNXSLPBN | + +---+-----------------+-------+----------+ + | M | Video Extension | xSDT | LNXVIDEO | + +---+-----------------+-------+----------+ + | M | ATA Controller | xSDT | LNXIOBAY | + +---+-----------------+-------+----------+ + | M | Docking Station | xSDT | LNXDOCK | + +---+-----------------+-------+----------+ + + Table 1. ACPI Namespace Objects Mapping + + The following rules apply when creating struct acpi_device objects on + the basis of the contents of ACPI System Description Tables (as + indicated by the letter in the first column and the notation in the + second column of the table above): + N: + 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 + directory in sysfs will contain the 'path' attribute whose value is + the full path to the node from the namespace root. + F: + The struct acpi_device object is created for a fixed hardware + feature (as indicated by the fixed feature flag's name in the second + column), so its sysfs directory will not contain the 'path' + attribute. + M: + The struct acpi_device object is created for an ACPI namespace node + with specific control methods (as indicated by the ACPI defined + device's type in the second column). The 'path' attribute containing + its namespace path will be present in its sysfs directory. For + example, if the _BCL method is present for an ACPI namespace node, a + struct acpi_device object with LNXVIDEO 'bus_id' will be created for + it. + + The third column of the above table indicates which ACPI System + Description Tables contain information used for the creation of the + struct acpi_device objects represented by the given row (xSDT means DSDT + or SSDT). + + The forth column of the above table indicates the 'bus_id' generation + rule of the struct acpi_device object: + _HID: + _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 + the corresponding ACPI namespace node. The object's sysfs directory + will then contain the 'hid' and 'modalias' attributes that can be + used to retrieve the _HID and _CIDs of that object. + LNXxxxxx: + The 'modalias' attribute is also present for struct acpi_device + objects having bus_id of the "LNXxxxxx" form (pseudo devices), in + which cases it contains the bus_id string itself. + device: + 'device' in the last column of the table indicates that the object's + bus_id cannot be determined from _HID/_CID of the corresponding + ACPI namespace node, although that object represents a device (for + example, it may be a PCI device with _ADR defined and without _HID + or _CID). In that case the string 'device' will be used as the + object's bus_id. + + +4. Linux ACPI Physical Device Glue + + ACPI device (i.e. struct acpi_device) objects may be linked to other + objects in the Linux' device hierarchy that represent "physical" devices + (for example, devices on the PCI bus). If that happens, it means that + the ACPI device object is a "companion" of a device otherwise + represented in a different way and is used (1) to provide configuration + 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 + control methods. One ACPI device object may be linked this way to + multiple "physical" devices. + + If an ACPI device object is linked to a "physical" device, its sysfs + directory contains the "physical_node" symbolic link to the sysfs + directory of the target device object. In turn, the target device's + sysfs directory will then contain the "firmware_node" symbolic link to + the sysfs directory of the companion ACPI device object. + The linking mechanism relies on device identification provided by the + ACPI namespace. For example, if there's an ACPI namespace object + representing a PCI device (i.e. a device object under an ACPI namespace + object representing a PCI bridge) whose _ADR returns 0x00020000 and the + bus number of the parent PCI bridge is 0, the sysfs directory + representing the struct acpi_device object created for that ACPI + namespace object will contain the 'physical_node' symbolic link to the + /sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the + corresponding PCI device. + + The linking mechanism is generally bus-specific. The core of its + implementation is located in the drivers/acpi/glue.c file, but there are + complementary parts depending on the bus types in question located + elsewhere. For example, the PCI-specific part of it is located in + drivers/pci/pci-acpi.c. + + +5. Example Linux ACPI Device Tree + + The sysfs hierarchy of struct acpi_device objects corresponding to the + example ACPI namespace illustrated in Figure 2 with the addition of + fixed PWR_BUTTON/SLP_BUTTON devices is shown below. + + +--------------+---+-----------------+ + | LNXSYSTEM:00 | \ | acpi:LNXSYSTEM: | + +--------------+---+-----------------+ + | + | +-------------+-----+----------------+ + +-| LNXPWRBN:00 | N/A | acpi:LNXPWRBN: | + | +-------------+-----+----------------+ + | + | +-------------+-----+----------------+ + +-| LNXSLPBN:00 | N/A | acpi:LNXSLPBN: | + | +-------------+-----+----------------+ + | + | +-----------+------------+--------------+ + +-| LNXCPU:00 | \_PR_.CPU0 | acpi:LNXCPU: | + | +-----------+------------+--------------+ + | + | +-------------+-------+----------------+ + +-| LNXSYBUS:00 | \_SB_ | acpi:LNXSYBUS: | + | +-------------+-------+----------------+ + | | + | | +- - - - - - - +- - - - - - +- - - - - - - -+ + | +-| PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: | + | | +- - - - - - - +- - - - - - +- - - - - - - -+ + | | + | | +------------+------------+-----------------------+ + | +-| PNP0A08:00 | \_SB_.PCI0 | acpi:PNP0A08:PNP0A03: | + | +------------+------------+-----------------------+ + | | + | | +-----------+-----------------+-----+ + | +-| device:00 | \_SB_.PCI0.RP03 | N/A | + | | +-----------+-----------------+-----+ + | | | + | | | +-------------+----------------------+----------------+ + | | +-| LNXPOWER:00 | \_SB_.PCI0.RP03.PXP3 | acpi:LNXPOWER: | + | | +-------------+----------------------+----------------+ + | | + | | +-------------+-----------------+----------------+ + | +-| LNXVIDEO:00 | \_SB_.PCI0.GFX0 | acpi:LNXVIDEO: | + | +-------------+-----------------+----------------+ + | | + | | +-----------+-----------------+-----+ + | +-| device:01 | \_SB_.PCI0.DD01 | N/A | + | +-----------+-----------------+-----+ + | + | +-------------+-------+----------------+ + +-| LNXSYBUS:01 | \_TZ_ | acpi:LNXSYBUS: | + +-------------+-------+----------------+ + | + | +-------------+------------+----------------+ + +-| LNXPOWER:0a | \_TZ_.FN00 | acpi:LNXPOWER: | + | +-------------+------------+----------------+ + | + | +------------+------------+---------------+ + +-| PNP0C0B:00 | \_TZ_.FAN0 | acpi:PNP0C0B: | + | +------------+------------+---------------+ + | + | +-------------+------------+----------------+ + +-| LNXTHERM:00 | \_TZ_.TZ00 | acpi:LNXTHERM: | + +-------------+------------+----------------+ + + Figure 3. Example Linux ACPI Device Tree + + 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 + ACPI namespace object, as returned by the object's 'path' + sysfs attribute. + 3. 'modalias' is the value of the object's 'modalias' sysfs + attribute (as described earlier in this document). + NOTE: N/A indicates the device object does not have the 'path' or the + 'modalias' attribute. diff --git a/Documentation/acpi/scan_handlers.txt b/Documentation/acpi/scan_handlers.txt new file mode 100644 index 000000000..3246ccf15 --- /dev/null +++ b/Documentation/acpi/scan_handlers.txt @@ -0,0 +1,77 @@ +ACPI Scan Handlers + +Copyright (C) 2012, Intel Corporation +Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> + +During system initialization and ACPI-based device hot-add, the ACPI namespace +is scanned in search of device objects that generally represent various pieces +of hardware. This causes a struct acpi_device object to be created and +registered with the driver core for every device object in the ACPI namespace +and the hierarchy of those struct acpi_device objects reflects the namespace +layout (i.e. parent device objects in the namespace are represented by parent +struct acpi_device objects and analogously for their children). Those struct +acpi_device objects are referred to as "device nodes" in what follows, but they +should not be confused with struct device_node objects used by the Device Trees +parsing code (although their role is analogous to the role of those objects). + +During ACPI-based device hot-remove device nodes representing pieces of hardware +being removed are unregistered and deleted. + +The core ACPI namespace scanning code in drivers/acpi/scan.c carries out basic +initialization of device nodes, such as retrieving common configuration +information from the device objects represented by them and populating them with +appropriate data, but some of them require additional handling after they have +been registered. For example, if the given device node represents a PCI host +bridge, its registration should cause the PCI bus under that bridge to be +enumerated and PCI devices on that bus to be registered with the driver core. +Similarly, if the device node represents a PCI interrupt link, it is necessary +to configure that link so that the kernel can use it. + +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 +basis of the device node's hardware ID (HID). They are performed by objects +called ACPI scan handlers represented by the following structure: + +struct acpi_scan_handler { + const struct acpi_device_id *ids; + struct list_head list_node; + int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id); + void (*detach)(struct acpi_device *dev); +}; + +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 +maintained by the ACPI core and the .attach() and .detach() callbacks are +executed, respectively, after registration of new device nodes and before +unregistration of device nodes the handler attached to previously. + +The namespace scanning function, acpi_bus_scan(), first registers all of the +device nodes in the given namespace scope with the driver core. Then, it tries +to match a scan handler against each of them using the ids arrays of the +available scan handlers. If a matching scan handler is found, its .attach() +callback is executed for the given device node. If that callback returns 1, +that means that the handler has claimed the device node and is now responsible +for carrying out any additional configuration tasks related to it. It also will +be responsible for preparing the device node for unregistration in that case. +The device node's handler field is then populated with the address of the scan +handler that has claimed it. + +If the .attach() callback returns 0, it means that the device node is not +interesting to the given scan handler and may be matched against the next scan +handler in the list. If it returns a (negative) error code, that means that +the namespace scan should be terminated due to a serious error. The error code +returned should then reflect the type of the error. + +The namespace trimming function, acpi_bus_trim(), first executes .detach() +callbacks from the scan handlers of all device nodes in the given namespace +scope (if they have scan handlers). Next, it unregisters all of the device +nodes in that scope. + +ACPI scan handlers can be added to the list maintained by the ACPI core with the +help of the acpi_scan_add_handler() function taking a pointer to the new scan +handler as an argument. The order in which scan handlers are added to the list +is the order in which they are matched against device nodes during namespace +scans. + +All scan handles must be added to the list before acpi_bus_scan() is run for the +first time and they cannot be removed from it. diff --git a/Documentation/acpi/video_extension.txt b/Documentation/acpi/video_extension.txt new file mode 100644 index 000000000..78b32ac02 --- /dev/null +++ b/Documentation/acpi/video_extension.txt @@ -0,0 +1,106 @@ +ACPI video extensions +~~~~~~~~~~~~~~~~~~~~~ + +This driver implement the ACPI Extensions For Display Adapters for +integrated graphics devices on motherboard, as specified in ACPI 2.0 +Specification, Appendix B, allowing to perform some basic control like +defining the video POST device, retrieving EDID information or to +setup a video output, etc. Note that this is an ref. implementation +only. It may or may not work for your integrated video device. + +The ACPI video driver does 3 things regarding backlight control: + +1 Export a sysfs interface for user space to control backlight level + +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 +and set the required backlight operation structure for it for the sysfs +interface control. For every registered class device, there will be a +directory named acpi_videoX under /sys/class/backlight. + +The backlight sysfs interface has a standard definition here: +Documentation/ABI/stable/sysfs-class-backlight. + +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; +bl_power: not implemented, will set the current brightness instead; +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 +brightness, actual_brightness and max_brightness. So if we have +the following _BCL package: + +Method (_BCL, 0, NotSerialized) +{ + Return (Package (0x0C) + { + 0x64, + 0x32, + 0x0A, + 0x14, + 0x1E, + 0x28, + 0x32, + 0x3C, + 0x46, + 0x50, + 0x5A, + 0x64 + }) +} + +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 +that we can choose from. The applicable index values are from 0 (that +corresponds to the 0x0A brightness value) to 9 (that corresponds to the +0x64 brightness value) inclusive. Each of those index values is regarded +as a "brightness level" indicator. Thus from the user space perspective +the range of available brightness levels is from 0 to 9 (max_brightness) +inclusive. + +2 Notify user space about hotkey event + +There are generally two cases for hotkey event reporting: +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 + the keyboard driver as a key type input event, with proper remap, the + following key code will appear to user space: + + EV_KEY, KEY_BRIGHTNESSUP + EV_KEY, KEY_BRIGHTNESSDOWN + etc. + +For this case, ACPI video driver does not need to do anything(actually, +it doesn't even know this happened). + +ii) For some laptops, the press of the hotkey will not generate the + scancode, instead, firmware will notify the video device ACPI node + about the event. The event value is defined in the ACPI spec. ACPI + video driver will generate an key type input event according to the + notify value it received and send the event to user space through the + input device it created: + + event keycode + 0x86 KEY_BRIGHTNESSUP + 0x87 KEY_BRIGHTNESSDOWN + etc. + +so this would lead to the same effect as case i) now. + +Once user space tool receives this event, it can modify the backlight +level through the sysfs interface. + +3 Change backlight level in the kernel + +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 +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 +directly. This behaviour can be controlled through the brightness_switch_enabled +module parameter as documented in kernel-parameters.txt. It is recommended to +disable this behaviour once a GUI environment starts up and wants to have full +control of the backlight level. |