root/drivers/iommu/iommu-sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. release_device
  2. iommu_dev_init
  3. iommu_device_sysfs_add
  4. iommu_device_sysfs_remove
  5. iommu_device_link
  6. iommu_device_unlink

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * IOMMU sysfs class support
   4  *
   5  * Copyright (C) 2014 Red Hat, Inc.  All rights reserved.
   6  *     Author: Alex Williamson <alex.williamson@redhat.com>
   7  */
   8 
   9 #include <linux/device.h>
  10 #include <linux/iommu.h>
  11 #include <linux/init.h>
  12 #include <linux/slab.h>
  13 
  14 /*
  15  * We provide a common class "devices" group which initially has no attributes.
  16  * As devices are added to the IOMMU, we'll add links to the group.
  17  */
  18 static struct attribute *devices_attr[] = {
  19         NULL,
  20 };
  21 
  22 static const struct attribute_group devices_attr_group = {
  23         .name = "devices",
  24         .attrs = devices_attr,
  25 };
  26 
  27 static const struct attribute_group *dev_groups[] = {
  28         &devices_attr_group,
  29         NULL,
  30 };
  31 
  32 static void release_device(struct device *dev)
  33 {
  34         kfree(dev);
  35 }
  36 
  37 static struct class iommu_class = {
  38         .name = "iommu",
  39         .dev_release = release_device,
  40         .dev_groups = dev_groups,
  41 };
  42 
  43 static int __init iommu_dev_init(void)
  44 {
  45         return class_register(&iommu_class);
  46 }
  47 postcore_initcall(iommu_dev_init);
  48 
  49 /*
  50  * Init the struct device for the IOMMU. IOMMU specific attributes can
  51  * be provided as an attribute group, allowing a unique namespace per
  52  * IOMMU type.
  53  */
  54 int iommu_device_sysfs_add(struct iommu_device *iommu,
  55                            struct device *parent,
  56                            const struct attribute_group **groups,
  57                            const char *fmt, ...)
  58 {
  59         va_list vargs;
  60         int ret;
  61 
  62         iommu->dev = kzalloc(sizeof(*iommu->dev), GFP_KERNEL);
  63         if (!iommu->dev)
  64                 return -ENOMEM;
  65 
  66         device_initialize(iommu->dev);
  67 
  68         iommu->dev->class = &iommu_class;
  69         iommu->dev->parent = parent;
  70         iommu->dev->groups = groups;
  71 
  72         va_start(vargs, fmt);
  73         ret = kobject_set_name_vargs(&iommu->dev->kobj, fmt, vargs);
  74         va_end(vargs);
  75         if (ret)
  76                 goto error;
  77 
  78         ret = device_add(iommu->dev);
  79         if (ret)
  80                 goto error;
  81 
  82         dev_set_drvdata(iommu->dev, iommu);
  83 
  84         return 0;
  85 
  86 error:
  87         put_device(iommu->dev);
  88         return ret;
  89 }
  90 
  91 void iommu_device_sysfs_remove(struct iommu_device *iommu)
  92 {
  93         dev_set_drvdata(iommu->dev, NULL);
  94         device_unregister(iommu->dev);
  95         iommu->dev = NULL;
  96 }
  97 /*
  98  * IOMMU drivers can indicate a device is managed by a given IOMMU using
  99  * this interface.  A link to the device will be created in the "devices"
 100  * directory of the IOMMU device in sysfs and an "iommu" link will be
 101  * created under the linked device, pointing back at the IOMMU device.
 102  */
 103 int iommu_device_link(struct iommu_device *iommu, struct device *link)
 104 {
 105         int ret;
 106 
 107         if (!iommu || IS_ERR(iommu))
 108                 return -ENODEV;
 109 
 110         ret = sysfs_add_link_to_group(&iommu->dev->kobj, "devices",
 111                                       &link->kobj, dev_name(link));
 112         if (ret)
 113                 return ret;
 114 
 115         ret = sysfs_create_link_nowarn(&link->kobj, &iommu->dev->kobj, "iommu");
 116         if (ret)
 117                 sysfs_remove_link_from_group(&iommu->dev->kobj, "devices",
 118                                              dev_name(link));
 119 
 120         return ret;
 121 }
 122 
 123 void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
 124 {
 125         if (!iommu || IS_ERR(iommu))
 126                 return;
 127 
 128         sysfs_remove_link(&link->kobj, "iommu");
 129         sysfs_remove_link_from_group(&iommu->dev->kobj, "devices", dev_name(link));
 130 }

/* [<][>][^][v][top][bottom][index][help] */