Merge branches 'iommu/fixes', 'arm/exynos', 'arm/renesas', 'arm/smmu', 'arm/mediatek', 'arm/core', 'x86/vt-d' and 'core' into next
This commit is contained in:

@@ -31,6 +31,13 @@
|
||||
#define IOMMU_CACHE (1 << 2) /* DMA cache coherency */
|
||||
#define IOMMU_NOEXEC (1 << 3)
|
||||
#define IOMMU_MMIO (1 << 4) /* e.g. things like MSI doorbells */
|
||||
/*
|
||||
* This is to make the IOMMU API setup privileged
|
||||
* mapppings accessible by the master only at higher
|
||||
* privileged execution level and inaccessible at
|
||||
* less privileged levels.
|
||||
*/
|
||||
#define IOMMU_PRIV (1 << 5)
|
||||
|
||||
struct iommu_ops;
|
||||
struct iommu_group;
|
||||
@@ -117,18 +124,25 @@ enum iommu_attr {
|
||||
DOMAIN_ATTR_MAX,
|
||||
};
|
||||
|
||||
/* These are the possible reserved region types */
|
||||
#define IOMMU_RESV_DIRECT (1 << 0)
|
||||
#define IOMMU_RESV_RESERVED (1 << 1)
|
||||
#define IOMMU_RESV_MSI (1 << 2)
|
||||
|
||||
/**
|
||||
* struct iommu_dm_region - descriptor for a direct mapped memory region
|
||||
* struct iommu_resv_region - descriptor for a reserved memory region
|
||||
* @list: Linked list pointers
|
||||
* @start: System physical start address of the region
|
||||
* @length: Length of the region in bytes
|
||||
* @prot: IOMMU Protection flags (READ/WRITE/...)
|
||||
* @type: Type of the reserved region
|
||||
*/
|
||||
struct iommu_dm_region {
|
||||
struct iommu_resv_region {
|
||||
struct list_head list;
|
||||
phys_addr_t start;
|
||||
size_t length;
|
||||
int prot;
|
||||
int type;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IOMMU_API
|
||||
@@ -150,9 +164,9 @@ struct iommu_dm_region {
|
||||
* @device_group: find iommu group for a particular device
|
||||
* @domain_get_attr: Query domain attributes
|
||||
* @domain_set_attr: Change domain attributes
|
||||
* @get_dm_regions: Request list of direct mapping requirements for a device
|
||||
* @put_dm_regions: Free list of direct mapping requirements for a device
|
||||
* @apply_dm_region: Temporary helper call-back for iova reserved ranges
|
||||
* @get_resv_regions: Request list of reserved regions for a device
|
||||
* @put_resv_regions: Free list of reserved regions for a device
|
||||
* @apply_resv_region: Temporary helper call-back for iova reserved ranges
|
||||
* @domain_window_enable: Configure and enable a particular window for a domain
|
||||
* @domain_window_disable: Disable a particular window for a domain
|
||||
* @domain_set_windows: Set the number of windows for a domain
|
||||
@@ -184,11 +198,12 @@ struct iommu_ops {
|
||||
int (*domain_set_attr)(struct iommu_domain *domain,
|
||||
enum iommu_attr attr, void *data);
|
||||
|
||||
/* Request/Free a list of direct mapping requirements for a device */
|
||||
void (*get_dm_regions)(struct device *dev, struct list_head *list);
|
||||
void (*put_dm_regions)(struct device *dev, struct list_head *list);
|
||||
void (*apply_dm_region)(struct device *dev, struct iommu_domain *domain,
|
||||
struct iommu_dm_region *region);
|
||||
/* Request/Free a list of reserved regions for a device */
|
||||
void (*get_resv_regions)(struct device *dev, struct list_head *list);
|
||||
void (*put_resv_regions)(struct device *dev, struct list_head *list);
|
||||
void (*apply_resv_region)(struct device *dev,
|
||||
struct iommu_domain *domain,
|
||||
struct iommu_resv_region *region);
|
||||
|
||||
/* Window handling functions */
|
||||
int (*domain_window_enable)(struct iommu_domain *domain, u32 wnd_nr,
|
||||
@@ -204,6 +219,42 @@ struct iommu_ops {
|
||||
unsigned long pgsize_bitmap;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iommu_device - IOMMU core representation of one IOMMU hardware
|
||||
* instance
|
||||
* @list: Used by the iommu-core to keep a list of registered iommus
|
||||
* @ops: iommu-ops for talking to this iommu
|
||||
* @dev: struct device for sysfs handling
|
||||
*/
|
||||
struct iommu_device {
|
||||
struct list_head list;
|
||||
const struct iommu_ops *ops;
|
||||
struct fwnode_handle *fwnode;
|
||||
struct device dev;
|
||||
};
|
||||
|
||||
int iommu_device_register(struct iommu_device *iommu);
|
||||
void iommu_device_unregister(struct iommu_device *iommu);
|
||||
int iommu_device_sysfs_add(struct iommu_device *iommu,
|
||||
struct device *parent,
|
||||
const struct attribute_group **groups,
|
||||
const char *fmt, ...) __printf(4, 5);
|
||||
void iommu_device_sysfs_remove(struct iommu_device *iommu);
|
||||
int iommu_device_link(struct iommu_device *iommu, struct device *link);
|
||||
void iommu_device_unlink(struct iommu_device *iommu, struct device *link);
|
||||
|
||||
static inline void iommu_device_set_ops(struct iommu_device *iommu,
|
||||
const struct iommu_ops *ops)
|
||||
{
|
||||
iommu->ops = ops;
|
||||
}
|
||||
|
||||
static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
|
||||
struct fwnode_handle *fwnode)
|
||||
{
|
||||
iommu->fwnode = fwnode;
|
||||
}
|
||||
|
||||
#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */
|
||||
#define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */
|
||||
#define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3 /* Pre Driver bind */
|
||||
@@ -233,9 +284,13 @@ extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t io
|
||||
extern void iommu_set_fault_handler(struct iommu_domain *domain,
|
||||
iommu_fault_handler_t handler, void *token);
|
||||
|
||||
extern void iommu_get_dm_regions(struct device *dev, struct list_head *list);
|
||||
extern void iommu_put_dm_regions(struct device *dev, struct list_head *list);
|
||||
extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
|
||||
extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
|
||||
extern int iommu_request_dm_for_dev(struct device *dev);
|
||||
extern struct iommu_resv_region *
|
||||
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot, int type);
|
||||
extern int iommu_get_group_resv_regions(struct iommu_group *group,
|
||||
struct list_head *head);
|
||||
|
||||
extern int iommu_attach_group(struct iommu_domain *domain,
|
||||
struct iommu_group *group);
|
||||
@@ -267,12 +322,6 @@ extern int iommu_domain_get_attr(struct iommu_domain *domain, enum iommu_attr,
|
||||
void *data);
|
||||
extern int iommu_domain_set_attr(struct iommu_domain *domain, enum iommu_attr,
|
||||
void *data);
|
||||
struct device *iommu_device_create(struct device *parent, void *drvdata,
|
||||
const struct attribute_group **groups,
|
||||
const char *fmt, ...) __printf(4, 5);
|
||||
void iommu_device_destroy(struct device *dev);
|
||||
int iommu_device_link(struct device *dev, struct device *link);
|
||||
void iommu_device_unlink(struct device *dev, struct device *link);
|
||||
|
||||
/* Window handling function prototypes */
|
||||
extern int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
|
||||
@@ -352,15 +401,14 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode,
|
||||
const struct iommu_ops *ops);
|
||||
void iommu_fwspec_free(struct device *dev);
|
||||
int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
|
||||
void iommu_register_instance(struct fwnode_handle *fwnode,
|
||||
const struct iommu_ops *ops);
|
||||
const struct iommu_ops *iommu_get_instance(struct fwnode_handle *fwnode);
|
||||
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
|
||||
|
||||
#else /* CONFIG_IOMMU_API */
|
||||
|
||||
struct iommu_ops {};
|
||||
struct iommu_group {};
|
||||
struct iommu_fwspec {};
|
||||
struct iommu_device {};
|
||||
|
||||
static inline bool iommu_present(struct bus_type *bus)
|
||||
{
|
||||
@@ -443,16 +491,22 @@ static inline void iommu_set_fault_handler(struct iommu_domain *domain,
|
||||
{
|
||||
}
|
||||
|
||||
static inline void iommu_get_dm_regions(struct device *dev,
|
||||
static inline void iommu_get_resv_regions(struct device *dev,
|
||||
struct list_head *list)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void iommu_put_dm_regions(struct device *dev,
|
||||
static inline void iommu_put_resv_regions(struct device *dev,
|
||||
struct list_head *list)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int iommu_get_group_resv_regions(struct iommu_group *group,
|
||||
struct list_head *head)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int iommu_request_dm_for_dev(struct device *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
@@ -546,15 +600,34 @@ static inline int iommu_domain_set_attr(struct iommu_domain *domain,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline struct device *iommu_device_create(struct device *parent,
|
||||
void *drvdata,
|
||||
const struct attribute_group **groups,
|
||||
const char *fmt, ...)
|
||||
static inline int iommu_device_register(struct iommu_device *iommu)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void iommu_device_destroy(struct device *dev)
|
||||
static inline void iommu_device_set_ops(struct iommu_device *iommu,
|
||||
const struct iommu_ops *ops)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
|
||||
struct fwnode_handle *fwnode)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void iommu_device_unregister(struct iommu_device *iommu)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int iommu_device_sysfs_add(struct iommu_device *iommu,
|
||||
struct device *parent,
|
||||
const struct attribute_group **groups,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void iommu_device_sysfs_remove(struct iommu_device *iommu)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -584,13 +657,8 @@ static inline int iommu_fwspec_add_ids(struct device *dev, u32 *ids,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline void iommu_register_instance(struct fwnode_handle *fwnode,
|
||||
const struct iommu_ops *ops)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
const struct iommu_ops *iommu_get_instance(struct fwnode_handle *fwnode)
|
||||
const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user