video: tegra: host: add DT support
Min-wuk Lee [Wed, 24 Apr 2013 02:31:07 +0000 (11:31 +0900)]
- this commit adds the infrastructure to parse and
allocate device from DT
- it also adds support to parse and add resources from DT
into the newly allocated device
- it also matches the device and drivers using .compatible
property
- of_platform_populate() assigns platform_bus as host1x parent, so
condition in nvhost_get_parent() was modified

bug 1041377
bug 1240921

Change-Id: I3373b5fb48e417e14f819d15e33f94ea1efb6194

Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Signed-off-by: Min-wuk Lee <mlee@nvidia.com>
Reviewed-on: http://git-master/r/145937
(cherry picked from commit 83de44b147fd9582f73fb3f1aec105c6bcebbd3e)
Change-Id: Id53db1638ea02e7d19bee3c020c43051c74e4365
Reviewed-on: http://git-master/r/229228
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>

drivers/video/tegra/host/gr2d/gr2d.c
drivers/video/tegra/host/gr3d/gr3d.c
drivers/video/tegra/host/host1x/host1x.c
drivers/video/tegra/host/host1x/host1x.h
drivers/video/tegra/host/isp/isp.c
drivers/video/tegra/host/mpe/mpe.c
drivers/video/tegra/host/msenc/msenc.c
drivers/video/tegra/host/nvhost_acm.c
drivers/video/tegra/host/nvhost_syncpt.c
drivers/video/tegra/host/tsec/tsec.c
drivers/video/tegra/host/vi/vi.c

index af6b0f3..dba1731 100644 (file)
 #include <linux/export.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 
 #include "dev.h"
 #include "bus_client.h"
 #include "gr2d_t30.h"
 #include "gr2d_t114.h"
+#include "t20/t20.h"
+#include "t30/t30.h"
+#include "t114/t114.h"
 
+static struct of_device_id tegra_gr2d_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-gr2d",
+               .data = (struct nvhost_device_data *)&t20_gr2d_info },
+       { .compatible = "nvidia,tegra30-gr2d",
+               .data = (struct nvhost_device_data *)&t30_gr2d_info },
+       { .compatible = "nvidia,tegra114-gr2d",
+               .data = (struct nvhost_device_data *)&t11_gr2d_info },
+       { },
+};
 static int __devinit gr2d_probe(struct platform_device *dev)
 {
        int err = 0;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
 
+               match = of_match_device(tegra_gr2d_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
        pdata->pdev = dev;
        platform_set_drvdata(dev, pdata);
 
@@ -76,6 +104,9 @@ static struct platform_driver gr2d_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "gr2d",
+#ifdef CONFIG_OF
+               .of_match_table = tegra_gr2d_of_match,
+#endif
        },
 };
 
index 3afd907..b73f872 100644 (file)
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <mach/gpufuse.h>
 
 #include "t20/t20.h"
+#include "t30/t30.h"
+#include "t114/t114.h"
 #include "host1x/host1x01_hardware.h"
 #include "nvhost_hwctx.h"
 #include "dev.h"
@@ -155,11 +160,34 @@ int nvhost_gr3d_prepare_power_off(struct platform_device *dev)
        return nvhost_channel_save_context(pdata->channel);
 }
 
+static struct of_device_id tegra_gr3d_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-gr3d",
+               .data = (struct nvhost_device_data *)&t20_gr3d_info },
+       { .compatible = "nvidia,tegra30-gr3d",
+               .data = (struct nvhost_device_data *)&t30_gr3d_info },
+       { .compatible = "nvidia,tegra114-gr3d",
+               .data = (struct nvhost_device_data *)&t11_gr3d_info },
+       { },
+};
 static int __devinit gr3d_probe(struct platform_device *dev)
 {
        int err = 0;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
+
+               match = of_match_device(tegra_gr3d_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
 
        pdata->pdev = dev;
        platform_set_drvdata(dev, pdata);
@@ -204,6 +232,9 @@ static struct platform_driver gr3d_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "gr3d",
+#ifdef CONFIG_OF
+               .of_match_table = tegra_gr3d_of_match,
+#endif
        },
 };
 
index d8d7f29..e583267 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host Driver Entrypoint
  *
- * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION, All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -27,6 +27,9 @@
 #include <linux/hrtimer.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 
 #include "dev.h"
 #include <trace/events/nvhost.h>
@@ -40,6 +43,9 @@
 #include "nvhost_channel.h"
 #include "nvhost_job.h"
 #include "chip_support.h"
+#include "t20/t20.h"
+#include "t30/t30.h"
+#include "t114/t114.h"
 
 #define DRIVER_NAME            "host1x"
 
