Re: [PATCH V5] acpi: trigger wakeup key event from power button

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Oct 7, 2023 at 9:55 AM Ken Xue <Ken.Xue@xxxxxxx> wrote:
>
> Andorid can wakeup from various wakeup sources, but only several wakeup
> sources can wake up screen with right events(POWER, WAKEUP) from input
> device.
>
> Regarding pressing acpi power button, it can resume system and
> ACPI_BITMASK_WAKE_STATUS and ACPI_BITMASK_POWER_BUTTON_STATUS are set in
> pm1a_sts, but kernel does not report any key event to user space during
> resuming by default.
>
> So, send wakeup key event to user space during resume from power button.
>
> Signed-off-by: Ken Xue <Ken.Xue@xxxxxxx>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx>
>
> ---
> V1->V2: fix some compile warning/error caused by lack of
>         "struct acpi_device" declaration by including acpi.h.
> V2->V3: use "forward declaration" to fix compile warning/error.
> V3->V4: refine coding style and commit message
> V4->V5: add "select ACPI_BUTTON" to fix build error if CONFIG_ACPI_BUTTON=m. https://lore.kernel.org/oe-kbuild-all/202309150947.YLjvs2Vv-lkp@xxxxxxxxx/
> ---
>  drivers/acpi/Kconfig  |  1 +
>  drivers/acpi/button.c | 17 +++++++++++++++++
>  drivers/acpi/sleep.c  |  5 +++++
>  include/acpi/button.h |  4 ++++
>  4 files changed, 27 insertions(+)
>
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 00dd309b6682..001da6233fcd 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -53,6 +53,7 @@ config ACPI_GENERIC_GSI
>
>  config ACPI_SYSTEM_POWER_STATES_SUPPORT
>         bool
> +       select ACPI_BUTTON
>
>  config ACPI_CCA_REQUIRED
>         bool
> diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
> index 1e76a64cce0a..3baddecd66c6 100644
> --- a/drivers/acpi/button.c
> +++ b/drivers/acpi/button.c
> @@ -363,6 +363,22 @@ static int acpi_button_remove_fs(struct acpi_device *device)
>         return 0;
>  }
>
> +void acpi_power_button_wakeup(struct acpi_device *dev)
> +{
> +       struct acpi_button *button = acpi_driver_data(dev);
> +       struct input_dev *input;
> +
> +       if (button->type != ACPI_BUTTON_TYPE_POWER)
> +               return;
> +
> +       input = button->input;
> +       input_report_key(input, KEY_WAKEUP, 1);
> +       input_sync(input);
> +       input_report_key(input, KEY_WAKEUP, 0);
> +       input_sync(input);
> +}
> +EXPORT_SYMBOL(acpi_power_button_wakeup);
> +
>  /* Driver Interface */
>  int acpi_lid_open(void)
>  {
> @@ -579,6 +595,7 @@ static int acpi_button_add(struct acpi_device *device)
>         switch (button->type) {
>         case ACPI_BUTTON_TYPE_POWER:
>                 input_set_capability(input, EV_KEY, KEY_POWER);
> +               input_set_capability(input, EV_KEY, KEY_WAKEUP);
>                 break;
>
>         case ACPI_BUTTON_TYPE_SLEEP:
> diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
> index 808484d11209..f816606abd71 100644
> --- a/drivers/acpi/sleep.c
> +++ b/drivers/acpi/sleep.c
> @@ -20,9 +20,13 @@
>  #include <linux/acpi.h>
>  #include <linux/module.h>
>  #include <linux/syscore_ops.h>
> +
>  #include <asm/io.h>
> +
>  #include <trace/events/power.h>
>
> +#include <acpi/button.h>

Not really.

> +
>  #include "internal.h"
>  #include "sleep.h"
>
> @@ -507,6 +511,7 @@ static void acpi_pm_finish(void)
>         pwr_btn_adev = acpi_dev_get_first_match_dev(ACPI_BUTTON_HID_POWERF,
>                                                     NULL, -1);
>         if (pwr_btn_adev) {
> +               acpi_power_button_wakeup(pwr_btn_adev);

Why does this need to be done from here?

Can't the button driver itself to it?

>                 pm_wakeup_event(&pwr_btn_adev->dev, 0);
>                 acpi_dev_put(pwr_btn_adev);
>         }
> diff --git a/include/acpi/button.h b/include/acpi/button.h
> index af2fce5d2ee3..6126d665aa42 100644
> --- a/include/acpi/button.h
> +++ b/include/acpi/button.h
> @@ -2,17 +2,21 @@
>  #ifndef ACPI_BUTTON_H
>  #define ACPI_BUTTON_H
>
> +struct acpi_device;
> +
>  #define ACPI_BUTTON_HID_POWER  "PNP0C0C"
>  #define ACPI_BUTTON_HID_LID    "PNP0C0D"
>  #define ACPI_BUTTON_HID_SLEEP  "PNP0C0E"
>
>  #if IS_ENABLED(CONFIG_ACPI_BUTTON)
>  extern int acpi_lid_open(void);
> +extern void acpi_power_button_wakeup(struct acpi_device *dev);
>  #else
>  static inline int acpi_lid_open(void)
>  {
>         return 1;
>  }
> +static inline void acpi_power_button_wakeup(struct acpi_device *dev) {}
>  #endif /* IS_ENABLED(CONFIG_ACPI_BUTTON) */
>
>  #endif /* ACPI_BUTTON_H */
>
> base-commit: b483d3b8a54a544ab8854ca6dbb8d99c423b3ba4
> --
> 2.35.1
>





[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]
  Powered by Linux