xref: /linux/drivers/platform/chrome/cros_ec_debugfs.c (revision 96a6de1a541c86e9e67b9c310c14db4099bd1cbc)
1 /*
2  * cros_ec_debugfs - debug logs for Chrome OS EC
3  *
4  * Copyright 2015 Google, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <linux/circ_buf.h>
21 #include <linux/debugfs.h>
22 #include <linux/delay.h>
23 #include <linux/fs.h>
24 #include <linux/mfd/cros_ec.h>
25 #include <linux/mfd/cros_ec_commands.h>
26 #include <linux/module.h>
27 #include <linux/mutex.h>
28 #include <linux/platform_device.h>
29 #include <linux/poll.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h>
32 #include <linux/wait.h>
33 
34 #define DRV_NAME "cros-ec-debugfs"
35 
36 #define LOG_SHIFT		14
37 #define LOG_SIZE		(1 << LOG_SHIFT)
38 #define LOG_POLL_SEC		10
39 
40 #define CIRC_ADD(idx, size, value)	(((idx) + (value)) & ((size) - 1))
41 
42 /* struct cros_ec_debugfs - ChromeOS EC debugging information
43  *
44  * @ec: EC device this debugfs information belongs to
45  * @dir: dentry for debugfs files
46  * @log_buffer: circular buffer for console log information
47  * @read_msg: preallocated EC command and buffer to read console log
48  * @log_mutex: mutex to protect circular buffer
49  * @log_wq: waitqueue for log readers
50  * @log_poll_work: recurring task to poll EC for new console log data
51  * @panicinfo_blob: panicinfo debugfs blob
52  */
53 struct cros_ec_debugfs {
54 	struct cros_ec_dev *ec;
55 	struct dentry *dir;
56 	/* EC log */
57 	struct circ_buf log_buffer;
58 	struct cros_ec_command *read_msg;
59 	struct mutex log_mutex;
60 	wait_queue_head_t log_wq;
61 	struct delayed_work log_poll_work;
62 	/* EC panicinfo */
63 	struct debugfs_blob_wrapper panicinfo_blob;
64 };
65 
66 /*
67  * We need to make sure that the EC log buffer on the UART is large enough,
68  * so that it is unlikely enough to overlow within LOG_POLL_SEC.
69  */
70 static void cros_ec_console_log_work(struct work_struct *__work)
71 {
72 	struct cros_ec_debugfs *debug_info =
73 		container_of(to_delayed_work(__work),
74 			     struct cros_ec_debugfs,
75 			     log_poll_work);
76 	struct cros_ec_dev *ec = debug_info->ec;
77 	struct circ_buf *cb = &debug_info->log_buffer;
78 	struct cros_ec_command snapshot_msg = {
79 		.command = EC_CMD_CONSOLE_SNAPSHOT + ec->cmd_offset,
80 	};
81 
82 	struct ec_params_console_read_v1 *read_params =
83 		(struct ec_params_console_read_v1 *)debug_info->read_msg->data;
84 	uint8_t *ec_buffer = (uint8_t *)debug_info->read_msg->data;
85 	int idx;
86 	int buf_space;
87 	int ret;
88 
89 	ret = cros_ec_cmd_xfer(ec->ec_dev, &snapshot_msg);
90 	if (ret < 0) {
91 		dev_err(ec->dev, "EC communication failed\n");
92 		goto resched;
93 	}
94 	if (snapshot_msg.result != EC_RES_SUCCESS) {
95 		dev_err(ec->dev, "EC failed to snapshot the console log\n");
96 		goto resched;
97 	}
98 
99 	/* Loop until we have read everything, or there's an error. */
100 	mutex_lock(&debug_info->log_mutex);
101 	buf_space = CIRC_SPACE(cb->head, cb->tail, LOG_SIZE);
102 
103 	while (1) {
104 		if (!buf_space) {
105 			dev_info_once(ec->dev,
106 				      "Some logs may have been dropped...\n");
107 			break;
108 		}
109 
110 		memset(read_params, '\0', sizeof(*read_params));
111 		read_params->subcmd = CONSOLE_READ_RECENT;
112 		ret = cros_ec_cmd_xfer(ec->ec_dev, debug_info->read_msg);
113 		if (ret < 0) {
114 			dev_err(ec->dev, "EC communication failed\n");
115 			break;
116 		}
117 		if (debug_info->read_msg->result != EC_RES_SUCCESS) {
118 			dev_err(ec->dev,
119 				"EC failed to read the console log\n");
120 			break;
121 		}
122 
123 		/* If the buffer is empty, we're done here. */
124 		if (ret == 0 || ec_buffer[0] == '\0')
125 			break;
126 
127 		idx = 0;
128 		while (idx < ret && ec_buffer[idx] != '\0' && buf_space > 0) {
129 			cb->buf[cb->head] = ec_buffer[idx];
130 			cb->head = CIRC_ADD(cb->head, LOG_SIZE, 1);
131 			idx++;
132 			buf_space--;
133 		}
134 
135 		wake_up(&debug_info->log_wq);
136 	}
137 
138 	mutex_unlock(&debug_info->log_mutex);
139 
140 resched:
141 	schedule_delayed_work(&debug_info->log_poll_work,
142 			      msecs_to_jiffies(LOG_POLL_SEC * 1000));
143 }
144 
145 static int cros_ec_console_log_open(struct inode *inode, struct file *file)
146 {
147 	file->private_data = inode->i_private;
148 
149 	return nonseekable_open(inode, file);
150 }
151 
152 static ssize_t cros_ec_console_log_read(struct file *file, char __user *buf,
153 					size_t count, loff_t *ppos)
154 {
155 	struct cros_ec_debugfs *debug_info = file->private_data;
156 	struct circ_buf *cb = &debug_info->log_buffer;
157 	ssize_t ret;
158 
159 	mutex_lock(&debug_info->log_mutex);
160 
161 	while (!CIRC_CNT(cb->head, cb->tail, LOG_SIZE)) {
162 		if (file->f_flags & O_NONBLOCK) {
163 			ret = -EAGAIN;
164 			goto error;
165 		}
166 
167 		mutex_unlock(&debug_info->log_mutex);
168 
169 		ret = wait_event_interruptible(debug_info->log_wq,
170 					CIRC_CNT(cb->head, cb->tail, LOG_SIZE));
171 		if (ret < 0)
172 			return ret;
173 
174 		mutex_lock(&debug_info->log_mutex);
175 	}
176 
177 	/* Only copy until the end of the circular buffer, and let userspace
178 	 * retry to get the rest of the data.
179 	 */
180 	ret = min_t(size_t, CIRC_CNT_TO_END(cb->head, cb->tail, LOG_SIZE),
181 		    count);
182 
183 	if (copy_to_user(buf, cb->buf + cb->tail, ret)) {
184 		ret = -EFAULT;
185 		goto error;
186 	}
187 
188 	cb->tail = CIRC_ADD(cb->tail, LOG_SIZE, ret);
189 
190 error:
191 	mutex_unlock(&debug_info->log_mutex);
192 	return ret;
193 }
194 
195 static __poll_t cros_ec_console_log_poll(struct file *file,
196 					     poll_table *wait)
197 {
198 	struct cros_ec_debugfs *debug_info = file->private_data;
199 	__poll_t mask = 0;
200 
201 	poll_wait(file, &debug_info->log_wq, wait);
202 
203 	mutex_lock(&debug_info->log_mutex);
204 	if (CIRC_CNT(debug_info->log_buffer.head,
205 		     debug_info->log_buffer.tail,
206 		     LOG_SIZE))
207 		mask |= EPOLLIN | EPOLLRDNORM;
208 	mutex_unlock(&debug_info->log_mutex);
209 
210 	return mask;
211 }
212 
213 static int cros_ec_console_log_release(struct inode *inode, struct file *file)
214 {
215 	return 0;
216 }
217 
218 static ssize_t cros_ec_pdinfo_read(struct file *file,
219 				   char __user *user_buf,
220 				   size_t count,
221 				   loff_t *ppos)
222 {
223 	char read_buf[EC_USB_PD_MAX_PORTS * 40], *p = read_buf;
224 	struct cros_ec_debugfs *debug_info = file->private_data;
225 	struct cros_ec_device *ec_dev = debug_info->ec->ec_dev;
226 	struct {
227 		struct cros_ec_command msg;
228 		union {
229 			struct ec_response_usb_pd_control_v1 resp;
230 			struct ec_params_usb_pd_control params;
231 		};
232 	} __packed ec_buf;
233 	struct cros_ec_command *msg;
234 	struct ec_response_usb_pd_control_v1 *resp;
235 	struct ec_params_usb_pd_control *params;
236 	int i;
237 
238 	msg = &ec_buf.msg;
239 	params = (struct ec_params_usb_pd_control *)msg->data;
240 	resp = (struct ec_response_usb_pd_control_v1 *)msg->data;
241 
242 	msg->command = EC_CMD_USB_PD_CONTROL;
243 	msg->version = 1;
244 	msg->insize = sizeof(*resp);
245 	msg->outsize = sizeof(*params);
246 
247 	/*
248 	 * Read status from all PD ports until failure, typically caused
249 	 * by attempting to read status on a port that doesn't exist.
250 	 */
251 	for (i = 0; i < EC_USB_PD_MAX_PORTS; ++i) {
252 		params->port = i;
253 		params->role = 0;
254 		params->mux = 0;
255 		params->swap = 0;
256 
257 		if (cros_ec_cmd_xfer_status(ec_dev, msg) < 0)
258 			break;
259 
260 		p += scnprintf(p, sizeof(read_buf) + read_buf - p,
261 			       "p%d: %s en:%.2x role:%.2x pol:%.2x\n", i,
262 			       resp->state, resp->enabled, resp->role,
263 			       resp->polarity);
264 	}
265 
266 	return simple_read_from_buffer(user_buf, count, ppos,
267 				       read_buf, p - read_buf);
268 }
269 
270 const struct file_operations cros_ec_console_log_fops = {
271 	.owner = THIS_MODULE,
272 	.open = cros_ec_console_log_open,
273 	.read = cros_ec_console_log_read,
274 	.llseek = no_llseek,
275 	.poll = cros_ec_console_log_poll,
276 	.release = cros_ec_console_log_release,
277 };
278 
279 const struct file_operations cros_ec_pdinfo_fops = {
280 	.owner = THIS_MODULE,
281 	.open = simple_open,
282 	.read = cros_ec_pdinfo_read,
283 	.llseek = default_llseek,
284 };
285 
286 static int ec_read_version_supported(struct cros_ec_dev *ec)
287 {
288 	struct ec_params_get_cmd_versions_v1 *params;
289 	struct ec_response_get_cmd_versions *response;
290 	int ret;
291 
292 	struct cros_ec_command *msg;
293 
294 	msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*response)),
295 		GFP_KERNEL);
296 	if (!msg)
297 		return 0;
298 
299 	msg->command = EC_CMD_GET_CMD_VERSIONS + ec->cmd_offset;
300 	msg->outsize = sizeof(*params);
301 	msg->insize = sizeof(*response);
302 
303 	params = (struct ec_params_get_cmd_versions_v1 *)msg->data;
304 	params->cmd = EC_CMD_CONSOLE_READ;
305 	response = (struct ec_response_get_cmd_versions *)msg->data;
306 
307 	ret = cros_ec_cmd_xfer(ec->ec_dev, msg) >= 0 &&
308 		msg->result == EC_RES_SUCCESS &&
309 		(response->version_mask & EC_VER_MASK(1));
310 
311 	kfree(msg);
312 
313 	return ret;
314 }
315 
316 static int cros_ec_create_console_log(struct cros_ec_debugfs *debug_info)
317 {
318 	struct cros_ec_dev *ec = debug_info->ec;
319 	char *buf;
320 	int read_params_size;
321 	int read_response_size;
322 
323 	if (!ec_read_version_supported(ec)) {
324 		dev_warn(ec->dev,
325 			"device does not support reading the console log\n");
326 		return 0;
327 	}
328 
329 	buf = devm_kzalloc(ec->dev, LOG_SIZE, GFP_KERNEL);
330 	if (!buf)
331 		return -ENOMEM;
332 
333 	read_params_size = sizeof(struct ec_params_console_read_v1);
334 	read_response_size = ec->ec_dev->max_response;
335 	debug_info->read_msg = devm_kzalloc(ec->dev,
336 		sizeof(*debug_info->read_msg) +
337 			max(read_params_size, read_response_size), GFP_KERNEL);
338 	if (!debug_info->read_msg)
339 		return -ENOMEM;
340 
341 	debug_info->read_msg->version = 1;
342 	debug_info->read_msg->command = EC_CMD_CONSOLE_READ + ec->cmd_offset;
343 	debug_info->read_msg->outsize = read_params_size;
344 	debug_info->read_msg->insize = read_response_size;
345 
346 	debug_info->log_buffer.buf = buf;
347 	debug_info->log_buffer.head = 0;
348 	debug_info->log_buffer.tail = 0;
349 
350 	mutex_init(&debug_info->log_mutex);
351 	init_waitqueue_head(&debug_info->log_wq);
352 
353 	if (!debugfs_create_file("console_log",
354 				 S_IFREG | 0444,
355 				 debug_info->dir,
356 				 debug_info,
357 				 &cros_ec_console_log_fops))
358 		return -ENOMEM;
359 
360 	INIT_DELAYED_WORK(&debug_info->log_poll_work,
361 			  cros_ec_console_log_work);
362 	schedule_delayed_work(&debug_info->log_poll_work, 0);
363 
364 	return 0;
365 }
366 
367 static void cros_ec_cleanup_console_log(struct cros_ec_debugfs *debug_info)
368 {
369 	if (debug_info->log_buffer.buf) {
370 		cancel_delayed_work_sync(&debug_info->log_poll_work);
371 		mutex_destroy(&debug_info->log_mutex);
372 	}
373 }
374 
375 static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info)
376 {
377 	struct cros_ec_device *ec_dev = debug_info->ec->ec_dev;
378 	int ret;
379 	struct cros_ec_command *msg;
380 	int insize;
381 
382 	insize = ec_dev->max_response;
383 
384 	msg = devm_kzalloc(debug_info->ec->dev,
385 			sizeof(*msg) + insize, GFP_KERNEL);
386 	if (!msg)
387 		return -ENOMEM;
388 
389 	msg->command = EC_CMD_GET_PANIC_INFO;
390 	msg->insize = insize;
391 
392 	ret = cros_ec_cmd_xfer(ec_dev, msg);
393 	if (ret < 0) {
394 		dev_warn(debug_info->ec->dev, "Cannot read panicinfo.\n");
395 		ret = 0;
396 		goto free;
397 	}
398 
399 	/* No panic data */
400 	if (ret == 0)
401 		goto free;
402 
403 	debug_info->panicinfo_blob.data = msg->data;
404 	debug_info->panicinfo_blob.size = ret;
405 
406 	if (!debugfs_create_blob("panicinfo",
407 				 S_IFREG | 0444,
408 				 debug_info->dir,
409 				 &debug_info->panicinfo_blob)) {
410 		ret = -ENOMEM;
411 		goto free;
412 	}
413 
414 	return 0;
415 
416 free:
417 	devm_kfree(debug_info->ec->dev, msg);
418 	return ret;
419 }
420 
421 static int cros_ec_create_pdinfo(struct cros_ec_debugfs *debug_info)
422 {
423 	if (!debugfs_create_file("pdinfo", 0444, debug_info->dir, debug_info,
424 				 &cros_ec_pdinfo_fops))
425 		return -ENOMEM;
426 
427 	return 0;
428 }
429 
430 static int cros_ec_debugfs_probe(struct platform_device *pd)
431 {
432 	struct cros_ec_dev *ec = dev_get_drvdata(pd->dev.parent);
433 	struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev);
434 	const char *name = ec_platform->ec_name;
435 	struct cros_ec_debugfs *debug_info;
436 	int ret;
437 
438 	debug_info = devm_kzalloc(ec->dev, sizeof(*debug_info), GFP_KERNEL);
439 	if (!debug_info)
440 		return -ENOMEM;
441 
442 	debug_info->ec = ec;
443 	debug_info->dir = debugfs_create_dir(name, NULL);
444 	if (!debug_info->dir)
445 		return -ENOMEM;
446 
447 	ret = cros_ec_create_panicinfo(debug_info);
448 	if (ret)
449 		goto remove_debugfs;
450 
451 	ret = cros_ec_create_console_log(debug_info);
452 	if (ret)
453 		goto remove_debugfs;
454 
455 	ret = cros_ec_create_pdinfo(debug_info);
456 	if (ret)
457 		goto remove_debugfs;
458 
459 	ec->debug_info = debug_info;
460 
461 	dev_set_drvdata(&pd->dev, ec);
462 
463 	return 0;
464 
465 remove_debugfs:
466 	debugfs_remove_recursive(debug_info->dir);
467 	return ret;
468 }
469 
470 static int cros_ec_debugfs_remove(struct platform_device *pd)
471 {
472 	struct cros_ec_dev *ec = dev_get_drvdata(pd->dev.parent);
473 
474 	debugfs_remove_recursive(ec->debug_info->dir);
475 	cros_ec_cleanup_console_log(ec->debug_info);
476 
477 	return 0;
478 }
479 
480 static int __maybe_unused cros_ec_debugfs_suspend(struct device *dev)
481 {
482 	struct cros_ec_dev *ec = dev_get_drvdata(dev);
483 
484 	cancel_delayed_work_sync(&ec->debug_info->log_poll_work);
485 
486 	return 0;
487 }
488 
489 static int __maybe_unused cros_ec_debugfs_resume(struct device *dev)
490 {
491 	struct cros_ec_dev *ec = dev_get_drvdata(dev);
492 
493 	schedule_delayed_work(&ec->debug_info->log_poll_work, 0);
494 
495 	return 0;
496 }
497 
498 static SIMPLE_DEV_PM_OPS(cros_ec_debugfs_pm_ops,
499 			 cros_ec_debugfs_suspend, cros_ec_debugfs_resume);
500 
501 static struct platform_driver cros_ec_debugfs_driver = {
502 	.driver = {
503 		.name = DRV_NAME,
504 		.pm = &cros_ec_debugfs_pm_ops,
505 	},
506 	.probe = cros_ec_debugfs_probe,
507 	.remove = cros_ec_debugfs_remove,
508 };
509 
510 module_platform_driver(cros_ec_debugfs_driver);
511 
512 MODULE_LICENSE("GPL");
513 MODULE_DESCRIPTION("Debug logs for ChromeOS EC");
514 MODULE_ALIAS("platform:" DRV_NAME);
515