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);
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.