u32 l;
        int r;
 
+       r = venc_runtime_get();
+       if (r)
+               goto err0;
+
        venc_reset();
        venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
 
 
        r = regulator_enable(venc.vdda_dac_reg);
        if (r)
-               goto err;
-
-       if (dssdev->platform_enable)
-               dssdev->platform_enable(dssdev);
+               goto err1;
 
        r = dss_mgr_enable(dssdev->manager);
        if (r)
-               goto err;
+               goto err2;
 
        return 0;
 
-err:
+err2:
+       regulator_disable(venc.vdda_dac_reg);
+err1:
        venc_write_reg(VENC_OUTPUT_CONTROL, 0);
        dss_set_dac_pwrdn_bgz(0);
 
-       if (dssdev->platform_disable)
-               dssdev->platform_disable(dssdev);
-
-       regulator_disable(venc.vdda_dac_reg);
-
+       venc_runtime_put();
+err0:
        return r;
 }
 
 
        dss_mgr_disable(dssdev->manager);
 
-       if (dssdev->platform_disable)
-               dssdev->platform_disable(dssdev);
-
        regulator_disable(venc.vdda_dac_reg);
+
+       venc_runtime_put();
 }
 
 unsigned long venc_get_pixel_clock(void)
        return 13500000;
 }
 
-static ssize_t display_output_type_show(struct device *dev,
-               struct device_attribute *attr, char *buf)
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       const char *ret;
-
-       switch (dssdev->phy.venc.type) {
-       case OMAP_DSS_VENC_TYPE_COMPOSITE:
-               ret = "composite";
-               break;
-       case OMAP_DSS_VENC_TYPE_SVIDEO:
-               ret = "svideo";
-               break;
-       default:
-               return -EINVAL;
-       }
+       int r;
 
-       return snprintf(buf, PAGE_SIZE, "%s\n", ret);
-}
-
-static ssize_t display_output_type_store(struct device *dev,
-               struct device_attribute *attr, const char *buf, size_t size)
-{
-       struct omap_dss_device *dssdev = to_dss_device(dev);
-       enum omap_dss_venc_type new_type;
-
-       if (sysfs_streq("composite", buf))
-               new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
-       else if (sysfs_streq("svideo", buf))
-               new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
-       else
-               return -EINVAL;
+       DSSDBG("venc_display_enable\n");
 
        mutex_lock(&venc.venc_lock);
 
-       if (dssdev->phy.venc.type != new_type) {
-               dssdev->phy.venc.type = new_type;
-               if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-                       venc_power_off(dssdev);
-                       venc_power_on(dssdev);
-               }
+       if (dssdev->manager == NULL) {
+               DSSERR("Failed to enable display: no manager\n");
+               r = -ENODEV;
+               goto err0;
        }
 
-       mutex_unlock(&venc.venc_lock);
-
-       return size;
-}
-
-static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
-               display_output_type_show, display_output_type_store);
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
-       dssdev->panel.timings = omap_dss_pal_timings;
-
-       return device_create_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
-       device_remove_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
-       int r = 0;
-
-       DSSDBG("venc_enable_display\n");
-
-       mutex_lock(&venc.venc_lock);
-
        r = omap_dss_start_device(dssdev);
        if (r) {
                DSSERR("failed to start device\n");
                goto err0;
        }
 
-       if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-               r = -EINVAL;
-               goto err1;
-       }
+       if (dssdev->platform_enable)
+               dssdev->platform_enable(dssdev);
 
-       r = venc_runtime_get();
-       if (r)
-               goto err1;
 
        r = venc_power_on(dssdev);
        if (r)
-               goto err2;
+               goto err1;
 
        venc.wss_data = 0;
 
-       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
        mutex_unlock(&venc.venc_lock);
+
        return 0;
-err2:
-       venc_runtime_put();
 err1:
+       if (dssdev->platform_disable)
+               dssdev->platform_disable(dssdev);
        omap_dss_stop_device(dssdev);
 err0:
        mutex_unlock(&venc.venc_lock);
