iommu: Add iommu_reg_read and iommu_reg_write

It might be useful for IOMMU clients to peek and poke at their IOMMU's
registers, but knowing how to access those registers is really the job
of the IOMMU driver (it might need to enable specific clocks and
regulators, for example).  Provide an API to read and write IOMMU
registers that can be implemented by the driver.

Change-Id: I5b2f19225f8bd258278780ff24b4ea96460857aa
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
This commit is contained in:
Mitchel Humpherys 2015-08-21 14:06:14 -07:00 committed by David Keitel
parent e9f7462305
commit b7473024e2
2 changed files with 45 additions and 0 deletions

View file

@ -902,6 +902,30 @@ void iommu_trigger_fault(struct iommu_domain *domain, unsigned long flags)
domain->ops->trigger_fault(domain, flags);
}
/**
* iommu_reg_read() - read an IOMMU register
*
* Reads the IOMMU register at the given offset.
*/
unsigned long iommu_reg_read(struct iommu_domain *domain, unsigned long offset)
{
if (domain->ops->reg_read)
return domain->ops->reg_read(domain, offset);
return 0;
}
/**
* iommu_reg_write() - write an IOMMU register
*
* Writes the given value to the IOMMU register at the given offset.
*/
void iommu_reg_write(struct iommu_domain *domain, unsigned long offset,
unsigned long val)
{
if (domain->ops->reg_write)
domain->ops->reg_write(domain, offset, val);
}
struct iommu_domain *iommu_domain_alloc(struct bus_type *bus)
{
struct iommu_domain *domain;

View file

@ -124,6 +124,8 @@ extern struct dentry *iommu_debugfs_top;
* @domain_set_attr: Change domain attributes
* @pgsize_bitmap: bitmap of supported page sizes
* @trigger_fault: trigger a fault on the device attached to an iommu domain
* @reg_read: read an IOMMU register
* @reg_write: write an IOMMU register
*/
struct iommu_ops {
bool (*capable)(enum iommu_cap);
@ -159,6 +161,10 @@ struct iommu_ops {
int (*dma_supported)(struct iommu_domain *domain, struct device *dev,
u64 mask);
void (*trigger_fault)(struct iommu_domain *domain, unsigned long flags);
unsigned long (*reg_read)(struct iommu_domain *domain,
unsigned long offset);
void (*reg_write)(struct iommu_domain *domain, unsigned long val,
unsigned long offset);
unsigned long pgsize_bitmap;
};
@ -196,6 +202,10 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain,
iommu_fault_handler_t handler, void *token);
extern void iommu_trigger_fault(struct iommu_domain *domain,
unsigned long flags);
extern unsigned long iommu_reg_read(struct iommu_domain *domain,
unsigned long offset);
extern void iommu_reg_write(struct iommu_domain *domain, unsigned long offset,
unsigned long val);
extern int iommu_attach_group(struct iommu_domain *domain,
struct iommu_group *group);
@ -390,6 +400,17 @@ static inline void iommu_trigger_fault(struct iommu_domain *domain,
{
}
static inline unsigned long iommu_reg_read(struct iommu_domain *domain,
unsigned long offset)
{
return 0;
}
static inline void iommu_reg_write(struct iommu_domain *domain,
unsigned long val, unsigned long offset)
{
}
static inline int iommu_attach_group(struct iommu_domain *domain,
struct iommu_group *group)
{