mirror of
https://github.com/reactos/reactos.git
synced 2024-07-10 06:35:06 +00:00
[ACPI]
- Add support for fixed power buttons - Cleanup some extra junk - Add a hack to prevent acquiring the mutex while in an ISR or DPC - Button events are received now and "acpi_bus_generate_event" will appear in the debug log when a power/sleep button is pressed - TODO: Implement IOCTL_GET_SYS_BUTTON_EVENT support so the power manager can recognize our button presses svn path=/trunk/; revision=46442
This commit is contained in:
parent
497c878f97
commit
da0c010307
|
@ -1262,9 +1262,15 @@ acpi_bus_add (
|
||||||
hid = ACPI_THERMAL_HID;
|
hid = ACPI_THERMAL_HID;
|
||||||
break;
|
break;
|
||||||
case ACPI_BUS_TYPE_POWER_BUTTON:
|
case ACPI_BUS_TYPE_POWER_BUTTON:
|
||||||
|
hid = ACPI_BUTTON_HID_POWER;
|
||||||
|
break;
|
||||||
|
case ACPI_BUS_TYPE_POWER_BUTTONF:
|
||||||
hid = ACPI_BUTTON_HID_POWERF;
|
hid = ACPI_BUTTON_HID_POWERF;
|
||||||
break;
|
break;
|
||||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||||
|
hid = ACPI_BUTTON_HID_SLEEP;
|
||||||
|
break;
|
||||||
|
case ACPI_BUS_TYPE_SLEEP_BUTTONF:
|
||||||
hid = ACPI_BUTTON_HID_SLEEPF;
|
hid = ACPI_BUTTON_HID_SLEEPF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1326,7 +1332,9 @@ acpi_bus_add (
|
||||||
*/
|
*/
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACPI_BUS_TYPE_POWER_BUTTON:
|
case ACPI_BUS_TYPE_POWER_BUTTON:
|
||||||
|
case ACPI_BUS_TYPE_POWER_BUTTONF:
|
||||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||||
|
case ACPI_BUS_TYPE_SLEEP_BUTTONF:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
status = AcpiAttachData(device->handle,
|
status = AcpiAttachData(device->handle,
|
||||||
|
@ -1530,16 +1538,40 @@ acpi_bus_scan_fixed (
|
||||||
if (!root)
|
if (!root)
|
||||||
return_VALUE(AE_NOT_FOUND);
|
return_VALUE(AE_NOT_FOUND);
|
||||||
|
|
||||||
/*
|
/* If ACPI_FADT_POWER_BUTTON is set, then a control
|
||||||
* Enumerate all fixed-feature devices.
|
* method power button is present. Otherwise, a fixed
|
||||||
|
* power button is present.
|
||||||
*/
|
*/
|
||||||
if (AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON)
|
if (AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON)
|
||||||
result = acpi_bus_add(&device, acpi_root,
|
result = acpi_bus_add(&device, acpi_root,
|
||||||
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
|
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Enable the fixed power button so we get notified if it is pressed */
|
||||||
|
AcpiWriteBitRegister(ACPI_BITREG_POWER_BUTTON_ENABLE, 1);
|
||||||
|
|
||||||
|
result = acpi_bus_add(&device, acpi_root,
|
||||||
|
NULL, ACPI_BUS_TYPE_POWER_BUTTONF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This one is a bit more complicated and we do it wrong
|
||||||
|
* right now. If ACPI_FADT_SLEEP_BUTTON is set but no
|
||||||
|
* device object is present then no sleep button is present, but
|
||||||
|
* if the flags is clear and there is no device object then it is
|
||||||
|
* a fixed sleep button. If the flag is set and there is a device object
|
||||||
|
* the we have a control method button just like above.
|
||||||
|
*/
|
||||||
if (AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON)
|
if (AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON)
|
||||||
result = acpi_bus_add(&device, acpi_root,
|
result = acpi_bus_add(&device, acpi_root,
|
||||||
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
|
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Enable the fixed sleep button so we get notified if it is pressed */
|
||||||
|
AcpiWriteBitRegister(ACPI_BITREG_SLEEP_BUTTON_ENABLE, 1);
|
||||||
|
|
||||||
|
result = acpi_bus_add(&device, acpi_root,
|
||||||
|
NULL, ACPI_BUS_TYPE_SLEEP_BUTTONF);
|
||||||
|
}
|
||||||
|
|
||||||
return_VALUE(result);
|
return_VALUE(result);
|
||||||
}
|
}
|
||||||
|
@ -1549,120 +1581,6 @@ acpi_bus_scan_fixed (
|
||||||
Initialization/Cleanup
|
Initialization/Cleanup
|
||||||
-------------------------------------------------------------------------- */
|
-------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
|
||||||
acpi_bus_init_irq (void)
|
|
||||||
{
|
|
||||||
ACPI_STATUS status = AE_OK;
|
|
||||||
ACPI_OBJECT arg = {ACPI_TYPE_INTEGER};
|
|
||||||
ACPI_OBJECT_LIST arg_list = {1, &arg};
|
|
||||||
//char *message = NULL;
|
|
||||||
|
|
||||||
DPRINT("acpi_bus_init_irq");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Let the system know what interrupt model we are using by
|
|
||||||
* evaluating the \_PIC object, if exists.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//switch (acpi_irq_model) {
|
|
||||||
//case ACPI_IRQ_MODEL_PIC:
|
|
||||||
// message = "PIC";
|
|
||||||
// break;
|
|
||||||
//case ACPI_IRQ_MODEL_IOAPIC:
|
|
||||||
// message = "IOAPIC";
|
|
||||||
// break;
|
|
||||||
//case ACPI_IRQ_MODEL_IOSAPIC:
|
|
||||||
// message = "IOSAPIC";
|
|
||||||
// break;
|
|
||||||
//default:
|
|
||||||
// DPRINT1("Unknown interrupt routing model\n");
|
|
||||||
// return_VALUE(AE_NOT_FOUND);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//DPRINT("Using %s for interrupt routing\n", message);
|
|
||||||
|
|
||||||
//arg.Integer.Value = acpi_irq_model;
|
|
||||||
|
|
||||||
//status = AcpiEvaluateObject(NULL, "\\_PIC", &arg_list, NULL);
|
|
||||||
//if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
|
|
||||||
// ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PIC\n"));
|
|
||||||
// return_VALUE(AE_NOT_FOUND);
|
|
||||||
//}
|
|
||||||
|
|
||||||
return_VALUE(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//void
|
|
||||||
//acpi_early_init (void)
|
|
||||||
//{
|
|
||||||
// ACPI_STATUS status = AE_OK;
|
|
||||||
//
|
|
||||||
// DPRINT("acpi_early_init");
|
|
||||||
//
|
|
||||||
// if (acpi_disabled)
|
|
||||||
// return_VOID;
|
|
||||||
//
|
|
||||||
/* enable workarounds, unless strict ACPI spec. compliance */
|
|
||||||
// if (!acpi_strict)
|
|
||||||
// acpi_gbl_enable_interpreter_slack = TRUE;
|
|
||||||
//
|
|
||||||
// status = acpi_reallocate_root_table();
|
|
||||||
// if (ACPI_FAILURE(status)) {
|
|
||||||
// printk(KERN_ERR PREFIX
|
|
||||||
// "Unable to reallocate ACPI tables\n");
|
|
||||||
// goto error0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// status = acpi_initialize_subsystem();
|
|
||||||
// if (ACPI_FAILURE(status)) {
|
|
||||||
// printk(KERN_ERR PREFIX
|
|
||||||
// "Unable to initialize the ACPI Interpreter\n");
|
|
||||||
// goto error0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// status = acpi_load_tables();
|
|
||||||
// if (ACPI_FAILURE(status)) {
|
|
||||||
// printk(KERN_ERR PREFIX
|
|
||||||
// "Unable to load the System Description Tables\n");
|
|
||||||
// goto error0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//#ifdef CONFIG_X86
|
|
||||||
// if (!acpi_ioapic) {
|
|
||||||
// /* compatible (0) means level (3) */
|
|
||||||
// if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
|
|
||||||
// acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
|
|
||||||
// acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
|
|
||||||
// }
|
|
||||||
// /* Set PIC-mode SCI trigger type */
|
|
||||||
// acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
|
|
||||||
// (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
|
|
||||||
// } else {
|
|
||||||
// /*
|
|
||||||
// * now that acpi_gbl_FADT is initialized,
|
|
||||||
// * update it with result from INT_SRC_OVR parsing
|
|
||||||
// */
|
|
||||||
// acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
|
|
||||||
// }
|
|
||||||
//#endif
|
|
||||||
//
|
|
||||||
// status =
|
|
||||||
// acpi_enable_subsystem(~
|
|
||||||
// (ACPI_NO_HARDWARE_INIT |
|
|
||||||
// ACPI_NO_ACPI_ENABLE));
|
|
||||||
// if (ACPI_FAILURE(status)) {
|
|
||||||
// printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
|
|
||||||
// goto error0;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return;
|
|
||||||
//
|
|
||||||
// error0:
|
|
||||||
// disable_acpi();
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
acpi_bus_init (void)
|
acpi_bus_init (void)
|
||||||
{
|
{
|
||||||
|
@ -1701,13 +1619,6 @@ acpi_bus_init (void)
|
||||||
/* Initialize sleep structures */
|
/* Initialize sleep structures */
|
||||||
//acpi_sleep_init();
|
//acpi_sleep_init();
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the system interrupt model and evaluate \_PIC.
|
|
||||||
*/
|
|
||||||
result = acpi_bus_init_irq();
|
|
||||||
if (result)
|
|
||||||
goto error1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register the for all standard device notifications.
|
* Register the for all standard device notifications.
|
||||||
*/
|
*/
|
||||||
|
@ -1726,6 +1637,7 @@ acpi_bus_init (void)
|
||||||
if (result)
|
if (result)
|
||||||
goto error2;
|
goto error2;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enumerate devices in the ACPI namespace.
|
* Enumerate devices in the ACPI namespace.
|
||||||
*/
|
*/
|
||||||
|
@ -1736,7 +1648,6 @@ acpi_bus_init (void)
|
||||||
if (result)
|
if (result)
|
||||||
DPRINT1("acpi_bus_scan failed\n");
|
DPRINT1("acpi_bus_scan failed\n");
|
||||||
|
|
||||||
//acpi_motherboard_init();
|
|
||||||
return_VALUE(0);
|
return_VALUE(0);
|
||||||
|
|
||||||
/* Mimic structured exception handling */
|
/* Mimic structured exception handling */
|
||||||
|
|
|
@ -57,6 +57,11 @@ struct acpi_button {
|
||||||
UINT8 type;
|
UINT8 type;
|
||||||
unsigned long pushed;
|
unsigned long pushed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct acpi_device *power_button;
|
||||||
|
struct acpi_device *sleep_button;
|
||||||
|
struct acpi_device *lid_button;
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
Driver Interface
|
Driver Interface
|
||||||
-------------------------------------------------------------------------- */
|
-------------------------------------------------------------------------- */
|
||||||
|
@ -113,10 +118,6 @@ acpi_button_add (
|
||||||
ACPI_STATUS status = AE_OK;
|
ACPI_STATUS status = AE_OK;
|
||||||
struct acpi_button *button = NULL;
|
struct acpi_button *button = NULL;
|
||||||
|
|
||||||
static struct acpi_device *power_button;
|
|
||||||
static struct acpi_device *sleep_button;
|
|
||||||
static struct acpi_device *lid_button;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE("acpi_button_add");
|
ACPI_FUNCTION_TRACE("acpi_button_add");
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
|
|
|
@ -73,6 +73,8 @@ enum acpi_bus_device_type {
|
||||||
ACPI_BUS_TYPE_SYSTEM,
|
ACPI_BUS_TYPE_SYSTEM,
|
||||||
ACPI_BUS_TYPE_POWER_BUTTON,
|
ACPI_BUS_TYPE_POWER_BUTTON,
|
||||||
ACPI_BUS_TYPE_SLEEP_BUTTON,
|
ACPI_BUS_TYPE_SLEEP_BUTTON,
|
||||||
|
ACPI_BUS_TYPE_POWER_BUTTONF,
|
||||||
|
ACPI_BUS_TYPE_SLEEP_BUTTONF,
|
||||||
ACPI_BUS_DEVICE_TYPE_COUNT
|
ACPI_BUS_DEVICE_TYPE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern struct acpi_device *sleep_button;
|
||||||
|
extern struct acpi_device *power_button;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
Bus_AddDevice(
|
Bus_AddDevice(
|
||||||
|
@ -215,23 +218,38 @@ ACPIDispatchDeviceControl(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C") ||
|
if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
|
||||||
wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"ACPI_FPB"))
|
|
||||||
{
|
|
||||||
DPRINT1("Power button reported to power manager\n");
|
|
||||||
Caps |= SYS_BUTTON_POWER;
|
|
||||||
}
|
|
||||||
else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E") ||
|
|
||||||
wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"ACPI_FSB"))
|
|
||||||
{
|
|
||||||
DPRINT1("Sleep button reported to power manager\n");
|
|
||||||
Caps |= SYS_BUTTON_SLEEP;
|
|
||||||
}
|
|
||||||
else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
|
|
||||||
{
|
{
|
||||||
DPRINT1("Lid button reported to power manager\n");
|
DPRINT1("Lid button reported to power manager\n");
|
||||||
Caps |= SYS_BUTTON_LID;
|
Caps |= SYS_BUTTON_LID;
|
||||||
}
|
}
|
||||||
|
else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL)
|
||||||
|
{
|
||||||
|
/* We have to return both at the same time because since we
|
||||||
|
* have a NULL handle we are the fixed feature DO and we will
|
||||||
|
* only be called once (not once per device)
|
||||||
|
*/
|
||||||
|
if (power_button)
|
||||||
|
{
|
||||||
|
DPRINT1("Fixed power button reported to power manager\n");
|
||||||
|
Caps |= SYS_BUTTON_POWER;
|
||||||
|
}
|
||||||
|
if (sleep_button)
|
||||||
|
{
|
||||||
|
DPRINT1("Fixed sleep button reported to power manager\n");
|
||||||
|
Caps |= SYS_BUTTON_SLEEP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
|
||||||
|
{
|
||||||
|
DPRINT1("Control method power button reported to power manager\n");
|
||||||
|
Caps |= SYS_BUTTON_POWER;
|
||||||
|
}
|
||||||
|
else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
|
||||||
|
{
|
||||||
|
DPRINT1("Control method sleep reported to power manager\n");
|
||||||
|
Caps |= SYS_BUTTON_SLEEP;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
|
DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n");
|
||||||
|
|
|
@ -576,7 +576,12 @@ AcpiOsWaitSemaphore(
|
||||||
DPRINT("Waiting for semaphore %p\n", Handle);
|
DPRINT("Waiting for semaphore %p\n", Handle);
|
||||||
ASSERT(Mutex);
|
ASSERT(Mutex);
|
||||||
|
|
||||||
ExAcquireFastMutex(Mutex);
|
/* HACK: We enter here at a high IRQL sometimes
|
||||||
|
* because we get called from DPCs and ISRs and
|
||||||
|
* we can't use a fast mutex at that IRQL */
|
||||||
|
if (KeGetCurrentIrql() <= APC_LEVEL)
|
||||||
|
ExAcquireFastMutex(Mutex);
|
||||||
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +595,12 @@ AcpiOsSignalSemaphore (
|
||||||
DPRINT("AcpiOsSignalSemaphore %p\n",Handle);
|
DPRINT("AcpiOsSignalSemaphore %p\n",Handle);
|
||||||
ASSERT(Mutex);
|
ASSERT(Mutex);
|
||||||
|
|
||||||
ExReleaseFastMutex(Mutex);
|
/* HACK: We enter here at a high IRQL sometimes
|
||||||
|
* because we get called from DPCs and ISRs and
|
||||||
|
* we can't use a fast mutex at that IRQL */
|
||||||
|
if (KeGetCurrentIrql() <= APC_LEVEL)
|
||||||
|
ExReleaseFastMutex(Mutex);
|
||||||
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue