OMAPDSS: flush write after irq enable
[pandora-kernel.git] / drivers / video / omap2 / dss / core.c
index 86ec12e..fc408d0 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/suspend.h>
 
 #include <video/omapdss.h>
 
@@ -168,7 +169,29 @@ static inline void dss_uninitialize_debugfs(void)
 #endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
 
 /* PLATFORM DEVICE */
-static int omap_dss_probe(struct platform_device *pdev)
+static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d)
+{
+       DSSDBG("pm notif %lu\n", v);
+
+       switch (v) {
+       case PM_SUSPEND_PREPARE:
+               DSSDBG("suspending displays\n");
+               return dss_suspend_all_devices();
+
+       case PM_POST_SUSPEND:
+               DSSDBG("resuming displays\n");
+               return dss_resume_all_devices();
+
+       default:
+               return 0;
+       }
+}
+
+static struct notifier_block omap_dss_pm_notif_block = {
+       .notifier_call = omap_dss_pm_notif,
+};
+
+static int __init omap_dss_probe(struct platform_device *pdev)
 {
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
        int r;
@@ -181,42 +204,6 @@ static int omap_dss_probe(struct platform_device *pdev)
        dss_init_overlay_managers(pdev);
        dss_init_overlays(pdev);
 
-       r = dss_init_platform_driver();
-       if (r) {
-               DSSERR("Failed to initialize DSS platform driver\n");
-               goto err_dss;
-       }
-
-       r = dispc_init_platform_driver();
-       if (r) {
-               DSSERR("Failed to initialize dispc platform driver\n");
-               goto err_dispc;
-       }
-
-       r = rfbi_init_platform_driver();
-       if (r) {
-               DSSERR("Failed to initialize rfbi platform driver\n");
-               goto err_rfbi;
-       }
-
-       r = venc_init_platform_driver();
-       if (r) {
-               DSSERR("Failed to initialize venc platform driver\n");
-               goto err_venc;
-       }
-
-       r = dsi_init_platform_driver();
-       if (r) {
-               DSSERR("Failed to initialize DSI platform driver\n");
-               goto err_dsi;
-       }
-
-       r = hdmi_init_platform_driver();
-       if (r) {
-               DSSERR("Failed to initialize hdmi\n");
-               goto err_hdmi;
-       }
-
        r = dss_initialize_debugfs();
        if (r)
                goto err_debugfs;
@@ -239,23 +226,13 @@ static int omap_dss_probe(struct platform_device *pdev)
                        pdata->default_device = dssdev;
        }
 
+       register_pm_notifier(&omap_dss_pm_notif_block);
+
        return 0;
 
 err_register:
        dss_uninitialize_debugfs();
 err_debugfs:
-       hdmi_uninit_platform_driver();
-err_hdmi:
-       dsi_uninit_platform_driver();
-err_dsi:
-       venc_uninit_platform_driver();
-err_venc:
-       dispc_uninit_platform_driver();
-err_dispc:
-       rfbi_uninit_platform_driver();
-err_rfbi:
-       dss_uninit_platform_driver();
-err_dss:
 
        return r;
 }
@@ -265,14 +242,9 @@ static int omap_dss_remove(struct platform_device *pdev)
        struct omap_dss_board_info *pdata = pdev->dev.platform_data;
        int i;
 
-       dss_uninitialize_debugfs();
+       unregister_pm_notifier(&omap_dss_pm_notif_block);
 
-       hdmi_uninit_platform_driver();
-       dsi_uninit_platform_driver();
-       venc_uninit_platform_driver();
-       rfbi_uninit_platform_driver();
-       dispc_uninit_platform_driver();
-       dss_uninit_platform_driver();
+       dss_uninitialize_debugfs();
 
        dss_uninit_overlays(pdev);
        dss_uninit_overlay_managers(pdev);
@@ -289,26 +261,9 @@ static void omap_dss_shutdown(struct platform_device *pdev)
        dss_disable_all_devices();
 }
 
