mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-16 10:47:26 +00:00
dm: use power button acpi device to find its input event
check the power button acpi driver firstly, then find input event corresponding to the power button. Tracked-On: #2695 Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
55f52978db
commit
f6a989b7be
@ -37,6 +37,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "vmmapi.h"
|
#include "vmmapi.h"
|
||||||
#include "acpi.h"
|
#include "acpi.h"
|
||||||
@ -46,8 +49,9 @@
|
|||||||
#include "lpc.h"
|
#include "lpc.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
|
|
||||||
#define POWER_BUTTON_EVENT 116
|
|
||||||
#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_INPUT_DIR POWER_BUTTON_ACPI_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;
|
||||||
@ -242,6 +246,7 @@ INOUT_PORT(pm1_enable, PM1A_EVT_ADDR + 2, IOPORT_F_INOUT, pm1_enable_handler);
|
|||||||
static void
|
static void
|
||||||
power_button_press_emulation(struct vmctx *ctx)
|
power_button_press_emulation(struct vmctx *ctx)
|
||||||
{
|
{
|
||||||
|
printf("%s", "press power button\n");
|
||||||
pthread_mutex_lock(&pm_lock);
|
pthread_mutex_lock(&pm_lock);
|
||||||
if (!(pm1_status & PM1_PWRBTN_STS)) {
|
if (!(pm1_status & PM1_PWRBTN_STS)) {
|
||||||
pm1_status |= PM1_PWRBTN_STS;
|
pm1_status |= PM1_PWRBTN_STS;
|
||||||
@ -267,7 +272,11 @@ input_event0_handler(int fd, enum ev_type type, void *arg)
|
|||||||
if (rc < 0 || rc != sizeof(ev))
|
if (rc < 0 || rc != sizeof(ev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ev.code == POWER_BUTTON_EVENT && ev.value == 1)
|
/*
|
||||||
|
* The input key defines in input-event-codes.h
|
||||||
|
* KEY_POWER 116 SC System Power Down
|
||||||
|
*/
|
||||||
|
if (ev.code == KEY_POWER && ev.value == 1)
|
||||||
power_button_press_emulation(arg);
|
power_button_press_emulation(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,6 +345,109 @@ static struct monitor_vm_ops vm_ops = {
|
|||||||
.suspend = vm_suspend_handler,
|
.suspend = vm_suspend_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
input_dir_filter(const struct dirent *dir)
|
||||||
|
{
|
||||||
|
return !strncmp(dir->d_name, "input", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
event_dir_filter(const struct dirent *dir)
|
||||||
|
{
|
||||||
|
return !strncmp(dir->d_name, "event", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
open_power_button_input_device()
|
||||||
|
{
|
||||||
|
struct dirent **input_dirs = NULL;
|
||||||
|
struct dirent **event_dirs = NULL;
|
||||||
|
int ninput = 0;
|
||||||
|
int nevent = 0;
|
||||||
|
char path[256] = {0};
|
||||||
|
char name[256] = {0};
|
||||||
|
int rc, fd;
|
||||||
|
|
||||||
|
if (access(POWER_BUTTON_ACPI_DRV, F_OK) != 0) {
|
||||||
|
fprintf(stderr, "failed to detect power button driver\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan path to get inputN
|
||||||
|
* path is /sys/bus/acpi/drivers/button/LNXPWRBN:00/input
|
||||||
|
*/
|
||||||
|
ninput = scandir(POWER_BUTTON_INPUT_DIR, &input_dirs, input_dir_filter,
|
||||||
|
alphasort);
|
||||||
|
if (ninput < 0) {
|
||||||
|
fprintf(stderr, "failed to scan power button %s\n",
|
||||||
|
POWER_BUTTON_INPUT_DIR);
|
||||||
|
goto err;
|
||||||
|
} else if (ninput == 1) {
|
||||||
|
rc = snprintf(path, sizeof(path), "%s/%s",
|
||||||
|
POWER_BUTTON_INPUT_DIR, input_dirs[0]->d_name);
|
||||||
|
if (rc < 0 || rc >= sizeof(path)) {
|
||||||
|
fprintf(stderr, "failed to set power button path %d\n",
|
||||||
|
rc);
|
||||||
|
goto err_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan path to get eventN
|
||||||
|
* path is /sys/bus/acpi/drivers/button/LNXPWRBN:00/input/inputN
|
||||||
|
*/
|
||||||
|
nevent = scandir(path, &event_dirs, event_dir_filter,
|
||||||
|
alphasort);
|
||||||
|
if (nevent < 0) {
|
||||||
|
fprintf(stderr, "failed to get power button event %s\n",
|
||||||
|
path);
|
||||||
|
goto err_input;
|
||||||
|
} else if (nevent == 1) {
|
||||||
|
|
||||||
|
/* Get the power button input event name */
|
||||||
|
rc = snprintf(name, sizeof(name), "/dev/input/%s",
|
||||||
|
event_dirs[0]->d_name);
|
||||||
|
if (rc < 0 || rc >= sizeof(name)) {
|
||||||
|
fprintf(stderr, "power button error %d\n", rc);
|
||||||
|
goto err_input;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "power button event number error %d\n",
|
||||||
|
nevent);
|
||||||
|
goto err_event;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "power button input number error %d\n", nevent);
|
||||||
|
goto err_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the input device */
|
||||||
|
fd = open(name, O_RDONLY);
|
||||||
|
if (fd > 0)
|
||||||
|
printf("Watching power button on %s\n", name);
|
||||||
|
|
||||||
|
while (nevent--)
|
||||||
|
free(event_dirs[nevent]);
|
||||||
|
free(event_dirs);
|
||||||
|
while (ninput--)
|
||||||
|
free(input_dirs[ninput]);
|
||||||
|
free(input_dirs);
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
err_event:
|
||||||
|
while (nevent--)
|
||||||
|
free(event_dirs[nevent]);
|
||||||
|
free(event_dirs);
|
||||||
|
|
||||||
|
err_input:
|
||||||
|
while (ninput--)
|
||||||
|
free(input_dirs[ninput]);
|
||||||
|
free(input_dirs);
|
||||||
|
|
||||||
|
err:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ACPI SMI Command Register
|
* ACPI SMI Command Register
|
||||||
*
|
*
|
||||||
@ -371,11 +483,8 @@ smi_cmd_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
|
|||||||
old_power_handler = signal(SIGTERM, SIG_IGN);
|
old_power_handler = signal(SIGTERM, SIG_IGN);
|
||||||
}
|
}
|
||||||
if (input_evt0 == NULL) {
|
if (input_evt0 == NULL) {
|
||||||
/*
|
|
||||||
* FIXME: check /sys/bus/acpi/devices/LNXPWRBN\:00/input to
|
pwrbtn_fd = open_power_button_input_device();
|
||||||
* get input event node instead hardcode in here.
|
|
||||||
*/
|
|
||||||
pwrbtn_fd = open("/dev/input/event0", O_RDONLY);
|
|
||||||
if (pwrbtn_fd < 0)
|
if (pwrbtn_fd < 0)
|
||||||
fprintf(stderr, "open input event0 error=%d\n",
|
fprintf(stderr, "open input event0 error=%d\n",
|
||||||
errno);
|
errno);
|
||||||
|
Loading…
Reference in New Issue
Block a user