dm: pm: support control method power button

ACPI supports two ways for power button device, one of them is control
method, and its _HID object is PNP0C0C.

If power button mediator doesn't scan power button from LNXPWRBN node
try to scan PNP0C0C node instead.

v2): Move the functions of openning fixed/control method power button to open_native_power_button

Tracked-On: #3594
Signed-off-by: Yuan Liu <yuan1.liu@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Yuan Liu 2019-07-30 17:18:44 +08:00 committed by wenlingz
parent 6beb34c3cb
commit 3cc0eabac6

View File

@ -51,6 +51,8 @@
#define POWER_BUTTON_NAME "power_button" #define POWER_BUTTON_NAME "power_button"
#define POWER_BUTTON_ACPI_DRV "/sys/bus/acpi/drivers/button/LNXPWRBN:00/" #define POWER_BUTTON_ACPI_DRV "/sys/bus/acpi/drivers/button/LNXPWRBN:00/"
#define POWER_BUTTON_INPUT_DIR POWER_BUTTON_ACPI_DRV"input" #define POWER_BUTTON_INPUT_DIR POWER_BUTTON_ACPI_DRV"input"
#define POWER_BUTTON_PNP0C0C_DRV "/sys/bus/acpi/drivers/button/PNP0C0C:00/"
#define POWER_BUTTON_PNP0C0C_DIR POWER_BUTTON_PNP0C0C_DRV"input"
static pthread_mutex_t pm_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t pm_lock = PTHREAD_MUTEX_INITIALIZER;
static struct mevent *power_button; static struct mevent *power_button;
static sig_t old_power_handler; static sig_t old_power_handler;
@ -345,7 +347,7 @@ event_dir_filter(const struct dirent *dir)
} }
static int static int
open_power_button_input_device() open_power_button_input_device(const char *drv, const char *dir)
{ {
struct dirent **input_dirs = NULL; struct dirent **input_dirs = NULL;
struct dirent **event_dirs = NULL; struct dirent **event_dirs = NULL;
@ -355,24 +357,21 @@ open_power_button_input_device()
char name[256] = {0}; char name[256] = {0};
int rc, fd; int rc, fd;
if (access(POWER_BUTTON_ACPI_DRV, F_OK) != 0) { if (access(drv, F_OK) != 0)
fprintf(stderr, "failed to detect power button driver\n");
return -1; return -1;
}
/* /*
* Scan path to get inputN * Scan path to get inputN
* path is /sys/bus/acpi/drivers/button/LNXPWRBN:00/input * path is /sys/bus/acpi/drivers/button/LNXPWRBN:00/input
*/ */
ninput = scandir(POWER_BUTTON_INPUT_DIR, &input_dirs, input_dir_filter, ninput = scandir(dir, &input_dirs, input_dir_filter,
alphasort); alphasort);
if (ninput < 0) { if (ninput < 0) {
fprintf(stderr, "failed to scan power button %s\n", fprintf(stderr, "failed to scan power button %s\n",
POWER_BUTTON_INPUT_DIR); dir);
goto err; goto err;
} else if (ninput == 1) { } else if (ninput == 1) {
rc = snprintf(path, sizeof(path), "%s/%s", rc = snprintf(path, sizeof(path), "%s/%s",
POWER_BUTTON_INPUT_DIR, input_dirs[0]->d_name); dir, input_dirs[0]->d_name);
if (rc < 0 || rc >= sizeof(path)) { if (rc < 0 || rc >= sizeof(path)) {
fprintf(stderr, "failed to set power button path %d\n", fprintf(stderr, "failed to set power button path %d\n",
rc); rc);
@ -435,6 +434,25 @@ err:
return -1; return -1;
} }
static int
open_native_power_button()
{
int fd;
/*
* Open fixed power button firstly, if it can't be opened
* try to open control method power button.
*/
fd = open_power_button_input_device(POWER_BUTTON_ACPI_DRV,
POWER_BUTTON_INPUT_DIR);
if (fd < 0)
return open_power_button_input_device(
POWER_BUTTON_PNP0C0C_DRV,
POWER_BUTTON_PNP0C0C_DIR);
else
return fd;
}
/* /*
* ACPI SMI Command Register * ACPI SMI Command Register
* *
@ -470,9 +488,9 @@ smi_cmd_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
} }
if (input_evt0 == NULL) { if (input_evt0 == NULL) {
pwrbtn_fd = open_power_button_input_device(); pwrbtn_fd = open_native_power_button();
if (pwrbtn_fd < 0) if (pwrbtn_fd < 0)
fprintf(stderr, "open input event0 error=%d\n", fprintf(stderr, "open power button error=%d\n",
errno); errno);
else else
input_evt0 = mevent_add(pwrbtn_fd, EVF_READ, input_evt0 = mevent_add(pwrbtn_fd, EVF_READ,