diff options
-rw-r--r-- | drivers/acpi/Kconfig | 13 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 18 | ||||
-rw-r--r-- | drivers/acpi/ec_sys.c | 57 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 24 |
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 | ||
107 | config 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 | |||
107 | config ACPI_PROC_EVENT | 120 | config 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 | |||
60 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 60 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
61 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | 61 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o |
62 | obj-$(CONFIG_ACPI_HED) += hed.o | 62 | obj-$(CONFIG_ACPI_HED) += hed.o |
63 | obj-$(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 |
65 | processor-y := processor_driver.o processor_throttling.o | 66 | processor-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 | ||
107 | static struct acpi_ec { | 110 | struct acpi_ec *boot_ec, *first_ec; |
108 | acpi_handle handle; | 111 | EXPORT_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 | ||
121 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 113 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
122 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | 114 | static 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 | |||
6 | MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>"); | ||
7 | MODULE_DESCRIPTION("ACPI EC sysfs access driver"); | ||
8 | MODULE_LICENSE("GPL"); | ||
9 | |||
10 | struct sysdev_class acpi_ec_sysdev_class = { | ||
11 | .name = "ec", | ||
12 | }; | ||
13 | |||
14 | static struct dentry *acpi_ec_debugfs_dir; | ||
15 | |||
16 | int 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 | |||
41 | static 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 | |||
51 | static void __exit acpi_ec_sys_exit(void) | ||
52 | { | ||
53 | debugfs_remove_recursive(acpi_ec_debugfs_dir); | ||
54 | } | ||
55 | |||
56 | module_init(acpi_ec_sys_init); | ||
57 | module_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 | ||
23 | int init_acpi_device_notify(void); | 28 | int 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 | -------------------------------------------------------------------------- */ |
54 | struct 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 | |||
69 | extern struct acpi_ec *first_ec; | ||
70 | |||
49 | int acpi_ec_init(void); | 71 | int acpi_ec_init(void); |
50 | int acpi_ec_ecdt_probe(void); | 72 | int acpi_ec_ecdt_probe(void); |
51 | int acpi_boot_ec_enable(void); | 73 | int acpi_boot_ec_enable(void); |
@@ -63,3 +85,5 @@ int acpi_sleep_proc_init(void); | |||
63 | #else | 85 | #else |
64 | static inline int acpi_sleep_proc_init(void) { return 0; } | 86 | static inline int acpi_sleep_proc_init(void) { return 0; } |
65 | #endif | 87 | #endif |
88 | |||
89 | #endif /* _ACPI_INTERNAL_H_ */ | ||