aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorAntonios Motakis <a.motakis@virtualopensystems.com>2013-10-18 11:08:29 -0400
committerWill Deacon <will.deacon@arm.com>2013-12-16 14:30:28 -0500
commit5fc63a7c446e998d01a68b108fe007be675aced7 (patch)
treeb7f5bc54103694b5b9f00030b768504240a19b93 /drivers/iommu
parent319e2e3f63c348a9b66db4667efa73178e18b17d (diff)
iommu/arm-smmu: add devices attached to the SMMU to an IOMMU group
IOMMU groups are expected by certain users of the IOMMU API, e.g. VFIO. Add new devices found by the SMMU driver to an IOMMU group to satisfy those users. Acked-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/arm-smmu.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e46a88700b68..879da20617fb 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1494,6 +1494,13 @@ static int arm_smmu_add_device(struct device *dev)
1494{ 1494{
1495 struct arm_smmu_device *child, *parent, *smmu; 1495 struct arm_smmu_device *child, *parent, *smmu;
1496 struct arm_smmu_master *master = NULL; 1496 struct arm_smmu_master *master = NULL;
1497 struct iommu_group *group;
1498 int ret;
1499
1500 if (dev->archdata.iommu) {
1501 dev_warn(dev, "IOMMU driver already assigned to device\n");
1502 return -EINVAL;
1503 }
1497 1504
1498 spin_lock(&arm_smmu_devices_lock); 1505 spin_lock(&arm_smmu_devices_lock);
1499 list_for_each_entry(parent, &arm_smmu_devices, list) { 1506 list_for_each_entry(parent, &arm_smmu_devices, list) {
@@ -1526,13 +1533,23 @@ static int arm_smmu_add_device(struct device *dev)
1526 if (!master) 1533 if (!master)
1527 return -ENODEV; 1534 return -ENODEV;
1528 1535
1536 group = iommu_group_alloc();
1537 if (IS_ERR(group)) {
1538 dev_err(dev, "Failed to allocate IOMMU group\n");
1539 return PTR_ERR(group);
1540 }
1541
1542 ret = iommu_group_add_device(group, dev);
1543 iommu_group_put(group);
1529 dev->archdata.iommu = smmu; 1544 dev->archdata.iommu = smmu;
1530 return 0; 1545
1546 return ret;
1531} 1547}
1532 1548
1533static void arm_smmu_remove_device(struct device *dev) 1549static void arm_smmu_remove_device(struct device *dev)
1534{ 1550{
1535 dev->archdata.iommu = NULL; 1551 dev->archdata.iommu = NULL;
1552 iommu_group_remove_device(dev);
1536} 1553}
1537 1554
1538static struct iommu_ops arm_smmu_ops = { 1555static struct iommu_ops arm_smmu_ops = {