[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20251030-lid-switch-notifier-v1-1-c58dc9b1439d@google.com>
Date: Thu, 30 Oct 2025 14:10:40 +0000
From: Jonathan Denose <jdenose@...gle.com>
To: Dmitry Torokhov <dmitry.torokhov@...il.com>, Jiri Kosina <jikos@...nel.org>, 
	Benjamin Tissoires <bentiss@...nel.org>
Cc: linux-input@...r.kernel.org, linux-kernel@...r.kernel.org, 
	Jonathan Denose <jdenose@...gle.com>
Subject: [PATCH 1/2] Input: Create input notifier chain in input.c
To expose input events to other kernel modules, add a blocking notifier
chain. Publish LID_SWITCH_OPEN/LID_SWITCH_CLOSE events through this
notifier chain when input_handle_event detects events signaling the lid
switch has opened or closed.
Additionally, export a function which allows other kernel modules to
register notifier_block structs against this notifier chain.
Signed-off-by: Jonathan Denose <jdenose@...gle.com>
---
 drivers/input/input.c | 13 +++++++++++++
 include/linux/input.h |  7 +++++++
 2 files changed, 20 insertions(+)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index a500e1e276c211d1146dbfea421a3402084007f8..b342b1ff138ccc58d4623edcf1152bd85d7054bf 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -26,6 +26,7 @@
 #include <linux/kstrtox.h>
 #include <linux/mutex.h>
 #include <linux/rcupdate.h>
+#include <linux/notifier.h>
 #include "input-compat.h"
 #include "input-core-private.h"
 #include "input-poller.h"
@@ -62,6 +63,8 @@ static const unsigned int input_max_code[EV_CNT] = {
 	[EV_FF] = FF_MAX,
 };
 
+static struct blocking_notifier_head input_notifier_head;
+
 static inline int is_event_supported(unsigned int code,
 				     unsigned long *bm, unsigned int max)
 {
@@ -367,10 +370,20 @@ void input_handle_event(struct input_dev *dev,
 		if (type != EV_SYN)
 			add_input_randomness(type, code, value);
 
+		if (type == EV_SW && code == SW_LID && !value)
+			blocking_notifier_call_chain(&input_notifier_head, value ?
+				LID_SWITCH_CLOSE : LID_SWITCH_OPEN, dev);
+
 		input_event_dispose(dev, disposition, type, code, value);
 	}
 }
 
+int register_input_notifier(struct notifier_block *notifier)
+{
+	return blocking_notifier_chain_register(&input_notifier_head, notifier);
+}
+EXPORT_SYMBOL(register_input_notifier);
+
 /**
  * input_event() - report new input event
  * @dev: device that generated the event
diff --git a/include/linux/input.h b/include/linux/input.h
index 7d7cb0593a63e93c4906c49cde430188db2d1ab5..e940aff8843a0afc693c60a252d6b0dbcb3476c4 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -42,6 +42,11 @@ enum input_clock_type {
 	INPUT_CLK_MAX
 };
 
+enum input_notify_event_type {
+	LID_SWITCH_OPEN,
+	LID_SWITCH_CLOSE
+};
+
 /**
  * struct input_dev - represents an input device
  * @name: name of the device
@@ -431,6 +436,8 @@ int input_flush_device(struct input_handle *handle, struct file *file);
 void input_set_timestamp(struct input_dev *dev, ktime_t timestamp);
 ktime_t *input_get_timestamp(struct input_dev *dev);
 
+int register_input_notifier(struct notifier_block *notifier);
+
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
 void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
 
-- 
2.51.1.851.g4ebd6896fd-goog
Powered by blists - more mailing lists
 
