public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dtor@insightbb.com>
To: "Brown, Len" <len.brown@intel.com>
Cc: Richard Hughes <hughsient@gmail.com>,
	Matthew Garrett <mjg59@srcf.ucam.org>,
	linux-acpi@vger.kernel.org, gnome-power-manager-list@gnome.org,
	hal@lists.freedesktop.org, desktop_portables@lists.osdl.org
Subject: Re: [gpm] Untangling the sleep hotkey mess
Date: Thu, 27 Jul 2006 00:12:35 -0400	[thread overview]
Message-ID: <200607270012.35966.dtor@insightbb.com> (raw)
In-Reply-To: <CFF307C98FEABE47A452B27C06B85BB601125524@hdsmsx411.amr.corp.intel.com>

[-- Attachment #1: Type: text/plain, Size: 8260 bytes --]

On Wednesday 26 July 2006 19:41, Brown, Len wrote:
> 
> >> But input layer will be a hub of sorts and I am arguing for ACPI
> >> to be converted to use input layer directly.
> >
> >What does lkml think of ACPI using the input layer directly? 
> 
> I think it is a good idea.
> 
> The only question I have is how to transition.
> If I replace the acpi_bus_generate_event() calls for
> power/sleep/lid/hotkeys
> and replace them with input_report_key(), will there be something up
> there
> listening for these events when acpid does not get them?
> 

Let's start with adding reporting through input layer while still
reporintg through /proc/acpi/event, this will allow gradual transition.

What do you think about the patch below (should be applied on top of
cleanup patch which is attached)? I will need to adjust it to
!CONFIG_INPUT, but it can be done later if we agree on principle.
 
-- 
Dmitry

Subject: ACPI: button - register with input layer

ACPI: button - register with input layer

In addition to signalling button/lid events through /proc/acpi/event
create separate input devices and report KEY_POWER, KEY_SLEEP and
SW_LID through input layer.

My sleep button autorepeat but userspace will have to filter duplicate
sleep requests anyway (and discard unprocessed events right after
wakeup).

Unlike /proc/acpi/event interface input device corresponding to LID
switch reports true lid state instead of just a counter. SW_LID is
active when lid is closed.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/acpi/button.c |  172 ++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 125 insertions(+), 47 deletions(-)

Index: work/drivers/acpi/button.c
===================================================================
--- work.orig/drivers/acpi/button.c
+++ work/drivers/acpi/button.c
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/input.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -83,7 +84,9 @@ static struct acpi_driver acpi_button_dr
 
 struct acpi_button {
 	struct acpi_device *device;	/* Fixed button kludge */
-	u8 type;
+	unsigned int type;
+	struct input_dev *input;
+	char phys[32];			/* for input device */
 	unsigned long pushed;
 };
 
@@ -245,12 +248,35 @@ static int acpi_button_remove_fs(struct 
 static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
 {
 	struct acpi_button *button = data;
+	struct input_dev *input;
 
 	if (!button || !button->device)
 		return;
 
 	switch (event) {
 	case ACPI_BUTTON_NOTIFY_STATUS:
+		input = button->input;
+
+		if (button->type == ACPI_BUTTON_TYPE_LID) {
+			struct acpi_handle *handle = button->device->handle;
+			unsigned long state;
+
+			if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
+								NULL, &state)))
+				state = 1;	/* assume open */
+
+			input_report_switch(input, SW_LID, !state);
+
+		} else {
+			int keycode = test_bit(KEY_SLEEP, input->keybit) ?
+						KEY_SLEEP : KEY_POWER;
+
+			input_report_key(input, keycode, 1);
+			input_sync(input);
+			input_report_key(input, keycode, 0);
+		}
+		input_sync(input);
+
 		acpi_bus_generate_event(button->device, event,
 					++button->pushed);
 		break;
@@ -275,11 +301,58 @@ static acpi_status acpi_button_notify_fi
 	return AE_OK;
 }
 
