]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
video: host: vi: fix unbalanced power operations
authorBryan Wu <pengw@nvidia.com>
Sat, 7 Dec 2013 00:34:24 +0000 (16:34 -0800)
committerTerje Bergstrom <tbergstrom@nvidia.com>
Wed, 18 Dec 2013 11:50:49 +0000 (03:50 -0800)
Forget to remove VI platform device from power domain, which will
cause kernel oops when reload the module. Add
tegra_pd_remove_device() to solve this problem.

Regulator operation is also unbalanced, so move regulator_get()
in vi_init() and regulator_put() in vi_deinit(). Move
regulator_enable() in nvhost_vi_finalize_poweron() and
regulator_disable() in nvhost_vi_prepare_poweroff()

Remove pm_runtime operations, since they are handled by nvhost core

Bug 1421146

Change-Id: Iaec45d54ebf75f910c8e08b40b989632be834558
Signed-off-by: Bryan Wu <pengw@nvidia.com>
Reviewed-on: http://git-master/r/339527
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
drivers/video/tegra/host/vi/tegra_vi.c
drivers/video/tegra/host/vi/vi.c

index 5552b1f2e58c801218ec52fa227e96eb99a7112a..789393d37ddc4c9a2356bad94109452e9e07d0dd 100644 (file)
@@ -39,38 +39,52 @@ static DEFINE_MUTEX(la_lock);
 
 #ifdef TEGRA_12X_OR_HIGHER_CONFIG
 
-int nvhost_vi_init(struct platform_device *dev) {return 0; }
-
-void nvhost_vi_deinit(struct platform_device *dev) {}
-
-int nvhost_vi_finalize_poweron(struct platform_device *dev)
+int nvhost_vi_init(struct platform_device *dev)
 {
        int ret = 0;
-       struct vi *tegra_vi;
-       tegra_vi = (struct vi *)nvhost_get_private_data(dev);
+       struct vi *tegra_vi = nvhost_get_private_data(dev);
 
        tegra_vi->reg = regulator_get(&dev->dev, "avdd_dsi_csi");
        if (IS_ERR(tegra_vi->reg)) {
                if (tegra_vi->reg == ERR_PTR(-ENODEV)) {
                        ret = -ENODEV;
                        dev_info(&dev->dev,
-                               "%s: no regulator device\n",
-                               __func__);
+                                       "%s: no regulator device\n",
+                                       __func__);
                } else {
                        dev_err(&dev->dev,
-                               "%s: couldn't get regulator\n",
-                               __func__);
+                                       "%s: couldn't get regulator\n",
+                                       __func__);
                }
                tegra_vi->reg = NULL;
-               goto fail;
+               return ret;
+       }
+
+       return 0;
+}
+
+void nvhost_vi_deinit(struct platform_device *dev)
+{
+       struct vi *tegra_vi = nvhost_get_private_data(dev);
+
+       if (tegra_vi->reg) {
+               regulator_put(tegra_vi->reg);
+               tegra_vi->reg = NULL;
        }
+}
+
+int nvhost_vi_finalize_poweron(struct platform_device *dev)
+{
+       int ret = 0;
+       struct vi *tegra_vi;
+       tegra_vi = (struct vi *)nvhost_get_private_data(dev);
 
        if (tegra_vi->reg) {
                ret = regulator_enable(tegra_vi->reg);
                if (ret) {
                        dev_err(&dev->dev,
-                               "%s: enable csi regulator failed.\n",
-                               __func__);
+                                       "%s: enable csi regulator failed.\n",
+                                       __func__);
                        goto fail;
                }
        }
@@ -95,8 +109,6 @@ int nvhost_vi_prepare_poweroff(struct platform_device *dev)
                                __func__);
                        goto fail;
                }
-               regulator_put(tegra_vi->reg);
-               tegra_vi->reg = NULL;
        }
  fail:
        return ret;
index 4d09e6726d9ad363fc60cb29a4d2c04cca26ce80..edab7ba82c438d865537a3b45877a75a8a6152a6 100644 (file)
@@ -152,6 +152,7 @@ static int __exit vi_remove(struct platform_device *dev)
        dev_info(&dev->dev, "%s: ++\n", __func__);
 
        nvhost_client_device_release(dev);
+       pdata->aperture[0] = NULL;
 
 #ifdef CONFIG_TEGRA_CAMERA
        err = tegra_camera_unregister(tegra_vi->camera);
@@ -159,12 +160,10 @@ static int __exit vi_remove(struct platform_device *dev)
                return err;
 #endif
 
-#ifdef CONFIG_PM_RUNTIME
-       pm_runtime_put(&dev->dev);
-       pm_runtime_disable(&dev->dev);
-#else
-       nvhost_module_disable_clk(&dev->dev);
+#ifdef CONFIG_PM_GENERIC_DOMAINS
+       tegra_pd_remove_device(&dev->dev);
 #endif
+
        /* Remove I2C Devices according to settings from board file */
        if (i2c_ctrl && i2c_ctrl->remove_devices)
                i2c_ctrl->remove_devices(dev);