Skip to content

Commit 64ab5e4

Browse files
committed
Merge tag 'acpi-6.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI fix from Rafael Wysocki: "Fix an issue related to the ACPI EC device handling that causes the _REG control method to be evaluated for EC operation regions that are not expected to be used. This confuses the platform firmware and provokes various types of misbehavior on some systems (Rafael Wysocki)" * tag 'acpi-6.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI: EC: Evaluate _REG outside the EC scope more carefully ACPICA: Add a depth argument to acpi_execute_reg_methods() Revert "ACPI: EC: Evaluate orphan _REG under EC device"
2 parents e4a55b5 + 71bf41b commit 64ab5e4

File tree

7 files changed

+30
-74
lines changed

7 files changed

+30
-74
lines changed

drivers/acpi/acpica/acevents.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,9 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
188188
u8 acpi_ns_is_locked);
189189

190190
void
191-
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
191+
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, u32 max_depth,
192192
acpi_adr_space_type space_id, u32 function);
193193

194-
void
195-
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *node,
196-
acpi_adr_space_type space_id);
197-
198194
acpi_status
199195
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function);
200196

drivers/acpi/acpica/evregion.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ extern u8 acpi_gbl_default_address_spaces[];
2020

2121
/* Local prototypes */
2222

23+
static void
24+
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
25+
acpi_adr_space_type space_id);
26+
2327
static acpi_status
2428
acpi_ev_reg_run(acpi_handle obj_handle,
2529
u32 level, void *context, void **return_value);
@@ -61,6 +65,7 @@ acpi_status acpi_ev_initialize_op_regions(void)
6165
acpi_gbl_default_address_spaces
6266
[i])) {
6367
acpi_ev_execute_reg_methods(acpi_gbl_root_node,
68+
ACPI_UINT32_MAX,
6469
acpi_gbl_default_address_spaces
6570
[i], ACPI_REG_CONNECT);
6671
}
@@ -668,6 +673,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
668673
* FUNCTION: acpi_ev_execute_reg_methods
669674
*
670675
* PARAMETERS: node - Namespace node for the device
676+
* max_depth - Depth to which search for _REG
671677
* space_id - The address space ID
672678
* function - Passed to _REG: On (1) or Off (0)
673679
*
@@ -679,7 +685,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
679685
******************************************************************************/
680686

681687
void
682-
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
688+
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, u32 max_depth,
683689
acpi_adr_space_type space_id, u32 function)
684690
{
685691
struct acpi_reg_walk_info info;
@@ -713,7 +719,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
713719
* regions and _REG methods. (i.e. handlers must be installed for all
714720
* regions of this Space ID before we can run any _REG methods)
715721
*/
716-
(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
722+
(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, max_depth,
717723
ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL,
718724
&info, NULL);
719725

@@ -814,7 +820,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
814820
*
815821
******************************************************************************/
816822

817-
void
823+
static void
818824
acpi_ev_execute_orphan_reg_method(struct acpi_namespace_node *device_node,
819825
acpi_adr_space_type space_id)
820826
{

drivers/acpi/acpica/evxfregn.c

Lines changed: 7 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ acpi_install_address_space_handler_internal(acpi_handle device,
8585
/* Run all _REG methods for this address space */
8686

8787
if (run_reg) {
88-
acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
88+
acpi_ev_execute_reg_methods(node, ACPI_UINT32_MAX, space_id,
89+
ACPI_REG_CONNECT);
8990
}
9091

9192
unlock_and_exit:
@@ -263,6 +264,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)
263264
* FUNCTION: acpi_execute_reg_methods
264265
*
265266
* PARAMETERS: device - Handle for the device
267+
* max_depth - Depth to which search for _REG
266268
* space_id - The address space ID
267269
*
268270
* RETURN: Status
@@ -271,7 +273,8 @@ ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)
271273
*
272274
******************************************************************************/
273275
acpi_status
274-
acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
276+
acpi_execute_reg_methods(acpi_handle device, u32 max_depth,
277+
acpi_adr_space_type space_id)
275278
{
276279
struct acpi_namespace_node *node;
277280
acpi_status status;
@@ -296,7 +299,8 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
296299

297300
/* Run all _REG methods for this address space */
298301

299-
acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
302+
acpi_ev_execute_reg_methods(node, max_depth, space_id,
303+
ACPI_REG_CONNECT);
300304
} else {
301305
status = AE_BAD_PARAMETER;
302306
}
@@ -306,57 +310,3 @@ acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
306310
}
307311

308312
ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods)
309-
310-
/*******************************************************************************
311-
*
312-
* FUNCTION: acpi_execute_orphan_reg_method
313-
*
314-
* PARAMETERS: device - Handle for the device
315-
* space_id - The address space ID
316-
*
317-
* RETURN: Status
318-
*
319-
* DESCRIPTION: Execute an "orphan" _REG method that appears under an ACPI
320-
* device. This is a _REG method that has no corresponding region
321-
* within the device's scope.
322-
*
323-
******************************************************************************/
324-
acpi_status
325-
acpi_execute_orphan_reg_method(acpi_handle device, acpi_adr_space_type space_id)
326-
{
327-
struct acpi_namespace_node *node;
328-
acpi_status status;
329-
330-
ACPI_FUNCTION_TRACE(acpi_execute_orphan_reg_method);
331-
332-
/* Parameter validation */
333-
334-
if (!device) {
335-
return_ACPI_STATUS(AE_BAD_PARAMETER);
336-
}
337-
338-
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
339-
if (ACPI_FAILURE(status)) {
340-
return_ACPI_STATUS(status);
341-
}
342-
343-
/* Convert and validate the device handle */
344-
345-
node = acpi_ns_validate_handle(device);
346-
if (node) {
347-
348-
/*
349-
* If an "orphan" _REG method is present in the device's scope
350-
* for the given address space ID, run it.
351-
*/
352-
353-
acpi_ev_execute_orphan_reg_method(node, space_id);
354-
} else {
355-
status = AE_BAD_PARAMETER;
356-
}
357-
358-
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
359-
return_ACPI_STATUS(status);
360-
}
361-
362-
ACPI_EXPORT_SYMBOL(acpi_execute_orphan_reg_method)

drivers/acpi/ec.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,12 +1487,13 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
14871487
static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
14881488
bool call_reg)
14891489
{
1490-
acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
14911490
acpi_status status;
14921491

14931492
acpi_ec_start(ec, false);
14941493

14951494
if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
1495+
acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
1496+
14961497
acpi_ec_enter_noirq(ec);
14971498
status = acpi_install_address_space_handler_no_reg(scope_handle,
14981499
ACPI_ADR_SPACE_EC,
@@ -1506,10 +1507,7 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
15061507
}
15071508

15081509
if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
1509-
acpi_execute_reg_methods(scope_handle, ACPI_ADR_SPACE_EC);
1510-
if (scope_handle != ec->handle)
1511-
acpi_execute_orphan_reg_method(ec->handle, ACPI_ADR_SPACE_EC);
1512-
1510+
acpi_execute_reg_methods(ec->handle, ACPI_UINT32_MAX, ACPI_ADR_SPACE_EC);
15131511
set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
15141512
}
15151513

@@ -1724,6 +1722,12 @@ static void acpi_ec_remove(struct acpi_device *device)
17241722
}
17251723
}
17261724

1725+
void acpi_ec_register_opregions(struct acpi_device *adev)
1726+
{
1727+
if (first_ec && first_ec->handle != adev->handle)
1728+
acpi_execute_reg_methods(adev->handle, 1, ACPI_ADR_SPACE_EC);
1729+
}
1730+
17271731
static acpi_status
17281732
ec_parse_io_ports(struct acpi_resource *resource, void *context)
17291733
{

drivers/acpi/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
223223
acpi_handle handle, acpi_ec_query_func func,
224224
void *data);
225225
void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
226+
void acpi_ec_register_opregions(struct acpi_device *adev);
226227

227228
#ifdef CONFIG_PM_SLEEP
228229
void acpi_ec_flush_work(void);

drivers/acpi/scan.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,6 +2273,8 @@ static int acpi_bus_attach(struct acpi_device *device, void *first_pass)
22732273
if (device->handler)
22742274
goto ok;
22752275

2276+
acpi_ec_register_opregions(device);
2277+
22762278
if (!device->flags.initialized) {
22772279
device->flags.power_manageable =
22782280
device->power.states[ACPI_STATE_D0].flags.valid;

include/acpi/acpixf.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -660,12 +660,9 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
660660
void *context))
661661
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
662662
acpi_execute_reg_methods(acpi_handle device,
663+
u32 nax_depth,
663664
acpi_adr_space_type
664665
space_id))
665-
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
666-
acpi_execute_orphan_reg_method(acpi_handle device,
667-
acpi_adr_space_type
668-
space_id))
669666
ACPI_EXTERNAL_RETURN_STATUS(acpi_status
670667
acpi_remove_address_space_handler(acpi_handle
671668
device,

0 commit comments

Comments
 (0)