]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
qcom-scm: Align PAS api with "upstream" implementation
authorBjorn Andersson <bjorn.andersson@linaro.org>
Wed, 20 Apr 2016 01:42:10 +0000 (18:42 -0700)
committerNicolas Dechesne <nicolas.dechesne@linaro.org>
Tue, 21 Jun 2016 08:02:06 +0000 (11:02 +0300)
This aligns the PAS implementation with the patches heading upstream,
in particular tying the dma allocation in pas_init_image to the scm
platform_device rather then the caller.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/firmware/qcom_scm-32.c
drivers/firmware/qcom_scm-64.c
drivers/firmware/qcom_scm.c
drivers/firmware/qcom_scm.h
include/linux/qcom_scm.h

index cabbe1f7e397d54d38f2061510411f22a75207c6..246e4c28b779a41179d8616fb87c60c50f4a9c5d 100644 (file)
@@ -521,39 +521,23 @@ bool __qcom_scm_pas_supported(u32 peripheral)
        return ret ? false : !!ret_val;
 }
 
-int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, const void *metadata, size_t size)
+int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys)
 {
-       dma_addr_t mdata_phys;
-       void *mdata_buf;
-       u32 scm_ret;
+       __le32 scm_ret;
        int ret;
-       struct pas_init_image_req {
-               u32 proc;
-               u32 image_addr;
+       struct {
+               __le32 proc;
+               __le32 image_addr;
        } request;
 
-       /*
-        * During the scm call memory protection will be enabled for the meta
-        * data blob, so make sure it's physically contiguous, 4K aligned and
-        * non-cachable to avoid XPU violations.
-        */
-       mdata_buf = dma_alloc_coherent(dev, size, &mdata_phys, GFP_KERNEL);
-       if (!mdata_buf) {
-               pr_err("Allocation of metadata buffer failed.\n");
-               return -ENOMEM;
-       }
-       memcpy(mdata_buf, metadata, size);
-
-       request.proc = peripheral;
-       request.image_addr = mdata_phys;
+       request.proc = cpu_to_le32(peripheral);
+       request.image_addr = cpu_to_le32(metadata_phys);
 
        ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD,
                            &request, sizeof(request),
                            &scm_ret, sizeof(scm_ret));
 
-       dma_free_coherent(dev, size, mdata_buf, mdata_phys);
-
-       return ret ? : scm_ret;
+       return ret ? : le32_to_cpu(scm_ret);
 }
 
 int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
index dc64858935fa7f977ef624e382691783fc7b6aba..e785f9cfadd19290faaf2f336eba43aeb491bbc4 100644 (file)
@@ -502,37 +502,20 @@ bool __qcom_scm_pas_supported(u32 peripheral)
        return ret ? false : !!desc.ret[0];
 }
 
-int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, const void *metadata, size_t size)
+int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys)
 {
        int ret;
        struct qcom_scm_desc desc = {0};
        u32 scm_ret;
-       dma_addr_t mdata_phys;
-       void *mdata_buf;
-
-dev->coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
-
-       /*
-        * During the scm call memory protection will be enabled for the meta
-        * data blob, so make sure it's physically contiguous, 4K aligned and
-        * non-cachable to avoid XPU violations.
-        */
-       mdata_buf = dma_alloc_coherent(dev, size, &mdata_phys, GFP_KERNEL);
-       if (!mdata_buf) {
-               pr_err("Allocation of metadata buffer failed.\n");
-               return -ENOMEM;
-       }
-       memcpy(mdata_buf, metadata, size);
 
        desc.args[0] = peripheral;
-       desc.args[1] = mdata_phys;
+       desc.args[1] = metadata_phys;
        desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW);
 
        ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD,
                                &desc);
        scm_ret = desc.ret[0];
 
-       dma_free_coherent(dev, size, mdata_buf, mdata_phys);
        return ret ? : scm_ret;
 }
 
index a1a25185a867e786c4dace4cb693d0051a53b628..4628c30ca01a483e3d8d47532a8619dcddfc484e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/export.h>
+#include <linux/dma-mapping.h>
 #include <linux/types.h>
 #include <linux/qcom_scm.h>
 #include <linux/of.h>
@@ -23,6 +24,7 @@
 #include "qcom_scm.h"
 
 struct qcom_scm {
+       struct device *dev;
        struct clk *core_clk;
        struct clk *iface_clk;
        struct clk *bus_clk;
@@ -34,44 +36,31 @@ static int qcom_scm_clk_enable(void)
 {
        int ret;
 
-       if(__scm->core_clk) {
-               ret = clk_prepare_enable(__scm->core_clk);
-               if (ret)
-                       goto bail;
-       }
-
-       if(__scm->iface_clk) {
-               ret = clk_prepare_enable(__scm->iface_clk);
-               if (ret)
-                       goto disable_core;
-       }
-
-       if(__scm->bus_clk) {
-               ret = clk_prepare_enable(__scm->bus_clk);
-               if (ret)
-                       goto disable_iface;
-       }
+       ret = clk_prepare_enable(__scm->core_clk);
+       if (ret)
+               goto bail;
+       ret = clk_prepare_enable(__scm->iface_clk);
+       if (ret)
+               goto disable_core;
+       ret = clk_prepare_enable(__scm->bus_clk);
+       if (ret)
+               goto disable_iface;
 
        return 0;
 
 disable_iface:
-       if(__scm->iface_clk)
-               clk_disable_unprepare(__scm->iface_clk);
+       clk_disable_unprepare(__scm->iface_clk);
 disable_core:
-       if(__scm->core_clk)
-               clk_disable_unprepare(__scm->core_clk);
+       clk_disable_unprepare(__scm->core_clk);
 bail:
        return ret;
 }
 
 static void qcom_scm_clk_disable(void)
 {
-       if(__scm->core_clk)
-               clk_disable_unprepare(__scm->core_clk);
-       if(__scm->iface_clk)
-               clk_disable_unprepare(__scm->iface_clk);
-       if(__scm->bus_clk)
-               clk_disable_unprepare(__scm->bus_clk);
+       clk_disable_unprepare(__scm->core_clk);
+       clk_disable_unprepare(__scm->iface_clk);
+       clk_disable_unprepare(__scm->bus_clk);
 }
 
 /**
@@ -161,7 +150,15 @@ EXPORT_SYMBOL(qcom_scm_hdcp_req);
 
 int qcom_scm_restart_proc(u32 pid, int restart, u32 *resp)
 {
-       return __qcom_scm_restart_proc(pid, restart, resp);
+       int ret;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_restart_proc(pid, restart, resp);
+       qcom_scm_clk_disable();
+       return ret;
 }
 EXPORT_SYMBOL(qcom_scm_restart_proc);
 /**
@@ -196,9 +193,36 @@ EXPORT_SYMBOL(qcom_scm_pas_supported);
  *
  * Returns 0 on success.
  */
-int qcom_scm_pas_init_image(struct device *dev, u32 peripheral, const void *metadata, size_t size)
+int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
 {
-       return __qcom_scm_pas_init_image(dev, peripheral, metadata, size);
+       dma_addr_t mdata_phys;
+       void *mdata_buf;
+       int ret;
+
+       /*
+        * During the scm call memory protection will be enabled for the meta
+        * data blob, so make sure it's physically contiguous, 4K aligned and
+        * non-cachable to avoid XPU violations.
+        */
+       mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys, GFP_KERNEL);
+       if (!mdata_buf) {
+               dev_err(__scm->dev, "Allocation of metadata buffer failed.\n");
+               return -ENOMEM;
+       }
+       memcpy(mdata_buf, metadata, size);
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               goto free_metadata;
+
+       ret = __qcom_scm_pas_init_image(peripheral, mdata_phys);
+
+       qcom_scm_clk_disable();
+
+free_metadata:
+       dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
+
+       return ret;
 }
 EXPORT_SYMBOL(qcom_scm_pas_init_image);
 
@@ -213,7 +237,16 @@ EXPORT_SYMBOL(qcom_scm_pas_init_image);
  */
 int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
 {
-       return __qcom_scm_pas_mem_setup(peripheral, addr, size);
+       int ret;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_pas_mem_setup(peripheral, addr, size);
+       qcom_scm_clk_disable();
+
+       return ret;
 }
 EXPORT_SYMBOL(qcom_scm_pas_mem_setup);
 