@@ -402,14 +408,37 @@ void nvhost_host1x_update_clk(struct platform_device *pdev)
        actmon_op().update_sample_period(host);
 }
 
+static struct of_device_id tegra_host1x_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-host1x",
+               .data = (struct nvhost_device_data *)&t20_host1x_info },
+       { .compatible = "nvidia,tegra30-host1x",
+               .data = (struct nvhost_device_data *)&t30_host1x_info },
+       { .compatible = "nvidia,tegra114-host1x",
+               .data = (struct nvhost_device_data *)&t11_host1x_info },
+       { },
+};
+
 static int __devinit nvhost_probe(struct platform_device *dev)
 {
        struct nvhost_master *host;
        struct resource *regs, *intr0, *intr1;
        int i, err;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
 
+               match = of_match_device(tegra_host1x_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
        regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
        intr0 = platform_get_resource(dev, IORESOURCE_IRQ, 0);
        intr1 = platform_get_resource(dev, IORESOURCE_IRQ, 1);
@@ -550,7 +579,10 @@ static struct platform_driver platform_driver = {
        .resume = nvhost_resume,
        .driver = {
                .owner = THIS_MODULE,
-               .name = DRIVER_NAME
+               .name = DRIVER_NAME,
+#ifdef CONFIG_OF
+               .of_match_table = tegra_host1x_of_match,
+#endif
        },
 };
 
index a734da6..09e8943 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host Driver Entrypoint
  *
- * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION, All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -90,7 +90,7 @@ static inline struct nvhost_master *nvhost_get_host(
 {
        struct platform_device *pdev;
 
-       if (_dev->dev.parent) {
+       if (_dev->dev.parent && _dev->dev.parent != &platform_bus) {
                pdev = to_platform_device(_dev->dev.parent);
                return nvhost_get_private_data(pdev);
        } else
@@ -100,7 +100,8 @@ static inline struct nvhost_master *nvhost_get_host(
 static inline struct platform_device *nvhost_get_parent(
        struct platform_device *_dev)
 {
-       return _dev->dev.parent ? to_platform_device(_dev->dev.parent) : NULL;
+       return (_dev->dev.parent && _dev->dev.parent != &platform_bus)
+               ? to_platform_device(_dev->dev.parent) : NULL;
 }
 
 void nvhost_host1x_update_clk(struct platform_device *pdev);
index 4f9d99b..b98d256 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics ISP
  *
- * Copyright (c) 2012, NVIDIA Corporation.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION, All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 #include <linux/export.h>
 #include <linux/resource.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 
 #include <mach/iomap.h>
 
 #include "dev.h"
 #include "bus_client.h"
-
+#include "t20/t20.h"
+#include "t30/t30.h"
+#include "t114/t114.h"
+
+static struct of_device_id tegra_isp_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-isp",
+               .data = (struct nvhost_device_data *)&t20_isp_info },
+       { .compatible = "nvidia,tegra30-isp",
+               .data = (struct nvhost_device_data *)&t30_isp_info },
+       { .compatible = "nvidia,tegra114-isp",
+               .data = (struct nvhost_device_data *)&t11_isp_info },
+       { },
+};
 static int __devinit isp_probe(struct platform_device *dev)
 {
        int err = 0;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
+
+               match = of_match_device(tegra_isp_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
 
        pdata->pdev = dev;
        platform_set_drvdata(dev, pdata);
@@ -80,6 +109,9 @@ static struct platform_driver isp_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "isp",
+#ifdef CONFIG_OF
+               .of_match_table = tegra_isp_of_match,
+#endif
        }
 };
 
index 7ae1604..5eece60 100644 (file)
@@ -24,6 +24,9 @@
 #include <linux/module.h>
 #include <linux/scatterlist.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 
 #include <mach/iomap.h>
 #include <mach/hardware.h>
@@ -34,6 +37,8 @@
 #include "host1x/host1x01_hardware.h"
 #include "host1x/host1x_hwctx.h"
 #include "t20/t20.h"
+#include "t30/t30.h"
+#include "t114/t114.h"
 #include "chip_support.h"
 #include "nvhost_memmgr.h"
 #include "class_ids.h"
@@ -615,11 +620,32 @@ int nvhost_mpe_prepare_power_off(struct platform_device *dev)
        return nvhost_channel_save_context(pdata->channel);
 }
 
+static struct of_device_id tegra_mpe_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-mpe",
+               .data = (struct nvhost_device_data *)&t20_mpe_info },
+       { .compatible = "nvidia,tegra30-mpe",
+               .data = (struct nvhost_device_data *)&t30_mpe_info },
+       { },
+};
 static int __devinit mpe_probe(struct platform_device *dev)
 {
        int err = 0;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
+
+               match = of_match_device(tegra_mpe_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
 
        pdata->pdev = dev;
        platform_set_drvdata(dev, pdata);
@@ -668,6 +694,9 @@ static struct platform_driver mpe_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "mpe",
+#ifdef CONFIG_OF
+               .of_match_table = tegra_mpe_of_match,
+#endif
        },
 };
 
index 6abfeb8..0ac0663 100644 (file)
@@ -26,6 +26,9 @@
 #include <asm/byteorder.h>      /* for parsing ucode image wrt endianness */
 #include <linux/delay.h>       /* for udelay */
 #include <linux/scatterlist.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <mach/iomap.h>
 #include "dev.h"
 #include "msenc.h"
@@ -34,6 +37,7 @@
 #include "nvhost_acm.h"
 #include "chip_support.h"
 #include "nvhost_memmgr.h"
+#include "t114/t114.h"
 
 #define MSENC_IDLE_TIMEOUT_DEFAULT     10000   /* 10 milliseconds */
 #define MSENC_IDLE_CHECK_PERIOD                10      /* 10 usec */
@@ -313,8 +317,7 @@ clean_up:
 
 void nvhost_msenc_init(struct platform_device *dev)
 {
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = platform_get_drvdata(dev);
        int err = 0;
        struct msenc *m;
        char *fw_name;
@@ -379,11 +382,30 @@ void nvhost_msenc_finalize_poweron(struct platform_device *dev)
        msenc_boot(dev);
 }
 
+static struct of_device_id tegra_msenc_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra114-msenc",
+               .data = (struct nvhost_device_data *)&t11_msenc_info },
+       { },
+};
 static int __devinit msenc_probe(struct platform_device *dev)
 {
        int err = 0;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
+
+               match = of_match_device(tegra_msenc_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
 
        pdata->pdev = dev;
        pdata->init = nvhost_msenc_init;
@@ -436,6 +458,9 @@ static struct platform_driver msenc_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "msenc",
+#ifdef CONFIG_OF
+               .of_match_table = tegra_msenc_of_match,
+#endif
        }
 };
 
