mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-09 08:56:55 +00:00
dm: implement power button for power managerment
Listen to power button state via /dev/input/event0. When the power button is pressed, then set PWRBTN_STS bit. If PWRBTN_EN is set, the sci interrupt is triggered. For suspend or shutdown of UOS by power button, needs UOS to configure the default behavior of the power button. Tracked-On: #2560 Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
b24a8a0f59
commit
8e8ed07dd7
@ -34,6 +34,9 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
#include "vmmapi.h"
|
#include "vmmapi.h"
|
||||||
#include "acpi.h"
|
#include "acpi.h"
|
||||||
@ -42,10 +45,13 @@
|
|||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "lpc.h"
|
#include "lpc.h"
|
||||||
|
|
||||||
|
#define POWER_BUTTON_EVENT 116
|
||||||
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;
|
||||||
|
|
||||||
|
static struct mevent *input_evt0;
|
||||||
|
static int pwrbtn_fd = -1;
|
||||||
/*
|
/*
|
||||||
* Reset Control register at I/O port 0xcf9. Bit 2 forces a system
|
* Reset Control register at I/O port 0xcf9. Bit 2 forces a system
|
||||||
* reset when it transitions from 0 to 1. Bit 1 selects the type of
|
* reset when it transitions from 0 to 1. Bit 1 selects the type of
|
||||||
@ -224,6 +230,20 @@ power_button_handler(int signal, enum ev_type type, void *arg)
|
|||||||
pthread_mutex_unlock(&pm_lock);
|
pthread_mutex_unlock(&pm_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_event0_handler(int fd, enum ev_type type, void *arg)
|
||||||
|
{
|
||||||
|
struct input_event ev;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = read(fd, &ev, sizeof(ev));
|
||||||
|
if (rc < 0 || rc != sizeof(ev))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ev.code == POWER_BUTTON_EVENT && ev.value == 1)
|
||||||
|
power_button_handler(fd, type, arg);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Power Management 1 Control Register
|
* Power Management 1 Control Register
|
||||||
*
|
*
|
||||||
@ -295,10 +315,26 @@ smi_cmd_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
|
|||||||
case ACPI_ENABLE:
|
case ACPI_ENABLE:
|
||||||
pm1_control |= PM1_SCI_EN;
|
pm1_control |= PM1_SCI_EN;
|
||||||
if (power_button == NULL) {
|
if (power_button == NULL) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: For the SIGTERM, IOC mediator also needs to
|
||||||
|
* support it, and SIGTERM handler needs to be written
|
||||||
|
* as one common interface for both APCI power button
|
||||||
|
* and IOC mediator in future.
|
||||||
|
*/
|
||||||
power_button = mevent_add(SIGTERM, EVF_SIGNAL,
|
power_button = mevent_add(SIGTERM, EVF_SIGNAL,
|
||||||
power_button_handler, ctx, NULL, NULL);
|
power_button_handler, ctx, NULL, NULL);
|
||||||
old_power_handler = signal(SIGTERM, SIG_IGN);
|
old_power_handler = signal(SIGTERM, SIG_IGN);
|
||||||
}
|
}
|
||||||
|
if (input_evt0 == NULL) {
|
||||||
|
pwrbtn_fd = open("/dev/input/event0", O_RDONLY);
|
||||||
|
if (pwrbtn_fd < 0)
|
||||||
|
fprintf(stderr, "open input event0 error=%d\n",
|
||||||
|
errno);
|
||||||
|
else
|
||||||
|
input_evt0 = mevent_add(pwrbtn_fd, EVF_READ,
|
||||||
|
input_event0_handler, ctx, NULL, NULL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACPI_DISABLE:
|
case ACPI_DISABLE:
|
||||||
pm1_control &= ~PM1_SCI_EN;
|
pm1_control &= ~PM1_SCI_EN;
|
||||||
@ -307,6 +343,11 @@ smi_cmd_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
|
|||||||
power_button = NULL;
|
power_button = NULL;
|
||||||
signal(SIGTERM, old_power_handler);
|
signal(SIGTERM, old_power_handler);
|
||||||
}
|
}
|
||||||
|
if (input_evt0 != NULL) {
|
||||||
|
mevent_delete_close(input_evt0);
|
||||||
|
input_evt0 = NULL;
|
||||||
|
pwrbtn_fd = -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&pm_lock);
|
pthread_mutex_unlock(&pm_lock);
|
||||||
|
Loading…
Reference in New Issue
Block a user