mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +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
5 changed files with 85 additions and 143 deletions
|
@ -1262,9 +1262,15 @@ acpi_bus_add (
|
|||
hid = ACPI_THERMAL_HID;
|
||||
break;
|
||||
case ACPI_BUS_TYPE_POWER_BUTTON:
|
||||
hid = ACPI_BUTTON_HID_POWER;
|
||||
break;
|
||||
case ACPI_BUS_TYPE_POWER_BUTTONF:
|
||||
hid = ACPI_BUTTON_HID_POWERF;
|
||||
break;
|
||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||
hid = ACPI_BUTTON_HID_SLEEP;
|
||||
break;
|
||||
case ACPI_BUS_TYPE_SLEEP_BUTTONF:
|
||||
hid = ACPI_BUTTON_HID_SLEEPF;
|
||||
break;
|
||||
}
|
||||
|
@ -1326,7 +1332,9 @@ acpi_bus_add (
|
|||
*/
|
||||
switch (type) {
|
||||
case ACPI_BUS_TYPE_POWER_BUTTON:
|
||||
case ACPI_BUS_TYPE_POWER_BUTTONF:
|
||||
case ACPI_BUS_TYPE_SLEEP_BUTTON:
|
||||
case ACPI_BUS_TYPE_SLEEP_BUTTONF:
|
||||
break;
|
||||
default:
|
||||
status = AcpiAttachData(device->handle,
|
||||
|
@ -1530,16 +1538,40 @@ acpi_bus_scan_fixed (
|
|||
if (!root)
|
||||
return_VALUE(AE_NOT_FOUND);
|
||||
|
||||
/*
|
||||
* Enumerate all fixed-feature devices.
|
||||
/* If ACPI_FADT_POWER_BUTTON is set, then a control
|
||||
* method power button is present. Otherwise, a fixed
|
||||
* power button is present.
|
||||
*/
|
||||
if (AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON)
|
||||
result = acpi_bus_add(&device, acpi_root,
|
||||
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)
|
||||
result = acpi_bus_add(&device, acpi_root,
|
||||
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);
|
||||
}
|
||||
|
@ -1549,120 +1581,6 @@ acpi_bus_scan_fixed (
|
|||
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
|
||||
acpi_bus_init (void)
|
||||
{
|
||||
|
@ -1701,13 +1619,6 @@ acpi_bus_init (void)
|
|||
/* Initialize sleep structures */
|
||||
//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.
|
||||
*/
|
||||
|
@ -1726,6 +1637,7 @@ acpi_bus_init (void)
|
|||
if (result)
|
||||
goto error2;
|
||||
|
||||
|
||||
/*
|
||||
* Enumerate devices in the ACPI namespace.
|
||||
*/
|
||||
|
@ -1736,7 +1648,6 @@ acpi_bus_init (void)
|
|||
if (result)
|
||||
DPRINT1("acpi_bus_scan failed\n");
|
||||
|
||||
//acpi_motherboard_init();
|
||||
return_VALUE(0);
|
||||
|
||||
/* Mimic structured exception handling */
|
||||
|
|
|
@ -57,6 +57,11 @@ struct acpi_button {
|
|||
UINT8 type;
|
||||
unsigned long pushed;
|
||||
};
|
||||
|
||||
struct acpi_device *power_button;
|
||||
struct acpi_device *sleep_button;
|
||||
struct acpi_device *lid_button;
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
|
@ -113,10 +118,6 @@ acpi_button_add (
|
|||
ACPI_STATUS status = AE_OK;
|
||||
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");
|
||||
|
||||
if (!device)
|
||||
|
|
|
@ -73,6 +73,8 @@ enum acpi_bus_device_type {
|
|||
ACPI_BUS_TYPE_SYSTEM,
|
||||
ACPI_BUS_TYPE_POWER_BUTTON,
|
||||
ACPI_BUS_TYPE_SLEEP_BUTTON,
|
||||
ACPI_BUS_TYPE_POWER_BUTTONF,
|
||||
ACPI_BUS_TYPE_SLEEP_BUTTONF,
|
||||
ACPI_BUS_DEVICE_TYPE_COUNT
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
#endif
|
||||
|
||||
extern struct acpi_device *sleep_button;
|
||||
extern struct acpi_device *power_button;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
Bus_AddDevice(
|
||||
|
@ -215,23 +218,38 @@ ACPIDispatchDeviceControl(
|
|||
break;
|
||||
}
|
||||
|
||||
if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C") ||
|
||||
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"))
|
||||
if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
|
||||
{
|
||||
DPRINT1("Lid button reported to power manager\n");
|
||||
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
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -590,7 +595,12 @@ AcpiOsSignalSemaphore (
|
|||
DPRINT("AcpiOsSignalSemaphore %p\n",Handle);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue