]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
iommu: qcom: v1: move iommu-sec pgtable allocation
authorStanimir Varbanov <stanimir.varbanov@linaro.org>
Tue, 12 Jan 2016 13:07:55 +0000 (15:07 +0200)
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Thu, 14 Jan 2016 10:29:22 +0000 (10:29 +0000)
move the allocation of iommu-sec page table into msm_iommu_dev
in order to use properly initialised struct device.
The dma_alloc_attrs would fail to allocate memory with the fake
struct device which was the case before this change.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
drivers/iommu/qcom/msm_iommu_dev-v1.c
drivers/iommu/qcom/msm_iommu_sec.c

index 9520cc296e3f453b0807f2a9889bd49cccf356e3..0989c5c47b0f53d85a5517eed2eeabd5149f02c3 100644 (file)
@@ -29,6 +29,7 @@
 #include "msm_iommu_hw-v1.h"
 #include <linux/qcom_iommu.h>
 #include "msm_iommu_perfmon.h"
+#include <linux/qcom_scm.h>
 
 static const struct of_device_id msm_iommu_ctx_match_table[];
 
@@ -263,6 +264,75 @@ static int msm_iommu_pmon_parse_dt(struct platform_device *pdev,
        return 0;
 }
 
+#define SCM_SVC_MP             0xc
+#define MAXIMUM_VIRT_SIZE      (300 * SZ_1M)
+#define MAKE_VERSION(major, minor, patch) \
+       (((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))
+
+static int msm_iommu_sec_ptbl_init(struct device *dev)
+{
+       int psize[2] = {0, 0};
+       unsigned int spare = 0;
+       int ret;
+       int version;
+       void *cpu_addr;
+       dma_addr_t paddr;
+       DEFINE_DMA_ATTRS(attrs);
+       static bool allocated = false;
+
+       if (allocated)
+               return 0;
+
+       version = qcom_scm_get_feat_version(SCM_SVC_MP);
+
+       if (version >= MAKE_VERSION(1, 1, 1)) {
+               ret = qcom_scm_iommu_set_cp_pool_size(MAXIMUM_VIRT_SIZE, 0);
+               if (ret) {
+                       dev_err(dev, "failed setting max virtual size (%d)\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       ret = qcom_scm_iommu_secure_ptbl_size(spare, psize);
+       if (ret) {
+               dev_err(dev, "failed to get iommu secure pgtable size (%d)\n",
+                       ret);
+               return ret;
+       }
+
+       if (psize[1]) {
+               dev_err(dev, "failed to get iommu secure pgtable size (%d)\n",
+                       ret);
+               return psize[1];
+       }
+
+       dev_info(dev, "iommu sec: pgtable size: %d\n", psize[0]);
+
+       dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
+
+       cpu_addr = dma_alloc_attrs(dev, psize[0], &paddr, GFP_KERNEL, &attrs);
+       if (!cpu_addr) {
+               dev_err(dev, "failed to allocate %d bytes for pgtable\n",
+                       psize[0]);
+               return -ENOMEM;
+       }
+
+       ret = qcom_scm_iommu_secure_ptbl_init(paddr, psize[0], spare);
+       if (ret) {
+               dev_err(dev, "failed to init iommu pgtable (%d)\n", ret);
+               goto free_mem;
+       }
+
+       allocated = true;
+
+       return 0;
+
+free_mem:
+       dma_free_attrs(dev, psize[0], cpu_addr, paddr, &attrs);
+       return ret;
+}
+
 static int msm_iommu_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -328,6 +398,12 @@ static int msm_iommu_probe(struct platform_device *pdev)
        dev_info(dev, "device %s (model: %d) mapped at %p, with %d ctx banks\n",
                 drvdata->name, drvdata->model, drvdata->base, drvdata->ncb);
 
+       if (drvdata->sec_id != -1) {
+               ret = msm_iommu_sec_ptbl_init(dev);
+               if (ret)
+                       return ret;
+       }
+
        platform_set_drvdata(pdev, drvdata);
 
        pmon_info = msm_iommu_pm_alloc(dev);
index 33a1e988ae1e174c832580bdad9f228cf0d99b20..573245d4a57efad7babaa3e9924e4911e462c9f5 100644 (file)
 
 /* commands for SCM_SVC_UTIL */
 #define IOMMU_DUMP_SMMU_FAULT_REGS 0X0C
-#define MAXIMUM_VIRT_SIZE      (300*SZ_1M)
-
-
-#define MAKE_VERSION(major, minor, patch) \
-       (((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))
-
+#define SCM_SVC_MP             0xc
 
 static struct iommu_access_ops *iommu_access_ops;
 static int is_secure;
@@ -322,80 +317,6 @@ lock_release:
        return ret;
 }
 
-#define SCM_SVC_MP                     0xc
-
-static int msm_iommu_sec_ptbl_init(void)
-{
-       struct device_node *np;
-       int psize[2] = {0, 0};
-       unsigned int spare = 0;
-       int ret;
-       int version;
-       /* Use a dummy device for dma_alloc_attrs allocation */
-       struct device dev = { 0 };
-       void *cpu_addr;
-       dma_addr_t paddr;
-       DEFINE_DMA_ATTRS(attrs);
-
-       for_each_matching_node(np, msm_smmu_list)
-               if (of_find_property(np, "qcom,iommu-secure-id", NULL) &&
-                               of_device_is_available(np))
-                       break;
-
-       if (!np)
-               return 0;
-
-       of_node_put(np);
-
-       version = qcom_scm_get_feat_version(SCM_SVC_MP);
-
-       if (version >= MAKE_VERSION(1, 1, 1)) {
-               ret = qcom_scm_iommu_set_cp_pool_size(MAXIMUM_VIRT_SIZE, 0);
-               if (ret) {
-                       pr_err("scm call IOMMU_SET_CP_POOL_SIZE failed\n");
-                       goto fail;
-               }
-       }
-
-       ret = qcom_scm_iommu_secure_ptbl_size(spare, psize);
-       if (ret) {
-               pr_err("scm call IOMMU_SECURE_PTBL_SIZE failed\n");
-               goto fail;
-       }
-
-       pr_err("iommu sec: psize[0]: %d, psize[1]: %d\n", psize[0], psize[1]);
-
-       if (psize[1]) {
-               pr_err("scm call IOMMU_SECURE_PTBL_SIZE failed\n");
-               goto fail;
-       }
-
-       dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
-       dev.coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
-
-       cpu_addr = dma_alloc_attrs(&dev, psize[0], &paddr, GFP_KERNEL, &attrs);
-       if (!cpu_addr) {
-               pr_err("%s: Failed to allocate %d bytes for PTBL\n",
-                       __func__, psize[0]);
-               ret = -ENOMEM;
-               goto fail;
-       }
-
-       ret = qcom_scm_iommu_secure_ptbl_init(paddr, psize[0], spare);
-
-       if (ret) {
-               pr_err("scm call IOMMU_SECURE_PTBL_INIT failed (%d)\n", ret);
-               goto fail_mem;
-       }
-
-       return 0;
-
-fail_mem:
-       dma_free_attrs(&dev, psize[0], cpu_addr, paddr, &attrs);
-fail:
-       return ret;
-}
-
 int msm_iommu_sec_program_iommu(struct msm_iommu_drvdata *drvdata,
                        struct msm_iommu_ctx_drvdata *ctx_drvdata)
 {
@@ -865,9 +786,7 @@ static int __init msm_iommu_sec_init(void)
                return ret;
        }
 
-       ret = msm_iommu_sec_ptbl_init();
-
-       return ret;
+       return 0;
 }
 
 subsys_initcall(msm_iommu_sec_init);