@@ -226,7 +259,16 @@ EXPORT_SYMBOL(qcom_scm_pas_mem_setup);
  */
 int qcom_scm_pas_auth_and_reset(u32 peripheral)
 {
-       return __qcom_scm_pas_auth_and_reset(peripheral);
+       int ret;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_pas_auth_and_reset(peripheral);
+       qcom_scm_clk_disable();
+
+       return ret;
 }
 EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset);
 
@@ -238,7 +280,16 @@ EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset);
  */
 int qcom_scm_pas_shutdown(u32 peripheral)
 {
-       return __qcom_scm_pas_shutdown(peripheral);
+       int ret;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_pas_shutdown(peripheral);
+       qcom_scm_clk_disable();
+
+       return ret;
 }
 EXPORT_SYMBOL(qcom_scm_pas_shutdown);
 
@@ -365,35 +416,40 @@ static int qcom_scm_probe(struct platform_device *pdev)
        if (!scm)
                return -ENOMEM;
 
+       scm->dev = &pdev->dev;
+
        scm->core_clk = devm_clk_get(&pdev->dev, "core");
        if (IS_ERR(scm->core_clk)) {
-               if (PTR_ERR(scm->core_clk) != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "failed to acquire core clk\n");
+               if (PTR_ERR(scm->core_clk) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+
+               dev_err(&pdev->dev, "failed to acquire core clk\n");
                scm->core_clk = NULL;
        }
 
        scm->iface_clk = devm_clk_get(&pdev->dev, "iface");
        if (IS_ERR(scm->iface_clk)) {
-               if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "failed to acquire iface clk\n");
+               if (PTR_ERR(scm->iface_clk) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+
+               dev_err(&pdev->dev, "failed to acquire iface clk\n");
                scm->iface_clk = NULL;
        }
 
        scm->bus_clk = devm_clk_get(&pdev->dev, "bus");
        if (IS_ERR(scm->bus_clk)) {
-               if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER)
-                       dev_err(&pdev->dev, "failed to acquire bus clk\n");
+               if (PTR_ERR(scm->bus_clk) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
 
+               dev_err(&pdev->dev, "failed to acquire bus clk\n");
                scm->bus_clk = NULL;
        }
 
-       if (scm->core_clk) {
        /* vote for max clk rate for highest performance */
-               rate = clk_round_rate(scm->core_clk, INT_MAX);
-               ret = clk_set_rate(scm->core_clk, rate);
-               if (ret)
-                       return ret;
-       }
+       rate = clk_round_rate(scm->core_clk, INT_MAX);
+       ret = clk_set_rate(scm->core_clk, rate);
+       if (ret)
+               return ret;
 
        __scm = scm;
 
index 93b94c9ad34f05eb6e41067f5bf12fe10925c9af..5c10ccced74852a780581cb342684d7d2a479ebf 100644 (file)
@@ -43,7 +43,7 @@ extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
 #define QCOM_SCM_PAS_SHUTDOWN_CMD      0x6
 #define QCOM_SCM_PAS_IS_SUPPORTED_CMD  0x7
 extern bool __qcom_scm_pas_supported(u32 peripheral);
-extern int  __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, const void *metadata, size_t size);
+extern int  __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys);
 extern int  __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
 extern int  __qcom_scm_pas_auth_and_reset(u32 peripheral);
 extern int  __qcom_scm_pas_shutdown(u32 peripheral);
index 0b9f01b489cb2d70c53a3d4471918bc4efb0daf2..536f34671bded19ca1b6cf1ed0ce64777a70f131 100644 (file)
@@ -33,7 +33,7 @@ extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
 
 extern bool qcom_scm_pas_supported(u32 peripheral);
 extern int qcom_scm_restart_proc(u32 pid, int restart, u32 *resp);
-extern int qcom_scm_pas_init_image(struct device *dev, u32 peripheral, const void *metadata, size_t size);
+extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size);
 extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
 extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
 extern int qcom_scm_pas_shutdown(u32 peripheral);