blob: f2bd9bfdefe257ea63dfb1d15d964d3aa7b1ee68 [file] [log] [blame]
developere5e687d2023-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
39 if (rty++ < 3)
40 msleep(100);
41 else
42 break;
43 }
44
45 return ERR_PTR(-ENOMEM);
46}
47
48void mtk_trm_fs_relay_flush(void)
49{
50 relay_flush(relay);
51}
52
53static struct dentry *trm_fs_create_buf_file_cb(const char *filename,
54 struct dentry *parent,
55 umode_t mode,
56 struct rchan_buf *buf,
57 int *is_global)
58{
59 struct dentry *debugfs_file;
60
61 debugfs_file = debugfs_create_file("dump_data", mode,
62 parent, buf,
63 &relay_file_operations);
64
65 *is_global = 1;
66
67 return debugfs_file;
68}
69
70static int trm_fs_remove_buf_file_cb(struct dentry *debugfs_file)
71{
72 debugfs_remove(debugfs_file);
73
74 return 0;
75}
76
77int mtk_trm_fs_init(void)
78{
79 static struct rchan_callbacks relay_cb = {
80 .create_buf_file = trm_fs_create_buf_file_cb,
81 .remove_buf_file = trm_fs_remove_buf_file_cb,
82 };
83 int ret = 0;
84
85 if (!debugfs_dir) {
86 debugfs_dir = debugfs_create_dir("tops", NULL);
87 if (IS_ERR(debugfs_dir)) {
88 ret = PTR_ERR(debugfs_dir);
89 goto out;
90 }
91 }
92
93 if (!relay) {
94 relay = relay_open("dump_data", debugfs_dir,
95 RLY_DUMP_SUBBUF_SZ,
96 RLY_DUMP_SUBBUF_NUM,
97 &relay_cb, NULL);
98 if (!relay) {
99 ret = -EINVAL;
100 goto err_debugfs_remove;
101 }
102 }
103
104 relay_reset(relay);
105
106 trm_fs_is_init = true;
107
108out:
109 return ret;
110
111err_debugfs_remove:
112 trm_fs_is_init = false;
113
114 debugfs_remove(debugfs_dir);
115
116 debugfs_dir = NULL;
117
118 return ret;
119}
120
121void mtk_trm_fs_deinit(void)
122{
123 trm_fs_is_init = false;
124
125 relay_close(relay);
126
127 debugfs_remove(debugfs_dir);
128}