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

Commit 66b5589d authored by Chintan Pandya's avatar Chintan Pandya
Browse files

iommu: add support for multiple iommu drivers



Some targets may have more than 1 SMMU IPs which
require different driver supports. By default,
all the driver register themselves onto platform
bus. But platform bus cannot support more than
one IOMMU ops implementation. So, move MSM driver
onto separate bus and provide and interface to
select the right bus just before requesting for
a domain.

Add following API:
msm_iommu_get_bus(struct device *dev)

Change-Id: I116ecb203b73157bf5cd6220391344a01a165bb1
Signed-off-by: default avatarChintan Pandya <cpandya@codeaurora.org>
parent 0597b5d5
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1718,8 +1718,14 @@ static struct iommu_ops msm_iommu_ops = {

static int __init msm_iommu_init(void)
{
	int ret;

	msm_iommu_pagetable_init();
	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
	ret = msm_iommu_bus_register();
	if (ret)
		return ret;

	bus_set_iommu(msm_iommu_non_sec_bus_type, &msm_iommu_ops);
	msm_iommu_build_dump_regs_table();

	return 0;
+39 −0
Original line number Diff line number Diff line
@@ -48,6 +48,45 @@ struct bus_type msm_iommu_sec_bus_type = {
	.name = "msm_iommu_sec_bus",
};

struct bus_type iommu_non_sec_bus_type = {
	.name = "msm_iommu_non_sec_bus",
};

struct bus_type *msm_iommu_non_sec_bus_type;

#ifndef CONFIG_ARM_SMMU
int msm_iommu_bus_register(void)
{
	msm_iommu_non_sec_bus_type = &platform_bus_type;
	return 0;
}
#else
int msm_iommu_bus_register(void)
{
	msm_iommu_non_sec_bus_type = &iommu_non_sec_bus_type;
	return bus_register(msm_iommu_non_sec_bus_type);
}
#endif

/**
 * Pass the context bank device here. Based on the context bank
 * device, the bus is chosen and hence the respective IOMMU ops.
 */
struct bus_type *msm_iommu_get_bus(struct device *dev)
{
	if (!dev)
		return NULL;

	if (of_device_is_compatible(dev->of_node, "qcom,msm-smmu-v2-ctx")) {
		if (of_property_read_bool(dev->of_node, "qcom,secure-context"))
			return &msm_iommu_sec_bus_type;
		else
			return msm_iommu_non_sec_bus_type;
	} else
		return &platform_bus_type;
}
EXPORT_SYMBOL(msm_iommu_get_bus);

void msm_set_iommu_access_ops(struct iommu_access_ops *ops)
{
	iommu_access_ops = ops;
+8 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

extern pgprot_t     pgprot_kernel;
extern struct bus_type msm_iommu_sec_bus_type;
extern struct bus_type *msm_iommu_non_sec_bus_type;
extern struct iommu_access_ops iommu_access_ops_v0;
extern struct iommu_access_ops iommu_access_ops_v1;

@@ -330,11 +331,18 @@ void msm_iommu_remote_p0_spin_unlock(unsigned int need_lock);
 * their platform devices.
 */
struct device *msm_iommu_get_ctx(const char *ctx_name);
struct bus_type *msm_iommu_get_bus(struct device *dev);
int msm_iommu_bus_register(void);
#else
static inline struct device *msm_iommu_get_ctx(const char *ctx_name)
{
	return NULL;
}

static inline struct bus_type *msm_iommu_get_bus(struct device *dev)
{
	return &platform_bus_type;
}
#endif

/*