diff options
author | Lv Zheng <lv.zheng@intel.com> | 2015-12-02 21:43:14 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-12-14 18:17:44 -0500 |
commit | 836d0830188a97d5c73e8eb514f346a857c086b9 (patch) | |
tree | c2eb9b87cdf6a5096e8d3bf2d1418717b2023a10 | |
parent | 37645d6590a49d3009eecdf093599795da2b5b41 (diff) |
ACPI / debugger: Add module support for ACPI debugger
This patch converts AML debugger into a loadable module.
Note that, it implements driver unloading at the level dependent on the
module reference count. Which means if ACPI debugger is being used by a
userspace program, "rmmod acpi_dbg" should result in failure.
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/Kconfig | 16 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/acpi_dbg.c | 80 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 3 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 207 | ||||
-rw-r--r-- | include/linux/acpi.h | 71 | ||||
-rw-r--r-- | include/linux/acpi_dbg.h | 52 |
7 files changed, 340 insertions, 91 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 2a7e6d4c3edc..82b96ee8624c 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -60,13 +60,23 @@ config ACPI_CCA_REQUIRED | |||
60 | config ACPI_DEBUGGER | 60 | config ACPI_DEBUGGER |
61 | bool "AML debugger interface" | 61 | bool "AML debugger interface" |
62 | select ACPI_DEBUG | 62 | select ACPI_DEBUG |
63 | depends on DEBUG_FS | ||
64 | help | 63 | help |
65 | Enable in-kernel debugging of AML facilities: statistics, internal | 64 | Enable in-kernel debugging of AML facilities: statistics, |
66 | object dump, single step control method execution. | 65 | internal object dump, single step control method execution. |
67 | This is still under development, currently enabling this only | 66 | This is still under development, currently enabling this only |
68 | results in the compilation of the ACPICA debugger files. | 67 | results in the compilation of the ACPICA debugger files. |
69 | 68 | ||
69 | if ACPI_DEBUGGER | ||
70 | |||
71 | config ACPI_DEBUGGER_USER | ||
72 | tristate "Userspace debugger accessiblity" | ||
73 | depends on DEBUG_FS | ||
74 | help | ||
75 | Export /sys/kernel/debug/acpi/acpidbg for userspace utilities | ||
76 | to access the debugger functionalities. | ||
77 | |||
78 | endif | ||
79 | |||
70 | config ACPI_SLEEP | 80 | config ACPI_SLEEP |
71 | bool | 81 | bool |
72 | depends on SUSPEND || HIBERNATION | 82 | depends on SUSPEND || HIBERNATION |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 102b5e610425..c6f236f1b510 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -50,7 +50,6 @@ acpi-y += sysfs.o | |||
50 | acpi-y += property.o | 50 | acpi-y += property.o |
51 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o | 51 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o |
52 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o | 52 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o |
53 | acpi-$(CONFIG_ACPI_DEBUGGER) += acpi_dbg.o | ||
54 | acpi-$(CONFIG_ACPI_NUMA) += numa.o | 53 | acpi-$(CONFIG_ACPI_NUMA) += numa.o |
55 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | 54 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o |
56 | acpi-y += acpi_lpat.o | 55 | acpi-y += acpi_lpat.o |
@@ -80,6 +79,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o | |||
80 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o | 79 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o |
81 | obj-$(CONFIG_ACPI_BGRT) += bgrt.o | 80 | obj-$(CONFIG_ACPI_BGRT) += bgrt.o |
82 | obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_acpi.o | 81 | obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_acpi.o |
82 | obj-$(CONFIG_ACPI_DEBUGGER_USER) += acpi_dbg.o | ||
83 | 83 | ||
84 | # processor has its own "processor." module_param namespace | 84 | # processor has its own "processor." module_param namespace |
85 | processor-y := processor_driver.o | 85 | processor-y := processor_driver.o |
diff --git a/drivers/acpi/acpi_dbg.c b/drivers/acpi/acpi_dbg.c index abc23b2fd5d3..381beb299bf7 100644 --- a/drivers/acpi/acpi_dbg.c +++ b/drivers/acpi/acpi_dbg.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/debugfs.h> | 22 | #include <linux/debugfs.h> |
23 | #include <linux/circ_buf.h> | 23 | #include <linux/circ_buf.h> |
24 | #include <linux/acpi_dbg.h> | 24 | #include <linux/acpi.h> |
25 | #include "internal.h" | 25 | #include "internal.h" |
26 | 26 | ||
27 | #define ACPI_AML_BUF_ALIGN (sizeof (acpi_size)) | 27 | #define ACPI_AML_BUF_ALIGN (sizeof (acpi_size)) |
@@ -307,7 +307,7 @@ static int acpi_aml_readb_kern(void) | |||
307 | * the debugger output and store the output into the debugger interface | 307 | * the debugger output and store the output into the debugger interface |
308 | * buffer. Return the size of stored logs or errno. | 308 | * buffer. Return the size of stored logs or errno. |
309 | */ | 309 | */ |
310 | ssize_t acpi_aml_write_log(const char *msg) | 310 | static ssize_t acpi_aml_write_log(const char *msg) |
311 | { | 311 | { |
312 | int ret = 0; | 312 | int ret = 0; |
313 | int count = 0, size = 0; | 313 | int count = 0, size = 0; |
@@ -337,7 +337,6 @@ again: | |||
337 | } | 337 | } |
338 | return size > 0 ? size : ret; | 338 | return size > 0 ? size : ret; |
339 | } | 339 | } |
340 | EXPORT_SYMBOL(acpi_aml_write_log); | ||
341 | 340 | ||
342 | /* | 341 | /* |
343 | * acpi_aml_read_cmd() - Capture debugger input | 342 | * acpi_aml_read_cmd() - Capture debugger input |
@@ -348,7 +347,7 @@ EXPORT_SYMBOL(acpi_aml_write_log); | |||
348 | * the debugger input commands and store the input commands into the | 347 | * the debugger input commands and store the input commands into the |
349 | * debugger interface buffer. Return the size of stored commands or errno. | 348 | * debugger interface buffer. Return the size of stored commands or errno. |
350 | */ | 349 | */ |
351 | ssize_t acpi_aml_read_cmd(char *msg, size_t count) | 350 | static ssize_t acpi_aml_read_cmd(char *msg, size_t count) |
352 | { | 351 | { |
353 | int ret = 0; | 352 | int ret = 0; |
354 | int size = 0; | 353 | int size = 0; |
@@ -390,7 +389,6 @@ again: | |||
390 | } | 389 | } |
391 | return size > 0 ? size : ret; | 390 | return size > 0 ? size : ret; |
392 | } | 391 | } |
393 | EXPORT_SYMBOL(acpi_aml_read_cmd); | ||
394 | 392 | ||
395 | static int acpi_aml_thread(void *unsed) | 393 | static int acpi_aml_thread(void *unsed) |
396 | { | 394 | { |
@@ -427,7 +425,7 @@ static int acpi_aml_thread(void *unsed) | |||
427 | * This function should be used to implement acpi_os_execute() which is | 425 | * This function should be used to implement acpi_os_execute() which is |
428 | * used by the ACPICA debugger to create the debugger thread. | 426 | * used by the ACPICA debugger to create the debugger thread. |
429 | */ | 427 | */ |
430 | int acpi_aml_create_thread(acpi_osd_exec_callback function, void *context) | 428 | static int acpi_aml_create_thread(acpi_osd_exec_callback function, void *context) |
431 | { | 429 | { |
432 | struct task_struct *t; | 430 | struct task_struct *t; |
433 | 431 | ||
@@ -449,30 +447,27 @@ int acpi_aml_create_thread(acpi_osd_exec_callback function, void *context) | |||
449 | mutex_unlock(&acpi_aml_io.lock); | 447 | mutex_unlock(&acpi_aml_io.lock); |
450 | return 0; | 448 | return 0; |
451 | } | 449 | } |
452 | EXPORT_SYMBOL(acpi_aml_create_thread); | ||
453 | 450 | ||
454 | int acpi_aml_wait_command_ready(void) | 451 | static int acpi_aml_wait_command_ready(bool single_step, |
452 | char *buffer, size_t length) | ||
455 | { | 453 | { |
456 | acpi_status status; | 454 | acpi_status status; |
457 | 455 | ||
458 | if (!acpi_gbl_method_executing) | 456 | if (single_step) |
459 | acpi_os_printf("\n%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); | ||
460 | else | ||
461 | acpi_os_printf("\n%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); | 457 | acpi_os_printf("\n%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT); |
458 | else | ||
459 | acpi_os_printf("\n%1c ", ACPI_DEBUGGER_COMMAND_PROMPT); | ||
462 | 460 | ||
463 | status = acpi_os_get_line(acpi_gbl_db_line_buf, | 461 | status = acpi_os_get_line(buffer, length, NULL); |
464 | ACPI_DB_LINE_BUFFER_SIZE, NULL); | ||
465 | if (ACPI_FAILURE(status)) | 462 | if (ACPI_FAILURE(status)) |
466 | return -EINVAL; | 463 | return -EINVAL; |
467 | return 0; | 464 | return 0; |
468 | } | 465 | } |
469 | EXPORT_SYMBOL(acpi_aml_wait_command_ready); | ||
470 | 466 | ||
471 | int acpi_aml_notify_command_complete(void) | 467 | static int acpi_aml_notify_command_complete(void) |
472 | { | 468 | { |
473 | return 0; | 469 | return 0; |
474 | } | 470 | } |
475 | EXPORT_SYMBOL(acpi_aml_notify_command_complete); | ||
476 | 471 | ||
477 | static int acpi_aml_open(struct inode *inode, struct file *file) | 472 | static int acpi_aml_open(struct inode *inode, struct file *file) |
478 | { | 473 | { |
@@ -746,10 +741,23 @@ static const struct file_operations acpi_aml_operations = { | |||
746 | .llseek = generic_file_llseek, | 741 | .llseek = generic_file_llseek, |
747 | }; | 742 | }; |
748 | 743 | ||
744 | static const struct acpi_debugger_ops acpi_aml_debugger = { | ||
745 | .create_thread = acpi_aml_create_thread, | ||
746 | .read_cmd = acpi_aml_read_cmd, | ||
747 | .write_log = acpi_aml_write_log, | ||
748 | .wait_command_ready = acpi_aml_wait_command_ready, | ||
749 | .notify_command_complete = acpi_aml_notify_command_complete, | ||
750 | }; | ||
751 | |||
749 | int __init acpi_aml_init(void) | 752 | int __init acpi_aml_init(void) |
750 | { | 753 | { |
751 | if (!acpi_debugfs_dir) | 754 | int ret = 0; |
752 | return -ENOENT; | 755 | |
756 | if (!acpi_debugfs_dir) { | ||
757 | ret = -ENOENT; | ||
758 | goto err_exit; | ||
759 | } | ||
760 | |||
753 | /* Initialize AML IO interface */ | 761 | /* Initialize AML IO interface */ |
754 | mutex_init(&acpi_aml_io.lock); | 762 | mutex_init(&acpi_aml_io.lock); |
755 | init_waitqueue_head(&acpi_aml_io.wait); | 763 | init_waitqueue_head(&acpi_aml_io.wait); |
@@ -759,21 +767,39 @@ int __init acpi_aml_init(void) | |||
759 | S_IFREG | S_IRUGO | S_IWUSR, | 767 | S_IFREG | S_IRUGO | S_IWUSR, |
760 | acpi_debugfs_dir, NULL, | 768 | acpi_debugfs_dir, NULL, |
761 | &acpi_aml_operations); | 769 | &acpi_aml_operations); |
762 | if (acpi_aml_dentry == NULL) | 770 | if (acpi_aml_dentry == NULL) { |
763 | return -ENODEV; | 771 | ret = -ENODEV; |
772 | goto err_exit; | ||
773 | } | ||
774 | ret = acpi_register_debugger(THIS_MODULE, &acpi_aml_debugger); | ||
775 | if (ret) | ||
776 | goto err_fs; | ||
764 | acpi_aml_initialized = true; | 777 | acpi_aml_initialized = true; |
765 | return 0; | 778 | |
779 | err_fs: | ||
780 | if (ret) { | ||
781 | debugfs_remove(acpi_aml_dentry); | ||
782 | acpi_aml_dentry = NULL; | ||
783 | } | ||
784 | err_exit: | ||
785 | return ret; | ||
766 | } | 786 | } |
767 | 787 | ||
768 | #if 0 | ||
769 | void __exit acpi_aml_exit(void) | 788 | void __exit acpi_aml_exit(void) |
770 | { | 789 | { |
771 | /* TODO: Stop the in kernel debugger */ | 790 | if (acpi_aml_initialized) { |
772 | if (acpi_aml_dentry) | 791 | acpi_unregister_debugger(&acpi_aml_debugger); |
773 | debugfs_remove(acpi_aml_dentry); | 792 | if (acpi_aml_dentry) { |
774 | acpi_aml_initialized = false; | 793 | debugfs_remove(acpi_aml_dentry); |
794 | acpi_aml_dentry = NULL; | ||
795 | } | ||
796 | acpi_aml_initialized = false; | ||
797 | } | ||
775 | } | 798 | } |
776 | 799 | ||
777 | module_init(acpi_aml_init); | 800 | module_init(acpi_aml_init); |
778 | module_exit(acpi_aml_exit); | 801 | module_exit(acpi_aml_exit); |
779 | #endif | 802 | |
803 | MODULE_AUTHOR("Lv Zheng"); | ||
804 | MODULE_DESCRIPTION("ACPI debugger userspace IO driver"); | ||
805 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 06fbba92099b..1a40111e1c86 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <acpi/apei.h> | 37 | #include <acpi/apei.h> |
38 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
39 | #include <linux/suspend.h> | 39 | #include <linux/suspend.h> |
40 | #include <linux/acpi_dbg.h> | ||
41 | 40 | ||
42 | #include "internal.h" | 41 | #include "internal.h" |
43 | 42 | ||
@@ -1095,7 +1094,7 @@ static int __init acpi_init(void) | |||
1095 | acpi_debugfs_init(); | 1094 | acpi_debugfs_init(); |
1096 | acpi_sleep_proc_init(); | 1095 | acpi_sleep_proc_init(); |
1097 | acpi_wakeup_device_init(); | 1096 | acpi_wakeup_device_init(); |
1098 | acpi_aml_init(); | 1097 | acpi_debugger_init(); |
1099 | return 0; | 1098 | return 0; |
1100 | } | 1099 | } |
1101 | 1100 | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 4c1339819bfc..bb66093b7799 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/list.h> | 40 | #include <linux/list.h> |
41 | #include <linux/jiffies.h> | 41 | #include <linux/jiffies.h> |
42 | #include <linux/semaphore.h> | 42 | #include <linux/semaphore.h> |
43 | #include <linux/acpi_dbg.h> | ||
44 | 43 | ||
45 | #include <asm/io.h> | 44 | #include <asm/io.h> |
46 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
@@ -221,6 +220,7 @@ void acpi_os_printf(const char *fmt, ...) | |||
221 | acpi_os_vprintf(fmt, args); | 220 | acpi_os_vprintf(fmt, args); |
222 | va_end(args); | 221 | va_end(args); |
223 | } | 222 | } |
223 | EXPORT_SYMBOL(acpi_os_printf); | ||
224 | 224 | ||
225 | void acpi_os_vprintf(const char *fmt, va_list args) | 225 | void acpi_os_vprintf(const char *fmt, va_list args) |
226 | { | 226 | { |
@@ -235,7 +235,7 @@ void acpi_os_vprintf(const char *fmt, va_list args) | |||
235 | printk(KERN_CONT "%s", buffer); | 235 | printk(KERN_CONT "%s", buffer); |
236 | } | 236 | } |
237 | #else | 237 | #else |
238 | if (acpi_aml_write_log(buffer) < 0) | 238 | if (acpi_debugger_write_log(buffer) < 0) |
239 | printk(KERN_CONT "%s", buffer); | 239 | printk(KERN_CONT "%s", buffer); |
240 | #endif | 240 | #endif |
241 | } | 241 | } |
@@ -1103,6 +1103,200 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
1103 | kfree(dpc); | 1103 | kfree(dpc); |
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | #ifdef CONFIG_ACPI_DEBUGGER | ||
1107 | static struct acpi_debugger acpi_debugger; | ||
1108 | static bool acpi_debugger_initialized; | ||
1109 | |||
1110 | int acpi_register_debugger(struct module *owner, | ||
1111 | const struct acpi_debugger_ops *ops) | ||
1112 | { | ||
1113 | int ret = 0; | ||
1114 | |||
1115 | mutex_lock(&acpi_debugger.lock); | ||
1116 | if (acpi_debugger.ops) { | ||
1117 | ret = -EBUSY; | ||
1118 | goto err_lock; | ||
1119 | } | ||
1120 | |||
1121 | acpi_debugger.owner = owner; | ||
1122 | acpi_debugger.ops = ops; | ||
1123 | |||
1124 | err_lock: | ||
1125 | mutex_unlock(&acpi_debugger.lock); | ||
1126 | return ret; | ||
1127 | } | ||
1128 | EXPORT_SYMBOL(acpi_register_debugger); | ||
1129 | |||
1130 | void acpi_unregister_debugger(const struct acpi_debugger_ops *ops) | ||
1131 | { | ||
1132 | mutex_lock(&acpi_debugger.lock); | ||
1133 | if (ops == acpi_debugger.ops) { | ||
1134 | acpi_debugger.ops = NULL; | ||
1135 | acpi_debugger.owner = NULL; | ||
1136 | } | ||
1137 | mutex_unlock(&acpi_debugger.lock); | ||
1138 | } | ||
1139 | EXPORT_SYMBOL(acpi_unregister_debugger); | ||
1140 | |||
1141 | int acpi_debugger_create_thread(acpi_osd_exec_callback function, void *context) | ||
1142 | { | ||
1143 | int ret; | ||
1144 | int (*func)(acpi_osd_exec_callback, void *); | ||
1145 | struct module *owner; | ||
1146 | |||
1147 | if (!acpi_debugger_initialized) | ||
1148 | return -ENODEV; | ||
1149 | mutex_lock(&acpi_debugger.lock); | ||
1150 | if (!acpi_debugger.ops) { | ||
1151 | ret = -ENODEV; | ||
1152 | goto err_lock; | ||
1153 | } | ||
1154 | if (!try_module_get(acpi_debugger.owner)) { | ||
1155 | ret = -ENODEV; | ||
1156 | goto err_lock; | ||
1157 | } | ||
1158 | func = acpi_debugger.ops->create_thread; | ||
1159 | owner = acpi_debugger.owner; | ||
1160 | mutex_unlock(&acpi_debugger.lock); | ||
1161 | |||
1162 | ret = func(function, context); | ||
1163 | |||
1164 | mutex_lock(&acpi_debugger.lock); | ||
1165 | module_put(owner); | ||
1166 | err_lock: | ||
1167 | mutex_unlock(&acpi_debugger.lock); | ||
1168 | return ret; | ||
1169 | } | ||
1170 | |||
1171 | ssize_t acpi_debugger_write_log(const char *msg) | ||
1172 | { | ||
1173 | ssize_t ret; | ||
1174 | ssize_t (*func)(const char *); | ||
1175 | struct module *owner; | ||
1176 | |||
1177 | if (!acpi_debugger_initialized) | ||
1178 | return -ENODEV; | ||
1179 | mutex_lock(&acpi_debugger.lock); | ||
1180 | if (!acpi_debugger.ops) { | ||
1181 | ret = -ENODEV; | ||
1182 | goto err_lock; | ||
1183 | } | ||
1184 | if (!try_module_get(acpi_debugger.owner)) { | ||
1185 | ret = -ENODEV; | ||
1186 | goto err_lock; | ||
1187 | } | ||
1188 | func = acpi_debugger.ops->write_log; | ||
1189 | owner = acpi_debugger.owner; | ||
1190 | mutex_unlock(&acpi_debugger.lock); | ||
1191 | |||
1192 | ret = func(msg); | ||
1193 | |||
1194 | mutex_lock(&acpi_debugger.lock); | ||
1195 | module_put(owner); | ||
1196 | err_lock: | ||
1197 | mutex_unlock(&acpi_debugger.lock); | ||
1198 | return ret; | ||
1199 | } | ||
1200 | |||
1201 | ssize_t acpi_debugger_read_cmd(char *buffer, size_t buffer_length) | ||
1202 | { | ||
1203 | ssize_t ret; | ||
1204 | ssize_t (*func)(char *, size_t); | ||
1205 | struct module *owner; | ||
1206 | |||
1207 | if (!acpi_debugger_initialized) | ||
1208 | return -ENODEV; | ||
1209 | mutex_lock(&acpi_debugger.lock); | ||
1210 | if (!acpi_debugger.ops) { | ||
1211 | ret = -ENODEV; | ||
1212 | goto err_lock; | ||
1213 | } | ||
1214 | if (!try_module_get(acpi_debugger.owner)) { | ||
1215 | ret = -ENODEV; | ||
1216 | goto err_lock; | ||
1217 | } | ||
1218 | func = acpi_debugger.ops->read_cmd; | ||
1219 | owner = acpi_debugger.owner; | ||
1220 | mutex_unlock(&acpi_debugger.lock); | ||
1221 | |||
1222 | ret = func(buffer, buffer_length); | ||
1223 | |||
1224 | mutex_lock(&acpi_debugger.lock); | ||
1225 | module_put(owner); | ||
1226 | err_lock: | ||
1227 | mutex_unlock(&acpi_debugger.lock); | ||
1228 | return ret; | ||
1229 | } | ||
1230 | |||
1231 | int acpi_debugger_wait_command_ready(void) | ||
1232 | { | ||
1233 | int ret; | ||
1234 | int (*func)(bool, char *, size_t); | ||
1235 | struct module *owner; | ||
1236 | |||
1237 | if (!acpi_debugger_initialized) | ||
1238 | return -ENODEV; | ||
1239 | mutex_lock(&acpi_debugger.lock); | ||
1240 | if (!acpi_debugger.ops) { | ||
1241 | ret = -ENODEV; | ||
1242 | goto err_lock; | ||
1243 | } | ||
1244 | if (!try_module_get(acpi_debugger.owner)) { | ||
1245 | ret = -ENODEV; | ||
1246 | goto err_lock; | ||
1247 | } | ||
1248 | func = acpi_debugger.ops->wait_command_ready; | ||
1249 | owner = acpi_debugger.owner; | ||
1250 | mutex_unlock(&acpi_debugger.lock); | ||
1251 | |||
1252 | ret = func(acpi_gbl_method_executing, | ||
1253 | acpi_gbl_db_line_buf, ACPI_DB_LINE_BUFFER_SIZE); | ||
1254 | |||
1255 | mutex_lock(&acpi_debugger.lock); | ||
1256 | module_put(owner); | ||
1257 | err_lock: | ||
1258 | mutex_unlock(&acpi_debugger.lock); | ||
1259 | return ret; | ||
1260 | } | ||
1261 | |||
1262 | int acpi_debugger_notify_command_complete(void) | ||
1263 | { | ||
1264 | int ret; | ||
1265 | int (*func)(void); | ||
1266 | struct module *owner; | ||
1267 | |||
1268 | if (!acpi_debugger_initialized) | ||
1269 | return -ENODEV; | ||
1270 | mutex_lock(&acpi_debugger.lock); | ||
1271 | if (!acpi_debugger.ops) { | ||
1272 | ret = -ENODEV; | ||
1273 | goto err_lock; | ||
1274 | } | ||
1275 | if (!try_module_get(acpi_debugger.owner)) { | ||
1276 | ret = -ENODEV; | ||
1277 | goto err_lock; | ||
1278 | } | ||
1279 | func = acpi_debugger.ops->notify_command_complete; | ||
1280 | owner = acpi_debugger.owner; | ||
1281 | mutex_unlock(&acpi_debugger.lock); | ||
1282 | |||
1283 | ret = func(); | ||
1284 | |||
1285 | mutex_lock(&acpi_debugger.lock); | ||
1286 | module_put(owner); | ||
1287 | err_lock: | ||
1288 | mutex_unlock(&acpi_debugger.lock); | ||
1289 | return ret; | ||
1290 | } | ||
1291 | |||
1292 | int __init acpi_debugger_init(void) | ||
1293 | { | ||
1294 | mutex_init(&acpi_debugger.lock); | ||
1295 | acpi_debugger_initialized = true; | ||
1296 | return 0; | ||
1297 | } | ||
1298 | #endif | ||
1299 | |||
1106 | /******************************************************************************* | 1300 | /******************************************************************************* |
1107 | * | 1301 | * |
1108 | * FUNCTION: acpi_os_execute | 1302 | * FUNCTION: acpi_os_execute |
@@ -1130,7 +1324,7 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
1130 | function, context)); | 1324 | function, context)); |
1131 | 1325 | ||
1132 | if (type == OSL_DEBUGGER_MAIN_THREAD) { | 1326 | if (type == OSL_DEBUGGER_MAIN_THREAD) { |
1133 | ret = acpi_aml_create_thread(function, context); | 1327 | ret = acpi_debugger_create_thread(function, context); |
1134 | if (ret) { | 1328 | if (ret) { |
1135 | pr_err("Call to kthread_create() failed.\n"); | 1329 | pr_err("Call to kthread_create() failed.\n"); |
1136 | status = AE_ERROR; | 1330 | status = AE_ERROR; |
@@ -1380,7 +1574,7 @@ acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read) | |||
1380 | #else | 1574 | #else |
1381 | int ret; | 1575 | int ret; |
1382 | 1576 | ||
1383 | ret = acpi_aml_read_cmd(buffer, buffer_length); | 1577 | ret = acpi_debugger_read_cmd(buffer, buffer_length); |
1384 | if (ret < 0) | 1578 | if (ret < 0) |
1385 | return AE_ERROR; | 1579 | return AE_ERROR; |
1386 | if (bytes_read) | 1580 | if (bytes_read) |
@@ -1389,12 +1583,13 @@ acpi_status acpi_os_get_line(char *buffer, u32 buffer_length, u32 *bytes_read) | |||
1389 | 1583 | ||
1390 | return AE_OK; | 1584 | return AE_OK; |
1391 | } | 1585 | } |
1586 | EXPORT_SYMBOL(acpi_os_get_line); | ||
1392 | 1587 | ||
1393 | acpi_status acpi_os_wait_command_ready(void) | 1588 | acpi_status acpi_os_wait_command_ready(void) |
1394 | { | 1589 | { |
1395 | int ret; | 1590 | int ret; |
1396 | 1591 | ||
1397 | ret = acpi_aml_wait_command_ready(); | 1592 | ret = acpi_debugger_wait_command_ready(); |
1398 | if (ret < 0) | 1593 | if (ret < 0) |
1399 | return AE_ERROR; | 1594 | return AE_ERROR; |
1400 | return AE_OK; | 1595 | return AE_OK; |
@@ -1404,7 +1599,7 @@ acpi_status acpi_os_notify_command_complete(void) | |||
1404 | { | 1599 | { |
1405 | int ret; | 1600 | int ret; |
1406 | 1601 | ||
1407 | ret = acpi_aml_notify_command_complete(); | 1602 | ret = acpi_debugger_notify_command_complete(); |
1408 | if (ret < 0) | 1603 | if (ret < 0) |
1409 | return AE_ERROR; | 1604 | return AE_ERROR; |
1410 | return AE_OK; | 1605 | return AE_OK; |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 1991aea2ec4c..a03a05474527 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/list.h> | 37 | #include <linux/list.h> |
38 | #include <linux/mod_devicetable.h> | 38 | #include <linux/mod_devicetable.h> |
39 | #include <linux/dynamic_debug.h> | 39 | #include <linux/dynamic_debug.h> |
40 | #include <linux/module.h> | ||
41 | #include <linux/mutex.h> | ||
40 | 42 | ||
41 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
42 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
@@ -119,6 +121,75 @@ typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table); | |||
119 | typedef int (*acpi_tbl_entry_handler)(struct acpi_subtable_header *header, | 121 | typedef int (*acpi_tbl_entry_handler)(struct acpi_subtable_header *header, |
120 | const unsigned long end); | 122 | const unsigned long end); |
121 | 123 | ||
124 | /* Debugger support */ | ||
125 | |||
126 | struct acpi_debugger_ops { | ||
127 | int (*create_thread)(acpi_osd_exec_callback function, void *context); | ||
128 | ssize_t (*write_log)(const char *msg); | ||
129 | ssize_t (*read_cmd)(char *buffer, size_t length); | ||
130 | int (*wait_command_ready)(bool single_step, char *buffer, size_t length); | ||
131 | int (*notify_command_complete)(void); | ||
132 | }; | ||
133 | |||
134 | struct acpi_debugger { | ||
135 | const struct acpi_debugger_ops *ops; | ||
136 | struct module *owner; | ||
137 | struct mutex lock; | ||
138 | }; | ||
139 | |||
140 | #ifdef CONFIG_ACPI_DEBUGGER | ||
141 | int __init acpi_debugger_init(void); | ||
142 | int acpi_register_debugger(struct module *owner, | ||
143 | const struct acpi_debugger_ops *ops); | ||
144 | void acpi_unregister_debugger(const struct acpi_debugger_ops *ops); | ||
145 | int acpi_debugger_create_thread(acpi_osd_exec_callback function, void *context); | ||
146 | ssize_t acpi_debugger_write_log(const char *msg); | ||
147 | ssize_t acpi_debugger_read_cmd(char *buffer, size_t buffer_length); | ||
148 | int acpi_debugger_wait_command_ready(void); | ||
149 | int acpi_debugger_notify_command_complete(void); | ||
150 | #else | ||
151 | static inline int acpi_debugger_init(void) | ||
152 | { | ||
153 | return -ENODEV; | ||
154 | } | ||
155 | |||
156 | static inline int acpi_register_debugger(struct module *owner, | ||
157 | const struct acpi_debugger_ops *ops) | ||
158 | { | ||
159 | return -ENODEV; | ||
160 | } | ||
161 | |||
162 | static inline void acpi_unregister_debugger(const struct acpi_debugger_ops *ops) | ||
163 | { | ||
164 | } | ||
165 | |||
166 | static inline int acpi_debugger_create_thread(acpi_osd_exec_callback function, | ||
167 | void *context) | ||
168 | { | ||
169 | return -ENODEV; | ||
170 | } | ||
171 | |||
172 | static inline int acpi_debugger_write_log(const char *msg) | ||
173 | { | ||
174 | return -ENODEV; | ||
175 | } | ||
176 | |||
177 | static inline int acpi_debugger_read_cmd(char *buffer, u32 buffer_length) | ||
178 | { | ||
179 | return -ENODEV; | ||
180 | } | ||
181 | |||
182 | static inline int acpi_debugger_wait_command_ready(void) | ||
183 | { | ||
184 | return -ENODEV; | ||
185 | } | ||
186 | |||
187 | static inline int acpi_debugger_notify_command_complete(void) | ||
188 | { | ||
189 | return -ENODEV; | ||
190 | } | ||
191 | #endif | ||
192 | |||
122 | #ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE | 193 | #ifdef CONFIG_ACPI_INITRD_TABLE_OVERRIDE |
123 | void acpi_initrd_override(void *data, size_t size); | 194 | void acpi_initrd_override(void *data, size_t size); |
124 | #else | 195 | #else |
diff --git a/include/linux/acpi_dbg.h b/include/linux/acpi_dbg.h deleted file mode 100644 index 60f3887ed816..000000000000 --- a/include/linux/acpi_dbg.h +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * ACPI AML interfacing support | ||
3 | * | ||
4 | * Copyright (C) 2015, Intel Corporation | ||
5 | * Authors: Lv Zheng <lv.zheng@intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _LINUX_ACPI_DBG_H | ||
13 | #define _LINUX_ACPI_DBG_H | ||
14 | |||
15 | #include <linux/acpi.h> | ||
16 | |||
17 | #ifdef CONFIG_ACPI_DEBUGGER | ||
18 | int __init acpi_aml_init(void); | ||
19 | int acpi_aml_create_thread(acpi_osd_exec_callback function, void *context); | ||
20 | ssize_t acpi_aml_write_log(const char *msg); | ||
21 | ssize_t acpi_aml_read_cmd(char *buffer, size_t buffer_length); | ||
22 | int acpi_aml_wait_command_ready(void); | ||
23 | int acpi_aml_notify_command_complete(void); | ||
24 | #else | ||
25 | static int inline acpi_aml_init(void) | ||
26 | { | ||
27 | return 0; | ||
28 | } | ||
29 | static inline int acpi_aml_create_thread(acpi_osd_exec_callback function, | ||
30 | void *context) | ||
31 | { | ||
32 | return -ENODEV; | ||
33 | } | ||
34 | static inline int acpi_aml_write_log(const char *msg) | ||
35 | { | ||
36 | return -ENODEV; | ||
37 | } | ||
38 | static inline int acpi_aml_read_cmd(char *buffer, u32 buffer_length) | ||
39 | { | ||
40 | return -ENODEV; | ||
41 | } | ||
42 | static inline int acpi_aml_wait_command_ready(void) | ||
43 | { | ||
44 | return -ENODEV; | ||
45 | } | ||
46 | static inline int acpi_aml_notify_command_complete(void) | ||
47 | { | ||
48 | return -ENODEV; | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | #endif /* _LINUX_ACPI_DBG_H */ | ||