blob: 3728ee1ee284c4e2f817f34c83af392b58ef73a6 [file] [log] [blame]
developerbc627362023-08-08 16:05:33 +08001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
4 *
5 * Author: Alvin Kuo <alvin.kuog@mediatek.com>
6 * Ren-Ting Wang <ren-ting.wang@mediatek.com>
7 */
8
9#include <linux/debugfs.h>
10#include <linux/delay.h>
11#include <linux/err.h>
12#include <linux/relay.h>
13
14#include "trm-fs.h"
15#include "trm-mcu.h"
16#include "trm.h"
17
18#define RLY_RETRY_NUM 3
19
20static struct dentry *debugfs_dir;
21static struct rchan *relay;
22static bool trm_fs_is_init;
23
24bool mtk_trm_fs_is_init(void)
25{
26 return trm_fs_is_init;
27}
28
29void *mtk_trm_fs_relay_reserve(u32 size)
30{
31 u32 rty = 0;
32 void *dst;
33
34 while (rty < RLY_RETRY_NUM) {
35 dst = relay_reserve(relay, size);
36 if (likely(dst))
37 return dst;
38
developer916d29b2023-08-24 16:23:03 +080039 rty++;
40 msleep(100);
developerbc627362023-08-08 16:05:33 +080041 }
42
43 return ERR_PTR(-ENOMEM);
44}
45
46void mtk_trm_fs_relay_flush(void)
47{
48 relay_flush(relay);
49}
50
51static struct dentry *trm_fs_create_buf_file_cb(const char *filename,
52 struct dentry *parent,
53 umode_t mode,
54 struct rchan_buf *buf,
55 int *is_global)
56{
57 struct dentry *debugfs_file;
58
59 debugfs_file = debugfs_create_file("dump_data", mode,
60 parent, buf,
61 &relay_file_operations);
62
63 *is_global = 1;
64
65 return debugfs_file;
66}
67
68static int trm_fs_remove_buf_file_cb(struct dentry *debugfs_file)
69{
70 debugfs_remove(debugfs_file);
71
72 return 0;
73}
74
75int mtk_trm_fs_init(void)
76{
77 static struct rchan_callbacks relay_cb = {
78 .create_buf_file = trm_fs_create_buf_file_cb,
79 .remove_buf_file = trm_fs_remove_buf_file_cb,
80 };
81 int ret = 0;
82
83 if (!debugfs_dir) {
84 debugfs_dir = debugfs_create_dir("tops", NULL);
85 if (IS_ERR(debugfs_dir)) {
86 ret = PTR_ERR(debugfs_dir);
87 goto out;
88 }
89 }
90
91 if (!relay) {
92 relay = relay_open("dump_data", debugfs_dir,
93 RLY_DUMP_SUBBUF_SZ,
94 RLY_DUMP_SUBBUF_NUM,
95 &relay_cb, NULL);
96 if (!relay) {
97 ret = -EINVAL;
98 goto err_debugfs_remove;
99 }
100 }
101
102 relay_reset(relay);
103
104 trm_fs_is_init = true;
105
106out:
107 return ret;
108
109err_debugfs_remove:
110 trm_fs_is_init = false;
111
112 debugfs_remove(debugfs_dir);
113
114 debugfs_dir = NULL;
115
116 return ret;
117}
118
119void mtk_trm_fs_deinit(void)
120{
121 trm_fs_is_init = false;
122
123 relay_close(relay);
124
125 debugfs_remove(debugfs_dir);
126}