linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues
@ 2022-10-03 14:42 Hans de Goede
  2022-10-03 14:42 ` [RFC v3 1/4] ACPICA: include/acpi/acpixf.h: Fix indentation Hans de Goede
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Hans de Goede @ 2022-10-03 14:42 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg
  Cc: Hans de Goede, Zhang Rui, Andy Shevchenko, kai.heng.feng,
	Johannes Penßel, linux-acpi, devel

Hi All,

Here is v3 of my series fixing some ECDT EC probe ordering issues which
are causing issues om some laptops:

https://bugzilla.kernel.org/show_bug.cgi?id=214899

This is a RFC because fixing this requires some ACPICA changes which
obviously need to go upstream through the ACPICA project:
https://github.com/acpica/acpica/pull/786

The problem this fixed is best described by the commit message of patch 4:

ACPI-2.0 says that the EC OpRegion handler must be available immediately
(like the standard default OpRegion handlers):

Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ...
2. OSPM must make Embedded Controller operation regions, accessed via
the Embedded Controllers described in ECDT, available before executing
any control method. These operation regions may become inaccessible
after OSPM runs _REG(EmbeddedControl, 0)."

So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls
acpi_install_address_space_handler() to install the EC's OpRegion
handler, early on.

This not only installs the OpRegion handler, but also calls the EC's
_REG method. The _REG method call is a problem because it may rely on
initialization done by the _INI methods of one of the PCI / _SB root devs,
see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 .

Generally speaking _REG methods are executed when the ACPI-device they
are part of has a driver bound to it. Where as _INI methods must be
executed at table load time (according to the spec). The problem here
is that the early acpi_install_address_space_handler() call causes
the _REG handler to run too early.

To allow fixing this the ACPICA code now allows to split the OpRegion
handler installation and the executing of _REG into 2 separate steps.

This commit uses this ACPICA functionality to fix the EC probe ordering
by delaying the executing of _REG for ECDT described ECs till the matching
EC device in the DSDT gets parsed and acpi_ec_add() for it gets called.
This moves the calling of _REG for the EC on devices with an ECDT to
the same point in time where it is called on devices without an ECDT table.

Changes in v3:
- Add a prep patch to fix an indentation issue in Linux' acpixf.h to fix
  the patch from ACPICA's script not applying
- Add 2 new functions to ACPICA for this instead of a flags argument
  1. acpi_install_address_space_handler_no_reg()
  2. acpi_execute_reg_methods()
- Add a patch to fix EC handler removal in the ECDT case

From my pov this series is ready for merging once the ACPICA changes
are accepted.

Regards,

Hans


Hans de Goede (4):
  ACPICA: include/acpi/acpixf.h: Fix indentation
  ACPICA: Allow address_space_handler Install and _REG execution as 2
    separate steps
  ACPI: EC: Fix EC address space handler unregistration
  ACPI: EC: fix ECDT probe ordering issues

 drivers/acpi/acpica/evxfregn.c |  92 +++++++++++++++++++++--
 drivers/acpi/ec.c              |  32 +++++---
 drivers/acpi/internal.h        |   1 +
 include/acpi/acpixf.h          | 130 ++++++++++++++++++---------------
 4 files changed, 177 insertions(+), 78 deletions(-)

-- 
2.37.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [RFC v3 1/4] ACPICA: include/acpi/acpixf.h: Fix indentation
  2022-10-03 14:42 [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues Hans de Goede
@ 2022-10-03 14:42 ` Hans de Goede
  2022-10-03 14:42 ` [RFC v3 2/4] ACPICA: Allow address_space_handler Install and _REG execution as 2 separate steps Hans de Goede
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Hans de Goede @ 2022-10-03 14:42 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg
  Cc: Hans de Goede, Zhang Rui, Andy Shevchenko, kai.heng.feng,
	Johannes Penßel, linux-acpi, devel

A bunch of the functions declared in include/acpi/acpixf.h have their
name aligned a space after the '(' of e.g. the
`ACPI_EXTERNAL_RETURN_STATUS(acpi_status` line above rather then being
directly aligned after the '('.

This breaks applying patches generated from the ACPICA upstream git,
remove the extra space before the function-names and all the arguments
to fix this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 include/acpi/acpixf.h | 120 +++++++++++++++++++++---------------------
 1 file changed, 60 insertions(+), 60 deletions(-)

diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 67c0b9e734b6..3fde274c465b 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -589,82 +589,82 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			    acpi_install_initialization_handler
 			    (acpi_init_handler handler, u32 function))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_install_sci_handler(acpi_sci_handler
-							  address,
-							  void *context))
-ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_remove_sci_handler(acpi_sci_handler
-							 address))
+				acpi_install_sci_handler(acpi_sci_handler
+							 address,
+							 void *context))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_install_global_event_handler
-				 (acpi_gbl_event_handler handler,
-				  void *context))
+				acpi_remove_sci_handler(acpi_sci_handler
+							address))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_install_fixed_event_handler(u32
-								  acpi_event,
-								  acpi_event_handler
-								  handler,
-								  void
-								  *context))
+				acpi_install_global_event_handler
+				(acpi_gbl_event_handler handler,
+				 void *context))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_remove_fixed_event_handler(u32 acpi_event,
+				acpi_install_fixed_event_handler(u32
+								 acpi_event,
 								 acpi_event_handler
-								 handler))
-ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_install_gpe_handler(acpi_handle
-							  gpe_device,
-							  u32 gpe_number,
-							  u32 type,
-							  acpi_gpe_handler
-							  address,
-							  void *context))
+								 handler,
+								 void
+								 *context))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_install_gpe_raw_handler(acpi_handle
-							      gpe_device,
-							      u32 gpe_number,
-							      u32 type,
-							      acpi_gpe_handler
-							      address,
-							      void *context))
+				acpi_remove_fixed_event_handler(u32 acpi_event,
+								acpi_event_handler
+								handler))
 ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
-				 acpi_remove_gpe_handler(acpi_handle gpe_device,
+				acpi_install_gpe_handler(acpi_handle
+							 gpe_device,
 							 u32 gpe_number,
+							 u32 type,
 							 acpi_gpe_handler
-							 address))
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_install_notify_handler(acpi_handle device,
-							 u32 handler_type,
-							 acpi_notify_handler
-							 handler,
+							 address,
 							 void *context))
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
+				acpi_install_gpe_raw_handler(acpi_handle
+							     gpe_device,
+							     u32 gpe_number,
+							     u32 type,
+							     acpi_gpe_handler
+							     address,
+							     void *context))
+ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status
+				acpi_remove_gpe_handler(acpi_handle gpe_device,
+							u32 gpe_number,
+							acpi_gpe_handler
+							address))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_remove_notify_handler(acpi_handle device,
+			    acpi_install_notify_handler(acpi_handle device,
 							u32 handler_type,
 							acpi_notify_handler
-							handler))
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_install_address_space_handler(acpi_handle
-								device,
-								acpi_adr_space_type
-								space_id,
-								acpi_adr_space_handler
-								handler,
-								acpi_adr_space_setup
-								setup,
-								void *context))
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_remove_address_space_handler(acpi_handle
+							handler,
+							void *context))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+			    acpi_remove_notify_handler(acpi_handle device,
+						       u32 handler_type,
+						       acpi_notify_handler
+						       handler))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+			    acpi_install_address_space_handler(acpi_handle
 							       device,
 							       acpi_adr_space_type
 							       space_id,
 							       acpi_adr_space_handler
-							       handler))
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_install_exception_handler
-			     (acpi_exception_handler handler))
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_install_interface_handler
-			     (acpi_interface_handler handler))
+							       handler,
+							       acpi_adr_space_setup
+							       setup,
+							       void *context))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+			    acpi_remove_address_space_handler(acpi_handle
+							      device,
+							      acpi_adr_space_type
+							      space_id,
+							      acpi_adr_space_handler
+							      handler))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+			    acpi_install_exception_handler
+			    (acpi_exception_handler handler))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+			    acpi_install_interface_handler
+			    (acpi_interface_handler handler))
 
 /*
  * Global Lock interfaces
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC v3 2/4] ACPICA: Allow address_space_handler Install and _REG execution as 2 separate steps
  2022-10-03 14:42 [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues Hans de Goede
  2022-10-03 14:42 ` [RFC v3 1/4] ACPICA: include/acpi/acpixf.h: Fix indentation Hans de Goede
@ 2022-10-03 14:42 ` Hans de Goede
  2022-10-03 14:42 ` [RFC v3 3/4] ACPI: EC: Fix EC address space handler unregistration Hans de Goede
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Hans de Goede @ 2022-10-03 14:42 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg
  Cc: Hans de Goede, Zhang Rui, Andy Shevchenko, kai.heng.feng,
	Johannes Penßel, linux-acpi, devel

ACPICA commit ead772dd15412719e033617966ec7e3a14bd4d89

ACPI-2.0 says that the EC op_region handler must be available immediately
(like the standard default op_region handlers):

Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ...
2. OSPM must make Embedded Controller operation regions, accessed via
the Embedded Controllers described in ECDT, available before executing
any control method. These operation regions may become inaccessible
after OSPM runs _REG(EmbeddedControl, 0)."

So the OS must probe the ECDT described EC and install the OpRegion hdlr
before calling acpi_enable_subsystem() and acpi_initialize_objects().

This is a problem because calling acpi_install_address_space_handler()
does not just install the op_region handler, it also runs the EC's _REG
method. This _REG method may rely on initialization done by the _INI
methods of one of the PCI / _SB root devices.

For the other early/default op_region handlers the op_region handler
install and the _REG execution is split into 2 separate steps:
1. acpi_ev_install_region_handlers(), called early from acpi_load_tables()
2. acpi_ev_initialize_op_regions(), called from acpi_initialize_objects()

To fix the EC op_region issue, add 2 bew functions:
1. acpi_install_address_space_handler_no_Reg()
2. acpi_execute_reg_methods()
to allow doing things in 2 steps for other op_region handlers,
like the EC handler, too.

Note that the comment describing acpi_ev_install_region_handlers() even has
an alinea describing this problem. Using the new methods allows users
to avoid this problem.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=214899
Link: https://github.com/acpica/acpica/commit/ead772dd
Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/acpica/evxfregn.c | 92 +++++++++++++++++++++++++++++++---
 include/acpi/acpixf.h          | 10 ++++
 2 files changed, 95 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 0a8372bf6a77..a5c19f46ec17 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -20,13 +20,14 @@ ACPI_MODULE_NAME("evxfregn")
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_install_address_space_handler
+ * FUNCTION:    acpi_install_address_space_handler_internal
  *
  * PARAMETERS:  device          - Handle for the device
  *              space_id        - The address space ID
  *              handler         - Address of the handler
  *              setup           - Address of the setup function
  *              context         - Value passed to the handler on each access
+ *              Run_reg         - Run _REG methods for this address space?
  *
  * RETURN:      Status
  *
@@ -37,13 +38,16 @@ ACPI_MODULE_NAME("evxfregn")
  * are executed here, and these methods can only be safely executed after
  * the default handlers have been installed and the hardware has been
  * initialized (via acpi_enable_subsystem.)
+ * To avoid this problem pass FALSE for Run_Reg and later on call
+ * acpi_execute_reg_methods() to execute _REG.
  *
  ******************************************************************************/
-acpi_status
-acpi_install_address_space_handler(acpi_handle device,
-				   acpi_adr_space_type space_id,
-				   acpi_adr_space_handler handler,
-				   acpi_adr_space_setup setup, void *context)
+static acpi_status
+acpi_install_address_space_handler_internal(acpi_handle device,
+					    acpi_adr_space_type space_id,
+					    acpi_adr_space_handler handler,
+					    acpi_adr_space_setup setup,
+					    void *context, u8 run_reg)
 {
 	struct acpi_namespace_node *node;
 	acpi_status status;
@@ -80,14 +84,40 @@ acpi_install_address_space_handler(acpi_handle device,
 
 	/* Run all _REG methods for this address space */
 
-	acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
+	if (run_reg) {
+		acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
+	}
 
 unlock_and_exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	return_ACPI_STATUS(status);
 }
 
+acpi_status
+acpi_install_address_space_handler(acpi_handle device,
+				   acpi_adr_space_type space_id,
+				   acpi_adr_space_handler handler,
+				   acpi_adr_space_setup setup, void *context)
+{
+	return acpi_install_address_space_handler_internal(device, space_id,
+							   handler, setup,
+							   context, TRUE);
+}
+
 ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler)
+acpi_status
+acpi_install_address_space_handler_no_reg(acpi_handle device,
+					  acpi_adr_space_type space_id,
+					  acpi_adr_space_handler handler,
+					  acpi_adr_space_setup setup,
+					  void *context)
+{
+	return acpi_install_address_space_handler_internal(device, space_id,
+							   handler, setup,
+							   context, FALSE);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_install_address_space_handler_no_reg)
 
 /*******************************************************************************
  *
@@ -228,3 +258,51 @@ acpi_remove_address_space_handler(acpi_handle device,
 }
 
 ACPI_EXPORT_SYMBOL(acpi_remove_address_space_handler)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_execute_reg_methods
+ *
+ * PARAMETERS:  device          - Handle for the device
+ *              space_id        - The address space ID
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute _REG for all op_regions of a given space_id.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
+{
+	struct acpi_namespace_node *node;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(acpi_execute_reg_methods);
+
+	/* Parameter validation */
+
+	if (!device) {
+		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	}
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/* Convert and validate the device handle */
+
+	node = acpi_ns_validate_handle(device);
+	if (node) {
+
+		/* Run all _REG methods for this address space */
+
+		acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
+	} else {
+		status = AE_BAD_PARAMETER;
+	}
+
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_execute_reg_methods)
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 3fde274c465b..9c1021dcd270 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -652,6 +652,16 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 							       acpi_adr_space_setup
 							       setup,
 							       void *context))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+			    acpi_install_address_space_handler_no_reg
+			    (acpi_handle device, acpi_adr_space_type space_id,
+			     acpi_adr_space_handler handler,
+			     acpi_adr_space_setup setup,
+			     void *context))
+ACPI_EXTERNAL_RETURN_STATUS(acpi_status
+			    acpi_execute_reg_methods(acpi_handle device,
+						     acpi_adr_space_type
+						     space_id))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			    acpi_remove_address_space_handler(acpi_handle
 							      device,
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC v3 3/4] ACPI: EC: Fix EC address space handler unregistration
  2022-10-03 14:42 [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues Hans de Goede
  2022-10-03 14:42 ` [RFC v3 1/4] ACPICA: include/acpi/acpixf.h: Fix indentation Hans de Goede
  2022-10-03 14:42 ` [RFC v3 2/4] ACPICA: Allow address_space_handler Install and _REG execution as 2 separate steps Hans de Goede
@ 2022-10-03 14:42 ` Hans de Goede
  2022-10-03 14:42 ` [RFC v3 4/4] ACPI: EC: fix ECDT probe ordering issues Hans de Goede
  2022-10-13 16:53 ` [RFC v3 0/4] ACPI[CA]: fix ECDT EC " Rafael J. Wysocki
  4 siblings, 0 replies; 9+ messages in thread
From: Hans de Goede @ 2022-10-03 14:42 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg
  Cc: Hans de Goede, Zhang Rui, Andy Shevchenko, kai.heng.feng,
	Johannes Penßel, linux-acpi, devel

When an ECDT table is present the EC address space handler gets registered
on the root node. So to unregister it properly the unregister call also
must be done on the root node.

Store the ACPI handle used for the acpi_install_address_space_handler()
call and use te same handle for the acpi_remove_address_space_handler()
call.

Reported-by: Rafael J. Wysocki <rafael@kernel.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/ec.c       | 4 +++-
 drivers/acpi/internal.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index c95e535035a0..55c503225396 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1479,6 +1479,7 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
 			return -ENODEV;
 		}
 		set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
+		ec->address_space_handler_holder = ec->handle;
 	}
 
 	if (!device)
@@ -1530,7 +1531,8 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
 static void ec_remove_handlers(struct acpi_ec *ec)
 {
 	if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
-		if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
+		if (ACPI_FAILURE(acpi_remove_address_space_handler(
+					ec->address_space_handler_holder,
 					ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
 			pr_err("failed to remove space handler\n");
 		clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 628bf8f18130..dd3bcbefbc06 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -173,6 +173,7 @@ enum acpi_ec_event_state {
 
 struct acpi_ec {
 	acpi_handle handle;
+	acpi_handle address_space_handler_holder;
 	int gpe;
 	int irq;
 	unsigned long command_addr;
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [RFC v3 4/4] ACPI: EC: fix ECDT probe ordering issues
  2022-10-03 14:42 [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues Hans de Goede
                   ` (2 preceding siblings ...)
  2022-10-03 14:42 ` [RFC v3 3/4] ACPI: EC: Fix EC address space handler unregistration Hans de Goede
@ 2022-10-03 14:42 ` Hans de Goede
  2022-10-04  8:24   ` Andy Shevchenko
  2022-10-13 16:53 ` [RFC v3 0/4] ACPI[CA]: fix ECDT EC " Rafael J. Wysocki
  4 siblings, 1 reply; 9+ messages in thread
From: Hans de Goede @ 2022-10-03 14:42 UTC (permalink / raw)
  To: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg
  Cc: Hans de Goede, Zhang Rui, Andy Shevchenko, kai.heng.feng,
	Johannes Penßel, linux-acpi, devel

ACPI-2.0 says that the EC OpRegion handler must be available immediately
(like the standard default OpRegion handlers):

Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ...
2. OSPM must make Embedded Controller operation regions, accessed via
the Embedded Controllers described in ECDT, available before executing
any control method. These operation regions may become inaccessible
after OSPM runs _REG(EmbeddedControl, 0)."

So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls
acpi_install_address_space_handler() to install the EC's OpRegion
handler, early on.

This not only installs the OpRegion handler, but also calls the EC's
_REG method. The _REG method call is a problem because it may rely on
initialization done by the _INI methods of one of the PCI / _SB root devs,
see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 .

Generally speaking _REG methods are executed when the ACPI-device they
are part of has a driver bound to it. Where as _INI methods must be
executed at table load time (according to the spec). The problem here
is that the early acpi_install_address_space_handler() call causes
the _REG handler to run too early.

To allow fixing this the ACPICA code now allows to split the OpRegion
handler installation and the executing of _REG into 2 separate steps.

This commit uses this ACPICA functionality to fix the EC probe ordering
by delaying the executing of _REG for ECDT described ECs till the matching
EC device in the DSDT gets parsed and acpi_ec_add() for it gets called.
This moves the calling of _REG for the EC on devices with an ECDT to
the same point in time where it is called on devices without an ECDT table.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899
Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v3:
- Rebase on top of v2 ACPICA patches which add 2 new functions for this
  instead of using a flags argument
---
 drivers/acpi/ec.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 55c503225396..538e521085c3 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -94,6 +94,7 @@ enum {
 	EC_FLAGS_QUERY_ENABLED,		/* Query is enabled */
 	EC_FLAGS_EVENT_HANDLER_INSTALLED,	/* Event handler installed */
 	EC_FLAGS_EC_HANDLER_INSTALLED,	/* OpReg handler installed */
+	EC_FLAGS_EC_REG_CALLED,		/* OpReg ACPI _REG method called */
 	EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */
 	EC_FLAGS_STARTED,		/* Driver is started */
 	EC_FLAGS_STOPPED,		/* Driver is stopped */
@@ -1450,6 +1451,7 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
  * ec_install_handlers - Install service callbacks and register query methods.
  * @ec: Target EC.
  * @device: ACPI device object corresponding to @ec.
+ * @call_reg: If _REG should be called to notify OpRegion availability
  *
  * 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
@@ -1462,7 +1464,8 @@ static bool install_gpio_irq_event_handler(struct acpi_ec *ec)
  * -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)
+static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device,
+			       bool call_reg)
 {
 	acpi_status status;
 
@@ -1470,10 +1473,10 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
 
 	if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
 		acpi_ec_enter_noirq(ec);
-		status = acpi_install_address_space_handler(ec->handle,
-							    ACPI_ADR_SPACE_EC,
-							    &acpi_ec_space_handler,
-							    NULL, ec);
+		status = acpi_install_address_space_handler_no_reg(ec->handle,
+								   ACPI_ADR_SPACE_EC,
+								   &acpi_ec_space_handler,
+								   NULL, ec);
 		if (ACPI_FAILURE(status)) {
 			acpi_ec_stop(ec, false);
 			return -ENODEV;
@@ -1482,6 +1485,11 @@ static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device)
 		ec->address_space_handler_holder = ec->handle;
 	}
 
