diff options
| author | 2018-09-15 20:50:42 +0200 | |
|---|---|---|
| committer | 2018-09-15 20:50:42 +0200 | |
| commit | 9ac669fc01dbfef707ecaa6b618c0d03294cca16 (patch) | |
| tree | 3207995766ab5664c60026daae5da268806a3262 /drivers/acpi | |
| parent | clockevents: Warn if cpu_all_mask is used as cpumask (diff) | |
| parent | RISC-V: Request newstat syscalls (diff) | |
Merge tag 'y2038' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground into timers/core
Pull more y2038 work from Arnd Bergman:
y2038: convert more syscalls
Here is another set of system call changes to prepare the change over to
64-bit time_t. As before, the strategy is to change system calls that
take a 'struct timespec' argument over to 'struct __kernel_timespec',
which for now is defined to be the same but will get redefined to use a
64-bit time_t argument once we are ready to modify the system call tables.
The major change from previous patches is that the plan is no longer
to directly use the 'compat' system calls for providing compatibility
with the existing 32-bit time_t based entry points. Instead, we rename
the compat code to something that makes more sense on 32-bit architectures,
e.g. compat_timespec becomes old_timespec32.
With the renamed types in place, change over the 'stat' and 'utimes'
families of system calls, sched_rr_get_interval, recvmmsg and
rt_sigtimedwait. Another series for poll, select and io_pgetevents is
currently being tested.
Diffstat (limited to 'drivers/acpi')
34 files changed, 633 insertions, 302 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b533eeb6139d..dd1eea90f67f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -3,13 +3,15 @@ # ACPI Configuration # +config ARCH_SUPPORTS_ACPI + bool + menuconfig ACPI bool "ACPI (Advanced Configuration and Power Interface) Support" - depends on !IA64_HP_SIM - depends on IA64 || X86 || ARM64 + depends on ARCH_SUPPORTS_ACPI depends on PCI select PNP - default y if (IA64 || X86) + default y if X86 help Advanced Configuration and Power Interface (ACPI) support for Linux requires an ACPI-compliant platform (hardware/firmware), diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index f8fecfec5df9..9706613eecf9 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -879,6 +879,7 @@ static void acpi_lpss_dismiss(struct device *dev) #define LPSS_GPIODEF0_DMA_LLP BIT(13) static DEFINE_MUTEX(lpss_iosf_mutex); +static bool lpss_iosf_d3_entered; static void lpss_iosf_enter_d3_state(void) { @@ -921,6 +922,9 @@ static void lpss_iosf_enter_d3_state(void) iosf_mbi_modify(LPSS_IOSF_UNIT_LPIOEP, MBI_CR_WRITE, LPSS_IOSF_GPIODEF0, value1, mask1); + + lpss_iosf_d3_entered = true; + exit: mutex_unlock(&lpss_iosf_mutex); } @@ -935,6 +939,11 @@ static void lpss_iosf_exit_d3_state(void) mutex_lock(&lpss_iosf_mutex); + if (!lpss_iosf_d3_entered) + goto exit; + + lpss_iosf_d3_entered = false; + iosf_mbi_modify(LPSS_IOSF_UNIT_LPIOEP, MBI_CR_WRITE, LPSS_IOSF_GPIODEF0, value1, mask1); @@ -944,13 +953,13 @@ static void lpss_iosf_exit_d3_state(void) iosf_mbi_modify(LPSS_IOSF_UNIT_LPIO1, MBI_CFG_WRITE, LPSS_IOSF_PMCSR, value2, mask2); +exit: mutex_unlock(&lpss_iosf_mutex); } -static int acpi_lpss_suspend(struct device *dev, bool runtime) +static int acpi_lpss_suspend(struct device *dev, bool wakeup) { struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); - bool wakeup = runtime || device_may_wakeup(dev); int ret; if (pdata->dev_desc->flags & LPSS_SAVE_CTX) @@ -963,14 +972,14 @@ static int acpi_lpss_suspend(struct device *dev, bool runtime) * wrong status for devices being about to be powered off. See * lpss_iosf_enter_d3_state() for further information. */ - if ((runtime || !pm_suspend_via_firmware()) && + if (acpi_target_system_state() == ACPI_STATE_S0 && lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available()) lpss_iosf_enter_d3_state(); return ret; } -static int acpi_lpss_resume(struct device *dev, bool runtime) +static int acpi_lpss_resume(struct device *dev) { struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev)); int ret; @@ -979,8 +988,7 @@ static int acpi_lpss_resume(struct device *dev, bool runtime) * This call is kept first to be in symmetry with * acpi_lpss_runtime_suspend() one. */ - if ((runtime || !pm_resume_via_firmware()) && - lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available()) + if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available()) lpss_iosf_exit_d3_state(); ret = acpi_dev_resume(dev); @@ -1004,12 +1012,12 @@ static int acpi_lpss_suspend_late(struct device *dev) return 0; ret = pm_generic_suspend_late(dev); - return ret ? ret : acpi_lpss_suspend(dev, false); + return ret ? ret : acpi_lpss_suspend(dev, device_may_wakeup(dev)); } static int acpi_lpss_resume_early(struct device *dev) { - int ret = acpi_lpss_resume(dev, false); + int ret = acpi_lpss_resume(dev); return ret ? ret : pm_generic_resume_early(dev); } @@ -1024,7 +1032,7 @@ static int acpi_lpss_runtime_suspend(struct device *dev) static int acpi_lpss_runtime_resume(struct device *dev) { - int ret = acpi_lpss_resume(dev, true); + int ret = acpi_lpss_resume(dev); return ret ? ret : pm_generic_runtime_resume(dev); } diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 51c386bf230d..0f28a38a43ea 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -164,8 +164,8 @@ struct acpi_namespace_node { #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ #define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */ +#define ANOBJ_NODE_EARLY_INIT 0x80 /* acpi_exec only: Node was create via init file (-fi) */ -#define IMPLICIT_EXTERNAL 0x02 /* iASL only: This object created implicitly via External */ #define ANOBJ_IS_EXTERNAL 0x08 /* iASL only: This object created via External() */ #define ANOBJ_METHOD_NO_RETVAL 0x10 /* iASL only: Method has no return value */ #define ANOBJ_METHOD_SOME_NO_RETVAL 0x20 /* iASL only: Method has at least one return value */ diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 3825df923480..bbb3b4d1e796 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -25,14 +25,15 @@ /* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */ #define ACPI_NS_NO_UPSEARCH 0 -#define ACPI_NS_SEARCH_PARENT 0x01 -#define ACPI_NS_DONT_OPEN_SCOPE 0x02 -#define ACPI_NS_NO_PEER_SEARCH 0x04 -#define ACPI_NS_ERROR_IF_FOUND 0x08 -#define ACPI_NS_PREFIX_IS_SCOPE 0x10 -#define ACPI_NS_EXTERNAL 0x20 -#define ACPI_NS_TEMPORARY 0x40 -#define ACPI_NS_OVERRIDE_IF_FOUND 0x80 +#define ACPI_NS_SEARCH_PARENT 0x0001 +#define ACPI_NS_DONT_OPEN_SCOPE 0x0002 +#define ACPI_NS_NO_PEER_SEARCH 0x0004 +#define ACPI_NS_ERROR_IF_FOUND 0x0008 +#define ACPI_NS_PREFIX_IS_SCOPE 0x0010 +#define ACPI_NS_EXTERNAL 0x0020 +#define ACPI_NS_TEMPORARY 0x0040 +#define ACPI_NS_OVERRIDE_IF_FOUND 0x0080 +#define ACPI_NS_EARLY_INIT 0x0100 /* Flags for acpi_ns_walk_namespace */ diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 2733cd4e418c..3374d41582b5 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -180,6 +180,8 @@ char acpi_ut_remove_leading_zeros(char **string); u8 acpi_ut_detect_hex_prefix(char **string); +void acpi_ut_remove_hex_prefix(char **string); + u8 acpi_ut_detect_octal_prefix(char **string); /* diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index 556ff59bbbfc..3e5f95390f0d 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c @@ -763,7 +763,12 @@ acpi_db_command_dispatch(char *input_buffer, case CMD_DISASSEMBLE: case CMD_DISASM: +#ifdef ACPI_DISASSEMBLER (void)acpi_db_disassemble_method(acpi_gbl_db_args[1]); +#else + acpi_os_printf + ("The AML Disassembler is not configured/present\n"); +#endif break; case CMD_DUMP: @@ -872,7 +877,12 @@ acpi_db_command_dispatch(char *input_buffer, case CMD_LIST: +#ifdef ACPI_DISASSEMBLER acpi_db_disassemble_aml(acpi_gbl_db_args[1], op); +#else + acpi_os_printf + ("The AML Disassembler is not configured/present\n"); +#endif break; case CMD_LOCKS: diff --git a/drivers/acpi/acpica/dbmethod.c b/drivers/acpi/acpica/dbmethod.c index 9fcecf104ba0..d8b7a0fe92ec 100644 --- a/drivers/acpi/acpica/dbmethod.c +++ b/drivers/acpi/acpica/dbmethod.c @@ -216,6 +216,7 @@ cleanup: acpi_ut_remove_reference(obj_desc); } +#ifdef ACPI_DISASSEMBLER /******************************************************************************* * * FUNCTION: acpi_db_disassemble_aml @@ -242,9 +243,8 @@ void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op) if (statements) { num_statements = strtoul(statements, NULL, 0); } -#ifdef ACPI_DISASSEMBLER + acpi_dm_disassemble(NULL, op, num_statements); -#endif } /******************************************************************************* @@ -317,8 +317,6 @@ acpi_status acpi_db_disassemble_method(char *name) walk_state->parse_flags |= ACPI_PARSE_DISASSEMBLE; status = acpi_ps_parse_aml(walk_state); - -#ifdef ACPI_DISASSEMBLER (void)acpi_dm_parse_deferred_ops(op); /* Now we can disassemble the method */ @@ -326,7 +324,6 @@ acpi_status acpi_db_disassemble_method(char *name) acpi_gbl_dm_opt_verbose = FALSE; acpi_dm_disassemble(NULL, op, 0); acpi_gbl_dm_opt_verbose = TRUE; -#endif acpi_ps_delete_parse_tree(op); @@ -337,6 +334,7 @@ acpi_status acpi_db_disassemble_method(char *name) acpi_ut_release_owner_id(&obj_desc->method.owner_id); return (AE_OK); } +#endif /******************************************************************************* * diff --git a/drivers/acpi/acpica/dbxface.c b/drivers/acpi/acpica/dbxface.c index 4647aa8efecb..f2526726daf6 100644 --- a/drivers/acpi/acpica/dbxface.c +++ b/drivers/acpi/acpica/dbxface.c @@ -10,6 +10,7 @@ #include "amlcode.h" #include "acdebug.h" #include "acinterp.h" +#include "acparser.h" #define _COMPONENT ACPI_CA_DEBUGGER ACPI_MODULE_NAME("dbxface") @@ -262,10 +263,17 @@ acpi_db_single_step(struct acpi_walk_state *walk_state, } } - /* Now we can display it */ + /* Now we can disassemble and display it */ #ifdef ACPI_DISASSEMBLER acpi_dm_disassemble(walk_state, display_op, ACPI_UINT32_MAX); +#else + /* + * The AML Disassembler is not configured - at least we can + * display the opcode value and name + */ + acpi_os_printf("AML Opcode: %4.4X %s\n", op->common.aml_opcode, + acpi_ps_get_opcode_name(op->common.aml_opcode)); #endif if ((op->common.aml_opcode == AML_IF_OP) || diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 7c937595dfcb..30fe89545d6a 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -15,6 +15,10 @@ #include "acnamesp.h" #include "acparser.h" +#ifdef ACPI_EXEC_APP +#include "aecommon.h" +#endif + #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dsfield") @@ -259,6 +263,13 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, u64 position; union acpi_parse_object *child; +#ifdef ACPI_EXEC_APP + u64 value = 0; + union acpi_operand_object *result_desc; + union acpi_operand_object *obj_desc; + char *name_path; +#endif + ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); /* First field starts at bit zero */ @@ -391,6 +402,25 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } +#ifdef ACPI_EXEC_APP + name_path = + acpi_ns_get_external_pathname(info-> + field_node); + obj_desc = + acpi_ut_create_integer_object + (value); + if (ACPI_SUCCESS + (ae_lookup_init_file_entry + (name_path, &value))) { + acpi_ex_write_data_to_field + (obj_desc, + acpi_ns_get_attached_object + (info->field_node), + &result_desc); + } + acpi_ut_remove_reference(obj_desc); + ACPI_FREE(name_path); +#endif } } @@ -573,7 +603,9 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { flags |= ACPI_NS_TEMPORARY; } - +#ifdef ACPI_EXEC_APP + flags |= ACPI_NS_OVERRIDE_IF_FOUND; +#endif /* * Walk the list of entries in the field_list * Note: field_list can be of zero length. In this case, Arg will be NULL. diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 3de794bcf8fa..69603ba52a3a 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -528,13 +528,18 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value) status = acpi_hw_read(&value64, &acpi_gbl_FADT.xpm2_control_block); - value = (u32)value64; + if (ACPI_SUCCESS(status)) { + value = (u32)value64; + } break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ status = acpi_hw_read(&value64, &acpi_gbl_FADT.xpm_timer_block); - value = (u32)value64; + if (ACPI_SUCCESS(status)) { + value = (u32)value64; + } + break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index fc0c2e2328cd..d8b8fc2ff563 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -51,16 +51,18 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state) return_ACPI_STATUS(status); } - /* - * 1) Disable all GPEs - * 2) Enable all wakeup GPEs - */ + /* Disable all GPEs */ status = acpi_hw_disable_all_gpes(); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } + status = acpi_hw_clear_acpi_status(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } acpi_gbl_system_awake_and_running = FALSE; + /* Enable all wakeup GPEs */ status = acpi_hw_enable_all_wakeup_gpes(); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 220a718fbce9..e3f10afde5ff 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -558,6 +558,14 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, (char *)¤t_node->name, current_node)); } +#ifdef ACPI_EXEC_APP + if ((status == AE_ALREADY_EXISTS) && + (this_node->flags & ANOBJ_NODE_EARLY_INIT)) { + this_node->flags &= ~ANOBJ_NODE_EARLY_INIT; + status = AE_OK; + } +#endif + #ifdef ACPI_ASL_COMPILER /* * If this ACPI name already exists within the namespace as an @@ -613,13 +621,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, /* Special handling for the last segment (num_segments == 0) */ else { -#ifdef ACPI_ASL_COMPILER - if (!acpi_gbl_disasm_flag - && (this_node->flags & ANOBJ_IS_EXTERNAL)) { - this_node->flags &= ~IMPLICIT_EXTERNAL; - } -#endif - /* * Sanity typecheck of the target object: * @@ -683,6 +684,11 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, } } } +#ifdef ACPI_EXEC_APP + if (flags & ACPI_NS_EARLY_INIT) { + this_node->flags |= ANOBJ_NODE_EARLY_INIT; + } +#endif *return_node = this_node; return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index e9c9a63bb6a4..f594ab75a5fe 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -381,7 +381,6 @@ acpi_ns_search_and_enter(u32 target_name, if (flags & ACPI_NS_EXTERNAL || (walk_state && walk_state->opcode == AML_SCOPE_OP)) { new_node->flags |= ANOBJ_IS_EXTERNAL; - new_node->flags |= IMPLICIT_EXTERNAL; } #endif diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index bc5f05906bd1..34fc2f7476ed 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -22,6 +22,7 @@ #include "acdispat.h" #include "amlcode.h" #include "acconvert.h" +#include "acnamesp.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psloop") @@ -497,6 +498,18 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) status = acpi_ps_create_op(walk_state, aml_op_start, &op); if (ACPI_FAILURE(status)) { + /* + * ACPI_PARSE_MODULE_LEVEL means that we are loading a table by + * executing it as a control method. However, if we encounter + * an error while loading the table, we need to keep trying to + * load the table rather than aborting the table load. Set the + * status to AE_OK to proceed with the table load. + */ + if ((walk_state-> + parse_flags & ACPI_PARSE_MODULE_LEVEL) + && status == AE_ALREADY_EXISTS) { + status = AE_OK; + } if (status == AE_CTRL_PARSE_CONTINUE) { continue; } @@ -515,12 +528,18 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - if (walk_state->opcode == AML_SCOPE_OP) { + if (acpi_ns_opens_scope + (acpi_ps_get_opcode_info + (walk_state->opcode)->object_type)) { /* - * If the scope op fails to parse, skip the body of the - * scope op because the parse failure indicates that the - * device may not exist. + * If the scope/device op fails to parse, skip the body of + * the scope op because the parse failure indicates that + * the device may not exist. */ + ACPI_ERROR((AE_INFO, + "Skip parsing opcode %s", + acpi_ps_get_opcode_name + (walk_state->opcode))); walk_state->parser_state.aml = walk_state->aml + 1; walk_state->parser_state.aml = @@ -528,8 +547,6 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) (&walk_state->parser_state); walk_state->aml = walk_state->parser_state.aml; - ACPI_ERROR((AE_INFO, - "Skipping Scope block")); } continue; @@ -694,6 +711,25 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state) acpi_ps_next_parse_state(walk_state, op, status); if (status == AE_CTRL_PENDING) { status = AE_OK; + } else + if ((walk_state-> + parse_flags & ACPI_PARSE_MODULE_LEVEL) + && (ACPI_AML_EXCEPTION(status) + || status == AE_ALREADY_EXISTS + || status == AE_NOT_FOUND)) { + /* + * ACPI_PARSE_MODULE_LEVEL flag means that we + * are currently loading a table by executing + * it as a control method. However, if we + * encounter an error while loading the table, + * we need to keep trying to load the table + * rather than aborting the table load (setting + * the status to AE_OK continues the table + * load). If we get a failure at this point, it + * means that the dispatcher got an error while + * trying to execute the Op. + */ + status = AE_OK; } } diff --git a/drivers/acpi/acpica/tbdata.c b/drivers/acpi/acpica/tbdata.c index 51891f9fb057..862149c8a208 100644 --- a/drivers/acpi/acpica/tbdata.c +++ b/drivers/acpi/acpica/tbdata.c @@ -516,9 +516,9 @@ acpi_tb_verify_temp_table(struct acpi_table_desc *table_desc, acpi_tb_check_duplication(table_desc, table_index); if (ACPI_FAILURE(status)) { if (status != AE_CTRL_TERMINATE) { - ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, + ACPI_EXCEPTION((AE_INFO, status, "%4.4s 0x%8.8X%8.8X" - " Table is duplicated", + " Table is already loaded", acpi_ut_valid_nameseg (table_desc->signature. ascii) ? table_desc-> diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index 118f3ff1fbb5..8cc4392c61f3 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -355,6 +355,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) u16 original_count; u16 new_count = 0; acpi_cpu_flags lock_flags; + char *message; ACPI_FUNCTION_NAME(ut_update_ref_count); @@ -391,6 +392,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) object, object->common.type, acpi_ut_get_object_type_name(object), new_count)); + message = "Incremement"; break; case REF_DECREMENT: @@ -420,6 +422,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) if (new_count == 0) { acpi_ut_delete_internal_obj(object); } + message = "Decrement"; break; default: @@ -436,8 +439,8 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) */ if (new_count > ACPI_MAX_REFERENCE_COUNT) { ACPI_WARNING((AE_INFO, - "Large Reference Count (0x%X) in object %p, Type=0x%.2X", - new_count, object, object->common.type)); + "Large Reference Count (0x%X) in object %p, Type=0x%.2X Operation=%s", + new_count, object, object->common.type, message)); } } diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c index 5a64ddaed8a3..e47430272692 100644 --- a/drivers/acpi/acpica/uterror.c +++ b/drivers/acpi/acpica/uterror.c @@ -182,19 +182,19 @@ acpi_ut_prefixed_namespace_error(const char *module_name, switch (lookup_status) { case AE_ALREADY_EXISTS: - acpi_os_printf("\n" ACPI_MSG_BIOS_ERROR); + acpi_os_printf(ACPI_MSG_BIOS_ERROR); message = "Failure creating"; break; case AE_NOT_FOUND: - acpi_os_printf("\n" ACPI_MSG_BIOS_ERROR); + acpi_os_printf(ACPI_MSG_BIOS_ERROR); message = "Could not resolve"; break; default: - acpi_os_printf("\n" ACPI_MSG_ERROR); + acpi_os_printf(ACPI_MSG_ERROR); message = "Failure resolving"; break; } diff --git a/drivers/acpi/acpica/utstrsuppt.c b/drivers/acpi/acpica/utstrsuppt.c index 954f8e3e35cd..05ff20049b87 100644 --- a/drivers/acpi/acpica/utstrsuppt.c +++ b/drivers/acpi/acpica/utstrsuppt.c @@ -231,14 +231,34 @@ char acpi_ut_remove_whitespace(char **string) u8 acpi_ut_detect_hex_prefix(char **string) { + char *initial_position = *string; + acpi_ut_remove_hex_prefix(string); + if (*string != initial_position) { + return (TRUE); /* String is past leading 0x */ + } + + return (FALSE); /* Not a hex string */ +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_remove_hex_prefix + * + * PARAMETERS: string - Pointer to input ASCII string + * + * RETURN: none + * + * DESCRIPTION: Remove a hex "0x" prefix + * + ******************************************************************************/ + +void acpi_ut_remove_hex_prefix(char **string) +{ if ((**string == ACPI_ASCII_ZERO) && (tolower((int)*(*string + 1)) == 'x')) { *string += 2; /* Go past the leading 0x */ - return (TRUE); } - - return (FALSE); /* Not a hex string */ } /******************************************************************************* diff --git a/drivers/acpi/acpica/utstrtoul64.c b/drivers/acpi/acpica/utstrtoul64.c index 8fadad242db6..5fde619a8bbd 100644 --- a/drivers/acpi/acpica/utstrtoul64.c +++ b/drivers/acpi/acpica/utstrtoul64.c @@ -218,7 +218,7 @@ u64 acpi_ut_implicit_strtoul64(char *string) * implicit conversions, and the "0x" prefix is "not allowed". * However, allow a "0x" prefix as an ACPI extension. */ - acpi_ut_detect_hex_prefix(&string); + acpi_ut_remove_hex_prefix(&string); if (!acpi_ut_remove_leading_zeros(&string)) { return_VALUE(0); diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 7a3a541046ed..08f26db2da7e 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -947,6 +947,24 @@ static int nc_dma_get_range(struct device *dev, u64 *size) return 0; } +static int rc_dma_get_range(struct device *dev, u64 *size) +{ + struct acpi_iort_node *node; + struct acpi_iort_root_complex *rc; + + node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, + iort_match_node_callback, dev); + if (!node || node->revision < 1) + return -ENODEV; + + rc = (struct acpi_iort_root_complex *)node->node_data; + + *size = rc->memory_address_limit >= 64 ? U64_MAX : + 1ULL<<rc->memory_address_limit; + + return 0; +} + /** * iort_dma_setup() - Set-up device DMA parameters. * @@ -960,25 +978,28 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) int ret, msb; /* - * Set default coherent_dma_mask to 32 bit. Drivers are expected to - * setup the correct supported mask. + * If @dev is expected to be DMA-capable then the bus code that created + * it should have initialised its dma_mask pointer by this point. For + * now, we'll continue the legacy behaviour of coercing it to the + * coherent mask if not, but we'll no longer do so quietly. */ - 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) + if (!dev->dma_mask) { + dev_warn(dev, "DMA mask not set\n"); dev->dma_mask = &dev->coherent_dma_mask; + } - size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); + if (dev->coherent_dma_mask) + size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); + else + size = 1ULL << 32; - if (dev_is_pci(dev)) + if (dev_is_pci(dev)) { ret = acpi_dma_get_range(dev, &dmaaddr, &offset, &size); - else + if (ret == -ENODEV) + ret = rc_dma_get_range(dev, &size); + } else { ret = nc_dma_get_range(dev, &size); + } if (!ret) { msb = fls64(dmaaddr + size - 1); @@ -993,6 +1014,7 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size) * Limit coherent and dma mask based on size * retrieved from firmware. */ + dev->bus_dma_mask = mask; dev->coherent_dma_mask = mask; *dev->dma_mask = mask; } diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b0113a5802a3..cb97b6105f52 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -23,18 +23,18 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/async.h> +#include <linux/delay.h> +#include <linux/dmi.h> +#include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/module.h> #include <linux/mutex.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/jiffies.h> -#include <linux/async.h> -#include <linux/dmi.h> -#include <linux/delay.h> #include <linux/slab.h> #include <linux/suspend.h> +#include <linux/types.h> + #include <asm/unaligned.h> #ifdef CONFIG_ACPI_PROCFS_POWER @@ -364,6 +364,20 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_SERIAL_NUMBER, }; +static enum power_supply_property energy_battery_full_cap_broken_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_POWER_NOW, + POWER_SUPPLY_PROP_ENERGY_NOW, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + /* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ @@ -577,8 +591,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && (s16)(battery->rate_now) < 0) { battery->rate_now = abs((s16)battery->rate_now); - printk_once(KERN_WARNING FW_BUG - "battery: (dis)charge rate invalid.\n"); + pr_warn_once(FW_BUG "battery: (dis)charge rate invalid.\n"); } if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) @@ -717,10 +730,11 @@ void battery_hook_register(struct acpi_battery_hook *hook) */ pr_err("extension failed to load: %s", hook->name); __battery_hook_unregister(hook, 0); - return; + goto end; } } pr_info("new extension: %s\n", hook->name); +end: mutex_unlock(&hook_mutex); } EXPORT_SYMBOL_GPL(battery_hook_register); @@ -732,7 +746,7 @@ EXPORT_SYMBOL_GPL(battery_hook_register); */ static void battery_hook_add_battery(struct acpi_battery *battery) { - struct acpi_battery_hook *hook_node; + struct acpi_battery_hook *hook_node, *tmp; mutex_lock(&hook_mutex); INIT_LIST_HEAD(&battery->list); @@ -744,15 +758,15 @@ static void battery_hook_add_battery(struct acpi_battery *battery) * when a battery gets hotplugged or initialized * during the battery module initialization. */ - list_for_each_entry(hook_node, &battery_hook_list, list) { + list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) { if (hook_node->add_battery(battery->bat)) { /* * The notification of the extensions has failed, to * prevent further errors we will unload the extension. */ - __battery_hook_unregister(hook_node, 0); pr_err("error in extension, unloading: %s", hook_node->name); + __battery_hook_unregister(hook_node, 0); } } mutex_unlock(&hook_mutex); @@ -798,6 +812,11 @@ static int sysfs_add_battery(struct acpi_battery *battery) battery->bat_desc.properties = charge_battery_props; battery->bat_desc.num_properties = ARRAY_SIZE(charge_battery_props); + } else if (battery->full_charge_capacity == 0) { + battery->bat_desc.properties = + energy_battery_full_cap_broken_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_full_cap_broken_props); } else { battery->bat_desc.properties = energy_battery_props; battery->bat_desc.num_properties = @@ -917,10 +936,11 @@ static void acpi_battery_quirks(struct acpi_battery *battery) static int acpi_battery_update(struct acpi_battery *battery, bool resume) { - int result, old_present = acpi_battery_present(battery); - result = acpi_battery_get_status(battery); + int result = acpi_battery_get_status(battery); + if (result) return result; + if (!acpi_battery_present(battery)) { sysfs_remove_battery(battery); battery->update_time = 0; @@ -930,8 +950,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) if (resume) return 0; - if (!battery->update_time || - old_present != acpi_battery_present(battery)) { + if (!battery->update_time) { result = acpi_battery_get_info(battery); if (result) return result; @@ -1020,7 +1039,7 @@ static int acpi_battery_info_proc_show(struct seq_file *seq, void *offset) acpi_battery_units(battery)); seq_printf(seq, "battery technology: %srechargeable\n", - (!battery->technology)?"non-":""); + battery->technology ? "" : "non-"); if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "design voltage: unknown\n"); @@ -1111,11 +1130,12 @@ static int acpi_battery_alarm_proc_show(struct seq_file *seq, void *offset) goto end; } seq_printf(seq, "alarm: "); - if (!battery->alarm) - seq_printf(seq, "unsupported\n"); - else + if (battery->alarm) { seq_printf(seq, "%u %sh\n", battery->alarm, acpi_battery_units(battery)); + } else { + seq_printf(seq, "unsupported\n"); + } end: if (result) seq_printf(seq, "ERROR: Unable to read battery alarm\n"); @@ -1148,9 +1168,9 @@ static ssize_t acpi_battery_write_alarm(struct file *file, } result = acpi_battery_set_alarm(battery); end: - if (!result) - return count; - return result; + if (result) + return result; + return count; } static int acpi_battery_alarm_proc_open(struct inode *inode, struct file *file) @@ -1169,8 +1189,7 @@ static const struct file_operations acpi_battery_alarm_fops = { static int acpi_battery_add_fs(struct acpi_device *device) { - printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," - " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); + pr_warning(PREFIX "Deprecated procfs I/F for battery is loaded, please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_battery_dir); @@ -1246,7 +1265,9 @@ static int battery_notify(struct notifier_block *nb, if (!acpi_battery_present(battery)) return 0; - if (!battery->bat) { + if (battery->bat) { + acpi_battery_refresh(battery); + } else { result = acpi_battery_get_info(battery); if (result) return result; @@ -1254,8 +1275,7 @@ static int battery_notify(struct notifier_block *nb, result = sysfs_add_battery(battery); if (result) return result; - } else - acpi_battery_refresh(battery); + } acpi_battery_init_alarm(battery); acpi_battery_get_state(battery); @@ -1397,7 +1417,7 @@ static int acpi_battery_add(struct acpi_device *device) } #endif - printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", + pr_info(PREFIX "%s Slot [%s] (battery %s)\n", ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), device->status.battery_present ? "present" : "absent"); diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 84b4a62018eb..292088fcc624 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -66,37 +66,10 @@ static int set_copy_dsdt(const struct dmi_system_id *id) return 0; } #endif -static int set_gbl_term_list(const struct dmi_system_id *id) -{ - acpi_gbl_execute_tables_as_methods = 1; - return 0; -} -static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = { - /* - * Touchpad on Dell XPS 9570/Precision M5530 doesn't work under I2C - * mode. - * https://bugzilla.kernel.org/show_bug.cgi?id=198515 - */ - { - .callback = set_gbl_term_list, - .ident = "Dell Precision M5530", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Precision M5530"), - }, - }, - { - .callback = set_gbl_term_list, - .ident = "Dell XPS 15 9570", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 9570"), - }, - }, +static const struct dmi_system_id dsdt_dmi_table[] __initconst = { /* * Invoke DSDT corruption work-around on all Toshiba Satellite. - * DSDT will be copied to memory. * https://bugzilla.kernel.org/show_bug.cgi?id=14679 */ { @@ -110,7 +83,7 @@ static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = { {} }; #else -static const struct dmi_system_id acpi_quirks_dmi_table[] __initconst = { +static const struct dmi_system_id dsdt_dmi_table[] __initconst = { {} }; #endif @@ -962,7 +935,7 @@ static int acpi_device_probe(struct device *dev) return 0; } -static int acpi_device_remove(struct device * dev) +static int acpi_device_remove(struct device *dev) { struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = acpi_dev->driver; @@ -1060,8 +1033,11 @@ void __init acpi_early_init(void) acpi_permanent_mmap = true; - /* Check machine-specific quirks */ - dmi_check_system(acpi_quirks_dmi_table); + /* + * If the machine falls into the DMI check table, + * DSDT will be copied to memory + */ + dmi_check_system(dsdt_dmi_table); status = acpi_reallocate_root_table(); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 2345a5ee2dbb..a19ff3977ac4 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -21,6 +21,7 @@ #define pr_fmt(fmt) "ACPI: button: " fmt +#include <linux/compiler.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -235,9 +236,6 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) button->last_time = ktime_get(); } - if (state) - acpi_pm_wakeup_event(&device->dev); - ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); if (ret == NOTIFY_DONE) ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, @@ -252,7 +250,8 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) return ret; } -static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) +static int __maybe_unused acpi_button_state_seq_show(struct seq_file *seq, + void *offset) { struct acpi_device *device = seq->private; int state; @@ -366,7 +365,8 @@ int acpi_lid_open(void) } EXPORT_SYMBOL(acpi_lid_open); -static int acpi_lid_update_state(struct acpi_device *device) +static int acpi_lid_update_state(struct acpi_device *device, + bool signal_wakeup) { int state; @@ -374,6 +374,9 @@ static int acpi_lid_update_state(struct acpi_device *device) if (state < 0) return state; + if (state && signal_wakeup) + acpi_pm_wakeup_event(&device->dev); + return acpi_lid_notify_state(device, state); } @@ -384,7 +387,7 @@ static void acpi_lid_initialize_state(struct acpi_device *device) (void)acpi_lid_notify_state(device, 1); break; case ACPI_BUTTON_LID_INIT_METHOD: - (void)acpi_lid_update_state(device); + (void)acpi_lid_update_state(device, false); break; case ACPI_BUTTON_LID_INIT_IGNORE: default: @@ -409,7 +412,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) users = button->input->users; mutex_unlock(&button->input->mutex); if (users) - acpi_lid_update_state(device); + acpi_lid_update_state(device, true); } else { int keycode; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 442a9e24f439..d4e5610e09c5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -2042,7 +2042,21 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { .ident = "Thinkpad X1 Carbon 6th", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20KGS3JF01"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Thinkpad X1 Carbon 6th"), + }, + }, + { + .ident = "ThinkPad X1 Carbon 6th", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"), + }, + }, + { + .ident = "ThinkPad X1 Yoga 3rd", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"), }, }, { }, diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index d15814e1727f..b072cfc5f20e 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -408,6 +408,8 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, const guid_t *guid; int rc, i; + if (cmd_rc) + *cmd_rc = -EINVAL; func = cmd; if (cmd == ND_CMD_CALL) { call_pkg = buf; @@ -518,6 +520,8 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, * If we return an error (like elsewhere) then caller wouldn't * be able to rely upon data returned to make calculation. */ + if (cmd_rc) + *cmd_rc = 0; return 0; } @@ -1273,7 +1277,7 @@ static ssize_t scrub_show(struct device *dev, mutex_lock(&acpi_desc->init_mutex); rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, - work_busy(&acpi_desc->dwork.work) + acpi_desc->scrub_busy && !acpi_desc->cancel ? "+\n" : "\n"); mutex_unlock(&acpi_desc->init_mutex); } @@ -1695,7 +1699,7 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, { struct acpi_device *adev, *adev_dimm; struct device *dev = acpi_desc->dev; - unsigned long dsm_mask; + unsigned long dsm_mask, label_mask; const guid_t *guid; int i; int family = -1; @@ -1767,6 +1771,16 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, 1ULL << i)) set_bit(i, &nfit_mem->dsm_mask); + /* + * Prefer the NVDIMM_FAMILY_INTEL label read commands if present + * due to their better semantics handling locked capacity. + */ + label_mask = 1 << ND_CMD_GET_CONFIG_SIZE | 1 << ND_CMD_GET_CONFIG_DATA + | 1 << ND_CMD_SET_CONFIG_DATA; + if (family == NVDIMM_FAMILY_INTEL + && (dsm_mask & label_mask) == label_mask) + return 0; + if (acpi_nvdimm_has_method(adev_dimm, "_LSI") && acpi_nvdimm_has_method(adev_dimm, "_LSR")) { dev_dbg(dev, "%s: has _LSR\n", dev_name(&adev_dimm->dev)); @@ -2555,7 +2569,12 @@ static void ars_complete(struct acpi_nfit_desc *acpi_desc, test_bit(ARS_SHORT, &nfit_spa->ars_state) ? "short" : "long"); clear_bit(ARS_SHORT, &nfit_spa->ars_state); - set_bit(ARS_DONE, &nfit_spa->ars_state); + if (test_and_clear_bit(ARS_REQ_REDO, &nfit_spa->ars_state)) { + set_bit(ARS_SHORT, &nfit_spa->ars_state); + set_bit(ARS_REQ, &nfit_spa->ars_state); + dev_dbg(dev, "ARS: processing scrub request received while in progress\n"); + } else + set_bit(ARS_DONE, &nfit_spa->ars_state); } static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc) @@ -2939,6 +2958,32 @@ static unsigned int __acpi_nfit_scrub(struct acpi_nfit_desc *acpi_desc, return 0; } +static void __sched_ars(struct acpi_nfit_desc *acpi_desc, unsigned int tmo) +{ + lockdep_assert_held(&acpi_desc->init_mutex); + + acpi_desc->scrub_busy = 1; + /* note this should only be set from within the workqueue */ + if (tmo) + acpi_desc->scrub_tmo = tmo; + queue_delayed_work(nfit_wq, &acpi_desc->dwork, tmo * HZ); +} + +static void sched_ars(struct acpi_nfit_desc *acpi_desc) +{ + __sched_ars(acpi_desc, 0); +} + +static void notify_ars_done(struct acpi_nfit_desc *acpi_desc) +{ + lockdep_assert_held(&acpi_desc->init_mutex); + + acpi_desc->scrub_busy = 0; + acpi_desc->scrub_count++; + if (acpi_desc->scrub_count_state) + sysfs_notify_dirent(acpi_desc->scrub_count_state); +} + static void acpi_nfit_scrub(struct work_struct *work) { struct acpi_nfit_desc *acpi_desc; @@ -2949,14 +2994,10 @@ static void acpi_nfit_scrub(struct work_struct *work) mutex_lock(&acpi_desc->init_mutex); query_rc = acpi_nfit_query_poison(acpi_desc); tmo = __acpi_nfit_scrub(acpi_desc, query_rc); - if (tmo) { - queue_delayed_work(nfit_wq, &acpi_desc->dwork, tmo * HZ); - acpi_desc->scrub_tmo = tmo; - } else { - acpi_desc->scrub_count++; - if (acpi_desc->scrub_count_state) - sysfs_notify_dirent(acpi_desc->scrub_count_state); - } + if (tmo) + __sched_ars(acpi_desc, tmo); + else + notify_ars_done(acpi_desc); memset(acpi_desc->ars_status, 0, acpi_desc->max_ars); mutex_unlock(&acpi_desc->init_mutex); } @@ -3037,7 +3078,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc) break; } - queue_delayed_work(nfit_wq, &acpi_desc->dwork, 0); + sched_ars(acpi_desc); return 0; } @@ -3230,16 +3271,17 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags) if (test_bit(ARS_FAILED, &nfit_spa->ars_state)) continue; - if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state)) + if (test_and_set_bit(ARS_REQ, &nfit_spa->ars_state)) { busy++; - else { + set_bit(ARS_REQ_REDO, &nfit_spa->ars_state); + } else { if (test_bit(ARS_SHORT, &flags)) set_bit(ARS_SHORT, &nfit_spa->ars_state); scheduled++; } } if (scheduled) { - queue_delayed_work(nfit_wq, &acpi_desc->dwork, 0); + sched_ars(acpi_desc); dev_dbg(dev, "ars_scan triggered\n"); } mutex_unlock(&acpi_desc->init_mutex); diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h index 7d15856a739f..d1274ea2d251 100644 --- a/drivers/acpi/nfit/nfit.h +++ b/drivers/acpi/nfit/nfit.h @@ -119,6 +119,7 @@ enum nfit_dimm_notifiers { enum nfit_ars_state { ARS_REQ, + ARS_REQ_REDO, ARS_DONE, ARS_SHORT, ARS_FAILED, @@ -203,6 +204,7 @@ struct acpi_nfit_desc { unsigned int max_ars; unsigned int scrub_count; unsigned int scrub_mode; + unsigned int scrub_busy:1; unsigned int cancel:1; unsigned long dimm_cmd_force_en; unsigned long bus_cmd_force_en; diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c index 8a8f43568510..b2a16ed7e81a 100644 --- a/drivers/acpi/osi.c +++ b/drivers/acpi/osi.c @@ -66,6 +66,14 @@ osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { * be removed if both new and old graphics cards are supported. */ {"Linux-Dell-Video", true}, + /* + * Linux-Lenovo-NV-HDMI-Audio is used by BIOS to power on NVidia's HDMI + * audio device which is turned off for power-saving in Windows OS. + * This power management feature observed on some Lenovo Thinkpad + * systems which will not be able to output audio via HDMI without + * a BIOS workaround. + */ + {"Linux-Lenovo-NV-HDMI-Audio", true}, }; static u32 acpi_osi_handler(acpi_string interface, u32 supported) diff --git a/drivers/acpi/pmic/intel_pmic_crc.c b/drivers/acpi/pmic/intel_pmic_crc.c index 7ffa74048107..22c9e374c923 100644 --- a/drivers/acpi/pmic/intel_pmic_crc.c +++ b/drivers/acpi/pmic/intel_pmic_crc.c @@ -25,16 +25,121 @@ #define PMIC_A0LOCK_REG 0xc5 static struct pmic_table power_table[] = { +/* { + .address = 0x00, + .reg = ??, + .bit = ??, + }, ** VSYS */ + { + .address = 0x04, + .reg = 0x63, + .bit = 0x00, + }, /* SYSX -> VSYS_SX */ + { + .address = 0x08, + .reg = 0x62, + .bit = 0x00, + }, /* SYSU -> VSYS_U */ + { + .address = 0x0c, + .reg = 0x64, + .bit = 0x00, + }, /* SYSS -> VSYS_S */ + { + .address = 0x10, + .reg = 0x6a, + .bit = 0x00, + }, /* V50S -> V5P0S */ + { + .address = 0x14, + .reg = 0x6b, + .bit = 0x00, + }, /* HOST -> VHOST, USB2/3 host */ + { + .address = 0x18, + .reg = 0x6c, + .bit = 0x00, + }, /* VBUS -> VBUS, USB2/3 OTG */ + { + .address = 0x1c, + .reg = 0x6d, + .bit = 0x00, + }, /* HDMI -> VHDMI */ +/* { + .address = 0x20, + .reg = ??, + .bit = ??, + }, ** S285 */ { .address = 0x24, .reg = 0x66, .bit = 0x00, - }, + }, /* X285 -> V2P85SX, camera */ +/* { + .address = 0x28, + .reg = ??, + .bit = ??, + }, ** V33A */ + { + .address = 0x2c, + .reg = 0x69, + .bit = 0x00, + }, /* V33S -> V3P3S, display/ssd/audio */ + { + .address = 0x30, + .reg = 0x68, + .bit = 0x00, + }, /* V33U -> V3P3U, SDIO wifi&bt */ +/* { + .address = 0x34 .. 0x40, + .reg = ??, + .bit = ??, + }, ** V33I, V18A, REFQ, V12A */ + { + .address = 0x44, + .reg = 0x5c, + .bit = 0x00, + }, /* V18S -> V1P8S, SOC/USB PHY/SIM */ { .address = 0x48, .reg = 0x5d, .bit = 0x00, - }, + }, /* V18X -> V1P8SX, eMMC/camara/audio */ + { + .address = 0x4c, + .reg = 0x5b, + .bit = 0x00, + }, /* V18U -> V1P8U, LPDDR */ + { + .address = 0x50, + .reg = 0x61, + .bit = 0x00, + }, /* V12X -> V1P2SX, SOC SFR */ + { + .address = 0x54, + .reg = 0x60, + .bit = 0x00, + }, /* V12S -> V1P2S, MIPI */ +/* { + .address = 0x58, + .reg = ??, + .bit = ??, + }, ** V10A */ + { + .address = 0x5c, + .reg = 0x56, + .bit = 0x00, + }, /* V10S -> V1P0S, SOC GFX */ + { + .address = 0x60, + .reg = 0x57, + .bit = 0x00, + }, /* V10X -> V1P0SX, SOC display/DDR IO/PCIe */ + { + .address = 0x64, + .reg = 0x59, + .bit = 0x00, + }, /* V105 -> V1P05S, L2 SRAM */ }; static struct pmic_table thermal_table[] = { diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index e5ea1974d1e3..d1e26cb599bf 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -481,8 +481,14 @@ static int topology_get_acpi_cpu_tag(struct acpi_table_header *table, if (cpu_node) { cpu_node = acpi_find_processor_package_id(table, cpu_node, level, flag); - /* Only the first level has a guaranteed id */ - if (level == 0) + /* + * As per specification if the processor structure represents + * an actual processor, then ACPI processor ID must be valid. + * For processor containers ACPI_PPTT_ACPI_PROCESSOR_ID_VALID + * should be set if the UID is valid + */ + if (level == 0 || + cpu_node->flags & ACPI_PPTT_ACPI_PROCESSOR_ID_VALID) return cpu_node->acpi_processor_id; return ACPI_PTR_DIFF(cpu_node, table); } diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b933061b6b60..8c0a54d50d0e 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -205,6 +205,7 @@ phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) return phys_id; } +EXPORT_SYMBOL_GPL(acpi_get_phys_id); int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id) { diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 5815356ea6ad..693cf05b0cc4 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -542,6 +542,23 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data, return 0; } +static struct fwnode_handle * +acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode, + const char *childname) +{ + struct fwnode_handle *child; + + /* + * Find first matching named child node of this fwnode. + * For ACPI this will be a data only sub-node. + */ + fwnode_for_each_child_node(fwnode, child) + if (acpi_data_node_match(child, childname)) + return child; + + return NULL; +} + /** * __acpi_node_get_property_reference - returns handle to the referenced object * @fwnode: Firmware node to get the property from @@ -579,7 +596,7 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data, */ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, const char *propname, size_t index, size_t num_args, - struct acpi_reference_args *args) + struct fwnode_reference_args *args) { const union acpi_object *element, *end; const union acpi_object *obj; @@ -607,7 +624,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, if (ret) return ret == -ENODEV ? -EINVAL : ret; - args->adev = device; + args->fwnode = acpi_fwnode_handle(device); args->nargs = 0; return 0; } @@ -633,6 +650,8 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, u32 nargs, i; if (element->type == ACPI_TYPE_LOCAL_REFERENCE) { + struct fwnode_handle *ref_fwnode; + ret = acpi_bus_get_device(element->reference.handle, &device); if (ret) @@ -641,6 +660,19 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, nargs = 0; element++; + /* + * Find the referred data extension node under the + * referred device node. + */ + for (ref_fwnode = acpi_fwnode_handle(device); + element < end && element->type == ACPI_TYPE_STRING; + element++) { + ref_fwnode = acpi_fwnode_get_named_child_node( + ref_fwnode, element->string.pointer); + if (!ref_fwnode) + return -EINVAL; + } + /* assume following integer elements are all args */ for (i = 0; element + i < end && i < num_args; i++) { int type = element[i].type; @@ -653,11 +685,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, return -EINVAL; } - if (nargs > MAX_ACPI_REFERENCE_ARGS) + if (nargs > NR_FWNODE_REFERENCE_ARGS) return -EINVAL; if (idx == index) { - args->adev = device; + args->fwnode = ref_fwnode; args->nargs = nargs; for (i = 0; i < nargs; i++) args->args[i] = element[i].integer.value; @@ -995,16 +1027,36 @@ struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode) return NULL; } +/* + * Return true if the node is an ACPI graph node. Called on either ports + * or endpoints. + */ +static bool is_acpi_graph_node(struct fwnode_handle *fwnode, + const char *str) +{ + unsigned int len = strlen(str); + const char *name; + + if (!len || !is_acpi_data_node(fwnode)) + return false; + + name = to_acpi_data_node(fwnode)->name; + + return (fwnode_property_present(fwnode, "reg") && + !strncmp(name, str, len) && name[len] == '@') || + fwnode_property_present(fwnode, str); +} + /** * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node * @fwnode: Pointer to the parent firmware node * @prev: Previous endpoint node or %NULL to get the first * * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns - * %NULL if there is no next endpoint, ERR_PTR() in case of error. In case - * of success the next endpoint is returned. + * %NULL if there is no next endpoint or in case of error. In case of success + * the next endpoint is returned. */ -struct fwnode_handle *acpi_graph_get_next_endpoint( +static struct fwnode_handle *acpi_graph_get_next_endpoint( const struct fwnode_handle *fwnode, struct fwnode_handle *prev) { struct fwnode_handle *port = NULL; @@ -1013,8 +1065,14 @@ struct fwnode_handle *acpi_graph_get_next_endpoint( if (!prev) { do { port = fwnode_get_next_child_node(fwnode, port); - /* Ports must have port property */ - if (fwnode_property_present(port, "port")) + /* + * The names of the port nodes begin with "port@" + * followed by the number of the port node and they also + * have a "reg" property that also has the number of the + * port node. For compatibility reasons a node is also + * recognised as a port node from the "port" property. + */ + if (is_acpi_graph_node(port, "port")) break; } while (port); } else { @@ -1029,15 +1087,19 @@ struct fwnode_handle *acpi_graph_get_next_endpoint( port = fwnode_get_next_child_node(fwnode, port); if (!port) break; - if (fwnode_property_present(port, "port")) + if (is_acpi_graph_node(port, "port")) endpoint = fwnode_get_next_child_node(port, NULL); } - if (endpoint) { - /* Endpoints must have "endpoint" property */ - if (!fwnode_property_present(endpoint, "endpoint")) - return ERR_PTR(-EPROTO); - } + /* + * The names of the endpoint nodes begin with "endpoint@" followed by + * the number of the endpoint node and they also have a "reg" property + * that also has the number of the endpoint node. For compatibility + * reasons a node is also recognised as an endpoint node from the + * "endpoint" property. + */ + if (!is_acpi_graph_node(endpoint, "endpoint")) + return NULL; return endpoint; } @@ -1074,65 +1136,42 @@ static struct fwnode_handle *acpi_graph_get_child_prop_value( /** * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint * @fwnode: Endpoint firmware node pointing to a remote device - * @parent: Firmware node of remote port parent is filled here if not %NULL - * @port: Firmware node of remote port is filled here if not %NULL * @endpoint: Firmware node of remote endpoint is filled here if not %NULL * - * Function parses remote end of ACPI firmware remote endpoint and fills in - * fields requested by the caller. Returns %0 in case of success and - * negative errno otherwise. + * Returns the remote endpoint corresponding to @__fwnode. NULL on error. */ -int acpi_graph_get_remote_endpoint(const struct fwnode_handle *__fwnode, - struct fwnode_handle **parent, - struct fwnode_handle **port, - struct fwnode_handle **endpoint) +static struct fwnode_handle * +acpi_graph_get_remote_endpoint(const struct fwnode_handle *__fwnode) { struct fwnode_handle *fwnode; unsigned int port_nr, endpoint_nr; - struct acpi_reference_args args; + struct fwnode_reference_args args; int ret; memset(&args, 0, sizeof(args)); ret = acpi_node_get_property_reference(__fwnode, "remote-endpoint", 0, &args); if (ret) - return ret; + return NULL; + + /* Direct endpoint reference? */ + if (!is_acpi_device_node(args.fwnode)) + return args.nargs ? NULL : args.fwnode; /* * Always require two arguments with the reference: port and * endpoint indices. */ if (args.nargs != 2) - return -EPROTO; + return NULL; - fwnode = acpi_fwnode_handle(args.adev); + fwnode = args.fwnode; port_nr = args.args[0]; endpoint_nr = args.args[1]; - if (parent) - *parent = fwnode; - - if (!port && !endpoint) - return 0; - fwnode = acpi_graph_get_child_prop_value(fwnode, "port", port_nr); - if (!fwnode) - return -EPROTO; - - if (port) - *port = fwnode; - - if (!endpoint) - return 0; - fwnode = acpi_graph_get_child_prop_value(fwnode, "endpoint", - endpoint_nr); - if (!fwnode) - return -EPROTO; - - *endpoint = fwnode; - - return 0; + return acpi_graph_get_child_prop_value(fwnode, "endpoint", endpoint_nr); } static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode) @@ -1186,70 +1225,14 @@ acpi_fwnode_property_read_string_array(const struct fwnode_handle *fwnode, val, nval); } -static struct fwnode_handle * -acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode, - const char *childname) -{ - struct fwnode_handle *child; - - /* - * Find first matching named child node of this fwnode. - * For ACPI this will be a data only sub-node. - */ - fwnode_for_each_child_node(fwnode, child) - if (acpi_data_node_match(child, childname)) - return child; - - return NULL; -} - static int acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode, const char *prop, const char *nargs_prop, unsigned int args_count, unsigned int index, struct fwnode_reference_args *args) { - struct acpi_reference_args acpi_args; - unsigned int i; - int ret; - - ret = __acpi_node_get_property_reference(fwnode, prop, index, - args_count, &acpi_args); - if (ret < 0) - return ret; - if (!args) - return 0; - - args->nargs = acpi_args.nargs; - args->fwnode = acpi_fwnode_handle(acpi_args.adev); - - for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++) - args->args[i] = i < acpi_args.nargs ? acpi_args.args[i] : 0; - - return 0; -} - -static struct fwnode_handle * -acpi_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, - struct fwnode_handle *prev) -{ - struct fwnode_handle *endpoint; - - endpoint = acpi_graph_get_next_endpoint(fwnode, prev); - if (IS_ERR(endpoint)) - return NULL; - - return endpoint; -} - -static struct fwnode_handle * -acpi_fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) -{ - struct fwnode_handle *endpoint = NULL; - - acpi_graph_get_remote_endpoint(fwnode, NULL, NULL, &endpoint); - - return endpoint; + return __acpi_node_get_property_reference(fwnode, prop, index, + args_count, args); } static struct fwnode_handle * @@ -1265,8 +1248,10 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, endpoint->local_fwnode = fwnode; - fwnode_property_read_u32(port_fwnode, "port", &endpoint->port); - fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + if (fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port)) + fwnode_property_read_u32(port_fwnode, "port", &endpoint->port); + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); return 0; } @@ -1292,9 +1277,9 @@ acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, .get_named_child_node = acpi_fwnode_get_named_child_node, \ .get_reference_args = acpi_fwnode_get_reference_args, \ .graph_get_next_endpoint = \ - acpi_fwnode_graph_get_next_endpoint, \ + acpi_graph_get_next_endpoint, \ .graph_get_remote_endpoint = \ - acpi_fwnode_graph_get_remote_endpoint, \ + acpi_graph_get_remote_endpoint, \ .graph_get_port_parent = acpi_fwnode_get_parent, \ .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \ }; \ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 970dd87d347c..e1b6231cfa1c 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1528,7 +1528,7 @@ static int acpi_check_serial_bus_slave(struct acpi_resource *ares, void *data) static bool acpi_is_indirect_io_slave(struct acpi_device *device) { struct acpi_device *parent = device->parent; - const struct acpi_device_id indirect_io_hosts[] = { + static const struct acpi_device_id indirect_io_hosts[] = { {"HISI0191", 0}, {} }; @@ -1540,6 +1540,18 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) { struct list_head resource_list; bool is_serial_bus_slave = false; + /* + * These devices have multiple I2cSerialBus resources and an i2c-client + * must be instantiated for each, each with its own i2c_device_id. + * Normally we only instantiate an i2c-client for the first resource, + * using the ACPI HID as id. These special cases are handled by the + * drivers/platform/x86/i2c-multi-instantiate.c driver, which knows + * which i2c_device_id to use for each resource. + */ + static const struct acpi_device_id i2c_multi_instantiate_ids[] = { + {"BSG1160", }, + {} + }; if (acpi_is_indirect_io_slave(device)) return true; @@ -1551,6 +1563,10 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) fwnode_property_present(&device->fwnode, "baud"))) return true; + /* Instantiate a pdev for the i2c-multi-instantiate drv to bind to */ + if (!acpi_match_device_ids(device, i2c_multi_instantiate_ids)) + return false; + INIT_LIST_HEAD(&resource_list); acpi_dev_get_resources(device, &resource_list, acpi_check_serial_bus_slave, @@ -1612,7 +1628,8 @@ static int acpi_add_single_object(struct acpi_device **child, * Note this must be done before the get power-/wakeup_dev-flags calls. */ if (type == ACPI_BUS_TYPE_DEVICE) - acpi_bus_get_status(device); + if (acpi_bus_get_status(device) < 0) + acpi_set_device_status(device, 0); acpi_bus_get_power_flags(device); acpi_bus_get_wakeup_device_flags(device); @@ -1690,7 +1707,7 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, * acpi_add_single_object updates this once we've an acpi_device * so that acpi_bus_get_status' quirk handling can be used. */ - *sta = 0; + *sta = ACPI_STA_DEFAULT; break; case ACPI_TYPE_PROCESSOR: *type = ACPI_BUS_TYPE_PROCESSOR; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5d0486f1cfcd..754d59f95500 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -338,6 +338,14 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), }, }, + { + .callback = init_nvs_save_s3, + .ident = "Asus 1025C", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "1025C"), + }, + }, /* * https://bugzilla.kernel.org/show_bug.cgi?id=189431 * Lenovo G50-45 is a platform later than 2012, but needs nvs memory @@ -718,9 +726,6 @@ static const struct acpi_device_id lps0_device_ids[] = { #define ACPI_LPS0_ENTRY 5 #define ACPI_LPS0_EXIT 6 -#define ACPI_LPS0_SCREEN_MASK ((1 << ACPI_LPS0_SCREEN_OFF) | (1 << ACPI_LPS0_SCREEN_ON)) -#define ACPI_LPS0_PLATFORM_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT)) - static acpi_handle lps0_device_handle; static guid_t lps0_dsm_guid; static char lps0_dsm_func_mask; @@ -924,17 +929,14 @@ static int lps0_device_attach(struct acpi_device *adev, if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { char bitmask = *(char *)out_obj->buffer.pointer; - if ((bitmask & ACPI_LPS0_PLATFORM_MASK) == ACPI_LPS0_PLATFORM_MASK || - (bitmask & ACPI_LPS0_SCREEN_MASK) == ACPI_LPS0_SCREEN_MASK) { - lps0_dsm_func_mask = bitmask; - lps0_device_handle = adev->handle; - /* - * Use suspend-to-idle by default if the default - * suspend mode was not set from the command line. - */ - if (mem_sleep_default > PM_SUSPEND_MEM) - mem_sleep_current = PM_SUSPEND_TO_IDLE; - } + lps0_dsm_func_mask = bitmask; + lps0_device_handle = adev->handle; + /* + * Use suspend-to-idle by default if the default + * suspend mode was not set from the command line. + */ + if (mem_sleep_default > PM_SUSPEND_MEM) + mem_sleep_current = PM_SUSPEND_TO_IDLE; acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n", bitmask); diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index ec5b0f190231..06c31ec3cc70 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -62,14 +62,20 @@ static const struct always_present_id always_present_ids[] = { */ ENTRY("INT0002", "1", ICPU(INTEL_FAM6_ATOM_AIRMONT), {}), /* - * On the Dell Venue 11 Pro 7130 the DSDT hides the touchscreen ACPI - * device until a certain time after _SB.PCI0.GFX0.LCD.LCD1._ON gets - * called has passed *and* _STA has been called at least 3 times since. + * On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides + * the touchscreen ACPI device until a certain time + * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed + * *and* _STA has been called at least 3 times since. */ ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), }), + ENTRY("SYNA7500", "1", ICPU(INTEL_FAM6_HASWELL_ULT), { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"), + }), + /* * The GPD win BIOS dated 20170221 has disabled the accelerometer, the * drivers sometimes cause crashes under Windows and this is how the @@ -103,13 +109,9 @@ static const struct always_present_id always_present_ids[] = { bool acpi_device_always_present(struct acpi_device *adev) { - u32 *status = (u32 *)&adev->status; - u32 old_status = *status; bool ret = false; unsigned int i; - /* acpi_match_device_ids checks status, so set it to default */ - *status = ACPI_STA_DEFAULT; for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) { if (acpi_match_device_ids(adev, always_present_ids[i].hid)) continue; @@ -125,15 +127,9 @@ bool acpi_device_always_present(struct acpi_device *adev) !dmi_check_system(always_present_ids[i].dmi_ids)) continue; - if (old_status != ACPI_STA_DEFAULT) /* Log only once */ - dev_info(&adev->dev, - "Device [%s] is in always present list\n", - adev->pnp.bus_id); - ret = true; break; } - *status = old_status; return ret; } |
