hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/memory/mtk-smi.c
....@@ -1,15 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015-2016 MediaTek Inc.
34 * Author: Yong Wu <yong.wu@mediatek.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 as
7
- * published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
135 */
146 #include <linux/clk.h>
157 #include <linux/component.h>
....@@ -23,9 +15,13 @@
2315 #include <linux/pm_runtime.h>
2416 #include <soc/mediatek/smi.h>
2517 #include <dt-bindings/memory/mt2701-larb-port.h>
18
+#include <dt-bindings/memory/mtk-memory-port.h>
2619
2720 /* mt8173 */
2821 #define SMI_LARB_MMU_EN 0xf00
22
+
23
+/* mt8167 */
24
+#define MT8167_SMI_LARB_MMU_EN 0xfc0
2925
3026 /* mt2701 */
3127 #define REG_SMI_SECUR_CON_BASE 0x5c0
....@@ -48,18 +44,45 @@
4844 /* mt2712 */
4945 #define SMI_LARB_NONSEC_CON(id) (0x380 + ((id) * 4))
5046 #define F_MMU_EN BIT(0)
47
+#define BANK_SEL(id) ({ \
48
+ u32 _id = (id) & 0x3; \
49
+ (_id << 8 | _id << 10 | _id << 12 | _id << 14); \
50
+})
51
+
52
+/* SMI COMMON */
53
+#define SMI_BUS_SEL 0x220
54
+#define SMI_BUS_LARB_SHIFT(larbid) ((larbid) << 1)
55
+/* All are MMU0 defaultly. Only specialize mmu1 here. */
56
+#define F_MMU1_LARB(larbid) (0x1 << SMI_BUS_LARB_SHIFT(larbid))
57
+
58
+enum mtk_smi_gen {
59
+ MTK_SMI_GEN1,
60
+ MTK_SMI_GEN2
61
+};
62
+
63
+struct mtk_smi_common_plat {
64
+ enum mtk_smi_gen gen;
65
+ bool has_gals;
66
+ u32 bus_sel; /* Balance some larbs to enter mmu0 or mmu1 */
67
+};
5168
5269 struct mtk_smi_larb_gen {
53
- bool need_larbid;
5470 int port_in_larb[MTK_LARB_NR_MAX + 1];
55
- void (*config_port)(struct device *);
71
+ void (*config_port)(struct device *dev);
72
+ unsigned int larb_direct_to_common_mask;
73
+ bool has_gals;
5674 };
5775
5876 struct mtk_smi {
5977 struct device *dev;
6078 struct clk *clk_apb, *clk_smi;
79
+ struct clk *clk_gals0, *clk_gals1;
6180 struct clk *clk_async; /*only needed by mt2701*/
62
- void __iomem *smi_ao_base;
81
+ union {
82
+ void __iomem *smi_ao_base; /* only for gen1 */
83
+ void __iomem *base; /* only for gen2 */
84
+ };
85
+ const struct mtk_smi_common_plat *plat;
6386 };
6487
6588 struct mtk_smi_larb { /* larb: local arbiter */
....@@ -69,84 +92,59 @@
6992 const struct mtk_smi_larb_gen *larb_gen;
7093 int larbid;
7194 u32 *mmu;
95
+ unsigned char *bank;
7296 };
7397
74
-enum mtk_smi_gen {
75
- MTK_SMI_GEN1,
76
- MTK_SMI_GEN2
77
-};
78
-
79
-static int mtk_smi_enable(const struct mtk_smi *smi)
98
+static int mtk_smi_clk_enable(const struct mtk_smi *smi)
8099 {
81100 int ret;
82101
83
- ret = pm_runtime_get_sync(smi->dev);
84
- if (ret < 0)
85
- return ret;
86
-
87102 ret = clk_prepare_enable(smi->clk_apb);
88103 if (ret)
89
- goto err_put_pm;
104
+ return ret;
90105
91106 ret = clk_prepare_enable(smi->clk_smi);
92107 if (ret)
93108 goto err_disable_apb;
94109
110
+ ret = clk_prepare_enable(smi->clk_gals0);
111
+ if (ret)
112
+ goto err_disable_smi;
113
+
114
+ ret = clk_prepare_enable(smi->clk_gals1);
115
+ if (ret)
116
+ goto err_disable_gals0;
117
+
95118 return 0;
96119
120
+err_disable_gals0:
121
+ clk_disable_unprepare(smi->clk_gals0);
122
+err_disable_smi:
123
+ clk_disable_unprepare(smi->clk_smi);
97124 err_disable_apb:
98125 clk_disable_unprepare(smi->clk_apb);
99
-err_put_pm:
100
- pm_runtime_put_sync(smi->dev);
101126 return ret;
102127 }
103128
104
-static void mtk_smi_disable(const struct mtk_smi *smi)
129
+static void mtk_smi_clk_disable(const struct mtk_smi *smi)
105130 {
131
+ clk_disable_unprepare(smi->clk_gals1);
132
+ clk_disable_unprepare(smi->clk_gals0);
106133 clk_disable_unprepare(smi->clk_smi);
107134 clk_disable_unprepare(smi->clk_apb);
108
- pm_runtime_put_sync(smi->dev);
109135 }
110136
111137 int mtk_smi_larb_get(struct device *larbdev)
112138 {
113
- struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
114
- const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
115
- struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
116
- int ret;
139
+ int ret = pm_runtime_resume_and_get(larbdev);
117140
118
- /* Enable the smi-common's power and clocks */
119
- ret = mtk_smi_enable(common);
120
- if (ret)
121
- return ret;
122
-
123
- /* Enable the larb's power and clocks */
124
- ret = mtk_smi_enable(&larb->smi);
125
- if (ret) {
126
- mtk_smi_disable(common);
127
- return ret;
128
- }
129
-
130
- /* Configure the iommu info for this larb */
131
- larb_gen->config_port(larbdev);
132
-
133
- return 0;
141
+ return (ret < 0) ? ret : 0;
134142 }
135143 EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
136144
137145 void mtk_smi_larb_put(struct device *larbdev)
138146 {
139
- struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
140
- struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
141
-
142
- /*
143
- * Don't de-configure the iommu info for this larb since there may be
144
- * several modules in this larb.
145
- * The iommu info will be reset after power off.
146
- */
147
-
148
- mtk_smi_disable(&larb->smi);
149
- mtk_smi_disable(common);
147
+ pm_runtime_put_sync(larbdev);
150148 }
151149 EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
152150
....@@ -154,44 +152,33 @@
154152 mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
155153 {
156154 struct mtk_smi_larb *larb = dev_get_drvdata(dev);
157
- struct mtk_smi_iommu *smi_iommu = data;
155
+ struct mtk_smi_larb_iommu *larb_mmu = data;
158156 unsigned int i;
159157
160
- if (larb->larb_gen->need_larbid) {
161
- larb->mmu = &smi_iommu->larb_imu[larb->larbid].mmu;
162
- return 0;
163
- }
164
-
165
- /*
166
- * If there is no larbid property, Loop to find the corresponding
167
- * iommu information.
168
- */
169
- for (i = 0; i < smi_iommu->larb_nr; i++) {
170
- if (dev == smi_iommu->larb_imu[i].dev) {
171
- /* The 'mmu' may be updated in iommu-attach/detach. */
172
- larb->mmu = &smi_iommu->larb_imu[i].mmu;
158
+ for (i = 0; i < MTK_LARB_NR_MAX; i++) {
159
+ if (dev == larb_mmu[i].dev) {
160
+ larb->larbid = i;
161
+ larb->mmu = &larb_mmu[i].mmu;
162
+ larb->bank = larb_mmu[i].bank;
173163 return 0;
174164 }
175165 }
176166 return -ENODEV;
177167 }
178168
179
-static void mtk_smi_larb_config_port_mt2712(struct device *dev)
169
+static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
180170 {
181171 struct mtk_smi_larb *larb = dev_get_drvdata(dev);
182172 u32 reg;
183173 int i;
184174
185
- /*
186
- * larb 8/9 is the bdpsys larb, the iommu_en is enabled defaultly.
187
- * Don't need to set it again.
188
- */
189
- if (larb->larbid == 8 || larb->larbid == 9)
175
+ if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
190176 return;
191177
192178 for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
193179 reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
194180 reg |= F_MMU_EN;
181
+ reg |= BANK_SEL(larb->bank[i]);
195182 writel(reg, larb->base + SMI_LARB_NONSEC_CON(i));
196183 }
197184 }
....@@ -201,6 +188,13 @@
201188 struct mtk_smi_larb *larb = dev_get_drvdata(dev);
202189
203190 writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
191
+}
192
+
193
+static void mtk_smi_larb_config_port_mt8167(struct device *dev)
194
+{
195
+ struct mtk_smi_larb *larb = dev_get_drvdata(dev);
196
+
197
+ writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN);
204198 }
205199
206200 static void mtk_smi_larb_config_port_gen1(struct device *dev)
....@@ -250,8 +244,12 @@
250244 .config_port = mtk_smi_larb_config_port_mt8173,
251245 };
252246
247
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8167 = {
248
+ /* mt8167 do not need the port in larb */
249
+ .config_port = mtk_smi_larb_config_port_mt8167,
250
+};
251
+
253252 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
254
- .need_larbid = true,
255253 .port_in_larb = {
256254 LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
257255 LARB2_PORT_OFFSET, LARB3_PORT_OFFSET
....@@ -260,11 +258,33 @@
260258 };
261259
262260 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = {
263
- .need_larbid = true,
264
- .config_port = mtk_smi_larb_config_port_mt2712,
261
+ .config_port = mtk_smi_larb_config_port_gen2_general,
262
+ .larb_direct_to_common_mask = BIT(8) | BIT(9), /* bdpsys */
263
+};
264
+
265
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt6779 = {
266
+ .config_port = mtk_smi_larb_config_port_gen2_general,
267
+ .larb_direct_to_common_mask =
268
+ BIT(4) | BIT(6) | BIT(11) | BIT(12) | BIT(13),
269
+ /* DUMMY | IPU0 | IPU1 | CCU | MDLA */
270
+};
271
+
272
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
273
+ .has_gals = true,
274
+ .config_port = mtk_smi_larb_config_port_gen2_general,
275
+ .larb_direct_to_common_mask = BIT(2) | BIT(3) | BIT(7),
276
+ /* IPU0 | IPU1 | CCU */
277
+};
278
+
279
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
280
+ .config_port = mtk_smi_larb_config_port_gen2_general,
265281 };
266282
267283 static const struct of_device_id mtk_smi_larb_of_ids[] = {
284
+ {
285
+ .compatible = "mediatek,mt8167-smi-larb",
286
+ .data = &mtk_smi_larb_mt8167
287
+ },
268288 {
269289 .compatible = "mediatek,mt8173-smi-larb",
270290 .data = &mtk_smi_larb_mt8173
....@@ -277,6 +297,18 @@
277297 .compatible = "mediatek,mt2712-smi-larb",
278298 .data = &mtk_smi_larb_mt2712
279299 },
300
+ {
301
+ .compatible = "mediatek,mt6779-smi-larb",
302
+ .data = &mtk_smi_larb_mt6779
303
+ },
304
+ {
305
+ .compatible = "mediatek,mt8183-smi-larb",
306
+ .data = &mtk_smi_larb_mt8183
307
+ },
308
+ {
309
+ .compatible = "mediatek,mt8192-smi-larb",
310
+ .data = &mtk_smi_larb_mt8192
311
+ },
280312 {}
281313 };
282314
....@@ -287,7 +319,6 @@
287319 struct device *dev = &pdev->dev;
288320 struct device_node *smi_node;
289321 struct platform_device *smi_pdev;
290
- int err;
291322
292323 larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
293324 if (!larb)
....@@ -306,16 +337,16 @@
306337 larb->smi.clk_smi = devm_clk_get(dev, "smi");
307338 if (IS_ERR(larb->smi.clk_smi))
308339 return PTR_ERR(larb->smi.clk_smi);
309
- larb->smi.dev = dev;
310340
311
- if (larb->larb_gen->need_larbid) {
312
- err = of_property_read_u32(dev->of_node, "mediatek,larb-id",
313
- &larb->larbid);
314
- if (err) {
315
- dev_err(dev, "missing larbid property\n");
316
- return err;
317
- }
341
+ if (larb->larb_gen->has_gals) {
342
+ /* The larbs may still haven't gals even if the SoC support.*/
343
+ larb->smi.clk_gals0 = devm_clk_get(dev, "gals");
344
+ if (PTR_ERR(larb->smi.clk_gals0) == -ENOENT)
345
+ larb->smi.clk_gals0 = NULL;
346
+ else if (IS_ERR(larb->smi.clk_gals0))
347
+ return PTR_ERR(larb->smi.clk_gals0);
318348 }
349
+ larb->smi.dev = dev;
319350
320351 smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
321352 if (!smi_node)
....@@ -344,27 +375,114 @@
344375 return 0;
345376 }
346377
378
+static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
379
+{
380
+ struct mtk_smi_larb *larb = dev_get_drvdata(dev);
381
+ const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
382
+ int ret;
383
+
384
+ /* Power on smi-common. */
385
+ ret = pm_runtime_resume_and_get(larb->smi_common_dev);
386
+ if (ret < 0) {
387
+ dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret);
388
+ return ret;
389
+ }
390
+
391
+ ret = mtk_smi_clk_enable(&larb->smi);
392
+ if (ret < 0) {
393
+ dev_err(dev, "Failed to enable clock(%d).\n", ret);
394
+ pm_runtime_put_sync(larb->smi_common_dev);
395
+ return ret;
396
+ }
397
+
398
+ /* Configure the basic setting for this larb */
399
+ larb_gen->config_port(dev);
400
+
401
+ return 0;
402
+}
403
+
404
+static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
405
+{
406
+ struct mtk_smi_larb *larb = dev_get_drvdata(dev);
407
+
408
+ mtk_smi_clk_disable(&larb->smi);
409
+ pm_runtime_put_sync(larb->smi_common_dev);
410
+ return 0;
411
+}
412
+
413
+static const struct dev_pm_ops smi_larb_pm_ops = {
414
+ SET_RUNTIME_PM_OPS(mtk_smi_larb_suspend, mtk_smi_larb_resume, NULL)
415
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
416
+ pm_runtime_force_resume)
417
+};
418
+
347419 static struct platform_driver mtk_smi_larb_driver = {
348420 .probe = mtk_smi_larb_probe,
349421 .remove = mtk_smi_larb_remove,
350422 .driver = {
351423 .name = "mtk-smi-larb",
352424 .of_match_table = mtk_smi_larb_of_ids,
425
+ .pm = &smi_larb_pm_ops,
353426 }
427
+};
428
+
429
+static const struct mtk_smi_common_plat mtk_smi_common_gen1 = {
430
+ .gen = MTK_SMI_GEN1,
431
+};
432
+
433
+static const struct mtk_smi_common_plat mtk_smi_common_gen2 = {
434
+ .gen = MTK_SMI_GEN2,
435
+};
436
+
437
+static const struct mtk_smi_common_plat mtk_smi_common_mt6779 = {
438
+ .gen = MTK_SMI_GEN2,
439
+ .has_gals = true,
440
+ .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(4) |
441
+ F_MMU1_LARB(5) | F_MMU1_LARB(6) | F_MMU1_LARB(7),
442
+};
443
+
444
+static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
445
+ .gen = MTK_SMI_GEN2,
446
+ .has_gals = true,
447
+ .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
448
+ F_MMU1_LARB(7),
449
+};
450
+
451
+static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
452
+ .gen = MTK_SMI_GEN2,
453
+ .has_gals = true,
454
+ .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
455
+ F_MMU1_LARB(6),
354456 };
355457
356458 static const struct of_device_id mtk_smi_common_of_ids[] = {
357459 {
358460 .compatible = "mediatek,mt8173-smi-common",
359
- .data = (void *)MTK_SMI_GEN2
461
+ .data = &mtk_smi_common_gen2,
462
+ },
463
+ {
464
+ .compatible = "mediatek,mt8167-smi-common",
465
+ .data = &mtk_smi_common_gen2,
360466 },
361467 {
362468 .compatible = "mediatek,mt2701-smi-common",
363
- .data = (void *)MTK_SMI_GEN1
469
+ .data = &mtk_smi_common_gen1,
364470 },
365471 {
366472 .compatible = "mediatek,mt2712-smi-common",
367
- .data = (void *)MTK_SMI_GEN2
473
+ .data = &mtk_smi_common_gen2,
474
+ },
475
+ {
476
+ .compatible = "mediatek,mt6779-smi-common",
477
+ .data = &mtk_smi_common_mt6779,
478
+ },
479
+ {
480
+ .compatible = "mediatek,mt8183-smi-common",
481
+ .data = &mtk_smi_common_mt8183,
482
+ },
483
+ {
484
+ .compatible = "mediatek,mt8192-smi-common",
485
+ .data = &mtk_smi_common_mt8192,
368486 },
369487 {}
370488 };
....@@ -374,13 +492,13 @@
374492 struct device *dev = &pdev->dev;
375493 struct mtk_smi *common;
376494 struct resource *res;
377
- enum mtk_smi_gen smi_gen;
378495 int ret;
379496
380497 common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
381498 if (!common)
382499 return -ENOMEM;
383500 common->dev = dev;
501
+ common->plat = of_device_get_match_data(dev);
384502
385503 common->clk_apb = devm_clk_get(dev, "apb");
386504 if (IS_ERR(common->clk_apb))
....@@ -390,14 +508,23 @@
390508 if (IS_ERR(common->clk_smi))
391509 return PTR_ERR(common->clk_smi);
392510
511
+ if (common->plat->has_gals) {
512
+ common->clk_gals0 = devm_clk_get(dev, "gals0");
513
+ if (IS_ERR(common->clk_gals0))
514
+ return PTR_ERR(common->clk_gals0);
515
+
516
+ common->clk_gals1 = devm_clk_get(dev, "gals1");
517
+ if (IS_ERR(common->clk_gals1))
518
+ return PTR_ERR(common->clk_gals1);
519
+ }
520
+
393521 /*
394522 * for mtk smi gen 1, we need to get the ao(always on) base to config
395523 * m4u port, and we need to enable the aync clock for transform the smi
396524 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
397525 * base.
398526 */
399
- smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev);
400
- if (smi_gen == MTK_SMI_GEN1) {
527
+ if (common->plat->gen == MTK_SMI_GEN1) {
401528 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
402529 common->smi_ao_base = devm_ioremap_resource(dev, res);
403530 if (IS_ERR(common->smi_ao_base))
....@@ -410,6 +537,11 @@
410537 ret = clk_prepare_enable(common->clk_async);
411538 if (ret)
412539 return ret;
540
+ } else {
541
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
542
+ common->base = devm_ioremap_resource(dev, res);
543
+ if (IS_ERR(common->base))
544
+ return PTR_ERR(common->base);
413545 }
414546 pm_runtime_enable(dev);
415547 platform_set_drvdata(pdev, common);
....@@ -422,35 +554,63 @@
422554 return 0;
423555 }
424556
557
+static int __maybe_unused mtk_smi_common_resume(struct device *dev)
558
+{
559
+ struct mtk_smi *common = dev_get_drvdata(dev);
560
+ u32 bus_sel = common->plat->bus_sel;
561
+ int ret;
562
+
563
+ ret = mtk_smi_clk_enable(common);
564
+ if (ret) {
565
+ dev_err(common->dev, "Failed to enable clock(%d).\n", ret);
566
+ return ret;
567
+ }
568
+
569
+ if (common->plat->gen == MTK_SMI_GEN2 && bus_sel)
570
+ writel(bus_sel, common->base + SMI_BUS_SEL);
571
+ return 0;
572
+}
573
+
574
+static int __maybe_unused mtk_smi_common_suspend(struct device *dev)
575
+{
576
+ struct mtk_smi *common = dev_get_drvdata(dev);
577
+
578
+ mtk_smi_clk_disable(common);
579
+ return 0;
580
+}
581
+
582
+static const struct dev_pm_ops smi_common_pm_ops = {
583
+ SET_RUNTIME_PM_OPS(mtk_smi_common_suspend, mtk_smi_common_resume, NULL)
584
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
585
+ pm_runtime_force_resume)
586
+};
587
+
425588 static struct platform_driver mtk_smi_common_driver = {
426589 .probe = mtk_smi_common_probe,
427590 .remove = mtk_smi_common_remove,
428591 .driver = {
429592 .name = "mtk-smi-common",
430593 .of_match_table = mtk_smi_common_of_ids,
594
+ .pm = &smi_common_pm_ops,
431595 }
596
+};
597
+
598
+static struct platform_driver * const smidrivers[] = {
599
+ &mtk_smi_common_driver,
600
+ &mtk_smi_larb_driver,
432601 };
433602
434603 static int __init mtk_smi_init(void)
435604 {
436
- int ret;
437
-
438
- ret = platform_driver_register(&mtk_smi_common_driver);
439
- if (ret != 0) {
440
- pr_err("Failed to register SMI driver\n");
441
- return ret;
442
- }
443
-
444
- ret = platform_driver_register(&mtk_smi_larb_driver);
445
- if (ret != 0) {
446
- pr_err("Failed to register SMI-LARB driver\n");
447
- goto err_unreg_smi;
448
- }
449
- return ret;
450
-
451
-err_unreg_smi:
452
- platform_driver_unregister(&mtk_smi_common_driver);
453
- return ret;
605
+ return platform_register_drivers(smidrivers, ARRAY_SIZE(smidrivers));
454606 }
455
-
456607 module_init(mtk_smi_init);
608
+
609
+static void __exit mtk_smi_exit(void)
610
+{
611
+ platform_unregister_drivers(smidrivers, ARRAY_SIZE(smidrivers));
612
+}
613
+module_exit(mtk_smi_exit);
614
+
615
+MODULE_DESCRIPTION("MediaTek SMI driver");
616
+MODULE_LICENSE("GPL v2");