diff options
-rw-r--r-- | drivers/iommu/rockchip-iommu.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 9afcbf79f0b0..36d089025f4c 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c | |||
@@ -90,6 +90,7 @@ struct rk_iommu { | |||
90 | void __iomem **bases; | 90 | void __iomem **bases; |
91 | int num_mmu; | 91 | int num_mmu; |
92 | int irq; | 92 | int irq; |
93 | struct iommu_device iommu; | ||
93 | struct list_head node; /* entry in rk_iommu_domain.iommus */ | 94 | struct list_head node; /* entry in rk_iommu_domain.iommus */ |
94 | struct iommu_domain *domain; /* domain to which iommu is attached */ | 95 | struct iommu_domain *domain; /* domain to which iommu is attached */ |
95 | }; | 96 | }; |
@@ -1032,6 +1033,7 @@ static int rk_iommu_group_set_iommudata(struct iommu_group *group, | |||
1032 | static int rk_iommu_add_device(struct device *dev) | 1033 | static int rk_iommu_add_device(struct device *dev) |
1033 | { | 1034 | { |
1034 | struct iommu_group *group; | 1035 | struct iommu_group *group; |
1036 | struct rk_iommu *iommu; | ||
1035 | int ret; | 1037 | int ret; |
1036 | 1038 | ||
1037 | if (!rk_iommu_is_dev_iommu_master(dev)) | 1039 | if (!rk_iommu_is_dev_iommu_master(dev)) |
@@ -1054,6 +1056,10 @@ static int rk_iommu_add_device(struct device *dev) | |||
1054 | if (ret) | 1056 | if (ret) |
1055 | goto err_remove_device; | 1057 | goto err_remove_device; |
1056 | 1058 | ||
1059 | iommu = rk_iommu_from_dev(dev); | ||
1060 | if (iommu) | ||
1061 | iommu_device_link(&iommu->iommu, dev); | ||
1062 | |||
1057 | iommu_group_put(group); | 1063 | iommu_group_put(group); |
1058 | 1064 | ||
1059 | return 0; | 1065 | return 0; |
@@ -1067,9 +1073,15 @@ err_put_group: | |||
1067 | 1073 | ||
1068 | static void rk_iommu_remove_device(struct device *dev) | 1074 | static void rk_iommu_remove_device(struct device *dev) |
1069 | { | 1075 | { |
1076 | struct rk_iommu *iommu; | ||
1077 | |||
1070 | if (!rk_iommu_is_dev_iommu_master(dev)) | 1078 | if (!rk_iommu_is_dev_iommu_master(dev)) |
1071 | return; | 1079 | return; |
1072 | 1080 | ||
1081 | iommu = rk_iommu_from_dev(dev); | ||
1082 | if (iommu) | ||
1083 | iommu_device_unlink(&iommu->iommu, dev); | ||
1084 | |||
1073 | iommu_group_remove_device(dev); | 1085 | iommu_group_remove_device(dev); |
1074 | } | 1086 | } |
1075 | 1087 | ||
@@ -1117,7 +1129,7 @@ static int rk_iommu_probe(struct platform_device *pdev) | |||
1117 | struct rk_iommu *iommu; | 1129 | struct rk_iommu *iommu; |
1118 | struct resource *res; | 1130 | struct resource *res; |
1119 | int num_res = pdev->num_resources; | 1131 | int num_res = pdev->num_resources; |
1120 | int i; | 1132 | int err, i; |
1121 | 1133 | ||
1122 | iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); | 1134 | iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); |
1123 | if (!iommu) | 1135 | if (!iommu) |
@@ -1150,11 +1162,25 @@ static int rk_iommu_probe(struct platform_device *pdev) | |||
1150 | return -ENXIO; | 1162 | return -ENXIO; |
1151 | } | 1163 | } |
1152 | 1164 | ||
1153 | return 0; | 1165 | err = iommu_device_sysfs_add(&iommu->iommu, dev, NULL, dev_name(dev)); |
1166 | if (err) | ||
1167 | return err; | ||
1168 | |||
1169 | iommu_device_set_ops(&iommu->iommu, &rk_iommu_ops); | ||
1170 | err = iommu_device_register(&iommu->iommu); | ||
1171 | |||
1172 | return err; | ||
1154 | } | 1173 | } |
1155 | 1174 | ||
1156 | static int rk_iommu_remove(struct platform_device *pdev) | 1175 | static int rk_iommu_remove(struct platform_device *pdev) |
1157 | { | 1176 | { |
1177 | struct rk_iommu *iommu = platform_get_drvdata(pdev); | ||
1178 | |||
1179 | if (iommu) { | ||
1180 | iommu_device_sysfs_remove(&iommu->iommu); | ||
1181 | iommu_device_unregister(&iommu->iommu); | ||
1182 | } | ||
1183 | |||
1158 | return 0; | 1184 | return 0; |
1159 | } | 1185 | } |
1160 | 1186 | ||