hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/iommu/mtk_iommu_v1.c
....@@ -1,19 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
3
+ * IOMMU API for MTK architected m4u v1 implementations
4
+ *
25 * Copyright (c) 2015-2016 MediaTek Inc.
36 * Author: Honghui Zhang <honghui.zhang@mediatek.com>
47 *
58 * Based on driver/iommu/mtk_iommu.c
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License version 2 as
9
- * published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
159 */
16
-#include <linux/bootmem.h>
10
+#include <linux/memblock.h>
1711 #include <linux/bug.h>
1812 #include <linux/clk.h>
1913 #include <linux/component.h>
....@@ -35,7 +29,7 @@
3529 #include <linux/spinlock.h>
3630 #include <asm/barrier.h>
3731 #include <asm/dma-iommu.h>
38
-#include <linux/module.h>
32
+#include <linux/init.h>
3933 #include <dt-bindings/memory/mt2701-larb-port.h>
4034 #include <soc/mediatek/smi.h>
4135 #include "mtk_iommu.h"
....@@ -206,13 +200,13 @@
206200 {
207201 struct mtk_smi_larb_iommu *larb_mmu;
208202 unsigned int larbid, portid;
209
- struct iommu_fwspec *fwspec = dev->iommu_fwspec;
203
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
210204 int i;
211205
212206 for (i = 0; i < fwspec->num_ids; ++i) {
213207 larbid = mt2701_m4u_to_larb(fwspec->ids[i]);
214208 portid = mt2701_m4u_to_port(fwspec->ids[i]);
215
- larb_mmu = &data->smi_imu.larb_imu[larbid];
209
+ larb_mmu = &data->larb_imu[larbid];
216210
217211 dev_dbg(dev, "%s iommu port: %d\n",
218212 enable ? "enable" : "disable", portid);
....@@ -230,9 +224,8 @@
230224
231225 spin_lock_init(&dom->pgtlock);
232226
233
- dom->pgt_va = dma_zalloc_coherent(data->dev,
234
- M2701_IOMMU_PGT_SIZE,
235
- &dom->pgt_pa, GFP_KERNEL);
227
+ dom->pgt_va = dma_alloc_coherent(data->dev, M2701_IOMMU_PGT_SIZE,
228
+ &dom->pgt_pa, GFP_KERNEL);
236229 if (!dom->pgt_va)
237230 return -ENOMEM;
238231
....@@ -270,12 +263,15 @@
270263 static int mtk_iommu_attach_device(struct iommu_domain *domain,
271264 struct device *dev)
272265 {
266
+ struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
273267 struct mtk_iommu_domain *dom = to_mtk_domain(domain);
274
- struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
268
+ struct dma_iommu_mapping *mtk_mapping;
275269 int ret;
276270
277
- if (!data)
278
- return -ENODEV;
271
+ /* Only allow the domain created internally. */
272
+ mtk_mapping = data->mapping;
273
+ if (mtk_mapping->domain != domain)
274
+ return 0;
279275
280276 if (!data->m4u_dom) {
281277 data->m4u_dom = dom;
....@@ -293,16 +289,13 @@
293289 static void mtk_iommu_detach_device(struct iommu_domain *domain,
294290 struct device *dev)
295291 {
296
- struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv;
297
-
298
- if (!data)
299
- return;
292
+ struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
300293
301294 mtk_iommu_config(data, dev, false);
302295 }
303296
304297 static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
305
- phys_addr_t paddr, size_t size, int prot)
298
+ phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
306299 {
307300 struct mtk_iommu_domain *dom = to_mtk_domain(domain);
308301 unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT;
....@@ -331,7 +324,8 @@
331324 }
332325
333326 static size_t mtk_iommu_unmap(struct iommu_domain *domain,
334
- unsigned long iova, size_t size)
327
+ unsigned long iova, size_t size,
328
+ struct iommu_iotlb_gather *gather)
335329 {
336330 struct mtk_iommu_domain *dom = to_mtk_domain(domain);
337331 unsigned long flags;
....@@ -362,7 +356,7 @@
362356 return pa;
363357 }
364358
365
-static struct iommu_ops mtk_iommu_ops;
359
+static const struct iommu_ops mtk_iommu_ops;
366360
367361 /*
368362 * MTK generation one iommu HW only support one iommu domain, and all the client
....@@ -371,10 +365,10 @@
371365 static int mtk_iommu_create_mapping(struct device *dev,
372366 struct of_phandle_args *args)
373367 {
368
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
374369 struct mtk_iommu_data *data;
375370 struct platform_device *m4updev;
376371 struct dma_iommu_mapping *mtk_mapping;
377
- struct device *m4udev;
378372 int ret;
379373
380374 if (args->args_count != 1) {
....@@ -383,30 +377,30 @@
383377 return -EINVAL;
384378 }
385379
386
- if (!dev->iommu_fwspec) {
380
+ if (!fwspec) {
387381 ret = iommu_fwspec_init(dev, &args->np->fwnode, &mtk_iommu_ops);
388382 if (ret)
389383 return ret;
390
- } else if (dev->iommu_fwspec->ops != &mtk_iommu_ops) {
384
+ fwspec = dev_iommu_fwspec_get(dev);
385
+ } else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) {
391386 return -EINVAL;
392387 }
393388
394
- if (!dev->iommu_fwspec->iommu_priv) {
389
+ if (!dev_iommu_priv_get(dev)) {
395390 /* Get the m4u device */
396391 m4updev = of_find_device_by_node(args->np);
397392 if (WARN_ON(!m4updev))
398393 return -EINVAL;
399394
400
- dev->iommu_fwspec->iommu_priv = platform_get_drvdata(m4updev);
395
+ dev_iommu_priv_set(dev, platform_get_drvdata(m4updev));
401396 }
402397
403398 ret = iommu_fwspec_add_ids(dev, args->args, 1);
404399 if (ret)
405400 return ret;
406401
407
- data = dev->iommu_fwspec->iommu_priv;
408
- m4udev = data->dev;
409
- mtk_mapping = m4udev->archdata.iommu;
402
+ data = dev_iommu_priv_get(dev);
403
+ mtk_mapping = data->mapping;
410404 if (!mtk_mapping) {
411405 /* MTK iommu support 4GB iova address space. */
412406 mtk_mapping = arm_iommu_create_mapping(&platform_bus_type,
....@@ -414,72 +408,69 @@
414408 if (IS_ERR(mtk_mapping))
415409 return PTR_ERR(mtk_mapping);
416410
417
- m4udev->archdata.iommu = mtk_mapping;
411
+ data->mapping = mtk_mapping;
418412 }
419413
420414 return 0;
421415 }
422416
423
-static int mtk_iommu_add_device(struct device *dev)
417
+static int mtk_iommu_def_domain_type(struct device *dev)
424418 {
425
- struct dma_iommu_mapping *mtk_mapping;
419
+ return IOMMU_DOMAIN_UNMANAGED;
420
+}
421
+
422
+static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
423
+{
424
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
426425 struct of_phandle_args iommu_spec;
427426 struct of_phandle_iterator it;
428427 struct mtk_iommu_data *data;
429
- struct iommu_group *group;
430428 int err;
431429
432430 of_for_each_phandle(&it, err, dev->of_node, "iommus",
433
- "#iommu-cells", 0) {
431
+ "#iommu-cells", -1) {
434432 int count = of_phandle_iterator_args(&it, iommu_spec.args,
435433 MAX_PHANDLE_ARGS);
436434 iommu_spec.np = of_node_get(it.node);
437435 iommu_spec.args_count = count;
438436
439437 mtk_iommu_create_mapping(dev, &iommu_spec);
438
+
439
+ /* dev->iommu_fwspec might have changed */
440
+ fwspec = dev_iommu_fwspec_get(dev);
441
+
440442 of_node_put(iommu_spec.np);
441443 }
442444
443
- if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
444
- return -ENODEV; /* Not a iommu client device */
445
+ if (!fwspec || fwspec->ops != &mtk_iommu_ops)
446
+ return ERR_PTR(-ENODEV); /* Not a iommu client device */
445447
446
- /*
447
- * This is a short-term bodge because the ARM DMA code doesn't
448
- * understand multi-device groups, but we have to call into it
449
- * successfully (and not just rely on a normal IOMMU API attach
450
- * here) in order to set the correct DMA API ops on @dev.
451
- */
452
- group = iommu_group_alloc();
453
- if (IS_ERR(group))
454
- return PTR_ERR(group);
448
+ data = dev_iommu_priv_get(dev);
455449
456
- err = iommu_group_add_device(group, dev);
457
- iommu_group_put(group);
458
- if (err)
459
- return err;
460
-
461
- data = dev->iommu_fwspec->iommu_priv;
462
- mtk_mapping = data->dev->archdata.iommu;
463
- err = arm_iommu_attach_device(dev, mtk_mapping);
464
- if (err) {
465
- iommu_group_remove_device(dev);
466
- return err;
467
- }
468
-
469
- return iommu_device_link(&data->iommu, dev);;
450
+ return &data->iommu;
470451 }
471452
472
-static void mtk_iommu_remove_device(struct device *dev)
453
+static void mtk_iommu_probe_finalize(struct device *dev)
473454 {
455
+ struct dma_iommu_mapping *mtk_mapping;
474456 struct mtk_iommu_data *data;
457
+ int err;
475458
476
- if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops)
459
+ data = dev_iommu_priv_get(dev);
460
+ mtk_mapping = data->mapping;
461
+
462
+ err = arm_iommu_attach_device(dev, mtk_mapping);
463
+ if (err)
464
+ dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n");
465
+}
466
+
467
+static void mtk_iommu_release_device(struct device *dev)
468
+{
469
+ struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
470
+
471
+ if (!fwspec || fwspec->ops != &mtk_iommu_ops)
477472 return;
478473
479
- data = dev->iommu_fwspec->iommu_priv;
480
- iommu_device_unlink(&data->iommu, dev);
481
-
482
- iommu_group_remove_device(dev);
483474 iommu_fwspec_free(dev);
484475 }
485476
....@@ -524,7 +515,7 @@
524515 return 0;
525516 }
526517
527
-static struct iommu_ops mtk_iommu_ops = {
518
+static const struct iommu_ops mtk_iommu_ops = {
528519 .domain_alloc = mtk_iommu_domain_alloc,
529520 .domain_free = mtk_iommu_domain_free,
530521 .attach_dev = mtk_iommu_attach_device,
....@@ -532,8 +523,11 @@
532523 .map = mtk_iommu_map,
533524 .unmap = mtk_iommu_unmap,
534525 .iova_to_phys = mtk_iommu_iova_to_phys,
535
- .add_device = mtk_iommu_add_device,
536
- .remove_device = mtk_iommu_remove_device,
526
+ .probe_device = mtk_iommu_probe_device,
527
+ .probe_finalize = mtk_iommu_probe_finalize,
528
+ .release_device = mtk_iommu_release_device,
529
+ .def_domain_type = mtk_iommu_def_domain_type,
530
+ .device_group = generic_device_group,
537531 .pgsize_bitmap = ~0UL << MT2701_IOMMU_PAGE_SHIFT,
538532 };
539533
....@@ -609,13 +603,11 @@
609603 }
610604 }
611605
612
- data->smi_imu.larb_imu[larb_nr].dev = &plarbdev->dev;
606
+ data->larb_imu[larb_nr].dev = &plarbdev->dev;
613607 component_match_add_release(dev, &match, release_of,
614608 compare_of, larb_spec.np);
615609 larb_nr++;
616610 }
617
-
618
- data->smi_imu.larb_nr = larb_nr;
619611
620612 platform_set_drvdata(pdev, data);
621613
....@@ -626,18 +618,34 @@
626618 ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
627619 dev_name(&pdev->dev));
628620 if (ret)
629
- return ret;
621
+ goto out_clk_unprepare;
630622
631623 iommu_device_set_ops(&data->iommu, &mtk_iommu_ops);
632624
633625 ret = iommu_device_register(&data->iommu);
634626 if (ret)
635
- return ret;
627
+ goto out_sysfs_remove;
636628
637
- if (!iommu_present(&platform_bus_type))
638
- bus_set_iommu(&platform_bus_type, &mtk_iommu_ops);
629
+ if (!iommu_present(&platform_bus_type)) {
630
+ ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops);
631
+ if (ret)
632
+ goto out_dev_unreg;
633
+ }
639634
640
- return component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
635
+ ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
636
+ if (ret)
637
+ goto out_bus_set_null;
638
+ return ret;
639
+
640
+out_bus_set_null:
641
+ bus_set_iommu(&platform_bus_type, NULL);
642
+out_dev_unreg:
643
+ iommu_device_unregister(&data->iommu);
644
+out_sysfs_remove:
645
+ iommu_device_sysfs_remove(&data->iommu);
646
+out_clk_unprepare:
647
+ clk_disable_unprepare(data->bclk);
648
+ return ret;
641649 }
642650
643651 static int mtk_iommu_remove(struct platform_device *pdev)
....@@ -704,15 +712,4 @@
704712 {
705713 return platform_driver_register(&mtk_iommu_driver);
706714 }
707
-
708
-static void __exit m4u_exit(void)
709
-{
710
- return platform_driver_unregister(&mtk_iommu_driver);
711
-}
712
-
713715 subsys_initcall(m4u_init);
714
-module_exit(m4u_exit);
715
-
716
-MODULE_DESCRIPTION("IOMMU API for MTK architected m4u v1 implementations");
717
-MODULE_AUTHOR("Honghui Zhang <honghui.zhang@mediatek.com>");
718
-MODULE_LICENSE("GPL v2");