Re: [REGRESSION] Toshiba Fn keys + lidswitch

From: Rafael J. Wysocki

Date: Tue May 19 2026 - 13:23:48 EST


On Tuesday, May 19, 2026 4:08:36 PM CEST Rafael J. Wysocki wrote:
> On Tue, May 12, 2026 at 7:16 PM Nick <nick@xxxxxxxx> wrote:
> >
> > My Toshiba Tecra X40 laptop's function keys no longer send events.
> >
> > Specifically the mute ("KEY_MUTE"), lock ("KEY_COFFEE"), "power plan"
> > ("KEY_BATTERY"), sleep ("KEY_SLEEP"), mic mute (for some reason this
> > reads as "KEY_SUSPEND"), screen switch ("KEY_SWITCHVIDEOMODE"),
> > brightness ("KEY_BRIGHTNESSDOWN" and "KEY_BRIGHTNESSUP"), and rfkill
> > ("KEY_WLAN") hotkeys -- these are the Fn-shifted versions of Esc, F1,
> > F2, F3, F4, F5, F6, F7 and F8 -- keys no longer work. Neither does the
> > lid-switch.
> >
> > Fn+F9, Fn+10, Fn+F11 and Fn+12 still work; those show up on
> > /dev/input/event3 like the rest of my keyboard, but the hotkeys show up
> > on /dev/input/event6.
> >
> > I'm on ArchLinux. My keys worked on v6.19.14, I first noticed them
> > broken on v7.0.2.
> >
> > I bisected mainline and found the break is: "ACPI: scan: Use
> > acpi_setup_gpe_for_wake() for buttons"
> > <https://lore.kernel.org/all/2259694.irdbgypaU6@rafael.j.wysocki/>.
> > That is, 57c31e6d620f132dcf610b2c52b4cdbd203c6f4a is bad and
> > 88fad6ce090b395af4c654594a54589a386bf24b is good.
> >
> > #regzbot introduced: 57c31e6d620f132dcf610b2c52b4cdbd203c6f4a
> >
> > Maybe acpi_mark_gpe_for_wake was initializing something particular to
> > Toshiba hardware?
>
> Thanks for reporting!
>
> I think that the problem is acpi_setup_gpe_for_wake() doing too much,
> I'll send you a patch to test later today.

So please let me know if the patch below fixes the problem for you.

In either case, please grep the dmesg output for "ACPI GPE" and let me know
the result.

Thanks!

---
drivers/acpi/scan.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)

--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1000,11 +1000,15 @@ static int acpi_bus_extract_wakeup_devic
return err;
}

+/* Do not use a button for S5 wakeup */
+#define ACPI_AVOID_WAKE_FROM_S5 BIT(0)
+
static bool acpi_wakeup_gpe_init(struct acpi_device *device)
{
static const struct acpi_device_id button_device_ids[] = {
- {"PNP0C0D", 0}, /* Lid */
- {"PNP0C0E", 0}, /* Sleep button */
+ {"PNP0C0C", 0}, /* Power button */
+ {"PNP0C0D", ACPI_AVOID_WAKE_FROM_S5}, /* Lid */
+ {"PNP0C0E", ACPI_AVOID_WAKE_FROM_S5}, /* Sleep button */
{"", 0},
};
struct acpi_device_wakeup *wakeup = &device->wakeup;
@@ -1014,8 +1018,21 @@ static bool acpi_wakeup_gpe_init(struct
wakeup->flags.notifier_present = 0;

match = acpi_match_acpi_device(button_device_ids, device);
- if (match && wakeup->sleep_state == ACPI_STATE_S5)
- wakeup->sleep_state = ACPI_STATE_S4;
+ if (match) {
+ acpi_event_status gpe_status = 0;
+
+ if (wakeup->sleep_state == ACPI_STATE_S5 &&
+ match->driver_data == ACPI_AVOID_WAKE_FROM_S5)
+ wakeup->sleep_state = ACPI_STATE_S4;
+
+ acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number,
+ &gpe_status);
+ if (gpe_status & ACPI_EVENT_FLAG_ENABLE_SET) {
+ acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+ dev_info(&device->dev, "ACPI GPE enabled for %s\n",
+ (char *)match->id);
+ }
+ }

status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
wakeup->gpe_number);