From c11886dbbe7d88b703b84630c82c92f5c6b75b9c Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Wed, 2 Mar 2005 05:05:18 +0000 Subject: [PATCH] Now we have a nice structure for handling ACPI fixed events. This means we can do things like make acpi_button block, instead of polling it. Direct register access has gone away. The next revision of the bus manager interface should include namespace traversal and AML control method execution. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11529 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/ACPI.h | 44 +++++++---------- .../kernel/bus_managers/acpi/acpi_busman.c | 47 +++++++++++++++---- .../drivers/power/acpi_button/acpi_button.c | 35 +++++--------- 3 files changed, 66 insertions(+), 60 deletions(-) diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index b37fb719f3..7454bcb7fb 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -7,45 +7,35 @@ #define _ACPI_H #include +#include typedef struct acpi_module_info acpi_module_info; struct acpi_module_info { bus_manager_info binfo; - - uint32 (*read_acpi_reg) (uint32 register_id); - void (*write_acpi_reg) (uint32 register_id, uint32 value); + + void (*enable_fixed_event) (uint32 event); + void (*disable_fixed_event) (uint32 event); + + uint32 (*fixed_event_status) (uint32 event); + /* Returns 1 if event set, 0 otherwise */ + void (*reset_fixed_event) (uint32 event); + + status_t (*install_fixed_event_handler) (uint32 event, interrupt_handler *handler, void *data); + status_t (*remove_fixed_event_handler) (uint32 event, interrupt_handler *handler); }; #define B_ACPI_MODULE_NAME "bus_managers/acpi/v1" #ifndef __ACTYPES_H__ -/* ACPI register_id arguments */ +/* ACPI fixed event types */ -#define ACPI_BITREG_TIMER_STATUS 0x00 -#define ACPI_BITREG_BUS_MASTER_STATUS 0x01 -#define ACPI_BITREG_GLOBAL_LOCK_STATUS 0x02 -#define ACPI_BITREG_POWER_BUTTON_STATUS 0x03 -#define ACPI_BITREG_SLEEP_BUTTON_STATUS 0x04 -#define ACPI_BITREG_RT_CLOCK_STATUS 0x05 -#define ACPI_BITREG_WAKE_STATUS 0x06 - -#define ACPI_BITREG_TIMER_ENABLE 0x07 -#define ACPI_BITREG_GLOBAL_LOCK_ENABLE 0x08 -#define ACPI_BITREG_POWER_BUTTON_ENABLE 0x09 -#define ACPI_BITREG_SLEEP_BUTTON_ENABLE 0x0A -#define ACPI_BITREG_RT_CLOCK_ENABLE 0x0B -#define ACPI_BITREG_WAKE_ENABLE 0x0C - -#define ACPI_BITREG_SCI_ENABLE 0x0D -#define ACPI_BITREG_BUS_MASTER_RLD 0x0E -#define ACPI_BITREG_GLOBAL_LOCK_RELEASE 0x0F -#define ACPI_BITREG_SLEEP_TYPE_A 0x10 -#define ACPI_BITREG_SLEEP_TYPE_B 0x11 -#define ACPI_BITREG_SLEEP_ENABLE 0x12 - -#define ACPI_BITREG_ARB_DISABLE 0x13 +#define ACPI_EVENT_PMTIMER 0 +#define ACPI_EVENT_GLOBAL 1 +#define ACPI_EVENT_POWER_BUTTON 2 +#define ACPI_EVENT_SLEEP_BUTTON 3 +#define ACPI_EVENT_RTC 4 #endif diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c index c009b7e5b5..00583a84cc 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -7,8 +7,15 @@ status_t acpi_std_ops(int32 op,...); status_t acpi_rescan_stub(void); -uint32 read_acpi_reg(uint32 id); -void write_acpi_reg(uint32 id, uint32 value); + +void enable_fixed_event (uint32 event); +void disable_fixed_event (uint32 event); + +uint32 fixed_event_status (uint32 event); +void reset_fixed_event (uint32 event); + +status_t install_fixed_event_handler (uint32 event, interrupt_handler *handler, void *data); +status_t remove_fixed_event_handler (uint32 event, interrupt_handler *handler); struct acpi_module_info acpi_module = { { @@ -21,8 +28,12 @@ struct acpi_module_info acpi_module = { acpi_rescan_stub }, - read_acpi_reg, - write_acpi_reg + enable_fixed_event, + disable_fixed_event, + fixed_event_status, + reset_fixed_event, + install_fixed_event_handler, + remove_fixed_event_handler }; _EXPORT module_info *modules[] = { @@ -79,12 +90,28 @@ status_t acpi_rescan_stub(void) { return B_OK; } -uint32 read_acpi_reg(uint32 id) { - uint32 value; - AcpiGetRegister(id,&value,ACPI_MTX_LOCK); - return value; +void enable_fixed_event (uint32 event) { + AcpiEnableEvent(event,0); } -void write_acpi_reg(uint32 id, uint32 value) { - AcpiSetRegister(id,value,ACPI_MTX_LOCK); +void disable_fixed_event (uint32 event) { + AcpiDisableEvent(event,0); +} + +uint32 fixed_event_status (uint32 event) { + ACPI_EVENT_STATUS status = 0; + AcpiGetEventStatus(event,&status); + return (status/* & ACPI_EVENT_FLAG_SET*/); +} + +void reset_fixed_event (uint32 event) { + AcpiClearEvent(event); +} + +status_t install_fixed_event_handler (uint32 event, interrupt_handler *handler, void *data) { + return ((AcpiInstallFixedEventHandler(event,handler,data) == AE_OK) ? B_OK : B_ERROR); +} + +status_t remove_fixed_event_handler (uint32 event, interrupt_handler *handler) { + return ((AcpiRemoveFixedEventHandler(event,handler) == AE_OK) ? B_OK : B_ERROR); } diff --git a/src/add-ons/kernel/drivers/power/acpi_button/acpi_button.c b/src/add-ons/kernel/drivers/power/acpi_button/acpi_button.c index 95f6585031..f93381bf7e 100644 --- a/src/add-ons/kernel/drivers/power/acpi_button/acpi_button.c +++ b/src/add-ons/kernel/drivers/power/acpi_button/acpi_button.c @@ -36,15 +36,15 @@ uninit_driver (void) static status_t acpi_button_open (const char *name, uint32 flags, void** cookie) { - if (strcmp(name,"power/button/power") == 0) { - *cookie = (void *)ACPI_BITREG_POWER_BUTTON_STATUS; - acpi->write_acpi_reg(ACPI_BITREG_POWER_BUTTON_ENABLE,0); - } else if (strcmp(name,"power/button/sleep") == 0) { - *cookie = (void *)ACPI_BITREG_SLEEP_BUTTON_STATUS; - acpi->write_acpi_reg(ACPI_BITREG_SLEEP_BUTTON_ENABLE,0); - } else { + if (strcmp(name,"power/button/power") == 0) + *cookie = (void *)ACPI_EVENT_POWER_BUTTON; + else if (strcmp(name,"power/button/sleep") == 0) + *cookie = (void *)ACPI_EVENT_SLEEP_BUTTON; + else return B_ERROR; - } + + acpi->enable_fixed_event((uint32)(cookie)); + return B_OK; } @@ -59,12 +59,9 @@ acpi_button_read (void* cookie, off_t position, void *buf, size_t* num_bytes) if (*num_bytes < 1) return B_IO_ERROR; - *((uint8 *)(buf)) = acpi->read_acpi_reg((uint32)(cookie)); + *((uint8 *)(buf)) = acpi->fixed_event_status((uint32)(cookie)) ? 1 : 0; - acpi->write_acpi_reg((uint32)(cookie),1); - - /* You need to write 1 to the status register to clear it to 0. - No, I don't understand Intel either. */ + acpi->reset_fixed_event((uint32)(cookie)); *num_bytes = 1; return B_OK; @@ -78,12 +75,7 @@ acpi_button_read (void* cookie, off_t position, void *buf, size_t* num_bytes) static status_t acpi_button_write (void* cookie, off_t position, const void* buffer, size_t* num_bytes) { - if (*num_bytes < 1) - return B_IO_ERROR; - - acpi->write_acpi_reg((uint32)(cookie),*((uint8 *)(buffer))); - *num_bytes = 1; - return B_OK; + return B_IO_ERROR; } @@ -105,10 +97,7 @@ acpi_button_control (void* cookie, uint32 op, void* arg, size_t len) static status_t acpi_button_close (void* cookie) { - if ((uint32)(cookie) == ACPI_BITREG_POWER_BUTTON_STATUS) - acpi->write_acpi_reg(ACPI_BITREG_POWER_BUTTON_ENABLE,1); - else if ((uint32)(cookie) == ACPI_BITREG_SLEEP_BUTTON_STATUS) - acpi->write_acpi_reg(ACPI_BITREG_SLEEP_BUTTON_ENABLE,1); + acpi->disable_fixed_event((uint32)(cookie)); return B_OK; }