+	if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
+		acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
+		set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
+	}
+
 	if (!device)
 		return 0;
 
@@ -1568,11 +1576,11 @@ static void ec_remove_handlers(struct acpi_ec *ec)
 	}
 }
 
-static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device)
+static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device, bool call_reg)
 {
 	int ret;
 
-	ret = ec_install_handlers(ec, device);
+	ret = ec_install_handlers(ec, device, call_reg);
 	if (ret)
 		return ret;
 
@@ -1637,7 +1645,7 @@ static int acpi_ec_add(struct acpi_device *device)
 		}
 	}
 
-	ret = acpi_ec_setup(ec, device);
+	ret = acpi_ec_setup(ec, device, true);
 	if (ret)
 		goto err;
 
@@ -1757,7 +1765,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);
+	ret = acpi_ec_setup(ec, NULL, true);
 	if (ret) {
 		acpi_ec_free(ec);
 		return;
@@ -1941,7 +1949,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);
+	ret = acpi_ec_setup(ec, NULL, false);
 	if (ret) {
 		acpi_ec_free(ec);
 		goto out;
-- 
2.37.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [RFC v3 4/4] ACPI: EC: fix ECDT probe ordering issues
  2022-10-03 14:42 ` [RFC v3 4/4] ACPI: EC: fix ECDT probe ordering issues Hans de Goede
@ 2022-10-04  8:24   ` Andy Shevchenko
  2022-10-04  9:23     ` Hans de Goede
  0 siblings, 1 reply; 9+ messages in thread
From: Andy Shevchenko @ 2022-10-04  8:24 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg,
	Zhang Rui, kai.heng.feng, Johannes Penßel, linux-acpi,
	devel

On Mon, Oct 03, 2022 at 04:42:14PM +0200, Hans de Goede wrote:
> ACPI-2.0 says that the EC OpRegion handler must be available immediately
> (like the standard default OpRegion handlers):
> 
> Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ...

(Side note: As of today the revision 6.5 of the ACPI specification is
 available)

> 2. OSPM must make Embedded Controller operation regions, accessed via
> the Embedded Controllers described in ECDT, available before executing
> any control method. These operation regions may become inaccessible
> after OSPM runs _REG(EmbeddedControl, 0)."
> 
> So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls
> acpi_install_address_space_handler() to install the EC's OpRegion
> handler, early on.
> 
> This not only installs the OpRegion handler, but also calls the EC's
> _REG method. The _REG method call is a problem because it may rely on
> initialization done by the _INI methods of one of the PCI / _SB root devs,
> see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 .
> 
> Generally speaking _REG methods are executed when the ACPI-device they
> are part of has a driver bound to it. Where as _INI methods must be
> executed at table load time (according to the spec). The problem here
> is that the early acpi_install_address_space_handler() call causes
> the _REG handler to run too early.
> 
> To allow fixing this the ACPICA code now allows to split the OpRegion
> handler installation and the executing of _REG into 2 separate steps.
> 
> This commit uses this ACPICA functionality to fix the EC probe ordering
> by delaying the executing of _REG for ECDT described ECs till the matching
> EC device in the DSDT gets parsed and acpi_ec_add() for it gets called.
> This moves the calling of _REG for the EC on devices with an ECDT to
> the same point in time where it is called on devices without an ECDT table.

...

> +	if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
> +		acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);

> +		set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);

Just to be sure: do you need atomic operation here? Does it prevent of any
kind of races? Because if it had been the case, it would have been done via
test_and_set_bit() rather than testing and setting separated.

> +	}

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC v3 4/4] ACPI: EC: fix ECDT probe ordering issues
  2022-10-04  8:24   ` Andy Shevchenko
@ 2022-10-04  9:23     ` Hans de Goede
  0 siblings, 0 replies; 9+ messages in thread
From: Hans de Goede @ 2022-10-04  9:23 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg,
	Zhang Rui, kai.heng.feng, Johannes Penßel, linux-acpi,
	devel

Hi,

On 10/4/22 10:24, Andy Shevchenko wrote:
> On Mon, Oct 03, 2022 at 04:42:14PM +0200, Hans de Goede wrote:
>> ACPI-2.0 says that the EC OpRegion handler must be available immediately
>> (like the standard default OpRegion handlers):
>>
>> Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ...
> 
> (Side note: As of today the revision 6.5 of the ACPI specification is
>  available)
> 
>> 2. OSPM must make Embedded Controller operation regions, accessed via
>> the Embedded Controllers described in ECDT, available before executing
>> any control method. These operation regions may become inaccessible
>> after OSPM runs _REG(EmbeddedControl, 0)."
>>
>> So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls
>> acpi_install_address_space_handler() to install the EC's OpRegion
>> handler, early on.
>>
>> This not only installs the OpRegion handler, but also calls the EC's
>> _REG method. The _REG method call is a problem because it may rely on
>> initialization done by the _INI methods of one of the PCI / _SB root devs,
>> see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 .
>>
>> Generally speaking _REG methods are executed when the ACPI-device they
>> are part of has a driver bound to it. Where as _INI methods must be
>> executed at table load time (according to the spec). The problem here
>> is that the early acpi_install_address_space_handler() call causes
>> the _REG handler to run too early.
>>
>> To allow fixing this the ACPICA code now allows to split the OpRegion
>> handler installation and the executing of _REG into 2 separate steps.
>>
>> This commit uses this ACPICA functionality to fix the EC probe ordering
>> by delaying the executing of _REG for ECDT described ECs till the matching
>> EC device in the DSDT gets parsed and acpi_ec_add() for it gets called.
>> This moves the calling of _REG for the EC on devices with an ECDT to
>> the same point in time where it is called on devices without an ECDT table.
> 
> ...
> 
>> +	if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
>> +		acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
> 
>> +		set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
> 
> Just to be sure: do you need atomic operation here? Does it prevent of any
> kind of races? Because if it had been the case, it would have been done via
> test_and_set_bit() rather than testing and setting separated.

AFAIK we do not need atomic operations here (I did not verify this). Also note
that existing code a couple of lines above already uses the same pattern.

Regards,

Hans


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues
  2022-10-03 14:42 [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues Hans de Goede
                   ` (3 preceding siblings ...)
  2022-10-03 14:42 ` [RFC v3 4/4] ACPI: EC: fix ECDT probe ordering issues Hans de Goede
@ 2022-10-13 16:53 ` Rafael J. Wysocki
  2022-10-13 17:43   ` Hans de Goede
  4 siblings, 1 reply; 9+ messages in thread
From: Rafael J. Wysocki @ 2022-10-13 16:53 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Rafael J . Wysocki, Len Brown, Robert Moore, Mika Westerberg,
	Zhang Rui, Andy Shevchenko, kai.heng.feng, Johannes Penßel,
	linux-acpi, devel

Hi Hans,

On Mon, Oct 3, 2022 at 4:42 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi All,
>
> Here is v3 of my series fixing some ECDT EC probe ordering issues which
> are causing issues om some laptops:
>
> https://bugzilla.kernel.org/show_bug.cgi?id=214899
>
> This is a RFC because fixing this requires some ACPICA changes which
> obviously need to go upstream through the ACPICA project:
> https://github.com/acpica/acpica/pull/786

I've just approved your pull request.

Also, as soon as it gets merged, you can resubmit the series with a
proper ACPICA  commit ID and I will be able to apply the patches right
away then.

> The problem this fixed is best described by the commit message of patch 4:
>
> ACPI-2.0 says that the EC OpRegion handler must be available immediately
> (like the standard default OpRegion handlers):
>
> Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ...
> 2. OSPM must make Embedded Controller operation regions, accessed via
> the Embedded Controllers described in ECDT, available before executing
> any control method. These operation regions may become inaccessible
> after OSPM runs _REG(EmbeddedControl, 0)."
>
> So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls
> acpi_install_address_space_handler() to install the EC's OpRegion
> handler, early on.
>
> This not only installs the OpRegion handler, but also calls the EC's
> _REG method. The _REG method call is a problem because it may rely on
> initialization done by the _INI methods of one of the PCI / _SB root devs,
> see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 .
>
> Generally speaking _REG methods are executed when the ACPI-device they
> are part of has a driver bound to it. Where as _INI methods must be
> executed at table load time (according to the spec). The problem here
> is that the early acpi_install_address_space_handler() call causes
> the _REG handler to run too early.
>
> To allow fixing this the ACPICA code now allows to split the OpRegion
> handler installation and the executing of _REG into 2 separate steps.
>
> This commit uses this ACPICA functionality to fix the EC probe ordering
> by delaying the executing of _REG for ECDT described ECs till the matching
> EC device in the DSDT gets parsed and acpi_ec_add() for it gets called.
> This moves the calling of _REG for the EC on devices with an ECDT to
> the same point in time where it is called on devices without an ECDT table.
>
> Changes in v3:
> - Add a prep patch to fix an indentation issue in Linux' acpixf.h to fix
>   the patch from ACPICA's script not applying
> - Add 2 new functions to ACPICA for this instead of a flags argument
>   1. acpi_install_address_space_handler_no_reg()
>   2. acpi_execute_reg_methods()
> - Add a patch to fix EC handler removal in the ECDT case
>
> From my pov this series is ready for merging once the ACPICA changes
> are accepted.

I agree, please resubmit as soon as the upstream ACPICA pull request
gets merged.

Thanks!

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues
  2022-10-13 16:53 ` [RFC v3 0/4] ACPI[CA]: fix ECDT EC " Rafael J. Wysocki
@ 2022-10-13 17:43   ` Hans de Goede
  0 siblings, 0 replies; 9+ messages in thread
From: Hans de Goede @ 2022-10-13 17:43 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Len Brown, Robert Moore, Mika Westerberg, Zhang Rui,
	Andy Shevchenko, kai.heng.feng, Johannes Penßel, linux-acpi,
	devel

Hi,

On 10/13/22 18:53, Rafael J. Wysocki wrote:
> Hi Hans,
> 
> On Mon, Oct 3, 2022 at 4:42 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> Hi All,
>>
>> Here is v3 of my series fixing some ECDT EC probe ordering issues which
>> are causing issues om some laptops:
>>
>> https://bugzilla.kernel.org/show_bug.cgi?id=214899
>>
>> This is a RFC because fixing this requires some ACPICA changes which
>> obviously need to go upstream through the ACPICA project:
>> https://github.com/acpica/acpica/pull/786
> 
> I've just approved your pull request.

Thanks.

> Also, as soon as it gets merged, you can resubmit the series with a
> proper ACPICA  commit ID and I will be able to apply the patches right
> away then.

Will do.

Regards,

Hans



>> The problem this fixed is best described by the commit message of patch 4:
>>
>> ACPI-2.0 says that the EC OpRegion handler must be available immediately
>> (like the standard default OpRegion handlers):
>>
>> Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ...
>> 2. OSPM must make Embedded Controller operation regions, accessed via
>> the Embedded Controllers described in ECDT, available before executing
>> any control method. These operation regions may become inaccessible
>> after OSPM runs _REG(EmbeddedControl, 0)."
>>
>> So acpi_bus_init() calls acpi_ec_ecdt_probe(), which calls
>> acpi_install_address_space_handler() to install the EC's OpRegion
>> handler, early on.
>>
>> This not only installs the OpRegion handler, but also calls the EC's
>> _REG method. The _REG method call is a problem because it may rely on
>> initialization done by the _INI methods of one of the PCI / _SB root devs,
>> see for example: https://bugzilla.kernel.org/show_bug.cgi?id=214899 .
>>
>> Generally speaking _REG methods are executed when the ACPI-device they
>> are part of has a driver bound to it. Where as _INI methods must be
>> executed at table load time (according to the spec). The problem here
>> is that the early acpi_install_address_space_handler() call causes
>> the _REG handler to run too early.
>>
>> To allow fixing this the ACPICA code now allows to split the OpRegion
>> handler installation and the executing of _REG into 2 separate steps.
>>
>> This commit uses this ACPICA functionality to fix the EC probe ordering
>> by delaying the executing of _REG for ECDT described ECs till the matching
>> EC device in the DSDT gets parsed and acpi_ec_add() for it gets called.
>> This moves the calling of _REG for the EC on devices with an ECDT to
>> the same point in time where it is called on devices without an ECDT table.
>>
>> Changes in v3:
>> - Add a prep patch to fix an indentation issue in Linux' acpixf.h to fix
>>   the patch from ACPICA's script not applying
>> - Add 2 new functions to ACPICA for this instead of a flags argument
>>   1. acpi_install_address_space_handler_no_reg()
>>   2. acpi_execute_reg_methods()
>> - Add a patch to fix EC handler removal in the ECDT case
>>
>> From my pov this series is ready for merging once the ACPICA changes
>> are accepted.
> 
> I agree, please resubmit as soon as the upstream ACPICA pull request
> gets merged.
> 
> Thanks!
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-10-13 17:44 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-03 14:42 [RFC v3 0/4] ACPI[CA]: fix ECDT EC probe ordering issues Hans de Goede
2022-10-03 14:42 ` [RFC v3 1/4] ACPICA: include/acpi/acpixf.h: Fix indentation Hans de Goede
2022-10-03 14:42 ` [RFC v3 2/4] ACPICA: Allow address_space_handler Install and _REG execution as 2 separate steps Hans de Goede
2022-10-03 14:42 ` [RFC v3 3/4] ACPI: EC: Fix EC address space handler unregistration Hans de Goede
2022-10-03 14:42 ` [RFC v3 4/4] ACPI: EC: fix ECDT probe ordering issues Hans de Goede
2022-10-04  8:24   ` Andy Shevchenko
2022-10-04  9:23     ` Hans de Goede
2022-10-13 16:53 ` [RFC v3 0/4] ACPI[CA]: fix ECDT EC " Rafael J. Wysocki
2022-10-13 17:43   ` Hans de Goede

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).