Skip to content

Commit 057b40f

Browse files
committed
Merge tag 'acpi-6.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI updates from Rafael Wysocki: "These fix an AML byte code execution issue in ACPICA and two issues in the ACPI EC driver which requires rearranging ACPICA code. Specifics: - Avoid trying to resolve operands in AML when there are none (Amadeusz Sławiński) - Fix indentation in include/acpi/acpixf.h to help applying patches from the upstream ACPICA git (Hans de Goede) - Make it possible to install an address space handler without evaluating _REG for Operation Regions in the given address space (Hans de Goede) - Defer the evaluation of _REG for ECDT described ECs till the matching EC device in the DSDT gets parsed and acpi_ec_add() gets called for it (Hans de Goede) - Fix EC address space handler unregistration (Hans de Goede)" * tag 'acpi-6.2-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI: EC: Fix ECDT probe ordering issues ACPI: EC: Fix EC address space handler unregistration ACPICA: Allow address_space_handler Install and _REG execution as 2 separate steps ACPICA: include/acpi/acpixf.h: Fix indentation ACPICA: Fix operand resolution
2 parents 601c1aa + 3d03140 commit 057b40f

File tree

5 files changed

+181
-80
lines changed

5 files changed

+181
-80
lines changed

drivers/acpi/acpica/dswexec.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,11 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
389389

390390
/*
391391
* All opcodes require operand resolution, with the only exceptions
392-
* being the object_type and size_of operators.
392+
* being the object_type and size_of operators as well as opcodes that
393+
* take no arguments.
393394
*/
394-
if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
395+
if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE) &&
396+
(walk_state->op_info->flags & AML_HAS_ARGS)) {
395397

396398
/* Resolve all operands */
397399

drivers/acpi/acpica/evxfregn.c

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ ACPI_MODULE_NAME("evxfregn")
2020

2121
/*******************************************************************************
2222
*
23-
* FUNCTION: acpi_install_address_space_handler
23+
* FUNCTION: acpi_install_address_space_handler_internal
2424
*
2525
* PARAMETERS: device - Handle for the device
2626
* space_id - The address space ID
2727
* handler - Address of the handler
2828
* setup - Address of the setup function
2929
* context - Value passed to the handler on each access
30+
* Run_reg - Run _REG methods for this address space?
3031
*
3132
* RETURN: Status
3233
*
@@ -37,13 +38,16 @@ ACPI_MODULE_NAME("evxfregn")
3738
* are executed here, and these methods can only be safely executed after
3839
* the default handlers have been installed and the hardware has been
3940
* initialized (via acpi_enable_subsystem.)
41+
* To avoid this problem pass FALSE for Run_Reg and later on call
42+
* acpi_execute_reg_methods() to execute _REG.
4043
*
4144
******************************************************************************/
42-
acpi_status
43-
acpi_install_address_space_handler(acpi_handle device,
44-
acpi_adr_space_type space_id,
45-
acpi_adr_space_handler handler,
46-
acpi_adr_space_setup setup, void *context)
45+
static acpi_status
46+
acpi_install_address_space_handler_internal(acpi_handle device,
47+
acpi_adr_space_type space_id,
48+
acpi_adr_space_handler handler,
49+
acpi_adr_space_setup setup,
50+
void *context, u8 run_reg)
4751
{
4852
struct acpi_namespace_node *node;
4953
acpi_status status;
@@ -80,14 +84,40 @@ acpi_install_address_space_handler(acpi_handle device,
8084

8185
/* Run all _REG methods for this address space */
8286

83-
acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
87+
if (run_reg) {
88+
acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
89+
}
8490

8591
unlock_and_exit:
8692
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
8793
return_ACPI_STATUS(status);
8894
}
8995

96+
acpi_status
97+
acpi_install_address_space_handler(acpi_handle device,
98+
acpi_adr_space_type space_id,
99+
acpi_adr_space_handler handler,
100+
acpi_adr_space_setup setup, void *context)
101+
{
102+
return acpi_install_address_space_handler_internal(device, space_id,
103+
handler, setup,
104+
context, TRUE);
105+
}
106+
90107
ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler)
108+
acpi_status
109+
acpi_install_address_space_handler_no_reg(acpi_handle device,
110+
acpi_adr_space_type space_id,
111+
acpi_adr_space_handler handler,
112+
acpi_adr_space_setup setup,
113+
void *context)
114+
{
115+
return acpi_install_address_space_handler_internal(device, space_id,
116+
handler, setup,
117+
context, FALSE);
118+
}
119+
120+
ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler_no_reg)
91121

