linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).