diff mbox

[RFC] ACPI: Add GPIO-signaled event simulator.

Message ID 1406217076-17150-1-git-send-email-tomasz.nowicki@linaro.org
State New
Headers show

Commit Message

Tomasz Nowicki July 24, 2014, 3:51 p.m. UTC
GPIO signaled events is quite new thing in Linux kernel.
AFAIK, there are not many board which can take advantage of it.
However, GPIO events are very useful feature during work on ACPI
subsystems.

This commit emulates GPIO h/w behaviour and consists on read/write
operation to debugfs file. GPIO device instance is still required in DSDT
table along with _AEI resources and event methods.

Reading from file provides pin to GPIO device map e.g. :
$ cat /sys/kernel/debug/acpi/gpio_event
GPIO device name: /__SB.GPI0
Available GPIO pin map:
/__SB.GPI0 <-> pin 0x100

Based on that, user can trigger method corresponding to device pin number:
$ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event

Please, see Kconfig help and driver head section for more details
regarding tool usage.

Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org>
---
 drivers/acpi/Kconfig        |  11 +++
 drivers/acpi/Makefile       |   1 +
 drivers/acpi/gpio_evt_emu.c | 207 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 219 insertions(+)
 create mode 100644 drivers/acpi/gpio_evt_emu.c

Comments

Linus Walleij Aug. 8, 2014, 12:36 p.m. UTC | #1
On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
<tomasz.nowicki@linaro.org> wrote:

> GPIO signaled events is quite new thing in Linux kernel.
> AFAIK, there are not many board which can take advantage of it.
> However, GPIO events are very useful feature during work on ACPI
> subsystems.

Overall this seems like a pretty nice debug feature.

> This commit emulates GPIO h/w behaviour and consists on read/write
> operation to debugfs file. GPIO device instance is still required in DSDT
> table along with _AEI resources and event methods.
>
> Reading from file provides pin to GPIO device map e.g. :
> $ cat /sys/kernel/debug/acpi/gpio_event
> GPIO device name: /__SB.GPI0
> Available GPIO pin map:
> /__SB.GPI0 <-> pin 0x100
>
> Based on that, user can trigger method corresponding to device pin number:
> $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event

I need input from Rafael and Mika as to whether this is a
good interface.

It seems a bit confusing for me: why do you have to extract
a number from one file and then insert the same magic number
somewhere else?

Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mika Westerberg Aug. 12, 2014, 10:01 a.m. UTC | #2
On Fri, Aug 08, 2014 at 02:36:02PM +0200, Linus Walleij wrote:
> On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
> <tomasz.nowicki@linaro.org> wrote:
> 
> > GPIO signaled events is quite new thing in Linux kernel.
> > AFAIK, there are not many board which can take advantage of it.
> > However, GPIO events are very useful feature during work on ACPI
> > subsystems.
> 
> Overall this seems like a pretty nice debug feature.
> 
> > This commit emulates GPIO h/w behaviour and consists on read/write
> > operation to debugfs file. GPIO device instance is still required in DSDT
> > table along with _AEI resources and event methods.
> >
> > Reading from file provides pin to GPIO device map e.g. :
> > $ cat /sys/kernel/debug/acpi/gpio_event
> > GPIO device name: /__SB.GPI0
> > Available GPIO pin map:
> > /__SB.GPI0 <-> pin 0x100
> >
> > Based on that, user can trigger method corresponding to device pin number:
> > $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
> 
> I need input from Rafael and Mika as to whether this is a
> good interface.

Maybe it would make sense to move this into drivers/gpio/gpiolib-acpi.c
and hide it behind some Kconfig entry?

Since you already need to have DSDT/SSDT table for this to provide the
GPIO device, _AEI and the event methods, I would rather make it so that
acpi_gpiochip_request_interrupt() will add debugfs entry for each GPIO
it finds in _AEI, like:

/sys/kernel/debug/acpi/events/<GPIO DEVICE>/n

And you could trigger it by writing '1' or something like that to that
file.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alexandre Courbot Aug. 12, 2014, 2:15 p.m. UTC | #3
On Tue, Aug 12, 2014 at 3:01 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Fri, Aug 08, 2014 at 02:36:02PM +0200, Linus Walleij wrote:
>> On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
>> <tomasz.nowicki@linaro.org> wrote:
>>
>> > GPIO signaled events is quite new thing in Linux kernel.
>> > AFAIK, there are not many board which can take advantage of it.
>> > However, GPIO events are very useful feature during work on ACPI
>> > subsystems.
>>
>> Overall this seems like a pretty nice debug feature.
>>
>> > This commit emulates GPIO h/w behaviour and consists on read/write
>> > operation to debugfs file. GPIO device instance is still required in DSDT
>> > table along with _AEI resources and event methods.
>> >
>> > Reading from file provides pin to GPIO device map e.g. :
>> > $ cat /sys/kernel/debug/acpi/gpio_event
>> > GPIO device name: /__SB.GPI0
>> > Available GPIO pin map:
>> > /__SB.GPI0 <-> pin 0x100
>> >
>> > Based on that, user can trigger method corresponding to device pin number:
>> > $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
>>
>> I need input from Rafael and Mika as to whether this is a
>> good interface.
>
> Maybe it would make sense to move this into drivers/gpio/gpiolib-acpi.c
> and hide it behind some Kconfig entry?

I actually like that this feature is contained in its own file - it
makes it easier to Kconfig-isolate and keeps the base ACPI code short
and readable. We spent some effort decoupling the sysfs and legacy
interfaces from the main gpiolib source file, let's keep that policy
going. ;)

Maybe the source file could be renamed to highlight the fact this is
an ACPI-only feature, e.g. gpio-acpi-evt-emu.c? (let's also use '-' as
separator since this is what all GPIO drivers do).
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mika Westerberg Aug. 12, 2014, 3:24 p.m. UTC | #4
On Tue, Aug 12, 2014 at 07:15:41AM -0700, Alexandre Courbot wrote:
> On Tue, Aug 12, 2014 at 3:01 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Fri, Aug 08, 2014 at 02:36:02PM +0200, Linus Walleij wrote:
> >> On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
> >> <tomasz.nowicki@linaro.org> wrote:
> >>
> >> > GPIO signaled events is quite new thing in Linux kernel.
> >> > AFAIK, there are not many board which can take advantage of it.
> >> > However, GPIO events are very useful feature during work on ACPI
> >> > subsystems.
> >>
> >> Overall this seems like a pretty nice debug feature.
> >>
> >> > This commit emulates GPIO h/w behaviour and consists on read/write
> >> > operation to debugfs file. GPIO device instance is still required in DSDT
> >> > table along with _AEI resources and event methods.
> >> >
> >> > Reading from file provides pin to GPIO device map e.g. :
> >> > $ cat /sys/kernel/debug/acpi/gpio_event
> >> > GPIO device name: /__SB.GPI0
> >> > Available GPIO pin map:
> >> > /__SB.GPI0 <-> pin 0x100
> >> >
> >> > Based on that, user can trigger method corresponding to device pin number:
> >> > $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
> >>
> >> I need input from Rafael and Mika as to whether this is a
> >> good interface.
> >
> > Maybe it would make sense to move this into drivers/gpio/gpiolib-acpi.c
> > and hide it behind some Kconfig entry?
> 
> I actually like that this feature is contained in its own file - it
> makes it easier to Kconfig-isolate and keeps the base ACPI code short
> and readable. We spent some effort decoupling the sysfs and legacy
> interfaces from the main gpiolib source file, let's keep that policy
> going. ;)

