aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/iommu/omap-iommu.c39
-rw-r--r--drivers/iommu/omap-iommu.h1
2 files changed, 39 insertions, 1 deletions
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index ef44fc740da7..95dfca36ccb9 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -943,9 +943,13 @@ static int omap_iommu_probe(struct platform_device *pdev)
943 return err; 943 return err;
944 platform_set_drvdata(pdev, obj); 944 platform_set_drvdata(pdev, obj);
945 945
946 obj->group = iommu_group_alloc();
947 if (IS_ERR(obj->group))
948 return PTR_ERR(obj->group);
949
946 err = iommu_device_sysfs_add(&obj->iommu, obj->dev, NULL, obj->name); 950 err = iommu_device_sysfs_add(&obj->iommu, obj->dev, NULL, obj->name);
947 if (err) 951 if (err)
948 return err; 952 goto out_group;
949 953
950 iommu_device_set_ops(&obj->iommu, &omap_iommu_ops); 954 iommu_device_set_ops(&obj->iommu, &omap_iommu_ops);
951 955
@@ -959,10 +963,13 @@ static int omap_iommu_probe(struct platform_device *pdev)
959 omap_iommu_debugfs_add(obj); 963 omap_iommu_debugfs_add(obj);
960 964
961 dev_info(&pdev->dev, "%s registered\n", obj->name); 965 dev_info(&pdev->dev, "%s registered\n", obj->name);
966
962 return 0; 967 return 0;
963 968
964out_sysfs: 969out_sysfs:
965 iommu_device_sysfs_remove(&obj->iommu); 970 iommu_device_sysfs_remove(&obj->iommu);
971out_group:
972 iommu_group_put(obj->group);
966 return err; 973 return err;
967} 974}
968 975
@@ -970,6 +977,9 @@ static int omap_iommu_remove(struct platform_device *pdev)
970{ 977{
971 struct omap_iommu *obj = platform_get_drvdata(pdev); 978 struct omap_iommu *obj = platform_get_drvdata(pdev);
972 979
980 iommu_group_put(obj->group);
981 obj->group = NULL;
982
973 iommu_device_sysfs_remove(&obj->iommu); 983 iommu_device_sysfs_remove(&obj->iommu);
974 iommu_device_unregister(&obj->iommu); 984 iommu_device_unregister(&obj->iommu);
975 985
@@ -1217,6 +1227,7 @@ static int omap_iommu_add_device(struct device *dev)
1217{ 1227{
1218 struct omap_iommu_arch_data *arch_data; 1228 struct omap_iommu_arch_data *arch_data;
1219 struct omap_iommu *oiommu; 1229 struct omap_iommu *oiommu;
1230 struct iommu_group *group;
1220 struct device_node *np; 1231 struct device_node *np;
1221 struct platform_device *pdev; 1232 struct platform_device *pdev;
1222 int ret; 1233 int ret;
@@ -1262,6 +1273,19 @@ static int omap_iommu_add_device(struct device *dev)
1262 arch_data->iommu_dev = oiommu; 1273 arch_data->iommu_dev = oiommu;
1263 dev->archdata.iommu = arch_data; 1274 dev->archdata.iommu = arch_data;
1264 1275
1276 /*
1277 * IOMMU group initialization calls into omap_iommu_device_group, which
1278 * needs a valid dev->archdata.iommu pointer
1279 */
1280 group = iommu_group_get_for_dev(dev);
1281 if (IS_ERR(group)) {
1282 iommu_device_unlink(&oiommu->iommu, dev);
1283 dev->archdata.iommu = NULL;
1284 kfree(arch_data);
1285 return PTR_ERR(group);
1286 }
1287 iommu_group_put(group);
1288
1265 of_node_put(np); 1289 of_node_put(np);
1266 1290
1267 return 0; 1291 return 0;
@@ -1275,12 +1299,24 @@ static void omap_iommu_remove_device(struct device *dev)
1275 return; 1299 return;
1276 1300
1277 iommu_device_unlink(&arch_data->iommu_dev->iommu, dev); 1301 iommu_device_unlink(&arch_data->iommu_dev->iommu, dev);
1302 iommu_group_remove_device(dev);
1278 1303
1279 dev->archdata.iommu = NULL; 1304 dev->archdata.iommu = NULL;
1280 kfree(arch_data); 1305 kfree(arch_data);
1281 1306
1282} 1307}
1283 1308
1309static struct iommu_group *omap_iommu_device_group(struct device *dev)
1310{
1311 struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
1312 struct iommu_group *group = NULL;
1313
1314 if (arch_data->iommu_dev)
1315 group = arch_data->iommu_dev->group;
1316
1317 return group;
1318}
1319
1284static const struct iommu_ops omap_iommu_ops = { 1320static const struct iommu_ops omap_iommu_ops = {
1285 .domain_alloc = omap_iommu_domain_alloc, 1321 .domain_alloc = omap_iommu_domain_alloc,
1286 .domain_free = omap_iommu_domain_free, 1322 .domain_free = omap_iommu_domain_free,
@@ -1292,6 +1328,7 @@ static const struct iommu_ops omap_iommu_ops = {
1292 .iova_to_phys = omap_iommu_iova_to_phys, 1328 .iova_to_phys = omap_iommu_iova_to_phys,
1293 .add_device = omap_iommu_add_device, 1329 .add_device = omap_iommu_add_device,
1294 .remove_device = omap_iommu_remove_device, 1330 .remove_device = omap_iommu_remove_device,
1331 .device_group = omap_iommu_device_group,
1295 .pgsize_bitmap = OMAP_IOMMU_PGSIZES, 1332 .pgsize_bitmap = OMAP_IOMMU_PGSIZES,
1296}; 1333};
1297 1334
diff --git a/drivers/iommu/omap-iommu.h b/drivers/iommu/omap-iommu.h
index 758958a4712c..6e70515e6038 100644
--- a/drivers/iommu/omap-iommu.h
+++ b/drivers/iommu/omap-iommu.h
@@ -70,6 +70,7 @@ struct omap_iommu {
70 u32 id; 70 u32 id;
71 71
72 struct iommu_device iommu; 72 struct iommu_device iommu;
73 struct iommu_group *group;
73}; 74};
74 75
75/** 76/**