Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05100db8 authored by Hans de Goede's avatar Hans de Goede Committed by Greg Kroah-Hartman
Browse files

gpiolib: acpi: Add honor_wakeup module-option + quirk mechanism

commit aa23ca3d98f756d5b1e503fb140665fb24a41a38 upstream.

On some laptops enabling wakeup on the GPIO interrupts used for ACPI _AEI
event handling causes spurious wakeups.

This commit adds a new honor_wakeup option, defaulting to true (our current
behavior), which can be used to disable wakeup on troublesome hardware
to avoid these spurious wakeups.

This is a workaround for an architectural problem with s2idle under Linux
where we do not have any mechanism to immediately go back to sleep after
wakeup events, other then for embedded-controller events using the standard
ACPI EC interface, for details see:
https://lore.kernel.org/linux-acpi/61450f9b-cbc6-0c09-8b3a-aff6bf9a0b3c@redhat.com/



One series of laptops which is not able to suspend without this workaround
is the HP x2 10 Cherry Trail models, this commit adds a DMI based quirk
which makes sets honor_wakeup to false on these models.

Cc: stable@vger.kernel.org
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20200105160357.97154-3-hdegoede@redhat.com


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 34defb89
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -25,12 +25,18 @@
#include "gpiolib.h"

#define QUIRK_NO_EDGE_EVENTS_ON_BOOT		0x01l
#define QUIRK_NO_WAKEUP				0x02l

static int run_edge_events_on_boot = -1;
module_param(run_edge_events_on_boot, int, 0444);
MODULE_PARM_DESC(run_edge_events_on_boot,
		 "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto");

static int honor_wakeup = -1;
module_param(honor_wakeup, int, 0444);
MODULE_PARM_DESC(honor_wakeup,
		 "Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto");

/**
 * struct acpi_gpio_event - ACPI GPIO event handler data
 *
@@ -280,7 +286,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
	event->handle = evt_handle;
	event->handler = handler;
	event->irq = irq;
	event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE;
	event->irq_is_wake = honor_wakeup && agpio->wake_capable == ACPI_WAKE_CAPABLE;
	event->pin = pin;
	event->desc = desc;

@@ -1291,6 +1297,23 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] = {
		},
		.driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT,
	},
	{
		/*
		 * Various HP X2 10 Cherry Trail models use an external
		 * embedded-controller connected via I2C + an ACPI GPIO
		 * event handler. The embedded controller generates various
		 * spurious wakeup events when suspended. So disable wakeup
		 * for its handler (it uses the only ACPI GPIO event handler).
		 * This breaks wakeup when opening the lid, the user needs
		 * to press the power-button to wakeup the system. The
		 * alternative is suspend simply not working, which is worse.
		 */
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
			DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
		},
		.driver_data = (void *)QUIRK_NO_WAKEUP,
	},
	{} /* Terminating entry */
};

@@ -1310,6 +1333,13 @@ static int acpi_gpio_setup_params(void)
			run_edge_events_on_boot = 1;
	}

	if (honor_wakeup < 0) {
		if (quirks & QUIRK_NO_WAKEUP)
			honor_wakeup = 0;
		else
			honor_wakeup = 1;
	}

	return 0;
}