-
        return r;
 }
 
-static void venc_panel_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
-       DSSDBG("venc_disable_display\n");
+       DSSDBG("venc_display_disable\n");
 
        mutex_lock(&venc.venc_lock);
 
-       if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
-               goto end;
-
-       if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
-               /* suspended is the same as disabled with venc */
-               dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-               goto end;
-       }
-
        venc_power_off(dssdev);
 
-       venc_runtime_put();
-
-       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
        omap_dss_stop_device(dssdev);
-end:
-       mutex_unlock(&venc.venc_lock);
-}
 
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-       venc_panel_disable(dssdev);
-       return 0;
-}
+       if (dssdev->platform_disable)
+               dssdev->platform_disable(dssdev);
 
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-       return venc_panel_enable(dssdev);
+       mutex_unlock(&venc.venc_lock);
 }
 
-static void venc_set_timings(struct omap_dss_device *dssdev,
-                       struct omap_video_timings *timings)
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
 {
        DSSDBG("venc_set_timings\n");
 
+       mutex_lock(&venc.venc_lock);
+
        /* Reset WSS data when the TV standard changes. */
        if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
                venc.wss_data = 0;
 
        dssdev->panel.timings = *timings;
+
        if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+               int r;
+
                /* turn the venc off and on to get new timings to use */
-               venc_panel_disable(dssdev);
-               venc_panel_enable(dssdev);
+               venc_power_off(dssdev);
+
+               r = venc_power_on(dssdev);
+               if (r)
+                       DSSERR("failed to power on VENC\n");
        } else {
                dss_mgr_set_timings(dssdev->manager, timings);
        }
+
+       mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_check_timings(struct omap_dss_device *dssdev,
-                       struct omap_video_timings *timings)
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
 {
        DSSDBG("venc_check_timings\n");
 
        return -EINVAL;
 }
 
-static u32 venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
 {
        /* Invert due to VENC_L21_WC_CTL:INV=1 */
        return (venc.wss_data >> 8) ^ 0xfffff;
 }
 
