* [PATCH] ACPI: add internal event mechanism
@ 2007-06-01 3:06 Daniel Drake
2007-06-15 3:28 ` Dmitry Torokhov
0 siblings, 1 reply; 2+ messages in thread
From: Daniel Drake @ 2007-06-01 3:06 UTC (permalink / raw)
To: linux-acpi
This patch creates a new event system for communication between in-kernel
ACPI drivers ("ievent"). It is simple - it should only be used to infrequently
pass simple messages to a small audience.
This is used in an upcoming patch which makes the ACPI video driver listen for
lid open events from the button driver. I hope it is generic enough to be
useful to other ACPI drivers in the future.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Index: linux/drivers/acpi/bus.c
===================================================================
--- linux.orig/drivers/acpi/bus.c
+++ linux/drivers/acpi/bus.c
@@ -533,6 +533,100 @@ static void acpi_bus_notify(acpi_handle
}
/* --------------------------------------------------------------------------
+ Internal events
+ -------------------------------------------------------------------------- */
+
+/*
+ * This is an event implementation designed for simple communication between
+ * ACPI drivers. It is intended for infrequent events that do not have
+ * many listeners.
+ *
+ * Drivers install an ievent handler to a certain event, and unregister it
+ * later. Drivers may raise (notify) events from any point except from the
+ * context of an event handler function.
+ */
+
+static struct list_head ievent_list;
+static spinlock_t ievent_lock;
+
+struct acpi_ievent_handle {
+ struct list_head list;
+ enum acpi_ievent_code event;
+ acpi_ievent_handler handler;
+ void *user_data;
+};
+
+/* Subscribe to a specific internal event.
+ *
+ * The handler function takes 3 parameters:
+ * 1. The acpi_ievent_code of the event that was raised
+ * 2. Some event data (set when the event was raised by the code which
+ * raised the event)
+ * 3. Some user data which you can specify in the data parameter below.
+ *
+ * This function returns a handle which you must save so that you can
+ * unsubscribe later.
+ */
+struct acpi_ievent_handle *
+acpi_install_ievent_handler(enum acpi_ievent_code event,
+ acpi_ievent_handler handler, void *data)
+{
+ unsigned long flags;
+ struct acpi_ievent_handle *handle
+ = kmalloc(sizeof(*handle), GFP_KERNEL);
+ if (!handle)
+ return NULL;
+
+ handle->event = event;
+ handle->handler = handler;
+ handle->user_data = data;
+ INIT_LIST_HEAD(&handle->list);
+
+ spin_lock_irqsave(&ievent_lock, flags);
+ list_add_tail(&handle->list, &ievent_list);
+ spin_unlock_irqrestore(&ievent_lock, flags);
+
+ return handle;
+}
+EXPORT_SYMBOL_GPL(acpi_install_ievent_handler);
+
+/*
+ * Unsubscribe from an internal event, using a handle that was returned from
+ * acpi_install_ievent_handler() earlier.
+ */
+void acpi_remove_ievent_handler(struct acpi_ievent_handle *handle)
+{
+ unsigned long flags;
+
+ if (!handle)
+ return;
+
+ spin_lock_irqsave(&ievent_lock, flags);
+ list_del(&handle->list);
+ spin_unlock_irqrestore(&ievent_lock, flags);
+ kfree(handle);
+}
+EXPORT_SYMBOL_GPL(acpi_remove_ievent_handler);
+
+/*
+ * Raise an event with some data.
+ */
+void acpi_ievent_notify(enum acpi_ievent_code event, void *event_data)
+{
+ struct acpi_ievent_handle *handle;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ievent_lock, flags);
+ list_for_each_entry(handle, &ievent_list, list) {
+ if (handle->event != event)
+ continue;
+ handle->handler(event, event_data, handle->user_data);
+ }
+ spin_unlock_irqrestore(&ievent_lock, flags);
+}
+EXPORT_SYMBOL_GPL(acpi_ievent_notify);
+
+/* --------------------------------------------------------------------------
Initialization/Cleanup
-------------------------------------------------------------------------- */
@@ -741,6 +835,8 @@ static int __init acpi_init(void)
{
int result = 0;
+ spin_lock_init(&ievent_lock);
+ INIT_LIST_HEAD(&ievent_list);
if (acpi_disabled) {
printk(KERN_INFO PREFIX "Interpreter disabled.\n");
Index: linux/include/acpi/acpi_bus.h
===================================================================
--- linux.orig/include/acpi/acpi_bus.h
+++ linux/include/acpi/acpi_bus.h
@@ -323,6 +323,26 @@ struct acpi_bus_event {
extern struct kset acpi_subsys;
/*
+ * Internal events
+ */
+
+enum acpi_ievent_code {
+ ACPI_IEVENT_LID,
+};
+
+struct acpi_ievent_handle;
+
+typedef
+void (*acpi_ievent_handler)(enum acpi_ievent_code event, void *event_data,
+ void *user_data);
+
+struct acpi_ievent_handle *
+acpi_install_ievent_handler(enum acpi_ievent_code event,
+ acpi_ievent_handler handler, void *data);
+void acpi_remove_ievent_handler(struct acpi_ievent_handle *handle);
+void acpi_ievent_notify(enum acpi_ievent_code event, void *event_data);
+
+/*
* External Functions
*/
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] ACPI: add internal event mechanism
2007-06-01 3:06 [PATCH] ACPI: add internal event mechanism Daniel Drake
@ 2007-06-15 3:28 ` Dmitry Torokhov
0 siblings, 0 replies; 2+ messages in thread
From: Dmitry Torokhov @ 2007-06-15 3:28 UTC (permalink / raw)
To: Daniel Drake; +Cc: linux-acpi
Hi Daniel,
On Thursday 31 May 2007 23:06, Daniel Drake wrote:
> This patch creates a new event system for communication between in-kernel
> ACPI drivers ("ievent"). It is simple - it should only be used to infrequently
> pass simple messages to a small audience.
>
> This is used in an upcoming patch which makes the ACPI video driver listen for
> lid open events from the button driver. I hope it is generic enough to be
> useful to other ACPI drivers in the future.
>
The same can be achieved within input layer framework (just register an input
handler latching onto EV_SW/SW_LID devices). Unless there are more users for
ACPI-specific implementation input layer might be better option.
--
Dmitry
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-06-15 3:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-01 3:06 [PATCH] ACPI: add internal event mechanism Daniel Drake
2007-06-15 3:28 ` Dmitry Torokhov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).