Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Nicolas Boichat and committed by
Benson Leung
6e494106 73b44f40

+54
+54
drivers/platform/chrome/cros_ec_debugfs.c
··· 47 47 * @log_mutex: mutex to protect circular buffer 48 48 * @log_wq: waitqueue for log readers 49 49 * @log_poll_work: recurring task to poll EC for new console log data 50 + * @panicinfo_blob: panicinfo debugfs blob 50 51 */ 51 52 struct cros_ec_debugfs { 52 53 struct cros_ec_dev *ec; 53 54 struct dentry *dir; 55 + /* EC log */ 54 56 struct circ_buf log_buffer; 55 57 struct cros_ec_command *read_msg; 56 58 struct mutex log_mutex; 57 59 wait_queue_head_t log_wq; 58 60 struct delayed_work log_poll_work; 61 + /* EC panicinfo */ 62 + struct debugfs_blob_wrapper panicinfo_blob; 59 63 }; 60 64 61 65 /* ··· 312 308 } 313 309 } 314 310 311 + static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info) 312 + { 313 + struct cros_ec_device *ec_dev = debug_info->ec->ec_dev; 314 + int ret; 315 + struct cros_ec_command *msg; 316 + int insize; 317 + 318 + insize = ec_dev->max_response; 319 + 320 + msg = devm_kzalloc(debug_info->ec->dev, 321 + sizeof(*msg) + insize, GFP_KERNEL); 322 + if (!msg) 323 + return -ENOMEM; 324 + 325 + msg->command = EC_CMD_GET_PANIC_INFO; 326 + msg->insize = insize; 327 + 328 + ret = cros_ec_cmd_xfer(ec_dev, msg); 329 + if (ret < 0) { 330 + dev_warn(debug_info->ec->dev, "Cannot read panicinfo.\n"); 331 + ret = 0; 332 + goto free; 333 + } 334 + 335 + /* No panic data */ 336 + if (ret == 0) 337 + goto free; 338 + 339 + debug_info->panicinfo_blob.data = msg->data; 340 + debug_info->panicinfo_blob.size = ret; 341 + 342 + if (!debugfs_create_blob("panicinfo", 343 + S_IFREG | S_IRUGO, 344 + debug_info->dir, 345 + &debug_info->panicinfo_blob)) { 346 + ret = -ENOMEM; 347 + goto free; 348 + } 349 + 350 + return 0; 351 + 352 + free: 353 + devm_kfree(debug_info->ec->dev, msg); 354 + return ret; 355 + } 356 + 315 357 int cros_ec_debugfs_init(struct cros_ec_dev *ec) 316 358 { 317 359 struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev); ··· 373 323 debug_info->dir = debugfs_create_dir(name, NULL); 374 324 if (!debug_info->dir) 375 325 return -ENOMEM; 326 + 327 + ret = cros_ec_create_panicinfo(debug_info); 328 + if (ret) 329 + goto remove_debugfs; 376 330 377 331 ret = cros_ec_create_console_log(debug_info); 378 332 if (ret)