diff options
author | Joerg Roedel <jroedel@suse.de> | 2015-10-21 17:51:41 -0400 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2015-10-21 18:00:49 -0400 |
commit | af65993224c1cfd40b81080c95c6c68d41fc46c7 (patch) | |
tree | ce3c10250236fd439b48e1e8e29f734af08af366 /drivers/iommu | |
parent | d5e582971576698ab3e0236359f1ab5b91686047 (diff) |
iommu/arm-smmu: Switch to device_group call-back
This converts the ARM SMMU and the SMMUv3 driver to use the
new device_group call-back.
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/arm-smmu-v3.c | 1 | ||||
-rw-r--r-- | drivers/iommu/arm-smmu.c | 77 |
2 files changed, 47 insertions, 31 deletions
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index dafaf59dc3b8..fbd4fedd5162 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c | |||
@@ -1898,6 +1898,7 @@ static struct iommu_ops arm_smmu_ops = { | |||
1898 | .iova_to_phys = arm_smmu_iova_to_phys, | 1898 | .iova_to_phys = arm_smmu_iova_to_phys, |
1899 | .add_device = arm_smmu_add_device, | 1899 | .add_device = arm_smmu_add_device, |
1900 | .remove_device = arm_smmu_remove_device, | 1900 | .remove_device = arm_smmu_remove_device, |
1901 | .device_group = pci_device_group, | ||
1901 | .domain_get_attr = arm_smmu_domain_get_attr, | 1902 | .domain_get_attr = arm_smmu_domain_get_attr, |
1902 | .domain_set_attr = arm_smmu_domain_set_attr, | 1903 | .domain_set_attr = arm_smmu_domain_set_attr, |
1903 | .pgsize_bitmap = -1UL, /* Restricted during device attach */ | 1904 | .pgsize_bitmap = -1UL, /* Restricted during device attach */ |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 48a39dfa9777..b4c0629d7f7d 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -1292,33 +1292,25 @@ static void __arm_smmu_release_pci_iommudata(void *data) | |||
1292 | kfree(data); | 1292 | kfree(data); |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | static int arm_smmu_add_pci_device(struct pci_dev *pdev) | 1295 | static int arm_smmu_init_pci_device(struct pci_dev *pdev, |
1296 | struct iommu_group *group) | ||
1296 | { | 1297 | { |
1297 | int i, ret; | ||
1298 | u16 sid; | ||
1299 | struct iommu_group *group; | ||
1300 | struct arm_smmu_master_cfg *cfg; | 1298 | struct arm_smmu_master_cfg *cfg; |
1301 | 1299 | u16 sid; | |
1302 | group = iommu_group_get_for_dev(&pdev->dev); | 1300 | int i; |
1303 | if (IS_ERR(group)) | ||
1304 | return PTR_ERR(group); | ||
1305 | 1301 | ||
1306 | cfg = iommu_group_get_iommudata(group); | 1302 | cfg = iommu_group_get_iommudata(group); |
1307 | if (!cfg) { | 1303 | if (!cfg) { |
1308 | cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); | 1304 | cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); |
1309 | if (!cfg) { | 1305 | if (!cfg) |
1310 | ret = -ENOMEM; | 1306 | return -ENOMEM; |
1311 | goto out_put_group; | ||
1312 | } | ||
1313 | 1307 | ||
1314 | iommu_group_set_iommudata(group, cfg, | 1308 | iommu_group_set_iommudata(group, cfg, |
1315 | __arm_smmu_release_pci_iommudata); | 1309 | __arm_smmu_release_pci_iommudata); |
1316 | } | 1310 | } |
1317 | 1311 | ||
1318 | if (cfg->num_streamids >= MAX_MASTER_STREAMIDS) { | 1312 | if (cfg->num_streamids >= MAX_MASTER_STREAMIDS) |
1319 | ret = -ENOSPC; | 1313 | return -ENOSPC; |
1320 | goto out_put_group; | ||
1321 | } | ||
1322 | 1314 | ||
1323 | /* | 1315 | /* |
1324 | * Assume Stream ID == Requester ID for now. | 1316 | * Assume Stream ID == Requester ID for now. |
@@ -1334,16 +1326,13 @@ static int arm_smmu_add_pci_device(struct pci_dev *pdev) | |||
1334 | cfg->streamids[cfg->num_streamids++] = sid; | 1326 | cfg->streamids[cfg->num_streamids++] = sid; |
1335 | 1327 | ||
1336 | return 0; | 1328 | return 0; |
1337 | out_put_group: | ||
1338 | iommu_group_put(group); | ||
1339 | return ret; | ||
1340 | } | 1329 | } |
1341 | 1330 | ||
1342 | static int arm_smmu_add_platform_device(struct device *dev) | 1331 | static int arm_smmu_init_platform_device(struct device *dev, |
1332 | struct iommu_group *group) | ||
1343 | { | 1333 | { |
1344 | struct iommu_group *group; | ||
1345 | struct arm_smmu_master *master; | ||
1346 | struct arm_smmu_device *smmu = find_smmu_for_device(dev); | 1334 | struct arm_smmu_device *smmu = find_smmu_for_device(dev); |
1335 | struct arm_smmu_master *master; | ||
1347 | 1336 | ||
1348 | if (!smmu) | 1337 | if (!smmu) |
1349 | return -ENODEV; | 1338 | return -ENODEV; |
@@ -1352,21 +1341,20 @@ static int arm_smmu_add_platform_device(struct device *dev) | |||
1352 | if (!master) | 1341 | if (!master) |
1353 | return -ENODEV; | 1342 | return -ENODEV; |
1354 | 1343 | ||
1355 | /* No automatic group creation for platform devices */ | ||
1356 | group = iommu_group_alloc(); | ||
1357 | if (IS_ERR(group)) | ||
1358 | return PTR_ERR(group); | ||
1359 | |||
1360 | iommu_group_set_iommudata(group, &master->cfg, NULL); | 1344 | iommu_group_set_iommudata(group, &master->cfg, NULL); |
1361 | return iommu_group_add_device(group, dev); | 1345 | |
1346 | return 0; | ||
1362 | } | 1347 | } |
1363 | 1348 | ||
1364 | static int arm_smmu_add_device(struct device *dev) | 1349 | static int arm_smmu_add_device(struct device *dev) |
1365 | { | 1350 | { |
1366 | if (dev_is_pci(dev)) | 1351 | struct iommu_group *group; |
1367 | return arm_smmu_add_pci_device(to_pci_dev(dev)); | ||
1368 | 1352 | ||
1369 | return arm_smmu_add_platform_device(dev); | 1353 | group = iommu_group_get_for_dev(dev); |
1354 | if (IS_ERR(group)) | ||
1355 | return PTR_ERR(group); | ||
1356 | |||
1357 | return 0; | ||
1370 | } | 1358 | } |
1371 | 1359 | ||
1372 | static void arm_smmu_remove_device(struct device *dev) | 1360 | static void arm_smmu_remove_device(struct device *dev) |
@@ -1374,6 +1362,32 @@ static void arm_smmu_remove_device(struct device *dev) | |||
1374 | iommu_group_remove_device(dev); | 1362 | iommu_group_remove_device(dev); |
1375 | } | 1363 | } |
1376 | 1364 | ||
1365 | static struct iommu_group *arm_smmu_device_group(struct device *dev) | ||
1366 | { | ||
1367 | struct iommu_group *group; | ||
1368 | int ret; | ||
1369 | |||
1370 | if (dev_is_pci(dev)) | ||
1371 | group = pci_device_group(dev); | ||
1372 | else | ||
1373 | group = generic_device_group(dev); | ||
1374 | |||
1375 | if (IS_ERR(group)) | ||
1376 | return group; | ||
1377 | |||
1378 | if (dev_is_pci(dev)) | ||
1379 | ret = arm_smmu_init_pci_device(to_pci_dev(dev), group); | ||
1380 | else | ||
1381 | ret = arm_smmu_init_platform_device(dev, group); | ||
1382 | |||
1383 | if (ret) { | ||
1384 | iommu_group_put(group); | ||
1385 | group = ERR_PTR(ret); | ||
1386 | } | ||
1387 | |||
1388 | return group; | ||
1389 | } | ||
1390 | |||
1377 | static int arm_smmu_domain_get_attr(struct iommu_domain *domain, | 1391 | static int arm_smmu_domain_get_attr(struct iommu_domain *domain, |
1378 | enum iommu_attr attr, void *data) | 1392 | enum iommu_attr attr, void *data) |
1379 | { | 1393 | { |
@@ -1430,6 +1444,7 @@ static struct iommu_ops arm_smmu_ops = { | |||
1430 | .iova_to_phys = arm_smmu_iova_to_phys, | 1444 | .iova_to_phys = arm_smmu_iova_to_phys, |
1431 | .add_device = arm_smmu_add_device, | 1445 | .add_device = arm_smmu_add_device, |
1432 | .remove_device = arm_smmu_remove_device, | 1446 | .remove_device = arm_smmu_remove_device, |
1447 | .device_group = arm_smmu_device_group, | ||
1433 | .domain_get_attr = arm_smmu_domain_get_attr, | 1448 | .domain_get_attr = arm_smmu_domain_get_attr, |
1434 | .domain_set_attr = arm_smmu_domain_set_attr, | 1449 | .domain_set_attr = arm_smmu_domain_set_attr, |
1435 | .pgsize_bitmap = -1UL, /* Restricted during device attach */ | 1450 | .pgsize_bitmap = -1UL, /* Restricted during device attach */ |