summaryrefslogtreecommitdiff
path: root/drivers/iommu/s390-iommu.c
diff options
context:
space:
mode:
authorJoerg Roedel <jroedel@suse.de>2017-04-27 15:44:06 +0300
committerJoerg Roedel <jroedel@suse.de>2017-08-15 19:22:45 +0300
commitf42c22351455bcc8b9eecea19b48bdb499a50a65 (patch)
treebef9c48454e3d1d0f9df8806c6897a26a6172db6 /drivers/iommu/s390-iommu.c
parentef954844c7ace62f773f4f23e28d2d915adc419f (diff)
downloadlinux-f42c22351455bcc8b9eecea19b48bdb499a50a65.tar.xz
iommu/s390: Add support for iommu_device handling
Add support for the iommu_device_register interface to make the s390 hardware iommus visible to the iommu core and in sysfs. Acked-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/s390-iommu.c')
-rw-r--r--drivers/iommu/s390-iommu.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index 8788640756a7..85f3bc52efc2 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -18,6 +18,8 @@
*/
#define S390_IOMMU_PGSIZES (~0xFFFUL)
+static struct iommu_ops s390_iommu_ops;
+
struct s390_domain {
struct iommu_domain domain;
struct list_head devices;
@@ -166,11 +168,13 @@ static void s390_iommu_detach_device(struct iommu_domain *domain,
static int s390_iommu_add_device(struct device *dev)
{
struct iommu_group *group = iommu_group_get_for_dev(dev);
+ struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;
if (IS_ERR(group))
return PTR_ERR(group);
iommu_group_put(group);
+ iommu_device_link(&zdev->iommu_dev, dev);
return 0;
}
@@ -197,6 +201,7 @@ static void s390_iommu_remove_device(struct device *dev)
s390_iommu_detach_device(domain, dev);
}
+ iommu_device_unlink(&zdev->iommu_dev, dev);
iommu_group_remove_device(dev);
}
@@ -327,6 +332,36 @@ static size_t s390_iommu_unmap(struct iommu_domain *domain,
return size;
}
+int zpci_init_iommu(struct zpci_dev *zdev)
+{
+ int rc = 0;
+
+ rc = iommu_device_sysfs_add(&zdev->iommu_dev, NULL, NULL,
+ "s390-iommu.%08x", zdev->fid);
+ if (rc)
+ goto out_err;
+
+ iommu_device_set_ops(&zdev->iommu_dev, &s390_iommu_ops);
+
+ rc = iommu_device_register(&zdev->iommu_dev);
+ if (rc)
+ goto out_sysfs;
+
+ return 0;
+
+out_sysfs:
+ iommu_device_sysfs_remove(&zdev->iommu_dev);
+
+out_err:
+ return rc;
+}
+
+void zpci_destroy_iommu(struct zpci_dev *zdev)
+{
+ iommu_device_unregister(&zdev->iommu_dev);
+ iommu_device_sysfs_remove(&zdev->iommu_dev);
+}
+
static struct iommu_ops s390_iommu_ops = {
.capable = s390_iommu_capable,
.domain_alloc = s390_domain_alloc,