mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
Merge back earlier ACPICA changes for v4.11.
This commit is contained in:
commit
1b62d134d3
11659 changed files with 740674 additions and 247265 deletions
|
|
@ -104,7 +104,7 @@ config ACPI_PROCFS_POWER
|
|||
Say N to delete power /proc/acpi/ directories that have moved to /sys/
|
||||
|
||||
config ACPI_REV_OVERRIDE_POSSIBLE
|
||||
bool "Allow supported ACPI revision to be overriden"
|
||||
bool "Allow supported ACPI revision to be overridden"
|
||||
depends on X86
|
||||
default y
|
||||
help
|
||||
|
|
@ -342,7 +342,7 @@ config ACPI_DEBUG
|
|||
|
||||
Use the acpi.debug_layer and acpi.debug_level kernel command-line
|
||||
parameters documented in Documentation/acpi/debug.txt and
|
||||
Documentation/kernel-parameters.txt to control the type and
|
||||
Documentation/admin-guide/kernel-parameters.rst to control the type and
|
||||
amount of debug output.
|
||||
|
||||
config ACPI_PCI_SLOT
|
||||
|
|
|
|||
|
|
@ -77,6 +77,11 @@ static const struct apd_device_desc cz_i2c_desc = {
|
|||
.fixed_clk_rate = 133000000,
|
||||
};
|
||||
|
||||
static const struct apd_device_desc wt_i2c_desc = {
|
||||
.setup = acpi_apd_setup,
|
||||
.fixed_clk_rate = 150000000,
|
||||
};
|
||||
|
||||
static struct property_entry uart_properties[] = {
|
||||
PROPERTY_ENTRY_U32("reg-io-width", 4),
|
||||
PROPERTY_ENTRY_U32("reg-shift", 2),
|
||||
|
|
@ -156,7 +161,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
|
|||
/* Generic apd devices */
|
||||
#ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
|
||||
{ "AMD0010", APD_ADDR(cz_i2c_desc) },
|
||||
{ "AMDI0010", APD_ADDR(cz_i2c_desc) },
|
||||
{ "AMDI0010", APD_ADDR(wt_i2c_desc) },
|
||||
{ "AMD0020", APD_ADDR(cz_uart_desc) },
|
||||
{ "AMDI0020", APD_ADDR(cz_uart_desc) },
|
||||
{ "AMD0030", },
|
||||
|
|
|
|||
|
|
@ -718,13 +718,14 @@ static int acpi_lpss_resume_early(struct device *dev)
|
|||
#define LPSS_GPIODEF0_DMA1_D3 BIT(2)
|
||||
#define LPSS_GPIODEF0_DMA2_D3 BIT(3)
|
||||
#define LPSS_GPIODEF0_DMA_D3_MASK GENMASK(3, 2)
|
||||
#define LPSS_GPIODEF0_DMA_LLP BIT(13)
|
||||
|
||||
static DEFINE_MUTEX(lpss_iosf_mutex);
|
||||
|
||||
static void lpss_iosf_enter_d3_state(void)
|
||||
{
|
||||
u32 value1 = 0;
|
||||
u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK;
|
||||
u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK | LPSS_GPIODEF0_DMA_LLP;
|
||||
u32 value2 = LPSS_PMCSR_D3hot;
|
||||
u32 mask2 = LPSS_PMCSR_Dx_MASK;
|
||||
/*
|
||||
|
|
@ -768,8 +769,9 @@ exit:
|
|||
|
||||
static void lpss_iosf_exit_d3_state(void)
|
||||
{
|
||||
u32 value1 = LPSS_GPIODEF0_DMA1_D3 | LPSS_GPIODEF0_DMA2_D3;
|
||||
u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK;
|
||||
u32 value1 = LPSS_GPIODEF0_DMA1_D3 | LPSS_GPIODEF0_DMA2_D3 |
|
||||
LPSS_GPIODEF0_DMA_LLP;
|
||||
u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK | LPSS_GPIODEF0_DMA_LLP;
|
||||
u32 value2 = LPSS_PMCSR_D0;
|
||||
u32 mask2 = LPSS_PMCSR_Dx_MASK;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,23 +37,12 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/video.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
#define ACPI_VIDEO_BUS_NAME "Video Bus"
|
||||
#define ACPI_VIDEO_DEVICE_NAME "Video Device"
|
||||
#define ACPI_VIDEO_NOTIFY_SWITCH 0x80
|
||||
#define ACPI_VIDEO_NOTIFY_PROBE 0x81
|
||||
#define ACPI_VIDEO_NOTIFY_CYCLE 0x82
|
||||
#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
|
||||
#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
|
||||
|
||||
#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
|
||||
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
|
||||
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
|
||||
#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
|
||||
#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
|
||||
|
||||
#define MAX_NAME_LEN 20
|
||||
|
||||
|
|
|
|||
|
|
@ -770,7 +770,7 @@ union acpi_parse_value {
|
|||
char *operator_symbol;/* Used for C-style operator name strings */\
|
||||
char aml_op_name[16]) /* Op name (debug only) */
|
||||
|
||||
/* Flags for disasm_flags field above */
|
||||
/* Internal opcodes for disasm_opcode field above */
|
||||
|
||||
#define ACPI_DASM_BUFFER 0x00 /* Buffer is a simple data buffer */
|
||||
#define ACPI_DASM_RESOURCE 0x01 /* Buffer is a Resource Descriptor */
|
||||
|
|
@ -783,7 +783,10 @@ union acpi_parse_value {
|
|||
#define ACPI_DASM_LNOT_PREFIX 0x08 /* Start of a Lnot_equal (etc.) pair of opcodes */
|
||||
#define ACPI_DASM_LNOT_SUFFIX 0x09 /* End of a Lnot_equal (etc.) pair of opcodes */
|
||||
#define ACPI_DASM_HID_STRING 0x0A /* String is a _HID or _CID */
|
||||
#define ACPI_DASM_IGNORE 0x0B /* Not used at this time */
|
||||
#define ACPI_DASM_IGNORE_SINGLE 0x0B /* Ignore the opcode but not it's children */
|
||||
#define ACPI_DASM_SWITCH_PREDICATE 0x0C /* Object is a predicate for a Switch or Case block */
|
||||
#define ACPI_DASM_CASE 0x0D /* If/Else is a Case in a Switch/Case block */
|
||||
#define ACPI_DASM_DEFAULT 0x0E /* Else is a Default in a Switch/Case block */
|
||||
|
||||
/*
|
||||
* Generic operation (for example: If, While, Store)
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
/*
|
||||
* Extract data using a pointer. Any more than a byte and we
|
||||
* get into potential aligment issues -- see the STORE macros below.
|
||||
* get into potential alignment issues -- see the STORE macros below.
|
||||
* Use with care.
|
||||
*/
|
||||
#define ACPI_CAST8(ptr) ACPI_CAST_PTR (u8, (ptr))
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
#define ACPI_SET64(ptr, val) (*ACPI_CAST64 (ptr) = (u64) (val))
|
||||
|
||||
/*
|
||||
* printf() format helper. This macros is a workaround for the difficulties
|
||||
* printf() format helper. This macro is a workaround for the difficulties
|
||||
* with emitting 64-bit integers and 64-bit pointers with the same code
|
||||
* for both 32-bit and 64-bit hosts.
|
||||
*/
|
||||
|
|
@ -260,8 +260,70 @@
|
|||
|
||||
#define ACPI_IS_MISALIGNED(value) (((acpi_size) value) & (sizeof(acpi_size)-1))
|
||||
|
||||
/* Generic bit manipulation */
|
||||
|
||||
#ifndef ACPI_USE_NATIVE_BIT_FINDER
|
||||
|
||||
#define __ACPI_FIND_LAST_BIT_2(a, r) ((((u8) (a)) & 0x02) ? (r)+1 : (r))
|
||||
#define __ACPI_FIND_LAST_BIT_4(a, r) ((((u8) (a)) & 0x0C) ? \
|
||||
__ACPI_FIND_LAST_BIT_2 ((a)>>2, (r)+2) : \
|
||||
__ACPI_FIND_LAST_BIT_2 ((a), (r)))
|
||||
#define __ACPI_FIND_LAST_BIT_8(a, r) ((((u8) (a)) & 0xF0) ? \
|
||||
__ACPI_FIND_LAST_BIT_4 ((a)>>4, (r)+4) : \
|
||||
__ACPI_FIND_LAST_BIT_4 ((a), (r)))
|
||||
#define __ACPI_FIND_LAST_BIT_16(a, r) ((((u16) (a)) & 0xFF00) ? \
|
||||
__ACPI_FIND_LAST_BIT_8 ((a)>>8, (r)+8) : \
|
||||
__ACPI_FIND_LAST_BIT_8 ((a), (r)))
|
||||
#define __ACPI_FIND_LAST_BIT_32(a, r) ((((u32) (a)) & 0xFFFF0000) ? \
|
||||
__ACPI_FIND_LAST_BIT_16 ((a)>>16, (r)+16) : \
|
||||
__ACPI_FIND_LAST_BIT_16 ((a), (r)))
|
||||
#define __ACPI_FIND_LAST_BIT_64(a, r) ((((u64) (a)) & 0xFFFFFFFF00000000) ? \
|
||||
__ACPI_FIND_LAST_BIT_32 ((a)>>32, (r)+32) : \
|
||||
__ACPI_FIND_LAST_BIT_32 ((a), (r)))
|
||||
|
||||
#define ACPI_FIND_LAST_BIT_8(a) ((a) ? __ACPI_FIND_LAST_BIT_8 (a, 1) : 0)
|
||||
#define ACPI_FIND_LAST_BIT_16(a) ((a) ? __ACPI_FIND_LAST_BIT_16 (a, 1) : 0)
|
||||
#define ACPI_FIND_LAST_BIT_32(a) ((a) ? __ACPI_FIND_LAST_BIT_32 (a, 1) : 0)
|
||||
#define ACPI_FIND_LAST_BIT_64(a) ((a) ? __ACPI_FIND_LAST_BIT_64 (a, 1) : 0)
|
||||
|
||||
#define __ACPI_FIND_FIRST_BIT_2(a, r) ((((u8) (a)) & 0x01) ? (r) : (r)+1)
|
||||
#define __ACPI_FIND_FIRST_BIT_4(a, r) ((((u8) (a)) & 0x03) ? \
|
||||
__ACPI_FIND_FIRST_BIT_2 ((a), (r)) : \
|
||||
__ACPI_FIND_FIRST_BIT_2 ((a)>>2, (r)+2))
|
||||
#define __ACPI_FIND_FIRST_BIT_8(a, r) ((((u8) (a)) & 0x0F) ? \
|
||||
__ACPI_FIND_FIRST_BIT_4 ((a), (r)) : \
|
||||
__ACPI_FIND_FIRST_BIT_4 ((a)>>4, (r)+4))
|
||||
#define __ACPI_FIND_FIRST_BIT_16(a, r) ((((u16) (a)) & 0x00FF) ? \
|
||||
__ACPI_FIND_FIRST_BIT_8 ((a), (r)) : \
|
||||
__ACPI_FIND_FIRST_BIT_8 ((a)>>8, (r)+8))
|
||||
#define __ACPI_FIND_FIRST_BIT_32(a, r) ((((u32) (a)) & 0x0000FFFF) ? \
|
||||
__ACPI_FIND_FIRST_BIT_16 ((a), (r)) : \
|
||||
__ACPI_FIND_FIRST_BIT_16 ((a)>>16, (r)+16))
|
||||
#define __ACPI_FIND_FIRST_BIT_64(a, r) ((((u64) (a)) & 0x00000000FFFFFFFF) ? \
|
||||
__ACPI_FIND_FIRST_BIT_32 ((a), (r)) : \
|
||||
__ACPI_FIND_FIRST_BIT_32 ((a)>>32, (r)+32))
|
||||
|
||||
#define ACPI_FIND_FIRST_BIT_8(a) ((a) ? __ACPI_FIND_FIRST_BIT_8 (a, 1) : 0)
|
||||
#define ACPI_FIND_FIRST_BIT_16(a) ((a) ? __ACPI_FIND_FIRST_BIT_16 (a, 1) : 0)
|
||||
#define ACPI_FIND_FIRST_BIT_32(a) ((a) ? __ACPI_FIND_FIRST_BIT_32 (a, 1) : 0)
|
||||
#define ACPI_FIND_FIRST_BIT_64(a) ((a) ? __ACPI_FIND_FIRST_BIT_64 (a, 1) : 0)
|
||||
|
||||
#endif /* ACPI_USE_NATIVE_BIT_FINDER */
|
||||
|
||||
/* Generic (power-of-two) rounding */
|
||||
|
||||
#define ACPI_ROUND_UP_POWER_OF_TWO_8(a) ((u8) \
|
||||
(((u16) 1) << ACPI_FIND_LAST_BIT_8 ((a) - 1)))
|
||||
#define ACPI_ROUND_DOWN_POWER_OF_TWO_8(a) ((u8) \
|
||||
(((u16) 1) << (ACPI_FIND_LAST_BIT_8 ((a)) - 1)))
|
||||
#define ACPI_ROUND_UP_POWER_OF_TWO_16(a) ((u16) \
|
||||
(((u32) 1) << ACPI_FIND_LAST_BIT_16 ((a) - 1)))
|
||||
#define ACPI_ROUND_DOWN_POWER_OF_TWO_16(a) ((u16) \
|
||||
(((u32) 1) << (ACPI_FIND_LAST_BIT_16 ((a)) - 1)))
|
||||
#define ACPI_ROUND_UP_POWER_OF_TWO_32(a) ((u32) \
|
||||
(((u64) 1) << ACPI_FIND_LAST_BIT_32 ((a) - 1)))
|
||||
#define ACPI_ROUND_DOWN_POWER_OF_TWO_32(a) ((u32) \
|
||||
(((u64) 1) << (ACPI_FIND_LAST_BIT_32 ((a)) - 1)))
|
||||
#define ACPI_IS_ALIGNED(a, s) (((a) & ((s) - 1)) == 0)
|
||||
#define ACPI_IS_POWER_OF_TWO(a) ACPI_IS_ALIGNED(a, a)
|
||||
|
||||
|
|
@ -270,8 +332,8 @@
|
|||
* Bit positions start at zero.
|
||||
* MASK_BITS_ABOVE creates a mask starting AT the position and above
|
||||
* MASK_BITS_BELOW creates a mask starting one bit BELOW the position
|
||||
* MASK_BITS_ABOVE/BELOW accpets a bit offset to create a mask
|
||||
* MASK_BITS_ABOVE/BELOW_32/64 accpets a bit width to create a mask
|
||||
* MASK_BITS_ABOVE/BELOW accepts a bit offset to create a mask
|
||||
* MASK_BITS_ABOVE/BELOW_32/64 accepts a bit width to create a mask
|
||||
* Note: The ACPI_INTEGER_BIT_SIZE check is used to bypass compiler
|
||||
* differences with the shift operator
|
||||
*/
|
||||
|
|
@ -389,7 +451,7 @@
|
|||
*/
|
||||
#ifndef ACPI_NO_ERROR_MESSAGES
|
||||
/*
|
||||
* Error reporting. Callers module and line number are inserted by AE_INFO,
|
||||
* Error reporting. The callers module and line number are inserted by AE_INFO,
|
||||
* the plist contains a set of parens to allow variable-length lists.
|
||||
* These macros are used for both the debug and non-debug versions of the code.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@
|
|||
#define ARGP_BYTELIST_OP ARGP_LIST1 (ARGP_NAMESTRING)
|
||||
#define ARGP_CONCAT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
|
||||
#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
|
||||
#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_NAME_OR_REF,ARGP_TARGET)
|
||||
#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SIMPLENAME, ARGP_TARGET)
|
||||
#define ARGP_CONNECTFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
|
||||
#define ARGP_CONTINUE_OP ARG_NONE
|
||||
#define ARGP_COPY_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SIMPLENAME)
|
||||
|
|
@ -105,7 +105,7 @@
|
|||
#define ARGP_DATA_REGION_OP ARGP_LIST4 (ARGP_NAME, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG)
|
||||
#define ARGP_DEBUG_OP ARG_NONE
|
||||
#define ARGP_DECREMENT_OP ARGP_LIST1 (ARGP_SUPERNAME)
|
||||
#define ARGP_DEREF_OF_OP ARGP_LIST1 (ARGP_TERMARG)
|
||||
#define ARGP_DEREF_OF_OP ARGP_LIST1 (ARGP_SUPERNAME)
|
||||
#define ARGP_DEVICE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_OBJLIST)
|
||||
#define ARGP_DIVIDE_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET, ARGP_TARGET)
|
||||
#define ARGP_DWORD_OP ARGP_LIST1 (ARGP_DWORDDATA)
|
||||
|
|
@ -152,14 +152,14 @@
|
|||
#define ARGP_NAMEPATH_OP ARGP_LIST1 (ARGP_NAMESTRING)
|
||||
#define ARGP_NOOP_OP ARG_NONE
|
||||
#define ARGP_NOTIFY_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG)
|
||||
#define ARGP_OBJECT_TYPE_OP ARGP_LIST1 (ARGP_NAME_OR_REF)
|
||||
#define ARGP_OBJECT_TYPE_OP ARGP_LIST1 (ARGP_SIMPLENAME)
|
||||
#define ARGP_ONE_OP ARG_NONE
|
||||
#define ARGP_ONES_OP ARG_NONE
|
||||
#define ARGP_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_BYTEDATA, ARGP_DATAOBJLIST)
|
||||
#define ARGP_POWER_RES_OP ARGP_LIST5 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_WORDDATA, ARGP_OBJLIST)
|
||||
#define ARGP_PROCESSOR_OP ARGP_LIST6 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_DWORDDATA, ARGP_BYTEDATA, ARGP_OBJLIST)
|
||||
#define ARGP_QWORD_OP ARGP_LIST1 (ARGP_QWORDDATA)
|
||||
#define ARGP_REF_OF_OP ARGP_LIST1 (ARGP_NAME_OR_REF)
|
||||
#define ARGP_REF_OF_OP ARGP_LIST1 (ARGP_SIMPLENAME)
|
||||
#define ARGP_REGION_OP ARGP_LIST4 (ARGP_NAME, ARGP_BYTEDATA, ARGP_TERMARG, ARGP_TERMARG)
|
||||
#define ARGP_RELEASE_OP ARGP_LIST1 (ARGP_SUPERNAME)
|
||||
#define ARGP_RESERVEDFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
|
||||
|
|
@ -249,7 +249,7 @@
|
|||
#define ARGI_FIELD_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_FIND_SET_LEFT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET)
|
||||
#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_IF_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_TARGETREF)
|
||||
#define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE
|
||||
|
|
@ -313,12 +313,12 @@
|
|||
#define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_THERMAL_ZONE_OP ARGI_INVALID_OPCODE
|
||||
#define ARGI_TIMER_OP ARG_NONE
|
||||
#define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET)
|
||||
#define ARGI_TO_BUFFER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
|
||||
#define ARGI_TO_DEC_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
|
||||
#define ARGI_TO_HEX_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
|
||||
#define ARGI_TO_INTEGER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
|
||||
#define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_FIXED_TARGET)
|
||||
#define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_TO_BUFFER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_TARGETREF)
|
||||
#define ARGI_TO_DEC_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_TARGETREF)
|
||||
#define ARGI_TO_HEX_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_TARGETREF)
|
||||
#define ARGI_TO_INTEGER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_TARGETREF)
|
||||
#define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_TARGETREF)
|
||||
#define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE)
|
||||
#define ARGI_VAR_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER)
|
||||
#define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER)
|
||||
|
|
|
|||
|
|
@ -277,9 +277,23 @@
|
|||
#define ARGI_DEVICE_REF 0x0D
|
||||
#define ARGI_REFERENCE 0x0E
|
||||
#define ARGI_TARGETREF 0x0F /* Target, subject to implicit conversion */
|
||||
#define ARGI_FIXED_TARGET 0x10 /* Target, no implicit conversion */
|
||||
#define ARGI_SIMPLE_TARGET 0x11 /* Name, Local, Arg -- no implicit conversion */
|
||||
#define ARGI_STORE_TARGET 0x12 /* Target for store is TARGETREF + package objects */
|
||||
#define ARGI_SIMPLE_TARGET 0x10 /* Name, Local, Arg -- no implicit conversion */
|
||||
#define ARGI_STORE_TARGET 0x11 /* Target for store is TARGETREF + package objects */
|
||||
/*
|
||||
* #define ARGI_FIXED_TARGET 0x10 Target, no implicit conversion
|
||||
*
|
||||
* Removed 10/2016. ARGI_FIXED_TARGET was used for these operators:
|
||||
* from_BCD
|
||||
* to_BCD
|
||||
* to_decimal_string
|
||||
* to_hex_string
|
||||
* to_integer
|
||||
* to_buffer
|
||||
* The purpose of this type was to disable "implicit result conversion",
|
||||
* but this was incorrect per the ACPI spec and other ACPI implementations.
|
||||
* These operators now have the target operand defined as a normal
|
||||
* ARGI_TARGETREF.
|
||||
*/
|
||||
|
||||
/* Multiple/complex types */
|
||||
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ acpi_status acpi_initialize_debugger(void)
|
|||
|
||||
/* These were created with one unit, grab it */
|
||||
|
||||
status = acpi_os_initialize_command_signals();
|
||||
status = acpi_os_initialize_debugger();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
acpi_os_printf("Could not get debugger mutex\n");
|
||||
return_ACPI_STATUS(status);
|
||||
|
|
@ -482,7 +482,7 @@ void acpi_terminate_debugger(void)
|
|||
acpi_os_sleep(100);
|
||||
}
|
||||
|
||||
acpi_os_terminate_command_signals();
|
||||
acpi_os_terminate_debugger();
|
||||
}
|
||||
|
||||
if (acpi_gbl_db_buffer) {
|
||||
|
|
|
|||
|
|
@ -592,7 +592,6 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
|
|||
*/
|
||||
switch (GET_CURRENT_ARG_TYPE(walk_state->op_info->runtime_args)) {
|
||||
case ARGI_SIMPLE_TARGET:
|
||||
case ARGI_FIXED_TARGET:
|
||||
case ARGI_INTEGER_REF: /* Handles Increment, Decrement cases */
|
||||
|
||||
switch (destination_type) {
|
||||
|
|
|
|||
|
|
@ -305,7 +305,6 @@ acpi_ex_resolve_operands(u16 opcode,
|
|||
case ARGI_OBJECT_REF:
|
||||
case ARGI_DEVICE_REF:
|
||||
case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
|
||||
case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
|
||||
case ARGI_SIMPLE_TARGET: /* Name, Local, or arg - no implicit conversion */
|
||||
case ARGI_STORE_TARGET:
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@
|
|||
*/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include <linux/acpi.h>
|
||||
#include "accommon.h"
|
||||
|
||||
#define _COMPONENT ACPI_HARDWARE
|
||||
|
|
@ -103,7 +102,7 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument)
|
|||
acpi_status acpi_hw_extended_sleep(u8 sleep_state)
|
||||
{
|
||||
acpi_status status;
|
||||
u8 sleep_type_value;
|
||||
u8 sleep_control;
|
||||
u64 sleep_status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(hw_extended_sleep);
|
||||
|
|
@ -125,18 +124,6 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)
|
|||
|
||||
acpi_gbl_system_awake_and_running = FALSE;
|
||||
|
||||
/* Flush caches, as per ACPI specification */
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
status = acpi_os_prepare_extended_sleep(sleep_state,
|
||||
acpi_gbl_sleep_type_a,
|
||||
acpi_gbl_sleep_type_b);
|
||||
if (ACPI_SKIP(status))
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
if (ACPI_FAILURE(status))
|
||||
return_ACPI_STATUS(status);
|
||||
|
||||
/*
|
||||
* Set the SLP_TYP and SLP_EN bits.
|
||||
*
|
||||
|
|
@ -146,12 +133,22 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)
|
|||
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
|
||||
"Entering sleep state [S%u]\n", sleep_state));
|
||||
|
||||
sleep_type_value =
|
||||
((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
|
||||
ACPI_X_SLEEP_TYPE_MASK);
|
||||
sleep_control = ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
|
||||
ACPI_X_SLEEP_TYPE_MASK) | ACPI_X_SLEEP_ENABLE;
|
||||
|
||||
status = acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE),
|
||||
&acpi_gbl_FADT.sleep_control);
|
||||
/* Flush caches, as per ACPI specification */
|
||||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
status = acpi_os_enter_sleep(sleep_state, sleep_control, 0);
|
||||
if (status == AE_CTRL_TERMINATE) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
status = acpi_write((u64)sleep_control, &acpi_gbl_FADT.sleep_control);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ ACPI_MODULE_NAME("hwregs")
|
|||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/* Local Prototypes */
|
||||
static u8
|
||||
acpi_hw_get_access_bit_width(struct acpi_generic_address *reg,
|
||||
acpi_hw_get_access_bit_width(u64 address,
|
||||
struct acpi_generic_address *reg,
|
||||
u8 max_bit_width);
|
||||
|
||||
static acpi_status
|
||||
|
|
@ -71,7 +72,8 @@ acpi_hw_write_multiple(u32 value,
|
|||
*
|
||||
* FUNCTION: acpi_hw_get_access_bit_width
|
||||
*
|
||||
* PARAMETERS: reg - GAS register structure
|
||||
* PARAMETERS: address - GAS register address
|
||||
* reg - GAS register structure
|
||||
* max_bit_width - Max bit_width supported (32 or 64)
|
||||
*
|
||||
* RETURN: Status
|
||||
|
|
@ -81,27 +83,59 @@ acpi_hw_write_multiple(u32 value,
|
|||
******************************************************************************/
|
||||
|
||||
static u8
|
||||
acpi_hw_get_access_bit_width(struct acpi_generic_address *reg, u8 max_bit_width)
|
||||
acpi_hw_get_access_bit_width(u64 address,
|
||||
struct acpi_generic_address *reg, u8 max_bit_width)
|
||||
{
|
||||
if (!reg->access_width) {
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
|
||||
max_bit_width = 32;
|
||||
}
|
||||
u8 access_bit_width;
|
||||
|
||||
/*
|
||||
* Detect old register descriptors where only the bit_width field
|
||||
* makes senses.
|
||||
*/
|
||||
if (reg->bit_width < max_bit_width &&
|
||||
!reg->bit_offset && reg->bit_width &&
|
||||
ACPI_IS_POWER_OF_TWO(reg->bit_width) &&
|
||||
ACPI_IS_ALIGNED(reg->bit_width, 8)) {
|
||||
return (reg->bit_width);
|
||||
}
|
||||
return (max_bit_width);
|
||||
/*
|
||||
* GAS format "register", used by FADT:
|
||||
* 1. Detected if bit_offset is 0 and bit_width is 8/16/32/64;
|
||||
* 2. access_size field is ignored and bit_width field is used for
|
||||
* determining the boundary of the IO accesses.
|
||||
* GAS format "region", used by APEI registers:
|
||||
* 1. Detected if bit_offset is not 0 or bit_width is not 8/16/32/64;
|
||||
* 2. access_size field is used for determining the boundary of the
|
||||
* IO accesses;
|
||||
* 3. bit_offset/bit_width fields are used to describe the "region".
|
||||
*
|
||||
* Note: This algorithm assumes that the "Address" fields should always
|
||||
* contain aligned values.
|
||||
*/
|
||||
if (!reg->bit_offset && reg->bit_width &&
|
||||
ACPI_IS_POWER_OF_TWO(reg->bit_width) &&
|
||||
ACPI_IS_ALIGNED(reg->bit_width, 8)) {
|
||||
access_bit_width = reg->bit_width;
|
||||
} else if (reg->access_width) {
|
||||
access_bit_width = (1 << (reg->access_width + 2));
|
||||
} else {
|
||||
return (1 << (reg->access_width + 2));
|
||||
access_bit_width =
|
||||
ACPI_ROUND_UP_POWER_OF_TWO_8(reg->bit_offset +
|
||||
reg->bit_width);
|
||||
if (access_bit_width <= 8) {
|
||||
access_bit_width = 8;
|
||||
} else {
|
||||
while (!ACPI_IS_ALIGNED(address, access_bit_width >> 3)) {
|
||||
access_bit_width >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Maximum IO port access bit width is 32 */
|
||||
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
|
||||
max_bit_width = 32;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return access width according to the requested maximum access bit width,
|
||||
* as the caller should know the format of the register and may enforce
|
||||
* a 32-bit accesses.
|
||||
*/
|
||||
if (access_bit_width < max_bit_width) {
|
||||
return (access_bit_width);
|
||||
}
|
||||
return (max_bit_width);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
@ -163,7 +197,8 @@ acpi_hw_validate_register(struct acpi_generic_address *reg,
|
|||
|
||||
/* Validate the bit_width, convert access_width into number of bits */
|
||||
|
||||
access_width = acpi_hw_get_access_bit_width(reg, max_bit_width);
|
||||
access_width =
|
||||
acpi_hw_get_access_bit_width(*address, reg, max_bit_width);
|
||||
bit_width =
|
||||
ACPI_ROUND_UP(reg->bit_offset + reg->bit_width, access_width);
|
||||
if (max_bit_width < bit_width) {
|
||||
|
|
@ -219,7 +254,7 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
|
|||
* into number of bits based
|
||||
*/
|
||||
*value = 0;
|
||||
access_width = acpi_hw_get_access_bit_width(reg, 32);
|
||||
access_width = acpi_hw_get_access_bit_width(address, reg, 32);
|
||||
bit_width = reg->bit_offset + reg->bit_width;
|
||||
bit_offset = reg->bit_offset;
|
||||
|
||||
|
|
@ -252,20 +287,6 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
|
|||
&value32,
|
||||
access_width);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use offset style bit masks because:
|
||||
* bit_offset < access_width/bit_width < access_width, and
|
||||
* access_width is ensured to be less than 32-bits by
|
||||
* acpi_hw_validate_register().
|
||||
*/
|
||||
if (bit_offset) {
|
||||
value32 &= ACPI_MASK_BITS_BELOW(bit_offset);
|
||||
bit_offset = 0;
|
||||
}
|
||||
if (bit_width < access_width) {
|
||||
value32 &= ACPI_MASK_BITS_ABOVE(bit_width);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -306,6 +327,12 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
|
|||
acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
|
||||
{
|
||||
u64 address;
|
||||
u8 access_width;
|
||||
u32 bit_width;
|
||||
u8 bit_offset;
|
||||
u64 value64;
|
||||
u32 value32;
|
||||
u8 index;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_NAME(hw_write);
|
||||
|
|
@ -317,23 +344,61 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
|
|||
return (status);
|
||||
}
|
||||
|
||||
/* Convert access_width into number of bits based */
|
||||
|
||||
access_width = acpi_hw_get_access_bit_width(address, reg, 32);
|
||||
bit_width = reg->bit_offset + reg->bit_width;
|
||||
bit_offset = reg->bit_offset;
|
||||
|
||||
/*
|
||||
* Two address spaces supported: Memory or IO. PCI_Config is
|
||||
* not supported here because the GAS structure is insufficient
|
||||
*/
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
status = acpi_os_write_memory((acpi_physical_address)
|
||||
address, (u64)value,
|
||||
reg->bit_width);
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
index = 0;
|
||||
while (bit_width) {
|
||||
/*
|
||||
* Use offset style bit reads because "Index * AccessWidth" is
|
||||
* ensured to be less than 32-bits by acpi_hw_validate_register().
|
||||
*/
|
||||
value32 = ACPI_GET_BITS(&value, index * access_width,
|
||||
ACPI_MASK_BITS_ABOVE_32(access_width));
|
||||
|
||||
status = acpi_hw_write_port((acpi_io_address)
|
||||
address, value, reg->bit_width);
|
||||
if (bit_offset >= access_width) {
|
||||
bit_offset -= access_width;
|
||||
} else {
|
||||
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
value64 = (u64)value32;
|
||||
status =
|
||||
acpi_os_write_memory((acpi_physical_address)
|
||||
address +
|
||||
index *
|
||||
ACPI_DIV_8
|
||||
(access_width),
|
||||
value64, access_width);
|
||||
} else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
|
||||
|
||||
status = acpi_hw_write_port((acpi_io_address)
|
||||
address +
|
||||
index *
|
||||
ACPI_DIV_8
|
||||
(access_width),
|
||||
value32,
|
||||
access_width);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Index * access_width is ensured to be less than 32-bits by
|
||||
* acpi_hw_validate_register().
|
||||
*/
|
||||
bit_width -=
|
||||
bit_width > access_width ? access_width : bit_width;
|
||||
index++;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_IO,
|
||||
"Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
|
||||
value, reg->bit_width, ACPI_FORMAT_UINT64(address),
|
||||
value, access_width, ACPI_FORMAT_UINT64(address),
|
||||
acpi_ut_get_region_name(reg->space_id)));
|
||||
|
||||
return (status);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@
|
|||
*/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include <linux/acpi.h>
|
||||
#include "accommon.h"
|
||||
|
||||
#define _COMPONENT ACPI_HARDWARE
|
||||
|
|
@ -152,12 +151,14 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
|
|||
|
||||
ACPI_FLUSH_CPU_CACHE();
|
||||
|
||||
status = acpi_os_prepare_sleep(sleep_state, pm1a_control,
|
||||
pm1b_control);
|
||||
if (ACPI_SKIP(status))
|
||||
status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control);
|
||||
if (status == AE_CTRL_TERMINATE) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
if (ACPI_FAILURE(status))
|
||||
}
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Write #2: Write both SLP_TYP + SLP_EN */
|
||||
|
||||
status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
|
||||
|
|
|
|||
|
|
@ -269,23 +269,27 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
|
|||
*/
|
||||
if (ACPI_SUCCESS(status) &&
|
||||
possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
|
||||
if (walk_state->opcode == AML_UNLOAD_OP) {
|
||||
if ((GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
|
||||
ARGP_SUPERNAME)
|
||||
|| (GET_CURRENT_ARG_TYPE(walk_state->arg_types) ==
|
||||
ARGP_TARGET)) {
|
||||
/*
|
||||
* acpi_ps_get_next_namestring has increased the AML pointer,
|
||||
* so we need to restore the saved AML pointer for method call.
|
||||
* acpi_ps_get_next_namestring has increased the AML pointer past
|
||||
* the method invocation namestring, so we need to restore the
|
||||
* saved AML pointer back to the original method invocation
|
||||
* namestring.
|
||||
*/
|
||||
walk_state->parser_state.aml = start;
|
||||
walk_state->arg_count = 1;
|
||||
acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/* This name is actually a control method invocation */
|
||||
|
||||
method_desc = acpi_ns_get_attached_object(node);
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
|
||||
"Control Method - %p Desc %p Path=%p\n", node,
|
||||
method_desc, path));
|
||||
"Control Method invocation %4.4s - %p Desc %p Path=%p\n",
|
||||
node->name.ascii, node, method_desc, path));
|
||||
|
||||
name_op = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP, start);
|
||||
if (!name_op) {
|
||||
|
|
@ -719,6 +723,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||
|
||||
ACPI_FUNCTION_TRACE_PTR(ps_get_next_arg, parser_state);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
|
||||
"Expected argument type ARGP: %s (%2.2X)\n",
|
||||
acpi_ut_get_argument_type_name(arg_type), arg_type));
|
||||
|
||||
switch (arg_type) {
|
||||
case ARGP_BYTEDATA:
|
||||
case ARGP_WORDDATA:
|
||||
|
|
@ -796,11 +804,14 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||
}
|
||||
break;
|
||||
|
||||
case ARGP_TARGET:
|
||||
case ARGP_SUPERNAME:
|
||||
case ARGP_SIMPLENAME:
|
||||
case ARGP_NAME_OR_REF:
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
|
||||
"**** SimpleName/NameOrRef: %s (%2.2X)\n",
|
||||
acpi_ut_get_argument_type_name(arg_type),
|
||||
arg_type));
|
||||
|
||||
subop = acpi_ps_peek_opcode(parser_state);
|
||||
if (subop == 0 ||
|
||||
acpi_ps_is_leading_char(subop) ||
|
||||
|
|
@ -816,28 +827,49 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* To support super_name arg of Unload */
|
||||
status =
|
||||
acpi_ps_get_next_namepath(walk_state, parser_state,
|
||||
arg,
|
||||
ACPI_NOT_METHOD_CALL);
|
||||
} else {
|
||||
/* Single complex argument, nothing returned */
|
||||
|
||||
if (walk_state->opcode == AML_UNLOAD_OP) {
|
||||
status =
|
||||
acpi_ps_get_next_namepath(walk_state,
|
||||
parser_state, arg,
|
||||
ACPI_POSSIBLE_METHOD_CALL);
|
||||
walk_state->arg_count = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* If the super_name argument is a method call, we have
|
||||
* already restored the AML pointer, just free this Arg
|
||||
*/
|
||||
if (arg->common.aml_opcode ==
|
||||
AML_INT_METHODCALL_OP) {
|
||||
acpi_ps_free_op(arg);
|
||||
arg = NULL;
|
||||
}
|
||||
} else {
|
||||
status =
|
||||
acpi_ps_get_next_namepath(walk_state,
|
||||
parser_state, arg,
|
||||
ACPI_NOT_METHOD_CALL);
|
||||
case ARGP_TARGET:
|
||||
case ARGP_SUPERNAME:
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
|
||||
"**** Target/Supername: %s (%2.2X)\n",
|
||||
acpi_ut_get_argument_type_name(arg_type),
|
||||
arg_type));
|
||||
|
||||
subop = acpi_ps_peek_opcode(parser_state);
|
||||
if (subop == 0 ||
|
||||
acpi_ps_is_leading_char(subop) ||
|
||||
ACPI_IS_ROOT_PREFIX(subop) ||
|
||||
ACPI_IS_PARENT_PREFIX(subop)) {
|
||||
|
||||
/* NULL target (zero). Convert to a NULL namepath */
|
||||
|
||||
arg =
|
||||
acpi_ps_alloc_op(AML_INT_NAMEPATH_OP,
|
||||
parser_state->aml);
|
||||
if (!arg) {
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
status =
|
||||
acpi_ps_get_next_namepath(walk_state, parser_state,
|
||||
arg,
|
||||
ACPI_POSSIBLE_METHOD_CALL);
|
||||
|
||||
if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
|
||||
acpi_ps_free_op(arg);
|
||||
arg = NULL;
|
||||
walk_state->arg_count = 1;
|
||||
}
|
||||
} else {
|
||||
/* Single complex argument, nothing returned */
|
||||
|
|
@ -849,6 +881,11 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||
case ARGP_DATAOBJ:
|
||||
case ARGP_TERMARG:
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
|
||||
"**** TermArg/DataObj: %s (%2.2X)\n",
|
||||
acpi_ut_get_argument_type_name(arg_type),
|
||||
arg_type));
|
||||
|
||||
/* Single complex argument, nothing returned */
|
||||
|
||||
walk_state->arg_count = 1;
|
||||
|
|
|
|||
|
|
@ -92,6 +92,10 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
|
|||
|
||||
ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
|
||||
"Get arguments for opcode [%s]\n",
|
||||
op->common.aml_op_name));
|
||||
|
||||
switch (op->common.aml_opcode) {
|
||||
case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
|
||||
case AML_WORD_OP: /* AML_WORDDATA_ARG */
|
||||
|
|
|
|||
|
|
@ -348,7 +348,15 @@ acpi_ps_create_op(struct acpi_walk_state *walk_state,
|
|||
argument_count) {
|
||||
op->common.flags |= ACPI_PARSEOP_TARGET;
|
||||
}
|
||||
} else if (parent_scope->common.aml_opcode == AML_INCREMENT_OP) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Special case for both Increment() and Decrement(), where
|
||||
* the lone argument is both a source and a target.
|
||||
*/
|
||||
else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
|
||||
|| (parent_scope->common.aml_opcode ==
|
||||
AML_DECREMENT_OP)) {
|
||||
op->common.flags |= ACPI_PARSEOP_TARGET;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,10 +129,10 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
|
|||
union acpi_parse_object *prev_arg;
|
||||
const struct acpi_opcode_info *op_info;
|
||||
|
||||
ACPI_FUNCTION_ENTRY();
|
||||
ACPI_FUNCTION_TRACE(ps_append_arg);
|
||||
|
||||
if (!op) {
|
||||
return;
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/* Get the info structure for this opcode */
|
||||
|
|
@ -144,7 +144,7 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
|
|||
|
||||
ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
|
||||
op->common.aml_opcode));
|
||||
return;
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/* Check if this opcode requires argument sub-objects */
|
||||
|
|
@ -153,7 +153,7 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
|
|||
|
||||
/* Has no linked argument objects */
|
||||
|
||||
return;
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/* Append the argument to the linked argument list */
|
||||
|
|
@ -181,6 +181,8 @@ acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
|
|||
|
||||
op->common.arg_list_length++;
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ const char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
|
|||
|
||||
if (!obj_desc) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
|
||||
return_PTR("[NULL Object Descriptor]");
|
||||
return_STR("[NULL Object Descriptor]");
|
||||
}
|
||||
|
||||
/* These descriptor types share a common area */
|
||||
|
|
@ -251,7 +251,7 @@ const char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
|
|||
acpi_ut_get_descriptor_name(obj_desc),
|
||||
obj_desc));
|
||||
|
||||
return_PTR("Invalid object");
|
||||
return_STR("Invalid object");
|
||||
}
|
||||
|
||||
return_STR(acpi_ut_get_type_name(obj_desc->common.type));
|
||||
|
|
|
|||
|
|
@ -421,8 +421,10 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
|
|||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
|
||||
"Obj %p Type %.2X Refs %.2X [Incremented]\n",
|
||||
object, object->common.type, new_count));
|
||||
"Obj %p Type %.2X [%s] Refs %.2X [Incremented]\n",
|
||||
object, object->common.type,
|
||||
acpi_ut_get_object_type_name(object),
|
||||
new_count));
|
||||
break;
|
||||
|
||||
case REF_DECREMENT:
|
||||
|
|
|
|||
|
|
@ -421,8 +421,10 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
|
|||
|
||||
ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
|
||||
|
||||
/* The absolute minimum resource template is one end_tag descriptor */
|
||||
|
||||
/*
|
||||
* The absolute minimum resource template is one end_tag descriptor.
|
||||
* However, we will treat a lone end_tag as just a simple buffer.
|
||||
*/
|
||||
if (aml_length < sizeof(struct aml_resource_end_tag)) {
|
||||
return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
|
||||
}
|
||||
|
|
@ -454,9 +456,8 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
|
|||
/* Invoke the user function */
|
||||
|
||||
if (user_function) {
|
||||
status =
|
||||
user_function(aml, length, offset, resource_index,
|
||||
context);
|
||||
status = user_function(aml, length, offset,
|
||||
resource_index, context);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
|
@ -480,6 +481,12 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
|
|||
*context = aml;
|
||||
}
|
||||
|
||||
/* Check if buffer is defined to be longer than the resource length */
|
||||
|
||||
if (aml_length > (offset + length)) {
|
||||
return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
|
||||
}
|
||||
|
||||
/* Normal exit */
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
|
|
|
|||
|
|
@ -852,6 +852,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
|
|||
if (ghes_read_estatus(ghes, 1)) {
|
||||
ghes_clear_estatus(ghes);
|
||||
continue;
|
||||
} else {
|
||||
ret = NMI_HANDLED;
|
||||
}
|
||||
|
||||
sev = ghes_severity(ghes->estatus->error_severity);
|
||||
|
|
@ -863,12 +865,11 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
|
|||
|
||||
__process_error(ghes);
|
||||
ghes_clear_estatus(ghes);
|
||||
|
||||
ret = NMI_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
irq_work_queue(&ghes_proc_irq_work);
|
||||
if (ret == NMI_HANDLED)
|
||||
irq_work_queue(&ghes_proc_irq_work);
|
||||
#endif
|
||||
atomic_dec(&ghes_in_nmi);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -123,7 +123,13 @@ EXPORT_SYMBOL_GPL(apei_hest_parse);
|
|||
*/
|
||||
static int __init hest_parse_cmc(struct acpi_hest_header *hest_hdr, void *data)
|
||||
{
|
||||
return arch_apei_enable_cmcff(hest_hdr, data);
|
||||
if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
|
||||
return 0;
|
||||
|
||||
if (!acpi_disable_cmcff)
|
||||
return !arch_apei_enable_cmcff(hest_hdr, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ghes_arr {
|
||||
|
|
@ -232,8 +238,9 @@ void __init acpi_hest_init(void)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (!acpi_disable_cmcff)
|
||||
apei_hest_parse(hest_parse_cmc, NULL);
|
||||
rc = apei_hest_parse(hest_parse_cmc, NULL);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
if (!ghes_disable) {
|
||||
rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,17 @@
|
|||
#define pr_fmt(fmt) "ACPI: IORT: " fmt
|
||||
|
||||
#include <linux/acpi_iort.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define IORT_TYPE_MASK(type) (1 << (type))
|
||||
#define IORT_MSI_TYPE (1 << ACPI_IORT_NODE_ITS_GROUP)
|
||||
#define IORT_IOMMU_TYPE ((1 << ACPI_IORT_NODE_SMMU) | \
|
||||
(1 << ACPI_IORT_NODE_SMMU_V3))
|
||||
|
||||
struct iort_its_msi_chip {
|
||||
struct list_head list;
|
||||
|
|
@ -28,6 +37,90 @@ struct iort_its_msi_chip {
|
|||
u32 translation_id;
|
||||
};
|
||||
|
||||
struct iort_fwnode {
|
||||
struct list_head list;
|
||||
struct acpi_iort_node *iort_node;
|
||||
struct fwnode_handle *fwnode;
|
||||
};
|
||||
static LIST_HEAD(iort_fwnode_list);
|
||||
static DEFINE_SPINLOCK(iort_fwnode_lock);
|
||||
|
||||
/**
|
||||
* iort_set_fwnode() - Create iort_fwnode and use it to register
|
||||
* iommu data in the iort_fwnode_list
|
||||
*
|
||||
* @node: IORT table node associated with the IOMMU
|
||||
* @fwnode: fwnode associated with the IORT node
|
||||
*
|
||||
* Returns: 0 on success
|
||||
* <0 on failure
|
||||
*/
|
||||
static inline int iort_set_fwnode(struct acpi_iort_node *iort_node,
|
||||
struct fwnode_handle *fwnode)
|
||||
{
|
||||
struct iort_fwnode *np;
|
||||
|
||||
np = kzalloc(sizeof(struct iort_fwnode), GFP_ATOMIC);
|
||||
|
||||
if (WARN_ON(!np))
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&np->list);
|
||||
np->iort_node = iort_node;
|
||||
np->fwnode = fwnode;
|
||||
|
||||
spin_lock(&iort_fwnode_lock);
|
||||
list_add_tail(&np->list, &iort_fwnode_list);
|
||||
spin_unlock(&iort_fwnode_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* iort_get_fwnode() - Retrieve fwnode associated with an IORT node
|
||||
*
|
||||
* @node: IORT table node to be looked-up
|
||||
*
|
||||
* Returns: fwnode_handle pointer on success, NULL on failure
|
||||
*/
|
||||
static inline
|
||||
struct fwnode_handle *iort_get_fwnode(struct acpi_iort_node *node)
|
||||
{
|
||||
struct iort_fwnode *curr;
|
||||
struct fwnode_handle *fwnode = NULL;
|
||||
|
||||
spin_lock(&iort_fwnode_lock);
|
||||
list_for_each_entry(curr, &iort_fwnode_list, list) {
|
||||
if (curr->iort_node == node) {
|
||||
fwnode = curr->fwnode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&iort_fwnode_lock);
|
||||
|
||||
return fwnode;
|
||||
}
|
||||
|
||||
/**
|
||||
* iort_delete_fwnode() - Delete fwnode associated with an IORT node
|
||||
*
|
||||
* @node: IORT table node associated with fwnode to delete
|
||||
*/
|
||||
static inline void iort_delete_fwnode(struct acpi_iort_node *node)
|
||||
{
|
||||
struct iort_fwnode *curr, *tmp;
|
||||
|
||||
spin_lock(&iort_fwnode_lock);
|
||||
list_for_each_entry_safe(curr, tmp, &iort_fwnode_list, list) {
|
||||
if (curr->iort_node == node) {
|
||||
list_del(&curr->list);
|
||||
kfree(curr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&iort_fwnode_lock);
|
||||
}
|
||||
|
||||
typedef acpi_status (*iort_find_node_callback)
|
||||
(struct acpi_iort_node *node, void *context);
|
||||
|
||||
|
|
@ -141,6 +234,21 @@ static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static acpi_status
|
||||
iort_match_type_callback(struct acpi_iort_node *node, void *context)
|
||||
{
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
bool iort_node_match(u8 type)
|
||||
{
|
||||
struct acpi_iort_node *node;
|
||||
|
||||
node = iort_scan_node(type, iort_match_type_callback, NULL);
|
||||
|
||||
return node != NULL;
|
||||
}
|
||||
|
||||
static acpi_status iort_match_node_callback(struct acpi_iort_node *node,
|
||||
void *context)
|
||||
{
|
||||
|
|
@ -212,9 +320,48 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
|
||||
u32 *id_out, u8 type_mask,
|
||||
int index)
|
||||
{
|
||||
struct acpi_iort_node *parent;
|
||||
struct acpi_iort_id_mapping *map;
|
||||
|
||||
if (!node->mapping_offset || !node->mapping_count ||
|
||||
index >= node->mapping_count)
|
||||
return NULL;
|
||||
|
||||
map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node,
|
||||
node->mapping_offset);
|
||||
|
||||
/* Firmware bug! */
|
||||
if (!map->output_reference) {
|
||||
pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n",
|
||||
node, node->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table,
|
||||
map->output_reference);
|
||||
|
||||
if (!(IORT_TYPE_MASK(parent->type) & type_mask))
|
||||
return NULL;
|
||||
|
||||
if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) {
|
||||
if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
|
||||
node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) {
|
||||
*id_out = map[index].output_base;
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node,
|
||||
u32 rid_in, u32 *rid_out,
|
||||
u8 type)
|
||||
u8 type_mask)
|
||||
{
|
||||
u32 rid = rid_in;
|
||||
|
||||
|
|
@ -223,7 +370,7 @@ static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node,
|
|||
struct acpi_iort_id_mapping *map;
|
||||
int i;
|
||||
|
||||
if (node->type == type) {
|
||||
if (IORT_TYPE_MASK(node->type) & type_mask) {
|
||||
if (rid_out)
|
||||
*rid_out = rid;
|
||||
return node;
|
||||
|
|
@ -296,7 +443,7 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id)
|
|||
if (!node)
|
||||
return req_id;
|
||||
|
||||
iort_node_map_rid(node, req_id, &dev_id, ACPI_IORT_NODE_ITS_GROUP);
|
||||
iort_node_map_rid(node, req_id, &dev_id, IORT_MSI_TYPE);
|
||||
return dev_id;
|
||||
}
|
||||
|
||||
|
|
@ -318,7 +465,7 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id,
|
|||
if (!node)
|
||||
return -ENXIO;
|
||||
|
||||
node = iort_node_map_rid(node, req_id, NULL, ACPI_IORT_NODE_ITS_GROUP);
|
||||
node = iort_node_map_rid(node, req_id, NULL, IORT_MSI_TYPE);
|
||||
if (!node)
|
||||
return -ENXIO;
|
||||
|
||||
|
|
@ -356,13 +503,459 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id)
|
|||
return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI);
|
||||
}
|
||||
|
||||
static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data)
|
||||
{
|
||||
u32 *rid = data;
|
||||
|
||||
*rid = alias;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
|
||||
struct fwnode_handle *fwnode,
|
||||
const struct iommu_ops *ops)
|
||||
{
|
||||
int ret = iommu_fwspec_init(dev, fwnode, ops);
|
||||
|
||||
if (!ret)
|
||||
ret = iommu_fwspec_add_ids(dev, &streamid, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct iommu_ops *iort_iommu_xlate(struct device *dev,
|
||||
struct acpi_iort_node *node,
|
||||
u32 streamid)
|
||||
{
|
||||
const struct iommu_ops *ops = NULL;
|
||||
int ret = -ENODEV;
|
||||
struct fwnode_handle *iort_fwnode;
|
||||
|
||||
if (node) {
|
||||
iort_fwnode = iort_get_fwnode(node);
|
||||
if (!iort_fwnode)
|
||||
return NULL;
|
||||
|
||||
ops = iommu_get_instance(iort_fwnode);
|
||||
if (!ops)
|
||||
return NULL;
|
||||
|
||||
ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops);
|
||||
}
|
||||
|
||||
return ret ? NULL : ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* iort_set_dma_mask - Set-up dma mask for a device.
|
||||
*
|
||||
* @dev: device to configure
|
||||
*/
|
||||
void iort_set_dma_mask(struct device *dev)
|
||||
{
|
||||
/*
|
||||
* Set default coherent_dma_mask to 32 bit. Drivers are expected to
|
||||
* setup the correct supported mask.
|
||||
*/
|
||||
if (!dev->coherent_dma_mask)
|
||||
dev->coherent_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
/*
|
||||
* Set it to coherent_dma_mask by default if the architecture
|
||||
* code has not set it.
|
||||
*/
|
||||
if (!dev->dma_mask)
|
||||
dev->dma_mask = &dev->coherent_dma_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* iort_iommu_configure - Set-up IOMMU configuration for a device.
|
||||
*
|
||||
* @dev: device to configure
|
||||
*
|
||||
* Returns: iommu_ops pointer on configuration success
|
||||
* NULL on configuration failure
|
||||
*/
|
||||
const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
||||
{
|
||||
struct acpi_iort_node *node, *parent;
|
||||
const struct iommu_ops *ops = NULL;
|
||||
u32 streamid = 0;
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
struct pci_bus *bus = to_pci_dev(dev)->bus;
|
||||
u32 rid;
|
||||
|
||||
pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid,
|
||||
&rid);
|
||||
|
||||
node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
|
||||
iort_match_node_callback, &bus->dev);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
parent = iort_node_map_rid(node, rid, &streamid,
|
||||
IORT_IOMMU_TYPE);
|
||||
|
||||
ops = iort_iommu_xlate(dev, parent, streamid);
|
||||
|
||||
} else {
|
||||
int i = 0;
|
||||
|
||||
node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
|
||||
iort_match_node_callback, dev);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
parent = iort_node_get_id(node, &streamid,
|
||||
IORT_IOMMU_TYPE, i++);
|
||||
|
||||
while (parent) {
|
||||
ops = iort_iommu_xlate(dev, parent, streamid);
|
||||
|
||||
parent = iort_node_get_id(node, &streamid,
|
||||
IORT_IOMMU_TYPE, i++);
|
||||
}
|
||||
}
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
static void __init acpi_iort_register_irq(int hwirq, const char *name,
|
||||
int trigger,
|
||||
struct resource *res)
|
||||
{
|
||||
int irq = acpi_register_gsi(NULL, hwirq, trigger,
|
||||
ACPI_ACTIVE_HIGH);
|
||||
|
||||
if (irq <= 0) {
|
||||
pr_err("could not register gsi hwirq %d name [%s]\n", hwirq,
|
||||
name);
|
||||
return;
|
||||
}
|
||||
|
||||
res->start = irq;
|
||||
res->end = irq;
|
||||
res->flags = IORESOURCE_IRQ;
|
||||
res->name = name;
|
||||
}
|
||||
|
||||
static int __init arm_smmu_v3_count_resources(struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu_v3 *smmu;
|
||||
/* Always present mem resource */
|
||||
int num_res = 1;
|
||||
|
||||
/* Retrieve SMMUv3 specific data */
|
||||
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
|
||||
|
||||
if (smmu->event_gsiv)
|
||||
num_res++;
|
||||
|
||||
if (smmu->pri_gsiv)
|
||||
num_res++;
|
||||
|
||||
if (smmu->gerr_gsiv)
|
||||
num_res++;
|
||||
|
||||
if (smmu->sync_gsiv)
|
||||
num_res++;
|
||||
|
||||
return num_res;
|
||||
}
|
||||
|
||||
static void __init arm_smmu_v3_init_resources(struct resource *res,
|
||||
struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu_v3 *smmu;
|
||||
int num_res = 0;
|
||||
|
||||
/* Retrieve SMMUv3 specific data */
|
||||
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
|
||||
|
||||
res[num_res].start = smmu->base_address;
|
||||
res[num_res].end = smmu->base_address + SZ_128K - 1;
|
||||
res[num_res].flags = IORESOURCE_MEM;
|
||||
|
||||
num_res++;
|
||||
|
||||
if (smmu->event_gsiv)
|
||||
acpi_iort_register_irq(smmu->event_gsiv, "eventq",
|
||||
ACPI_EDGE_SENSITIVE,
|
||||
&res[num_res++]);
|
||||
|
||||
if (smmu->pri_gsiv)
|
||||
acpi_iort_register_irq(smmu->pri_gsiv, "priq",
|
||||
ACPI_EDGE_SENSITIVE,
|
||||
&res[num_res++]);
|
||||
|
||||
if (smmu->gerr_gsiv)
|
||||
acpi_iort_register_irq(smmu->gerr_gsiv, "gerror",
|
||||
ACPI_EDGE_SENSITIVE,
|
||||
&res[num_res++]);
|
||||
|
||||
if (smmu->sync_gsiv)
|
||||
acpi_iort_register_irq(smmu->sync_gsiv, "cmdq-sync",
|
||||
ACPI_EDGE_SENSITIVE,
|
||||
&res[num_res++]);
|
||||
}
|
||||
|
||||
static bool __init arm_smmu_v3_is_coherent(struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu_v3 *smmu;
|
||||
|
||||
/* Retrieve SMMUv3 specific data */
|
||||
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
|
||||
|
||||
return smmu->flags & ACPI_IORT_SMMU_V3_COHACC_OVERRIDE;
|
||||
}
|
||||
|
||||
static int __init arm_smmu_count_resources(struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu *smmu;
|
||||
|
||||
/* Retrieve SMMU specific data */
|
||||
smmu = (struct acpi_iort_smmu *)node->node_data;
|
||||
|
||||
/*
|
||||
* Only consider the global fault interrupt and ignore the
|
||||
* configuration access interrupt.
|
||||
*
|
||||
* MMIO address and global fault interrupt resources are always
|
||||
* present so add them to the context interrupt count as a static
|
||||
* value.
|
||||
*/
|
||||
return smmu->context_interrupt_count + 2;
|
||||
}
|
||||
|
||||
static void __init arm_smmu_init_resources(struct resource *res,
|
||||
struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu *smmu;
|
||||
int i, hw_irq, trigger, num_res = 0;
|
||||
u64 *ctx_irq, *glb_irq;
|
||||
|
||||
/* Retrieve SMMU specific data */
|
||||
smmu = (struct acpi_iort_smmu *)node->node_data;
|
||||
|
||||
res[num_res].start = smmu->base_address;
|
||||
res[num_res].end = smmu->base_address + smmu->span - 1;
|
||||
res[num_res].flags = IORESOURCE_MEM;
|
||||
num_res++;
|
||||
|
||||
glb_irq = ACPI_ADD_PTR(u64, node, smmu->global_interrupt_offset);
|
||||
/* Global IRQs */
|
||||
hw_irq = IORT_IRQ_MASK(glb_irq[0]);
|
||||
trigger = IORT_IRQ_TRIGGER_MASK(glb_irq[0]);
|
||||
|
||||
acpi_iort_register_irq(hw_irq, "arm-smmu-global", trigger,
|
||||
&res[num_res++]);
|
||||
|
||||
/* Context IRQs */
|
||||
ctx_irq = ACPI_ADD_PTR(u64, node, smmu->context_interrupt_offset);
|
||||
for (i = 0; i < smmu->context_interrupt_count; i++) {
|
||||
hw_irq = IORT_IRQ_MASK(ctx_irq[i]);
|
||||
trigger = IORT_IRQ_TRIGGER_MASK(ctx_irq[i]);
|
||||
|
||||
acpi_iort_register_irq(hw_irq, "arm-smmu-context", trigger,
|
||||
&res[num_res++]);
|
||||
}
|
||||
}
|
||||
|
||||
static bool __init arm_smmu_is_coherent(struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_smmu *smmu;
|
||||
|
||||
/* Retrieve SMMU specific data */
|
||||
smmu = (struct acpi_iort_smmu *)node->node_data;
|
||||
|
||||
return smmu->flags & ACPI_IORT_SMMU_COHERENT_WALK;
|
||||
}
|
||||
|
||||
struct iort_iommu_config {
|
||||
const char *name;
|
||||
int (*iommu_init)(struct acpi_iort_node *node);
|
||||
bool (*iommu_is_coherent)(struct acpi_iort_node *node);
|
||||
int (*iommu_count_resources)(struct acpi_iort_node *node);
|
||||
void (*iommu_init_resources)(struct resource *res,
|
||||
struct acpi_iort_node *node);
|
||||
};
|
||||
|
||||
static const struct iort_iommu_config iort_arm_smmu_v3_cfg __initconst = {
|
||||
.name = "arm-smmu-v3",
|
||||
.iommu_is_coherent = arm_smmu_v3_is_coherent,
|
||||
.iommu_count_resources = arm_smmu_v3_count_resources,
|
||||
.iommu_init_resources = arm_smmu_v3_init_resources
|
||||
};
|
||||
|
||||
static const struct iort_iommu_config iort_arm_smmu_cfg __initconst = {
|
||||
.name = "arm-smmu",
|
||||
.iommu_is_coherent = arm_smmu_is_coherent,
|
||||
.iommu_count_resources = arm_smmu_count_resources,
|
||||
.iommu_init_resources = arm_smmu_init_resources
|
||||
};
|
||||
|
||||
static __init
|
||||
const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node)
|
||||
{
|
||||
switch (node->type) {
|
||||
case ACPI_IORT_NODE_SMMU_V3:
|
||||
return &iort_arm_smmu_v3_cfg;
|
||||
case ACPI_IORT_NODE_SMMU:
|
||||
return &iort_arm_smmu_cfg;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* iort_add_smmu_platform_device() - Allocate a platform device for SMMU
|
||||
* @node: Pointer to SMMU ACPI IORT node
|
||||
*
|
||||
* Returns: 0 on success, <0 failure
|
||||
*/
|
||||
static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node)
|
||||
{
|
||||
struct fwnode_handle *fwnode;
|
||||
struct platform_device *pdev;
|
||||
struct resource *r;
|
||||
enum dev_dma_attr attr;
|
||||
int ret, count;
|
||||
const struct iort_iommu_config *ops = iort_get_iommu_cfg(node);
|
||||
|
||||
if (!ops)
|
||||
return -ENODEV;
|
||||
|
||||
pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO);
|
||||
if (!pdev)
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
count = ops->iommu_count_resources(node);
|
||||
|
||||
r = kcalloc(count, sizeof(*r), GFP_KERNEL);
|
||||
if (!r) {
|
||||
ret = -ENOMEM;
|
||||
goto dev_put;
|
||||
}
|
||||
|
||||
ops->iommu_init_resources(r, node);
|
||||
|
||||
ret = platform_device_add_resources(pdev, r, count);
|
||||
/*
|
||||
* Resources are duplicated in platform_device_add_resources,
|
||||
* free their allocated memory
|
||||
*/
|
||||
kfree(r);
|
||||
|
||||
if (ret)
|
||||
goto dev_put;
|
||||
|
||||
/*
|
||||
* Add a copy of IORT node pointer to platform_data to
|
||||
* be used to retrieve IORT data information.
|
||||
*/
|
||||
ret = platform_device_add_data(pdev, &node, sizeof(node));
|
||||
if (ret)
|
||||
goto dev_put;
|
||||
|
||||
/*
|
||||
* We expect the dma masks to be equivalent for
|
||||
* all SMMUs set-ups
|
||||
*/
|
||||
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||
|
||||
fwnode = iort_get_fwnode(node);
|
||||
|
||||
if (!fwnode) {
|
||||
ret = -ENODEV;
|
||||
goto dev_put;
|
||||
}
|
||||
|
||||
pdev->dev.fwnode = fwnode;
|
||||
|
||||
attr = ops->iommu_is_coherent(node) ?
|
||||
DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT;
|
||||
|
||||
/* Configure DMA for the page table walker */
|
||||
acpi_dma_configure(&pdev->dev, attr);
|
||||
|
||||
ret = platform_device_add(pdev);
|
||||
if (ret)
|
||||
goto dma_deconfigure;
|
||||
|
||||
return 0;
|
||||
|
||||
dma_deconfigure:
|
||||
acpi_dma_deconfigure(&pdev->dev);
|
||||
dev_put:
|
||||
platform_device_put(pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __init iort_init_platform_devices(void)
|
||||
{
|
||||
struct acpi_iort_node *iort_node, *iort_end;
|
||||
struct acpi_table_iort *iort;
|
||||
struct fwnode_handle *fwnode;
|
||||
int i, ret;
|
||||
|
||||
/*
|
||||
* iort_table and iort both point to the start of IORT table, but
|
||||
* have different struct types
|
||||
*/
|
||||
iort = (struct acpi_table_iort *)iort_table;
|
||||
|
||||
/* Get the first IORT node */
|
||||
iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort,
|
||||
iort->node_offset);
|
||||
iort_end = ACPI_ADD_PTR(struct acpi_iort_node, iort,
|
||||
iort_table->length);
|
||||
|
||||
for (i = 0; i < iort->node_count; i++) {
|
||||
if (iort_node >= iort_end) {
|
||||
pr_err("iort node pointer overflows, bad table\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((iort_node->type == ACPI_IORT_NODE_SMMU) ||
|
||||
(iort_node->type == ACPI_IORT_NODE_SMMU_V3)) {
|
||||
|
||||
fwnode = acpi_alloc_fwnode_static();
|
||||
if (!fwnode)
|
||||
return;
|
||||
|
||||
iort_set_fwnode(iort_node, fwnode);
|
||||
|
||||
ret = iort_add_smmu_platform_device(iort_node);
|
||||
if (ret) {
|
||||
iort_delete_fwnode(iort_node);
|
||||
acpi_free_fwnode_static(fwnode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
iort_node = ACPI_ADD_PTR(struct acpi_iort_node, iort_node,
|
||||
iort_node->length);
|
||||
}
|
||||
}
|
||||
|
||||
void __init acpi_iort_init(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_get_table(ACPI_SIG_IORT, 0, &iort_table);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
const char *msg = acpi_format_exception(status);
|
||||
pr_err("Failed to get table, %s\n", msg);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (status != AE_NOT_FOUND) {
|
||||
const char *msg = acpi_format_exception(status);
|
||||
|
||||
pr_err("Failed to get table, %s\n", msg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
iort_init_platform_devices();
|
||||
|
||||
acpi_probe_device_table(iort);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#ifdef CONFIG_ACPI_PROCFS_POWER
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
#endif
|
||||
|
||||
#include <linux/acpi.h>
|
||||
|
|
@ -430,39 +430,24 @@ static int acpi_battery_get_status(struct acpi_battery *battery)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_battery_get_info(struct acpi_battery *battery)
|
||||
|
||||
static int extract_battery_info(const int use_bix,
|
||||
struct acpi_battery *battery,
|
||||
const struct acpi_buffer *buffer)
|
||||
{
|
||||
int result = -EFAULT;
|
||||
acpi_status status = 0;
|
||||
char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
|
||||
"_BIX" : "_BIF";
|
||||
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
||||
if (!acpi_battery_present(battery))
|
||||
return 0;
|
||||
mutex_lock(&battery->lock);
|
||||
status = acpi_evaluate_object(battery->device->handle, name,
|
||||
NULL, &buffer);
|
||||
mutex_unlock(&battery->lock);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (battery_bix_broken_package)
|
||||
result = extract_package(battery, buffer.pointer,
|
||||
if (use_bix && battery_bix_broken_package)
|
||||
result = extract_package(battery, buffer->pointer,
|
||||
extended_info_offsets + 1,
|
||||
ARRAY_SIZE(extended_info_offsets) - 1);
|
||||
else if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
|
||||
result = extract_package(battery, buffer.pointer,
|
||||
else if (use_bix)
|
||||
result = extract_package(battery, buffer->pointer,
|
||||
extended_info_offsets,
|
||||
ARRAY_SIZE(extended_info_offsets));
|
||||
else
|
||||
result = extract_package(battery, buffer.pointer,
|
||||
result = extract_package(battery, buffer->pointer,
|
||||
info_offsets, ARRAY_SIZE(info_offsets));
|
||||
kfree(buffer.pointer);
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
|
||||
battery->full_charge_capacity = battery->design_capacity;
|
||||
if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
|
||||
|
|
@ -483,6 +468,45 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int acpi_battery_get_info(struct acpi_battery *battery)
|
||||
{
|
||||
const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
|
||||
int use_bix;
|
||||
int result = -ENODEV;
|
||||
|
||||
if (!acpi_battery_present(battery))
|
||||
return 0;
|
||||
|
||||
|
||||
for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) {
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
acpi_status status = AE_ERROR;
|
||||
|
||||
mutex_lock(&battery->lock);
|
||||
status = acpi_evaluate_object(battery->device->handle,
|
||||
use_bix ? "_BIX":"_BIF",
|
||||
NULL, &buffer);
|
||||
mutex_unlock(&battery->lock);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s",
|
||||
use_bix ? "_BIX":"_BIF"));
|
||||
} else {
|
||||
result = extract_battery_info(use_bix,
|
||||
battery,
|
||||
&buffer);
|
||||
|
||||
kfree(buffer.pointer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result && !use_bix && xinfo)
|
||||
pr_warn(FW_BUG "The _BIX method is broken, using _BIF.\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int acpi_battery_get_state(struct acpi_battery *battery)
|
||||
{
|
||||
int result = 0;
|
||||
|
|
|
|||
|
|
@ -160,6 +160,34 @@ static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = dmi_enable_rev_override,
|
||||
.ident = "DELL Precision 5520",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = dmi_enable_rev_override,
|
||||
.ident = "DELL Precision 3520",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"),
|
||||
},
|
||||
},
|
||||
/*
|
||||
* Resolves a quirk with the Dell Latitude 3350 that
|
||||
* causes the ethernet adapter to not function.
|
||||
*/
|
||||
{
|
||||
.callback = dmi_enable_rev_override,
|
||||
.ident = "DELL Latitude 3350",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"),
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -331,6 +331,16 @@ static void acpi_bus_osc_support(void)
|
|||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (boot_cpu_has(X86_FEATURE_HWP)) {
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
|
||||
|
||||
if (!ghes_disable)
|
||||
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT;
|
||||
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
|
||||
|
|
|
|||
|
|
@ -776,21 +776,25 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
|
|||
init_waitqueue_head(&pcc_data.pcc_write_wait_q);
|
||||
}
|
||||
|
||||
/* Plug PSD data into this CPUs CPC descriptor. */
|
||||
per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
|
||||
|
||||
/* Everything looks okay */
|
||||
pr_debug("Parsed CPC struct for CPU: %d\n", pr->id);
|
||||
|
||||
/* Add per logical CPU nodes for reading its feedback counters. */
|
||||
cpu_dev = get_cpu_device(pr->id);
|
||||
if (!cpu_dev)
|
||||
if (!cpu_dev) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Plug PSD data into this CPUs CPC descriptor. */
|
||||
per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
|
||||
|
||||
ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
|
||||
"acpi_cppc");
|
||||
if (ret)
|
||||
if (ret) {
|
||||
per_cpu(cpc_desc_ptr, pr->id) = NULL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
kfree(output.pointer);
|
||||
return 0;
|
||||
|
|
@ -824,6 +828,8 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr)
|
|||
void __iomem *addr;
|
||||
|
||||
cpc_ptr = per_cpu(cpc_desc_ptr, pr->id);
|
||||
if (!cpc_ptr)
|
||||
return;
|
||||
|
||||
/* Free all the mapped sys mem areas for this CPU */
|
||||
for (i = 2; i < cpc_ptr->num_entries; i++) {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ struct acpi_data_node_attr {
|
|||
|
||||
static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf)
|
||||
{
|
||||
return acpi_object_path(dn->handle, buf);
|
||||
return dn->handle ? acpi_object_path(dn->handle, buf) : 0;
|
||||
}
|
||||
|
||||
DATA_NODE_ATTR(path);
|
||||
|
|
@ -105,10 +105,10 @@ static void acpi_expose_nondev_subnodes(struct kobject *kobj,
|
|||
init_completion(&dn->kobj_done);
|
||||
ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype,
|
||||
kobj, "%s", dn->name);
|
||||
if (ret)
|
||||
acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
|
||||
else
|
||||
if (!ret)
|
||||
acpi_expose_nondev_subnodes(&dn->kobj, &dn->data);
|
||||
else if (dn->handle)
|
||||
acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ static const struct genl_multicast_group acpi_event_mcgrps[] = {
|
|||
{ .name = ACPI_GENL_MCAST_GROUP_NAME, },
|
||||
};
|
||||
|
||||
static struct genl_family acpi_event_genl_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
static struct genl_family acpi_event_genl_family __ro_after_init = {
|
||||
.module = THIS_MODULE,
|
||||
.name = ACPI_GENL_FAMILY_NAME,
|
||||
.version = ACPI_GENL_VERSION,
|
||||
.maxattr = ACPI_GENL_ATTR_MAX,
|
||||
|
|
@ -144,7 +144,7 @@ int acpi_bus_generate_netlink_event(const char *device_class,
|
|||
|
||||
EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
|
||||
|
||||
static int acpi_event_genetlink_init(void)
|
||||
static int __init acpi_event_genetlink_init(void)
|
||||
{
|
||||
return genl_register_family(&acpi_event_genl_family);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,8 +227,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
|
||||
attr = acpi_get_dma_attr(acpi_dev);
|
||||
if (attr != DEV_DMA_NOT_SUPPORTED)
|
||||
arch_setup_dma_ops(dev, 0, 0, NULL,
|
||||
attr == DEV_DMA_COHERENT);
|
||||
acpi_dma_configure(dev, attr);
|
||||
|
||||
acpi_physnode_link_name(physical_node_name, node_id);
|
||||
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
|
||||
|
|
@ -251,6 +250,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
|
|||
return 0;
|
||||
|
||||
err:
|
||||
acpi_dma_deconfigure(dev);
|
||||
ACPI_COMPANION_SET(dev, NULL);
|
||||
put_device(dev);
|
||||
put_device(&acpi_dev->dev);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
|
|||
return to_acpi_device(acpi_desc->dev);
|
||||
}
|
||||
|
||||
static int xlat_status(void *buf, unsigned int cmd, u32 status)
|
||||
static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
|
||||
{
|
||||
struct nd_cmd_clear_error *clear_err;
|
||||
struct nd_cmd_ars_status *ars_status;
|
||||
|
|
@ -113,7 +113,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
|
|||
flags = ND_ARS_PERSISTENT | ND_ARS_VOLATILE;
|
||||
if ((status >> 16 & flags) == 0)
|
||||
return -ENOTTY;
|
||||
break;
|
||||
return 0;
|
||||
case ND_CMD_ARS_START:
|
||||
/* ARS is in progress */
|
||||
if ((status & 0xffff) == NFIT_ARS_START_BUSY)
|
||||
|
|
@ -122,7 +122,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
|
|||
/* Command failed */
|
||||
if (status & 0xffff)
|
||||
return -EIO;
|
||||
break;
|
||||
return 0;
|
||||
case ND_CMD_ARS_STATUS:
|
||||
ars_status = buf;
|
||||
/* Command failed */
|
||||
|
|
@ -146,7 +146,8 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
|
|||
* then just continue with the returned results.
|
||||
*/
|
||||
if (status == NFIT_ARS_STATUS_INTR) {
|
||||
if (ars_status->flags & NFIT_ARS_F_OVERFLOW)
|
||||
if (ars_status->out_length >= 40 && (ars_status->flags
|
||||
& NFIT_ARS_F_OVERFLOW))
|
||||
return -ENOSPC;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -154,7 +155,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
|
|||
/* Unknown status */
|
||||
if (status >> 16)
|
||||
return -EIO;
|
||||
break;
|
||||
return 0;
|
||||
case ND_CMD_CLEAR_ERROR:
|
||||
clear_err = buf;
|
||||
if (status & 0xffff)
|
||||
|
|
@ -163,7 +164,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
|
|||
return -EIO;
|
||||
if (clear_err->length > clear_err->cleared)
|
||||
return clear_err->cleared;
|
||||
break;
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -174,9 +175,18 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
|
||||
struct nvdimm *nvdimm, unsigned int cmd, void *buf,
|
||||
unsigned int buf_len, int *cmd_rc)
|
||||
static int xlat_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd,
|
||||
u32 status)
|
||||
{
|
||||
if (!nvdimm)
|
||||
return xlat_bus_status(buf, cmd, status);
|
||||
if (status)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
|
||||
unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
|
||||
{
|
||||
struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
|
||||
union acpi_object in_obj, in_buf, *out_obj;
|
||||
|
|
@ -298,7 +308,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
|
|||
|
||||
for (i = 0, offset = 0; i < desc->out_num; i++) {
|
||||
u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf,
|
||||
(u32 *) out_obj->buffer.pointer);
|
||||
(u32 *) out_obj->buffer.pointer,
|
||||
out_obj->buffer.length - offset);
|
||||
|
||||
if (offset + out_size > out_obj->buffer.length) {
|
||||
dev_dbg(dev, "%s:%s output object underflow cmd: %s field: %d\n",
|
||||
|
|
@ -333,7 +344,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
|
|||
*/
|
||||
rc = buf_len - offset - in_buf.buffer.length;
|
||||
if (cmd_rc)
|
||||
*cmd_rc = xlat_status(buf, cmd, fw_status);
|
||||
*cmd_rc = xlat_status(nvdimm, buf, cmd,
|
||||
fw_status);
|
||||
} else {
|
||||
dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
|
||||
__func__, dimm_name, cmd_name, buf_len,
|
||||
|
|
@ -343,7 +355,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
|
|||
} else {
|
||||
rc = 0;
|
||||
if (cmd_rc)
|
||||
*cmd_rc = xlat_status(buf, cmd, fw_status);
|
||||
*cmd_rc = xlat_status(nvdimm, buf, cmd, fw_status);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -351,6 +363,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
|
|||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_nfit_ctl);
|
||||
|
||||
static const char *spa_type_name(u16 type)
|
||||
{
|
||||
|
|
@ -2001,19 +2014,32 @@ static int ars_get_status(struct acpi_nfit_desc *acpi_desc)
|
|||
return cmd_rc;
|
||||
}
|
||||
|
||||
static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus,
|
||||
static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc,
|
||||
struct nd_cmd_ars_status *ars_status)
|
||||
{
|
||||
struct nvdimm_bus *nvdimm_bus = acpi_desc->nvdimm_bus;
|
||||
int rc;
|
||||
u32 i;
|
||||
|
||||
/*
|
||||
* First record starts at 44 byte offset from the start of the
|
||||
* payload.
|
||||
*/
|
||||
if (ars_status->out_length < 44)
|
||||
return 0;
|
||||
for (i = 0; i < ars_status->num_records; i++) {
|
||||
/* only process full records */
|
||||
if (ars_status->out_length
|
||||
< 44 + sizeof(struct nd_ars_record) * (i + 1))
|
||||
break;
|
||||
rc = nvdimm_bus_add_poison(nvdimm_bus,
|
||||
ars_status->records[i].err_address,
|
||||
ars_status->records[i].length);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
if (i < ars_status->num_records)
|
||||
dev_warn(acpi_desc->dev, "detected truncated ars results\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2266,8 +2292,7 @@ static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc,
|
|||
if (rc < 0 && rc != -ENOSPC)
|
||||
return rc;
|
||||
|
||||
if (ars_status_process_records(acpi_desc->nvdimm_bus,
|
||||
acpi_desc->ars_status))
|
||||
if (ars_status_process_records(acpi_desc, acpi_desc->ars_status))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -240,5 +240,7 @@ const u8 *to_nfit_uuid(enum nfit_uuids id);
|
|||
int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz);
|
||||
void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event);
|
||||
void __acpi_nvdimm_notify(struct device *dev, u32 event);
|
||||
int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
|
||||
unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc);
|
||||
void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev);
|
||||
#endif /* __NFIT_H__ */
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ int acpi_map_pxm_to_node(int pxm)
|
|||
{
|
||||
int node;
|
||||
|
||||
if (pxm < 0 || pxm >= MAX_PXM_DOMAINS)
|
||||
if (pxm < 0 || pxm >= MAX_PXM_DOMAINS || numa_off)
|
||||
return NUMA_NO_NODE;
|
||||
|
||||
node = pxm_to_node_map[pxm];
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
#include <linux/semaphore.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
|
@ -182,15 +182,15 @@ void acpi_os_vprintf(const char *fmt, va_list args)
|
|||
static unsigned long acpi_rsdp;
|
||||
static int __init setup_acpi_rsdp(char *arg)
|
||||
{
|
||||
if (kstrtoul(arg, 16, &acpi_rsdp))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
return kstrtoul(arg, 16, &acpi_rsdp);
|
||||
}
|
||||
early_param("acpi_rsdp", setup_acpi_rsdp);
|
||||
#endif
|
||||
|
||||
acpi_physical_address __init acpi_os_get_root_pointer(void)
|
||||
{
|
||||
acpi_physical_address pa = 0;
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
if (acpi_rsdp)
|
||||
return acpi_rsdp;
|
||||
|
|
@ -199,21 +199,14 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
|
|||
if (efi_enabled(EFI_CONFIG_TABLES)) {
|
||||
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
|
||||
return efi.acpi20;
|
||||
else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
|
||||
if (efi.acpi != EFI_INVALID_TABLE_ADDR)
|
||||
return efi.acpi;
|
||||
else {
|
||||
printk(KERN_ERR PREFIX
|
||||
"System description tables not found\n");
|
||||
return 0;
|
||||
}
|
||||
pr_err(PREFIX "System description tables not found\n");
|
||||
} else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
|
||||
acpi_physical_address pa = 0;
|
||||
|
||||
acpi_find_root_pointer(&pa);
|
||||
return pa;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return pa;
|
||||
}
|
||||
|
||||
/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
|
||||
|
|
@ -1693,7 +1686,7 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state, u32 pm1a_control,
|
|||
if (rc < 0)
|
||||
return AE_ERROR;
|
||||
else if (rc > 0)
|
||||
return AE_CTRL_SKIP;
|
||||
return AE_CTRL_TERMINATE;
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
|
@ -1704,6 +1697,7 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state,
|
|||
__acpi_os_prepare_sleep = func;
|
||||
}
|
||||
|
||||
#if (ACPI_REDUCED_HARDWARE)
|
||||
acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
|
||||
u32 val_b)
|
||||
{
|
||||
|
|
@ -1714,13 +1708,35 @@ acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
|
|||
if (rc < 0)
|
||||
return AE_ERROR;
|
||||
else if (rc > 0)
|
||||
return AE_CTRL_SKIP;
|
||||
return AE_CTRL_TERMINATE;
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
#else
|
||||
acpi_status acpi_os_prepare_extended_sleep(u8 sleep_state, u32 val_a,
|
||||
u32 val_b)
|
||||
{
|
||||
return AE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state,
|
||||
u32 val_a, u32 val_b))
|
||||
{
|
||||
__acpi_os_prepare_extended_sleep = func;
|
||||
}
|
||||
|
||||
acpi_status acpi_os_enter_sleep(u8 sleep_state,
|
||||
u32 reg_a_value, u32 reg_b_value)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
if (acpi_gbl_reduced_hardware)
|
||||
status = acpi_os_prepare_extended_sleep(sleep_state,
|
||||
reg_a_value,
|
||||
reg_b_value);
|
||||
else
|
||||
status = acpi_os_prepare_sleep(sleep_state,
|
||||
reg_a_value, reg_b_value);
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci-acpi.h>
|
||||
#include <linux/pci-ecam.h>
|
||||
|
||||
/* Structure to hold entries from the MCFG table */
|
||||
struct mcfg_entry {
|
||||
|
|
@ -32,12 +33,166 @@ struct mcfg_entry {
|
|||
u8 bus_end;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
struct mcfg_fixup {
|
||||
char oem_id[ACPI_OEM_ID_SIZE + 1];
|
||||
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
|
||||
u32 oem_revision;
|
||||
u16 segment;
|
||||
struct resource bus_range;
|
||||
struct pci_ecam_ops *ops;
|
||||
struct resource cfgres;
|
||||
};
|
||||
|
||||
#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start), \
|
||||
((end) - (start) + 1), \
|
||||
NULL, IORESOURCE_BUS)
|
||||
#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
|
||||
|
||||
static struct mcfg_fixup mcfg_quirks[] = {
|
||||
/* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */
|
||||
|
||||
#define QCOM_ECAM32(seg) \
|
||||
{ "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops }
|
||||
QCOM_ECAM32(0),
|
||||
QCOM_ECAM32(1),
|
||||
QCOM_ECAM32(2),
|
||||
QCOM_ECAM32(3),
|
||||
QCOM_ECAM32(4),
|
||||
QCOM_ECAM32(5),
|
||||
QCOM_ECAM32(6),
|
||||
QCOM_ECAM32(7),
|
||||
|
||||
#define HISI_QUAD_DOM(table_id, seg, ops) \
|
||||
{ "HISI ", table_id, 0, (seg) + 0, MCFG_BUS_ANY, ops }, \
|
||||
{ "HISI ", table_id, 0, (seg) + 1, MCFG_BUS_ANY, ops }, \
|
||||
{ "HISI ", table_id, 0, (seg) + 2, MCFG_BUS_ANY, ops }, \
|
||||
{ "HISI ", table_id, 0, (seg) + 3, MCFG_BUS_ANY, ops }
|
||||
HISI_QUAD_DOM("HIP05 ", 0, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP06 ", 0, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 0, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 4, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 8, &hisi_pcie_ops),
|
||||
HISI_QUAD_DOM("HIP07 ", 12, &hisi_pcie_ops),
|
||||
|
||||
#define THUNDER_PEM_RES(addr, node) \
|
||||
DEFINE_RES_MEM((addr) + ((u64) (node) << 44), 0x39 * SZ_16M)
|
||||
#define THUNDER_PEM_QUIRK(rev, node) \
|
||||
{ "CAVIUM", "THUNDERX", rev, 4 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88001f000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 5 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x884057000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 6 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x88808f000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 7 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89001f000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 8 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x894057000000UL, node) }, \
|
||||
{ "CAVIUM", "THUNDERX", rev, 9 + (10 * (node)), MCFG_BUS_ANY, \
|
||||
&thunder_pem_ecam_ops, THUNDER_PEM_RES(0x89808f000000UL, node) }
|
||||
/* SoC pass2.x */
|
||||
THUNDER_PEM_QUIRK(1, 0),
|
||||
THUNDER_PEM_QUIRK(1, 1),
|
||||
|
||||
#define THUNDER_ECAM_QUIRK(rev, seg) \
|
||||
{ "CAVIUM", "THUNDERX", rev, seg, MCFG_BUS_ANY, \
|
||||
&pci_thunder_ecam_ops }
|
||||
/* SoC pass1.x */
|
||||
THUNDER_PEM_QUIRK(2, 0), /* off-chip devices */
|
||||
THUNDER_PEM_QUIRK(2, 1), /* off-chip devices */
|
||||
THUNDER_ECAM_QUIRK(2, 0),
|
||||
THUNDER_ECAM_QUIRK(2, 1),
|
||||
THUNDER_ECAM_QUIRK(2, 2),
|
||||
THUNDER_ECAM_QUIRK(2, 3),
|
||||
THUNDER_ECAM_QUIRK(2, 10),
|
||||
THUNDER_ECAM_QUIRK(2, 11),
|
||||
THUNDER_ECAM_QUIRK(2, 12),
|
||||
THUNDER_ECAM_QUIRK(2, 13),
|
||||
|
||||
#define XGENE_V1_ECAM_MCFG(rev, seg) \
|
||||
{"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
|
||||
&xgene_v1_pcie_ecam_ops }
|
||||
#define XGENE_V2_ECAM_MCFG(rev, seg) \
|
||||
{"APM ", "XGENE ", rev, seg, MCFG_BUS_ANY, \
|
||||
&xgene_v2_pcie_ecam_ops }
|
||||
/* X-Gene SoC with v1 PCIe controller */
|
||||
XGENE_V1_ECAM_MCFG(1, 0),
|
||||
XGENE_V1_ECAM_MCFG(1, 1),
|
||||
XGENE_V1_ECAM_MCFG(1, 2),
|
||||
XGENE_V1_ECAM_MCFG(1, 3),
|
||||
XGENE_V1_ECAM_MCFG(1, 4),
|
||||
XGENE_V1_ECAM_MCFG(2, 0),
|
||||
XGENE_V1_ECAM_MCFG(2, 1),
|
||||
XGENE_V1_ECAM_MCFG(2, 2),
|
||||
XGENE_V1_ECAM_MCFG(2, 3),
|
||||
XGENE_V1_ECAM_MCFG(2, 4),
|
||||
/* X-Gene SoC with v2.1 PCIe controller */
|
||||
XGENE_V2_ECAM_MCFG(3, 0),
|
||||
XGENE_V2_ECAM_MCFG(3, 1),
|
||||
/* X-Gene SoC with v2.2 PCIe controller */
|
||||
XGENE_V2_ECAM_MCFG(4, 0),
|
||||
XGENE_V2_ECAM_MCFG(4, 1),
|
||||
XGENE_V2_ECAM_MCFG(4, 2),
|
||||
};
|
||||
|
||||
static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
|
||||
static char mcfg_oem_table_id[ACPI_OEM_TABLE_ID_SIZE];
|
||||
static u32 mcfg_oem_revision;
|
||||
|
||||
static int pci_mcfg_quirk_matches(struct mcfg_fixup *f, u16 segment,
|
||||
struct resource *bus_range)
|
||||
{
|
||||
if (!memcmp(f->oem_id, mcfg_oem_id, ACPI_OEM_ID_SIZE) &&
|
||||
!memcmp(f->oem_table_id, mcfg_oem_table_id,
|
||||
ACPI_OEM_TABLE_ID_SIZE) &&
|
||||
f->oem_revision == mcfg_oem_revision &&
|
||||
f->segment == segment &&
|
||||
resource_contains(&f->bus_range, bus_range))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void pci_mcfg_apply_quirks(struct acpi_pci_root *root,
|
||||
struct resource *cfgres,
|
||||
struct pci_ecam_ops **ecam_ops)
|
||||
{
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
u16 segment = root->segment;
|
||||
struct resource *bus_range = &root->secondary;
|
||||
struct mcfg_fixup *f;
|
||||
int i;
|
||||
|
||||
for (i = 0, f = mcfg_quirks; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
|
||||
if (pci_mcfg_quirk_matches(f, segment, bus_range)) {
|
||||
if (f->cfgres.start)
|
||||
*cfgres = f->cfgres;
|
||||
if (f->ops)
|
||||
*ecam_ops = f->ops;
|
||||
dev_info(&root->device->dev, "MCFG quirk: ECAM at %pR for %pR with %ps\n",
|
||||
cfgres, bus_range, *ecam_ops);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* List to save MCFG entries */
|
||||
static LIST_HEAD(pci_mcfg_list);
|
||||
|
||||
phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res)
|
||||
int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
|
||||
struct pci_ecam_ops **ecam_ops)
|
||||
{
|
||||
struct pci_ecam_ops *ops = &pci_generic_ecam_ops;
|
||||
struct resource *bus_res = &root->secondary;
|
||||
u16 seg = root->segment;
|
||||
struct mcfg_entry *e;
|
||||
struct resource res;
|
||||
|
||||
/* Use address from _CBA if present, otherwise lookup MCFG */
|
||||
if (root->mcfg_addr)
|
||||
goto skip_lookup;
|
||||
|
||||
/*
|
||||
* We expect exact match, unless MCFG entry end bus covers more than
|
||||
|
|
@ -45,10 +200,32 @@ phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res)
|
|||
*/
|
||||
list_for_each_entry(e, &pci_mcfg_list, list) {
|
||||
if (e->segment == seg && e->bus_start == bus_res->start &&
|
||||
e->bus_end >= bus_res->end)
|
||||
return e->addr;
|
||||
e->bus_end >= bus_res->end) {
|
||||
root->mcfg_addr = e->addr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
skip_lookup:
|
||||
memset(&res, 0, sizeof(res));
|
||||
if (root->mcfg_addr) {
|
||||
res.start = root->mcfg_addr + (bus_res->start << 20);
|
||||
res.end = res.start + (resource_size(bus_res) << 20) - 1;
|
||||
res.flags = IORESOURCE_MEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow quirks to override default ECAM ops and CFG resource
|
||||
* range. This may even fabricate a CFG resource range in case
|
||||
* MCFG does not have it. Invalid CFG start address means MCFG
|
||||
* firmware bug or we need another quirk in array.
|
||||
*/
|
||||
pci_mcfg_apply_quirks(root, &res, &ops);
|
||||
if (!res.start)
|
||||
return -ENXIO;
|
||||
|
||||
*cfgres = res;
|
||||
*ecam_ops = ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -79,6 +256,13 @@ static __init int pci_mcfg_parse(struct acpi_table_header *header)
|
|||
list_add(&e->list, &pci_mcfg_list);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_QUIRKS
|
||||
/* Save MCFG IDs and revision for quirks matching */
|
||||
memcpy(mcfg_oem_id, header->oem_id, ACPI_OEM_ID_SIZE);
|
||||
memcpy(mcfg_oem_table_id, header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
|
||||
mcfg_oem_revision = header->oem_revision;
|
||||
#endif
|
||||
|
||||
pr_info("MCFG table detected, %d entries\n", n);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include <linux/suspend.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include "sleep.h"
|
||||
#include "internal.h"
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
|
|||
if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
|
||||
return;
|
||||
|
||||
if (amd_e400_c1e_detected)
|
||||
if (boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E))
|
||||
type = ACPI_STATE_C1;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ static void acpi_processor_ppc_ost(acpi_handle handle, int status)
|
|||
status, NULL);
|
||||
}
|
||||
|
||||
int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
|
||||
void acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
|
|||
*/
|
||||
if (event_flag)
|
||||
acpi_processor_ppc_ost(pr->handle, 1);
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = acpi_processor_get_platform_limit(pr);
|
||||
|
|
@ -182,10 +182,8 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
|
|||
else
|
||||
acpi_processor_ppc_ost(pr->handle, 0);
|
||||
}
|
||||
if (ret < 0)
|
||||
return (ret);
|
||||
else
|
||||
return cpufreq_update_policy(pr->id);
|
||||
if (ret >= 0)
|
||||
cpufreq_update_policy(pr->id);
|
||||
}
|
||||
|
||||
int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
|
||||
|
|
@ -465,11 +463,33 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr)
|
|||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info);
|
||||
int acpi_processor_notify_smm(struct module *calling_module)
|
||||
|
||||
int acpi_processor_pstate_control(void)
|
||||
{
|
||||
acpi_status status;
|
||||
static int is_done = 0;
|
||||
|
||||
if (!acpi_gbl_FADT.smi_command || !acpi_gbl_FADT.pstate_control)
|
||||
return 0;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Writing pstate_control [0x%x] to smi_command [0x%x]\n",
|
||||
acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
|
||||
|
||||
status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
|
||||
(u32)acpi_gbl_FADT.pstate_control, 8);
|
||||
if (ACPI_SUCCESS(status))
|
||||
return 1;
|
||||
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Failed to write pstate_control [0x%x] to smi_command [0x%x]",
|
||||
acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int acpi_processor_notify_smm(struct module *calling_module)
|
||||
{
|
||||
static int is_done = 0;
|
||||
int result;
|
||||
|
||||
if (!(acpi_processor_ppc_status & PPC_REGISTERED))
|
||||
return -EBUSY;
|
||||
|
|
@ -492,26 +512,15 @@ int acpi_processor_notify_smm(struct module *calling_module)
|
|||
|
||||
is_done = -EIO;
|
||||
|
||||
/* Can't write pstate_control to smi_command if either value is zero */
|
||||
if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) {
|
||||
result = acpi_processor_pstate_control();
|
||||
if (!result) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n"));
|
||||
module_put(calling_module);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Writing pstate_control [0x%x] to smi_command [0x%x]\n",
|
||||
acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
|
||||
|
||||
status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
|
||||
(u32) acpi_gbl_FADT.pstate_control, 8);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Failed to write pstate_control [0x%x] to "
|
||||
"smi_command [0x%x]", acpi_gbl_FADT.pstate_control,
|
||||
acpi_gbl_FADT.smi_command));
|
||||
if (result < 0) {
|
||||
module_put(calling_module);
|
||||
return status;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Success. If there's no _PPC, we need to fear nothing, so
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include <linux/cpufreq.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/processor.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include <linux/acpi.h>
|
||||
#include <acpi/processor.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
|
|
|
|||
|
|
@ -41,14 +41,13 @@ static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
|
|||
static bool acpi_extract_properties(const union acpi_object *desc,
|
||||
struct acpi_device_data *data);
|
||||
|
||||
static bool acpi_nondev_subnode_ok(acpi_handle scope,
|
||||
const union acpi_object *link,
|
||||
struct list_head *list)
|
||||
static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
|
||||
acpi_handle handle,
|
||||
const union acpi_object *link,
|
||||
struct list_head *list)
|
||||
{
|
||||
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
|
||||
struct acpi_data_node *dn;
|
||||
acpi_handle handle;
|
||||
acpi_status status;
|
||||
bool result;
|
||||
|
||||
dn = kzalloc(sizeof(*dn), GFP_KERNEL);
|
||||
if (!dn)
|
||||
|
|
@ -58,43 +57,75 @@ static bool acpi_nondev_subnode_ok(acpi_handle scope,
|
|||
dn->fwnode.type = FWNODE_ACPI_DATA;
|
||||
INIT_LIST_HEAD(&dn->data.subnodes);
|
||||
|
||||
status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto fail;
|
||||
result = acpi_extract_properties(desc, &dn->data);
|
||||
|
||||
status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
|
||||
ACPI_TYPE_PACKAGE);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto fail;
|
||||
if (handle) {
|
||||
acpi_handle scope;
|
||||
acpi_status status;
|
||||
|
||||
if (acpi_extract_properties(buf.pointer, &dn->data))
|
||||
/*
|
||||
* The scope for the subnode object lookup is the one of the
|
||||
* namespace node (device) containing the object that has
|
||||
* returned the package. That is, it's the scope of that
|
||||
* object's parent.
|
||||
*/
|
||||
status = acpi_get_parent(handle, &scope);
|
||||
if (ACPI_SUCCESS(status)
|
||||
&& acpi_enumerate_nondev_subnodes(scope, desc, &dn->data))
|
||||
result = true;
|
||||
} else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data)) {
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
dn->handle = handle;
|
||||
|
||||
/*
|
||||
* The scope for the subnode object lookup is the one of the namespace
|
||||
* node (device) containing the object that has returned the package.
|
||||
* That is, it's the scope of that object's parent.
|
||||
*/
|
||||
status = acpi_get_parent(handle, &scope);
|
||||
if (ACPI_SUCCESS(status)
|
||||
&& acpi_enumerate_nondev_subnodes(scope, buf.pointer, &dn->data))
|
||||
dn->handle = handle;
|
||||
|
||||
if (dn->handle) {
|
||||
dn->data.pointer = buf.pointer;
|
||||
dn->data.pointer = desc;
|
||||
list_add_tail(&dn->sibling, list);
|
||||
return true;
|
||||
}
|
||||
|
||||
acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
|
||||
|
||||
fail:
|
||||
ACPI_FREE(buf.pointer);
|
||||
kfree(dn);
|
||||
acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool acpi_nondev_subnode_data_ok(acpi_handle handle,
|
||||
const union acpi_object *link,
|
||||
struct list_head *list)
|
||||
{
|
||||
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
|
||||
ACPI_TYPE_PACKAGE);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list))
|
||||
return true;
|
||||
|
||||
ACPI_FREE(buf.pointer);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool acpi_nondev_subnode_ok(acpi_handle scope,
|
||||
const union acpi_object *link,
|
||||
struct list_head *list)
|
||||
{
|
||||
acpi_handle handle;
|
||||
acpi_status status;
|
||||
|
||||
if (!scope)
|
||||
return false;
|
||||
|
||||
status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
return acpi_nondev_subnode_data_ok(handle, link, list);
|
||||
}
|
||||
|
||||
static int acpi_add_nondev_subnodes(acpi_handle scope,
|
||||
const union acpi_object *links,
|
||||
struct list_head *list)
|
||||
|
|
@ -103,15 +134,37 @@ static int acpi_add_nondev_subnodes(acpi_handle scope,
|
|||
int i;
|
||||
|
||||
for (i = 0; i < links->package.count; i++) {
|
||||
const union acpi_object *link;
|
||||
const union acpi_object *link, *desc;
|
||||
acpi_handle handle;
|
||||
bool result;
|
||||
|
||||
link = &links->package.elements[i];
|
||||
/* Only two elements allowed, both must be strings. */
|
||||
if (link->package.count == 2
|
||||
&& link->package.elements[0].type == ACPI_TYPE_STRING
|
||||
&& link->package.elements[1].type == ACPI_TYPE_STRING
|
||||
&& acpi_nondev_subnode_ok(scope, link, list))
|
||||
ret = true;
|
||||
/* Only two elements allowed. */
|
||||
if (link->package.count != 2)
|
||||
continue;
|
||||
|
||||
/* The first one must be a string. */
|
||||
if (link->package.elements[0].type != ACPI_TYPE_STRING)
|
||||
continue;
|
||||
|
||||
/* The second one may be a string, a reference or a package. */
|
||||
switch (link->package.elements[1].type) {
|
||||
case ACPI_TYPE_STRING:
|
||||
result = acpi_nondev_subnode_ok(scope, link, list);
|
||||
break;
|
||||
case ACPI_TYPE_LOCAL_REFERENCE:
|
||||
handle = link->package.elements[1].reference.handle;
|
||||
result = acpi_nondev_subnode_data_ok(handle, link, list);
|
||||
break;
|
||||
case ACPI_TYPE_PACKAGE:
|
||||
desc = &link->package.elements[1];
|
||||
result = acpi_nondev_subnode_extract(desc, NULL, link, list);
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
ret = ret || result;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -664,3 +664,60 @@ int acpi_dev_filter_resource_type(struct acpi_resource *ares,
|
|||
return (type & types) ? 0 : 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
|
||||
|
||||
static int acpi_dev_consumes_res(struct acpi_device *adev, struct resource *res)
|
||||
{
|
||||
struct list_head resource_list;
|
||||
struct resource_entry *rentry;
|
||||
int ret, found = 0;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(rentry, &resource_list, node) {
|
||||
if (resource_contains(rentry->res, res)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
return found;
|
||||
}
|
||||
|
||||
static acpi_status acpi_res_consumer_cb(acpi_handle handle, u32 depth,
|
||||
void *context, void **ret)
|
||||
{
|
||||
struct resource *res = context;
|
||||
struct acpi_device **consumer = (struct acpi_device **) ret;
|
||||
struct acpi_device *adev;
|
||||
|
||||
if (acpi_bus_get_device(handle, &adev))
|
||||
return AE_OK;
|
||||
|
||||
if (acpi_dev_consumes_res(adev, res)) {
|
||||
*consumer = adev;
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_resource_consumer - Find the ACPI device that consumes @res.
|
||||
* @res: Resource to search for.
|
||||
*
|
||||
* Search the current resource settings (_CRS) of every ACPI device node
|
||||
* for @res. If we find an ACPI device whose _CRS includes @res, return
|
||||
* it. Otherwise, return NULL.
|
||||
*/
|
||||
struct acpi_device *acpi_resource_consumer(struct resource *res)
|
||||
{
|
||||
struct acpi_device *consumer = NULL;
|
||||
|
||||
acpi_get_devices(NULL, acpi_res_consumer_cb, res, (void **) &consumer);
|
||||
return consumer;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/acpi_iort.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/dmi.h>
|
||||
|
|
@ -1119,9 +1120,6 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
|
|||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
|
||||
"support\n"));
|
||||
*cap |= ACPI_VIDEO_BACKLIGHT;
|
||||
if (!acpi_has_method(handle, "_BQC"))
|
||||
printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, "
|
||||
"cannot determine initial brightness\n");
|
||||
/* We have backlight support, no need to scan further */
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
|
@ -1370,6 +1368,38 @@ enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
|
|||
return DEV_DMA_NON_COHERENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* acpi_dma_configure - Set-up DMA configuration for the device.
|
||||
* @dev: The pointer to the device
|
||||
* @attr: device dma attributes
|
||||
*/
|
||||
void acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
|
||||
{
|
||||
const struct iommu_ops *iommu;
|
||||
|
||||
iort_set_dma_mask(dev);
|
||||
|
||||
iommu = iort_iommu_configure(dev);
|
||||
|
||||
/*
|
||||
* Assume dma valid range starts at 0 and covers the whole
|
||||
* coherent_dma_mask.
|
||||
*/
|
||||
arch_setup_dma_ops(dev, 0, dev->coherent_dma_mask + 1, iommu,
|
||||
attr == DEV_DMA_COHERENT);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dma_configure);
|
||||
|
||||
/**
|
||||
* acpi_dma_deconfigure - Tear-down DMA configuration for the device.
|
||||
* @dev: The pointer to the device
|
||||
*/
|
||||
void acpi_dma_deconfigure(struct device *dev)
|
||||
{
|
||||
arch_teardown_dma_ops(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dma_deconfigure);
|
||||
|
||||
static void acpi_init_coherency(struct acpi_device *adev)
|
||||
{
|
||||
unsigned long long cca = 0;
|
||||
|
|
|
|||
|
|
@ -47,32 +47,15 @@ static void acpi_sleep_tts_switch(u32 acpi_state)
|
|||
}
|
||||
}
|
||||
|
||||
static void acpi_sleep_pts_switch(u32 acpi_state)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_execute_simple_method(NULL, "\\_PTS", acpi_state);
|
||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||
/*
|
||||
* OS can't evaluate the _PTS object correctly. Some warning
|
||||
* message will be printed. But it won't break anything.
|
||||
*/
|
||||
printk(KERN_NOTICE "Failure in evaluating _PTS object\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int sleep_notify_reboot(struct notifier_block *this,
|
||||
static int tts_notify_reboot(struct notifier_block *this,
|
||||
unsigned long code, void *x)
|
||||
{
|
||||
acpi_sleep_tts_switch(ACPI_STATE_S5);
|
||||
|
||||
acpi_sleep_pts_switch(ACPI_STATE_S5);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block sleep_notifier = {
|
||||
.notifier_call = sleep_notify_reboot,
|
||||
static struct notifier_block tts_notifier = {
|
||||
.notifier_call = tts_notify_reboot,
|
||||
.next = NULL,
|
||||
.priority = 0,
|
||||
};
|
||||
|
|
@ -691,6 +674,14 @@ static void acpi_sleep_suspend_setup(void)
|
|||
if (acpi_sleep_state_supported(i))
|
||||
sleep_states[i] = 1;
|
||||
|
||||
/*
|
||||
* Use suspend-to-idle by default if ACPI_FADT_LOW_POWER_S0 is set and
|
||||
* the default suspend mode was not selected from the command line.
|
||||
*/
|
||||
if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0 &&
|
||||
mem_sleep_default > PM_SUSPEND_MEM)
|
||||
mem_sleep_default = PM_SUSPEND_FREEZE;
|
||||
|
||||
suspend_set_ops(old_suspend_ordering ?
|
||||
&acpi_suspend_ops_old : &acpi_suspend_ops);
|
||||
freeze_set_ops(&acpi_freeze_ops);
|
||||
|
|
@ -916,9 +907,9 @@ int __init acpi_sleep_init(void)
|
|||
pr_info(PREFIX "(supports%s)\n", supported);
|
||||
|
||||
/*
|
||||
* Register the sleep_notifier to reboot notifier list so that the _TTS
|
||||
* and _PTS object can also be evaluated when the system enters S5.
|
||||
* Register the tts_notifier to reboot notifier list so that the _TTS
|
||||
* object can also be evaluated when the system enters S5.
|
||||
*/
|
||||
register_reboot_notifier(&sleep_notifier);
|
||||
register_reboot_notifier(&tts_notifier);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include <linux/thermal.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
|
|
|
|||
|
|
@ -296,6 +296,26 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "Dell XPS 17 L702X",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* https://bugzilla.redhat.com/show_bug.cgi?id=1204476 */
|
||||
/* https://bugs.launchpad.net/ubuntu/+source/linux-lts-trusty/+bug/1416940 */
|
||||
.callback = video_detect_force_native,
|
||||
.ident = "HP Pavilion dv6",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6 Notebook PC"),
|
||||
},
|
||||
},
|
||||
|
||||
{ },
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue