From b7473024e267ef572a08edb0f9c46ecc16a2922b Mon Sep 17 00:00:00 2001 From: Mitchel Humpherys Date: Fri, 21 Aug 2015 14:06:14 -0700 Subject: [PATCH] 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 --- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 21 +++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 19319a6af476..1e3a0198e7e7 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -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; diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 9a631f87d9d5..ec6d5798de81 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -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) {