Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318782
b: refs/heads/master
c: 86ed4bc
h: refs/heads/master
v: v3
  • Loading branch information
Bob Moore authored and Len Brown committed Jun 1, 2012
1 parent 4452303 commit 6ab76ca
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 442 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5134abfcfb4a8a9ef42c82dabad05762fbf04376
refs/heads/master: 86ed4bc83abf530cf2019044b74f89a39dfd6425
3 changes: 1 addition & 2 deletions trunk/drivers/acpi/acpica/acglobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,7 @@ ACPI_EXTERN acpi_cache_t *acpi_gbl_operand_cache;

/* Global handlers */

ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify;
ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify;
ACPI_EXTERN struct acpi_global_notify_handler acpi_gbl_global_notify[2];
ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler;
Expand Down
13 changes: 11 additions & 2 deletions trunk/drivers/acpi/acpica/aclocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -600,13 +600,22 @@ acpi_status(*acpi_parse_downwards) (struct acpi_walk_state * walk_state,

typedef acpi_status(*acpi_parse_upwards) (struct acpi_walk_state * walk_state);

/* Global handlers for AML Notifies */

struct acpi_global_notify_handler {
acpi_notify_handler handler;
void *context;
};

/*
* Notify info - used to pass info to the deferred notify
* handler/dispatcher.
*/
struct acpi_notify_info {
ACPI_STATE_COMMON struct acpi_namespace_node *node;
union acpi_operand_object *handler_obj;
ACPI_STATE_COMMON u8 handler_list_id;
struct acpi_namespace_node *node;
union acpi_operand_object *handler_list_head;
struct acpi_global_notify_handler *global;
};

/* Generic state is union of structs above */
Expand Down
9 changes: 4 additions & 5 deletions trunk/drivers/acpi/acpica/acobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ struct acpi_object_method {
* Common fields for objects that support ASL notifications
*/
#define ACPI_COMMON_NOTIFY_INFO \
union acpi_operand_object *system_notify; /* Handler for system notifies */\
union acpi_operand_object *device_notify; /* Handler for driver notifies */\
union acpi_operand_object *notify_list[2]; /* Handlers for system/device notifies */\
union acpi_operand_object *handler; /* Handler for Address space */

struct acpi_object_notify_common { /* COMMON NOTIFY for POWER, PROCESSOR, DEVICE, and THERMAL */
Expand Down Expand Up @@ -296,10 +295,10 @@ struct acpi_object_buffer_field {

struct acpi_object_notify_handler {
ACPI_OBJECT_COMMON_HEADER struct acpi_namespace_node *node; /* Parent device */
u32 handler_type;
acpi_notify_handler handler;
u32 handler_type; /* Type: Device/System/Both */
acpi_notify_handler handler; /* Handler address */
void *context;
struct acpi_object_notify_handler *next;
union acpi_operand_object *next[2]; /* Device and System handler lists */
};

struct acpi_object_addr_handler {
Expand Down
185 changes: 67 additions & 118 deletions trunk/drivers/acpi/acpica/evmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,102 +101,77 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
u32 notify_value)
{
union acpi_operand_object *obj_desc;
union acpi_operand_object *handler_obj = NULL;
union acpi_generic_state *notify_info;
union acpi_operand_object *handler_list_head = NULL;
union acpi_generic_state *info;
u8 handler_list_id = 0;
acpi_status status = AE_OK;

ACPI_FUNCTION_NAME(ev_queue_notify_request);

/*
* For value 0x03 (Ejection Request), may need to run a device method.
* For value 0x02 (Device Wake), if _PRW exists, may need to run
* the _PS0 method.
* For value 0x80 (Status Change) on the power button or sleep button,
* initiate soft-off or sleep operation.
*
* For all cases, simply dispatch the notify to the handler.
*/
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
acpi_ut_get_node_name(node),
acpi_ut_get_type_name(node->type), notify_value,
acpi_ut_get_notify_name(notify_value), node));
/* Are Notifies allowed on this object? */

/* Get the notify object attached to the NS Node */

obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {

/* We have the notify object, Get the correct handler */

switch (node->type) {
if (!acpi_ev_is_notify_object(node)) {
return (AE_TYPE);
}

/* Notify is allowed only on these types */
/* Get the correct notify list type (System or Device) */

case ACPI_TYPE_DEVICE:
case ACPI_TYPE_THERMAL:
case ACPI_TYPE_PROCESSOR:
if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
handler_list_id = ACPI_SYSTEM_HANDLER_LIST;
} else {
handler_list_id = ACPI_DEVICE_HANDLER_LIST;
}

if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
handler_obj =
obj_desc->common_notify.system_notify;
} else {
handler_obj =
obj_desc->common_notify.device_notify;
}
break;
/* Get the notify object attached to the namespace Node */

default:
obj_desc = acpi_ns_get_attached_object(node);
if (obj_desc) {

/* All other types are not supported */
/* We have an attached object, Get the correct handler list */

return (AE_TYPE);
}
handler_list_head =
obj_desc->common_notify.notify_list[handler_list_id];
}

/*
* If there is a handler to run, schedule the dispatcher.
* Check for:
* 1) Global system notify handler
* 2) Global device notify handler
* 3) Per-device notify handler
* If there is no notify handler (Global or Local)
* for this object, just ignore the notify
*/
if ((acpi_gbl_system_notify.handler &&
(notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
(acpi_gbl_device_notify.handler &&
(notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
notify_info = acpi_ut_create_generic_state();
if (!notify_info) {
return (AE_NO_MEMORY);
}
if (!acpi_gbl_global_notify[handler_list_id].handler
&& !handler_list_head) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
acpi_ut_get_node_name(node), notify_value,
node));

if (!handler_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Executing system notify handler for Notify (%4.4s, %X) "
"node %p\n",
acpi_ut_get_node_name(node),
notify_value, node));
}
return (AE_OK);
}

notify_info->common.descriptor_type =
ACPI_DESC_TYPE_STATE_NOTIFY;
notify_info->notify.node = node;
notify_info->notify.value = (u16) notify_value;
notify_info->notify.handler_obj = handler_obj;
/* Setup notify info and schedule the notify dispatcher */

status =
acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
notify_info);
if (ACPI_FAILURE(status)) {
acpi_ut_delete_generic_state(notify_info);
}
} else {
/* There is no notify handler (per-device or system) for this device */
info = acpi_ut_create_generic_state();
if (!info) {
return (AE_NO_MEMORY);
}

ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"No notify handler for Notify (%4.4s, %X) node %p\n",
acpi_ut_get_node_name(node), notify_value,
node));
info->common.descriptor_type = ACPI_DESC_TYPE_STATE_NOTIFY;