index b058a11..3bde9d6 100644 (file)
@@ -141,7 +141,7 @@ static void to_state_clockgated_locked(struct platform_device *dev)
                for (i = 0; i < pdata->num_clks; i++)
                        clk_disable_unprepare(pdata->clk[i]);
 
-               if (dev->dev.parent)
+               if (nvhost_get_parent(dev))
                        nvhost_module_idle(to_platform_device(dev->dev.parent));
 
                if (!pdata->can_powergate) {
@@ -175,7 +175,7 @@ static void to_state_running_locked(struct platform_device *dev)
                if (!pdata->can_powergate)
                        pm_runtime_get_sync(&dev->dev);
 
-               if (dev->dev.parent)
+               if (nvhost_get_parent(dev))
                        nvhost_module_busy(to_platform_device(dev->dev.parent));
 
                for (i = 0; i < pdata->num_clks; i++) {
@@ -755,7 +755,7 @@ bool nvhost_module_powered_ext(struct platform_device *dev)
 {
        struct platform_device *pdev;
 
-       BUG_ON(!dev->dev.parent);
+       BUG_ON(!nvhost_get_parent(dev));
 
        /* get the parent */
        pdev = to_platform_device(dev->dev.parent);
@@ -767,7 +767,7 @@ void nvhost_module_busy_ext(struct platform_device *dev)
 {
        struct platform_device *pdev;
 
-       BUG_ON(!dev->dev.parent);
+       BUG_ON(!nvhost_get_parent(dev));
 
        /* get the parent */
        pdev = to_platform_device(dev->dev.parent);
@@ -779,7 +779,7 @@ void nvhost_module_idle_ext(struct platform_device *dev)
 {
        struct platform_device *pdev;
 
-       BUG_ON(!dev->dev.parent);
+       BUG_ON(!nvhost_get_parent(dev));
 
        /* get the parent */
        pdev = to_platform_device(dev->dev.parent);
index 740502b..47cb27a 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host Syncpoints
  *
- * Copyright (c) 2010-2012, NVIDIA Corporation.
+ * Copyright (c) 2010-2013, NVIDIA CORPORATION, All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -513,7 +513,7 @@ u32 nvhost_syncpt_incr_max_ext(struct platform_device *dev, u32 id, u32 incrs)
        struct platform_device *pdev;
        struct nvhost_syncpt *sp;
 
-       BUG_ON(!dev->dev.parent);
+       BUG_ON(!nvhost_get_parent(dev));
 
        /* get the parent */
        pdev = to_platform_device(dev->dev.parent);
@@ -527,7 +527,7 @@ void nvhost_syncpt_cpu_incr_ext(struct platform_device *dev, u32 id)
        struct platform_device *pdev;
        struct nvhost_syncpt *sp;
 
-       BUG_ON(!dev->dev.parent);
+       BUG_ON(!nvhost_get_parent(dev));
 
        /* get the parent */
        pdev = to_platform_device(dev->dev.parent);
@@ -541,7 +541,7 @@ u32 nvhost_syncpt_read_ext(struct platform_device *dev, u32 id)
        struct platform_device *pdev;
        struct nvhost_syncpt *sp;
 
-       BUG_ON(!dev->dev.parent);
+       BUG_ON(!nvhost_get_parent(dev));
 
        /* get the parent */
        pdev = to_platform_device(dev->dev.parent);
@@ -556,7 +556,7 @@ int nvhost_syncpt_wait_timeout_ext(struct platform_device *dev, u32 id,
        struct platform_device *pdev;
        struct nvhost_syncpt *sp;
 
-       BUG_ON(!dev->dev.parent);
+       BUG_ON(!nvhost_get_parent(dev));
 
        /* get the parent */
        pdev = to_platform_device(dev->dev.parent);
index c2f0560..a9c4ffd 100644 (file)
@@ -27,6 +27,9 @@
 #include <linux/delay.h>       /* for udelay */
 #include <linux/scatterlist.h>
 #include <linux/stop_machine.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include "dev.h"
 #include "tsec.h"
 #include "hw_tsec.h"
@@ -35,6 +38,7 @@
 #include "chip_support.h"
 #include "nvhost_memmgr.h"
 #include "nvhost_intr.h"
+#include "t114/t114.h"
 
 #define TSEC_IDLE_TIMEOUT_DEFAULT      10000   /* 10 milliseconds */
 #define TSEC_IDLE_CHECK_PERIOD         10      /* 10 usec */
@@ -509,11 +513,30 @@ void nvhost_tsec_finalize_poweron(struct platform_device *dev)
        tsec_boot(dev);
 }
 
+static struct of_device_id tegra_tsec_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra114-tsec",
+               .data = (struct nvhost_device_data *)&t11_tsec_info },
+       { },
+};
 static int __devinit tsec_probe(struct platform_device *dev)
 {
        int err;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
+
+               match = of_match_device(tegra_tsec_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
 
        pdata->pdev = dev;
        pdata->init = nvhost_tsec_init;
@@ -581,6 +604,9 @@ static struct platform_driver tsec_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "tsec",
+#ifdef CONFIG_OF
+               .of_match_table = tegra_tsec_of_match,
+#endif
        }
 };
 
index 0669b4e..de2f7ad 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Tegra Graphics Host VI
  *
- * Copyright (c) 2012, NVIDIA Corporation.
+ * Copyright (c) 2012-2013, NVIDIA CORPORATION, All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 #include <linux/export.h>
 #include <linux/resource.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
 
 #include <mach/iomap.h>
 
 #include "dev.h"
 #include "bus_client.h"
+#include "t20/t20.h"
+#include "t30/t30.h"
+#include "t114/t114.h"
 #include "vi.h"
 
+static struct of_device_id tegra_vi_of_match[] __devinitdata = {
+       { .compatible = "nvidia,tegra20-vi",
+               .data = (struct nvhost_device_data *)&t20_vi_info },
+       { .compatible = "nvidia,tegra30-vi",
+               .data = (struct nvhost_device_data *)&t30_vi_info },
+       { .compatible = "nvidia,tegra114-vi",
+               .data = (struct nvhost_device_data *)&t11_vi_info },
+       { },
+};
 static int __devinit vi_probe(struct platform_device *dev)
 {
        int err = 0;
        struct vi *tegra_vi;
-       struct nvhost_device_data *pdata =
-               (struct nvhost_device_data *)dev->dev.platform_data;
+       struct nvhost_device_data *pdata = NULL;
+
+       if (dev->dev.of_node) {
+               const struct of_device_id *match;
+
+               match = of_match_device(tegra_vi_of_match, &dev->dev);
+               if (match)
+                       pdata = (struct nvhost_device_data *)match->data;
+       } else
+               pdata = (struct nvhost_device_data *)dev->dev.platform_data;
+
+       WARN_ON(!pdata);
+       if (!pdata) {
+               dev_info(&dev->dev, "no platform data\n");
+               return -ENODATA;
+       }
 
        dev_info(&dev->dev, "%s: ++\n", __func__);
        tegra_vi = kzalloc(sizeof(struct vi), GFP_KERNEL);
@@ -142,6 +171,9 @@ static struct platform_driver vi_driver = {
        .driver = {
                .owner = THIS_MODULE,
                .name = "vi",
+#ifdef CONFIG_OF
+               .of_match_table = tegra_vi_of_match,
+#endif
        }
 };