Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ede5d92 authored by Mitchel Humpherys's avatar Mitchel Humpherys Committed by Patrick Daly
Browse files

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: default avatarMitchel Humpherys <mitchelh@codeaurora.org>
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 017ee4b0
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -1569,6 +1569,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);
}

void iommu_get_dm_regions(struct device *dev, struct list_head *list)
{
	const struct iommu_ops *ops = dev->bus->iommu_ops;
+21 −0
Original line number Diff line number Diff line
@@ -172,6 +172,8 @@ struct iommu_dm_region {
 * @of_xlate: add OF master IDs to iommu grouping
 * @pgsize_bitmap: bitmap of all possible 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);
@@ -214,6 +216,10 @@ struct iommu_ops {
	/* Get the number of windows per domain */
	u32 (*domain_get_windows)(struct iommu_domain *domain);
	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);

	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);

@@ -352,6 +358,10 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain,
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);
/* PCI device grouping function */
extern struct iommu_group *pci_device_group(struct device *dev);
/* Generic device grouping function */
@@ -578,6 +588,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)
{
}

#endif /* CONFIG_IOMMU_API */

#endif /* __LINUX_IOMMU_H */