-static int venc_set_wss(struct omap_dss_device *dssdev,        u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 {
        const struct venc_config *config;
        int r;
        return r;
 }
 
-static struct omap_dss_driver venc_driver = {
-       .probe          = venc_panel_probe,
-       .remove         = venc_panel_remove,
-
-       .enable         = venc_panel_enable,
-       .disable        = venc_panel_disable,
-       .suspend        = venc_panel_suspend,
-       .resume         = venc_panel_resume,
-
-       .get_resolution = omapdss_default_get_resolution,
-       .get_recommended_bpp = omapdss_default_get_recommended_bpp,
-
-       .set_timings    = venc_set_timings,
-       .check_timings  = venc_check_timings,
-
-       .get_wss        = venc_get_wss,
-       .set_wss        = venc_set_wss,
-
-       .driver         = {
-               .name   = "venc",
-               .owner  = THIS_MODULE,
-       },
-};
-/* driver end */
-
 static int __init venc_init_display(struct omap_dss_device *dssdev)
 {
        DSSDBG("init_display\n");
 
        venc_runtime_put();
 
-       r = omap_dss_register_driver(&venc_driver);
+       r = venc_panel_init();
        if (r)
-               goto err_reg_panel_driver;
+               goto err_panel_init;
 
        dss_debugfs_create_file("venc", venc_dump_regs);
 
 
        return 0;
 
-err_reg_panel_driver:
+err_panel_init:
 err_runtime_get:
        pm_runtime_disable(&pdev->dev);
        venc_put_clocks();
                venc.vdda_dac_reg = NULL;
        }
 
-       omap_dss_unregister_driver(&venc_driver);
+       venc_panel_exit();
 
        pm_runtime_disable(&pdev->dev);
        venc_put_clocks();
 
--- /dev/null
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC panel driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct {
+       struct mutex lock;
+} venc_panel;
+
+static ssize_t display_output_type_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       const char *ret;
+
+       switch (dssdev->phy.venc.type) {
+       case OMAP_DSS_VENC_TYPE_COMPOSITE:
+               ret = "composite";
+               break;
+       case OMAP_DSS_VENC_TYPE_SVIDEO:
+               ret = "svideo";
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", ret);
+}
+
+static ssize_t display_output_type_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct omap_dss_device *dssdev = to_dss_device(dev);
+       enum omap_dss_venc_type new_type;
+
+       if (sysfs_streq("composite", buf))
+               new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+       else if (sysfs_streq("svideo", buf))
+               new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
+       else
+               return -EINVAL;
+
+       mutex_lock(&venc_panel.lock);
+
+       if (dssdev->phy.venc.type != new_type) {
+               dssdev->phy.venc.type = new_type;
+               if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+                       omapdss_venc_display_disable(dssdev);
+                       omapdss_venc_display_enable(dssdev);
+               }
+       }
+
+       mutex_unlock(&venc_panel.lock);
+
+       return size;
+}
+
+static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
+               display_output_type_show, display_output_type_store);
+
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+       /* set default timings to PAL */
+       const struct omap_video_timings default_timings = {
+               .x_res          = 720,
+               .y_res          = 574,
+               .pixel_clock    = 13500,
+               .hsw            = 64,
+               .hfp            = 12,
+               .hbp            = 68,
+               .vsw            = 5,
+               .vfp            = 5,
+               .vbp            = 41,
+
+               .vsync_level    = OMAPDSS_SIG_ACTIVE_HIGH,
+               .hsync_level    = OMAPDSS_SIG_ACTIVE_HIGH,
+
+               .interlace      = true,
+       };
+
+       mutex_init(&venc_panel.lock);
+
+       dssdev->panel.timings = default_timings;
+
+       return device_create_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+       device_remove_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+       int r;
+
+       dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+
+       mutex_lock(&venc_panel.lock);
+
+       if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+               r = -EINVAL;
+               goto err;
+       }
+
+       r = omapdss_venc_display_enable(dssdev);
+       if (r)
+               goto err;
+
+       dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+       mutex_unlock(&venc_panel.lock);
+
+       return 0;
+err:
+       mutex_unlock(&venc_panel.lock);
+
+       return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+       dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+
+       mutex_lock(&venc_panel.lock);
+
+       if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+               goto end;
+
+       if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
+               /* suspended is the same as disabled with venc */
+               dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+               goto end;
+       }
+
+       omapdss_venc_display_disable(dssdev);
+
+       dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+       mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+       venc_panel_disable(dssdev);
+       return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+       return venc_panel_enable(dssdev);
+}
+
+static void venc_panel_set_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+
+       mutex_lock(&venc_panel.lock);
+
+       omapdss_venc_set_timings(dssdev, timings);
+
+       mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_check_timings(struct omap_dss_device *dssdev,
+               struct omap_video_timings *timings)
+{
+       dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+
+       return omapdss_venc_check_timings(dssdev, timings);
+}
+
+static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
+{
+       dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+
+       return omapdss_venc_get_wss(dssdev);
+}
+
+static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
+{
+       dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+
+       return omapdss_venc_set_wss(dssdev, wss);
+}
+
+static struct omap_dss_driver venc_driver = {
+       .probe          = venc_panel_probe,
+       .remove         = venc_panel_remove,
+
+       .enable         = venc_panel_enable,
+       .disable        = venc_panel_disable,
+       .suspend        = venc_panel_suspend,
+       .resume         = venc_panel_resume,
+
+       .get_resolution = omapdss_default_get_resolution,
+       .get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+       .set_timings    = venc_panel_set_timings,
+       .check_timings  = venc_panel_check_timings,
+
+       .get_wss        = venc_panel_get_wss,
+       .set_wss        = venc_panel_set_wss,
+
+       .driver         = {
+               .name   = "venc",
+               .owner  = THIS_MODULE,
+       },
+};
+
+int venc_panel_init(void)
+{
+       return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_panel_exit(void)
+{
+       omap_dss_unregister_driver(&venc_driver);
+}