diff options
-rw-r--r-- | drivers/iommu/mtk_iommu.c | 26 | ||||
-rw-r--r-- | drivers/iommu/mtk_iommu.h | 2 |
2 files changed, 28 insertions, 0 deletions
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 1479c76ece9e..d484fa608db8 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c | |||
@@ -360,11 +360,15 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, | |||
360 | 360 | ||
361 | static int mtk_iommu_add_device(struct device *dev) | 361 | static int mtk_iommu_add_device(struct device *dev) |
362 | { | 362 | { |
363 | struct mtk_iommu_data *data; | ||
363 | struct iommu_group *group; | 364 | struct iommu_group *group; |
364 | 365 | ||
365 | if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops) | 366 | if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops) |
366 | return -ENODEV; /* Not a iommu client device */ | 367 | return -ENODEV; /* Not a iommu client device */ |
367 | 368 | ||
369 | data = dev->iommu_fwspec->iommu_priv; | ||
370 | iommu_device_link(&data->iommu, dev); | ||
371 | |||
368 | group = iommu_group_get_for_dev(dev); | 372 | group = iommu_group_get_for_dev(dev); |
369 | if (IS_ERR(group)) | 373 | if (IS_ERR(group)) |
370 | return PTR_ERR(group); | 374 | return PTR_ERR(group); |
@@ -375,9 +379,14 @@ static int mtk_iommu_add_device(struct device *dev) | |||
375 | 379 | ||
376 | static void mtk_iommu_remove_device(struct device *dev) | 380 | static void mtk_iommu_remove_device(struct device *dev) |
377 | { | 381 | { |
382 | struct mtk_iommu_data *data; | ||
383 | |||
378 | if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops) | 384 | if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != &mtk_iommu_ops) |
379 | return; | 385 | return; |
380 | 386 | ||
387 | data = dev->iommu_fwspec->iommu_priv; | ||
388 | iommu_device_unlink(&data->iommu, dev); | ||
389 | |||
381 | iommu_group_remove_device(dev); | 390 | iommu_group_remove_device(dev); |
382 | iommu_fwspec_free(dev); | 391 | iommu_fwspec_free(dev); |
383 | } | 392 | } |
@@ -497,6 +506,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) | |||
497 | struct mtk_iommu_data *data; | 506 | struct mtk_iommu_data *data; |
498 | struct device *dev = &pdev->dev; | 507 | struct device *dev = &pdev->dev; |
499 | struct resource *res; | 508 | struct resource *res; |
509 | resource_size_t ioaddr; | ||
500 | struct component_match *match = NULL; | 510 | struct component_match *match = NULL; |
501 | void *protect; | 511 | void *protect; |
502 | int i, larb_nr, ret; | 512 | int i, larb_nr, ret; |
@@ -519,6 +529,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) | |||
519 | data->base = devm_ioremap_resource(dev, res); | 529 | data->base = devm_ioremap_resource(dev, res); |
520 | if (IS_ERR(data->base)) | 530 | if (IS_ERR(data->base)) |
521 | return PTR_ERR(data->base); | 531 | return PTR_ERR(data->base); |
532 | ioaddr = res->start; | ||
522 | 533 | ||
523 | data->irq = platform_get_irq(pdev, 0); | 534 | data->irq = platform_get_irq(pdev, 0); |
524 | if (data->irq < 0) | 535 | if (data->irq < 0) |
@@ -567,6 +578,18 @@ static int mtk_iommu_probe(struct platform_device *pdev) | |||
567 | if (ret) | 578 | if (ret) |
568 | return ret; | 579 | return ret; |
569 | 580 | ||
581 | ret = iommu_device_sysfs_add(&data->iommu, dev, NULL, | ||
582 | "mtk-iommu.%pa", &ioaddr); | ||
583 | if (ret) | ||
584 | return ret; | ||
585 | |||
586 | iommu_device_set_ops(&data->iommu, &mtk_iommu_ops); | ||
587 | iommu_device_set_fwnode(&data->iommu, &pdev->dev.of_node->fwnode); | ||
588 | |||
589 | ret = iommu_device_register(&data->iommu); | ||
590 | if (ret) | ||
591 | return ret; | ||
592 | |||
570 | if (!iommu_present(&platform_bus_type)) | 593 | if (!iommu_present(&platform_bus_type)) |
571 | bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); | 594 | bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); |
572 | 595 | ||
@@ -577,6 +600,9 @@ static int mtk_iommu_remove(struct platform_device *pdev) | |||
577 | { | 600 | { |
578 | struct mtk_iommu_data *data = platform_get_drvdata(pdev); | 601 | struct mtk_iommu_data *data = platform_get_drvdata(pdev); |
579 | 602 | ||
603 | iommu_device_sysfs_remove(&data->iommu); | ||
604 | iommu_device_unregister(&data->iommu); | ||
605 | |||
580 | if (iommu_present(&platform_bus_type)) | 606 | if (iommu_present(&platform_bus_type)) |
581 | bus_set_iommu(&platform_bus_type, NULL); | 607 | bus_set_iommu(&platform_bus_type, NULL); |
582 | 608 | ||
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h index 50177f738e4e..2a28eadeea0e 100644 --- a/drivers/iommu/mtk_iommu.h +++ b/drivers/iommu/mtk_iommu.h | |||
@@ -47,6 +47,8 @@ struct mtk_iommu_data { | |||
47 | struct iommu_group *m4u_group; | 47 | struct iommu_group *m4u_group; |
48 | struct mtk_smi_iommu smi_imu; /* SMI larb iommu info */ | 48 | struct mtk_smi_iommu smi_imu; /* SMI larb iommu info */ |
49 | bool enable_4GB; | 49 | bool enable_4GB; |
50 | |||
51 | struct iommu_device iommu; | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | static inline int compare_of(struct device *dev, void *data) | 54 | static inline int compare_of(struct device *dev, void *data) |