From: Andre Eikmeyer <dev@deq.rocks>
To: Jiri Kosina <jikos@kernel.org>, Benjamin Tissoires <bentiss@kernel.org>
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
Andre Eikmeyer <dev@deq.rocks>
Subject: [PATCH] HID: apple-touchbar: avoid nested runtime PM in PM callbacks
Date: Mon, 10 Aug 2026 16:03:52 +0200 [thread overview]
Message-ID: <20260810140352.35866-1-dev@deq.rocks> (raw)
Hello everyone,
Runtime suspend of the Touch Bar display stalls because its HID suspend
callback requests a runtime PM resume while already running as part of the
same USB PM transition. The nested request waits for the transition that
invoked the callback to finish.
The matching resume callback has the same problem. It can stall after the
virtual host controller has successfully resumed the port.
The mode update is therefore split into an active-device helper and a
runtime-PM-managed wrapper. Both PM callbacks call the active-device
helper and no longer acquire a nested runtime PM reference.
We maintain the apple-bce/t2bce virtual host controller used on these
systems. Although that module is not yet upstream, its runtime PM path has
already been adjusted so the complete suspend and resume cycle works with
this change.
Thanks for your time and work.
Signed-off-by: Andre Eikmeyer <dev@deq.rocks>
---
drivers/hid/hid-appletb-kbd.c | 37 ++++++++++++++++++++++-------------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c
index 462010a75899..cbaf7587feea 100644
--- a/drivers/hid/hid-appletb-kbd.c
+++ b/drivers/hid/hid-appletb-kbd.c
@@ -87,29 +87,37 @@ static const struct key_entry appletb_kbd_keymap[] = {
{ KE_END, 0 }
};
-static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode)
+static int appletb_kbd_set_mode_active(struct appletb_kbd *kbd, u8 mode)
{
struct hid_report *report = kbd->mode_field->report;
struct hid_device *hdev = report->device;
int ret;
- ret = hid_hw_power(hdev, PM_HINT_FULLON);
- if (ret) {
- hid_err(hdev, "Device didn't resume (%pe)\n", ERR_PTR(ret));
- return ret;
- }
-
ret = hid_set_field(kbd->mode_field, 0, mode);
if (ret) {
hid_err(hdev, "Failed to set mode field to %u (%pe)\n", mode, ERR_PTR(ret));
- goto power_normal;
+ return ret;
}
hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
kbd->current_mode = mode;
+ return 0;
+}
+
+static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode)
+{
+ struct hid_device *hdev = kbd->mode_field->report->device;
+ int ret;
+
+ ret = hid_hw_power(hdev, PM_HINT_FULLON);
+ if (ret) {
+ hid_err(hdev, "Device didn't resume (%pe)\n", ERR_PTR(ret));
+ return ret;
+ }
+
+ ret = appletb_kbd_set_mode_active(kbd, mode);
-power_normal:
hid_hw_power(hdev, PM_HINT_NORMAL);
return ret;
@@ -487,18 +495,19 @@ static int appletb_kbd_suspend(struct hid_device *hdev, pm_message_t msg)
struct appletb_kbd *kbd = hid_get_drvdata(hdev);
kbd->saved_mode = kbd->current_mode;
- appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF);
- return 0;
+ /* This callback already runs as part of a USB PM transition. Taking a
+ * nested runtime-PM reference would wait for that transition to complete
+ * and deadlock the USB PM state machine.
+ */
+ return appletb_kbd_set_mode_active(kbd, APPLETB_KBD_MODE_OFF);
}
static int appletb_kbd_resume(struct hid_device *hdev)
{
struct appletb_kbd *kbd = hid_get_drvdata(hdev);
- appletb_kbd_set_mode(kbd, kbd->saved_mode);
-
- return 0;
+ return appletb_kbd_set_mode_active(kbd, kbd->saved_mode);
}
static const struct hid_device_id appletb_kbd_hid_ids[] = {
reply other threads:[~2026-08-10 14:13 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260810140352.35866-1-dev@deq.rocks \
--to=dev@deq.rocks \
--cc=bentiss@kernel.org \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox