forked from Minki/linux
ACPI updates for 5.7-rc1
- Update the ACPICA code in the kernel to the 20200214 upstream release including: * Fix to re-enable the sleep button after wakeup (Anchal Agarwal). * Fixes for mistakes in comments and typos (Bob Moore). * ASL-ASL+ converter updates (Erik Kaneda). * Type casting cleanups (Sven Barth). - Clean up the intialization of the EC driver and eliminate some dead code from it (Rafael Wysocki). - Clean up the quirk tables in the AC and battery drivers (Hans de Goede). - Fix the global lock handling on x86 to ignore unspecified bit positions in the global lock field (Jan Engelhardt). - Add a new "tiny" driver for ACPI button devices exposed by VMs to guest kernels to send signals directly to init (Josh Triplett). - Add a kernel parameter to disable ACPI BGRT on x86 (Alex Hung). - Make the ACPI PCI host bridge and fan drivers use scnprintf() to avoid potential buffer overflows (Takashi Iwai). - Clean up assorted pieces of code: * Reorder "asmlinkage" to make g++ happy (Alexey Dobriyan). * Drop unneeded variable initialization (Colin Ian King). * Add missing __acquires/__releases annotations (Jules Irenge). * Replace list_for_each_safe() with list_for_each_entry_safe() (chenqiwu). -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAl6CCQASHHJqd0Byand5 c29ja2kubmV0AAoJEILEb/54YlRx15UQAISSZxFTq6huh9c3r0xEgddamhn7VOX+ phjRuTmPzRn2RqFt7Q/ypiy5qqRgBko7oR0UyMJeHc7YPYcJ2nrRx/6Ymg46nmac mdIwTG3y1bH6cD/Fz8cM+9ZCtQl8iZRf36zvlY/8fNpk+Cj98et+x+wbUN8GMO9F 9anHpPKk7hHCwxSN/SnyrJGJpjKdW057sv9sYwgR65XnM35dGxExQNjqtQVFk/ih N7TKVHUAlEE06liS0QYCeugsZsu5/GviU/1uy3qwg+Fxcxw7muHfG/impZwFhdjn QrdnFOGz9lFXzY+ynQplW0tJtt1AvOLJzQtzGVOxurTJIgz1pEJnptvDXFWP2YBX aESfuFt47bzi/NT1f31L3YQ3vuOJczwkS/QlDxv4TJh6rFdZFnQQNo+iIxBAlB6n xSsADFbZ3OaAU2VcjVn6WSL7iD3znnIBZp/xQIybb+9BUoDhSXCTH7rNT7p025cR g4KGAevlNDEVKIsZs3UHRQYpFQ+qHDM3WNiAiIEyF9cdenSXEMKrBnEYKSbV7DnI rBYexFTvjAyVEb6qnuaQDwHHKhu5Xc0JebIXeTjByg993Y8SFLll7a5d40H71S6Z /nG4mOa8+Qt6MqhwvkXLu/cxrXgNmnCG8W9RH0/2sQs25AMys9SESo1jsvEeCS2o tC2xCpKl2TlU =kQmH -----END PGP SIGNATURE----- Merge tag 'acpi-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull ACPI updates from Rafael Wysocki: - Update the ACPICA code in the kernel to the 20200214 upstream release including: * Fix to re-enable the sleep button after wakeup (Anchal Agarwal). * Fixes for mistakes in comments and typos (Bob Moore). * ASL-ASL+ converter updates (Erik Kaneda). * Type casting cleanups (Sven Barth). - Clean up the intialization of the EC driver and eliminate some dead code from it (Rafael Wysocki). - Clean up the quirk tables in the AC and battery drivers (Hans de Goede). - Fix the global lock handling on x86 to ignore unspecified bit positions in the global lock field (Jan Engelhardt). - Add a new "tiny" driver for ACPI button devices exposed by VMs to guest kernels to send signals directly to init (Josh Triplett). - Add a kernel parameter to disable ACPI BGRT on x86 (Alex Hung). - Make the ACPI PCI host bridge and fan drivers use scnprintf() to avoid potential buffer overflows (Takashi Iwai). - Clean up assorted pieces of code: * Reorder "asmlinkage" to make g++ happy (Alexey Dobriyan). * Drop unneeded variable initialization (Colin Ian King). * Add missing __acquires/__releases annotations (Jules Irenge). * Replace list_for_each_safe() with list_for_each_entry_safe() (chenqiwu)" * tag 'acpi-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (31 commits) ACPICA: Update version to 20200214 ACPI: PCI: Use scnprintf() for avoiding potential buffer overflow ACPI: fan: Use scnprintf() for avoiding potential buffer overflow ACPI: EC: Eliminate EC_FLAGS_QUERY_HANDSHAKE ACPI: EC: Do not clear boot_ec_is_ecdt in acpi_ec_add() ACPI: EC: Simplify acpi_ec_ecdt_start() and acpi_ec_init() ACPI: EC: Consolidate event handler installation code acpi/x86: ignore unspecified bit positions in the ACPI global lock field acpi/x86: add a kernel parameter to disable ACPI BGRT x86/acpi: make "asmlinkage" part first thing in the function definition ACPI: list_for_each_safe() -> list_for_each_entry_safe() ACPI: video: remove redundant assignments to variable result ACPI: OSL: Add missing __acquires/__releases annotations ACPI / battery: Cleanup Lenovo Ideapad Miix 320 DMI table entry ACPI / AC: Cleanup DMI quirk table ACPI: EC: Use fast path in acpi_ec_add() for DSDT boot EC ACPI: EC: Simplify acpi_ec_add() ACPI: EC: Drop AE_NOT_FOUND special case from ec_install_handlers() ACPI: EC: Avoid passing redundant argument to functions ACPI: EC: Avoid printing confusing messages in acpi_ec_setup() ...
This commit is contained in:
commit
6d90508121
@ -450,6 +450,9 @@
|
||||
bert_disable [ACPI]
|
||||
Disable BERT OS support on buggy BIOSes.
|
||||
|
||||
bgrt_disable [ACPI][X86]
|
||||
Disable BGRT to avoid flickering OEM logo.
|
||||
|
||||
bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
|
||||
bttv.radio= Most important insmod options are available as
|
||||
kernel args too.
|
||||
|
@ -45,6 +45,7 @@ EXPORT_SYMBOL(acpi_disabled);
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
int acpi_noirq; /* skip ACPI IRQ initialization */
|
||||
int acpi_nobgrt; /* skip ACPI BGRT */
|
||||
int acpi_pci_disabled; /* skip ACPI PCI scan and IRQ initialization */
|
||||
EXPORT_SYMBOL(acpi_pci_disabled);
|
||||
|
||||
@ -1619,7 +1620,7 @@ int __init acpi_boot_init(void)
|
||||
acpi_process_madt();
|
||||
|
||||
acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
|
||||
if (IS_ENABLED(CONFIG_ACPI_BGRT))
|
||||
if (IS_ENABLED(CONFIG_ACPI_BGRT) && !acpi_nobgrt)
|
||||
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
|
||||
|
||||
if (!acpi_noirq)
|
||||
@ -1671,6 +1672,13 @@ static int __init parse_acpi(char *arg)
|
||||
}
|
||||
early_param("acpi", parse_acpi);
|
||||
|
||||
static int __init parse_acpi_bgrt(char *arg)
|
||||
{
|
||||
acpi_nobgrt = true;
|
||||
return 0;
|
||||
}
|
||||
early_param("bgrt_disable", parse_acpi_bgrt);
|
||||
|
||||
/* FIXME: Using pci= for an ACPI parameter is a travesty. */
|
||||
static int __init parse_pci(char *arg)
|
||||
{
|
||||
@ -1740,7 +1748,7 @@ int __acpi_acquire_global_lock(unsigned int *lock)
|
||||
new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
|
||||
val = cmpxchg(lock, old, new);
|
||||
} while (unlikely (val != old));
|
||||
return (new < 3) ? -1 : 0;
|
||||
return ((new & 0x3) < 3) ? -1 : 0;
|
||||
}
|
||||
|
||||
int __acpi_release_global_lock(unsigned int *lock)
|
||||
|
@ -43,7 +43,7 @@ unsigned long acpi_get_wakeup_address(void)
|
||||
*
|
||||
* Wrapper around acpi_enter_sleep_state() to be called by assmebly.
|
||||
*/
|
||||
acpi_status asmlinkage __visible x86_acpi_enter_sleep_state(u8 state)
|
||||
asmlinkage acpi_status __visible x86_acpi_enter_sleep_state(u8 state)
|
||||
{
|
||||
return acpi_enter_sleep_state(state);
|
||||
}
|
||||
|
@ -19,4 +19,4 @@ extern void do_suspend_lowlevel(void);
|
||||
|
||||
extern int x86_acpi_suspend_lowlevel(void);
|
||||
|
||||
acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state);
|
||||
asmlinkage acpi_status x86_acpi_enter_sleep_state(u8 state);
|
||||
|
@ -190,6 +190,30 @@ config ACPI_BUTTON
|
||||
To compile this driver as a module, choose M here:
|
||||
the module will be called button.
|
||||
|
||||
config ACPI_TINY_POWER_BUTTON
|
||||
tristate "Tiny Power Button Driver"
|
||||
depends on !ACPI_BUTTON
|
||||
help
|
||||
This driver provides a tiny alternative to the ACPI Button driver.
|
||||
The tiny power button driver only handles the power button. Rather
|
||||
than notifying userspace via the input layer or a netlink event, this
|
||||
driver directly signals the init process to shut down.
|
||||
|
||||
This driver is particularly suitable for cloud and VM environments,
|
||||
which use a simulated power button to initiate a controlled poweroff,
|
||||
but which may not want to run a separate userspace daemon to process
|
||||
input events.
|
||||
|
||||
config ACPI_TINY_POWER_BUTTON_SIGNAL
|
||||
int "Tiny Power Button Signal"
|
||||
depends on ACPI_TINY_POWER_BUTTON
|
||||
default 38
|
||||
help
|
||||
Default signal to send to init in response to the power button.
|
||||
|
||||
Likely values here include 38 (SIGRTMIN+4) to power off, or 2
|
||||
(SIGINT) to simulate Ctrl+Alt+Del.
|
||||
|
||||
config ACPI_VIDEO
|
||||
tristate "Video"
|
||||
depends on X86 && BACKLIGHT_CLASS_DEVICE
|
||||
|
@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o
|
||||
|
||||
obj-$(CONFIG_ACPI_AC) += ac.o
|
||||
obj-$(CONFIG_ACPI_BUTTON) += button.o
|
||||
obj-$(CONFIG_ACPI_TINY_POWER_BUTTON) += tiny-power-button.o
|
||||
obj-$(CONFIG_ACPI_FAN) += fan.o
|
||||
obj-$(CONFIG_ACPI_VIDEO) += video.o
|
||||
obj-$(CONFIG_ACPI_TAD) += acpi_tad.o
|
||||
|
@ -293,29 +293,30 @@ static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Please keep this list alphabetically sorted */
|
||||
static const struct dmi_system_id ac_dmi_table[] __initconst = {
|
||||
{
|
||||
/* Thinkpad e530 */
|
||||
.callback = thinkpad_e530_quirk,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* ECS EF20EA */
|
||||
/* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */
|
||||
.callback = ac_do_not_check_pmic_quirk,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Lenovo Ideapad Miix 320 */
|
||||
/* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
|
||||
.callback = ac_do_not_check_pmic_quirk,
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "80XF"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Lenovo Thinkpad e530, see comment in acpi_ac_notify() */
|
||||
.callback = thinkpad_e530_quirk,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"),
|
||||
},
|
||||
},
|
||||
{},
|
||||
|
@ -943,7 +943,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
|
||||
int i, max_level = 0;
|
||||
unsigned long long level, level_old;
|
||||
struct acpi_video_device_brightness *br = NULL;
|
||||
int result = -EINVAL;
|
||||
int result;
|
||||
|
||||
result = acpi_video_get_levels(device->dev, &br, &max_level);
|
||||
if (result)
|
||||
|
@ -65,9 +65,7 @@ void cg_write_aml_comment(union acpi_parse_object *op);
|
||||
/*
|
||||
* cvparser
|
||||
*/
|
||||
void
|
||||
cv_init_file_tree(struct acpi_table_header *table,
|
||||
u8 *aml_start, u32 aml_length);
|
||||
void cv_init_file_tree(struct acpi_table_header *table, FILE * root_file);
|
||||
|
||||
void cv_clear_op_comments(union acpi_parse_object *op);
|
||||
|
||||
|
@ -477,7 +477,7 @@
|
||||
#define ASL_CV_PRINT_ONE_COMMENT(a,b,c,d) cv_print_one_comment_type (a,b,c,d);
|
||||
#define ASL_CV_PRINT_ONE_COMMENT_LIST(a,b) cv_print_one_comment_list (a,b);
|
||||
#define ASL_CV_FILE_HAS_SWITCHED(a) cv_file_has_switched(a)
|
||||
#define ASL_CV_INIT_FILETREE(a,b,c) cv_init_file_tree(a,b,c);
|
||||
#define ASL_CV_INIT_FILETREE(a,b) cv_init_file_tree(a,b);
|
||||
|
||||
#else
|
||||
|
||||
@ -492,7 +492,7 @@
|
||||
#define ASL_CV_PRINT_ONE_COMMENT(a,b,c,d)
|
||||
#define ASL_CV_PRINT_ONE_COMMENT_LIST(a,b)
|
||||
#define ASL_CV_FILE_HAS_SWITCHED(a) 0
|
||||
#define ASL_CV_INIT_FILETREE(a,b,c)
|
||||
#define ASL_CV_INIT_FILETREE(a,b)
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -130,7 +130,7 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
|
||||
|
||||
/*
|
||||
* Initialize the structure that keeps track of fixed event handlers and
|
||||
* enable the fixed events.
|
||||
* disable all of the fixed events.
|
||||
*/
|
||||
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
|
||||
acpi_gbl_fixed_event_handlers[i].handler = NULL;
|
||||
|
@ -300,6 +300,18 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state)
|
||||
[ACPI_EVENT_POWER_BUTTON].
|
||||
status_register_id, ACPI_CLEAR_STATUS);
|
||||
|
||||
/* Enable sleep button */
|
||||
|
||||
(void)
|
||||
acpi_write_bit_register(acpi_gbl_fixed_event_info
|
||||
[ACPI_EVENT_SLEEP_BUTTON].
|
||||
enable_register_id, ACPI_ENABLE_EVENT);
|
||||
|
||||
(void)
|
||||
acpi_write_bit_register(acpi_gbl_fixed_event_info
|
||||
[ACPI_EVENT_SLEEP_BUTTON].
|
||||
status_register_id, ACPI_CLEAR_STATUS);
|
||||
|
||||
acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ acpi_ns_handle_to_pathname(acpi_handle target_handle,
|
||||
/* Build the path in the caller buffer */
|
||||
|
||||
(void)acpi_ns_build_normalized_path(node, buffer->pointer,
|
||||
required_size, no_trailing);
|
||||
(u32)required_size, no_trailing);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s [%X]\n",
|
||||
(char *)buffer->pointer, (u32) required_size));
|
||||
@ -315,7 +315,7 @@ char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
|
||||
|
||||
/* Build the path in the allocated buffer */
|
||||
|
||||
(void)acpi_ns_build_normalized_path(node, name_buffer, size,
|
||||
(void)acpi_ns_build_normalized_path(node, name_buffer, (u32)size,
|
||||
no_trailing);
|
||||
|
||||
ACPI_DEBUG_PRINT_RAW((ACPI_DB_NAMES, "%s: Path \"%s\"\n",
|
||||
@ -346,7 +346,7 @@ char *acpi_ns_build_prefixed_pathname(union acpi_generic_state *prefix_scope,
|
||||
char *full_path = NULL;
|
||||
char *external_path = NULL;
|
||||
char *prefix_path = NULL;
|
||||
u32 prefix_path_length = 0;
|
||||
acpi_size prefix_path_length = 0;
|
||||
|
||||
/* If there is a prefix, get the pathname to it */
|
||||
|
||||
|
@ -516,7 +516,7 @@ acpi_status acpi_install_method(u8 *buffer)
|
||||
|
||||
method_flags = *parser_state.aml++;
|
||||
aml_start = parser_state.aml;
|
||||
aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start);
|
||||
aml_length = (u32)ACPI_PTR_DIFF(parser_state.pkg_end, aml_start);
|
||||
|
||||
/*
|
||||
* Allocate resources up-front. We don't want to have to delete a new
|
||||
|
@ -202,14 +202,14 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_reallocate_root_table)
|
||||
*
|
||||
* PARAMETERS: signature - ACPI signature of needed table
|
||||
* instance - Which instance (for SSDTs)
|
||||
* out_table_header - The pointer to the table header to fill
|
||||
* out_table_header - The pointer to the where the table header
|
||||
* is returned
|
||||
*
|
||||
* RETURN: Status and pointer to mapped table header
|
||||
* RETURN: Status and a copy of the table header
|
||||
*
|
||||
* DESCRIPTION: Finds an ACPI table header.
|
||||
*
|
||||
* NOTE: Caller is responsible in unmapping the header with
|
||||
* acpi_os_unmap_memory
|
||||
* DESCRIPTION: Finds and returns an ACPI table header. Caller provides the
|
||||
* memory where a copy of the header is to be returned
|
||||
* (fixed length).
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
|
@ -44,7 +44,7 @@ acpi_ut_get_element_length(u8 object_type,
|
||||
*
|
||||
* NOTE: We always allocate the worst-case object descriptor because
|
||||
* these objects are cached, and we want them to be
|
||||
* one-size-satisifies-any-request. This in itself may not be
|
||||
* one-size-satisfies-any-request. This in itself may not be
|
||||
* the most memory efficient, but the efficiency of the object
|
||||
* cache should more than make up for this!
|
||||
*
|
||||
|
@ -1365,19 +1365,19 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = {
|
||||
},
|
||||
},
|
||||
{
|
||||
/* ECS EF20EA */
|
||||
/* ECS EF20EA, AXP288 PMIC but uses separate fuel-gauge */
|
||||
.callback = battery_do_not_check_pmic_quirk,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Lenovo Ideapad Miix 320 */
|
||||
/* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */
|
||||
.callback = battery_do_not_check_pmic_quirk,
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "80XF"),
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
|
||||
},
|
||||
},
|
||||
{},
|
||||
|
@ -30,17 +30,14 @@
|
||||
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
|
||||
|
||||
#define ACPI_BUTTON_SUBCLASS_POWER "power"
|
||||
#define ACPI_BUTTON_HID_POWER "PNP0C0C"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
|
||||
#define ACPI_BUTTON_TYPE_POWER 0x01
|
||||
|
||||
#define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
|
||||
#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
|
||||
#define ACPI_BUTTON_TYPE_SLEEP 0x03
|
||||
|
||||
#define ACPI_BUTTON_SUBCLASS_LID "lid"
|
||||
#define ACPI_BUTTON_HID_LID "PNP0C0D"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch"
|
||||
#define ACPI_BUTTON_TYPE_LID 0x05
|
||||
|
||||
|
@ -182,7 +182,6 @@ static bool boot_ec_is_ecdt = false;
|
||||
static struct workqueue_struct *ec_wq;
|
||||
static struct workqueue_struct *ec_query_wq;
|
||||
|
||||
static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
|
||||
static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
|
||||
static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
|
||||
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
|
||||
@ -690,21 +689,9 @@ static void advance_transaction(struct acpi_ec *ec)
|
||||
wakeup = true;
|
||||
}
|
||||
goto out;
|
||||
} else {
|
||||
if (EC_FLAGS_QUERY_HANDSHAKE &&
|
||||
!(status & ACPI_EC_FLAG_SCI) &&
|
||||
(t->command == ACPI_EC_COMMAND_QUERY)) {
|
||||
ec_transaction_transition(ec, ACPI_EC_COMMAND_POLL);
|
||||
t->rdata[t->ri++] = 0x00;
|
||||
ec_transaction_transition(ec, ACPI_EC_COMMAND_COMPLETE);
|
||||
ec_dbg_evt("Command(%s) completed by software",
|
||||
acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
|
||||
wakeup = true;
|
||||
} else if ((status & ACPI_EC_FLAG_IBF) == 0) {
|
||||
acpi_ec_write_cmd(ec, t->command);
|
||||
ec_transaction_transition(ec, ACPI_EC_COMMAND_POLL);
|
||||
} else
|
||||
goto err;
|
||||
} else if (!(status & ACPI_EC_FLAG_IBF)) {
|
||||
acpi_ec_write_cmd(ec, t->command);
|
||||
ec_transaction_transition(ec, ACPI_EC_COMMAND_POLL);
|
||||
goto out;
|
||||
}
|
||||
err:
|
||||
@ -1427,57 +1414,45 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
static void install_gpe_event_handler(struct acpi_ec *ec)
|
||||
static bool install_gpe_event_handler(struct acpi_ec *ec)
|
||||
{
|
||||
acpi_status status =
|
||||
acpi_install_gpe_raw_handler(NULL, ec->gpe,
|
||||
ACPI_GPE_EDGE_TRIGGERED,
|
||||
&acpi_ec_gpe_handler,
|
||||
ec);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
/* This is not fatal as we can poll EC events */
|
||||
set_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags);
|
||||
acpi_ec_leave_noirq(ec);
|
||||
if (test_bit(EC_FLAGS_STARTED, &ec->flags) &&
|
||||
ec->reference_count >= 1)
|
||||
acpi_ec_enable_gpe(ec, true);
|
||||
}
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_install_gpe_raw_handler(NULL, ec->gpe,
|
||||
ACPI_GPE_EDGE_TRIGGERED,
|
||||
&acpi_ec_gpe_handler, ec);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
if (test_bit(EC_FLAGS_STARTED, &ec->flags) && ec->reference_count >= 1)
|
||||
acpi_ec_enable_gpe(ec, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ACPI reduced hardware platforms use a GpioInt specified in _CRS. */
|
||||
static int install_gpio_irq_event_handler(struct acpi_ec *ec,
|
||||
struct acpi_device *device)
|
||||
static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
|
||||
{
|
||||
int irq = acpi_dev_gpio_irq_get(device, 0);
|
||||
int ret;
|
||||
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = request_irq(irq, acpi_ec_irq_handler, IRQF_SHARED,
|
||||
"ACPI EC", ec);
|
||||
|
||||
/*
|
||||
* Unlike the GPE case, we treat errors here as fatal, we'll only
|
||||
* implement GPIO polling if we find a case that needs it.
|
||||
*/
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ec->irq = irq;
|
||||
set_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags);
|
||||
acpi_ec_leave_noirq(ec);
|
||||
|
||||
return 0;
|
||||
return request_irq(ec->irq, acpi_ec_irq_handler, IRQF_SHARED,
|
||||
"ACPI EC", ec) >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: This function returns an error code only when the address space
|
||||
* handler is not installed, which means "not able to handle
|
||||
* transactions".
|
||||
/**
|
||||
* ec_install_handlers - Install service callbacks and register query methods.
|
||||
* @ec: Target EC.
|
||||
* @device: ACPI device object corresponding to @ec.
|
||||
*
|
||||
* Install a handler for the EC address space type unless it has been installed
|
||||
* already. If @device is not NULL, also look for EC query methods in the
|
||||
* namespace and register them, and install an event (either GPE or GPIO IRQ)
|
||||
* handler for the EC, if possible.
|
||||
*
|
||||
* Return:
|
||||
* -ENODEV if the address space handler cannot be installed, which means
|
||||
* "unable to handle transactions",
|
||||
* -EPROBE_DEFER if GPIO IRQ acquisition needs to be deferred,
|
||||
* or 0 (success) otherwise.
|
||||
*/
|
||||
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
|
||||
bool handle_events)
|
||||
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
@ -1490,26 +1465,28 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
|
||||
&acpi_ec_space_handler,
|
||||
NULL, ec);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
if (status == AE_NOT_FOUND) {
|
||||
/*
|
||||
* Maybe OS fails in evaluating the _REG
|
||||
* object. The AE_NOT_FOUND error will be
|
||||
* ignored and OS * continue to initialize
|
||||
* EC.
|
||||
*/
|
||||
pr_err("Fail in evaluating the _REG object"
|
||||
" of EC device. Broken bios is suspected.\n");
|
||||
} else {
|
||||
acpi_ec_stop(ec, false);
|
||||
return -ENODEV;
|
||||
}
|
||||
acpi_ec_stop(ec, false);
|
||||
return -ENODEV;
|
||||
}
|
||||
set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
|
||||
}
|
||||
|
||||
if (!handle_events)
|
||||
if (!device)
|
||||
return 0;
|
||||
|
||||
if (ec->gpe < 0) {
|
||||
/* ACPI reduced hardware platforms use a GpioInt from _CRS. */
|
||||
int irq = acpi_dev_gpio_irq_get(device, 0);
|
||||
/*
|
||||
* Bail out right away for deferred probing or complete the
|
||||
* initialization regardless of any other errors.
|
||||
*/
|
||||
if (irq == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
else if (irq >= 0)
|
||||
ec->irq = irq;
|
||||
}
|
||||
|
||||
if (!test_bit(EC_FLAGS_QUERY_METHODS_INSTALLED, &ec->flags)) {
|
||||
/* Find and register all query methods */
|
||||
acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
|
||||
@ -1518,16 +1495,21 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
|
||||
set_bit(EC_FLAGS_QUERY_METHODS_INSTALLED, &ec->flags);
|
||||
}
|
||||
if (!test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags)) {
|
||||
if (ec->gpe >= 0) {
|
||||
install_gpe_event_handler(ec);
|
||||
} else if (device) {
|
||||
int ret = install_gpio_irq_event_handler(ec, device);
|
||||
bool ready = false;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
} else { /* No GPE and no GpioInt? */
|
||||
return -ENODEV;
|
||||
if (ec->gpe >= 0)
|
||||
ready = install_gpe_event_handler(ec);
|
||||
else if (ec->irq >= 0)
|
||||
ready = install_gpio_irq_event_handler(ec);
|
||||
|
||||
if (ready) {
|
||||
set_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags);
|
||||
acpi_ec_leave_noirq(ec);
|
||||
}
|
||||
/*
|
||||
* Failures to install an event handler are not fatal, because
|
||||
* the EC can be polled for events.
|
||||
*/
|
||||
}
|
||||
/* EC is fully operational, allow queries */
|
||||
acpi_ec_enable_event(ec);
|
||||
@ -1574,61 +1556,46 @@ static void ec_remove_handlers(struct acpi_ec *ec)
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device,
|
||||
bool handle_events)
|
||||
static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ec_install_handlers(ec, device, handle_events);
|
||||
ret = ec_install_handlers(ec, device);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* First EC capable of handling transactions */
|
||||
if (!first_ec) {
|
||||
if (!first_ec)
|
||||
first_ec = ec;
|
||||
acpi_handle_info(first_ec->handle, "Used as first EC\n");
|
||||
|
||||
pr_info("EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->command_addr,
|
||||
ec->data_addr);
|
||||
|
||||
if (test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags)) {
|
||||
if (ec->gpe >= 0)
|
||||
pr_info("GPE=0x%x\n", ec->gpe);
|
||||
else
|
||||
pr_info("IRQ=%d\n", ec->irq);
|
||||
}
|
||||
|
||||
acpi_handle_info(ec->handle,
|
||||
"GPE=0x%x, IRQ=%d, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n",
|
||||
ec->gpe, ec->irq, ec->command_addr, ec->data_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool acpi_ec_ecdt_get_handle(acpi_handle *phandle)
|
||||
{
|
||||
struct acpi_table_ecdt *ecdt_ptr;
|
||||
acpi_status status;
|
||||
acpi_handle handle;
|
||||
|
||||
status = acpi_get_table(ACPI_SIG_ECDT, 1,
|
||||
(struct acpi_table_header **)&ecdt_ptr);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
status = acpi_get_handle(NULL, ecdt_ptr->id, &handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
*phandle = handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int acpi_ec_add(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_ec *ec = NULL;
|
||||
bool dep_update = true;
|
||||
acpi_status status;
|
||||
struct acpi_ec *ec;
|
||||
int ret;
|
||||
|
||||
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
|
||||
|
||||
if (!strcmp(acpi_device_hid(device), ACPI_ECDT_HID)) {
|
||||
boot_ec_is_ecdt = true;
|
||||
if ((boot_ec && boot_ec->handle == device->handle) ||
|
||||
!strcmp(acpi_device_hid(device), ACPI_ECDT_HID)) {
|
||||
/* Fast path: this device corresponds to the boot EC. */
|
||||
ec = boot_ec;
|
||||
dep_update = false;
|
||||
} else {
|
||||
acpi_status status;
|
||||
|
||||
ec = acpi_ec_alloc();
|
||||
if (!ec)
|
||||
return -ENOMEM;
|
||||
@ -1636,12 +1603,11 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||
status = ec_parse_device(device->handle, 0, ec, NULL);
|
||||
if (status != AE_CTRL_TERMINATE) {
|
||||
ret = -EINVAL;
|
||||
goto err_alloc;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (boot_ec && ec->command_addr == boot_ec->command_addr &&
|
||||
ec->data_addr == boot_ec->data_addr) {
|
||||
boot_ec_is_ecdt = false;
|
||||
/*
|
||||
* Trust PNP0C09 namespace location rather than
|
||||
* ECDT ID. But trust ECDT GPE rather than _GPE
|
||||
@ -1655,15 +1621,18 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||
}
|
||||
}
|
||||
|
||||
ret = acpi_ec_setup(ec, device, true);
|
||||
ret = acpi_ec_setup(ec, device);
|
||||
if (ret)
|
||||
goto err_query;
|
||||
goto err;
|
||||
|
||||
if (ec == boot_ec)
|
||||
acpi_handle_info(boot_ec->handle,
|
||||
"Boot %s EC used to handle transactions and events\n",
|
||||
"Boot %s EC initialization complete\n",
|
||||
boot_ec_is_ecdt ? "ECDT" : "DSDT");
|
||||
|
||||
acpi_handle_info(ec->handle,
|
||||
"EC: Used to handle transactions and events\n");
|
||||
|
||||
device->driver_data = ec;
|
||||
|
||||
ret = !!request_region(ec->data_addr, 1, "EC data");
|
||||
@ -1671,19 +1640,16 @@ static int acpi_ec_add(struct acpi_device *device)
|
||||
ret = !!request_region(ec->command_addr, 1, "EC cmd");
|
||||
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
|
||||
|
||||
if (dep_update) {
|
||||
/* Reprobe devices depending on the EC */
|
||||
acpi_walk_dep_device_list(ec->handle);
|
||||
}
|
||||
/* Reprobe devices depending on the EC */
|
||||
acpi_walk_dep_device_list(ec->handle);
|
||||
|
||||
acpi_handle_debug(ec->handle, "enumerated.\n");
|
||||
return 0;
|
||||
|
||||
err_query:
|
||||
if (ec != boot_ec)
|
||||
acpi_ec_remove_query_handlers(ec, true, 0);
|
||||
err_alloc:
|
||||
err:
|
||||
if (ec != boot_ec)
|
||||
acpi_ec_free(ec);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1775,7 +1741,7 @@ void __init acpi_ec_dsdt_probe(void)
|
||||
* At this point, the GPE is not fully initialized, so do not to
|
||||
* handle the events.
|
||||
*/
|
||||
ret = acpi_ec_setup(ec, NULL, false);
|
||||
ret = acpi_ec_setup(ec, NULL);
|
||||
if (ret) {
|
||||
acpi_ec_free(ec);
|
||||
return;
|
||||
@ -1788,53 +1754,44 @@ void __init acpi_ec_dsdt_probe(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* If the DSDT EC is not functioning, we still need to prepare a fully
|
||||
* functioning ECDT EC first in order to handle the events.
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=115021
|
||||
* acpi_ec_ecdt_start - Finalize the boot ECDT EC initialization.
|
||||
*
|
||||
* First, look for an ACPI handle for the boot ECDT EC if acpi_ec_add() has not
|
||||
* found a matching object in the namespace.
|
||||
*
|
||||
* Next, in case the DSDT EC is not functioning, it is still necessary to
|
||||
* provide a functional ECDT EC to handle events, so add an extra device object
|
||||
* to represent it (see https://bugzilla.kernel.org/show_bug.cgi?id=115021).
|
||||
*
|
||||
* This is useful on platforms with valid ECDT and invalid DSDT EC settings,
|
||||
* like ASUS X550ZE (see https://bugzilla.kernel.org/show_bug.cgi?id=196847).
|
||||
*/
|
||||
static int __init acpi_ec_ecdt_start(void)
|
||||
static void __init acpi_ec_ecdt_start(void)
|
||||
{
|
||||
struct acpi_table_ecdt *ecdt_ptr;
|
||||
acpi_handle handle;
|
||||
acpi_status status;
|
||||
|
||||
if (!boot_ec)
|
||||
return -ENODEV;
|
||||
/* In case acpi_ec_ecdt_start() is called after acpi_ec_add() */
|
||||
if (!boot_ec_is_ecdt)
|
||||
return -ENODEV;
|
||||
/* Bail out if a matching EC has been found in the namespace. */
|
||||
if (!boot_ec || boot_ec->handle != ACPI_ROOT_OBJECT)
|
||||
return;
|
||||
|
||||
/*
|
||||
* At this point, the namespace and the GPE is initialized, so
|
||||
* start to find the namespace objects and handle the events.
|
||||
*
|
||||
* Note: ec->handle can be valid if this function is called after
|
||||
* acpi_ec_add(), hence the fast path.
|
||||
*/
|
||||
if (boot_ec->handle == ACPI_ROOT_OBJECT) {
|
||||
if (!acpi_ec_ecdt_get_handle(&handle))
|
||||
return -ENODEV;
|
||||
boot_ec->handle = handle;
|
||||
}
|
||||
/* Look up the object pointed to from the ECDT in the namespace. */
|
||||
status = acpi_get_table(ACPI_SIG_ECDT, 1,
|
||||
(struct acpi_table_header **)&ecdt_ptr);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
/* Register to ACPI bus with PM ops attached */
|
||||
return acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC);
|
||||
status = acpi_get_handle(NULL, ecdt_ptr->id, &handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
boot_ec->handle = handle;
|
||||
|
||||
/* Add a special ACPI device object to represent the boot EC. */
|
||||
acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Some EC firmware variations refuses to respond QR_EC when SCI_EVT is not
|
||||
* set, for which case, we complete the QR_EC without issuing it to the
|
||||
* firmware.
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=82611
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=97381
|
||||
*/
|
||||
static int ec_flag_query_handshake(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_debug("Detected the EC firmware requiring QR_EC issued when SCI_EVT set\n");
|
||||
EC_FLAGS_QUERY_HANDSHAKE = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On some hardware it is necessary to clear events accumulated by the EC during
|
||||
* sleep. These ECs stop reporting GPEs until they are manually polled, if too
|
||||
@ -1962,7 +1919,7 @@ void __init acpi_ec_ecdt_probe(void)
|
||||
* At this point, the namespace is not initialized, so do not find
|
||||
* the namespace objects, or handle the events.
|
||||
*/
|
||||
ret = acpi_ec_setup(ec, NULL, false);
|
||||
ret = acpi_ec_setup(ec, NULL);
|
||||
if (ret) {
|
||||
acpi_ec_free(ec);
|
||||
return;
|
||||
@ -2165,14 +2122,13 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
int __init acpi_ec_init(void)
|
||||
void __init acpi_ec_init(void)
|
||||
{
|
||||
int result;
|
||||
int ecdt_fail, dsdt_fail;
|
||||
|
||||
result = acpi_ec_init_workqueues();
|
||||
if (result)
|
||||
return result;
|
||||
return;
|
||||
|
||||
/*
|
||||
* Disable EC wakeup on following systems to prevent periodic
|
||||
@ -2183,16 +2139,10 @@ int __init acpi_ec_init(void)
|
||||
pr_debug("Disabling EC wakeup on suspend-to-idle\n");
|
||||
}
|
||||
|
||||
/* Drivers must be started after acpi_ec_query_init() */
|
||||
dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver);
|
||||
/*
|
||||
* Register ECDT to ACPI bus only when PNP0C09 probe fails. This is
|
||||
* useful for platforms (confirmed on ASUS X550ZE) with valid ECDT
|
||||
* settings but invalid DSDT settings.
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=196847
|
||||
*/
|
||||
ecdt_fail = acpi_ec_ecdt_start();
|
||||
return ecdt_fail && dsdt_fail ? -ENODEV : 0;
|
||||
/* Driver must be registered after acpi_ec_init_workqueues(). */
|
||||
acpi_bus_register_driver(&acpi_ec_driver);
|
||||
|
||||
acpi_ec_ecdt_start();
|
||||
}
|
||||
|
||||
/* EC driver currently not unloadable */
|
||||
|
@ -276,29 +276,29 @@ static ssize_t show_state(struct device *dev, struct device_attribute *attr, cha
|
||||
int count;
|
||||
|
||||
if (fps->control == 0xFFFFFFFF || fps->control > 100)
|
||||
count = snprintf(buf, PAGE_SIZE, "not-defined:");
|
||||
count = scnprintf(buf, PAGE_SIZE, "not-defined:");
|
||||
else
|
||||
count = snprintf(buf, PAGE_SIZE, "%lld:", fps->control);
|
||||
count = scnprintf(buf, PAGE_SIZE, "%lld:", fps->control);
|
||||
|
||||
if (fps->trip_point == 0xFFFFFFFF || fps->trip_point > 9)
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "not-defined:");
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
|
||||
else
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "%lld:", fps->trip_point);
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->trip_point);
|
||||
|
||||
if (fps->speed == 0xFFFFFFFF)
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "not-defined:");
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
|
||||
else
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "%lld:", fps->speed);
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->speed);
|
||||
|
||||
if (fps->noise_level == 0xFFFFFFFF)
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "not-defined:");
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined:");
|
||||
else
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "%lld:", fps->noise_level * 100);
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld:", fps->noise_level * 100);
|
||||
|
||||
if (fps->power == 0xFFFFFFFF)
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "not-defined\n");
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "not-defined\n");
|
||||
else
|
||||
count += snprintf(&buf[count], PAGE_SIZE, "%lld\n", fps->power);
|
||||
count += scnprintf(&buf[count], PAGE_SIZE - count, "%lld\n", fps->power);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ extern struct acpi_ec *first_ec;
|
||||
/* External interfaces use first EC only, so remember */
|
||||
typedef int (*acpi_ec_query_func) (void *data);
|
||||
|
||||
int acpi_ec_init(void);
|
||||
void acpi_ec_init(void);
|
||||
void acpi_ec_ecdt_probe(void);
|
||||
void acpi_ec_dsdt_probe(void);
|
||||
void acpi_ec_block_transactions(void);
|
||||
|
@ -1598,6 +1598,7 @@ void acpi_os_delete_lock(acpi_spinlock handle)
|
||||
*/
|
||||
|
||||
acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
|
||||
__acquires(lockp)
|
||||
{
|
||||
acpi_cpu_flags flags;
|
||||
spin_lock_irqsave(lockp, flags);
|
||||
@ -1609,6 +1610,7 @@ acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
|
||||
*/
|
||||
|
||||
void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
|
||||
__releases(lockp)
|
||||
{
|
||||
spin_unlock_irqrestore(lockp, flags);
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word,
|
||||
buf[0] = '\0';
|
||||
for (i = 0, entry = table; i < size; i++, entry++)
|
||||
if (word & entry->bit)
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "%s%s",
|
||||
len += scnprintf(buf + len, sizeof(buf) - len, "%s%s",
|
||||
len ? " " : "", entry->desc);
|
||||
|
||||
dev_info(&root->device->dev, "_OSC: %s [%s]\n", msg, buf);
|
||||
|
@ -22,14 +22,13 @@ ACPI_MODULE_NAME("sleep")
|
||||
static int
|
||||
acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
struct acpi_device *dev, *tmp;
|
||||
|
||||
seq_printf(seq, "Device\tS-state\t Status Sysfs node\n");
|
||||
|
||||
mutex_lock(&acpi_device_lock);
|
||||
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
|
||||
struct acpi_device *dev =
|
||||
container_of(node, struct acpi_device, wakeup_list);
|
||||
list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
|
||||
wakeup_list) {
|
||||
struct acpi_device_physical_node *entry;
|
||||
|
||||
if (!dev->wakeup.flags.valid)
|
||||
@ -96,7 +95,7 @@ acpi_system_write_wakeup_device(struct file *file,
|
||||
const char __user * buffer,
|
||||
size_t count, loff_t * ppos)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
struct acpi_device *dev, *tmp;
|
||||
char strbuf[5];
|
||||
char str[5] = "";
|
||||
|
||||
@ -109,9 +108,8 @@ acpi_system_write_wakeup_device(struct file *file,
|
||||
sscanf(strbuf, "%s", str);
|
||||
|
||||
mutex_lock(&acpi_device_lock);
|
||||
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
|
||||
struct acpi_device *dev =
|
||||
container_of(node, struct acpi_device, wakeup_list);
|
||||
list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
|
||||
wakeup_list) {
|
||||
if (!dev->wakeup.flags.valid)
|
||||
continue;
|
||||
|
||||
|
46
drivers/acpi/tiny-power-button.c
Normal file
46
drivers/acpi/tiny-power-button.c
Normal file
@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/button.h>
|
||||
|
||||
ACPI_MODULE_NAME("tiny-power-button");
|
||||
MODULE_AUTHOR("Josh Triplett");
|
||||
MODULE_DESCRIPTION("ACPI Tiny Power Button Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int power_signal __read_mostly = CONFIG_ACPI_TINY_POWER_BUTTON_SIGNAL;
|
||||
module_param(power_signal, int, 0644);
|
||||
MODULE_PARM_DESC(power_signal, "Power button sends this signal to init");
|
||||
|
||||
static const struct acpi_device_id tiny_power_button_device_ids[] = {
|
||||
{ ACPI_BUTTON_HID_POWER, 0 },
|
||||
{ ACPI_BUTTON_HID_POWERF, 0 },
|
||||
{ "", 0 },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, tiny_power_button_device_ids);
|
||||
|
||||
static int acpi_noop_add_remove(struct acpi_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_tiny_power_button_notify(struct acpi_device *device, u32 event)
|
||||
{
|
||||
kill_cad_pid(power_signal, 1);
|
||||
}
|
||||
|
||||
static struct acpi_driver acpi_tiny_power_button_driver = {
|
||||
.name = "tiny-power-button",
|
||||
.class = "tiny-power-button",
|
||||
.ids = tiny_power_button_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_noop_add_remove,
|
||||
.remove = acpi_noop_add_remove,
|
||||
.notify = acpi_tiny_power_button_notify,
|
||||
},
|
||||
};
|
||||
|
||||
module_driver(acpi_tiny_power_button_driver,
|
||||
acpi_bus_register_driver,
|
||||
acpi_bus_unregister_driver);
|
@ -30,12 +30,10 @@ ACPI_MODULE_NAME("wakeup_devices")
|
||||
*/
|
||||
void acpi_enable_wakeup_devices(u8 sleep_state)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
|
||||
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
|
||||
struct acpi_device *dev =
|
||||
container_of(node, struct acpi_device, wakeup_list);
|
||||
struct acpi_device *dev, *tmp;
|
||||
|
||||
list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
|
||||
wakeup_list) {
|
||||
if (!dev->wakeup.flags.valid
|
||||
|| sleep_state > (u32) dev->wakeup.sleep_state
|
||||
|| !(device_may_wakeup(&dev->dev)
|
||||
@ -57,12 +55,10 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
|
||||
*/
|
||||
void acpi_disable_wakeup_devices(u8 sleep_state)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
|
||||
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
|
||||
struct acpi_device *dev =
|
||||
container_of(node, struct acpi_device, wakeup_list);
|
||||
struct acpi_device *dev, *tmp;
|
||||
|
||||
list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
|
||||
wakeup_list) {
|
||||
if (!dev->wakeup.flags.valid
|
||||
|| sleep_state > (u32) dev->wakeup.sleep_state
|
||||
|| !(device_may_wakeup(&dev->dev)
|
||||
@ -79,13 +75,11 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
|
||||
|
||||
int __init acpi_wakeup_device_init(void)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
struct acpi_device *dev, *tmp;
|
||||
|
||||
mutex_lock(&acpi_device_lock);
|
||||
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
|
||||
struct acpi_device *dev = container_of(node,
|
||||
struct acpi_device,
|
||||
wakeup_list);
|
||||
list_for_each_entry_safe(dev, tmp, &acpi_wakeup_device_list,
|
||||
wakeup_list) {
|
||||
if (device_can_wakeup(&dev->dev)) {
|
||||
/* Button GPEs are supposed to be always enabled. */
|
||||
acpi_enable_gpe(dev->wakeup.gpe_device,
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||
|
||||
#define ACPI_CA_VERSION 0x20200110
|
||||
#define ACPI_CA_VERSION 0x20200214
|
||||
|
||||
#include <acpi/acconfig.h>
|
||||
#include <acpi/actypes.h>
|
||||
|
@ -862,7 +862,7 @@ enum acpi_erst_instructions {
|
||||
/* Command status return values */
|
||||
|
||||
enum acpi_erst_command_status {
|
||||
ACPI_ERST_SUCESS = 0,
|
||||
ACPI_ERST_SUCCESS = 0,
|
||||
ACPI_ERST_NO_SPACE = 1,
|
||||
ACPI_ERST_NOT_AVAILABLE = 2,
|
||||
ACPI_ERST_FAILURE = 3,
|
||||
|
@ -2,6 +2,10 @@
|
||||
#ifndef ACPI_BUTTON_H
|
||||
#define ACPI_BUTTON_H
|
||||
|
||||
#define ACPI_BUTTON_HID_POWER "PNP0C0C"
|
||||
#define ACPI_BUTTON_HID_LID "PNP0C0D"
|
||||
#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI_BUTTON)
|
||||
extern int acpi_lid_open(void);
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user