92122
/*******************************************************************************
93123
*
@@ -228,3 +258,51 @@ acpi_remove_address_space_handler(acpi_handle device,
228258
}
229259

230260
ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)
261+
/*******************************************************************************
262+
*
263+
* FUNCTION: acpi_execute_reg_methods
264+
*
265+
* PARAMETERS: device - Handle for the device
266+
* space_id - The address space ID
267+
*
268+
* RETURN: Status
269+
*
270+
* DESCRIPTION: Execute _REG for all op_regions of a given space_id.
271+
*
272+
******************************************************************************/
273+
acpi_status
274+
acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
275+
{
276+
struct acpi_namespace_node *node;
277+
acpi_status status;
278+
279+
ACPI_FUNCTION_TRACE(acpi_execute_reg_methods);
280+
281+
/* Parameter validation */
282+
283+
if (!device) {
284+
return_ACPI_STATUS(AE_BAD_PARAMETER);
285+
}
286+
287+
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
288+
if (ACPI_FAILURE(status)) {
289+
return_ACPI_STATUS(status);
290+
}
291+
292+
/* Convert and validate the device handle */
293+
294+
node = acpi_ns_validate_handle(device);
295+
if (node) {
296+
297+
/* Run all _REG methods for this address space */
298+
299+
acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
300+
} else {
301+
status = AE_BAD_PARAMETER;
302+
}
303+
304+
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
305+
return_ACPI_STATUS(status);
306+
}
307+
308+
ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods)

drivers/acpi/ec.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ enum {
9494
EC_FLAGS_QUERY_ENABLED, /* Query is enabled */
9595
EC_FLAGS_EVENT_HANDLER_INSTALLED, /* Event handler installed */
9696
EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */
97+
EC_FLAGS_EC_REG_CALLED, /* OpReg ACPI _REG method called */
9798
EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */
9899
EC_FLAGS_STARTED, /* Driver is started */
99100
EC_FLAGS_STOPPED, /* Driver is stopped */
@@ -1446,6 +1447,7 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
14461447
* ec_install_handlers - Install service callbacks and register query methods.
14471448
* @ec: Target EC.
14481449
* @device: ACPI device object corresponding to @ec.
1450+
* @call_reg: If _REG should be called to notify OpRegion availability
14491451
*
14501452
* Install a handler for the EC address space type unless it has been installed
14511453
* already. If @device is not NULL, also look for EC query methods in the
@@ -1458,23 +1460,30 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
14581460
* -EPROBE_DEFER if GPIO IRQ acquisition needs to be deferred,
14591461
* or 0 (success) otherwise.
14601462
*/
1461-
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
1463+
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
1464+
bool call_reg)
14621465
{
14631466
acpi_status status;
14641467

14651468
acpi_ec_start(ec, false);
14661469

14671470
if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
14681471
acpi_ec_enter_noirq(ec);
1469-
status = acpi_install_address_space_handler(ec->handle,
1470-
ACPI_ADR_SPACE_EC,
1471-
&acpi_ec_space_handler,
1472-
NULL, ec);
1472+
status = acpi_install_address_space_handler_no_reg(ec->handle,
1473+
ACPI_ADR_SPACE_EC,
1474+
&acpi_ec_space_handler,
1475+
NULL, ec);
14731476
if (ACPI_FAILURE(status)) {
14741477
acpi_ec_stop(ec, false);
14751478
return -ENODEV;
14761479
}
14771480
set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
1481+
ec->address_space_handler_holder = ec->handle;
1482+
}
1483+
1484+
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
1485+
acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
1486+
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
14781487
}
14791488

14801489
if (!device)
@@ -1526,7 +1535,8 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
15261535
static void ec_remove_handlers(struct acpi_ec *ec)
15271536
{
15281537
if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
1529-
if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
1538+
if (ACPI_FAILURE(acpi_remove_address_space_handler(
1539+
ec->address_space_handler_holder,
15301540
ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
15311541
pr_err("failed to remove space handler\n");
15321542
clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
@@ -1562,11 +1572,11 @@ static void ec_remove_handlers(struct acpi_ec *ec)
15621572
}
15631573
}
15641574

1565-
static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device)
1575+
static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool call_reg)
15661576
{
15671577
int ret;
15681578

1569-
ret = ec_install_handlers(ec, device);
1579+
ret = ec_install_handlers(ec, device, call_reg);
15701580
if (ret)
15711581
return ret;
15721582

@@ -1631,7 +1641,7 @@ static int acpi_ec_add(struct acpi_device *device)
16311641
}
16321642
}
16331643

1634-
ret = acpi_ec_setup(ec, device);
1644+
ret = acpi_ec_setup(ec, device, true);
16351645
if (ret)
16361646
goto err;
16371647

@@ -1750,7 +1760,7 @@ void __init acpi_ec_dsdt_probe(void)
17501760
* At this point, the GPE is not fully initialized, so do not to
17511761
* handle the events.
17521762
*/
1753-
ret = acpi_ec_setup(ec, NULL);
1763+
ret = acpi_ec_setup(ec, NULL, true);
17541764
if (ret) {
17551765
acpi_ec_free(ec);
17561766
return;
@@ -1944,7 +1954,7 @@ void __init acpi_ec_ecdt_probe(void)
19441954
* At this point, the namespace is not initialized, so do not find
19451955
* the namespace objects, or handle the events.
19461956
*/
1947-
ret = acpi_ec_setup(ec, NULL);
1957+
ret = acpi_ec_setup(ec, NULL, false);
19481958
if (ret) {
19491959
acpi_ec_free(ec);
19501960
goto out;

drivers/acpi/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ enum acpi_ec_event_state {
173173

174174
struct acpi_ec {
175175
acpi_handle handle;
176+
acpi_handle address_space_handler_holder;
176177
int gpe;
177178
int irq;
178179
unsigned long command_addr;

0 commit comments

Comments
 (0)