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) |