-static int acpi_button_add(struct acpi_device *device)
+static int acpi_button_install_notify_handlers(struct acpi_button *button)
 {
-	int result;
 	acpi_status status;
+
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWERF:
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						     acpi_button_notify_fixed,
+						     button);
+		break;
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		status =
+		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						     acpi_button_notify_fixed,
+						     button);
+		break;
+	default:
+		status = acpi_install_notify_handler(button->device->handle,
+						     ACPI_DEVICE_NOTIFY,
+						     acpi_button_notify,
+						     button);
+		break;
+	}
+
+	return ACPI_FAILURE(status) ? -ENODEV : 0;
+}
+
+static void acpi_button_remove_notify_handlers(struct acpi_button *button)
+{
+	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWERF:
+		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						acpi_button_notify_fixed);
+		break;
+	case ACPI_BUTTON_TYPE_SLEEPF:
+		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						acpi_button_notify_fixed);
+		break;
+	default:
+		acpi_remove_notify_handler(button->device->handle,
+					   ACPI_DEVICE_NOTIFY,
+					   acpi_button_notify);
+		break;
+	}
+}
+
+static int acpi_button_add(struct acpi_device *device)
+{
+	int error;
 	struct acpi_button *button;
+	struct input_dev *input;
 
 	if (!device)
 		return -EINVAL;
@@ -291,6 +364,12 @@ static int acpi_button_add(struct acpi_d
 	button->device = device;
 	acpi_driver_data(device) = button;
 
+	button->input = input = input_allocate_device();
+	if (!input) {
+		error = -ENOMEM;
+		goto err_free_button;
+	}
+
 	/*
 	 * Determine the button type (via hid), as fixed-feature buttons
 	 * need to be handled a bit differently than generic-space.
@@ -325,39 +404,48 @@ static int acpi_button_add(struct acpi_d
 	} else {
 		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
 			    acpi_device_hid(device));
-		result = -ENODEV;
-		goto end;
+		error = -ENODEV;
+		goto err_free_input;
 	}
 
-	result = acpi_button_add_fs(device);
-	if (result)
-		goto end;
+	error = acpi_button_add_fs(device);
+	if (error)
+		goto err_free_input;
+
+	error = acpi_button_install_notify_handlers(button);
+	if (error)
+		goto err_remove_fs;
+
+	snprintf(button->phys, sizeof(button->phys),
+		 "%s/button/input0", acpi_device_hid(device));
+
+	input->name = acpi_device_name(device);
+	input->phys = button->phys;
+	input->id.bustype = BUS_HOST;
+	input->id.product = button->type;
 
 	switch (button->type) {
+	case ACPI_BUTTON_TYPE_POWER:
 	case ACPI_BUTTON_TYPE_POWERF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
+		input->evbit[0] = BIT(EV_KEY);
+		set_bit(KEY_POWER, input->keybit);
 		break;
+
+	case ACPI_BUTTON_TYPE_SLEEP:
 	case ACPI_BUTTON_TYPE_SLEEPF:
-		status =
-		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						     acpi_button_notify_fixed,
-						     button);
+		input->evbit[0] = BIT(EV_KEY);
+		set_bit(KEY_SLEEP, input->keybit);
 		break;
-	default:
-		status = acpi_install_notify_handler(device->handle,
-						     ACPI_DEVICE_NOTIFY,
-						     acpi_button_notify,
-						     button);
+
+	case ACPI_BUTTON_TYPE_LID:
+		input->evbit[0] = BIT(EV_SW);
+		set_bit(SW_LID, input->swbit);
 		break;
 	}
 
-	if (ACPI_FAILURE(status)) {
-		result = -ENODEV;
-		goto end;
-	}
+	error = input_register_device(input);
+	if (error)
+		goto err_remove_handlers;
 
 	if (device->wakeup.flags.valid) {
 		/* Button's GPE is run-wake GPE */
@@ -372,13 +460,17 @@ static int acpi_button_add(struct acpi_d
 	printk(KERN_INFO PREFIX "%s [%s]\n",
 	       acpi_device_name(device), acpi_device_bid(device));
 
-      end:
-	if (result) {
-		acpi_button_remove_fs(device);
-		kfree(button);
-	}
+	return 0;
 
-	return result;
+ err_remove_handlers:
+	acpi_button_remove_notify_handlers(button);
+ err_remove_fs:
+	acpi_button_remove_fs(device);
+ err_free_input:
+	input_free_device(input);
+ err_free_button:
+	kfree(button);
+	return error;
 }
 
 static int acpi_button_remove(struct acpi_device *device, int type)
@@ -390,23 +482,9 @@ static int acpi_button_remove(struct acp
 
 	button = acpi_driver_data(device);
 
-	/* Unregister for device notifications. */
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWERF:
-		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						acpi_button_notify_fixed);
-		break;
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						acpi_button_notify_fixed);
-		break;
-	default:
-		acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
-					   acpi_button_notify);
-		break;
-	}
-
+	acpi_button_remove_notify_handlers(button);
 	acpi_button_remove_fs(device);
+	input_unregister_device(button->input);
 	kfree(button);
 
 	return 0;

