2014-06-13 02:12:24 +04:00
/*
* IOMMU sysfs class support
*
* Copyright ( C ) 2014 Red Hat , Inc . All rights reserved .
* Author : Alex Williamson < alex . williamson @ redhat . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/device.h>
# include <linux/iommu.h>
# include <linux/module.h>
2014-07-07 14:01:21 +04:00
# include <linux/slab.h>
2014-06-13 02:12:24 +04:00
/*
* We provide a common class " devices " group which initially has no attributes .
* As devices are added to the IOMMU , we ' ll add links to the group .
*/
static struct attribute * devices_attr [ ] = {
NULL ,
} ;
static const struct attribute_group iommu_devices_attr_group = {
. name = " devices " ,
. attrs = devices_attr ,
} ;
static const struct attribute_group * iommu_dev_groups [ ] = {
& iommu_devices_attr_group ,
NULL ,
} ;
static void iommu_release_device ( struct device * dev )
{
kfree ( dev ) ;
}
static struct class iommu_class = {
. name = " iommu " ,
. dev_release = iommu_release_device ,
. dev_groups = iommu_dev_groups ,
} ;
static int __init iommu_dev_init ( void )
{
return class_register ( & iommu_class ) ;
}
postcore_initcall ( iommu_dev_init ) ;
/*
2017-02-01 18:56:46 +03:00
* Init the struct device for the IOMMU . IOMMU specific attributes can
* be provided as an attribute group , allowing a unique namespace per
* IOMMU type .
2014-06-13 02:12:24 +04:00
*/
2017-02-01 18:56:46 +03:00
int iommu_device_sysfs_add ( struct iommu_device * iommu ,
struct device * parent ,
const struct attribute_group * * groups ,
const char * fmt , . . . )
2014-06-13 02:12:24 +04:00
{
va_list vargs ;
int ret ;
2017-02-01 18:56:46 +03:00
device_initialize ( & iommu - > dev ) ;
2014-06-13 02:12:24 +04:00
2017-02-01 18:56:46 +03:00
iommu - > dev . class = & iommu_class ;
iommu - > dev . parent = parent ;
iommu - > dev . groups = groups ;
2014-06-13 02:12:24 +04:00
va_start ( vargs , fmt ) ;
2017-02-01 18:56:46 +03:00
ret = kobject_set_name_vargs ( & iommu - > dev . kobj , fmt , vargs ) ;
2014-06-13 02:12:24 +04:00
va_end ( vargs ) ;
if ( ret )
goto error ;
2017-02-01 18:56:46 +03:00
ret = device_add ( & iommu - > dev ) ;
2014-06-13 02:12:24 +04:00
if ( ret )
goto error ;
2017-02-01 18:56:46 +03:00
return 0 ;
2014-06-13 02:12:24 +04:00
error :
2017-02-01 18:56:46 +03:00
put_device ( & iommu - > dev ) ;
return ret ;
2014-06-13 02:12:24 +04:00
}
2017-02-01 18:56:46 +03:00
void iommu_device_sysfs_remove ( struct iommu_device * iommu )
2014-06-13 02:12:24 +04:00
{
2017-02-01 18:56:46 +03:00
device_unregister ( & iommu - > dev ) ;
2014-06-13 02:12:24 +04:00
}
/*
* IOMMU drivers can indicate a device is managed by a given IOMMU using
* this interface . A link to the device will be created in the " devices "
* directory of the IOMMU device in sysfs and an " iommu " link will be
* created under the linked device , pointing back at the IOMMU device .
*/
2017-02-01 19:23:22 +03:00
int iommu_device_link ( struct iommu_device * iommu , struct device * link )
2014-06-13 02:12:24 +04:00
{
int ret ;
2017-02-01 19:23:22 +03:00
if ( ! iommu | | IS_ERR ( iommu ) )
2014-06-13 02:12:24 +04:00
return - ENODEV ;
2017-02-01 19:23:22 +03:00
ret = sysfs_add_link_to_group ( & iommu - > dev . kobj , " devices " ,
2014-06-13 02:12:24 +04:00
& link - > kobj , dev_name ( link ) ) ;
if ( ret )
return ret ;
2017-02-01 19:23:22 +03:00
ret = sysfs_create_link_nowarn ( & link - > kobj , & iommu - > dev . kobj , " iommu " ) ;
2014-06-13 02:12:24 +04:00
if ( ret )
2017-02-01 19:23:22 +03:00
sysfs_remove_link_from_group ( & iommu - > dev . kobj , " devices " ,
2014-06-13 02:12:24 +04:00
dev_name ( link ) ) ;
return ret ;
}
2017-02-01 19:23:22 +03:00
void iommu_device_unlink ( struct iommu_device * iommu , struct device * link )
2014-06-13 02:12:24 +04:00
{
2017-02-01 19:23:22 +03:00
if ( ! iommu | | IS_ERR ( iommu ) )
2014-06-13 02:12:24 +04:00
return ;
sysfs_remove_link ( & link - > kobj , " iommu " ) ;
2017-02-01 19:23:22 +03:00
sysfs_remove_link_from_group ( & iommu - > dev . kobj , " devices " , dev_name ( link ) ) ;
2014-06-13 02:12:24 +04:00
}