diff mbox series

[1/1] HID: intel-ish-hid: ipc: Disable and reenable ACPI GPE bit

Message ID 20231031140952.461641-2-philip.cox@canonical.com
State New
Headers show
Series Fix gpe overflow on Elkhart lake suspend/resume codepath | expand

Commit Message

Philip Cox Oct. 31, 2023, 2:09 p.m. UTC
From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

BugLink: https://bugs.launchpad.net/bugs/2042101

The EHL (Elkhart Lake) based platforms provide a OOB (Out of band)
service, which allows to wakup device when the system is in S5 (Soft-Off
state). This OOB service can be enabled/disabled from BIOS settings. When
enabled, the ISH device gets PME wake capability. To enable PME wakeup,
driver also needs to enable ACPI GPE bit.

On resume, BIOS will clear the wakeup bit. So driver need to re-enable it
in resume function to keep the next wakeup capability. But this BIOS
clearing of wakeup bit doesn't decrement internal OS GPE reference count,
so this reenabling on every resume will cause reference count to overflow.

So first disable and reenable ACPI GPE bit using acpi_disable_gpe().

Fixes: 2e23a70edabe ("HID: intel-ish-hid: ipc: finish power flow for EHL OOB")
Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Closes: https://lore.kernel.org/lkml/CAAd53p4=oLYiH2YbVSmrPNj1zpMcfp=Wxbasb5vhMXOWCArLCg@mail.gmail.com/T/
Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
(cherry picked from commit 8f02139ad9a7e6e5c05712f8c1501eebed8eacfd)
Signed-off-by: Philip Cox <philip.cox@canonical.com>
---
 drivers/hid/intel-ish-hid/ipc/pci-ish.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

John Cabaj Nov. 6, 2023, 1:13 p.m. UTC | #1
On 10/31/23 9:09 AM, Philip Cox wrote:
> From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/2042101
> 
> The EHL (Elkhart Lake) based platforms provide a OOB (Out of band)
> service, which allows to wakup device when the system is in S5 (Soft-Off
> state). This OOB service can be enabled/disabled from BIOS settings. When
> enabled, the ISH device gets PME wake capability. To enable PME wakeup,
> driver also needs to enable ACPI GPE bit.
> 
> On resume, BIOS will clear the wakeup bit. So driver need to re-enable it
> in resume function to keep the next wakeup capability. But this BIOS
> clearing of wakeup bit doesn't decrement internal OS GPE reference count,
> so this reenabling on every resume will cause reference count to overflow.
> 
> So first disable and reenable ACPI GPE bit using acpi_disable_gpe().
> 
> Fixes: 2e23a70edabe ("HID: intel-ish-hid: ipc: finish power flow for EHL OOB")
> Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> Closes: https://lore.kernel.org/lkml/CAAd53p4=oLYiH2YbVSmrPNj1zpMcfp=Wxbasb5vhMXOWCArLCg@mail.gmail.com/T/
> Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
> (cherry picked from commit 8f02139ad9a7e6e5c05712f8c1501eebed8eacfd)
> Signed-off-by: Philip Cox <philip.cox@canonical.com>
> ---
>   drivers/hid/intel-ish-hid/ipc/pci-ish.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> index 2c67ec17bec6..514c193d410a 100644
> --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> @@ -131,6 +131,14 @@ static int enable_gpe(struct device *dev)
>   	}
>   	wakeup = &adev->wakeup;
>   
> +	/*
> +	 * Call acpi_disable_gpe(), so that reference count
> +	 * gpe_event_info->runtime_count doesn't overflow.
> +	 * When gpe_event_info->runtime_count = 0, the call
> +	 * to acpi_disable_gpe() simply return.
> +	 */
> +	acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
> +
>   	acpi_sts = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
>   	if (ACPI_FAILURE(acpi_sts)) {
>   		dev_err(dev, "enable ose_gpe failed\n");

Acked-by: John Cabaj <john.cabaj@canonical.com>
diff mbox series

Patch

diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
index 2c67ec17bec6..514c193d410a 100644
--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
@@ -131,6 +131,14 @@  static int enable_gpe(struct device *dev)
 	}
 	wakeup = &adev->wakeup;
 
+	/*
+	 * Call acpi_disable_gpe(), so that reference count
+	 * gpe_event_info->runtime_count doesn't overflow.
+	 * When gpe_event_info->runtime_count = 0, the call
+	 * to acpi_disable_gpe() simply return.
+	 */
+	acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+
 	acpi_sts = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
 	if (ACPI_FAILURE(acpi_sts)) {
 		dev_err(dev, "enable ose_gpe failed\n");