info->notify.node = node;
info->notify.value = (u16)notify_value;
info->notify.handler_list_id = handler_list_id;
info->notify.handler_list_head = handler_list_head;
info->notify.global = &acpi_gbl_global_notify[handler_list_id];

ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
acpi_ut_get_node_name(node),
acpi_ut_get_type_name(node->type), notify_value,
acpi_ut_get_notify_name(notify_value), node));

status = acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch,
info);
if (ACPI_FAILURE(status)) {
acpi_ut_delete_generic_state(info);
}

return (status);
Expand All @@ -217,60 +192,34 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,

static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
{
union acpi_generic_state *notify_info =
(union acpi_generic_state *)context;
acpi_notify_handler global_handler = NULL;
void *global_context = NULL;
union acpi_generic_state *info = (union acpi_generic_state *)context;
union acpi_operand_object *handler_obj;

ACPI_FUNCTION_ENTRY();

/*
* We will invoke a global notify handler if installed. This is done
* _before_ we invoke the per-device handler attached to the device.
*/
if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {

/* Global system notification handler */

if (acpi_gbl_system_notify.handler) {
global_handler = acpi_gbl_system_notify.handler;
global_context = acpi_gbl_system_notify.context;
}
} else {
/* Global driver notification handler */

if (acpi_gbl_device_notify.handler) {
global_handler = acpi_gbl_device_notify.handler;
global_context = acpi_gbl_device_notify.context;
}
}

/* Invoke the system handler first, if present */
/* Invoke a global notify handler if installed */

if (global_handler) {
global_handler(notify_info->notify.node,
notify_info->notify.value, global_context);
if (info->notify.global->handler) {
info->notify.global->handler(info->notify.node,
info->notify.value,
info->notify.global->context);
}

/* Now invoke the per-device handler, if present */
/* Now invoke the local notify handler(s) if any are installed */

handler_obj = notify_info->notify.handler_obj;
if (handler_obj) {
struct acpi_object_notify_handler *notifier;
handler_obj = info->notify.handler_list_head;
while (handler_obj) {
handler_obj->notify.handler(info->notify.node,
info->notify.value,
handler_obj->notify.context);

notifier = &handler_obj->notify;
while (notifier) {
notifier->handler(notify_info->notify.node,
notify_info->notify.value,
notifier->context);
notifier = notifier->next;
}
handler_obj =
handler_obj->notify.next[info->notify.handler_list_id];
}

/* All done with the info object */

acpi_ut_delete_generic_state(notify_info);
acpi_ut_delete_generic_state(info);
}

#if (!ACPI_REDUCED_HARDWARE)
Expand Down
Loading

0 comments on commit 6ab76ca

Please sign in to comment.