aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/Kconfig13
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ec.c18
-rw-r--r--drivers/acpi/ec_sys.c57
-rw-r--r--drivers/acpi/internal.h24
5 files changed, 100 insertions, 13 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 746411518802..f7226d1bc80e 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -104,6 +104,19 @@ config ACPI_SYSFS_POWER
104 help 104 help
105 Say N to disable power /sys interface 105 Say N to disable power /sys interface
106 106
107config ACPI_EC_DEBUGFS
108 tristate "EC read/write access through /sys/kernel/debug/ec"
109 default y
110 help
111 Say N to disable Embedded Controller /sys/kernel/debug interface
112
113 An Embedded Controller typically is available on laptops and reads
114 sensor values like battery state and temperature.
115 The kernel access the EC through ACPI parsed code provided by BIOS
116 tables.
117 Thus this option is a debug option that helps to write ACPI drivers
118 and can be used to identify ACPI code or EC firmware bugs.
119
107config ACPI_PROC_EVENT 120config ACPI_PROC_EVENT
108 bool "Deprecated /proc/acpi/event support" 121 bool "Deprecated /proc/acpi/event support"
109 depends on PROC_FS 122 depends on PROC_FS
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 6ee33169e1dc..833b582d1762 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_ACPI_SBS) += sbshc.o
60obj-$(CONFIG_ACPI_SBS) += sbs.o 60obj-$(CONFIG_ACPI_SBS) += sbs.o
61obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o 61obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o
62obj-$(CONFIG_ACPI_HED) += hed.o 62obj-$(CONFIG_ACPI_HED) += hed.o
63obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
63 64
64# processor has its own "processor." module_param namespace 65# processor has its own "processor." module_param namespace
65processor-y := processor_driver.o processor_throttling.o 66processor-y := processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index ce1f07fd7241..a79e1b193e85 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -43,10 +43,13 @@
43#include <acpi/acpi_drivers.h> 43#include <acpi/acpi_drivers.h>
44#include <linux/dmi.h> 44#include <linux/dmi.h>
45 45
46#include "internal.h"
47
46#define ACPI_EC_CLASS "embedded_controller" 48#define ACPI_EC_CLASS "embedded_controller"
47#define ACPI_EC_DEVICE_NAME "Embedded Controller" 49#define ACPI_EC_DEVICE_NAME "Embedded Controller"
48#define ACPI_EC_FILE_INFO "info" 50#define ACPI_EC_FILE_INFO "info"
49 51
52#undef PREFIX
50#define PREFIX "ACPI: EC: " 53#define PREFIX "ACPI: EC: "
51 54
52/* EC status register */ 55/* EC status register */
@@ -104,19 +107,8 @@ struct transaction {
104 bool done; 107 bool done;
105}; 108};
106 109
107static struct acpi_ec { 110struct acpi_ec *boot_ec, *first_ec;
108 acpi_handle handle; 111EXPORT_SYMBOL(first_ec);
109 unsigned long gpe;
110 unsigned long command_addr;
111 unsigned long data_addr;
112 unsigned long global_lock;
113 unsigned long flags;
114 struct mutex lock;
115 wait_queue_head_t wait;
116 struct list_head list;
117 struct transaction *curr;
118 spinlock_t curr_lock;
119} *boot_ec, *first_ec;
120 112
121static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ 113static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
122static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ 114static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
new file mode 100644
index 000000000000..834c21a42d67
--- /dev/null
+++ b/drivers/acpi/ec_sys.c
@@ -0,0 +1,57 @@
1#include <linux/kernel.h>
2#include <linux/acpi.h>
3#include <linux/debugfs.h>
4#include "internal.h"
5
6MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
7MODULE_DESCRIPTION("ACPI EC sysfs access driver");
8MODULE_LICENSE("GPL");
9
10struct sysdev_class acpi_ec_sysdev_class = {
11 .name = "ec",
12};
13
14static struct dentry *acpi_ec_debugfs_dir;
15
16int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count)
17{
18 struct dentry *dev_dir;
19 char name[64];
20 if (ec_device_count == 0) {
21 acpi_ec_debugfs_dir = debugfs_create_dir("ec", NULL);
22 if (!acpi_ec_debugfs_dir)
23 return -ENOMEM;
24 }
25
26 sprintf(name, "ec%u", ec_device_count);
27 dev_dir = debugfs_create_dir(name, acpi_ec_debugfs_dir);
28 if (!dev_dir) {
29 if (ec_device_count == 0)
30 debugfs_remove_recursive(acpi_ec_debugfs_dir);
31 /* TBD: Proper cleanup for multiple ECs */
32 return -ENOMEM;
33 }
34
35 debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe);
36 debugfs_create_bool("use_global_lock", 0444, dev_dir,
37 (u32 *)&first_ec->global_lock);
38 return 0;
39}
40
41static int __init acpi_ec_sys_init(void)
42{
43 int err = 0;
44 if (first_ec)
45 err = acpi_ec_add_debugfs(first_ec, 0);
46 else
47 err = -ENODEV;
48 return err;
49}
50
51static void __exit acpi_ec_sys_exit(void)
52{
53 debugfs_remove_recursive(acpi_ec_debugfs_dir);
54}
55
56module_init(acpi_ec_sys_init);
57module_exit(acpi_ec_sys_exit);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index f8f190ec066e..8ae27264a00e 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -18,6 +18,11 @@
18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 */ 19 */
20 20
21#ifndef _ACPI_INTERNAL_H_
22#define _ACPI_INTERNAL_H_
23
24#include <linux/sysdev.h>
25
21#define PREFIX "ACPI: " 26#define PREFIX "ACPI: "
22 27
23int init_acpi_device_notify(void); 28int init_acpi_device_notify(void);
@@ -46,6 +51,23 @@ void acpi_early_processor_set_pdc(void);
46/* -------------------------------------------------------------------------- 51/* --------------------------------------------------------------------------
47 Embedded Controller 52 Embedded Controller
48 -------------------------------------------------------------------------- */ 53 -------------------------------------------------------------------------- */
54struct acpi_ec {
55 acpi_handle handle;
56 unsigned long gpe;
57 unsigned long command_addr;
58 unsigned long data_addr;
59 unsigned long global_lock;
60 unsigned long flags;
61 struct mutex lock;
62 wait_queue_head_t wait;
63 struct list_head list;
64 struct transaction *curr;
65 spinlock_t curr_lock;
66 struct sys_device sysdev;
67};
68
69extern struct acpi_ec *first_ec;
70
49int acpi_ec_init(void); 71int acpi_ec_init(void);
50int acpi_ec_ecdt_probe(void); 72int acpi_ec_ecdt_probe(void);
51int acpi_boot_ec_enable(void); 73int acpi_boot_ec_enable(void);
@@ -63,3 +85,5 @@ int acpi_sleep_proc_init(void);
63#else 85#else
64static inline int acpi_sleep_proc_init(void) { return 0; } 86static inline int acpi_sleep_proc_init(void) { return 0; }
65#endif 87#endif
88
89#endif /* _ACPI_INTERNAL_H_ */