Subject: [PATCH] [acpi events] Smoothe out generic event handling - Change driver handler type to look like this: int (*e_handler) (struct acpi_dev *, u32, int *); instead of int (*e_handler) (struct acpi_dev *, u32, int *); - Update comments in include/acpi/event.h - Install local event handler to catch all events in ACPI driver core. - Check event received against driver's list of specified events, calling their handler only on specified events. - Check ->e_raise flag, and raise bus event if it is set (on successful return from driver's event handler). - Update notify_fixed() to directly call notify_handler(). Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/core/event.c | 43 ++++++++++++++++++++++++++++++++++--- include/acpi/event.h | 26 ++++++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) applies-to: 9aae38dd4ed2eedb65fd0f400e2ba9c249adf972 1b6a1c84c5e18a125ff5e50861e236af79b18a12 diff --git a/drivers/acpi/drivers/core/event.c b/drivers/acpi/drivers/core/event.c index a9f7dfc..64eb44e 100644 --- a/drivers/acpi/drivers/core/event.c +++ b/drivers/acpi/drivers/core/event.c @@ -7,13 +7,49 @@ #include "core.h" + +static void notify_handler(acpi_handle handle, u32 event, void * data) +{ + struct acpi_dev * ad = data; + struct acpi_device_driver * drv = to_acpi_driver(ad->dev.driver); + struct acpi_device_event * e = drv->d_event; + int raise_data; + int ret; + int i; + + ACPI_FUNCTION_TRACE(__FUNCTION__); + + for (i = 0; i < e->e_num_events; i++) { + if (event == e->e_events[i].e_event) { + ret = e->e_handler(ad, event, &raise_data); + + if (!ret) { + if (e->e_events[i].e_raise) + acpi_bus_generate_event(ad->acpi_device, + event, raise_data); + } else { + err("[%s - %s]: Event [%#x] failed", + drv->d_drv.name, ad->dev.bus_id, event); + break; + } + } + } + + if (i == e->e_num_events) + err("[%s - %s] Unsupported event [%#x]\n", + drv->d_drv.name, ad->dev.bus_id, event); + + return_VOID; +} + + static int install_notify(struct acpi_dev * ad, struct acpi_device_event * e) { acpi_status status; status = acpi_install_notify_handler(ad->acpi_device->handle, e->e_type, - e->e_handler, + notify_handler, ad); return ACPI_SUCCESS(status) ? 0 : -EIO; } @@ -21,7 +57,7 @@ static int install_notify(struct acpi_de static void remove_notify(struct acpi_dev * ad, struct acpi_device_event * e) { acpi_remove_notify_handler(ad->acpi_device->handle, - e->e_type, e->e_handler); + e->e_type, notify_handler); } @@ -33,8 +69,7 @@ static acpi_status notify_fixed(void * d ACPI_FUNCTION_TRACE(__FUNCTION__); - e->e_handler(ad->acpi_device->handle, - e->e_fixed->f_event, ad); + notify_handler(ad->acpi_device->handle, e->e_fixed->f_event, ad); return_ACPI_STATUS(AE_OK); } diff --git a/include/acpi/event.h b/include/acpi/event.h index bba481d..b78e5eb 100644 --- a/include/acpi/event.h +++ b/include/acpi/event.h @@ -109,11 +109,35 @@ static struct acpi_fixed_events __name## } +/** + * struct acpi_device_event + * + * This structure defines the event handling that a driver will do. + * A driver should declare one of these structures in a file called + * 'event.c' (Use one of the declaration macros below). + * + * ->e_type is the type of event (ACPI_DEVICE_NOTIFY by default) + * + * ->e_events is the array of events to listen for (described above) + * + * ->e_num_events is the number of events (automatically determined + * by the declaration macros). + * + * ->e_handler is the callback that is called when one of the + * specified events is encountered. + * It has 3 parameters: the acpi_dev, the event raised, and a pointer + * to the value to be passed to acpi_bus_generate_event(), if the + * event is declared to raise a bus event (see above). + * + * ->e_fixed is a pointer to the fixed event descriptor, which is + * described above, and filled in automatically below. + */ + struct acpi_device_event { u32 e_type; struct acpi_event * e_events; u32 e_num_events; - acpi_notify_handler e_handler; + int (*e_handler) (struct acpi_dev *, u32, int *); struct acpi_fixed_events * e_fixed; }; --- 0.99.9.GIT