Currently we abuse the platform device engine to create a platform
device for the zap shader subnode so that we can isolate the
reserved memory away from the parent GPU device.

It is much safer to create and register a simple child device and use
that instead.

Signed-off-by: Jordan Crouse <jcro...@codeaurora.org>
---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 77 ++++++++++++++++++++---------------
 drivers/gpu/drm/msm/adreno/a5xx_gpu.h |  2 +
 2 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 0a096f8..8678bce 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -31,7 +31,7 @@ static inline bool _check_segment(const struct elf32_phdr 
*phdr)
                phdr->p_memsz);
 }
 
-static int zap_load_segments(struct platform_device *pdev,
+static int zap_load_segments(struct device *dev,
                const struct firmware *mdt, const char *fwname,
                void *fwptr, size_t fw_size, unsigned long fw_min_addr)
 {
@@ -55,15 +55,15 @@ static int zap_load_segments(struct platform_device *pdev,
                /* Request the file containing the segment */
                snprintf(filename, sizeof(filename), "%s.b%02d", fwname, i);
 
-               ret = request_firmware(&fw, filename, &pdev->dev);
+               ret = request_firmware(&fw, filename, dev);
                if (ret) {
-                       DRM_DEV_ERROR(&pdev->dev, "Failed to load segment %s\n",
+                       DRM_DEV_ERROR(dev, "Failed to load segment %s\n",
                                filename);
                        break;
                }
 
                if (offset + fw->size > fw_size) {
-                       DRM_DEV_ERROR(&pdev->dev, "Segment %s is too big\n",
+                       DRM_DEV_ERROR(dev, "Segment %s is too big\n",
                                filename);
                        ret = -EINVAL;
                        release_firmware(fw);
@@ -82,7 +82,7 @@ static int zap_load_segments(struct platform_device *pdev,
        return ret;
 }
 
-static int zap_load_mdt(struct platform_device *pdev)
+static int zap_load_mdt(struct device *dev)
 {
        char filename[64];
        const char *fwname;
@@ -92,37 +92,29 @@ static int zap_load_mdt(struct platform_device *pdev)
        phys_addr_t fw_min_addr, fw_max_addr;
        dma_addr_t fw_phys;
        size_t fw_size;
-       void *ptr;
+       void *ptr = NULL;
        int i, ret;
 
-       if (pdev == NULL)
-               return -ENODEV;
-
-       if (!qcom_scm_is_available()) {
-               DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
-               return -EPROBE_DEFER;
-       }
-
-       ret = of_reserved_mem_device_init(&pdev->dev);
+       ret = of_reserved_mem_device_init(dev);
        if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "Unable to set up the reserved 
memory\n");
+               DRM_DEV_ERROR(dev, "Unable to set up the reserved memory\n");
                return ret;
        }
 
        /* Get the firmware and PAS id from the device node */
-       if (of_property_read_string(pdev->dev.of_node, "qcom,firmware",
+       if (of_property_read_string(dev->of_node, "qcom,firmware",
                &fwname)) {
-               DRM_DEV_ERROR(&pdev->dev, "Could not read a firmware name\n");
+               DRM_DEV_ERROR(dev, "Could not read a firmware name\n");
                return -EINVAL;
        }
 
        snprintf(filename, sizeof(filename), "%s.mdt", fwname);
 
        /* Request the MDT file for the firmware */
-       ret = request_firmware(&mdt, filename, &pdev->dev);
+       ret = request_firmware(&mdt, filename, dev);
        if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "Unable to load %s\n", filename);
-               return ret;
+               DRM_DEV_ERROR(dev, "Unable to load %s\n", filename);
+               goto out;
        }
 
        ehdr = (struct elf32_hdr *) mdt->data;
@@ -152,35 +144,36 @@ static int zap_load_mdt(struct platform_device *pdev)
        /* Verify the MDT header */
        ret = qcom_scm_pas_init_image(13, mdt->data, mdt->size);
        if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "Invalid firmware metadata\n");
+               DRM_DEV_ERROR(dev, "Invalid firmware metadata\n");
                goto out;
        }
 
        /* allocate some memory */
-       ptr = dma_alloc_coherent(&pdev->dev, fw_size, &fw_phys, GFP_KERNEL);
+       ptr = dma_alloc_coherent(dev, fw_size, &fw_phys, GFP_KERNEL);
        if (ptr == NULL)
                goto out;
 
        /* Set up the newly allocated memory region */
        ret = qcom_scm_pas_mem_setup(13, fw_phys, fw_size);
        if (ret) {
-               DRM_DEV_ERROR(&pdev->dev, "Unable to set up firmware memory\n");
+               DRM_DEV_ERROR(dev, "Unable to set up firmware memory\n");
                goto out;
        }
 
-       ret = zap_load_segments(pdev, mdt, fwname, ptr, fw_size, fw_min_addr);
+       ret = zap_load_segments(dev, mdt, fwname, ptr, fw_size, fw_min_addr);
        if (ret)
                goto out;
 
        ret = qcom_scm_pas_auth_and_reset(13);
        if (ret)
-               DRM_DEV_ERROR(&pdev->dev, "Unable to authorize the image\n");
+               DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
 
 out:
        if (ret && ptr)
-               dma_free_coherent(&pdev->dev, fw_size, ptr, fw_phys);
+               dma_free_coherent(dev, fw_size, ptr, fw_phys);
 
        release_firmware(mdt);
+
        return ret;
 }
 
@@ -498,8 +491,10 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
        if (loaded)
                return a5xx_zap_shader_resume(gpu);
 
-       /* Populate the sub-nodes if they haven't already been done */
-       of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+       if (!qcom_scm_is_available()) {
+               DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
+               return -EPROBE_DEFER;
+       }
 
        /* Find the sub-node for the zap shader */
        node = of_get_child_by_name(pdev->dev.of_node, "zap-shader");
@@ -509,10 +504,23 @@ static int a5xx_zap_shader_init(struct msm_gpu *gpu)
                return -ENODEV;
        }
 
-       ret = zap_load_mdt(of_find_device_by_node(node));
-       if (ret)
-               DRM_ERROR("%s: Unable to load the zap shader\n",
-                       gpu->name);
+       /* Set up the child device to "own" the zap shader */
+       if (!a5xx_gpu->zap_dev.parent) {
+               a5xx_gpu->zap_dev.parent = &pdev->dev;
+               a5xx_gpu->zap_dev.of_node = node;
+               dev_set_name(&a5xx_gpu->zap_dev, "adreno_zap_shader");
+
+               ret = device_register(&a5xx_gpu->zap_dev);
+               if (ret) {
+                       DRM_DEV_ERROR(&pdev->dev,
+                               "Couldn't register the zap shader device\n");
+
+                       a5xx_gpu->zap_dev.parent = NULL;
+                       return ret;
+               }
+       }
+
+       ret = zap_load_mdt(&a5xx_gpu->zap_dev);
 
        loaded = !ret;
 
@@ -755,6 +763,9 @@ static void a5xx_destroy(struct msm_gpu *gpu)
 
        DBG("%s", gpu->name);
 
+       if (a5xx_gpu->zap_dev.parent)
+               device_unregister(&a5xx_gpu->zap_dev);
+
        if (a5xx_gpu->pm4_bo) {
                if (a5xx_gpu->pm4_iova)
                        msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->id);
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
index 1590f84..78408f5 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
@@ -36,6 +36,8 @@ struct a5xx_gpu {
        uint32_t gpmu_dwords;
 
        uint32_t lm_leakage;
+
+       struct device zap_dev;
 };
 
 #define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base)
-- 
1.9.1

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

Reply via email to