Well, OK but then it needs to make some functions available through the
private gpiolib.h so that the gpiolib-acpi.c is able to call them. Of
course it depends on whether the idea of exporting debugfs entries from
acpi_gpiochip_request_interrupt() instead is going to be implemented.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tomasz Nowicki Aug. 18, 2014, 9:06 a.m. UTC | #5
On 08.08.2014 14:36, Linus Walleij wrote:
> On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
> <tomasz.nowicki@linaro.org> wrote:
>
>> GPIO signaled events is quite new thing in Linux kernel.
>> AFAIK, there are not many board which can take advantage of it.
>> However, GPIO events are very useful feature during work on ACPI
>> subsystems.
>
> Overall this seems like a pretty nice debug feature.
>
>> This commit emulates GPIO h/w behaviour and consists on read/write
>> operation to debugfs file. GPIO device instance is still required in DSDT
>> table along with _AEI resources and event methods.
>>
>> Reading from file provides pin to GPIO device map e.g. :
>> $ cat /sys/kernel/debug/acpi/gpio_event
>> GPIO device name: /__SB.GPI0
>> Available GPIO pin map:
>> /__SB.GPI0 <-> pin 0x100
>>
>> Based on that, user can trigger method corresponding to device pin number:
>> $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
>
> I need input from Rafael and Mika as to whether this is a
> good interface.
>
> It seems a bit confusing for me: why do you have to extract
> a number from one file and then insert the same magic number
> somewhere else?

Good point! Available GPIO event pins should be listed as debugfs node, 
then user would write e.g. 1 to one particular. Sounds simpler.

Regards,
Tomasz Nowicki
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tomasz Nowicki Aug. 18, 2014, 9:28 a.m. UTC | #6
On 12.08.2014 12:01, Mika Westerberg wrote:
> On Fri, Aug 08, 2014 at 02:36:02PM +0200, Linus Walleij wrote:
>> On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
>> <tomasz.nowicki@linaro.org> wrote:
>>
>>> GPIO signaled events is quite new thing in Linux kernel.
>>> AFAIK, there are not many board which can take advantage of it.
>>> However, GPIO events are very useful feature during work on ACPI
>>> subsystems.
>>
>> Overall this seems like a pretty nice debug feature.
>>
>>> This commit emulates GPIO h/w behaviour and consists on read/write
>>> operation to debugfs file. GPIO device instance is still required in DSDT
>>> table along with _AEI resources and event methods.
>>>
>>> Reading from file provides pin to GPIO device map e.g. :
>>> $ cat /sys/kernel/debug/acpi/gpio_event
>>> GPIO device name: /__SB.GPI0
>>> Available GPIO pin map:
>>> /__SB.GPI0 <-> pin 0x100
>>>
>>> Based on that, user can trigger method corresponding to device pin number:
>>> $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
>>
>> I need input from Rafael and Mika as to whether this is a
>> good interface.
>
> Maybe it would make sense to move this into drivers/gpio/gpiolib-acpi.c
> and hide it behind some Kconfig entry?
>
> Since you already need to have DSDT/SSDT table for this to provide the
> GPIO device, _AEI and the event methods, I would rather make it so that
> acpi_gpiochip_request_interrupt() will add debugfs entry for each GPIO
> it finds in _AEI, like:
>
> /sys/kernel/debug/acpi/events/<GPIO DEVICE>/n
>
> And you could trigger it by writing '1' or something like that to that
> file.
>

Thanks for comments. The idea of available gpio events list under 
/sys/kernel/debug/acpi/events/<GPIO DEVICE>/n is worth adding.

However, acpi_gpiochip_request_interrupt() would be called if we would 
have real GPIO H/W and related driver. Initial idea of this patch was to 
avoid that restriction. So there are two cases:
1. If we have GPIO chip, it is already described in DSDT/SSDT and using 
this patch, user could trigger events by software too.
2. None of GPIO chip, so we need to add GPIO/_AEI etc. descrition to 
DSDT/SSDT and pretend we have GPIO chip on board.

Regards,
Tomasz Nowicki

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
Tomasz Nowicki Aug. 18, 2014, 9:31 a.m. UTC | #7
On 12.08.2014 16:15, Alexandre Courbot wrote:
> On Tue, Aug 12, 2014 at 3:01 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
>> On Fri, Aug 08, 2014 at 02:36:02PM +0200, Linus Walleij wrote:
>>> On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
>>> <tomasz.nowicki@linaro.org> wrote:
>>>
>>>> GPIO signaled events is quite new thing in Linux kernel.
>>>> AFAIK, there are not many board which can take advantage of it.
>>>> However, GPIO events are very useful feature during work on ACPI
>>>> subsystems.
>>>
>>> Overall this seems like a pretty nice debug feature.
>>>
>>>> This commit emulates GPIO h/w behaviour and consists on read/write
>>>> operation to debugfs file. GPIO device instance is still required in DSDT
>>>> table along with _AEI resources and event methods.
>>>>
>>>> Reading from file provides pin to GPIO device map e.g. :
>>>> $ cat /sys/kernel/debug/acpi/gpio_event
>>>> GPIO device name: /__SB.GPI0
>>>> Available GPIO pin map:
>>>> /__SB.GPI0 <-> pin 0x100
>>>>
>>>> Based on that, user can trigger method corresponding to device pin number:
>>>> $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
>>>
>>> I need input from Rafael and Mika as to whether this is a
>>> good interface.
>>
>> Maybe it would make sense to move this into drivers/gpio/gpiolib-acpi.c
>> and hide it behind some Kconfig entry?
>
> I actually like that this feature is contained in its own file - it
> makes it easier to Kconfig-isolate and keeps the base ACPI code short
> and readable. We spent some effort decoupling the sysfs and legacy
> interfaces from the main gpiolib source file, let's keep that policy
> going. ;)

I will keep that isolation.

>
> Maybe the source file could be renamed to highlight the fact this is
> an ACPI-only feature, e.g. gpio-acpi-evt-emu.c? (let's also use '-' as
> separator since this is what all GPIO drivers do).
>

Yes, I will rename it as you suggested. I will address all comments 
based on feedback I have got and send another version. Thanks!

Regards,
Tomasz Nowicki
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mika Westerberg Aug. 18, 2014, 9:41 a.m. UTC | #8
On Mon, Aug 18, 2014 at 11:28:09AM +0200, Tomasz Nowicki wrote:
> On 12.08.2014 12:01, Mika Westerberg wrote:
> >On Fri, Aug 08, 2014 at 02:36:02PM +0200, Linus Walleij wrote:
> >>On Thu, Jul 24, 2014 at 5:51 PM, Tomasz Nowicki
> >><tomasz.nowicki@linaro.org> wrote:
> >>
> >>>GPIO signaled events is quite new thing in Linux kernel.
> >>>AFAIK, there are not many board which can take advantage of it.
> >>>However, GPIO events are very useful feature during work on ACPI
> >>>subsystems.
> >>
> >>Overall this seems like a pretty nice debug feature.
> >>
> >>>This commit emulates GPIO h/w behaviour and consists on read/write
> >>>operation to debugfs file. GPIO device instance is still required in DSDT
> >>>table along with _AEI resources and event methods.
> >>>
> >>>Reading from file provides pin to GPIO device map e.g. :
> >>>$ cat /sys/kernel/debug/acpi/gpio_event
> >>>GPIO device name: /__SB.GPI0
> >>>Available GPIO pin map:
> >>>/__SB.GPI0 <-> pin 0x100
> >>>
> >>>Based on that, user can trigger method corresponding to device pin number:
> >>>$ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
> >>
> >>I need input from Rafael and Mika as to whether this is a
> >>good interface.
> >
> >Maybe it would make sense to move this into drivers/gpio/gpiolib-acpi.c
> >and hide it behind some Kconfig entry?
> >
> >Since you already need to have DSDT/SSDT table for this to provide the
> >GPIO device, _AEI and the event methods, I would rather make it so that
> >acpi_gpiochip_request_interrupt() will add debugfs entry for each GPIO
> >it finds in _AEI, like:
> >
> >/sys/kernel/debug/acpi/events/<GPIO DEVICE>/n
> >
> >And you could trigger it by writing '1' or something like that to that
> >file.
> >
> 
> Thanks for comments. The idea of available gpio events list under
> /sys/kernel/debug/acpi/events/<GPIO DEVICE>/n is worth adding.
> 
> However, acpi_gpiochip_request_interrupt() would be called if we would have
> real GPIO H/W and related driver. Initial idea of this patch was to avoid
> that restriction. So there are two cases:
> 1. If we have GPIO chip, it is already described in DSDT/SSDT and using this
> patch, user could trigger events by software too.

Yes, this is what I would be interested in.

> 2. None of GPIO chip, so we need to add GPIO/_AEI etc. descrition to
> DSDT/SSDT and pretend we have GPIO chip on board.

OK.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
diff mbox

Patch

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index fd54a74..59e4c67 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -122,6 +122,17 @@  config ACPI_BUTTON
 	  To compile this driver as a module, choose M here:
 	  the module will be called button.
 
+config ACPI_GPIO_EVT_EMULATE
+        bool "ACPI GPIO-signaled Events Emulation Support"
+        depends on DEBUG_FS
+	default n
+	help
+	  This will enable your system to emulate GPIO-signaled event through
+	  proc file system /sys/kernel/debug/acpi/gpio_event. User needs to print
+	  available GPIO devices and pin map (cat path_to_proc_file) so that he
+	  knows how to trigger given event by echo "XXX YYY" > path_to_proc_file
+	  (where, XXX is a path to GPIO device and YYY is a pin number).
+
 config ACPI_VIDEO
 	tristate "Video"
 	depends on X86 && BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 9fa20ff..fb3c335 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -55,6 +55,7 @@  acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
 ifdef CONFIG_ACPI_VIDEO
 acpi-y				+= video_detect.o
 endif
+acpi-$(CONFIG_ACPI_GPIO_EVT_EMULATE)	+= gpio_evt_emu.o
 
 # These are (potentially) separate modules
 
diff --git a/drivers/acpi/gpio_evt_emu.c b/drivers/acpi/gpio_evt_emu.c
new file mode 100644
index 0000000..a2f762c
--- /dev/null
+++ b/drivers/acpi/gpio_evt_emu.c
@@ -0,0 +1,207 @@ 
+/*
+ * Code to emulate GPIO-signaled events.
+ *
+ * The sole purpose of this module is to help with GPIO event triggering.
+ * Suggested way of using:
+ * 1. Perform walk of the namespac device tree looking for GPIO devices
+ *    with associated _AEI resources e.g.:
+ *    $ cat /sys/kernel/debug/acpi/gpio_event
+ *    GPIO device name: /__SB.GPI0
+ *    Available GPIO pin map:
+ *    /__SB.GPI0 <-> pin 0x100
+ *
+ * 2. Trigger method corresponding to device pin number:
+ *    $ echo "/__SB.GPI0 0x100" > /sys/kernel/debug/acpi/gpio_event
+ */
+
+/*
+ * Copyright (C) 2014, Linaro Ltd.
+ * Author: Tomasz Nowicki <tomasz.nowicki@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/acpi.h>
+
+#include "acpica/accommon.h"
+#include "acpica/acnamesp.h"
+
+#include "internal.h"
+
+static struct dentry *gpio_evt_dentry;
+
+static void gpio_trigger_event(char *gpio_path, u32 pin)
+{
+	acpi_handle gpio_handle, evt_handle;
+	char ev_name[5];
+
+	if (ACPI_FAILURE(acpi_get_handle(NULL, gpio_path, &gpio_handle))) {
+		pr_err(PREFIX "getting handle to <%s> failed\n", gpio_path);
+		return;
+	}
+
+	if (pin <= 255)
+		sprintf(ev_name, "_L%02X", pin);
+	else
+		sprintf(ev_name, "_EVT");
+
+
+	if (ACPI_FAILURE(acpi_get_handle(gpio_handle, ev_name, &evt_handle))) {
+		pr_err(PREFIX "getting handle to <%s.%s> failed, there is no method related to 0x%02X pin\n",
+		       gpio_path, ev_name, pin);
+		return;
+	}
+
+	if (ACPI_FAILURE(acpi_execute_simple_method(evt_handle, NULL,
+						    pin <= 255 ? 0 : pin)))
+		pr_err(PREFIX "evaluating <%s._EVT for pin %d> failed\n",
+		       gpio_path, pin);
+
+	return;
+}
+
+static ssize_t gpio_evt_write(struct file *file, const char __user *user_buf,
+				 size_t count, loff_t *ppos)
+{
+	u32 pin_number;
+	char *gpio_path = NULL;
+	char *pin_str = NULL;
+	const char *delim = " ";
+	char *temp_buf = NULL;
+	char *temp_buf_addr = NULL;
+
+	temp_buf = kmalloc(count+1, GFP_ATOMIC);
+	if (!temp_buf) {
+		pr_warn(PREFIX "%s: Memory allocation failed\n", __func__);
+		return count;
+	}
+	temp_buf[count] = '\0';
+	temp_buf_addr = temp_buf;
+	if (copy_from_user(temp_buf, user_buf, count))
+		goto out;
+
+	gpio_path = strsep(&temp_buf, delim);
+	pin_str = strsep(&temp_buf, delim);
+
+	if (gpio_path && pin_str) {
+		ssize_t ret;
+		unsigned long val;
+
+		ret = kstrtoul(pin_str, 10, &val);
+		if (ret) {
+			pr_warn(PREFIX "unknown event\n");
+			goto out;
+		}
+
+		pin_number = (u32)val;
+	} else {
+		pr_warn(PREFIX "unknown device\n");
+		goto out;
+	}
+
+	pr_info(PREFIX "ACPI device name is <%s>, pin number is <%d>\n",
+		gpio_path, pin_number);
+
+	gpio_trigger_event(gpio_path, pin_number);
+
+out:
+	kfree(temp_buf_addr);
+	return count;
+}
+
+static acpi_status gpio_list_resource(struct acpi_resource *ares,
+					   void *context)
+{
+	struct acpi_resource_gpio *agpio;
+	struct seq_file *m = context;
+	int pin;
+
+	if (!m)
+		return AE_OK;
+
+	if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
+		return AE_OK;
+
+	agpio = &ares->data.gpio;
+	if (agpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_INT)
+		return AE_OK;
+
+	pin = agpio->pin_table[0];
+        seq_printf(m, "%s <-> pin %d\n", agpio->resource_source.string_ptr,
+        	   pin);
+
+	return AE_OK;
+}
+
+static acpi_status gpio_find_resource(acpi_handle handle, u32 lvl,
+					  void *context, void **rv)
+{
+	struct acpi_namespace_node *node;
+	struct seq_file *m = context;
+
+	if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__AEI,
+					gpio_list_resource, NULL)))
+		return AE_OK;
+
+	node = acpi_ns_validate_handle(handle);
+	if (!node) {
+		pr_err(PREFIX "Mapping GPIO handle to node failed\n");
+		return AE_OK;
+	}
+
+	seq_printf(m, "GPIO device name: %4.4s\nAvailable GPIO pin map:\n",
+		   ACPI_CAST_PTR(char, &node->name));
+	acpi_walk_resources(handle, METHOD_NAME__AEI, gpio_list_resource,
+			    context);
+	return AE_OK;
+}
+
+static int gpio_evt_show(struct seq_file *m, void *v)
+{
+	acpi_get_devices(NULL, gpio_find_resource, m, NULL);
+	return 0;
+}
+
+static int gpio_evt_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, gpio_evt_show, NULL);
+}
+
+static const struct file_operations gpio_evt_emu_fops = {
+	.open = gpio_evt_open,
+	.write = gpio_evt_write,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int __init gpio_evt_emu_init(void)
+{
+	if (acpi_debugfs_dir == NULL)
+		return -ENOENT;
+
+	gpio_evt_dentry = debugfs_create_file("gpio_event", S_IWUSR,
+				acpi_debugfs_dir, NULL, &gpio_evt_emu_fops);
+	if (gpio_evt_dentry == NULL)
+		return -ENODEV;
+
+	return 0;
+}
+
+device_initcall(gpio_evt_emu_init);
+ACPI_MODULE_NAME("acpi_evt_emu");
+MODULE_LICENSE("GPL");