@@ -46,6 +46,7 @@ to non-secure vs secure interrupt line.
for routing of context bank irq's to secure vs non-
secure lines. (Ie. if the iommu contains secure
context banks)
+- qcom,ctx-num : The number associated to the context bank
** Examples:
@@ -557,7 +557,8 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
* index into qcom_iommu->ctxs:
*/
if (WARN_ON(asid < 1) ||
- WARN_ON(asid > qcom_iommu->num_ctxs))
+ WARN_ON(asid > qcom_iommu->num_ctxs) ||
+ WARN_ON(qcom_iommu->ctxs[asid - 1] == NULL))
return -EINVAL;
if (!fwspec->iommu_priv) {
@@ -665,7 +666,8 @@ static int qcom_iommu_sec_ptbl_init(struct device *dev)
static int get_asid(const struct device_node *np)
{
- u32 reg;
+ u32 reg, val;
+ int asid;
/* read the "reg" property directly to get the relative address
* of the context bank, and calculate the asid from that:
@@ -673,7 +675,16 @@ static int get_asid(const struct device_node *np)
if (of_property_read_u32_index(np, "reg", 0, ®))
return -ENODEV;
- return reg / 0x1000; /* context banks are 0x1000 apart */
+ /* Context banks are 0x1000 apart but, in some cases, the ASID
+ * number doesn't match to this logic and needs to be passed
+ * from the DT configuration explicitly.
+ */
+ if (of_property_read_u32(np, "qcom,ctx-num", &val))
+ asid = reg / 0x1000;
+ else
+ asid = val;
+
+ return asid;
}
static int qcom_iommu_ctx_probe(struct platform_device *pdev)