diff options
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/arm-smmu.c | 19 |
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 | ||
1533 | static void arm_smmu_remove_device(struct device *dev) | 1549 | static 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 | ||
1538 | static struct iommu_ops arm_smmu_ops = { | 1555 | static struct iommu_ops arm_smmu_ops = { |