Subject: [PATCH] [acpi events] Make fixed event declaration smoother - Create struct acpi_fixed_events to be filled in by drivers to declare the set of fixed events that the driver wants to register. - Add declare_acpi_fixed() macro for drivers to use that fills in the struct acpi_fixed_events structure. - Update acpi_device_event_fixed() macro - Update core event code to check for right structure Signed-off-by: Patrick Mochel --- drivers/acpi/drivers/core/event.c | 60 +++++++++++++++++-------------- include/acpi/event.h | 71 ++++++++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 48 deletions(-) applies-to: cb54468f10b24a89f649b3fe55fd22e7ab14e7b5 de08792737e4972a9fd15baaba960207494d7f9e diff --git a/drivers/acpi/drivers/core/event.c b/drivers/acpi/drivers/core/event.c index c5a7686..a9f7dfc 100644 --- a/drivers/acpi/drivers/core/event.c +++ b/drivers/acpi/drivers/core/event.c @@ -34,25 +34,42 @@ static acpi_status notify_fixed(void * d ACPI_FUNCTION_TRACE(__FUNCTION__); e->e_handler(ad->acpi_device->handle, - e->e_fixed_event, ad); + e->e_fixed->f_event, ad); return_ACPI_STATUS(AE_OK); } -static int install_fixed(struct acpi_dev * ad, u32 event) +static int install_fixed(struct acpi_dev * ad, struct acpi_fixed_events * f) { acpi_status status; + int i; - status = acpi_install_fixed_event_handler(event, - notify_fixed, - ad); - return ACPI_SUCCESS(status) ? 0 : -EIO; + for (i = 0; i < f->f_num_fixed; i++) { + status = acpi_install_fixed_event_handler(f->f_fixed[i], + notify_fixed, + ad); + if (ACPI_FAILURE(status)) + goto Fail; + } + return 0; + + Fail: + /* + * Installing a fixed event handler failed. + * Remove the events that we've already installed. + */ + while (--i > 0) + acpi_remove_fixed_event_handler(f->f_fixed[i], notify_fixed); + return -EIO; } -static void remove_fixed(struct acpi_dev * ad, u32 event) +static void remove_fixed(struct acpi_dev * ad, struct acpi_fixed_events * f) { - acpi_remove_fixed_event_handler(event, notify_fixed); + int i; + + for (i = 0; i < f->f_num_fixed; i++) + acpi_remove_fixed_event_handler(f->f_fixed[i], notify_fixed); } @@ -74,35 +91,25 @@ int acpi_device_event_add(struct acpi_de struct acpi_device_driver * drv = to_acpi_driver(ad->dev.driver); struct acpi_device_event * e = drv->d_event; int ret = 0; - int i; if (e && e->e_handler) { ret = install_notify(ad, e); if (ret) { - err("Install notify handler failed [%s] [%s]", + err("Install notify handler failed [%s] [%s]", drv->d_drv.name, ad->dev.bus_id); return -EIO; } - for (i = 0; i < e->e_num_fixed; i++) { - ret = install_fixed(ad, e->e_fixed[i]); + if (e->e_fixed) { + ret = install_fixed(ad, e->e_fixed); if (ret) { - err("Install fixed handler failed [%s] [%s]", + err("Install fixed handler failed [%s] [%s]", drv->d_drv.name, ad->dev.bus_id); - goto FixedFailed; + remove_notify(ad, e); + return -EIO; } } } return 0; - - FixedFailed: - /* - * Installing a fixed event handler failed. - * Remove the events that we've already installed. - */ - while (--i > 0) - remove_fixed(ad, e->e_fixed[i]); - remove_notify(ad, e); - return ret; } @@ -116,12 +123,11 @@ void acpi_device_event_remove(struct acp { struct acpi_device_driver * drv = to_acpi_driver(ad->dev.driver); struct acpi_device_event * e = drv->d_event; - int i; if (e && e->e_handler) { remove_notify(ad, e); - for (i = 0; i < e->e_num_fixed; i++) - remove_fixed(ad, e->e_fixed[i]); + if (e->e_fixed) + remove_fixed(ad, e->e_fixed); } } diff --git a/include/acpi/event.h b/include/acpi/event.h index 9413600..d20b618 100644 --- a/include/acpi/event.h +++ b/include/acpi/event.h @@ -1,13 +1,53 @@ #include +/** + * struct acpi_fixed_events + * + * This structure describes a set of fixed events that a + * driver wants to register. The fields are as follows: + * + * ->f_event is the event to be passed to the driver's + * generic notify handler. + * + * ->f_fixed is the array of fixed events to be installed. + * + * ->f_num_fixed is the number of fixed events in ->f_fixed. + */ + +struct acpi_fixed_events { + u32 f_event; + u32 * f_fixed; + u32 f_num_fixed; +}; + + +/** + * declare_acpi_fixed() - helper for declaring fixed events + * @__name - Driver name + * @__event - Event to be passed to driver's generic notify handler + * @... - List of fixed events to be listened for + * + * A driver should use this to declare a set of fixed events + * that it wishes to listen for. It will be referenced by the + * acpi_device_event_fixed() macro below. + * + * Please see the button driver for an example of using fixed + * events (the only driver that uses fixed events). + */ + +#define declare_acpi_fixed(__name, __event, ... ) \ +static u32 __name##_fixed_events[] = { __VA_ARGS__ }; \ +static struct acpi_fixed_events __name##_fixed = { \ + .f_event = __event, \ + .f_fixed = __name##_fixed_events, \ + .f_num_fixed = ARRAY_SIZE(__name##_fixed_events), \ +} + struct acpi_device_event { u32 e_type; acpi_notify_handler e_handler; - - u32 e_num_fixed; - u32 * e_fixed; - u32 e_fixed_event; + struct acpi_fixed_events * e_fixed; }; @@ -32,31 +72,20 @@ struct acpi_device_event __name##_event /** - * This macro should be used by drivers that want to - * install a handler for a fixed event, and optionally - * a regular event (for control method-based devices). + * acpi_device_event_fixed() - Declare a driver event for + * regular and fixed events. + * @__name: The driver name. * * This follows the same rules as acpi_device_event() - * above, but also requires that the driver declare an - * array of fixed events (of type 'u32') that for which - * an internal handler is registered. - * - * The second parameter is the event that is passed to - * the notify handler (->e_handler()) when the fixed - * event is raised. - * - * For an example, please see the button driver, which - * is one of the devices that can actually generate fixed - * events. + * above, but also requires that the driver declare a + * a struct acpi_fixed_event (use the macro above). */ -#define acpi_device_event_fixed(__name, __event) \ +#define acpi_device_event_fixed(__name) \ struct acpi_device_event __name##_event = { \ .e_type = ACPI_DEVICE_NOTIFY, \ .e_handler = __name##_notify, \ - .e_num_fixed = ARRAY_SIZE(__name##_fixed), \ .e_fixed = __name##_fixed, \ - .e_fixed_event = __event, \ } --- 0.99.9.GIT