aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2017-05-16 11:46:48 -0400
committerBenson Leung <bleung@chromium.org>2017-06-16 16:57:45 -0400
commit6e4941067cef482c9ed254cf06cab70c32db05b2 (patch)
tree85dc68b480c186c5a4d9a7445005175c507bec9a
parent73b44f40c63bebcce9d66c4072878ecaceb43dda (diff)
mfd: cros_ec: Add support for dumping panic information
This dumps the EC panic information from the previous reboot. Similar to the information presented by ectool panicinfo, except that we do not bother doing any parsing (we should write a small offline tool for that). Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-by: Guenter Roeck <groeck@chromium.org> Tested-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Signed-off-by: Benson Leung <bleung@chromium.org>
-rw-r--r--drivers/platform/chrome/cros_ec_debugfs.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c
index c4150871b8ed..4cc66f405760 100644
--- a/drivers/platform/chrome/cros_ec_debugfs.c
+++ b/drivers/platform/chrome/cros_ec_debugfs.c
@@ -47,15 +47,19 @@
47 * @log_mutex: mutex to protect circular buffer 47 * @log_mutex: mutex to protect circular buffer
48 * @log_wq: waitqueue for log readers 48 * @log_wq: waitqueue for log readers
49 * @log_poll_work: recurring task to poll EC for new console log data 49 * @log_poll_work: recurring task to poll EC for new console log data
50 * @panicinfo_blob: panicinfo debugfs blob
50 */ 51 */
51struct cros_ec_debugfs { 52struct cros_ec_debugfs {
52 struct cros_ec_dev *ec; 53 struct cros_ec_dev *ec;
53 struct dentry *dir; 54 struct dentry *dir;
55 /* EC log */
54 struct circ_buf log_buffer; 56 struct circ_buf log_buffer;
55 struct cros_ec_command *read_msg; 57 struct cros_ec_command *read_msg;
56 struct mutex log_mutex; 58 struct mutex log_mutex;
57 wait_queue_head_t log_wq; 59 wait_queue_head_t log_wq;
58 struct delayed_work log_poll_work; 60 struct delayed_work log_poll_work;
61 /* EC panicinfo */
62 struct debugfs_blob_wrapper panicinfo_blob;
59}; 63};
60 64
61/* 65/*
@@ -308,6 +312,52 @@ static void cros_ec_cleanup_console_log(struct cros_ec_debugfs *debug_info)
308 } 312 }
309} 313}
310 314
315static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info)
316{
317 struct cros_ec_device *ec_dev = debug_info->ec->ec_dev;
318 int ret;
319 struct cros_ec_command *msg;
320 int insize;
321
322 insize = ec_dev->max_response;
323
324 msg = devm_kzalloc(debug_info->ec->dev,
325 sizeof(*msg) + insize, GFP_KERNEL);
326 if (!msg)
327 return -ENOMEM;
328
329 msg->command = EC_CMD_GET_PANIC_INFO;
330 msg->insize = insize;
331
332 ret = cros_ec_cmd_xfer(ec_dev, msg);
333 if (ret < 0) {
334 dev_warn(debug_info->ec->dev, "Cannot read panicinfo.\n");
335 ret = 0;
336 goto free;
337 }
338
339 /* No panic data */
340 if (ret == 0)
341 goto free;
342
343 debug_info->panicinfo_blob.data = msg->data;
344 debug_info->panicinfo_blob.size = ret;
345
346 if (!debugfs_create_blob("panicinfo",
347 S_IFREG | S_IRUGO,
348 debug_info->dir,
349 &debug_info->panicinfo_blob)) {
350 ret = -ENOMEM;
351 goto free;
352 }
353
354 return 0;
355
356free:
357 devm_kfree(debug_info->ec->dev, msg);
358 return ret;
359}
360
311int cros_ec_debugfs_init(struct cros_ec_dev *ec) 361int cros_ec_debugfs_init(struct cros_ec_dev *ec)
312{ 362{
313 struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev); 363 struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);
@@ -324,6 +374,10 @@ int cros_ec_debugfs_init(struct cros_ec_dev *ec)
324 if (!debug_info->dir) 374 if (!debug_info->dir)
325 return -ENOMEM; 375 return -ENOMEM;
326 376
377 ret = cros_ec_create_panicinfo(debug_info);
378 if (ret)
379 goto remove_debugfs;
380
327 ret = cros_ec_create_console_log(debug_info); 381 ret = cros_ec_create_console_log(debug_info);
328 if (ret) 382 if (ret)
329 goto remove_debugfs; 383 goto remove_debugfs;