summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/osl.c
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2015-12-02 21:43:14 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-12-14 18:17:44 -0500
commit836d0830188a97d5c73e8eb514f346a857c086b9 (patch)
treec2eb9b87cdf6a5096e8d3bf2d1418717b2023a10 /drivers/acpi/osl.c
parent37645d6590a49d3009eecdf093599795da2b5b41 (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>
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r--drivers/acpi/osl.c207
1 files changed, 201 insertions, 6 deletions
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}
223EXPORT_SYMBOL(acpi_os_printf);
224 224
225void acpi_os_vprintf(const char *fmt, va_list args) 225void 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
1107static struct acpi_debugger acpi_debugger;
1108static bool acpi_debugger_initialized;
1109
1110int 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
1124err_lock:
1125 mutex_unlock(&acpi_debugger.lock);
1126 return ret;
1127}
1128EXPORT_SYMBOL(acpi_register_debugger);
1129
1130void 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}
1139EXPORT_SYMBOL(acpi_unregister_debugger);
1140
1141int 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);
1166err_lock:
1167 mutex_unlock(&acpi_debugger.lock);
1168 return ret;
1169}
1170
1171ssize_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);
1196err_lock:
1197 mutex_unlock(&acpi_debugger.lock);
1198 return ret;
1199}
1200
1201ssize_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);
1226err_lock:
1227 mutex_unlock(&acpi_debugger.lock);
1228 return ret;
1229}
1230
1231int 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);
1257err_lock:
1258 mutex_unlock(&acpi_debugger.lock);
1259 return ret;
1260}
1261
1262int 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);
1287err_lock:
1288 mutex_unlock(&acpi_debugger.lock);
1289 return ret;
1290}
1291
1292int __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}
1586EXPORT_SYMBOL(acpi_os_get_line);
1392 1587
1393acpi_status acpi_os_wait_command_ready(void) 1588acpi_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;