MGS-2619-2 [#imx-188] Use imx-gpu-subsytem method to probe GPU Devices
authorPrabhu Sundararaj <prabhu.sundararaj@nxp.com>
Wed, 22 Feb 2017 22:59:44 +0000 (16:59 -0600)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:21:34 +0000 (15:21 -0500)
Use component_add menthod to initailize GPU devices. component_add helps
to load after power domains are loaded.

For more reference on the deferred loading
https://patchwork.kernel.org/patch/7683421/

Date: Feb 22, 2017
Signed-off-by: Prabhu Sundararaj <prabhu.sundararaj@nxp.com>
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6.c

index 401be61..405c258 100644 (file)
@@ -61,6 +61,7 @@
 #include "gc_hal_driver.h"
 
 #include <linux/platform_device.h>
+#include <linux/component.h>
 
 /* Zone used for header/footer. */
 #define _GC_OBJ_ZONE    gcvZONE_DRIVER
@@ -1036,7 +1037,35 @@ static void drv_exit(void)
 
     gcmkFOOTER_NO();
 }
+static int gpu_platform_bind(struct device *dev)
+{
+       int ret;
+
+       ret = component_bind_all(dev, 0);
+       if (ret < 0) {
+               return ret;
+    }
+
+    ret = drv_init();
+    if (!ret)  {
+        platform_set_drvdata(to_platform_device(dev), galDevice);
+
+        return ret;
+    }
+       component_unbind_all(dev, 0);
+       return ret;
+}
 
+static void gpu_platform_unbind(struct device *dev)
+{
+       component_unbind_all(dev, 0);
+}
+
+extern struct component_match *match;
+static const struct component_master_ops gpu_platform_master_ops = {
+       .bind = gpu_platform_bind,
+       .unbind = gpu_platform_unbind,
+};
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
 static int gpu_probe(struct platform_device *pdev)
 #else
@@ -1099,15 +1128,22 @@ static int __devinit gpu_probe(struct platform_device *pdev)
         /* Update module param because drv_init() uses them directly. */
         _UpdateModuleParam(&moduleParam);
     }
-
-    ret = drv_init();
-
-    if (!ret)
-    {
-        platform_set_drvdata(pdev, galDevice);
-
-        gcmkFOOTER_NO();
-        return ret;
+    if (platform.ops->registerDevice) {
+        /*drv_init() will be called during binding*/
+        ret = component_master_add_with_match(&pdev->dev, &gpu_platform_master_ops, match);
+        if(ret !=0)
+        {
+            gcmkFOOTER_NO();
+            return ret;
+        }
+    }
+    else {
+        ret = drv_init();
+        if (!ret) {
+            platform_set_drvdata(pdev, galDevice);
+            gcmkFOOTER_NO();
+            return ret;
+        }
     }
 
     gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
@@ -1128,7 +1164,9 @@ static int __devexit gpu_remove(struct platform_device *pdev)
     {
         platform.ops->putPower(&platform);
     }
-
+    if (platform.ops->registerDevice) {
+        component_master_del(&pdev->dev, &gpu_platform_master_ops);
+    }
     gcmkFOOTER_NO();
     return 0;
 }
@@ -1361,7 +1399,9 @@ static int __init gpu_init(void)
     if (platform.ops->registerDevice)
     {
         ret = platform.ops->registerDevice(&platform);
-        /*TODO: handle Error*/
+        if (ret != 0) {
+            goto out;
+        }
     }
 
     ret = platform_driver_register(&gpu_driver);
index 72addb8..f8a1e31 100644 (file)
@@ -124,7 +124,7 @@ typedef struct _gcsPLATFORM_OPERATIONS
     **
     **  runRegisterDevice
     **
-    **  Determine whether platform device need to be registered
+    **  Unregister platform device
     */
     gceSTATUS
     (*unRegisterDevice)(
index 2cdfe48..98f4f15 100644 (file)
@@ -67,6 +67,7 @@
 #if USE_PLATFORM_DRIVER
 #   include <linux/platform_device.h>
 #endif
+#include <linux/component.h>
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,9,0)) || (IMX8_SCU_CONTROL)
 #define IMX_GPU_SUBSYSTEM   1
@@ -404,6 +405,23 @@ struct imx_priv {
 static struct imx_priv imxPriv;
 
 #if IMX_GPU_SUBSYSTEM
+static int gpu_device_bind(struct device *dev, struct device *master,
+       void *data)
+{
+    return 0;
+}
+
+static void gpu_device_unbind(struct device *dev, struct device *master,
+       void *data)
+{
+
+}
+
+static const struct component_ops gpu_ops = {
+       .bind = gpu_device_bind,
+       .unbind = gpu_device_unbind,
+};
+
 static const struct of_device_id gpu_match[] = {
        {
                .compatible = "vivante,gc"
@@ -411,14 +429,15 @@ static const struct of_device_id gpu_match[] = {
        { /* sentinel */ }
 };
 
-static int mxc_gpu_platform_probe(struct platform_device *pdev)
+static int gpu_device_probe(struct platform_device *pdev)
 {
-       return 0;
+    return component_add(&pdev->dev, &gpu_ops);
 }
 
-static int mxc_gpu_platform_remove(struct platform_device *pdev)
+static int gpu_device_remove(struct platform_device *pdev)
 {
-       return 0;
+    component_del(&pdev->dev, &gpu_ops);
+    return 0;
 }
 struct platform_driver mxc_gpu_driver = {
        .driver = {
@@ -426,20 +445,15 @@ struct platform_driver mxc_gpu_driver = {
                .owner = THIS_MODULE,
                .of_match_table = gpu_match,
        },
-       .probe = mxc_gpu_platform_probe,
-       .remove = mxc_gpu_platform_remove,
+       .probe = gpu_device_probe,
+       .remove = gpu_device_remove,
 };
 gceSTATUS
 gckPLATFORM_RegisterDevice(
     IN gckPLATFORM Platform
     )
 {
-    int ret = 0;
-    ret = platform_driver_register(&mxc_gpu_driver);
-       if (ret != 0)
-               return ret;
-
-     return gcvSTATUS_OK;
+    return platform_driver_register(&mxc_gpu_driver);
 }
 
 gceSTATUS
@@ -450,7 +464,17 @@ gckPLATFORM_UnRegisterDevice(
     platform_driver_unregister(&mxc_gpu_driver);
     return gcvSTATUS_OK;
 }
+
+static int compare_of(struct device *dev, void *data)
+{
+    struct device_node *np = data;
+
+    return dev->of_node == np;
+}
 #endif
+/*TODO: Fix */
+struct component_match *match = NULL;
+
 gceSTATUS
 gckPLATFORM_AdjustParam(
     IN gckPLATFORM Platform,
@@ -469,8 +493,8 @@ gckPLATFORM_AdjustParam(
 #if IMX_GPU_SUBSYSTEM
     struct device_node *node =pdev->dev.of_node;
     if (node) {
-               struct device_node *core_node;
-               int i=0;
+        struct device_node *core_node;
+        int i=0;
         gctINT  coreMajor = gcvCORE_MAJOR;
         const char *cur = NULL;
         struct property *p = of_find_property(node, "core-names", NULL);
@@ -486,6 +510,8 @@ gckPLATFORM_AdjustParam(
             if(!of_device_is_available(core_node)){
                 continue;
             }
+            component_match_add(&pdev->dev, &match, compare_of,
+                                           core_node);
             pdev_gpu = of_find_device_by_node(core_node);
             if (!pdev_gpu) {
                                break;