acpi: use walk_resources to find embedded controller I/O ports.
* export walk_resources and use it * removed SmallResourceData * added embedded controller module for x86_64
This commit is contained in:
@@ -142,6 +142,8 @@ enum {
|
||||
*/
|
||||
typedef uint32 acpi_status;
|
||||
|
||||
typedef struct acpi_resource acpi_resource;
|
||||
|
||||
#endif // __ACTYPES_H__
|
||||
|
||||
|
||||
@@ -159,6 +161,9 @@ typedef acpi_status (*acpi_adr_space_setup)(acpi_handle regionHandle,
|
||||
typedef void (*acpi_notify_handler)(acpi_handle device, uint32 value,
|
||||
void *context);
|
||||
|
||||
typedef acpi_status (*acpi_walk_resources_callback)(acpi_resource* resource,
|
||||
void* context);
|
||||
|
||||
|
||||
struct acpi_module_info {
|
||||
module_info info;
|
||||
@@ -251,6 +256,9 @@ struct acpi_module_info {
|
||||
acpi_data *retBuffer);
|
||||
status_t (*set_current_resources)(acpi_handle busDeviceHandle,
|
||||
acpi_data *buffer);
|
||||
status_t (*walk_resources)(acpi_handle busDeviceHandle,
|
||||
char *method, acpi_walk_resources_callback callback,
|
||||
void* context);
|
||||
|
||||
/* Power state setting */
|
||||
|
||||
@@ -317,6 +325,10 @@ typedef struct acpi_device_module_info {
|
||||
/* Control method execution and data acquisition */
|
||||
status_t (*evaluate_method)(acpi_device device, const char *method,
|
||||
acpi_objects *args, acpi_data *returnValue);
|
||||
|
||||
/* Resource Management */
|
||||
status_t (*walk_resources)(acpi_device device, char *method,
|
||||
acpi_walk_resources_callback callback, void* context);
|
||||
} acpi_device_module_info;
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,11 @@ typedef struct acpi_device_cookie {
|
||||
} acpi_device_cookie;
|
||||
|
||||
|
||||
typedef struct acpi_resource acpi_resource;
|
||||
typedef acpi_status (*acpi_walk_resources_callback)(acpi_resource* resource,
|
||||
void* context);
|
||||
|
||||
|
||||
// ACPI root.
|
||||
typedef struct acpi_root_info {
|
||||
driver_module_info info;
|
||||
@@ -131,6 +136,9 @@ typedef struct acpi_root_info {
|
||||
acpi_data *retBuffer);
|
||||
status_t (*set_current_resources)(acpi_handle busDeviceHandle,
|
||||
acpi_data *buffer);
|
||||
status_t (*walk_resources)(acpi_handle busDeviceHandle,
|
||||
char *method, acpi_walk_resources_callback callback,
|
||||
void* context);
|
||||
|
||||
/* Power state setting */
|
||||
|
||||
@@ -217,6 +225,8 @@ status_t get_possible_resources(acpi_handle busDeviceHandle,
|
||||
acpi_data* returnValue);
|
||||
status_t set_current_resources(acpi_handle busDeviceHandle,
|
||||
acpi_data* buffer);
|
||||
status_t walk_resources(acpi_handle busDeviceHandle, char* method,
|
||||
acpi_walk_resources_callback callback, void* context);
|
||||
|
||||
status_t prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size);
|
||||
status_t enter_sleep_state(uint8 state);
|
||||
|
||||
@@ -624,6 +624,15 @@ set_current_resources(acpi_handle busDeviceHandle, acpi_data *buffer)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
walk_resources(acpi_handle busDeviceHandle, char* method,
|
||||
acpi_walk_resources_callback callback, void* context)
|
||||
{
|
||||
return AcpiWalkResources(busDeviceHandle, method,
|
||||
(ACPI_WALK_RESOURCE_CALLBACK)callback, context);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size)
|
||||
{
|
||||
@@ -770,6 +779,7 @@ struct acpi_module_info gACPIModule = {
|
||||
get_current_resources,
|
||||
get_possible_resources,
|
||||
set_current_resources,
|
||||
walk_resources,
|
||||
prepare_sleep_state,
|
||||
enter_sleep_state,
|
||||
reboot,
|
||||
|
||||
@@ -74,6 +74,14 @@ acpi_evaluate_method(acpi_device device, const char *method,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
acpi_walk_resources(acpi_device device, char *method,
|
||||
acpi_walk_resources_callback callback, void* context)
|
||||
{
|
||||
return walk_resources(device->handle, method, callback, context);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
acpi_device_init_driver(device_node *node, void **cookie)
|
||||
{
|
||||
@@ -154,4 +162,5 @@ acpi_device_module_info gACPIDeviceModule = {
|
||||
acpi_get_object_type,
|
||||
acpi_get_object,
|
||||
acpi_evaluate_method,
|
||||
acpi_walk_resources
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013, Jérôme Duval, [email protected].
|
||||
* Copyright (c) 2009 Clemens Zeidler
|
||||
* Copyright (c) 2003-2007 Nate Lawson
|
||||
* Copyright (c) 2000 Michael Smith
|
||||
@@ -40,8 +41,6 @@
|
||||
#include <KernelExport.h>
|
||||
#include <drivers/PCI.h>
|
||||
|
||||
#include "SmallResourceData.h"
|
||||
|
||||
|
||||
#define ACPI_EC_DRIVER_NAME "drivers/power/acpi_embedded_controller/driver_v1"
|
||||
|
||||
@@ -143,6 +142,25 @@ acpi_PkgInt32(acpi_object_type* res, int idx, uint32* dst)
|
||||
}
|
||||
|
||||
|
||||
acpi_status
|
||||
embedded_controller_io_ports_parse_callback(ACPI_RESOURCE* resource,
|
||||
void* _context)
|
||||
{
|
||||
acpi_ec_cookie* sc = (acpi_ec_cookie*)_context;
|
||||
if (resource->Type != ACPI_RESOURCE_TYPE_IO)
|
||||
return AE_OK;
|
||||
if (sc->ec_data_pci_address == 0) {
|
||||
sc->ec_data_pci_address = resource->Data.Io.Minimum;
|
||||
} else if (sc->ec_csr_pci_address == 0) {
|
||||
sc->ec_csr_pci_address = resource->Data.Io.Minimum;
|
||||
} else {
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -282,13 +300,6 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
||||
(void**)&sc->ec_handle);
|
||||
gDeviceManager->put_node(parent);
|
||||
|
||||
SmallResourceData resourceData(sc->ec_acpi, sc->ec_handle, "_CRS");
|
||||
if (resourceData.InitCheck() != B_OK) {
|
||||
TRACE("failed to read _CRS resource\n") ;
|
||||
return B_ERROR;
|
||||
}
|
||||
io_port portData;
|
||||
|
||||
if (get_module(B_ACPI_MODULE_NAME, (module_info**)&sc->ec_acpi_module)
|
||||
!= B_OK)
|
||||
return B_ERROR;
|
||||
@@ -313,7 +324,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
||||
// and GPE bit, similar to _PRW.
|
||||
status = sc->ec_acpi->evaluate_method(sc->ec_handle, "_GPE", NULL, &buf);
|
||||
if (status != B_OK) {
|
||||
TRACE("can't evaluate _GPE\n");
|
||||
ERROR("can't evaluate _GPE\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -337,22 +348,19 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
||||
goto error;
|
||||
break;
|
||||
default:
|
||||
TRACE("_GPE has invalid type %i\n", int(obj->object_type));
|
||||
ERROR("_GPE has invalid type %i\n", int(obj->object_type));
|
||||
goto error;
|
||||
}
|
||||
|
||||
sc->ec_suspending = FALSE;
|
||||
|
||||
// Attach bus resources for data and command/status ports.
|
||||
if (resourceData.ReadIOPort(&portData) != B_OK)
|
||||
status = sc->ec_acpi->walk_resources(sc->ec_handle, "_CRS",
|
||||
embedded_controller_io_ports_parse_callback, sc);
|
||||
if (status != B_OK) {
|
||||
ERROR("Error while getting IO ports addresses\n");
|
||||
goto error;
|
||||
|
||||
sc->ec_data_pci_address = portData.minimumBase;
|
||||
|
||||
if (resourceData.ReadIOPort(&portData) != B_OK)
|
||||
goto error;
|
||||
|
||||
sc->ec_csr_pci_address = portData.minimumBase;
|
||||
}
|
||||
|
||||
// Install a handler for this EC's GPE bit. We want edge-triggered
|
||||
// behavior.
|
||||
@@ -369,14 +377,14 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie)
|
||||
status = sc->ec_acpi->install_address_space_handler(sc->ec_handle,
|
||||
ACPI_ADR_SPACE_EC, &EcSpaceHandler, &EcSpaceSetup, sc);
|
||||
if (status != B_OK) {
|
||||
TRACE("can't install address space handler\n");
|
||||
ERROR("can't install address space handler\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Enable runtime GPEs for the handler.
|
||||
status = sc->ec_acpi_module->enable_gpe(sc->ec_gpehandle, sc->ec_gpebit);
|
||||
if (status != B_OK) {
|
||||
TRACE("AcpiEnableGpe failed.\n");
|
||||
ERROR("AcpiEnableGpe failed.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -519,7 +527,7 @@ EcGpeQueryHandler(void* context)
|
||||
// that may arise from running the query from causing another query
|
||||
// to be queued, we clear the pending flag only after running it.
|
||||
int sci_enqueued = sc->ec_sci_pending;
|
||||
acpi_status acpi_status;
|
||||
acpi_status acpi_status = AE_ERROR;
|
||||
for (uint8 retry = 0; retry < 2; retry++) {
|
||||
acpi_status = EcCommand(sc, EC_COMMAND_QUERY);
|
||||
if (acpi_status == AE_OK)
|
||||
|
||||
@@ -207,7 +207,6 @@ KernelAddon acpi :
|
||||
Device.cpp
|
||||
NamespaceDump.cpp
|
||||
EmbeddedController.cpp
|
||||
SmallResourceData.cpp
|
||||
:
|
||||
libacpi_ca.a
|
||||
;
|
||||
|
||||
@@ -221,6 +221,7 @@ static struct acpi_root_info sACPIRootModule = {
|
||||
get_current_resources,
|
||||
get_possible_resources,
|
||||
set_current_resources,
|
||||
walk_resources,
|
||||
prepare_sleep_state,
|
||||
enter_sleep_state,
|
||||
reboot,
|
||||
@@ -233,9 +234,7 @@ module_info* modules[] = {
|
||||
(module_info*)&sACPIRootModule,
|
||||
(module_info*)&acpi_ns_dump_module,
|
||||
(module_info*)&gACPIDeviceModule,
|
||||
#ifndef __x86_64__
|
||||
(module_info*)&embedded_controller_driver_module,
|
||||
(module_info*)&embedded_controller_device_module,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#include "SmallResourceData.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
//#define TRACE_SMALLRESOURCEDATA
|
||||
#ifdef TRACE_SMALLRESOURCEDATA
|
||||
# define TRACE(x...) dprintf("Small Resource Data: "x)
|
||||
#else
|
||||
# define TRACE(x...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
io_port::Print()
|
||||
{
|
||||
dprintf("io_port:\n");
|
||||
int i = (deviceAddresses16Bit ? 1 : 0);
|
||||
dprintf("deviceAddresses16Bit %i\n", i);
|
||||
dprintf("minimumBase %i\n", minimumBase);
|
||||
dprintf("maximumBase %i\n", maximumBase);
|
||||
dprintf("minimumBaseAlignment %i\n", minimumBaseAlignment);
|
||||
dprintf("contigiuousIOPorts %i\n", contigiuousIOPorts);
|
||||
}
|
||||
|
||||
|
||||
SmallResourceData::SmallResourceData(acpi_device_module_info* acpi,
|
||||
acpi_device acpiCookie, const char* method)
|
||||
{
|
||||
acpi_data buffer;
|
||||
buffer.pointer = NULL;
|
||||
buffer.length = ACPI_ALLOCATE_BUFFER;
|
||||
|
||||
fStatus = acpi->evaluate_method(acpiCookie, method, NULL, &buffer);
|
||||
|
||||
if (fStatus != B_OK)
|
||||
return;
|
||||
|
||||
fBuffer = (acpi_object_type*)buffer.pointer;
|
||||
|
||||
if (fBuffer[0].object_type != ACPI_TYPE_BUFFER) {
|
||||
fStatus = B_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
fResourcePointer = (int8*)fBuffer[0].data.buffer.buffer;
|
||||
fBufferSize = fBuffer[0].data.buffer.length;
|
||||
fRemainingBufferSize = fBufferSize;
|
||||
|
||||
// ToDo: Check checksum of the endtag. The sum of all databytes + checksum
|
||||
// is zero. See section 6.4.2.8.
|
||||
}
|
||||
|
||||
|
||||
SmallResourceData::~SmallResourceData()
|
||||
{
|
||||
if (InitCheck() == B_OK)
|
||||
free(fBuffer);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SmallResourceData::InitCheck()
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
|
||||
int8
|
||||
SmallResourceData::GetType()
|
||||
{
|
||||
return *fResourcePointer;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SmallResourceData::ReadIOPort(io_port* ioPort)
|
||||
{
|
||||
const size_t packageSize = 8;
|
||||
|
||||
if (fRemainingBufferSize < packageSize)
|
||||
return B_ERROR;
|
||||
if (fResourcePointer[0] != kIOPort)
|
||||
return B_ERROR;
|
||||
|
||||
ioPort->deviceAddresses16Bit = (fResourcePointer[1] == 1);
|
||||
|
||||
int16 tmp;
|
||||
tmp = fResourcePointer[3];
|
||||
tmp = tmp << 8;
|
||||
tmp |= fResourcePointer[2];
|
||||
ioPort->minimumBase = tmp;
|
||||
|
||||
tmp = fResourcePointer[5];
|
||||
tmp = tmp << 8;
|
||||
tmp |= fResourcePointer[4];
|
||||
ioPort->maximumBase = tmp;
|
||||
|
||||
ioPort->minimumBaseAlignment = fResourcePointer[6];
|
||||
ioPort->contigiuousIOPorts = fResourcePointer[7];
|
||||
|
||||
fResourcePointer += packageSize;
|
||||
fRemainingBufferSize -= packageSize;
|
||||
TRACE("SmallResourceData: remaining buffer size %i\n",
|
||||
int(fRemainingBufferSize));
|
||||
return B_OK;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Clemens Zeidler, haiku@clemens-zeidler.de
|
||||
*/
|
||||
|
||||
#ifndef SMALLRESOURCEDATA_H
|
||||
#define SMALLRESOURCEDATA_H
|
||||
|
||||
#include <ACPI.h>
|
||||
#include <Errors.h>
|
||||
|
||||
|
||||
enum resource_type
|
||||
{
|
||||
kIOPort = 0x47,
|
||||
kEndTag = 0x78
|
||||
};
|
||||
|
||||
|
||||
struct io_port
|
||||
{
|
||||
void Print();
|
||||
//! The logical device decodes 16-bit addresses.
|
||||
bool deviceAddresses16Bit;
|
||||
|
||||
uint16 minimumBase;
|
||||
uint16 maximumBase;
|
||||
uint8 minimumBaseAlignment;
|
||||
uint8 contigiuousIOPorts;
|
||||
};
|
||||
|
||||
|
||||
/*! ToDo: implement also the other resource data, see acpi section 6.2.4 */
|
||||
class SmallResourceData
|
||||
{
|
||||
public:
|
||||
SmallResourceData(acpi_device_module_info* acpi,
|
||||
acpi_device acpiCookie, const char* method);
|
||||
~SmallResourceData();
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
int8 GetType();
|
||||
/*! Get resource data and jump to the next resource. */
|
||||
status_t ReadIOPort(io_port* ioPort);
|
||||
|
||||
private:
|
||||
acpi_object_type* fBuffer;
|
||||
size_t fBufferSize;
|
||||
size_t fRemainingBufferSize;
|
||||
|
||||
int8* fResourcePointer;
|
||||
|
||||
status_t fStatus;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user