[-- Attachment #2: acpi-button-cleanup.patch --]
[-- Type: text/x-diff, Size: 5676 bytes --]

Subject: ACPI: button - general cleanup

ACPI: button - general cleanup

Remove unnecessary casts and initializations, clean up formatting.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/acpi/button.c |   69 ++++++++++++++++----------------------------------
 1 files changed, 23 insertions(+), 46 deletions(-)

Index: work/drivers/acpi/button.c
===================================================================
--- work.orig/drivers/acpi/button.c
+++ work/drivers/acpi/button.c
@@ -62,7 +62,7 @@
 #define _COMPONENT		ACPI_BUTTON_COMPONENT
 ACPI_MODULE_NAME("acpi_button")
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
 MODULE_LICENSE("GPL");
 
@@ -78,7 +78,7 @@ static struct acpi_driver acpi_button_dr
 	.ops = {
 		.add = acpi_button_add,
 		.remove = acpi_button_remove,
-		},
+	},
 };
 
 struct acpi_button {
@@ -109,8 +109,7 @@ static struct proc_dir_entry *acpi_butto
 
 static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = (struct acpi_button *)seq->private;
-
+	struct acpi_button *button = seq->private;
 
 	if (!button || !button->device)
 		return 0;
@@ -128,22 +127,17 @@ static int acpi_button_info_open_fs(stru
 
 static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
 {
-	struct acpi_button *button = (struct acpi_button *)seq->private;
+	struct acpi_button *button = seq->private;
 	acpi_status status;
 	unsigned long state;
 
-
 	if (!button || !button->device)
 		return 0;
 
 	status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
-	if (ACPI_FAILURE(status)) {
-		seq_printf(seq, "state:      unsupported\n");
-	} else {
-		seq_printf(seq, "state:      %s\n",
-			   (state ? "open" : "closed"));
-	}
-
+	seq_printf(seq, "state:      %s\n",
+		   ACPI_FAILURE(status) ? "unsupported" :
+			(state ? "open" : "closed"));
 	return 0;
 }
 
@@ -159,8 +153,7 @@ static struct proc_dir_entry *acpi_lid_d
 static int acpi_button_add_fs(struct acpi_device *device)
 {
 	struct proc_dir_entry *entry = NULL;
-	struct acpi_button *button = NULL;
-
+	struct acpi_button *button;
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
@@ -228,10 +221,8 @@ static int acpi_button_add_fs(struct acp
 
 static int acpi_button_remove_fs(struct acpi_device *device)
 {
-	struct acpi_button *button = NULL;
-
+	struct acpi_button *button = acpi_driver_data(device);
 
-	button = acpi_driver_data(device);
 	if (acpi_device_dir(device)) {
 		if (button->type == ACPI_BUTTON_TYPE_LID)
 			remove_proc_entry(ACPI_BUTTON_FILE_STATE,
@@ -253,8 +244,7 @@ static int acpi_button_remove_fs(struct 
 
 static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
 {
-	struct acpi_button *button = (struct acpi_button *)data;
-
+	struct acpi_button *button = data;
 
 	if (!button || !button->device)
 		return;
@@ -275,8 +265,7 @@ static void acpi_button_notify(acpi_hand
 
 static acpi_status acpi_button_notify_fixed(void *data)
 {
-	struct acpi_button *button = (struct acpi_button *)data;
-
+	struct acpi_button *button = data;
 
 	if (!button)
 		return AE_BAD_PARAMETER;
@@ -288,18 +277,16 @@ static acpi_status acpi_button_notify_fi
 
 static int acpi_button_add(struct acpi_device *device)
 {
-	int result = 0;
-	acpi_status status = AE_OK;
-	struct acpi_button *button = NULL;
-
+	int result;
+	acpi_status status;
+	struct acpi_button *button;
 
 	if (!device)
 		return -EINVAL;
 
-	button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL);
+	button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
 	if (!button)
 		return -ENOMEM;
-	memset(button, 0, sizeof(struct acpi_button));
 
 	button->device = device;
 	acpi_driver_data(device) = button;
@@ -396,9 +383,7 @@ static int acpi_button_add(struct acpi_d
 
 static int acpi_button_remove(struct acpi_device *device, int type)
 {
-	acpi_status status = 0;
-	struct acpi_button *button = NULL;
-
+	struct acpi_button *button;
 
 	if (!device || !acpi_driver_data(device))
 		return -EINVAL;
@@ -408,24 +393,20 @@ static int acpi_button_remove(struct acp
 	/* Unregister for device notifications. */
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWERF:
-		status =
-		    acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
-						    acpi_button_notify_fixed);
+		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+						acpi_button_notify_fixed);
 		break;
 	case ACPI_BUTTON_TYPE_SLEEPF:
-		status =
-		    acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
-						    acpi_button_notify_fixed);
+		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+						acpi_button_notify_fixed);
 		break;
 	default:
-		status = acpi_remove_notify_handler(device->handle,
-						    ACPI_DEVICE_NOTIFY,
-						    acpi_button_notify);
+		acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+					   acpi_button_notify);
 		break;
 	}
 
 	acpi_button_remove_fs(device);
-
 	kfree(button);
 
 	return 0;
@@ -433,8 +414,7 @@ static int acpi_button_remove(struct acp
 
 static int __init acpi_button_init(void)
 {
-	int result = 0;
-
+	int result;
 
 	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
 	if (!acpi_button_dir)
@@ -451,7 +431,6 @@ static int __init acpi_button_init(void)
 
 static void __exit acpi_button_exit(void)
 {
-
 	acpi_bus_unregister_driver(&acpi_button_driver);
 
 	if (acpi_power_dir)
@@ -461,8 +440,6 @@ static void __exit acpi_button_exit(void
 	if (acpi_lid_dir)
 		remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
 	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
-
-	return;
 }
 
 module_init(acpi_button_init);

  parent reply	other threads:[~2006-07-27  4:12 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-26 23:41 [gpm] Untangling the sleep hotkey mess Brown, Len
2006-07-26 23:52 ` Matthew Garrett
2006-07-27  4:12 ` Dmitry Torokhov [this message]
  -- strict thread matches above, loose matches on Subject: below --
2006-08-31  1:49 Brown, Len
2006-08-31  2:53 ` Dmitry Torokhov
2006-08-31  3:03   ` Len Brown
     [not found]     ` <200608302303.38458.len.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2006-08-31  3:07       ` Dmitry Torokhov
2006-09-18  7:55         ` Richard Hughes
     [not found]           ` <1158566150.2332.14.camel-Qvr7v16j6+Ap96r9Hs7rR1Kr0EmMEXJSn9A1Ff6Mc9Q@public.gmane.org>
2006-09-18 15:17             ` Dmitry Torokhov
2006-09-18 17:52               ` Richard Hughes
2006-01-09  1:37 Yu, Luming
2006-01-09  1:43 ` Matthew Garrett
     [not found]   ` <20060109014350.GA672-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>
2006-01-09  2:19     ` Yu Luming
     [not found]       ` <200601091019.01083.luming.yu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2006-01-09  2:30         ` Matthew Garrett
     [not found]           ` <20060109023037.GA1316-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>
2006-01-09  3:13             ` Yu Luming
     [not found]               ` <200601091113.16092.luming.yu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2006-01-09  3:27                 ` Matthew Garrett
     [not found]                   ` <20060109032717.GA2238-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>
2006-01-09  3:55                     ` Yu Luming
     [not found]                       ` <200601091155.24380.luming.yu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2006-01-09  4:07                         ` Matthew Garrett
2006-01-09 10:04             ` Richard Hughes
2006-01-09 21:14               ` Dmitry Torokhov
     [not found]               ` <d120d5000601091314g7cef73fk445976b14c549a04@mail.gmail.com>
2006-01-09 21:40                 ` Matthew Garrett
     [not found]                 ` <20060109214050.GA19974@srcf.ucam.org>
2006-01-09 21:52                   ` Dmitry Torokhov
     [not found]                   ` <d120d5000601091352m19ba5eb0n80c462cba49bd2a6@mail.gmail.com>
     [not found]                     ` <d120d5000601091352m19ba5eb0n80c462cba49bd2a6-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2006-01-09 22:04                       ` Matthew Garrett
2006-01-07 17:24 Matthew Garrett
2006-01-08 12:58 ` [gpm] " Richard Hughes
2006-01-08 13:47   ` Matthew Garrett
     [not found]     ` <20060108134744.GA21538-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>
2006-01-08 14:13       ` Richard Hughes
2006-01-09  1:10         ` Yu Luming
2006-01-09  1:21           ` Richard Hughes
2006-01-09  1:14         ` Richard Hughes
2006-01-09  5:07           ` Dmitry Torokhov
     [not found]             ` <200601090007.43578.dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
2006-01-09  5:24               ` Matthew Garrett
2006-01-09  9:43               ` Richard Hughes
     [not found]             ` <20060109052407.GA4213@srcf.ucam.org>
     [not found]               ` <20060109052407.GA4213-1xO5oi07KQx4cg9Nei1l7Q@public.gmane.org>
2006-01-09  6:09                 ` Dmitry Torokhov
     [not found]                   ` <200601090109.05791.dtor_core-yWtbtysYrB+LZ21kGMrzwg@public.gmane.org>
2006-01-09  9:44                     ` Richard Hughes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200607270012.35966.dtor@insightbb.com \
    --to=dtor@insightbb.com \
    --cc=desktop_portables@lists.osdl.org \
    --cc=gnome-power-manager-list@gnome.org \
    --cc=hal@lists.freedesktop.org \
    --cc=hughsient@gmail.com \
    --cc=len.brown@intel.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox