VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   57 Tags
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  1) // SPDX-License-Identifier: GPL-2.0
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  2) /*
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  3)  * /proc/bootconfig - Extra boot configuration
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  4)  */
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  5) #include <linux/fs.h>
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  6) #include <linux/init.h>
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  7) #include <linux/printk.h>
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  8) #include <linux/proc_fs.h>
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900  9) #include <linux/seq_file.h>
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 10) #include <linux/bootconfig.h>
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 11) #include <linux/slab.h>
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 12) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 13) static char *saved_boot_config;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 14) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 15) static int boot_config_proc_show(struct seq_file *m, void *v)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 16) {
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 17) 	if (saved_boot_config)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 18) 		seq_puts(m, saved_boot_config);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 19) 	return 0;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 20) }
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 21) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 22) /* Rest size of buffer */
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 23) #define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 24) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 25) /* Return the needed total length if @size is 0 */
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 26) static int __init copy_xbc_key_value_list(char *dst, size_t size)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 27) {
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 28) 	struct xbc_node *leaf, *vnode;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 29) 	char *key, *end = dst + size;
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 30) 	const char *val;
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 31) 	char q;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 32) 	int ret = 0;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 33) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 34) 	key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 35) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 36) 	xbc_for_each_key_value(leaf, val) {
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 37) 		ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 38) 		if (ret < 0)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 39) 			break;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 40) 		ret = snprintf(dst, rest(dst, end), "%s = ", key);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 41) 		if (ret < 0)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 42) 			break;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 43) 		dst += ret;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 44) 		vnode = xbc_node_get_child(leaf);
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 45) 		if (vnode) {
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 46) 			xbc_array_for_each_value(vnode, val) {
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 47) 				if (strchr(val, '"'))
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 48) 					q = '\'';
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 49) 				else
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 50) 					q = '"';
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 51) 				ret = snprintf(dst, rest(dst, end), "%c%s%c%s",
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 52) 					q, val, q, vnode->next ? ", " : "\n");
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 53) 				if (ret < 0)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 54) 					goto out;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 55) 				dst += ret;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 56) 			}
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 57) 		} else {
4e264ffd95346 (Masami Hiramatsu 2020-06-16 19:14:08 +0900 58) 			ret = snprintf(dst, rest(dst, end), "\"\"\n");
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 59) 			if (ret < 0)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 60) 				break;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 61) 			dst += ret;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 62) 		}
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 63) 	}
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 64) out:
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 65) 	kfree(key);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 66) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 67) 	return ret < 0 ? ret : dst - (end - size);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 68) }
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 69) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 70) static int __init proc_boot_config_init(void)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 71) {
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 72) 	int len;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 73) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 74) 	len = copy_xbc_key_value_list(NULL, 0);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 75) 	if (len < 0)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 76) 		return len;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 77) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 78) 	if (len > 0) {
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 79) 		saved_boot_config = kzalloc(len + 1, GFP_KERNEL);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 80) 		if (!saved_boot_config)
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 81) 			return -ENOMEM;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 82) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 83) 		len = copy_xbc_key_value_list(saved_boot_config, len + 1);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 84) 		if (len < 0) {
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 85) 			kfree(saved_boot_config);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 86) 			return len;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 87) 		}
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 88) 	}
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 89) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 90) 	proc_create_single("bootconfig", 0, NULL, boot_config_proc_show);
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 91) 
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 92) 	return 0;
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 93) }
c1a3c36017d4c (Masami Hiramatsu 2020-01-11 01:04:19 +0900 94) fs_initcall(proc_boot_config_init);