Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Remote Processor Framework
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2011 Texas Instruments, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2011 Google, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Ohad Ben-Cohen <ohad@wizery.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Mark Grosen <mgrosen@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Brian Swetland <swetland@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Fernando Guzman Lugo <fernando.lugo@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Suman Anna <s-anna@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Robert Tivy <rtivy@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * Armando Uribe De Leon <x0095078@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define pr_fmt(fmt)    "%s: " fmt, __func__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/remoteproc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "remoteproc_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* remoteproc debugfs parent dir */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) static struct dentry *rproc_dbg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * A coredump-configuration-to-string lookup table, for exposing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * human readable configuration via debugfs. Always keep in sync with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * enum rproc_coredump_mechanism
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static const char * const rproc_coredump_str[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	[RPROC_COREDUMP_DISABLED]	= "disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	[RPROC_COREDUMP_ENABLED]	= "enabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	[RPROC_COREDUMP_INLINE]		= "inline",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) /* Expose the current coredump configuration via debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static ssize_t rproc_coredump_read(struct file *filp, char __user *userbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 				   size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct rproc *rproc = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	char buf[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	len = scnprintf(buf, sizeof(buf), "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			rproc_coredump_str[rproc->dump_conf]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	return simple_read_from_buffer(userbuf, count, ppos, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * By writing to the 'coredump' debugfs entry, we control the behavior of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * coredump mechanism dynamically. The default value of this entry is "disabled".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * The 'coredump' debugfs entry supports these commands:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * disabled:	By default coredump collection is disabled. Recovery will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *		proceed without collecting any dump.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * enabled:	When the remoteproc crashes the entire coredump will be copied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *		to a separate buffer and exposed to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * inline:	The coredump will not be copied to a separate buffer and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *		recovery process will have to wait until data is read by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *		userspace. But this avoid usage of extra memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) static ssize_t rproc_coredump_write(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 				    const char __user *user_buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 				    loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct rproc *rproc = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	int ret, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	char buf[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (count < 1 || count > sizeof(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	ret = copy_from_user(buf, user_buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	/* remove end of line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (buf[count - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		buf[count - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (rproc->state == RPROC_CRASHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		dev_err(&rproc->dev, "can't change coredump configuration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (!strncmp(buf, "disabled", count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		rproc->dump_conf = RPROC_COREDUMP_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	} else if (!strncmp(buf, "enabled", count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		rproc->dump_conf = RPROC_COREDUMP_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	} else if (!strncmp(buf, "inline", count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		rproc->dump_conf = RPROC_COREDUMP_INLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		dev_err(&rproc->dev, "Invalid coredump configuration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return err ? err : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static const struct file_operations rproc_coredump_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	.read = rproc_coredump_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	.write = rproc_coredump_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	.open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	.llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * Some remote processors may support dumping trace logs into a shared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * memory buffer. We expose this trace buffer using debugfs, so users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  * can easily tell what's going on remotely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * We will most probably improve the rproc tracing facilities later on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * but this kind of lightweight and simple mechanism is always good to have,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * as it provides very early tracing with little to no dependencies at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static ssize_t rproc_trace_read(struct file *filp, char __user *userbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 				size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	struct rproc_debug_trace *data = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	struct rproc_mem_entry *trace = &data->trace_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	void *va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	char buf[100];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	va = rproc_da_to_va(data->rproc, trace->da, trace->len, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (!va) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		len = scnprintf(buf, sizeof(buf), "Trace %s not available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 				trace->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		va = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		len = strnlen(va, trace->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return simple_read_from_buffer(userbuf, count, ppos, va, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static const struct file_operations trace_rproc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	.read = rproc_trace_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	.open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	.llseek	= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /* expose the name of the remote processor via debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static ssize_t rproc_name_read(struct file *filp, char __user *userbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			       size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	struct rproc *rproc = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	/* need room for the name, a newline and a terminating null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	char buf[100];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	i = scnprintf(buf, sizeof(buf), "%.98s\n", rproc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static const struct file_operations rproc_name_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	.read = rproc_name_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	.open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	.llseek	= generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* expose recovery flag via debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static ssize_t rproc_recovery_read(struct file *filp, char __user *userbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				   size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct rproc *rproc = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	char *buf = rproc->recovery_disabled ? "disabled\n" : "enabled\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * By writing to the 'recovery' debugfs entry, we control the behavior of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  * recovery mechanism dynamically. The default value of this entry is "enabled".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * The 'recovery' debugfs entry supports these commands:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * enabled:	When enabled, the remote processor will be automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  *		recovered whenever it crashes. Moreover, if the remote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  *		processor crashes while recovery is disabled, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  *		be automatically recovered too as soon as recovery is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * disabled:	When disabled, a remote processor will remain in a crashed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *		state if it crashes. This is useful for debugging purposes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  *		without it, debugging a crash is substantially harder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * recover:	This function will trigger an immediate recovery if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  *		remote processor is in a crashed state, without changing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  *		or checking the recovery state (enabled/disabled).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  *		This is useful during debugging sessions, when one expects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  *		additional crashes to happen after enabling recovery. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  *		case, enabling recovery will make it hard to debug subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  *		crashes, so it's recommended to keep recovery disabled, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  *		instead use the "recover" command as needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) rproc_recovery_write(struct file *filp, const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		     size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	struct rproc *rproc = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (count < 1 || count > sizeof(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	ret = copy_from_user(buf, user_buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/* remove end of line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (buf[count - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		buf[count - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (!strncmp(buf, "enabled", count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		/* change the flag and begin the recovery process if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		rproc->recovery_disabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		rproc_trigger_recovery(rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	} else if (!strncmp(buf, "disabled", count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		rproc->recovery_disabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	} else if (!strncmp(buf, "recover", count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		/* begin the recovery process without changing the flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		rproc_trigger_recovery(rproc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static const struct file_operations rproc_recovery_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	.read = rproc_recovery_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	.write = rproc_recovery_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	.open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	.llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* expose the crash trigger via debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) rproc_crash_write(struct file *filp, const char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		  size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	struct rproc *rproc = filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	ret = kstrtouint_from_user(user_buf, count, 0, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	rproc_report_crash(rproc, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static const struct file_operations rproc_crash_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	.write = rproc_crash_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	.open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	.llseek = generic_file_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Expose resource table content via debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int rproc_rsc_table_show(struct seq_file *seq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	static const char * const types[] = {"carveout", "devmem", "trace", "vdev"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	struct rproc *rproc = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	struct resource_table *table = rproc->table_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	struct fw_rsc_carveout *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	struct fw_rsc_devmem *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	struct fw_rsc_trace *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	struct fw_rsc_vdev *v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (!table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		seq_puts(seq, "No resource table found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	for (i = 0; i < table->num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		int offset = table->offset[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		struct fw_rsc_hdr *hdr = (void *)table + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		void *rsc = (void *)hdr + sizeof(*hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		switch (hdr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		case RSC_CARVEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			c = rsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			seq_printf(seq, "  Device Address 0x%x\n", c->da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			seq_printf(seq, "  Physical Address 0x%x\n", c->pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			seq_printf(seq, "  Length 0x%x Bytes\n", c->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			seq_printf(seq, "  Flags 0x%x\n", c->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			seq_printf(seq, "  Reserved (should be zero) [%d]\n", c->reserved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			seq_printf(seq, "  Name %s\n\n", c->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		case RSC_DEVMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			d = rsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 			seq_printf(seq, "  Device Address 0x%x\n", d->da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			seq_printf(seq, "  Physical Address 0x%x\n", d->pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			seq_printf(seq, "  Length 0x%x Bytes\n", d->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			seq_printf(seq, "  Flags 0x%x\n", d->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			seq_printf(seq, "  Reserved (should be zero) [%d]\n", d->reserved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			seq_printf(seq, "  Name %s\n\n", d->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		case RSC_TRACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			t = rsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			seq_printf(seq, "  Device Address 0x%x\n", t->da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			seq_printf(seq, "  Length 0x%x Bytes\n", t->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			seq_printf(seq, "  Reserved (should be zero) [%d]\n", t->reserved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			seq_printf(seq, "  Name %s\n\n", t->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		case RSC_VDEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			v = rsc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			seq_printf(seq, "Entry %d is of type %s\n", i, types[hdr->type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 			seq_printf(seq, "  ID %d\n", v->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			seq_printf(seq, "  Notify ID %d\n", v->notifyid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			seq_printf(seq, "  Device features 0x%x\n", v->dfeatures);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 			seq_printf(seq, "  Guest features 0x%x\n", v->gfeatures);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			seq_printf(seq, "  Config length 0x%x\n", v->config_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			seq_printf(seq, "  Status 0x%x\n", v->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			seq_printf(seq, "  Number of vrings %d\n", v->num_of_vrings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			seq_printf(seq, "  Reserved (should be zero) [%d][%d]\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 				   v->reserved[0], v->reserved[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			for (j = 0; j < v->num_of_vrings; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 				seq_printf(seq, "  Vring %d\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				seq_printf(seq, "    Device Address 0x%x\n", v->vring[j].da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				seq_printf(seq, "    Alignment %d\n", v->vring[j].align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 				seq_printf(seq, "    Number of buffers %d\n", v->vring[j].num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 				seq_printf(seq, "    Notify ID %d\n", v->vring[j].notifyid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 				seq_printf(seq, "    Physical Address 0x%x\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 					   v->vring[j].pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 			seq_printf(seq, "Unknown resource type found: %d [hdr: %pK]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				   hdr->type, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) DEFINE_SHOW_ATTRIBUTE(rproc_rsc_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Expose carveout content via debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static int rproc_carveouts_show(struct seq_file *seq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	struct rproc *rproc = seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct rproc_mem_entry *carveout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	list_for_each_entry(carveout, &rproc->carveouts, node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		seq_puts(seq, "Carveout memory entry:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		seq_printf(seq, "\tName: %s\n", carveout->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		seq_printf(seq, "\tVirtual address: %pK\n", carveout->va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		seq_printf(seq, "\tDMA address: %pad\n", &carveout->dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		seq_printf(seq, "\tDevice address: 0x%x\n", carveout->da);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		seq_printf(seq, "\tLength: 0x%zx Bytes\n\n", carveout->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) DEFINE_SHOW_ATTRIBUTE(rproc_carveouts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) void rproc_remove_trace_file(struct dentry *tfile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	debugfs_remove(tfile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 				       struct rproc_debug_trace *trace)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	struct dentry *tfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, trace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 				    &trace_rproc_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	if (!tfile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		dev_err(&rproc->dev, "failed to create debugfs trace entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	return tfile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) void rproc_delete_debug_dir(struct rproc *rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	debugfs_remove_recursive(rproc->dbg_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) void rproc_create_debug_dir(struct rproc *rproc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	struct device *dev = &rproc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	if (!rproc_dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	rproc->dbg_dir = debugfs_create_dir(dev_name(dev), rproc_dbg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (!rproc->dbg_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	debugfs_create_file("name", 0400, rproc->dbg_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			    rproc, &rproc_name_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	debugfs_create_file("recovery", 0600, rproc->dbg_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			    rproc, &rproc_recovery_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	debugfs_create_file("crash", 0200, rproc->dbg_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			    rproc, &rproc_crash_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	debugfs_create_file("resource_table", 0400, rproc->dbg_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			    rproc, &rproc_rsc_table_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	debugfs_create_file("carveout_memories", 0400, rproc->dbg_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			    rproc, &rproc_carveouts_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	debugfs_create_file("coredump", 0600, rproc->dbg_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			    rproc, &rproc_coredump_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) void __init rproc_init_debugfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (debugfs_initialized()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		rproc_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (!rproc_dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			pr_err("can't create debugfs dir\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) void __exit rproc_exit_debugfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	debugfs_remove(rproc_dbg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }