blob: 05a7fe4c3060f6cc1bda95726f7198460b4b9e81 [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: Ren-Ting Wang <ren-ting.wang@mediatek.com>
6 */
7
8#include <linux/of.h>
9#include <linux/err.h>
10#include <linux/device.h>
11#include <linux/module.h>
developerfbdb5112023-08-21 15:12:14 +080012#include <linux/debugfs.h>
developere5e687d2023-08-08 16:05:33 +080013#include <linux/of_platform.h>
14#include <linux/platform_device.h>
15
16#include "ctrl.h"
17#include "firmware.h"
18#include "hpdma.h"
19#include "hwspinlock.h"
20#include "internal.h"
21#include "mbox.h"
22#include "mcu.h"
23#include "netsys.h"
24#include "net-event.h"
25#include "ser.h"
26#include "tdma.h"
27#include "trm-mcu.h"
28#include "trm.h"
29#include "tunnel.h"
30#include "wdt.h"
31
32struct device *tops_dev;
developerfbdb5112023-08-21 15:12:14 +080033struct dentry *tops_debugfs_root;
developere5e687d2023-08-08 16:05:33 +080034
35static int mtk_tops_post_init(struct platform_device *pdev)
36{
37 int ret = 0;
38
39 /* kick core */
40 ret = mtk_tops_mcu_bring_up(pdev);
41 if (ret) {
42 TOPS_ERR("mcu post init failed: %d\n", ret);
43 return ret;
44 }
45
46 /* offload tunnel protocol initialization */
47 ret = mtk_tops_tnl_offload_proto_setup(pdev);
48 if (ret) {
49 TOPS_ERR("tnl offload protocol init failed: %d\n", ret);
50 goto err_mcu_tear_down;
51 }
52
53 ret = mtk_tops_netevent_register(pdev);
54 if (ret) {
55 TOPS_ERR("netevent register fail: %d\n", ret);
56 goto err_offload_proto_tear_down;
57 }
58
59 /* create sysfs file */
60 ret = mtk_tops_ctrl_init(pdev);
61 if (ret) {
62 TOPS_ERR("ctrl init failed: %d\n", ret);
63 goto err_netevent_unregister;
64 }
65
66 ret = mtk_tops_ser_init(pdev);
67 if (ret) {
68 TOPS_ERR("ser init failed: %d\n", ret);
69 goto err_ctrl_deinit;
70 }
71
72 ret = mtk_tops_wdt_init(pdev);
73 if (ret) {
74 TOPS_ERR("wdt init failed: %d\n", ret);
75 goto err_ser_deinit;
76 }
77
78 return ret;
79
80err_ser_deinit:
81 mtk_tops_ser_deinit(pdev);
82
83err_ctrl_deinit:
84 mtk_tops_ctrl_deinit(pdev);
85
86err_netevent_unregister:
87 mtk_tops_netevent_unregister(pdev);
88
89err_offload_proto_tear_down:
90 mtk_tops_tnl_offload_proto_teardown(pdev);
91
92err_mcu_tear_down:
93 mtk_tops_mcu_tear_down(pdev);
94
95 return ret;
96}
97
98static int mtk_tops_probe(struct platform_device *pdev)
99{
100 int ret = 0;
101
102 tops_dev = &pdev->dev;
103
104 ret = mtk_tops_hwspinlock_init(pdev);
105 if (ret) {
106 TOPS_ERR("hwspinlock init failed: %d\n", ret);
107 return ret;
108 }
109
110 ret = mtk_tops_fw_init(pdev);
111 if (ret) {
112 TOPS_ERR("firmware init failed: %d\n", ret);
113 return ret;
114 }
115
116 ret = mtk_tops_mcu_init(pdev);
117 if (ret) {
118 TOPS_ERR("mcu init failed: %d\n", ret);
119 return ret;
120 }
121
122 ret = mtk_tops_netsys_init(pdev);
123 if (ret) {
124 TOPS_ERR("netsys init failed: %d\n", ret);
125 goto err_mcu_deinit;
126 }
127
128 ret = mtk_tops_tdma_init(pdev);
129 if (ret) {
130 TOPS_ERR("tdma init failed: %d\n", ret);
131 goto err_netsys_deinit;
132 }
133
134 ret = mtk_tops_tnl_offload_init(pdev);
135 if (ret) {
136 TOPS_ERR("tunnel table init failed: %d\n", ret);
137 goto err_tdma_deinit;
138 }
139
140 ret = mtk_tops_post_init(pdev);
141 if (ret)
142 goto err_tnl_offload_deinit;
143
144 TOPS_ERR("init done\n");
145 return ret;
146
147err_tnl_offload_deinit:
148 mtk_tops_tnl_offload_deinit(pdev);
149
150err_tdma_deinit:
151 mtk_tops_tdma_deinit(pdev);
152
153err_netsys_deinit:
154 mtk_tops_netsys_deinit(pdev);
155
156err_mcu_deinit:
157 mtk_tops_mcu_deinit(pdev);
158
159 return ret;
160}
161
162static int mtk_tops_remove(struct platform_device *pdev)
163{
164 mtk_tops_wdt_deinit(pdev);
165
166 mtk_tops_ser_deinit(pdev);
167
168 mtk_tops_ctrl_deinit(pdev);
169
170 mtk_tops_netevent_unregister(pdev);
171
172 mtk_tops_tnl_offload_proto_teardown(pdev);
173
174 mtk_tops_mcu_tear_down(pdev);
175
176 mtk_tops_tnl_offload_deinit(pdev);
177
178 mtk_tops_tdma_deinit(pdev);
179
180 mtk_tops_netsys_deinit(pdev);
181
182 mtk_tops_mcu_deinit(pdev);
183
184 return 0;
185}
186
187static const struct of_device_id tops_match[] = {
188 { .compatible = "mediatek,tops", },
189 { },
190};
191MODULE_DEVICE_TABLE(of, tops_match);
192
193static struct platform_driver mtk_tops_driver = {
194 .probe = mtk_tops_probe,
195 .remove = mtk_tops_remove,
196 .driver = {
197 .name = "mediatek,tops",
198 .owner = THIS_MODULE,
199 .of_match_table = tops_match,
200 },
201};
202
203static int __init mtk_tops_init(void)
204{
developerfbdb5112023-08-21 15:12:14 +0800205 tops_debugfs_root = debugfs_create_dir("tops", NULL);
206 if (IS_ERR(tops_debugfs_root)) {
207 TOPS_ERR("create tops debugfs root directory failed\n");
208 return PTR_ERR(tops_debugfs_root);
209 }
210
developere5e687d2023-08-08 16:05:33 +0800211 mtk_tops_mbox_init();
212
213 mtk_tops_hpdma_init();
214
215 mtk_tops_trm_init();
216
217 return platform_driver_register(&mtk_tops_driver);
218}
219
220static void __exit mtk_tops_exit(void)
221{
222 platform_driver_unregister(&mtk_tops_driver);
223
224 mtk_tops_trm_exit();
225
226 mtk_tops_hpdma_exit();
227
228 mtk_tops_mbox_exit();
developerfbdb5112023-08-21 15:12:14 +0800229
230 debugfs_remove_recursive(tops_debugfs_root);
developere5e687d2023-08-08 16:05:33 +0800231}
232
233module_init(mtk_tops_init);
234module_exit(mtk_tops_exit);
235
236MODULE_LICENSE("GPL v2");
237MODULE_DESCRIPTION("MediaTek TOPS Driver");
238MODULE_AUTHOR("Ren-Ting Wang <ren-ting.wang@mediatek.com>");