Message ID | 20231031140952.461641-2-philip.cox@canonical.com |
---|---|
State | New |
Headers | show |
Series | Fix gpe overflow on Elkhart lake suspend/resume codepath | expand |
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 --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");