-static int omap_dss_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       DSSDBG("suspend %d\n", state.event);
-
-       return dss_suspend_all_devices();
-}
-
-static int omap_dss_resume(struct platform_device *pdev)
-{
-       DSSDBG("resume\n");
-
-       return dss_resume_all_devices();
-}
-
 static struct platform_driver omap_dss_driver = {
-       .probe          = omap_dss_probe,
        .remove         = omap_dss_remove,
        .shutdown       = omap_dss_shutdown,
-       .suspend        = omap_dss_suspend,
-       .resume         = omap_dss_resume,
        .driver         = {
                .name   = "omapdss",
                .owner  = THIS_MODULE,
@@ -434,6 +389,8 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
        if (dssdriver->get_recommended_bpp == NULL)
                dssdriver->get_recommended_bpp =
                        omapdss_default_get_recommended_bpp;
+       if (dssdriver->get_timings == NULL)
+               dssdriver->get_timings = omapdss_default_get_timings;
 
        return driver_register(&dssdriver->driver);
 }
@@ -523,6 +480,80 @@ static int omap_dss_bus_register(void)
 
 /* INIT */
 
+static int __init omap_dss_register_drivers(void)
+{
+       int r;
+
+       r = platform_driver_probe(&omap_dss_driver, omap_dss_probe);
+       if (r)
+               return r;
+
+       r = dss_init_platform_driver();
+       if (r) {
+               DSSERR("Failed to initialize DSS platform driver\n");
+               goto err_dss;
+       }
+
+       r = dispc_init_platform_driver();
+       if (r) {
+               DSSERR("Failed to initialize dispc platform driver\n");
+               goto err_dispc;
+       }
+
+       r = rfbi_init_platform_driver();
+       if (r) {
+               DSSERR("Failed to initialize rfbi platform driver\n");
+               goto err_rfbi;
+       }
+
+       r = venc_init_platform_driver();
+       if (r) {
+               DSSERR("Failed to initialize venc platform driver\n");
+               goto err_venc;
+       }
+
+       r = dsi_init_platform_driver();
+       if (r) {
+               DSSERR("Failed to initialize DSI platform driver\n");
+               goto err_dsi;
+       }
+
+       r = hdmi_init_platform_driver();
+       if (r) {
+               DSSERR("Failed to initialize hdmi\n");
+               goto err_hdmi;
+       }
+
+       return 0;
+
+err_hdmi:
+       dsi_uninit_platform_driver();
+err_dsi:
+       venc_uninit_platform_driver();
+err_venc:
+       rfbi_uninit_platform_driver();
+err_rfbi:
+       dispc_uninit_platform_driver();
+err_dispc:
+       dss_uninit_platform_driver();
+err_dss:
+       platform_driver_unregister(&omap_dss_driver);
+
+       return r;
+}
+
+static void __exit omap_dss_unregister_drivers(void)
+{
+       hdmi_uninit_platform_driver();
+       dsi_uninit_platform_driver();
+       venc_uninit_platform_driver();
+       rfbi_uninit_platform_driver();
+       dispc_uninit_platform_driver();
+       dss_uninit_platform_driver();
+
+       platform_driver_unregister(&omap_dss_driver);
+}
+
 #ifdef CONFIG_OMAP2_DSS_MODULE
 static void omap_dss_bus_unregister(void)
 {
@@ -539,7 +570,7 @@ static int __init omap_dss_init(void)
        if (r)
                return r;
 
-       r = platform_driver_register(&omap_dss_driver);
+       r = omap_dss_register_drivers();
        if (r) {
                omap_dss_bus_unregister();
                return r;
@@ -560,7 +591,7 @@ static void __exit omap_dss_exit(void)
                core.vdds_sdi_reg = NULL;
        }
 
-       platform_driver_unregister(&omap_dss_driver);
+       omap_dss_unregister_drivers();
 
        omap_dss_bus_unregister();
 }
@@ -575,7 +606,7 @@ static int __init omap_dss_init(void)
 
 static int __init omap_dss_init2(void)
 {
-       return platform_driver_register(&omap_dss_driver);
+       return omap_dss_register_drivers();
 }
 
 core_initcall(omap_dss_init);