[PATCH] platform/chrome: cros_ec_lpc: Force synchronous probe

From: Brian Norris
Date: Fri Nov 11 2022 - 18:13:12 EST


This reverts commit bd88b965ae8c ("platform/chrome: cros_ec_lpc: Mark
PROBE_PREFER_ASYNCHRONOUS"), and then some.

It has been reported that there are issues with 'cros-ec-keyb' devices
that are children of this. As noted in the initial patch for its ACPI
support (commit ba0f32141bc5 ("Input: cros_ec_keyb - handle x86
detachable/convertible Chromebooks")), it's possible to probe an ACPI
child device before its parent is probed -- hence the need for
EPROBE_DEFER. Unfortunately, poking your parent's dev_get_drvdata()
isn't safe with asynchronous probe, as there's no locking, and the
ordering is all wrong anyway (drvdata is set before the device is
*really* ready).

Because this parent/child relationship has known issues, let's go the
other direction and force synchronous probe, until we resolve the
issues.

Possible solutions involve adding device links, so we ensure the child
doesn't probe before the parent is done; or perhaps some other larger
refactoring (auxiliary bus?). But that might take a little more effort
and review, as there are many other potential sub-devices of
cros_ec_lpc that could need patching.

Note that we don't have the same problem for non-ACPI cros-ec hosts,
like cros-ec-spi (commit 015e4b05c377 ("platform/chrome: cros_ec_spi:
Set PROBE_PREFER_ASYNCHRONOUS")), because its sub-devices aren't created
until cros_ec_register(), or they don't exist at all (e.g., FPMCU uses).

Fixes: bd88b965ae8c ("platform/chrome: cros_ec_lpc: Mark PROBE_PREFER_ASYNCHRONOUS")
Signed-off-by: Brian Norris <briannorris@xxxxxxxxxxxx>
---

drivers/platform/chrome/cros_ec_lpc.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c
index 2e4dba724ada..7fc8f82280ac 100644
--- a/drivers/platform/chrome/cros_ec_lpc.c
+++ b/drivers/platform/chrome/cros_ec_lpc.c
@@ -557,7 +557,12 @@ static struct platform_driver cros_ec_lpc_driver = {
.name = DRV_NAME,
.acpi_match_table = cros_ec_lpc_acpi_device_ids,
.pm = &cros_ec_lpc_pm_ops,
- .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ /*
+ * ACPI child devices may probe before us, and they racily
+ * check our drvdata pointer. Force synchronous probe until
+ * those races are resolved.
+ */
+ .probe_type = PROBE_FORCE_SYNCHRONOUS,
},
.probe = cros_ec_lpc_probe,
.remove = cros_ec_lpc_remove,
--
2.38.1.431.g37b22c650d-goog