summaryrefslogtreecommitdiff
path: root/recipes/linux/linux-omap-pm/dss2/0087-DSS2-new-device-driver-model.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/linux/linux-omap-pm/dss2/0087-DSS2-new-device-driver-model.patch')
-rw-r--r--recipes/linux/linux-omap-pm/dss2/0087-DSS2-new-device-driver-model.patch5336
1 files changed, 5336 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-pm/dss2/0087-DSS2-new-device-driver-model.patch b/recipes/linux/linux-omap-pm/dss2/0087-DSS2-new-device-driver-model.patch
new file mode 100644
index 0000000000..ecc51227f2
--- /dev/null
+++ b/recipes/linux/linux-omap-pm/dss2/0087-DSS2-new-device-driver-model.patch
@@ -0,0 +1,5336 @@
+From 63614d959a4558c552a9d9aec693018fb6eece63 Mon Sep 17 00:00:00 2001
+From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+Date: Mon, 1 Jun 2009 14:15:13 +0300
+Subject: [PATCH 087/146] DSS2: new device/driver model
+
+Use better model for handling DSS devices and drivers.
+
+Remove omap_display, omap_ctrl and omap_panel structs, and add
+omap_dss_device and omap_dss_driver. DSS devices are added to DSS bus.
+
+The commit changes almost every part of DSS2, even if actual
+functionality should be changed only in few parts.
+---
+ arch/arm/plat-omap/include/mach/display.h | 400 ++++++++----------
+ drivers/video/omap2/dss/core.c | 306 +++++++++++++-
+ drivers/video/omap2/dss/dispc.c | 36 +-
+ drivers/video/omap2/dss/display.c | 654 ++++++++++++-----------------
+ drivers/video/omap2/dss/dpi.c | 150 ++++---
+ drivers/video/omap2/dss/dsi.c | 584 ++++++++++++--------------
+ drivers/video/omap2/dss/dss.h | 44 ++-
+ drivers/video/omap2/dss/manager.c | 108 +++---
+ drivers/video/omap2/dss/overlay.c | 93 ++---
+ drivers/video/omap2/dss/rfbi.c | 104 +++---
+ drivers/video/omap2/dss/sdi.c | 115 +++---
+ drivers/video/omap2/dss/venc.c | 192 ++++++---
+ drivers/video/omap2/omapfb/omapfb-ioctl.c | 12 +-
+ drivers/video/omap2/omapfb/omapfb-main.c | 49 +--
+ drivers/video/omap2/omapfb/omapfb.h | 6 +-
+ 15 files changed, 1526 insertions(+), 1327 deletions(-)
+
+diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
+index d36f730..57bb8ff 100644
+--- a/arch/arm/plat-omap/include/mach/display.h
++++ b/arch/arm/plat-omap/include/mach/display.h
+@@ -22,6 +22,7 @@
+
+ #include <linux/list.h>
+ #include <linux/kobject.h>
++#include <linux/device.h>
+ #include <asm/atomic.h>
+
+ #define DISPC_IRQ_FRAMEDONE (1 << 0)
+@@ -42,6 +43,9 @@
+ #define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15)
+ #define DISPC_IRQ_WAKEUP (1 << 16)
+
++struct omap_dss_device;
++struct omap_overlay_manager;
++
+ enum omap_display_type {
+ OMAP_DISPLAY_TYPE_NONE = 0,
+ OMAP_DISPLAY_TYPE_DPI = 1 << 0,
+@@ -132,9 +136,41 @@ enum omap_dss_venc_type {
+ OMAP_DSS_VENC_TYPE_SVIDEO,
+ };
+
+-struct omap_display;
+-struct omap_panel;
+-struct omap_ctrl;
++enum omap_display_caps {
++ OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE = 1 << 0,
++};
++
++enum omap_dss_update_mode {
++ OMAP_DSS_UPDATE_DISABLED = 0,
++ OMAP_DSS_UPDATE_AUTO,
++ OMAP_DSS_UPDATE_MANUAL,
++};
++
++enum omap_dss_display_state {
++ OMAP_DSS_DISPLAY_DISABLED = 0,
++ OMAP_DSS_DISPLAY_ACTIVE,
++ OMAP_DSS_DISPLAY_SUSPENDED,
++};
++
++/* XXX perhaps this should be removed */
++enum omap_dss_overlay_managers {
++ OMAP_DSS_OVL_MGR_LCD,
++ OMAP_DSS_OVL_MGR_TV,
++};
++
++enum omap_dss_rotation_type {
++ OMAP_DSS_ROT_DMA = 0,
++ OMAP_DSS_ROT_VRFB = 1,
++};
++
++enum omap_overlay_caps {
++ OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
++ OMAP_DSS_OVL_CAP_DISPC = 1 << 1,
++};
++
++enum omap_overlay_manager_caps {
++ OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
++};
+
+ /* RFBI */
+
+@@ -178,108 +214,13 @@ int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
+ int dsi_vc_send_null(int channel);
+
+ /* Board specific data */
+-struct omap_dss_display_config {
+- enum omap_display_type type;
+-
+- union {
+- struct {
+- u8 data_lines;
+- } dpi;
+-
+- struct {
+- u8 channel;
+- u8 data_lines;
+- } rfbi;
+-
+- struct {
+- u8 datapairs;
+- } sdi;
+-
+- struct {
+- u8 clk_lane;
+- u8 clk_pol;
+- u8 data1_lane;
+- u8 data1_pol;
+- u8 data2_lane;
+- u8 data2_pol;
+- unsigned long lp_clk_hz;
+- unsigned long ddr_clk_hz;
+-
+- bool ext_te;
+- u8 ext_te_gpio;
+- } dsi;
+-
+- struct {
+- enum omap_dss_venc_type type;
+- } venc;
+- } u;
+-
+- int panel_reset_gpio;
+- int ctrl_reset_gpio;
+-
+- int max_backlight_level;
+-
+- const char *name; /* for debug */
+- const char *ctrl_name;
+- const char *panel_name;
+-
+- void *panel_data;
+- void *ctrl_data;
+-
+- /* platform specific enable/disable */
+- int (*panel_enable)(struct omap_display *display);
+- void (*panel_disable)(struct omap_display *display);
+- int (*ctrl_enable)(struct omap_display *display);
+- void (*ctrl_disable)(struct omap_display *display);
+- int (*set_backlight)(struct omap_display *display,
+- int level);
+- int (*get_backlight)(struct omap_display *display);
+-};
+-
+-struct device;
+-
+-/* Board specific data */
+-struct omap_dss_board_info {
++struct omap_dss_board_info {
+ int (*get_last_off_on_transaction_id)(struct device *dev);
++ int num_devices;
++ struct omap_dss_device **devices;
++ struct omap_dss_device *default_device;
+ int (*dsi_power_up)(void);
+ void (*dsi_power_down)(void);
+- int num_displays;
+- struct omap_dss_display_config *displays[];
+-};
+-
+-struct omap_ctrl {
+- struct module *owner;
+-
+- const char *name;
+-
+- int (*init)(struct omap_display *display);
+- void (*cleanup)(struct omap_display *display);
+- int (*enable)(struct omap_display *display);
+- void (*disable)(struct omap_display *display);
+- int (*suspend)(struct omap_display *display);
+- int (*resume)(struct omap_display *display);
+- void (*setup_update)(struct omap_display *display,
+- u16 x, u16 y, u16 w, u16 h);
+-
+- int (*enable_te)(struct omap_display *display, bool enable);
+- int (*wait_for_te)(struct omap_display *display);
+-
+- u8 (*get_rotate)(struct omap_display *display);
+- int (*set_rotate)(struct omap_display *display, u8 rotate);
+-
+- bool (*get_mirror)(struct omap_display *display);
+- int (*set_mirror)(struct omap_display *display, bool enable);
+-
+- int (*run_test)(struct omap_display *display, int test);
+- int (*memory_read)(struct omap_display *display,
+- void *buf, size_t size,
+- u16 x, u16 y, u16 w, u16 h);
+-
+- u8 pixel_size;
+-
+- struct rfbi_timings timings;
+-
+- void *priv;
+ };
+
+ struct omap_video_timings {
+@@ -301,7 +242,6 @@ struct omap_video_timings {
+ u16 vfp; /* Vertical front porch */
+ /* Unit: line clocks */
+ u16 vbp; /* Vertical back porch */
+-
+ };
+
+ #ifdef CONFIG_OMAP2_DSS_VENC
+@@ -313,46 +253,6 @@ const extern struct omap_video_timings omap_dss_pal_timings;
+ const extern struct omap_video_timings omap_dss_ntsc_timings;
+ #endif
+
+-struct omap_panel {
+- struct module *owner;
+-
+- const char *name;
+-
+- int (*init)(struct omap_display *display);
+- void (*cleanup)(struct omap_display *display);
+- int (*remove)(struct omap_display *display);
+- int (*enable)(struct omap_display *display);
+- void (*disable)(struct omap_display *display);
+- int (*suspend)(struct omap_display *display);
+- int (*resume)(struct omap_display *display);
+- int (*run_test)(struct omap_display *display, int test);
+-
+- struct omap_video_timings timings;
+-
+- int acbi; /* ac-bias pin transitions per interrupt */
+- /* Unit: line clocks */
+- int acb; /* ac-bias pin frequency */
+-
+- enum omap_panel_config config;
+-
+- u8 recommended_bpp;
+-
+- void *priv;
+-};
+-
+-/* XXX perhaps this should be removed */
+-enum omap_dss_overlay_managers {
+- OMAP_DSS_OVL_MGR_LCD,
+- OMAP_DSS_OVL_MGR_TV,
+-};
+-
+-struct omap_overlay_manager;
+-
+-enum omap_dss_rotation_type {
+- OMAP_DSS_ROT_DMA = 0,
+- OMAP_DSS_ROT_VRFB = 1,
+-};
+-
+ struct omap_overlay_info {
+ bool enabled;
+
+@@ -373,11 +273,6 @@ struct omap_overlay_info {
+ u8 global_alpha;
+ };
+
+-enum omap_overlay_caps {
+- OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
+- OMAP_DSS_OVL_CAP_DISPC = 1 << 1,
+-};
+-
+ struct omap_overlay {
+ struct kobject kobj;
+ struct list_head list;
+@@ -399,10 +294,6 @@ struct omap_overlay {
+ struct omap_overlay_info *info);
+ };
+
+-enum omap_overlay_manager_caps {
+- OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
+-};
+-
+ struct omap_overlay_manager {
+ struct kobject kobj;
+ struct list_head list;
+@@ -410,14 +301,14 @@ struct omap_overlay_manager {
+ const char *name;
+ int id;
+ enum omap_overlay_manager_caps caps;
+- struct omap_display *display;
++ struct omap_dss_device *device;
+ int num_overlays;
+ struct omap_overlay **overlays;
+ enum omap_display_type supported_displays;
+
+- int (*set_display)(struct omap_overlay_manager *mgr,
+- struct omap_display *display);
+- int (*unset_display)(struct omap_overlay_manager *mgr);
++ int (*set_device)(struct omap_overlay_manager *mgr,
++ struct omap_dss_device *dssdev);
++ int (*unset_device)(struct omap_overlay_manager *mgr);
+
+ int (*apply)(struct omap_overlay_manager *mgr);
+
+@@ -437,99 +328,183 @@ struct omap_overlay_manager {
+ bool enable);
+ };
+
+-enum omap_display_caps {
+- OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE = 1 << 0,
+-};
++struct omap_dss_device {
++ struct device dev;
+
+-enum omap_dss_update_mode {
+- OMAP_DSS_UPDATE_DISABLED = 0,
+- OMAP_DSS_UPDATE_AUTO,
+- OMAP_DSS_UPDATE_MANUAL,
+-};
++ enum omap_display_type type;
+
+-enum omap_dss_display_state {
+- OMAP_DSS_DISPLAY_DISABLED = 0,
+- OMAP_DSS_DISPLAY_ACTIVE,
+- OMAP_DSS_DISPLAY_SUSPENDED,
+-};
++ union {
++ struct {
++ u8 data_lines;
++ } dpi;
+
+-struct omap_display {
+- struct kobject kobj;
+- struct list_head list;
++ struct {
++ u8 channel;
++ u8 data_lines;
++ } rfbi;
+
+- /*atomic_t ref_count;*/
+- int ref_count;
+- /* helper variable for driver suspend/resume */
+- int activate_after_resume;
++ struct {
++ u8 datapairs;
++ } sdi;
++
++ struct {
++ u8 clk_lane;
++ u8 clk_pol;
++ u8 data1_lane;
++ u8 data1_pol;
++ u8 data2_lane;
++ u8 data2_pol;
++ unsigned long lp_clk_hz;
++ unsigned long ddr_clk_hz;
++
++ bool ext_te;
++ u8 ext_te_gpio;
++ } dsi;
++
++ struct {
++ enum omap_dss_venc_type type;
++ } venc;
++ } phy;
++
++ struct {
++ struct omap_video_timings timings;
++
++ int acbi; /* ac-bias pin transitions per interrupt */
++ /* Unit: line clocks */
++ int acb; /* ac-bias pin frequency */
++
++ enum omap_panel_config config;
++
++ u8 recommended_bpp;
++
++ struct omap_dss_device *ctrl;
++ } panel;
++
++ struct {
++ u8 pixel_size;
++ struct rfbi_timings rfbi_timings;
++ struct omap_dss_device *panel;
++ } ctrl;
++
++ int reset_gpio;
++
++ int max_backlight_level;
+
+- enum omap_display_type type;
+ const char *name;
+
++ /* used to match device to driver */
++ const char *driver_name;
++
++ void *data;
++
++ struct omap_dss_driver *driver;
++
++ /* helper variable for driver suspend/resume */
++ bool activate_after_resume;
++
+ enum omap_display_caps caps;
+
+ struct omap_overlay_manager *manager;
+
+ enum omap_dss_display_state state;
+
+- struct omap_dss_display_config hw_config; /* board specific data */
+- struct omap_ctrl *ctrl; /* static common data */
+- struct omap_panel *panel; /* static common data */
+-
+- int (*enable)(struct omap_display *display);
+- void (*disable)(struct omap_display *display);
++ int (*enable)(struct omap_dss_device *dssdev);
++ void (*disable)(struct omap_dss_device *dssdev);
+
+- int (*suspend)(struct omap_display *display);
+- int (*resume)(struct omap_display *display);
++ int (*suspend)(struct omap_dss_device *dssdev);
++ int (*resume)(struct omap_dss_device *dssdev);
+
+- void (*get_resolution)(struct omap_display *display,
++ void (*get_resolution)(struct omap_dss_device *dssdev,
+ u16 *xres, u16 *yres);
+- int (*get_recommended_bpp)(struct omap_display *display);
++ int (*get_recommended_bpp)(struct omap_dss_device *dssdev);
+
+- int (*check_timings)(struct omap_display *display,
++ int (*check_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+- void (*set_timings)(struct omap_display *display,
++ void (*set_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+- void (*get_timings)(struct omap_display *display,
++ void (*get_timings)(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+- int (*update)(struct omap_display *display,
++ int (*update)(struct omap_dss_device *dssdev,
+ u16 x, u16 y, u16 w, u16 h);
+- int (*sync)(struct omap_display *display);
+- int (*wait_vsync)(struct omap_display *display);
++ int (*sync)(struct omap_dss_device *dssdev);
++ int (*wait_vsync)(struct omap_dss_device *dssdev);
+
+- int (*set_update_mode)(struct omap_display *display,
++ int (*set_update_mode)(struct omap_dss_device *dssdev,
+ enum omap_dss_update_mode);
+ enum omap_dss_update_mode (*get_update_mode)
+- (struct omap_display *display);
++ (struct omap_dss_device *dssdev);
+
+- int (*enable_te)(struct omap_display *display, bool enable);
+- int (*get_te)(struct omap_display *display);
++ int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
++ int (*get_te)(struct omap_dss_device *dssdev);
++ int (*wait_for_te)(struct omap_dss_device *dssdev);
+
+- u8 (*get_rotate)(struct omap_display *display);
+- int (*set_rotate)(struct omap_display *display, u8 rotate);
++ u8 (*get_rotate)(struct omap_dss_device *dssdev);
++ int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
+
+- bool (*get_mirror)(struct omap_display *display);
+- int (*set_mirror)(struct omap_display *display, bool enable);
++ bool (*get_mirror)(struct omap_dss_device *dssdev);
++ int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
+
+- int (*run_test)(struct omap_display *display, int test);
+- int (*memory_read)(struct omap_display *display,
++ int (*run_test)(struct omap_dss_device *dssdev, int test);
++ int (*memory_read)(struct omap_dss_device *dssdev,
+ void *buf, size_t size,
+ u16 x, u16 y, u16 w, u16 h);
+
+ void (*configure_overlay)(struct omap_overlay *overlay);
+
+- int (*set_wss)(struct omap_display *display, u32 wss);
+- u32 (*get_wss)(struct omap_display *display);
++ int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
++ u32 (*get_wss)(struct omap_dss_device *dssdev);
++
++ /* platform specific */
++ int (*platform_enable)(struct omap_dss_device *dssdev);
++ void (*platform_disable)(struct omap_dss_device *dssdev);
++ int (*set_backlight)(struct omap_dss_device *dssdev, int level);
++ int (*get_backlight)(struct omap_dss_device *dssdev);
+ };
+
+-int omap_dss_get_num_displays(void);
+-struct omap_display *omap_dss_get_display(int no);
+-void omap_dss_put_display(struct omap_display *display);
++struct omap_dss_driver {
++ struct device_driver driver;
++
++ int (*probe)(struct omap_dss_device *);
++ void (*remove)(struct omap_dss_device *);
+
+-void omap_dss_register_ctrl(struct omap_ctrl *ctrl);
+-void omap_dss_unregister_ctrl(struct omap_ctrl *ctrl);
++ int (*enable)(struct omap_dss_device *display);
++ void (*disable)(struct omap_dss_device *display);
++ int (*suspend)(struct omap_dss_device *display);
++ int (*resume)(struct omap_dss_device *display);
++ int (*run_test)(struct omap_dss_device *display, int test);
+
+-void omap_dss_register_panel(struct omap_panel *panel);
+-void omap_dss_unregister_panel(struct omap_panel *panel);
++ void (*setup_update)(struct omap_dss_device *dssdev,
++ u16 x, u16 y, u16 w, u16 h);
++
++ int (*enable_te)(struct omap_dss_device *dssdev, bool enable);
++ int (*wait_for_te)(struct omap_dss_device *dssdev);
++
++ u8 (*get_rotate)(struct omap_dss_device *dssdev);
++ int (*set_rotate)(struct omap_dss_device *dssdev, u8 rotate);
++
++ bool (*get_mirror)(struct omap_dss_device *dssdev);
++ int (*set_mirror)(struct omap_dss_device *dssdev, bool enable);
++
++ int (*memory_read)(struct omap_dss_device *dssdev,
++ void *buf, size_t size,
++ u16 x, u16 y, u16 w, u16 h);
++};
++
++int omap_dss_register_driver(struct omap_dss_driver *);
++void omap_dss_unregister_driver(struct omap_dss_driver *);
++
++int omap_dss_register_device(struct omap_dss_device *);
++void omap_dss_unregister_device(struct omap_dss_device *);
++
++void omap_dss_get_device(struct omap_dss_device *dssdev);
++void omap_dss_put_device(struct omap_dss_device *dssdev);
++#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
++struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
++struct omap_dss_device *omap_dss_find_device(void *data,
++ int (*match)(struct omap_dss_device *dssdev, void *data));
++
++int omap_dss_start_device(struct omap_dss_device *dssdev);
++void omap_dss_stop_device(struct omap_dss_device *dssdev);
+
+ int omap_dss_get_num_overlay_managers(void);
+ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
+@@ -544,5 +519,4 @@ int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
+ int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
+ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
+ unsigned long timeout);
+-
+ #endif
+diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
+index 2a38507..c56c431 100644
+--- a/drivers/video/omap2/dss/core.c
++++ b/drivers/video/omap2/dss/core.c
+@@ -30,6 +30,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/debugfs.h>
+ #include <linux/io.h>
++#include <linux/device.h>
+
+ #include <mach/display.h>
+ #include <mach/clock.h>
+@@ -437,11 +438,16 @@ void dss_dsi_power_down(void)
+ /* PLATFORM DEVICE */
+ static int omap_dss_probe(struct platform_device *pdev)
+ {
++ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+ int skip_init = 0;
+ int r;
++ int i;
+
+ core.pdev = pdev;
+
++ dss_init_overlay_managers(pdev);
++ dss_init_overlays(pdev);
++
+ r = dss_get_clocks();
+ if (r)
+ goto fail0;
+@@ -483,7 +489,7 @@ static int omap_dss_probe(struct platform_device *pdev)
+ goto fail0;
+ }
+ #ifdef CONFIG_OMAP2_DSS_VENC
+- r = venc_init();
++ r = venc_init(pdev);
+ if (r) {
+ DSSERR("Failed to initialize venc\n");
+ goto fail0;
+@@ -498,7 +504,7 @@ static int omap_dss_probe(struct platform_device *pdev)
+ }
+ #endif
+ #ifdef CONFIG_OMAP2_DSS_DSI
+- r = dsi_init();
++ r = dsi_init(pdev);
+ if (r) {
+ DSSERR("Failed to initialize DSI\n");
+ goto fail0;
+@@ -512,9 +518,16 @@ static int omap_dss_probe(struct platform_device *pdev)
+ goto fail0;
+ #endif
+
+- dss_init_displays(pdev);
+- dss_init_overlay_managers(pdev);
+- dss_init_overlays(pdev, def_disp_name);
++ for (i = 0; i < pdata->num_devices; ++i) {
++ struct omap_dss_device *dssdev = pdata->devices[i];
++
++ r = omap_dss_register_device(dssdev);
++ if (r)
++ DSSERR("device reg failed %d\n", i);
++
++ if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0)
++ pdata->default_device = dssdev;
++ }
+
+ dss_clk_disable_all();
+
+@@ -527,12 +540,10 @@ fail0:
+
+ static int omap_dss_remove(struct platform_device *pdev)
+ {
++ struct omap_dss_board_info *pdata = pdev->dev.platform_data;
++ int i;
+ int c;
+
+- dss_uninit_overlays(pdev);
+- dss_uninit_overlay_managers(pdev);
+- dss_uninit_displays(pdev);
+-
+ #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+ dss_uninitialize_debugfs();
+ #endif
+@@ -597,6 +608,12 @@ static int omap_dss_remove(struct platform_device *pdev)
+
+ dss_put_clocks();
+
++ dss_uninit_overlays(pdev);
++ dss_uninit_overlay_managers(pdev);
++
++ for (i = 0; i < pdata->num_devices; ++i)
++ omap_dss_unregister_device(pdata->devices[i]);
++
+ return 0;
+ }
+
+@@ -609,14 +626,14 @@ static int omap_dss_suspend(struct platform_device *pdev, pm_message_t state)
+ {
+ DSSDBG("suspend %d\n", state.event);
+
+- return dss_suspend_all_displays();
++ return dss_suspend_all_devices();
+ }
+
+ static int omap_dss_resume(struct platform_device *pdev)
+ {
+ DSSDBG("resume\n");
+
+- return dss_resume_all_displays();
++ return dss_resume_all_devices();
+ }
+
+ static struct platform_driver omap_dss_driver = {
+@@ -631,19 +648,282 @@ static struct platform_driver omap_dss_driver = {
+ },
+ };
+
++/* BUS */
++static int dss_bus_match(struct device *dev, struct device_driver *driver)
++{
++ struct omap_dss_device *dssdev = to_dss_device(dev);
++
++ DSSDBG("bus_match. dev %s/%s, drv %s\n",
++ dev_name(dev), dssdev->driver_name, driver->name);
++
++ return strcmp(dssdev->driver_name, driver->name) == 0;
++}
++
++static ssize_t device_name_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct omap_dss_device *dssdev = to_dss_device(dev);
++ return snprintf(buf, PAGE_SIZE, "%s\n",
++ dssdev->name ?
++ dssdev->name : "");
++}
++
++static struct device_attribute default_dev_attrs[] = {
++ __ATTR(name, S_IRUGO, device_name_show, NULL),
++ __ATTR_NULL,
++};
++
++static ssize_t driver_name_show(struct device_driver *drv, char *buf)
++{
++ struct omap_dss_driver *dssdrv = to_dss_driver(drv);
++ return snprintf(buf, PAGE_SIZE, "%s\n",
++ dssdrv->driver.name ?
++ dssdrv->driver.name : "");
++}
++static struct driver_attribute default_drv_attrs[] = {
++ __ATTR(name, S_IRUGO, driver_name_show, NULL),
++ __ATTR_NULL,
++};
++
++static struct bus_type dss_bus_type = {
++ .name = "omapdss",
++ .match = dss_bus_match,
++ .dev_attrs = default_dev_attrs,
++ .drv_attrs = default_drv_attrs,
++};
++
++static void dss_bus_release(struct device *dev)
++{
++ DSSDBG("bus_release\n");
++}
++
++static struct device dss_bus = {
++ .release = dss_bus_release,
++};
++
++struct bus_type *dss_get_bus(void)
++{
++ return &dss_bus_type;
++}
++
++/* DRIVER */
++static int dss_driver_probe(struct device *dev)
++{
++ int r;
++ struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
++ struct omap_dss_device *dssdev = to_dss_device(dev);
++ struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
++ bool force;
++
++ DSSDBG("driver_probe: dev %s/%s, drv %s\n",
++ dev_name(dev), dssdev->driver_name,
++ dssdrv->driver.name);
++
++ dss_init_device(core.pdev, dssdev);
++
++ /* skip this if the device is behind a ctrl */
++ if (!dssdev->panel.ctrl) {
++ force = pdata->default_device == dssdev;
++ dss_recheck_connections(dssdev, force);
++ }
++
++ r = dssdrv->probe(dssdev);
++
++ if (r) {
++ DSSERR("driver probe failed: %d\n", r);
++ return r;
++ }
++
++ DSSDBG("probe done for device %s\n", dev_name(dev));
++
++ dssdev->driver = dssdrv;
++
++ return 0;
++}
++
++static int dss_driver_remove(struct device *dev)
++{
++ struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
++ struct omap_dss_device *dssdev = to_dss_device(dev);
++
++ DSSDBG("driver_remove: dev %s/%s\n", dev_name(dev),
++ dssdev->driver_name);
++
++ dssdrv->remove(dssdev);
++
++ dss_uninit_device(core.pdev, dssdev);
++
++ dssdev->driver = NULL;
++
++ return 0;
++}
++
++int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
++{
++ dssdriver->driver.bus = &dss_bus_type;
++ dssdriver->driver.probe = dss_driver_probe;
++ dssdriver->driver.remove = dss_driver_remove;
++ return driver_register(&dssdriver->driver);
++}
++EXPORT_SYMBOL(omap_dss_register_driver);
++
++void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
++{
++ driver_unregister(&dssdriver->driver);
++}
++EXPORT_SYMBOL(omap_dss_unregister_driver);
++
++/* DEVICE */
++static void reset_device(struct device *dev, int check)
++{
++ u8 *dev_p = (u8 *)dev;
++ u8 *dev_end = dev_p + sizeof(*dev);
++ void *saved_pdata;
++
++ saved_pdata = dev->platform_data;
++ if (check) {
++ /*
++ * Check if there is any other setting than platform_data
++ * in struct device; warn that these will be reset by our
++ * init.
++ */
++ dev->platform_data = NULL;
++ while (dev_p < dev_end) {
++ if (*dev_p) {
++ WARN("%s: struct device fields will be discarded\n",
++ __func__);
++ break;
++ }
++ dev_p++;
++ }
++ }
++ memset(dev, 0, sizeof(*dev));
++ dev->platform_data = saved_pdata;
++}
++
++
++static void omap_dss_dev_release(struct device *dev)
++{
++ reset_device(dev, 0);
++}
++
++int omap_dss_register_device(struct omap_dss_device *dssdev)
++{
++ static int dev_num;
++ static int panel_num;
++ int r;
++
++ WARN_ON(!dssdev->driver_name);
++
++ reset_device(&dssdev->dev, 1);
++ dssdev->dev.bus = &dss_bus_type;
++ dssdev->dev.parent = &dss_bus;
++ dssdev->dev.release = omap_dss_dev_release;
++ dev_set_name(&dssdev->dev, "display%d", dev_num++);
++ r = device_register(&dssdev->dev);
++ if (r)
++ return r;
++
++ if (dssdev->ctrl.panel) {
++ struct omap_dss_device *panel = dssdev->ctrl.panel;
++
++ panel->panel.ctrl = dssdev;
++
++ reset_device(&panel->dev, 1);
++ panel->dev.bus = &dss_bus_type;
++ panel->dev.parent = &dssdev->dev;
++ panel->dev.release = omap_dss_dev_release;
++ dev_set_name(&panel->dev, "panel%d", panel_num++);
++ r = device_register(&panel->dev);
++ if (r)
++ return r;
++ }
++
++ return 0;
++}
++
++void omap_dss_unregister_device(struct omap_dss_device *dssdev)
++{
++ device_unregister(&dssdev->dev);
++
++ if (dssdev->ctrl.panel) {
++ struct omap_dss_device *panel = dssdev->ctrl.panel;
++ device_unregister(&panel->dev);
++ }
++}
++
++/* BUS */
++static int omap_dss_bus_register(void)
++{
++ int r;
++
++ r = bus_register(&dss_bus_type);
++ if (r) {
++ DSSERR("bus register failed\n");
++ return r;
++ }
++
++ dev_set_name(&dss_bus, "omapdss");
++ r = device_register(&dss_bus);
++ if (r) {
++ DSSERR("bus driver register failed\n");
++ bus_unregister(&dss_bus_type);
++ return r;
++ }
++
++ return 0;
++}
++
++/* INIT */
++
++#ifdef CONFIG_OMAP2_DSS_MODULE
++static void omap_dss_bus_unregister(void)
++{
++ device_unregister(&dss_bus);
++
++ bus_unregister(&dss_bus_type);
++}
++
+ static int __init omap_dss_init(void)
+ {
+- return platform_driver_register(&omap_dss_driver);
++ int r;
++
++ r = omap_dss_bus_register();
++ if (r)
++ return r;
++
++ r = platform_driver_register(&omap_dss_driver);
++ if (r) {
++ omap_dss_bus_unregister();
++ return r;
++ }
++
++ return 0;
+ }
+
+ static void __exit omap_dss_exit(void)
+ {
+ platform_driver_unregister(&omap_dss_driver);
++
++ omap_dss_bus_unregister();
+ }
+
+-subsys_initcall(omap_dss_init);
++module_init(omap_dss_init);
+ module_exit(omap_dss_exit);
++#else
++static int __init omap_dss_init(void)
++{
++ return omap_dss_bus_register();
++}
++
++static int __init omap_dss_init2(void)
++{
++ return platform_driver_register(&omap_dss_driver);
++}
+
++core_initcall(omap_dss_init);
++device_initcall(omap_dss_init2);
++#endif
+
+ MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
+ MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
+diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
+index e936c59..52170f8 100644
+--- a/drivers/video/omap2/dss/dispc.c
++++ b/drivers/video/omap2/dss/dispc.c
+@@ -2319,15 +2319,15 @@ static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc,
+ enable_clocks(0);
+ }
+
+-void dispc_set_pol_freq(struct omap_panel *panel)
++void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb)
+ {
+- _dispc_set_pol_freq((panel->config & OMAP_DSS_LCD_ONOFF) != 0,
+- (panel->config & OMAP_DSS_LCD_RF) != 0,
+- (panel->config & OMAP_DSS_LCD_IEO) != 0,
+- (panel->config & OMAP_DSS_LCD_IPC) != 0,
+- (panel->config & OMAP_DSS_LCD_IHS) != 0,
+- (panel->config & OMAP_DSS_LCD_IVS) != 0,
+- panel->acbi, panel->acb);
++ _dispc_set_pol_freq((config & OMAP_DSS_LCD_ONOFF) != 0,
++ (config & OMAP_DSS_LCD_RF) != 0,
++ (config & OMAP_DSS_LCD_IEO) != 0,
++ (config & OMAP_DSS_LCD_IPC) != 0,
++ (config & OMAP_DSS_LCD_IHS) != 0,
++ (config & OMAP_DSS_LCD_IVS) != 0,
++ acbi, acb);
+ }
+
+ void find_lck_pck_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
+@@ -2790,9 +2790,9 @@ static void dispc_error_worker(struct work_struct *work)
+
+ if (mgr->id == OMAP_DSS_CHANNEL_LCD) {
+ manager = mgr;
+- enable = mgr->display->state ==
++ enable = mgr->device->state ==
+ OMAP_DSS_DISPLAY_ACTIVE;
+- mgr->display->disable(mgr->display);
++ mgr->device->disable(mgr->device);
+ break;
+ }
+ }
+@@ -2812,7 +2812,7 @@ static void dispc_error_worker(struct work_struct *work)
+ dispc_go(manager->id);
+ mdelay(50);
+ if (enable)
+- manager->display->enable(manager->display);
++ manager->device->enable(manager->device);
+ }
+ }
+
+@@ -2828,9 +2828,9 @@ static void dispc_error_worker(struct work_struct *work)
+
+ if (mgr->id == OMAP_DSS_CHANNEL_DIGIT) {
+ manager = mgr;
+- enable = mgr->display->state ==
++ enable = mgr->device->state ==
+ OMAP_DSS_DISPLAY_ACTIVE;
+- mgr->display->disable(mgr->display);
++ mgr->device->disable(mgr->device);
+ break;
+ }
+ }
+@@ -2850,7 +2850,7 @@ static void dispc_error_worker(struct work_struct *work)
+ dispc_go(manager->id);
+ mdelay(50);
+ if (enable)
+- manager->display->enable(manager->display);
++ manager->device->enable(manager->device);
+ }
+ }
+
+@@ -2861,7 +2861,7 @@ static void dispc_error_worker(struct work_struct *work)
+ mgr = omap_dss_get_overlay_manager(i);
+
+ if (mgr->caps & OMAP_DSS_OVL_CAP_DISPC)
+- mgr->display->disable(mgr->display);
++ mgr->device->disable(mgr->device);
+ }
+ }
+
+@@ -3126,7 +3126,7 @@ static int dispc_is_overlay_scaled(struct omap_overlay_info *pi)
+ }
+
+ /* returns the area that needs updating */
+-void dispc_setup_partial_planes(struct omap_display *display,
++void dispc_setup_partial_planes(struct omap_dss_device *dssdev,
+ u16 *xi, u16 *yi, u16 *wi, u16 *hi)
+ {
+ struct omap_overlay_manager *mgr;
+@@ -3143,7 +3143,7 @@ void dispc_setup_partial_planes(struct omap_display *display,
+ *xi, *yi, *wi, *hi);
+
+
+- mgr = display->manager;
++ mgr = dssdev->manager;
+
+ if (!mgr) {
+ DSSDBG("no manager\n");
+@@ -3307,7 +3307,7 @@ void dispc_setup_partial_planes(struct omap_display *display,
+ pi->mirror,
+ pi->global_alpha);
+
+- if (dss_use_replication(display, ovl->info.color_mode))
++ if (dss_use_replication(dssdev, ovl->info.color_mode))
+ dispc_enable_replication(ovl->id, true);
+ else
+ dispc_enable_replication(ovl->id, false);
+diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
+index 77a6dc4..2251bff 100644
+--- a/drivers/video/omap2/dss/display.c
++++ b/drivers/video/omap2/dss/display.c
+@@ -31,52 +31,54 @@
+ #include <mach/display.h>
+ #include "dss.h"
+
+-static int num_displays;
+ static LIST_HEAD(display_list);
+
+-static ssize_t display_name_show(struct omap_display *display, char *buf)
++static ssize_t display_enabled_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
+- return snprintf(buf, PAGE_SIZE, "%s\n", display->name);
+-}
+-
+-static ssize_t display_enabled_show(struct omap_display *display, char *buf)
+-{
+- bool enabled = display->state != OMAP_DSS_DISPLAY_DISABLED;
++ struct omap_dss_device *dssdev = to_dss_device(dev);
++ bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
+ }
+
+-static ssize_t display_enabled_store(struct omap_display *display,
++static ssize_t display_enabled_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ bool enabled, r;
+
+ enabled = simple_strtoul(buf, NULL, 10);
+
+- if (enabled != (display->state != OMAP_DSS_DISPLAY_DISABLED)) {
++ if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) {
+ if (enabled) {
+- r = display->enable(display);
++ r = dssdev->enable(dssdev);
+ if (r)
+ return r;
+ } else {
+- display->disable(display);
++ dssdev->disable(dssdev);
+ }
+ }
+
+ return size;
+ }
+
+-static ssize_t display_upd_mode_show(struct omap_display *display, char *buf)
++static ssize_t display_upd_mode_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
+- if (display->get_update_mode)
+- mode = display->get_update_mode(display);
++ if (dssdev->get_update_mode)
++ mode = dssdev->get_update_mode(dssdev);
+ return snprintf(buf, PAGE_SIZE, "%d\n", mode);
+ }
+
+-static ssize_t display_upd_mode_store(struct omap_display *display,
++static ssize_t display_upd_mode_store(struct device *dev,
++ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int val, r;
+ enum omap_dss_update_mode mode;
+
+@@ -92,43 +94,48 @@ static ssize_t display_upd_mode_store(struct omap_display *display,
+ return -EINVAL;
+ }
+
+- if ((r = display->set_update_mode(display, mode)))
++ if ((r = dssdev->set_update_mode(dssdev, mode)))
+ return r;
+
+ return size;
+ }
+
+-static ssize_t display_tear_show(struct omap_display *display, char *buf)
++static ssize_t display_tear_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+- display->get_te ? display->get_te(display) : 0);
++ dssdev->get_te ? dssdev->get_te(dssdev) : 0);
+ }
+
+-static ssize_t display_tear_store(struct omap_display *display,
+- const char *buf, size_t size)
++static ssize_t display_tear_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned long te;
+ int r;
+
+- if (!display->enable_te || !display->get_te)
++ if (!dssdev->enable_te || !dssdev->get_te)
+ return -ENOENT;
+
+ te = simple_strtoul(buf, NULL, 0);
+
+- if ((r = display->enable_te(display, te)))
++ if ((r = dssdev->enable_te(dssdev, te)))
+ return r;
+
+ return size;
+ }
+
+-static ssize_t display_timings_show(struct omap_display *display, char *buf)
++static ssize_t display_timings_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_video_timings t;
+
+- if (!display->get_timings)
++ if (!dssdev->get_timings)
+ return -ENOENT;
+
+- display->get_timings(display, &t);
++ dssdev->get_timings(dssdev, &t);
+
+ return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
+ t.pixel_clock,
+@@ -136,13 +143,14 @@ static ssize_t display_timings_show(struct omap_display *display, char *buf)
+ t.y_res, t.vfp, t.vbp, t.vsw);
+ }
+
+-static ssize_t display_timings_store(struct omap_display *display,
+- const char *buf, size_t size)
++static ssize_t display_timings_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_video_timings t;
+ int r, found;
+
+- if (!display->set_timings || !display->check_timings)
++ if (!dssdev->set_timings || !dssdev->check_timings)
+ return -ENOENT;
+
+ found = 0;
+@@ -161,103 +169,94 @@ static ssize_t display_timings_store(struct omap_display *display,
+ &t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)
+ return -EINVAL;
+
+- if ((r = display->check_timings(display, &t)))
++ if ((r = dssdev->check_timings(dssdev, &t)))
+ return r;
+
+- display->set_timings(display, &t);
++ dssdev->set_timings(dssdev, &t);
+
+ return size;
+ }
+
+-static ssize_t display_rotate_show(struct omap_display *display, char *buf)
++static ssize_t display_rotate_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int rotate;
+- if (!display->get_rotate)
++ if (!dssdev->get_rotate)
+ return -ENOENT;
+- rotate = display->get_rotate(display);
++ rotate = dssdev->get_rotate(dssdev);
+ return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
+ }
+
+-static ssize_t display_rotate_store(struct omap_display *display,
+- const char *buf, size_t size)
++static ssize_t display_rotate_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned long rot;
+ int r;
+
+- if (!display->set_rotate || !display->get_rotate)
++ if (!dssdev->set_rotate || !dssdev->get_rotate)
+ return -ENOENT;
+
+ rot = simple_strtoul(buf, NULL, 0);
+
+- if ((r = display->set_rotate(display, rot)))
++ if ((r = dssdev->set_rotate(dssdev, rot)))
+ return r;
+
+ return size;
+ }
+
+-static ssize_t display_mirror_show(struct omap_display *display, char *buf)
++static ssize_t display_mirror_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ int mirror;
+- if (!display->get_mirror)
++ if (!dssdev->get_mirror)
+ return -ENOENT;
+- mirror = display->get_mirror(display);
++ mirror = dssdev->get_mirror(dssdev);
+ return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
+ }
+
+-static ssize_t display_mirror_store(struct omap_display *display,
+- const char *buf, size_t size)
++static ssize_t display_mirror_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned long mirror;
+ int r;
+
+- if (!display->set_mirror || !display->get_mirror)
++ if (!dssdev->set_mirror || !dssdev->get_mirror)
+ return -ENOENT;
+
+ mirror = simple_strtoul(buf, NULL, 0);
+
+- if ((r = display->set_mirror(display, mirror)))
++ if ((r = dssdev->set_mirror(dssdev, mirror)))
+ return r;
+
+ return size;
+ }
+
+-static ssize_t display_panel_name_show(struct omap_display *display, char *buf)
+-{
+- return snprintf(buf, PAGE_SIZE, "%s\n",
+- display->panel ? display->panel->name : "");
+-}
+-
+-static ssize_t display_ctrl_name_show(struct omap_display *display, char *buf)
+-{
+- return snprintf(buf, PAGE_SIZE, "%s\n",
+- display->ctrl ? display->ctrl->name : "");
+-}
+-
+-struct display_attribute {
+- struct attribute attr;
+- ssize_t (*show)(struct omap_display *, char *);
+- ssize_t (*store)(struct omap_display *, const char *, size_t);
+-};
+-
+-static ssize_t display_wss_show(struct omap_display *display, char *buf)
++static ssize_t display_wss_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned int wss;
+
+- if (!display->get_wss)
++ if (!dssdev->get_wss)
+ return -ENOENT;
+
+- wss = display->get_wss(display);
++ wss = dssdev->get_wss(dssdev);
+
+ return snprintf(buf, PAGE_SIZE, "0x%05x\n", wss);
+ }
+
+-static ssize_t display_wss_store(struct omap_display *display,
+- const char *buf, size_t size)
++static ssize_t display_wss_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
+ {
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+ unsigned long wss;
+ int r;
+
+- if (!display->get_wss || !display->set_wss)
++ if (!dssdev->get_wss || !dssdev->set_wss)
+ return -ENOENT;
+
+ if (strict_strtoul(buf, 0, &wss))
+@@ -266,92 +265,43 @@ static ssize_t display_wss_store(struct omap_display *display,
+ if (wss > 0xfffff)
+ return -EINVAL;
+
+- if ((r = display->set_wss(display, wss)))
++ if ((r = dssdev->set_wss(dssdev, wss)))
+ return r;
+
+ return size;
+ }
+
+-#define DISPLAY_ATTR(_name, _mode, _show, _store) \
+- struct display_attribute display_attr_##_name = \
+- __ATTR(_name, _mode, _show, _store)
+-
+-static DISPLAY_ATTR(name, S_IRUGO, display_name_show, NULL);
+-static DISPLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
++static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
+ display_enabled_show, display_enabled_store);
+-static DISPLAY_ATTR(update_mode, S_IRUGO|S_IWUSR,
++static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR,
+ display_upd_mode_show, display_upd_mode_store);
+-static DISPLAY_ATTR(tear_elim, S_IRUGO|S_IWUSR,
++static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
+ display_tear_show, display_tear_store);
+-static DISPLAY_ATTR(timings, S_IRUGO|S_IWUSR,
++static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
+ display_timings_show, display_timings_store);
+-static DISPLAY_ATTR(rotate, S_IRUGO|S_IWUSR,
++static DEVICE_ATTR(rotate, S_IRUGO|S_IWUSR,
+ display_rotate_show, display_rotate_store);
+-static DISPLAY_ATTR(mirror, S_IRUGO|S_IWUSR,
++static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
+ display_mirror_show, display_mirror_store);
+-static DISPLAY_ATTR(panel_name, S_IRUGO, display_panel_name_show, NULL);
+-static DISPLAY_ATTR(ctrl_name, S_IRUGO, display_ctrl_name_show, NULL);
+-static DISPLAY_ATTR(wss, S_IRUGO|S_IWUSR,
++static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
+ display_wss_show, display_wss_store);
+
+-static struct attribute *display_sysfs_attrs[] = {
+- &display_attr_name.attr,
+- &display_attr_enabled.attr,
+- &display_attr_update_mode.attr,
+- &display_attr_tear_elim.attr,
+- &display_attr_timings.attr,
+- &display_attr_rotate.attr,
+- &display_attr_mirror.attr,
+- &display_attr_panel_name.attr,
+- &display_attr_ctrl_name.attr,
+- &display_attr_wss.attr,
++static struct device_attribute *display_sysfs_attrs[] = {
++ &dev_attr_enabled,
++ &dev_attr_update_mode,
++ &dev_attr_tear_elim,
++ &dev_attr_timings,
++ &dev_attr_rotate,
++ &dev_attr_mirror,
++ &dev_attr_wss,
+ NULL
+ };
+
+-static ssize_t display_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
+-{
+- struct omap_display *display;
+- struct display_attribute *display_attr;
+-
+- display = container_of(kobj, struct omap_display, kobj);
+- display_attr = container_of(attr, struct display_attribute, attr);
+-
+- if (!display_attr->show)
+- return -ENOENT;
+-
+- return display_attr->show(display, buf);
+-}
+-
+-static ssize_t display_attr_store(struct kobject *kobj, struct attribute *attr,
+- const char *buf, size_t size)
+-{
+- struct omap_display *display;
+- struct display_attribute *display_attr;
+-
+- display = container_of(kobj, struct omap_display, kobj);
+- display_attr = container_of(attr, struct display_attribute, attr);
+-
+- if (!display_attr->store)
+- return -ENOENT;
+-
+- return display_attr->store(display, buf, size);
+-}
+-
+-static struct sysfs_ops display_sysfs_ops = {
+- .show = display_attr_show,
+- .store = display_attr_store,
+-};
+-
+-static struct kobj_type display_ktype = {
+- .sysfs_ops = &display_sysfs_ops,
+- .default_attrs = display_sysfs_attrs,
+-};
+-
+-static void default_get_resolution(struct omap_display *display,
++static void default_get_resolution(struct omap_dss_device *dssdev,
+ u16 *xres, u16 *yres)
+ {
+- *xres = display->panel->timings.x_res;
+- *yres = display->panel->timings.y_res;
++ *xres = dssdev->panel.timings.x_res;
++ *yres = dssdev->panel.timings.y_res;
+ }
+
+ static void default_configure_overlay(struct omap_overlay *ovl)
+@@ -371,12 +321,12 @@ static void default_configure_overlay(struct omap_overlay *ovl)
+ dispc_setup_plane_fifo(plane, low, high);
+ }
+
+-static int default_wait_vsync(struct omap_display *display)
++static int default_wait_vsync(struct omap_dss_device *dssdev)
+ {
+ unsigned long timeout = msecs_to_jiffies(500);
+ u32 irq;
+
+- if (display->type == OMAP_DISPLAY_TYPE_VENC)
++ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
+ irq = DISPC_IRQ_EVSYNC_ODD;
+ else
+ irq = DISPC_IRQ_VSYNC;
+@@ -384,21 +334,21 @@ static int default_wait_vsync(struct omap_display *display)
+ return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+ }
+
+-static int default_get_recommended_bpp(struct omap_display *display)
++static int default_get_recommended_bpp(struct omap_dss_device *dssdev)
+ {
+- if (display->panel->recommended_bpp)
+- return display->panel->recommended_bpp;
++ if (dssdev->panel.recommended_bpp)
++ return dssdev->panel.recommended_bpp;
+
+- switch (display->type) {
++ switch (dssdev->type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+- if (display->hw_config.u.dpi.data_lines == 24)
++ if (dssdev->phy.dpi.data_lines == 24)
+ return 24;
+ else
+ return 16;
+
+ case OMAP_DISPLAY_TYPE_DBI:
+ case OMAP_DISPLAY_TYPE_DSI:
+- if (display->ctrl->pixel_size == 24)
++ if (dssdev->ctrl.pixel_size == 24)
+ return 24;
+ else
+ return 16;
+@@ -414,7 +364,7 @@ static int default_get_recommended_bpp(struct omap_display *display)
+ /* Checks if replication logic should be used. Only use for active matrix,
+ * when overlay is in RGB12U or RGB16 mode, and LCD interface is
+ * 18bpp or 24bpp */
+-bool dss_use_replication(struct omap_display *display,
++bool dss_use_replication(struct omap_dss_device *dssdev,
+ enum omap_color_mode mode)
+ {
+ int bpp;
+@@ -422,13 +372,13 @@ bool dss_use_replication(struct omap_display *display,
+ if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16)
+ return false;
+
+- if (display->type == OMAP_DISPLAY_TYPE_DPI &&
+- (display->panel->config & OMAP_DSS_LCD_TFT) == 0)
++ if (dssdev->type == OMAP_DISPLAY_TYPE_DPI &&
++ (dssdev->panel.config & OMAP_DSS_LCD_TFT) == 0)
+ return false;
+
+- switch (display->type) {
++ switch (dssdev->type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+- bpp = display->hw_config.u.dpi.data_lines;
++ bpp = dssdev->phy.dpi.data_lines;
+ break;
+ case OMAP_DISPLAY_TYPE_VENC:
+ case OMAP_DISPLAY_TYPE_SDI:
+@@ -436,7 +386,7 @@ bool dss_use_replication(struct omap_display *display,
+ break;
+ case OMAP_DISPLAY_TYPE_DBI:
+ case OMAP_DISPLAY_TYPE_DSI:
+- bpp = display->ctrl->pixel_size;
++ bpp = dssdev->ctrl.pixel_size;
+ break;
+ default:
+ BUG();
+@@ -445,319 +395,259 @@ bool dss_use_replication(struct omap_display *display,
+ return bpp > 16;
+ }
+
+-void dss_init_displays(struct platform_device *pdev)
++void dss_init_device(struct platform_device *pdev,
++ struct omap_dss_device *dssdev)
+ {
+- struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+- int i, r;
+-
+- INIT_LIST_HEAD(&display_list);
+-
+- num_displays = 0;
+-
+- for (i = 0; i < pdata->num_displays; ++i) {
+- struct omap_display *display;
++ struct device_attribute *attr;
++ int i;
++ int r;
+
+- switch (pdata->displays[i]->type) {
+- case OMAP_DISPLAY_TYPE_DPI:
++ switch (dssdev->type) {
++ case OMAP_DISPLAY_TYPE_DPI:
+ #ifdef CONFIG_OMAP2_DSS_RFBI
+- case OMAP_DISPLAY_TYPE_DBI:
++ case OMAP_DISPLAY_TYPE_DBI:
+ #endif
+ #ifdef CONFIG_OMAP2_DSS_SDI
+- case OMAP_DISPLAY_TYPE_SDI:
++ case OMAP_DISPLAY_TYPE_SDI:
+ #endif
+ #ifdef CONFIG_OMAP2_DSS_DSI
+- case OMAP_DISPLAY_TYPE_DSI:
++ case OMAP_DISPLAY_TYPE_DSI:
+ #endif
+ #ifdef CONFIG_OMAP2_DSS_VENC
+- case OMAP_DISPLAY_TYPE_VENC:
++ case OMAP_DISPLAY_TYPE_VENC:
+ #endif
+- break;
+- default:
+- DSSERR("Support for display '%s' not compiled in.\n",
+- pdata->displays[i]->name);
+- continue;
+- }
+-
+- display = kzalloc(sizeof(*display), GFP_KERNEL);
+-
+- /*atomic_set(&display->ref_count, 0);*/
+- display->ref_count = 0;
+-
+- display->hw_config = *pdata->displays[i];
+- display->type = pdata->displays[i]->type;
+- display->name = pdata->displays[i]->name;
++ break;
++ default:
++ DSSERR("Support for display '%s' not compiled in.\n",
++ dssdev->name);
++ return;
++ }
+
+- display->get_resolution = default_get_resolution;
+- display->get_recommended_bpp = default_get_recommended_bpp;
+- display->configure_overlay = default_configure_overlay;
+- display->wait_vsync = default_wait_vsync;
++ dssdev->get_resolution = default_get_resolution;
++ dssdev->get_recommended_bpp = default_get_recommended_bpp;
++ dssdev->configure_overlay = default_configure_overlay;
++ dssdev->wait_vsync = default_wait_vsync;
+
+- switch (display->type) {
+- case OMAP_DISPLAY_TYPE_DPI:
+- dpi_init_display(display);
+- break;
++ switch (dssdev->type) {
++ case OMAP_DISPLAY_TYPE_DPI:
++ dpi_init_display(dssdev);
++ break;
+ #ifdef CONFIG_OMAP2_DSS_RFBI
+- case OMAP_DISPLAY_TYPE_DBI:
+- rfbi_init_display(display);
+- break;
++ case OMAP_DISPLAY_TYPE_DBI:
++ rfbi_init_display(dssdev);
++ break;
+ #endif
+ #ifdef CONFIG_OMAP2_DSS_VENC
+- case OMAP_DISPLAY_TYPE_VENC:
+- venc_init_display(display);
+- break;
++ case OMAP_DISPLAY_TYPE_VENC:
++ venc_init_display(dssdev);
++ break;
+ #endif
+ #ifdef CONFIG_OMAP2_DSS_SDI
+- case OMAP_DISPLAY_TYPE_SDI:
+- sdi_init_display(display);
+- break;
++ case OMAP_DISPLAY_TYPE_SDI:
++ sdi_init_display(dssdev);
++ break;
+ #endif
+ #ifdef CONFIG_OMAP2_DSS_DSI
+- case OMAP_DISPLAY_TYPE_DSI:
+- dsi_init_display(display);
+- break;
++ case OMAP_DISPLAY_TYPE_DSI:
++ dsi_init_display(dssdev);
++ break;
+ #endif
+- default:
+- BUG();
+- }
+-
+- r = kobject_init_and_add(&display->kobj, &display_ktype,
+- &pdev->dev.kobj, "display%d", num_displays);
++ default:
++ BUG();
++ }
+
+- if (r) {
++ /* create device sysfs files */
++ i = 0;
++ while ((attr = display_sysfs_attrs[i++]) != NULL) {
++ r = device_create_file(&dssdev->dev, attr);
++ if (r)
+ DSSERR("failed to create sysfs file\n");
+- continue;
+- }
+-
+- num_displays++;
+-
+- list_add_tail(&display->list, &display_list);
+ }
++
++ /* create display? sysfs links */
++ r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
++ dev_name(&dssdev->dev));
++ if (r)
++ DSSERR("failed to create sysfs display link\n");
+ }
+
+-void dss_uninit_displays(struct platform_device *pdev)
++void dss_uninit_device(struct platform_device *pdev,
++ struct omap_dss_device *dssdev)
+ {
+- struct omap_display *display;
+-
+- while (!list_empty(&display_list)) {
+- display = list_first_entry(&display_list,
+- struct omap_display, list);
+- list_del(&display->list);
+- kobject_del(&display->kobj);
+- kobject_put(&display->kobj);
+- kfree(display);
+- }
++ struct device_attribute *attr;
++ int i = 0;
++
++ sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
++
++ while ((attr = display_sysfs_attrs[i++]) != NULL)
++ device_remove_file(&dssdev->dev, attr);
+
+- num_displays = 0;
++ if (dssdev->manager)
++ dssdev->manager->unset_device(dssdev->manager);
+ }
+
+-int dss_suspend_all_displays(void)
++static int dss_suspend_device(struct device *dev, void *data)
+ {
+ int r;
+- struct omap_display *display;
+-
+- list_for_each_entry(display, &display_list, list) {
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE) {
+- display->activate_after_resume = 0;
+- continue;
+- }
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+
+- if (!display->suspend) {
+- DSSERR("display '%s' doesn't implement suspend\n",
+- display->name);
+- r = -ENOSYS;
+- goto err;
+- }
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
++ dssdev->activate_after_resume = false;
++ return 0;
++ }
+
+- r = display->suspend(display);
++ if (!dssdev->suspend) {
++ DSSERR("display '%s' doesn't implement suspend\n",
++ dssdev->name);
++ return -ENOSYS;
++ }
+
+- if (r)
+- goto err;
++ r = dssdev->suspend(dssdev);
++ if (r)
++ return r;
+
+- display->activate_after_resume = 1;
+- }
++ dssdev->activate_after_resume = true;
+
+ return 0;
+-err:
+- /* resume all displays that were suspended */
+- dss_resume_all_displays();
+- return r;
+ }
+
+-int dss_resume_all_displays(void)
++int dss_suspend_all_devices(void)
+ {
+ int r;
+- struct omap_display *display;
+-
+- list_for_each_entry(display, &display_list, list) {
+- if (display->activate_after_resume && display->resume) {
+- r = display->resume(display);
+- if (r)
+- return r;
+- }
++ struct bus_type *bus = dss_get_bus();
+
+- display->activate_after_resume = 0;
++ r = bus_for_each_dev(bus, NULL, NULL, dss_suspend_device);
++ if (r) {
++ /* resume all displays that were suspended */
++ dss_resume_all_devices();
++ return r;
+ }
+
+ return 0;
+ }
+
+-int omap_dss_get_num_displays(void)
+-{
+- return num_displays;
+-}
+-EXPORT_SYMBOL(omap_dss_get_num_displays);
+-
+-struct omap_display *dss_get_display(int no)
++static int dss_resume_device(struct device *dev, void *data)
+ {
+- int i = 0;
+- struct omap_display *display;
++ int r;
++ struct omap_dss_device *dssdev = to_dss_device(dev);
+
+- list_for_each_entry(display, &display_list, list) {
+- if (i++ == no)
+- return display;
++ if (dssdev->activate_after_resume && dssdev->resume) {
++ r = dssdev->resume(dssdev);
++ if (r)
++ return r;
+ }
+
+- return NULL;
++ dssdev->activate_after_resume = false;
++
++ return 0;
+ }
+
+-struct omap_display *omap_dss_get_display(int no)
++int dss_resume_all_devices(void)
+ {
+- struct omap_display *display;
++ struct bus_type *bus = dss_get_bus();
+
+- display = dss_get_display(no);
++ return bus_for_each_dev(bus, NULL, NULL, dss_resume_device);
++}
+
+- if (!display)
+- return NULL;
+
+- switch (display->type) {
+- case OMAP_DISPLAY_TYPE_VENC:
+- break;
++void omap_dss_get_device(struct omap_dss_device *dssdev)
++{
++ get_device(&dssdev->dev);
++}
++EXPORT_SYMBOL(omap_dss_get_device);
+
+- case OMAP_DISPLAY_TYPE_DPI:
+- case OMAP_DISPLAY_TYPE_SDI:
+- if (display->panel == NULL)
+- return NULL;
+- break;
++void omap_dss_put_device(struct omap_dss_device *dssdev)
++{
++ put_device(&dssdev->dev);
++}
++EXPORT_SYMBOL(omap_dss_put_device);
+
+- case OMAP_DISPLAY_TYPE_DBI:
+- case OMAP_DISPLAY_TYPE_DSI:
+- if (display->panel == NULL || display->ctrl == NULL)
+- return NULL;
+- break;
++/* ref count of the found device is incremented. ref count
++ * of from-device is decremented. */
++struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
++{
++ struct device *dev;
++ struct device *dev_start = NULL;
++ struct omap_dss_device *dssdev = NULL;
+
+- default:
+- return NULL;
++ int match(struct device *dev, void *data)
++ {
++ /* skip panels connected to controllers */
++ if (to_dss_device(dev)->panel.ctrl)
++ return 0;
++
++ return 1;
+ }
+
+- if (display->ctrl) {
+- if (!try_module_get(display->ctrl->owner))
+- goto err0;
++ if (from)
++ dev_start = &from->dev;
++ dev = bus_find_device(dss_get_bus(), dev_start, NULL, match);
++ if (dev)
++ dssdev = to_dss_device(dev);
++ if (from)
++ put_device(&from->dev);
+
+- if (display->ctrl->init)
+- if (display->ctrl->init(display) != 0)
+- goto err1;
+- }
++ return dssdev;
++}
++EXPORT_SYMBOL(omap_dss_get_next_device);
+
+- if (display->panel) {
+- if (!try_module_get(display->panel->owner))
+- goto err2;
++struct omap_dss_device *omap_dss_find_device(void *data,
++ int (*match)(struct omap_dss_device *dssdev, void *data))
++{
++ struct omap_dss_device *dssdev = NULL;
+
+- if (display->panel->init)
+- if (display->panel->init(display) != 0)
+- goto err3;
++ while ((dssdev = omap_dss_get_next_device(dssdev)) != NULL)
++ {
++ if (match(dssdev, data))
++ return dssdev;
+ }
+
+- display->ref_count++;
+- /*
+- if (atomic_cmpxchg(&display->ref_count, 0, 1) != 0)
+- return 0;
+-*/
+-
+- return display;
+-err3:
+- if (display->panel)
+- module_put(display->panel->owner);
+-err2:
+- if (display->ctrl && display->ctrl->cleanup)
+- display->ctrl->cleanup(display);
+-err1:
+- if (display->ctrl)
+- module_put(display->ctrl->owner);
+-err0:
+ return NULL;
+ }
+-EXPORT_SYMBOL(omap_dss_get_display);
++EXPORT_SYMBOL(omap_dss_find_device);
+
+-void omap_dss_put_display(struct omap_display *display)
++int omap_dss_start_device(struct omap_dss_device *dssdev)
+ {
+- if (--display->ref_count > 0)
+- return;
+-/*
+- if (atomic_cmpxchg(&display->ref_count, 1, 0) != 1)
+- return;
+-*/
+- if (display->ctrl) {
+- if (display->ctrl->cleanup)
+- display->ctrl->cleanup(display);
+- module_put(display->ctrl->owner);
+- }
++ int r;
+
+- if (display->panel) {
+- if (display->panel->cleanup)
+- display->panel->cleanup(display);
+- module_put(display->panel->owner);
++ if (!dssdev->driver) {
++ DSSDBG("no driver\n");
++ r = -ENODEV;
++ goto err0;
+ }
+-}
+-EXPORT_SYMBOL(omap_dss_put_display);
+-
+-void omap_dss_register_ctrl(struct omap_ctrl *ctrl)
+-{
+- struct omap_display *display;
+
+- list_for_each_entry(display, &display_list, list) {
+- if (display->hw_config.ctrl_name &&
+- strcmp(display->hw_config.ctrl_name, ctrl->name) == 0) {
+- display->ctrl = ctrl;
+- DSSDBG("ctrl '%s' registered\n", ctrl->name);
+- }
++ if (dssdev->ctrl.panel && !dssdev->ctrl.panel->driver) {
++ DSSDBG("no panel driver\n");
++ r = -ENODEV;
++ goto err0;
+ }
+-}
+-EXPORT_SYMBOL(omap_dss_register_ctrl);
+
+-void omap_dss_register_panel(struct omap_panel *panel)
+-{
+- struct omap_display *display;
++ if(!try_module_get(dssdev->dev.driver->owner)) {
++ r = -ENODEV;
++ goto err0;
++ }
+
+- list_for_each_entry(display, &display_list, list) {
+- if (display->hw_config.panel_name &&
+- strcmp(display->hw_config.panel_name, panel->name) == 0) {
+- display->panel = panel;
+- DSSDBG("panel '%s' registered\n", panel->name);
++ if (dssdev->ctrl.panel) {
++ if(!try_module_get(dssdev->ctrl.panel->dev.driver->owner)) {
++ r = -ENODEV;
++ goto err1;
+ }
+ }
+-}
+-EXPORT_SYMBOL(omap_dss_register_panel);
+
+-void omap_dss_unregister_ctrl(struct omap_ctrl *ctrl)
+-{
+- struct omap_display *display;
+-
+- list_for_each_entry(display, &display_list, list) {
+- if (display->hw_config.ctrl_name &&
+- strcmp(display->hw_config.ctrl_name, ctrl->name) == 0)
+- display->ctrl = NULL;
+- }
++ return 0;
++err1:
++ module_put(dssdev->dev.driver->owner);
++err0:
++ return r;
+ }
+-EXPORT_SYMBOL(omap_dss_unregister_ctrl);
++EXPORT_SYMBOL(omap_dss_start_device);
+
+-void omap_dss_unregister_panel(struct omap_panel *panel)
++void omap_dss_stop_device(struct omap_dss_device *dssdev)
+ {
+- struct omap_display *display;
++ if (dssdev->ctrl.panel)
++ module_put(dssdev->ctrl.panel->dev.driver->owner);
+
+- list_for_each_entry(display, &display_list, list) {
+- if (display->hw_config.panel_name &&
+- strcmp(display->hw_config.panel_name, panel->name) == 0)
+- display->panel = NULL;
+- }
++ module_put(dssdev->dev.driver->owner);
+ }
+-EXPORT_SYMBOL(omap_dss_unregister_panel);
++EXPORT_SYMBOL(omap_dss_stop_device);
++
+diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
+index 71fffca..f5867cf 100644
+--- a/drivers/video/omap2/dss/dpi.c
++++ b/drivers/video/omap2/dss/dpi.c
+@@ -20,6 +20,8 @@
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
++#define DSS_SUBSYS_NAME "DPI"
++
+ #include <linux/kernel.h>
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+@@ -83,9 +85,9 @@ static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
+ }
+ #endif
+
+-static int dpi_set_mode(struct omap_display *display)
++static int dpi_set_mode(struct omap_dss_device *dssdev)
+ {
+- struct omap_panel *panel = display->panel;
++ struct omap_video_timings *t = &dssdev->panel.timings;
+ int lck_div, pck_div;
+ unsigned long fck;
+ unsigned long pck;
+@@ -94,15 +96,16 @@ static int dpi_set_mode(struct omap_display *display)
+
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+- dispc_set_pol_freq(panel);
++ dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi,
++ dssdev->panel.acb);
+
+- is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0;
++ is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
+
+ #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+- r = dpi_set_dsi_clk(is_tft, panel->timings.pixel_clock * 1000,
++ r = dpi_set_dsi_clk(is_tft, t->pixel_clock * 1000,
+ &fck, &lck_div, &pck_div);
+ #else
+- r = dpi_set_dispc_clk(is_tft, panel->timings.pixel_clock * 1000,
++ r = dpi_set_dispc_clk(is_tft, t->pixel_clock * 1000,
+ &fck, &lck_div, &pck_div);
+ #endif
+ if (r)
+@@ -110,97 +113,106 @@ static int dpi_set_mode(struct omap_display *display)
+
+ pck = fck / lck_div / pck_div / 1000;
+
+- if (pck != panel->timings.pixel_clock) {
++ if (pck != t->pixel_clock) {
+ DSSWARN("Could not find exact pixel clock. "
+ "Requested %d kHz, got %lu kHz\n",
+- panel->timings.pixel_clock, pck);
++ t->pixel_clock, pck);
+
+- panel->timings.pixel_clock = pck;
++ t->pixel_clock = pck;
+ }
+
+- dispc_set_lcd_timings(&panel->timings);
++ dispc_set_lcd_timings(t);
+
+ err0:
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ return r;
+ }
+
+-static int dpi_basic_init(struct omap_display *display)
++static int dpi_basic_init(struct omap_dss_device *dssdev)
+ {
+ bool is_tft;
+
+- is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0;
++ is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
+
+ dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS);
+ dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT :
+ OMAP_DSS_LCD_DISPLAY_STN);
+- dispc_set_tft_data_lines(display->hw_config.u.dpi.data_lines);
++ dispc_set_tft_data_lines(dssdev->phy.dpi.data_lines);
+
+ return 0;
+ }
+
+-static int dpi_display_enable(struct omap_display *display)
++static int dpi_display_enable(struct omap_dss_device *dssdev)
+ {
+- struct omap_panel *panel = display->panel;
+ int r;
+
+- if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
++ r = omap_dss_start_device(dssdev);
++ if (r) {
++ DSSERR("failed to start device\n");
++ goto err0;
++ }
++
++ if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+ DSSERR("display already enabled\n");
+- return -EINVAL;
++ r = -EINVAL;
++ goto err1;
+ }
+
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+- r = dpi_basic_init(display);
++ r = dpi_basic_init(dssdev);
+ if (r)
+- goto err0;
++ goto err2;
+
+ #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+ dss_clk_enable(DSS_CLK_FCK2);
+ r = dsi_pll_init(0, 1);
+ if (r)
+- goto err1;
++ goto err3;
+ #endif
+- r = dpi_set_mode(display);
++ r = dpi_set_mode(dssdev);
+ if (r)
+- goto err2;
++ goto err4;
+
+ mdelay(2);
+
+ dispc_enable_lcd_out(1);
+
+- r = panel->enable(display);
++ r = dssdev->driver->enable(dssdev);
+ if (r)
+- goto err3;
++ goto err5;
+
+- display->state = OMAP_DSS_DISPLAY_ACTIVE;
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+
+-err3:
++err5:
+ dispc_enable_lcd_out(0);
+-err2:
++err4:
+ #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+ dsi_pll_uninit();
+-err1:
++err3:
+ dss_clk_disable(DSS_CLK_FCK2);
+ #endif
+-err0:
++err2:
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
++err1:
++ omap_dss_stop_device(dssdev);
++err0:
+ return r;
+ }
+
+-static int dpi_display_resume(struct omap_display *display);
++static int dpi_display_resume(struct omap_dss_device *dssdev);
+
+-static void dpi_display_disable(struct omap_display *display)
++static void dpi_display_disable(struct omap_dss_device *dssdev)
+ {
+- if (display->state == OMAP_DSS_DISPLAY_DISABLED)
++ if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+ return;
+
+- if (display->state == OMAP_DSS_DISPLAY_SUSPENDED)
+- dpi_display_resume(display);
++ if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
++ dpi_display_resume(dssdev);
+
+- display->panel->disable(display);
++ dssdev->driver->disable(dssdev);
+
+ dispc_enable_lcd_out(0);
+
+@@ -212,31 +224,33 @@ static void dpi_display_disable(struct omap_display *display)
+
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+- display->state = OMAP_DSS_DISPLAY_DISABLED;
++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
++
++ omap_dss_stop_device(dssdev);
+ }
+
+-static int dpi_display_suspend(struct omap_display *display)
++static int dpi_display_suspend(struct omap_dss_device *dssdev)
+ {
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return -EINVAL;
+
+ DSSDBG("dpi_display_suspend\n");
+
+- if (display->panel->suspend)
+- display->panel->suspend(display);
++ if (dssdev->driver->suspend)
++ dssdev->driver->suspend(dssdev);
+
+ dispc_enable_lcd_out(0);
+
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+- display->state = OMAP_DSS_DISPLAY_SUSPENDED;
++ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+ return 0;
+ }
+
+-static int dpi_display_resume(struct omap_display *display)
++static int dpi_display_resume(struct omap_dss_device *dssdev)
+ {
+- if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
++ if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
+ return -EINVAL;
+
+ DSSDBG("dpi_display_resume\n");
+@@ -245,26 +259,26 @@ static int dpi_display_resume(struct omap_display *display)
+
+ dispc_enable_lcd_out(1);
+
+- if (display->panel->resume)
+- display->panel->resume(display);
++ if (dssdev->driver->resume)
++ dssdev->driver->resume(dssdev);
+
+- display->state = OMAP_DSS_DISPLAY_ACTIVE;
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+ }
+
+-static void dpi_set_timings(struct omap_display *display,
++static void dpi_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+ {
+ DSSDBG("dpi_set_timings\n");
+- display->panel->timings = *timings;
+- if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
+- dpi_set_mode(display);
++ dssdev->panel.timings = *timings;
++ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
++ dpi_set_mode(dssdev);
+ dispc_go(OMAP_DSS_CHANNEL_LCD);
+ }
+ }
+
+-static int dpi_check_timings(struct omap_display *display,
++static int dpi_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+ {
+ bool is_tft;
+@@ -300,7 +314,7 @@ static int dpi_check_timings(struct omap_display *display,
+ if (timings->pixel_clock == 0)
+ return -EINVAL;
+
+- is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0;
++ is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
+
+ #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
+ {
+@@ -337,13 +351,13 @@ static int dpi_check_timings(struct omap_display *display,
+ return 0;
+ }
+
+-static void dpi_get_timings(struct omap_display *display,
++static void dpi_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+ {
+- *timings = display->panel->timings;
++ *timings = dssdev->panel.timings;
+ }
+
+-static int dpi_display_set_update_mode(struct omap_display *display,
++static int dpi_display_set_update_mode(struct omap_dss_device *dssdev,
+ enum omap_dss_update_mode mode)
+ {
+ if (mode == OMAP_DSS_UPDATE_MANUAL)
+@@ -361,25 +375,25 @@ static int dpi_display_set_update_mode(struct omap_display *display,
+ }
+
+ static enum omap_dss_update_mode dpi_display_get_update_mode(
+- struct omap_display *display)
++ struct omap_dss_device *dssdev)
+ {
+ return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
+ OMAP_DSS_UPDATE_DISABLED;
+ }
+
+-void dpi_init_display(struct omap_display *display)
++void dpi_init_display(struct omap_dss_device *dssdev)
+ {
+- DSSDBG("DPI init_display\n");
+-
+- display->enable = dpi_display_enable;
+- display->disable = dpi_display_disable;
+- display->suspend = dpi_display_suspend;
+- display->resume = dpi_display_resume;
+- display->set_timings = dpi_set_timings;
+- display->check_timings = dpi_check_timings;
+- display->get_timings = dpi_get_timings;
+- display->set_update_mode = dpi_display_set_update_mode;
+- display->get_update_mode = dpi_display_get_update_mode;
++ DSSDBG("init_display\n");
++
++ dssdev->enable = dpi_display_enable;
++ dssdev->disable = dpi_display_disable;
++ dssdev->suspend = dpi_display_suspend;
++ dssdev->resume = dpi_display_resume;
++ dssdev->set_timings = dpi_set_timings;
++ dssdev->check_timings = dpi_check_timings;
++ dssdev->get_timings = dpi_get_timings;
++ dssdev->set_update_mode = dpi_display_set_update_mode;
++ dssdev->get_update_mode = dpi_display_get_update_mode;
+ }
+
+ int dpi_init(void)
+diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
+index a06fb75..fb2f7f0 100644
+--- a/drivers/video/omap2/dss/dsi.c
++++ b/drivers/video/omap2/dss/dsi.c
+@@ -30,6 +30,7 @@
+ #include <linux/mutex.h>
+ #include <linux/seq_file.h>
+ #include <linux/kfifo.h>
++#include <linux/platform_device.h>
+
+ #include <mach/board.h>
+ #include <mach/display.h>
+@@ -230,7 +231,7 @@ enum dsi_cmd {
+ };
+
+ struct dsi_cmd_item {
+- struct omap_display *display;
++ struct omap_dss_device *dssdev;
+
+ enum dsi_cmd cmd;
+
+@@ -256,7 +257,7 @@ static struct
+ unsigned long ddr_clk; /* Hz */
+
+ struct {
+- struct omap_display *display;
++ struct omap_dss_device *dssdev;
+ enum fifo_size fifo_size;
+ int dest_per; /* destination peripheral 0-3 */
+ } vc[4];
+@@ -317,9 +318,9 @@ module_param_named(dsi_perf, dsi_perf, bool, 0644);
+ #endif
+
+ static void dsi_process_cmd_fifo(struct work_struct *work);
+-static void dsi_push_update(struct omap_display *display,
++static void dsi_push_update(struct omap_dss_device *dssdev,
+ int x, int y, int w, int h);
+-static void dsi_push_autoupdate(struct omap_display *display);
++static void dsi_push_autoupdate(struct omap_dss_device *dssdev);
+
+ static inline void dsi_write_reg(const struct dsi_reg idx, u32 val)
+ {
+@@ -777,7 +778,7 @@ static unsigned long dsi_fclk_rate(void)
+ return r;
+ }
+
+-static int dsi_set_lp_clk_divisor(struct omap_display *display)
++static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
+ {
+ unsigned n;
+ unsigned long dsi_fclk;
+@@ -785,7 +786,7 @@ static int dsi_set_lp_clk_divisor(struct omap_display *display)
+
+ dsi_fclk = dsi_fclk_rate();
+
+- lp_clk_req = display->hw_config.u.dsi.lp_clk_hz;
++ lp_clk_req = dssdev->phy.dsi.lp_clk_hz;
+
+ for (n = 1; n < (1 << 13) - 1; ++n) {
+ lp_clk = dsi_fclk / 2 / n;
+@@ -1376,16 +1377,16 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state)
+ return 0;
+ }
+
+-static void dsi_complexio_config(struct omap_display *display)
++static void dsi_complexio_config(struct omap_dss_device *dssdev)
+ {
+ u32 r;
+
+- int clk_lane = display->hw_config.u.dsi.clk_lane;
+- int data1_lane = display->hw_config.u.dsi.data1_lane;
+- int data2_lane = display->hw_config.u.dsi.data2_lane;
+- int clk_pol = display->hw_config.u.dsi.clk_pol;
+- int data1_pol = display->hw_config.u.dsi.data1_pol;
+- int data2_pol = display->hw_config.u.dsi.data2_pol;
++ int clk_lane = dssdev->phy.dsi.clk_lane;
++ int data1_lane = dssdev->phy.dsi.data1_lane;
++ int data2_lane = dssdev->phy.dsi.data2_lane;
++ int clk_pol = dssdev->phy.dsi.clk_pol;
++ int data1_pol = dssdev->phy.dsi.data1_pol;
++ int data2_pol = dssdev->phy.dsi.data2_pol;
+
+ r = dsi_read_reg(DSI_COMPLEXIO_CFG1);
+ r = FLD_MOD(r, clk_lane, 2, 0);
+@@ -1497,7 +1498,7 @@ static void dsi_complexio_timings(void)
+ }
+
+
+-static int dsi_complexio_init(struct omap_display *display)
++static int dsi_complexio_init(struct omap_dss_device *dssdev)
+ {
+ int r = 0;
+
+@@ -1517,7 +1518,7 @@ static int dsi_complexio_init(struct omap_display *display)
+ goto err;
+ }
+
+- dsi_complexio_config(display);
++ dsi_complexio_config(dssdev);
+
+ r = dsi_complexio_power(DSI_COMPLEXIO_POWER_ON);
+
+@@ -2283,7 +2284,7 @@ static int dsi_set_hs_tx_timeout(int ns, int x4, int x16)
+
+ return 0;
+ }
+-static int dsi_proto_config(struct omap_display *display)
++static int dsi_proto_config(struct omap_dss_device *dssdev)
+ {
+ u32 r;
+ int buswidth = 0;
+@@ -2310,7 +2311,7 @@ static int dsi_proto_config(struct omap_display *display)
+ /* 10000ns * 4 */
+ dsi_set_hs_tx_timeout(10000, 1, 0);
+
+- switch (display->ctrl->pixel_size) {
++ switch (dssdev->ctrl.pixel_size) {
+ case 16:
+ buswidth = 0;
+ break;
+@@ -2355,7 +2356,7 @@ static int dsi_proto_config(struct omap_display *display)
+ return 0;
+ }
+
+-static void dsi_proto_timings(struct omap_display *display)
++static void dsi_proto_timings(struct omap_dss_device *dssdev)
+ {
+ unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
+ unsigned tclk_pre, tclk_post;
+@@ -2387,8 +2388,8 @@ static void dsi_proto_timings(struct omap_display *display)
+ tclk_post = ns2ddr(60) + 26;
+
+ /* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */
+- if (display->hw_config.u.dsi.data1_lane != 0 &&
+- display->hw_config.u.dsi.data2_lane != 0)
++ if (dssdev->phy.dsi.data1_lane != 0 &&
++ dssdev->phy.dsi.data2_lane != 0)
+ ths_eot = 2;
+ else
+ ths_eot = 4;
+@@ -2412,6 +2413,7 @@ static void dsi_proto_timings(struct omap_display *display)
+ enter_hs_mode_lat = 1 + DIV_ROUND_UP(tlpx, 4) +
+ DIV_ROUND_UP(ths_prepare, 4) +
+ DIV_ROUND_UP(ths_zero + 3, 4);
++
+ exit_hs_mode_lat = DIV_ROUND_UP(ths_trail + ths_exit, 4) + 1 + ths_eot;
+
+ r = FLD_VAL(enter_hs_mode_lat, 31, 16) |
+@@ -2441,7 +2443,7 @@ static void dsi_proto_timings(struct omap_display *display)
+ DSI_FLUSH(ch); \
+ } while (0)
+
+-static int dsi_update_screen_l4(struct omap_display *display,
++static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
+ int x, int y, int w, int h)
+ {
+ /* Note: supports only 24bit colors in 32bit container */
+@@ -2464,12 +2466,12 @@ static int dsi_update_screen_l4(struct omap_display *display,
+ DSSDBG("dsi_update_screen_l4 (%d,%d %dx%d)\n",
+ x, y, w, h);
+
+- ovl = display->manager->overlays[0];
++ ovl = dssdev->manager->overlays[0];
+
+ if (ovl->info.color_mode != OMAP_DSS_COLOR_RGB24U)
+ return -EINVAL;
+
+- if (display->ctrl->pixel_size != 24)
++ if (dssdev->ctrl.pixel_size != 24)
+ return -EINVAL;
+
+ scr_width = ovl->info.screen_width;
+@@ -2497,7 +2499,7 @@ static int dsi_update_screen_l4(struct omap_display *display,
+
+ dsi_bus_lock();
+
+- display->ctrl->setup_update(display, x, y, w, h);
++ dssdev->driver->setup_update(dssdev, x, y, w, h);
+
+ pixels_left = w * h;
+
+@@ -2595,101 +2597,7 @@ static int dsi_update_screen_l4(struct omap_display *display,
+ return 0;
+ }
+
+-#if 0
+-static void dsi_clear_screen_l4(struct omap_display *display,
+- int x, int y, int w, int h)
+-{
+- int first = 1;
+- int fifo_stalls = 0;
+- int max_dsi_packet_size;
+- int max_data_per_packet;
+- int max_pixels_per_packet;
+- int pixels_left;
+- int bytespp = 3;
+- int pixnum;
+-
+- debug_irq = 0;
+-
+- DSSDBG("dsi_clear_screen_l4 (%d,%d %dx%d)\n",
+- x, y, w, h);
+-
+- if (display->ctrl->bpp != 24)
+- return -EINVAL;
+-
+- /* We need header(4) + DCSCMD(1) + pixels(numpix*bytespp)
+- * bytes in fifo */
+-
+- /* When using CPU, max long packet size is TX buffer size */
+- max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4;
+-
+- max_data_per_packet = max_dsi_packet_size - 4 - 1;
+-
+- max_pixels_per_packet = max_data_per_packet / bytespp;
+-
+- enable_clocks(1);
+-
+- display->ctrl->setup_update(display, x, y, w, h);
+-
+- pixels_left = w * h;
+-
+- dsi.update_region.x = x;
+- dsi.update_region.y = y;
+- dsi.update_region.w = w;
+- dsi.update_region.h = h;
+- dsi.update_region.bytespp = bytespp;
+-
+- start_measuring();
+-
+- pixnum = 0;
+-
+- while (pixels_left > 0) {
+- /* 0x2c = write_memory_start */
+- /* 0x3c = write_memory_continue */
+- u8 dcs_cmd = first ? 0x2c : 0x3c;
+- int pixels;
+- DSI_DECL_VARS;
+- first = 0;
+-
+- /* TX_FIFO_NOT_EMPTY */
+- while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) {
+- fifo_stalls++;
+- if (fifo_stalls > 0xfffff) {
+- DSSERR("fifo stalls overflow\n");
+- dsi_if_enable(0);
+- enable_clocks(0);
+- return;
+- }
+- }
+-
+- pixels = min(max_pixels_per_packet, pixels_left);
+-
+- pixels_left -= pixels;
+-
+- dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE,
+- 1 + pixels * bytespp, 0);
+-
+- DSI_PUSH(0, dcs_cmd);
+-
+- while (pixels-- > 0) {
+- u32 pix;
+-
+- pix = 0x000000;
+-
+- DSI_PUSH(0, (pix >> 16) & 0xff);
+- DSI_PUSH(0, (pix >> 8) & 0xff);
+- DSI_PUSH(0, (pix >> 0) & 0xff);
+- }
+-
+- DSI_FLUSH(0);
+- }
+-
+- enable_clocks(0);
+-
+- end_measuring("L4 CLEAR");
+-}
+-#endif
+-
+-static void dsi_setup_update_dispc(struct omap_display *display,
++static void dsi_setup_update_dispc(struct omap_dss_device *dssdev,
+ u16 x, u16 y, u16 w, u16 h)
+ {
+ DSSDBG("dsi_setup_update_dispc(%d,%d %dx%d)\n",
+@@ -2703,16 +2611,16 @@ static void dsi_setup_update_dispc(struct omap_display *display,
+ dsi.update_region.bytespp = 3; // XXX
+ #endif
+
+- dispc_setup_partial_planes(display, &x, &y, &w, &h);
++ dispc_setup_partial_planes(dssdev, &x, &y, &w, &h);
+
+ dispc_set_lcd_size(w, h);
+ }
+
+-static void dsi_setup_autoupdate_dispc(struct omap_display *display)
++static void dsi_setup_autoupdate_dispc(struct omap_dss_device *dssdev)
+ {
+ u16 w, h;
+
+- display->get_resolution(display, &w, &h);
++ dssdev->get_resolution(dssdev, &w, &h);
+
+ #ifdef DEBUG
+ dsi.update_region.x = 0;
+@@ -2724,14 +2632,14 @@ static void dsi_setup_autoupdate_dispc(struct omap_display *display)
+
+ /* the overlay settings may not have been applied, if we were in manual
+ * mode earlier, so do it here */
+- display->manager->apply(display->manager);
++ dssdev->manager->apply(dssdev->manager);
+
+ dispc_set_lcd_size(w, h);
+
+ dsi.autoupdate_setup = 0;
+ }
+
+-static void dsi_update_screen_dispc(struct omap_display *display,
++static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
+ u16 x, u16 y, u16 w, u16 h)
+ {
+ int bytespp = 3;
+@@ -2760,10 +2668,10 @@ static void dsi_update_screen_dispc(struct omap_display *display,
+
+ dsi_bus_lock();
+
+- display->ctrl->setup_update(display, x, y, w, h);
++ dssdev->driver->setup_update(dssdev, x, y, w, h);
+
+- if (dsi.use_ext_te && display->ctrl->wait_for_te)
+- display->ctrl->wait_for_te(display);
++ if (dsi.use_ext_te && dssdev->wait_for_te)
++ dssdev->wait_for_te(dssdev);
+
+ if (0)
+ dsi_vc_print_status(1);
+@@ -2811,7 +2719,7 @@ static void framedone_timeout_callback(struct work_struct *work)
+ /* We check for target_update_mode, not update_mode. No reason to push
+ * new updates if we're turning auto update off */
+ if (dsi.target_update_mode == OMAP_DSS_UPDATE_AUTO)
+- dsi_push_autoupdate(dsi.vc[1].display);
++ dsi_push_autoupdate(dsi.vc[1].dssdev);
+
+ atomic_set(&dsi.cmd_pending, 0);
+ dsi_process_cmd_fifo(NULL);
+@@ -2895,19 +2803,19 @@ static void framedone_worker(struct work_struct *work)
+ /* We check for target_update_mode, not update_mode. No reason to push
+ * new updates if we're turning auto update off */
+ if (dsi.target_update_mode == OMAP_DSS_UPDATE_AUTO)
+- dsi_push_autoupdate(dsi.vc[1].display);
++ dsi_push_autoupdate(dsi.vc[1].dssdev);
+
+ atomic_set(&dsi.cmd_pending, 0);
+ dsi_process_cmd_fifo(NULL);
+ }
+
+-static void dsi_start_auto_update(struct omap_display *display)
++static void dsi_start_auto_update(struct omap_dss_device *dssdev)
+ {
+ DSSDBG("starting auto update\n");
+
+ dsi.autoupdate_setup = 1;
+
+- dsi_push_autoupdate(display);
++ dsi_push_autoupdate(dssdev);
+
+ perf_mark_start_auto();
+ }
+@@ -2936,7 +2844,7 @@ static void dsi_signal_fifo_waiters(void)
+ }
+
+ /* returns 1 for async op, and 0 for sync op */
+-static int dsi_do_update(struct omap_display *display,
++static int dsi_do_update(struct omap_dss_device *dssdev,
+ struct dsi_cmd_update *upd)
+ {
+ int r;
+@@ -2946,10 +2854,10 @@ static int dsi_do_update(struct omap_display *display,
+ if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
+ return 0;
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+- display->get_resolution(display, &dw, &dh);
++ dssdev->get_resolution(dssdev, &dw, &dh);
+ if (x > dw || y > dh)
+ return 0;
+
+@@ -2963,12 +2871,12 @@ static int dsi_do_update(struct omap_display *display,
+
+ perf_mark_setup();
+
+- if (display->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+- dsi_setup_update_dispc(display, x, y, w, h);
+- dsi_update_screen_dispc(display, x, y, w, h);
++ if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
++ dsi_setup_update_dispc(dssdev, x, y, w, h);
++ dsi_update_screen_dispc(dssdev, x, y, w, h);
+ return 1;
+ } else {
+- r = dsi_update_screen_l4(display, x, y, w, h);
++ r = dsi_update_screen_l4(dssdev, x, y, w, h);
+ if (r)
+ DSSERR("L4 update failed\n");
+ return 0;
+@@ -2976,7 +2884,7 @@ static int dsi_do_update(struct omap_display *display,
+ }
+
+ /* returns 1 for async op, and 0 for sync op */
+-static int dsi_do_autoupdate(struct omap_display *display)
++static int dsi_do_autoupdate(struct omap_dss_device *dssdev)
+ {
+ int r;
+ u16 w, h;
+@@ -2984,34 +2892,34 @@ static int dsi_do_autoupdate(struct omap_display *display)
+ if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
+ return 0;
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+- display->get_resolution(display, &w, &h);
++ dssdev->get_resolution(dssdev, &w, &h);
+
+ perf_mark_setup();
+
+- if (display->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
++ if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+ if (dsi.autoupdate_setup)
+- dsi_setup_autoupdate_dispc(display);
+- dsi_update_screen_dispc(display, 0, 0, w, h);
++ dsi_setup_autoupdate_dispc(dssdev);
++ dsi_update_screen_dispc(dssdev, 0, 0, w, h);
+ return 1;
+ } else {
+- r = dsi_update_screen_l4(display, 0, 0, w, h);
++ r = dsi_update_screen_l4(dssdev, 0, 0, w, h);
+ if (r)
+ DSSERR("L4 update failed\n");
+ return 0;
+ }
+ }
+
+-static void dsi_do_cmd_mem_read(struct omap_display *display,
++static void dsi_do_cmd_mem_read(struct omap_dss_device *dssdev,
+ struct dsi_cmd_mem_read *mem_read)
+ {
+ int r;
+
+ dsi_bus_lock();
+
+- r = display->ctrl->memory_read(display,
++ r = dssdev->driver->memory_read(dssdev,
+ mem_read->buf,
+ mem_read->size,
+ mem_read->x,
+@@ -3025,14 +2933,14 @@ static void dsi_do_cmd_mem_read(struct omap_display *display,
+ complete(mem_read->completion);
+ }
+
+-static void dsi_do_cmd_test(struct omap_display *display,
++static void dsi_do_cmd_test(struct omap_dss_device *dssdev,
+ struct dsi_cmd_test *test)
+ {
+ int r = 0;
+
+ DSSDBGF("");
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return;
+
+ dsi_bus_lock();
+@@ -3040,14 +2948,8 @@ static void dsi_do_cmd_test(struct omap_display *display,
+ /* run test first in low speed mode */
+ dsi_vc_enable_hs(0, 0);
+
+- if (display->ctrl->run_test) {
+- r = display->ctrl->run_test(display, test->test_num);
+- if (r)
+- goto end;
+- }
+-
+- if (display->panel->run_test) {
+- r = display->panel->run_test(display, test->test_num);
++ if (dssdev->driver->run_test) {
++ r = dssdev->driver->run_test(dssdev, test->test_num);
+ if (r)
+ goto end;
+ }
+@@ -3055,15 +2957,12 @@ static void dsi_do_cmd_test(struct omap_display *display,
+ /* then in high speed */
+ dsi_vc_enable_hs(0, 1);
+
+- if (display->ctrl->run_test) {
+- r = display->ctrl->run_test(display, test->test_num);
++ if (dssdev->driver->run_test) {
++ r = dssdev->driver->run_test(dssdev, test->test_num);
+ if (r)
+ goto end;
+ }
+
+- if (display->panel->run_test)
+- r = display->panel->run_test(display, test->test_num);
+-
+ end:
+ dsi_vc_enable_hs(0, 1);
+
+@@ -3075,21 +2974,21 @@ end:
+ DSSDBG("test end\n");
+ }
+
+-static void dsi_do_cmd_set_te(struct omap_display *display, bool enable)
++static void dsi_do_cmd_set_te(struct omap_dss_device *dssdev, bool enable)
+ {
+- if (!display->hw_config.u.dsi.ext_te)
++ if (!dssdev->phy.dsi.ext_te)
+ dsi.use_te = enable;
+ else
+ dsi.use_ext_te = enable;
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return;
+
+ dsi_bus_lock();
+- display->ctrl->enable_te(display, enable);
++ dssdev->driver->enable_te(dssdev, enable);
+ dsi_bus_unlock();
+
+- if (!display->hw_config.u.dsi.ext_te) {
++ if (!dssdev->phy.dsi.ext_te) {
+ if (enable) {
+ /* disable LP_RX_TO, so that we can receive TE.
+ * Time to wait for TE is longer than the timer allows */
+@@ -3100,16 +2999,16 @@ static void dsi_do_cmd_set_te(struct omap_display *display, bool enable)
+ }
+ }
+
+-static void dsi_do_cmd_set_update_mode(struct omap_display *display,
++static void dsi_do_cmd_set_update_mode(struct omap_dss_device *dssdev,
+ enum omap_dss_update_mode mode)
+ {
+ dsi.update_mode = mode;
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return;
+
+ if (mode == OMAP_DSS_UPDATE_AUTO)
+- dsi_start_auto_update(display);
++ dsi_start_auto_update(dssdev);
+ }
+
+ static void dsi_process_cmd_fifo(struct work_struct *work)
+@@ -3117,7 +3016,7 @@ static void dsi_process_cmd_fifo(struct work_struct *work)
+ int len;
+ struct dsi_cmd_item p;
+ unsigned long flags;
+- struct omap_display *display;
++ struct omap_dss_device *dssdev;
+ int exit = 0;
+
+ if (dsi.debug_process)
+@@ -3146,14 +3045,14 @@ static void dsi_process_cmd_fifo(struct work_struct *work)
+
+ BUG_ON(len != sizeof(p));
+
+- display = p.display;
++ dssdev = p.dssdev;
+
+ if (dsi.debug_process)
+ DSSDBG("processing cmd %d\n", p.cmd);
+
+ switch (p.cmd) {
+ case DSI_CMD_UPDATE:
+- if (dsi_do_update(display, &p.u.r)) {
++ if (dsi_do_update(dssdev, &p.u.r)) {
+ if (dsi.debug_process)
+ DSSDBG("async update\n");
+ exit = 1;
+@@ -3164,7 +3063,7 @@ static void dsi_process_cmd_fifo(struct work_struct *work)
+ break;
+
+ case DSI_CMD_AUTOUPDATE:
+- if (dsi_do_autoupdate(display)) {
++ if (dsi_do_autoupdate(dssdev)) {
+ if (dsi.debug_process)
+ DSSDBG("async autoupdate\n");
+ exit = 1;
+@@ -3181,24 +3080,24 @@ static void dsi_process_cmd_fifo(struct work_struct *work)
+ break;
+
+ case DSI_CMD_MEM_READ:
+- dsi_do_cmd_mem_read(display, &p.u.mem_read);
++ dsi_do_cmd_mem_read(dssdev, &p.u.mem_read);
+ break;
+
+ case DSI_CMD_TEST:
+- dsi_do_cmd_test(display, &p.u.test);
++ dsi_do_cmd_test(dssdev, &p.u.test);
+ break;
+
+ case DSI_CMD_SET_TE:
+- dsi_do_cmd_set_te(display, p.u.te);
++ dsi_do_cmd_set_te(dssdev, p.u.te);
+ break;
+
+ case DSI_CMD_SET_UPDATE_MODE:
+- dsi_do_cmd_set_update_mode(display, p.u.update_mode);
++ dsi_do_cmd_set_update_mode(dssdev, p.u.update_mode);
+ break;
+
+ case DSI_CMD_SET_ROTATE:
+ dsi_bus_lock();
+- display->ctrl->set_rotate(display, p.u.rotate);
++ dssdev->driver->set_rotate(dssdev, p.u.rotate);
+ if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO)
+ dsi.autoupdate_setup = 1;
+ dsi_bus_unlock();
+@@ -3206,7 +3105,7 @@ static void dsi_process_cmd_fifo(struct work_struct *work)
+
+ case DSI_CMD_SET_MIRROR:
+ dsi_bus_lock();
+- display->ctrl->set_mirror(display, p.u.mirror);
++ dssdev->driver->set_mirror(dssdev, p.u.mirror);
+ dsi_bus_unlock();
+ break;
+
+@@ -3263,12 +3162,12 @@ static void dsi_push_cmd(struct dsi_cmd_item *p)
+ queue_work(dsi.workqueue, &dsi.process_work);
+ }
+
+-static void dsi_push_update(struct omap_display *display,
++static void dsi_push_update(struct omap_dss_device *dssdev,
+ int x, int y, int w, int h)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_UPDATE;
+
+ p.u.r.x = x;
+@@ -3281,22 +3180,22 @@ static void dsi_push_update(struct omap_display *display,
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_autoupdate(struct omap_display *display)
++static void dsi_push_autoupdate(struct omap_dss_device *dssdev)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_AUTOUPDATE;
+
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_sync(struct omap_display *display,
++static void dsi_push_sync(struct omap_dss_device *dssdev,
+ struct completion *sync_comp)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_SYNC;
+ p.u.sync = sync_comp;
+
+@@ -3305,12 +3204,12 @@ static void dsi_push_sync(struct omap_display *display,
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_mem_read(struct omap_display *display,
++static void dsi_push_mem_read(struct omap_dss_device *dssdev,
+ struct dsi_cmd_mem_read *mem_read)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_MEM_READ;
+ p.u.mem_read = *mem_read;
+
+@@ -3319,12 +3218,12 @@ static void dsi_push_mem_read(struct omap_display *display,
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_test(struct omap_display *display, int test_num,
++static void dsi_push_test(struct omap_dss_device *dssdev, int test_num,
+ int *result, struct completion *completion)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_TEST;
+ p.u.test.test_num = test_num;
+ p.u.test.result = result;
+@@ -3335,11 +3234,11 @@ static void dsi_push_test(struct omap_display *display, int test_num,
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_set_te(struct omap_display *display, bool enable)
++static void dsi_push_set_te(struct omap_dss_device *dssdev, bool enable)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_SET_TE;
+ p.u.te = enable;
+
+@@ -3348,12 +3247,12 @@ static void dsi_push_set_te(struct omap_display *display, bool enable)
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_set_update_mode(struct omap_display *display,
++static void dsi_push_set_update_mode(struct omap_dss_device *dssdev,
+ enum omap_dss_update_mode mode)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_SET_UPDATE_MODE;
+ p.u.update_mode = mode;
+
+@@ -3362,11 +3261,11 @@ static void dsi_push_set_update_mode(struct omap_display *display,
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_set_rotate(struct omap_display *display, int rotate)
++static void dsi_push_set_rotate(struct omap_dss_device *dssdev, int rotate)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_SET_ROTATE;
+ p.u.rotate = rotate;
+
+@@ -3375,11 +3274,11 @@ static void dsi_push_set_rotate(struct omap_display *display, int rotate)
+ dsi_push_cmd(&p);
+ }
+
+-static void dsi_push_set_mirror(struct omap_display *display, int mirror)
++static void dsi_push_set_mirror(struct omap_dss_device *dssdev, int mirror)
+ {
+ struct dsi_cmd_item p;
+
+- p.display = display;
++ p.dssdev = dssdev;
+ p.cmd = DSI_CMD_SET_MIRROR;
+ p.u.mirror = mirror;
+
+@@ -3388,7 +3287,7 @@ static void dsi_push_set_mirror(struct omap_display *display, int mirror)
+ dsi_push_cmd(&p);
+ }
+
+-static int dsi_wait_sync(struct omap_display *display)
++static int dsi_wait_sync(struct omap_dss_device *dssdev)
+ {
+ long wait = msecs_to_jiffies(2000);
+ struct completion compl;
+@@ -3396,7 +3295,7 @@ static int dsi_wait_sync(struct omap_display *display)
+ DSSDBGF("");
+
+ init_completion(&compl);
+- dsi_push_sync(display, &compl);
++ dsi_push_sync(dssdev, &compl);
+
+ DSSDBG("Waiting for SYNC to happen...\n");
+ wait = wait_for_completion_timeout(&compl, wait);
+@@ -3423,7 +3322,7 @@ static int dsi_wait_sync(struct omap_display *display)
+
+ /* Display funcs */
+
+-static int dsi_display_init_dispc(struct omap_display *display)
++static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
+ {
+ int r;
+
+@@ -3439,7 +3338,7 @@ static int dsi_display_init_dispc(struct omap_display *display)
+ dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_DSI);
+ dispc_enable_fifohandcheck(1);
+
+- dispc_set_tft_data_lines(display->ctrl->pixel_size);
++ dispc_set_tft_data_lines(dssdev->ctrl.pixel_size);
+
+ {
+ struct omap_video_timings timings = {
+@@ -3457,13 +3356,13 @@ static int dsi_display_init_dispc(struct omap_display *display)
+ return 0;
+ }
+
+-static void dsi_display_uninit_dispc(struct omap_display *display)
++static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
+ {
+ omap_dispc_unregister_isr(framedone_callback, NULL,
+ DISPC_IRQ_FRAMEDONE);
+ }
+
+-static int dsi_display_init_dsi(struct omap_display *display)
++static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
+ {
+ struct dsi_clock_info cinfo;
+ int r;
+@@ -3476,7 +3375,7 @@ static int dsi_display_init_dsi(struct omap_display *display)
+ if (r)
+ goto err0;
+
+- r = dsi_pll_calc_ddrfreq(display->hw_config.u.dsi.ddr_clk_hz, &cinfo);
++ r = dsi_pll_calc_ddrfreq(dssdev->phy.dsi.ddr_clk_hz, &cinfo);
+ if (r)
+ goto err1;
+
+@@ -3486,19 +3385,19 @@ static int dsi_display_init_dsi(struct omap_display *display)
+
+ DSSDBG("PLL OK\n");
+
+- r = dsi_complexio_init(display);
++ r = dsi_complexio_init(dssdev);
+ if (r)
+ goto err1;
+
+ _dsi_print_reset_status();
+
+- dsi_proto_timings(display);
+- dsi_set_lp_clk_divisor(display);
++ dsi_proto_timings(dssdev);
++ dsi_set_lp_clk_divisor(dssdev);
+
+ if (1)
+ _dsi_print_reset_status();
+
+- r = dsi_proto_config(display);
++ r = dsi_proto_config(dssdev);
+ if (r)
+ goto err2;
+
+@@ -3508,27 +3407,18 @@ static int dsi_display_init_dsi(struct omap_display *display)
+ dsi_if_enable(1);
+ dsi_force_tx_stop_mode_io();
+
+- if (display->ctrl && display->ctrl->enable) {
+- r = display->ctrl->enable(display);
++ if (dssdev->driver->enable) {
++ r = dssdev->driver->enable(dssdev);
+ if (r)
+ goto err3;
+ }
+
+- if (display->panel && display->panel->enable) {
+- r = display->panel->enable(display);
+- if (r)
+- goto err4;
+- }
+-
+ /* enable high-speed after initial config */
+ dsi_vc_enable_hs(0, 1);
+
+ dsi_bus_unlock();
+
+ return 0;
+-err4:
+- if (display->ctrl && display->ctrl->disable)
+- display->ctrl->disable(display);
+ err3:
+ dsi_if_enable(0);
+ err2:
+@@ -3540,13 +3430,11 @@ err0:
+ return r;
+ }
+
+-static void dsi_display_uninit_dsi(struct omap_display *display)
++static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
+ {
+ dsi_bus_lock();
+- if (display->panel && display->panel->disable)
+- display->panel->disable(display);
+- if (display->ctrl && display->ctrl->disable)
+- display->ctrl->disable(display);
++ if (dssdev->driver->disable)
++ dssdev->driver->disable(dssdev);
+ dsi_bus_unlock();
+
+ dsi_complexio_uninit();
+@@ -3569,7 +3457,7 @@ static int dsi_core_init(void)
+ return 0;
+ }
+
+-static int dsi_display_enable(struct omap_display *display)
++static int dsi_display_enable(struct omap_dss_device *dssdev)
+ {
+ int r = 0;
+
+@@ -3577,101 +3465,177 @@ static int dsi_display_enable(struct omap_display *display)
+
+ mutex_lock(&dsi.lock);
+
+- if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
+- DSSERR("display already enabled\n");
+- r = -EINVAL;
++ r = omap_dss_start_device(dssdev);
++ if (r) {
++ DSSERR("failed to start device\n");
+ goto err0;
+ }
+
++ if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
++ DSSERR("dssdev already enabled\n");
++ r = -EINVAL;
++ goto err1;
++ }
++
+ enable_clocks(1);
+ dsi_enable_pll_clock(1);
+
+ r = _dsi_reset();
+ if (r)
+- return r;
++ goto err2;
+
+ dsi_core_init();
+
+- r = dsi_display_init_dispc(display);
++ r = dsi_display_init_dispc(dssdev);
+ if (r)
+- goto err1;
++ goto err2;
+
+- r = dsi_display_init_dsi(display);
++ r = dsi_display_init_dsi(dssdev);
+ if (r)
+- goto err2;
++ goto err3;
+
+- display->state = OMAP_DSS_DISPLAY_ACTIVE;
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ if (dsi.use_te || dsi.use_ext_te)
+- dsi_push_set_te(display, 1);
++ dsi_push_set_te(dssdev, 1);
+
+- dsi_push_set_update_mode(display, dsi.user_update_mode);
++ dsi_push_set_update_mode(dssdev, dsi.user_update_mode);
+ dsi.target_update_mode = dsi.user_update_mode;
+
+ mutex_unlock(&dsi.lock);
+
+- return dsi_wait_sync(display);
++ return dsi_wait_sync(dssdev);
+
++err3:
++ dsi_display_uninit_dispc(dssdev);
+ err2:
+- dsi_display_uninit_dispc(display);
+-err1:
+ enable_clocks(0);
+ dsi_enable_pll_clock(0);
++err1:
++ omap_dss_stop_device(dssdev);
+ err0:
+ mutex_unlock(&dsi.lock);
+ DSSDBG("dsi_display_enable FAILED\n");
+ return r;
+ }
+
+-static void dsi_display_disable(struct omap_display *display)
++static void dsi_display_disable(struct omap_dss_device *dssdev)
+ {
+ DSSDBG("dsi_display_disable\n");
+
+ mutex_lock(&dsi.lock);
+
+- if (display->state == OMAP_DSS_DISPLAY_DISABLED ||
+- display->state == OMAP_DSS_DISPLAY_SUSPENDED)
++ if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
++ dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
+ goto end;
+
+ if (dsi.target_update_mode != OMAP_DSS_UPDATE_DISABLED) {
+- dsi_push_set_update_mode(display, OMAP_DSS_UPDATE_DISABLED);
++ dsi_push_set_update_mode(dssdev, OMAP_DSS_UPDATE_DISABLED);
+ dsi.target_update_mode = OMAP_DSS_UPDATE_DISABLED;
+ }
+
+- dsi_wait_sync(display);
++ dsi_wait_sync(dssdev);
+
+- display->state = OMAP_DSS_DISPLAY_DISABLED;
++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+- dsi_display_uninit_dispc(display);
++ dsi_display_uninit_dispc(dssdev);
+
+- dsi_display_uninit_dsi(display);
++ dsi_display_uninit_dsi(dssdev);
+
+ enable_clocks(0);
+ dsi_enable_pll_clock(0);
++
++ omap_dss_stop_device(dssdev);
+ end:
+ mutex_unlock(&dsi.lock);
+ }
+
+-static int dsi_display_suspend(struct omap_display *display)
++static int dsi_display_suspend(struct omap_dss_device *dssdev)
+ {
+ DSSDBG("dsi_display_suspend\n");
+
+- dsi_display_disable(display);
++ mutex_lock(&dsi.lock);
++
++ if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
++ dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
++ goto end;
+
+- display->state = OMAP_DSS_DISPLAY_SUSPENDED;
++ if (dsi.target_update_mode != OMAP_DSS_UPDATE_DISABLED) {
++ dsi_push_set_update_mode(dssdev, OMAP_DSS_UPDATE_DISABLED);
++ dsi.target_update_mode = OMAP_DSS_UPDATE_DISABLED;
++ }
++
++ dsi_wait_sync(dssdev);
++
++ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
++
++ dsi_display_uninit_dispc(dssdev);
++
++ dsi_display_uninit_dsi(dssdev);
++
++ enable_clocks(0);
++ dsi_enable_pll_clock(0);
++end:
++ mutex_unlock(&dsi.lock);
+
+ return 0;
+ }
+
+-static int dsi_display_resume(struct omap_display *display)
++static int dsi_display_resume(struct omap_dss_device *dssdev)
+ {
++ int r;
++
+ DSSDBG("dsi_display_resume\n");
+
+- display->state = OMAP_DSS_DISPLAY_DISABLED;
+- return dsi_display_enable(display);
++ mutex_lock(&dsi.lock);
++
++ if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
++ DSSERR("dssdev not suspended\n");
++ r = -EINVAL;
++ goto err0;
++ }
++
++ enable_clocks(1);
++ dsi_enable_pll_clock(1);
++
++ r = _dsi_reset();
++ if (r)
++ goto err1;
++
++ dsi_core_init();
++
++ r = dsi_display_init_dispc(dssdev);
++ if (r)
++ goto err1;
++
++ r = dsi_display_init_dsi(dssdev);
++ if (r)
++ goto err2;
++
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
++
++ if (dsi.use_te || dsi.use_ext_te)
++ dsi_push_set_te(dssdev, 1);
++
++ dsi_push_set_update_mode(dssdev, dsi.user_update_mode);
++ dsi.target_update_mode = dsi.user_update_mode;
++
++ mutex_unlock(&dsi.lock);
++
++ return dsi_wait_sync(dssdev);
++
++err2:
++ dsi_display_uninit_dispc(dssdev);
++err1:
++ enable_clocks(0);
++ dsi_enable_pll_clock(0);
++err0:
++ mutex_unlock(&dsi.lock);
++ DSSDBG("dsi_display_resume FAILED\n");
++ return r;
+ }
+
+-static int dsi_display_update(struct omap_display *display,
++static int dsi_display_update(struct omap_dss_device *dssdev,
+ u16 x, u16 y, u16 w, u16 h)
+ {
+ DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h);
+@@ -3682,7 +3646,7 @@ static int dsi_display_update(struct omap_display *display,
+ mutex_lock(&dsi.lock);
+
+ if (dsi.target_update_mode == OMAP_DSS_UPDATE_MANUAL)
+- dsi_push_update(display, x, y, w, h);
++ dsi_push_update(dssdev, x, y, w, h);
+ /* XXX else return error? */
+
+ mutex_unlock(&dsi.lock);
+@@ -3690,13 +3654,13 @@ static int dsi_display_update(struct omap_display *display,
+ return 0;
+ }
+
+-static int dsi_display_sync(struct omap_display *display)
++static int dsi_display_sync(struct omap_dss_device *dssdev)
+ {
+ DSSDBGF("");
+- return dsi_wait_sync(display);
++ return dsi_wait_sync(dssdev);
+ }
+
+-static int dsi_display_set_update_mode(struct omap_display *display,
++static int dsi_display_set_update_mode(struct omap_dss_device *dssdev,
+ enum omap_dss_update_mode mode)
+ {
+ DSSDBGF("%d", mode);
+@@ -3704,7 +3668,7 @@ static int dsi_display_set_update_mode(struct omap_display *display,
+ mutex_lock(&dsi.lock);
+
+ if (dsi.target_update_mode != mode) {
+- dsi_push_set_update_mode(display, mode);
++ dsi_push_set_update_mode(dssdev, mode);
+
+ dsi.target_update_mode = mode;
+ dsi.user_update_mode = mode;
+@@ -3712,88 +3676,88 @@ static int dsi_display_set_update_mode(struct omap_display *display,
+
+ mutex_unlock(&dsi.lock);
+
+- return dsi_wait_sync(display);
++ return dsi_wait_sync(dssdev);
+ }
+
+ static enum omap_dss_update_mode dsi_display_get_update_mode(
+- struct omap_display *display)
++ struct omap_dss_device *dssdev)
+ {
+ return dsi.update_mode;
+ }
+
+-static int dsi_display_enable_te(struct omap_display *display, bool enable)
++static int dsi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
+ {
+ DSSDBGF("%d", enable);
+
+- if (!display->ctrl->enable_te)
++ if (!dssdev->driver->enable_te)
+ return -ENOENT;
+
+- dsi_push_set_te(display, enable);
++ dsi_push_set_te(dssdev, enable);
+
+- return dsi_wait_sync(display);
++ return dsi_wait_sync(dssdev);
+ }
+
+-static int dsi_display_get_te(struct omap_display *display)
++static int dsi_display_get_te(struct omap_dss_device *dssdev)
+ {
+ return dsi.use_te | dsi.use_ext_te;
+ }
+
+
+
+-static int dsi_display_set_rotate(struct omap_display *display, u8 rotate)
++static int dsi_display_set_rotate(struct omap_dss_device *dssdev, u8 rotate)
+ {
+ DSSDBGF("%d", rotate);
+
+- if (!display->ctrl->set_rotate || !display->ctrl->get_rotate)
++ if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
+ return -EINVAL;
+
+- dsi_push_set_rotate(display, rotate);
++ dsi_push_set_rotate(dssdev, rotate);
+
+- return dsi_wait_sync(display);
++ return dsi_wait_sync(dssdev);
+ }
+
+-static u8 dsi_display_get_rotate(struct omap_display *display)
++static u8 dsi_display_get_rotate(struct omap_dss_device *dssdev)
+ {
+- if (!display->ctrl->set_rotate || !display->ctrl->get_rotate)
++ if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
+ return 0;
+
+- return display->ctrl->get_rotate(display);
++ return dssdev->driver->get_rotate(dssdev);
+ }
+
+-static int dsi_display_set_mirror(struct omap_display *display, bool mirror)
++static int dsi_display_set_mirror(struct omap_dss_device *dssdev, bool mirror)
+ {
+ DSSDBGF("%d", mirror);
+
+- if (!display->ctrl->set_mirror || !display->ctrl->get_mirror)
++ if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
+ return -EINVAL;
+
+- dsi_push_set_mirror(display, mirror);
++ dsi_push_set_mirror(dssdev, mirror);
+
+- return dsi_wait_sync(display);
++ return dsi_wait_sync(dssdev);
+ }
+
+-static bool dsi_display_get_mirror(struct omap_display *display)
++static bool dsi_display_get_mirror(struct omap_dss_device *dssdev)
+ {
+- if (!display->ctrl->set_mirror || !display->ctrl->get_mirror)
++ if (!dssdev->driver->set_mirror || !dssdev->driver->get_mirror)
+ return 0;
+
+- return display->ctrl->get_mirror(display);
++ return dssdev->driver->get_mirror(dssdev);
+ }
+
+-static int dsi_display_run_test(struct omap_display *display, int test_num)
++static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num)
+ {
+ long wait = msecs_to_jiffies(60000);
+ struct completion compl;
+ int result;
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return -EIO;
+
+ DSSDBGF("%d", test_num);
+
+ init_completion(&compl);
+
+- dsi_push_test(display, test_num, &result, &compl);
++ dsi_push_test(dssdev, test_num, &result, &compl);
+
+ DSSDBG("Waiting for SYNC to happen...\n");
+ wait = wait_for_completion_timeout(&compl, wait);
+@@ -3807,7 +3771,7 @@ static int dsi_display_run_test(struct omap_display *display, int test_num)
+ return result;
+ }
+
+-static int dsi_display_memory_read(struct omap_display *display,
++static int dsi_display_memory_read(struct omap_dss_device *dssdev,
+ void *buf, size_t size,
+ u16 x, u16 y, u16 w, u16 h)
+ {
+@@ -3818,10 +3782,10 @@ static int dsi_display_memory_read(struct omap_display *display,
+
+ DSSDBGF("");
+
+- if (!display->ctrl->memory_read)
++ if (!dssdev->driver->memory_read)
+ return -EINVAL;
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return -EIO;
+
+ init_completion(&compl);
+@@ -3835,7 +3799,7 @@ static int dsi_display_memory_read(struct omap_display *display,
+ mem_read.ret_size = &ret_size;
+ mem_read.completion = &compl;
+
+- dsi_push_mem_read(display, &mem_read);
++ dsi_push_mem_read(dssdev, &mem_read);
+
+ DSSDBG("Waiting for SYNC to happen...\n");
+ wait = wait_for_completion_timeout(&compl, wait);
+@@ -3865,39 +3829,39 @@ static void dsi_configure_overlay(struct omap_overlay *ovl)
+ dispc_setup_plane_fifo(plane, low, high);
+ }
+
+-void dsi_init_display(struct omap_display *display)
++void dsi_init_display(struct omap_dss_device *dssdev)
+ {
+ DSSDBG("DSI init\n");
+
+- display->enable = dsi_display_enable;
+- display->disable = dsi_display_disable;
+- display->suspend = dsi_display_suspend;
+- display->resume = dsi_display_resume;
+- display->update = dsi_display_update;
+- display->sync = dsi_display_sync;
+- display->set_update_mode = dsi_display_set_update_mode;
+- display->get_update_mode = dsi_display_get_update_mode;
+- display->enable_te = dsi_display_enable_te;
+- display->get_te = dsi_display_get_te;
++ dssdev->enable = dsi_display_enable;
++ dssdev->disable = dsi_display_disable;
++ dssdev->suspend = dsi_display_suspend;
++ dssdev->resume = dsi_display_resume;
++ dssdev->update = dsi_display_update;
++ dssdev->sync = dsi_display_sync;
++ dssdev->set_update_mode = dsi_display_set_update_mode;
++ dssdev->get_update_mode = dsi_display_get_update_mode;
++ dssdev->enable_te = dsi_display_enable_te;
++ dssdev->get_te = dsi_display_get_te;
+
+- display->get_rotate = dsi_display_get_rotate;
+- display->set_rotate = dsi_display_set_rotate;
++ dssdev->get_rotate = dsi_display_get_rotate;
++ dssdev->set_rotate = dsi_display_set_rotate;
+
+- display->get_mirror = dsi_display_get_mirror;
+- display->set_mirror = dsi_display_set_mirror;
++ dssdev->get_mirror = dsi_display_get_mirror;
++ dssdev->set_mirror = dsi_display_set_mirror;
+
+- display->run_test = dsi_display_run_test;
+- display->memory_read = dsi_display_memory_read;
++ dssdev->run_test = dsi_display_run_test;
++ dssdev->memory_read = dsi_display_memory_read;
+
+- display->configure_overlay = dsi_configure_overlay;
++ dssdev->configure_overlay = dsi_configure_overlay;
+
+- display->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
++ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+
+- dsi.vc[0].display = display;
+- dsi.vc[1].display = display;
++ dsi.vc[0].dssdev = dssdev;
++ dsi.vc[1].dssdev = dssdev;
+ }
+
+-int dsi_init(void)
++int dsi_init(struct platform_device *pdev)
+ {
+ u32 rev;
+
+diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
+index d51ffe4..6180968 100644
+--- a/drivers/video/omap2/dss/dss.h
++++ b/drivers/video/omap2/dss/dss.h
+@@ -163,17 +163,22 @@ void dss_clk_disable(enum dss_clock clks);
+ unsigned long dss_clk_get_rate(enum dss_clock clk);
+ int dss_need_ctx_restore(void);
+ void dss_dump_clocks(struct seq_file *s);
+-
++struct bus_type *dss_get_bus(void);
+ int dss_dsi_power_up(void);
+ void dss_dsi_power_down(void);
+
++#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
++#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
++
+ /* display */
+-void dss_init_displays(struct platform_device *pdev);
+-void dss_uninit_displays(struct platform_device *pdev);
+-int dss_suspend_all_displays(void);
+-int dss_resume_all_displays(void);
+-struct omap_display *dss_get_display(int no);
+-bool dss_use_replication(struct omap_display *display,
++int dss_suspend_all_devices(void);
++int dss_resume_all_devices(void);
++
++void dss_init_device(struct platform_device *pdev,
++ struct omap_dss_device *dssdev);
++void dss_uninit_device(struct platform_device *pdev,
++ struct omap_dss_device *dssdev);
++bool dss_use_replication(struct omap_dss_device *dssdev,
+ enum omap_color_mode mode);
+
+ /* manager */
+@@ -181,10 +186,11 @@ int dss_init_overlay_managers(struct platform_device *pdev);
+ void dss_uninit_overlay_managers(struct platform_device *pdev);
+
+ /* overlay */
+-void dss_init_overlays(struct platform_device *pdev, const char *def_disp_name);
++void dss_init_overlays(struct platform_device *pdev);
+ void dss_uninit_overlays(struct platform_device *pdev);
+-int dss_check_overlay(struct omap_overlay *ovl, struct omap_display *display);
++int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev);
+ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
++void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
+
+ /* DSS */
+ int dss_init(bool skip_init);
+@@ -208,10 +214,10 @@ void dss_set_dac_pwrdn_bgz(bool enable);
+ /* SDI */
+ int sdi_init(bool skip_init);
+ void sdi_exit(void);
+-void sdi_init_display(struct omap_display *display);
++void sdi_init_display(struct omap_dss_device *display);
+
+ /* DSI */
+-int dsi_init(void);
++int dsi_init(struct platform_device *pdev);
+ void dsi_exit(void);
+
+ void dsi_dump_clocks(struct seq_file *s);
+@@ -220,7 +226,7 @@ void dsi_dump_regs(struct seq_file *s);
+ void dsi_save_context(void);
+ void dsi_restore_context(void);
+
+-void dsi_init_display(struct omap_display *display);
++void dsi_init_display(struct omap_dss_device *display);
+ void dsi_irq_handler(void);
+ unsigned long dsi_get_dsi1_pll_rate(void);
+ unsigned long dsi_get_dsi2_pll_rate(void);
+@@ -233,7 +239,7 @@ void dsi_pll_uninit(void);
+ /* DPI */
+ int dpi_init(void);
+ void dpi_exit(void);
+-void dpi_init_display(struct omap_display *display);
++void dpi_init_display(struct omap_dss_device *dssdev);
+
+ /* DISPC */
+ int dispc_init(void);
+@@ -306,7 +312,7 @@ void dispc_set_lcd_timings(struct omap_video_timings *timings);
+ unsigned long dispc_fclk_rate(void);
+ unsigned long dispc_lclk_rate(void);
+ unsigned long dispc_pclk_rate(void);
+-void dispc_set_pol_freq(struct omap_panel *panel);
++void dispc_set_pol_freq(enum omap_panel_config config, u8 acbi, u8 acb);
+ void find_lck_pck_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
+ u16 *lck_div, u16 *pck_div);
+ int dispc_calc_clock_div(bool is_tft, unsigned long req_pck,
+@@ -315,16 +321,16 @@ int dispc_set_clock_div(struct dispc_clock_info *cinfo);
+ int dispc_get_clock_div(struct dispc_clock_info *cinfo);
+ void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div);
+
+-void dispc_setup_partial_planes(struct omap_display *display,
++void dispc_setup_partial_planes(struct omap_dss_device *dssdev,
+ u16 *x, u16 *y, u16 *w, u16 *h);
+-void dispc_draw_partial_planes(struct omap_display *display);
++void dispc_draw_partial_planes(struct omap_dss_device *dssdev);
+
+
+ /* VENC */
+-int venc_init(void);
++int venc_init(struct platform_device *pdev);
+ void venc_exit(void);
+ void venc_dump_regs(struct seq_file *s);
+-void venc_init_display(struct omap_display *display);
++void venc_init_display(struct omap_dss_device *display);
+
+ /* RFBI */
+ int rfbi_init(void);
+@@ -337,6 +343,6 @@ void rfbi_transfer_area(u16 width, u16 height,
+ void (callback)(void *data), void *data);
+ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
+ unsigned long rfbi_get_max_tx_rate(void);
+-void rfbi_init_display(struct omap_display *display);
++void rfbi_init_display(struct omap_dss_device *display);
+
+ #endif
+diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
+index 8d5d00f..c68b9af 100644
+--- a/drivers/video/omap2/dss/manager.c
++++ b/drivers/video/omap2/dss/manager.c
+@@ -41,58 +41,68 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
+ static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
+ {
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+- mgr->display ? mgr->display->name : "<none>");
++ mgr->device ? mgr->device->name : "<none>");
+ }
+
+ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, const char *buf, size_t size)
+ {
+- int r, i;
+- int len = size;
+- struct omap_display *display = NULL;
++ int r = 0;
++ size_t len = size;
++ struct omap_dss_device *dssdev = NULL;
++
++ int match(struct omap_dss_device *dssdev, void *data)
++ {
++ const char *str = data;
++ return strcmp(dssdev->name, str) == 0;
++ }
+
+ if (buf[size-1] == '\n')
+ --len;
+
+ if (len > 0) {
+- for (i = 0; i < omap_dss_get_num_displays(); ++i) {
+- display = dss_get_display(i);
++ char name[64];
++ int n;
+
+- if (strncmp(buf, display->name, len) == 0)
+- break;
++ n = min(len, sizeof(name) - 1);
++ strncpy(name, buf, n);
++ name[n - 1] = 0;
+
+- display = NULL;
+- }
++ dssdev = omap_dss_find_device(name, match);
+ }
+
+- if (len > 0 && display == NULL)
++ if (len > 0 && dssdev == NULL)
+ return -EINVAL;
+
+- if (display)
+- DSSDBG("display %s found\n", display->name);
++ if (dssdev)
++ DSSDBG("display %s found\n", dssdev->name);
+
+- if (mgr->display) {
+- r = mgr->unset_display(mgr);
++ if (mgr->device) {
++ r = mgr->unset_device(mgr);
+ if (r) {
+ DSSERR("failed to unset display\n");
+- return r;
++ goto put_device;
+ }
+ }
+
+- if (display) {
+- r = mgr->set_display(mgr, display);
++ if (dssdev) {
++ r = mgr->set_device(mgr, dssdev);
+ if (r) {
+ DSSERR("failed to set manager\n");
+- return r;
++ goto put_device;
+ }
+
+ r = mgr->apply(mgr);
+ if (r) {
+ DSSERR("failed to apply dispc config\n");
+- return r;
++ goto put_device;
+ }
+ }
+
+- return size;
++put_device:
++ if (dssdev)
++ omap_dss_put_device(dssdev);
++
++ return r ? r : size;
+ }
+
+ static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
+@@ -334,21 +344,21 @@ static struct kobj_type manager_ktype = {
+ .default_attrs = manager_sysfs_attrs,
+ };
+
+-static int omap_dss_set_display(struct omap_overlay_manager *mgr,
+- struct omap_display *display)
++static int omap_dss_set_device(struct omap_overlay_manager *mgr,
++ struct omap_dss_device *dssdev)
+ {
+ int i;
+ int r;
+
+- if (display->manager) {
++ if (dssdev->manager) {
+ DSSERR("display '%s' already has a manager '%s'\n",
+- display->name, display->manager->name);
++ dssdev->name, dssdev->manager->name);
+ return -EINVAL;
+ }
+
+- if ((mgr->supported_displays & display->type) == 0) {
++ if ((mgr->supported_displays & dssdev->type) == 0) {
+ DSSERR("display '%s' does not support manager '%s'\n",
+- display->name, mgr->name);
++ dssdev->name, mgr->name);
+ return -EINVAL;
+ }
+
+@@ -358,26 +368,26 @@ static int omap_dss_set_display(struct omap_overlay_manager *mgr,
+ if (ovl->manager != mgr || !ovl->info.enabled)
+ continue;
+
+- r = dss_check_overlay(ovl, display);
++ r = dss_check_overlay(ovl, dssdev);
+ if (r)
+ return r;
+ }
+
+- display->manager = mgr;
+- mgr->display = display;
++ dssdev->manager = mgr;
++ mgr->device = dssdev;
+
+ return 0;
+ }
+
+-static int omap_dss_unset_display(struct omap_overlay_manager *mgr)
++static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
+ {
+- if (!mgr->display) {
++ if (!mgr->device) {
+ DSSERR("failed to unset display, display not set.\n");
+ return -EINVAL;
+ }
+
+- mgr->display->manager = NULL;
+- mgr->display = NULL;
++ mgr->device->manager = NULL;
++ mgr->device = NULL;
+
+ return 0;
+ }
+@@ -385,7 +395,7 @@ static int omap_dss_unset_display(struct omap_overlay_manager *mgr)
+
+ static int overlay_enabled(struct omap_overlay *ovl)
+ {
+- return ovl->info.enabled && ovl->manager && ovl->manager->display;
++ return ovl->info.enabled && ovl->manager && ovl->manager->device;
+ }
+
+ /* We apply settings to both managers here so that we can use optimizations
+@@ -396,7 +406,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+ int i;
+ int ret = 0;
+ enum omap_dss_update_mode mode;
+- struct omap_display *display;
++ struct omap_dss_device *dssdev;
+ struct omap_overlay *ovl;
+ bool ilace = 0;
+ int outw, outh;
+@@ -419,9 +429,9 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+ continue;
+ }
+
+- display = ovl->manager->display;
++ dssdev = ovl->manager->device;
+
+- if (dss_check_overlay(ovl, display)) {
++ if (dss_check_overlay(ovl, dssdev)) {
+ dispc_enable_plane(ovl->id, 0);
+ continue;
+ }
+@@ -431,14 +441,14 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+ /* On a manual update display, in manual update mode, update()
+ * handles configuring planes */
+ mode = OMAP_DSS_UPDATE_AUTO;
+- if (display->get_update_mode)
+- mode = display->get_update_mode(mgr->display);
++ if (dssdev->get_update_mode)
++ mode = dssdev->get_update_mode(dssdev);
+
+- if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
++ if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
+ mode != OMAP_DSS_UPDATE_AUTO)
+ continue;
+
+- if (display->type == OMAP_DISPLAY_TYPE_VENC)
++ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
+ ilace = 1;
+
+ if (ovl->info.out_width == 0)
+@@ -474,7 +484,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+ continue;
+ }
+
+- if (dss_use_replication(display, ovl->info.color_mode))
++ if (dss_use_replication(dssdev, ovl->info.color_mode))
+ dispc_enable_replication(ovl->id, true);
+ else
+ dispc_enable_replication(ovl->id, false);
+@@ -498,7 +508,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+ continue;
+ }
+
+- ovl->manager->display->configure_overlay(ovl);
++ ovl->manager->device->configure_overlay(ovl);
+ }
+
+ /* Issue GO for managers */
+@@ -506,15 +516,15 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+ if (!(mgr->caps & OMAP_DSS_OVL_MGR_CAP_DISPC))
+ continue;
+
+- display = mgr->display;
++ dssdev = mgr->device;
+
+- if (!display)
++ if (!dssdev)
+ continue;
+
+ /* We don't need GO with manual update display. LCD iface will
+ * always be turned off after frame, and new settings will
+ * be taken in to use at next update */
+- if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
++ if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
+ continue;
+
+ dispc_go(mgr->id);
+@@ -605,8 +615,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
+ break;
+ }
+
+- mgr->set_display = &omap_dss_set_display;
+- mgr->unset_display = &omap_dss_unset_display;
++ mgr->set_device = &omap_dss_set_device;
++ mgr->unset_device = &omap_dss_unset_device;
+ mgr->apply = &omap_dss_mgr_apply;
+ mgr->set_default_color = &omap_dss_mgr_set_def_color;
+ mgr->set_trans_key_type_and_value =
+diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
+index 035a57a..3704727 100644
+--- a/drivers/video/omap2/dss/overlay.c
++++ b/drivers/video/omap2/dss/overlay.c
+@@ -301,13 +301,13 @@ static struct kobj_type overlay_ktype = {
+ };
+
+ /* Check if overlay parameters are compatible with display */
+-int dss_check_overlay(struct omap_overlay *ovl, struct omap_display *display)
++int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
+ {
+ struct omap_overlay_info *info;
+ u16 outw, outh;
+ u16 dw, dh;
+
+- if (!display)
++ if (!dssdev)
+ return 0;
+
+ if (!ovl->info.enabled)
+@@ -320,7 +320,7 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_display *display)
+ return -EINVAL;
+ }
+
+- display->get_resolution(display, &dw, &dh);
++ dssdev->get_resolution(dssdev, &dw, &dh);
+
+ DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
+ ovl->id,
+@@ -374,7 +374,7 @@ static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
+ ovl->info = *info;
+
+ if (ovl->manager) {
+- r = dss_check_overlay(ovl, ovl->manager->display);
++ r = dss_check_overlay(ovl, ovl->manager->device);
+ if (r) {
+ ovl->info = old_info;
+ return r;
+@@ -400,7 +400,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
+ ovl->name, ovl->manager->name);
+ }
+
+- r = dss_check_overlay(ovl, mgr->display);
++ r = dss_check_overlay(ovl, mgr->device);
+ if (r)
+ return r;
+
+@@ -455,12 +455,9 @@ void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
+ mgr->overlays = dispc_overlays;
+ }
+
+-void dss_init_overlays(struct platform_device *pdev, const char *def_disp_name)
++void dss_init_overlays(struct platform_device *pdev)
+ {
+ int i, r;
+- struct omap_overlay_manager *lcd_mgr;
+- struct omap_overlay_manager *tv_mgr;
+- struct omap_overlay_manager *def_mgr = NULL;
+
+ INIT_LIST_HEAD(&overlay_list);
+
+@@ -515,71 +512,49 @@ void dss_init_overlays(struct platform_device *pdev, const char *def_disp_name)
+
+ dispc_overlays[i] = ovl;
+ }
++}
++
++/* connect overlays to the new device, if not already connected. if force
++ * selected, connect always. */
++void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
++{
++ int i;
++ struct omap_overlay_manager *lcd_mgr;
++ struct omap_overlay_manager *tv_mgr;
++ struct omap_overlay_manager *mgr = NULL;
+
+ lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
+ tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
+
+- if (def_disp_name) {
+- for (i = 0; i < omap_dss_get_num_displays() ; i++) {
+- struct omap_display *display = dss_get_display(i);
+-
+- if (strcmp(display->name, def_disp_name) == 0) {
+- if (display->type != OMAP_DISPLAY_TYPE_VENC) {
+- lcd_mgr->set_display(lcd_mgr, display);
+- def_mgr = lcd_mgr;
+- } else {
+- lcd_mgr->set_display(tv_mgr, display);
+- def_mgr = tv_mgr;
+- }
+-
+- break;
+- }
+- }
+-
+- if (!def_mgr)
+- DSSWARN("default display %s not found\n",
+- def_disp_name);
+- }
+-
+- if (def_mgr != lcd_mgr) {
+- /* connect lcd manager to first non-VENC display found */
+- for (i = 0; i < omap_dss_get_num_displays(); i++) {
+- struct omap_display *display = dss_get_display(i);
+- if (display->type != OMAP_DISPLAY_TYPE_VENC) {
+- lcd_mgr->set_display(lcd_mgr, display);
+-
+- if (!def_mgr)
+- def_mgr = lcd_mgr;
+-
+- break;
+- }
++ if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
++ if (!lcd_mgr->device || force) {
++ if (lcd_mgr->device)
++ lcd_mgr->unset_device(lcd_mgr);
++ lcd_mgr->set_device(lcd_mgr, dssdev);
++ mgr = lcd_mgr;
+ }
+ }
+
+- if (def_mgr != tv_mgr) {
+- /* connect tv manager to first VENC display found */
+- for (i = 0; i < omap_dss_get_num_displays(); i++) {
+- struct omap_display *display = dss_get_display(i);
+- if (display->type == OMAP_DISPLAY_TYPE_VENC) {
+- tv_mgr->set_display(tv_mgr, display);
+-
+- if (!def_mgr)
+- def_mgr = tv_mgr;
+-
+- break;
+- }
++ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
++ if (!tv_mgr->device || force) {
++ if (tv_mgr->device)
++ tv_mgr->unset_device(tv_mgr);
++ tv_mgr->set_device(tv_mgr, dssdev);
++ mgr = tv_mgr;
+ }
+ }
+
+- /* connect all dispc overlays to def_mgr */
+- if (def_mgr) {
++ if (mgr) {
+ for (i = 0; i < 3; i++) {
+ struct omap_overlay *ovl;
+ ovl = omap_dss_get_overlay(i);
+- omap_dss_set_manager(ovl, def_mgr);
++ if (!ovl->manager || force) {
++ if (ovl->manager)
++ omap_dss_unset_manager(ovl);
++ omap_dss_set_manager(ovl, mgr);
++ }
+ }
+ }
+-
+ #ifdef L4_EXAMPLE
+ /* setup L4 overlay as an example */
+ {
+diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
+index 3e9ae1e..e3cf799 100644
+--- a/drivers/video/omap2/dss/rfbi.c
++++ b/drivers/video/omap2/dss/rfbi.c
+@@ -119,7 +119,7 @@ static struct {
+ void (*framedone_callback)(void *data);
+ void *framedone_callback_data;
+
+- struct omap_display *display[2];
++ struct omap_dss_device *dssdev[2];
+
+ struct kfifo *cmd_fifo;
+ spinlock_t cmd_lock;
+@@ -938,12 +938,12 @@ int rfbi_configure(int rfbi_module, int bpp, int lines)
+ }
+ EXPORT_SYMBOL(rfbi_configure);
+
+-static int rfbi_find_display(struct omap_display *disp)
++static int rfbi_find_display(struct omap_dss_device *dssdev)
+ {
+- if (disp == rfbi.display[0])
++ if (dssdev == rfbi.dssdev[0])
+ return 0;
+
+- if (disp == rfbi.display[1])
++ if (dssdev == rfbi.dssdev[1])
+ return 1;
+
+ BUG();
+@@ -961,7 +961,7 @@ static void signal_fifo_waiters(void)
+ }
+
+ /* returns 1 for async op, and 0 for sync op */
+-static int do_update(struct omap_display *display, struct update_region *upd)
++static int do_update(struct omap_dss_device *dssdev, struct update_region *upd)
+ {
+ u16 x = upd->x;
+ u16 y = upd->y;
+@@ -970,18 +970,18 @@ static int do_update(struct omap_display *display, struct update_region *upd)
+
+ perf_mark_setup();
+
+- if (display->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+- /*display->ctrl->enable_te(display, 1); */
+- dispc_setup_partial_planes(display, &x, &y, &w, &h);
++ if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
++ /*dssdev->driver->enable_te(dssdev, 1); */
++ dispc_setup_partial_planes(dssdev, &x, &y, &w, &h);
+ }
+
+ #ifdef MEASURE_PERF
+ rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */
+ #endif
+
+- display->ctrl->setup_update(display, x, y, w, h);
++ dssdev->driver->setup_update(dssdev, x, y, w, h);
+
+- if (display->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
++ if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
+ rfbi_transfer_area(w, h, NULL, NULL);
+ return 1;
+ } else {
+@@ -989,7 +989,7 @@ static int do_update(struct omap_display *display, struct update_region *upd)
+ void __iomem *addr;
+ int scr_width;
+
+- ovl = display->manager->overlays[0];
++ ovl = dssdev->manager->overlays[0];
+ scr_width = ovl->info.screen_width;
+ addr = ovl->info.vaddr;
+
+@@ -1005,7 +1005,7 @@ static void process_cmd_fifo(void)
+ {
+ int len;
+ struct update_param p;
+- struct omap_display *display;
++ struct omap_dss_device *dssdev;
+ unsigned long flags;
+
+ if (atomic_inc_return(&rfbi.cmd_pending) != 1)
+@@ -1030,10 +1030,10 @@ static void process_cmd_fifo(void)
+ BUG_ON(len != sizeof(struct update_param));
+ BUG_ON(p.rfbi_module > 1);
+
+- display = rfbi.display[p.rfbi_module];
++ dssdev = rfbi.dssdev[p.rfbi_module];
+
+ if (p.cmd == RFBI_CMD_UPDATE) {
+- if (do_update(display, &p.par.r))
++ if (do_update(dssdev, &p.par.r))
+ break; /* async op */
+ } else if (p.cmd == RFBI_CMD_SYNC) {
+ DSSDBG("Signaling SYNC done!\n");
+@@ -1203,7 +1203,7 @@ void rfbi_exit(void)
+ }
+
+ /* struct omap_display support */
+-static int rfbi_display_update(struct omap_display *display,
++static int rfbi_display_update(struct omap_dss_device *dssdev,
+ u16 x, u16 y, u16 w, u16 h)
+ {
+ int rfbi_module;
+@@ -1211,19 +1211,19 @@ static int rfbi_display_update(struct omap_display *display,
+ if (w == 0 || h == 0)
+ return 0;
+
+- rfbi_module = rfbi_find_display(display);
++ rfbi_module = rfbi_find_display(dssdev);
+
+ rfbi_push_update(rfbi_module, x, y, w, h);
+
+ return 0;
+ }
+
+-static int rfbi_display_sync(struct omap_display *display)
++static int rfbi_display_sync(struct omap_dss_device *dssdev)
+ {
+ struct completion sync_comp;
+ int rfbi_module;
+
+- rfbi_module = rfbi_find_display(display);
++ rfbi_module = rfbi_find_display(dssdev);
+
+ init_completion(&sync_comp);
+ rfbi_push_sync(rfbi_module, &sync_comp);
+@@ -1233,72 +1233,76 @@ static int rfbi_display_sync(struct omap_display *display)
+ return 0;
+ }
+
+-static int rfbi_display_enable_te(struct omap_display *display, bool enable)
++static int rfbi_display_enable_te(struct omap_dss_device *dssdev, bool enable)
+ {
+- display->ctrl->enable_te(display, enable);
++ dssdev->driver->enable_te(dssdev, enable);
+ return 0;
+ }
+
+-static int rfbi_display_enable(struct omap_display *display)
++static int rfbi_display_enable(struct omap_dss_device *dssdev)
+ {
+ int r;
+
+- BUG_ON(display->panel == NULL || display->ctrl == NULL);
++ r = omap_dss_start_device(dssdev);
++ if (r) {
++ DSSERR("failed to start device\n");
++ goto err0;
++ }
+
+ r = omap_dispc_register_isr(framedone_callback, NULL,
+ DISPC_IRQ_FRAMEDONE);
+ if (r) {
+ DSSERR("can't get FRAMEDONE irq\n");
+- return r;
++ goto err1;
+ }
+
+ dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT);
+
+ dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_RFBI);
+
+- dispc_set_tft_data_lines(display->ctrl->pixel_size);
++ dispc_set_tft_data_lines(dssdev->ctrl.pixel_size);
+
+- rfbi_configure(display->hw_config.u.rfbi.channel,
+- display->ctrl->pixel_size,
+- display->hw_config.u.rfbi.data_lines);
++ rfbi_configure(dssdev->phy.rfbi.channel,
++ dssdev->ctrl.pixel_size,
++ dssdev->phy.rfbi.data_lines);
+
+- rfbi_set_timings(display->hw_config.u.rfbi.channel,
+- &display->ctrl->timings);
++ rfbi_set_timings(dssdev->phy.rfbi.channel,
++ &dssdev->ctrl.rfbi_timings);
+
+
+- if (display->ctrl && display->ctrl->enable) {
+- r = display->ctrl->enable(display);
++ if (dssdev->driver->enable) {
++ r = dssdev->driver->enable(dssdev);
+ if (r)
+- goto err;
+- }
+-
+- if (display->panel && display->panel->enable) {
+- r = display->panel->enable(display);
+- if (r)
+- goto err;
++ goto err2;
+ }
+
+ return 0;
+-err:
+- return -ENODEV;
++err2:
++ omap_dispc_unregister_isr(framedone_callback, NULL,
++ DISPC_IRQ_FRAMEDONE);
++err1:
++ omap_dss_stop_device(dssdev);
++err0:
++ return r;
+ }
+
+-static void rfbi_display_disable(struct omap_display *display)
++static void rfbi_display_disable(struct omap_dss_device *dssdev)
+ {
+- display->ctrl->disable(display);
++ dssdev->driver->disable(dssdev);
+ omap_dispc_unregister_isr(framedone_callback, NULL,
+ DISPC_IRQ_FRAMEDONE);
++ omap_dss_stop_device(dssdev);
+ }
+
+-void rfbi_init_display(struct omap_display *display)
++void rfbi_init_display(struct omap_dss_device *dssdev)
+ {
+- display->enable = rfbi_display_enable;
+- display->disable = rfbi_display_disable;
+- display->update = rfbi_display_update;
+- display->sync = rfbi_display_sync;
+- display->enable_te = rfbi_display_enable_te;
++ dssdev->enable = rfbi_display_enable;
++ dssdev->disable = rfbi_display_disable;
++ dssdev->update = rfbi_display_update;
++ dssdev->sync = rfbi_display_sync;
++ dssdev->enable_te = rfbi_display_enable_te;
+
+- rfbi.display[display->hw_config.u.rfbi.channel] = display;
++ rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
+
+- display->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
++ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+ }
+diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
+index fbff2b2..393fcd5 100644
+--- a/drivers/video/omap2/dss/sdi.c
++++ b/drivers/video/omap2/dss/sdi.c
+@@ -43,18 +43,25 @@ static void sdi_basic_init(void)
+ dispc_lcd_enable_signal_polarity(1);
+ }
+
+-static int sdi_display_enable(struct omap_display *display)
++static int sdi_display_enable(struct omap_dss_device *dssdev)
+ {
++ struct omap_video_timings *t = &dssdev->panel.timings;
+ struct dispc_clock_info cinfo;
+ u16 lck_div, pck_div;
+ unsigned long fck;
+- struct omap_panel *panel = display->panel;
+ unsigned long pck;
+ int r;
+
+- if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
+- DSSERR("display already enabled\n");
+- return -EINVAL;
++ r = omap_dss_start_device(dssdev);
++ if (r) {
++ DSSERR("failed to start device\n");
++ goto err0;
++ }
++
++ if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
++ DSSERR("dssdev already enabled\n");
++ r = -EINVAL;
++ goto err1;
+ }
+
+ /* In case of skip_init sdi_init has already enabled the clocks */
+@@ -64,18 +71,19 @@ static int sdi_display_enable(struct omap_display *display)
+ sdi_basic_init();
+
+ /* 15.5.9.1.2 */
+- panel->config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
++ dssdev->panel.config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
+
+- dispc_set_pol_freq(panel);
++ dispc_set_pol_freq(dssdev->panel.config, dssdev->panel.acbi,
++ dssdev->panel.acb);
+
+ if (!sdi.skip_init)
+- r = dispc_calc_clock_div(1, panel->timings.pixel_clock * 1000,
++ r = dispc_calc_clock_div(1, t->pixel_clock * 1000,
+ &cinfo);
+ else
+ r = dispc_get_clock_div(&cinfo);
+
+ if (r)
+- goto err0;
++ goto err2;
+
+ fck = cinfo.fck;
+ lck_div = cinfo.lck_div;
+@@ -83,57 +91,62 @@ static int sdi_display_enable(struct omap_display *display)
+
+ pck = fck / lck_div / pck_div / 1000;
+
+- if (pck != panel->timings.pixel_clock) {
++ if (pck != t->pixel_clock) {
+ DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
+ "got %lu kHz\n",
+- panel->timings.pixel_clock, pck);
++ t->pixel_clock, pck);
+
+- panel->timings.pixel_clock = pck;
++ t->pixel_clock = pck;
+ }
+
+
+- dispc_set_lcd_timings(&panel->timings);
++ dispc_set_lcd_timings(t);
+
+ r = dispc_set_clock_div(&cinfo);
+ if (r)
+- goto err1;
++ goto err2;
+
+ if (!sdi.skip_init) {
+- dss_sdi_init(display->hw_config.u.sdi.datapairs);
++ dss_sdi_init(dssdev->phy.sdi.datapairs);
+ dss_sdi_enable();
+ mdelay(2);
+ }
+
+ dispc_enable_lcd_out(1);
+
+- r = panel->enable(display);
+- if (r)
+- goto err2;
++ if (dssdev->driver->enable) {
++ r = dssdev->driver->enable(dssdev);
++ if (r)
++ goto err3;
++ }
+
+- display->state = OMAP_DSS_DISPLAY_ACTIVE;
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ sdi.skip_init = 0;
+
+ return 0;
+-err2:
++err3:
+ dispc_enable_lcd_out(0);
++err2:
++ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ err1:
++ omap_dss_stop_device(dssdev);
+ err0:
+- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ return r;
+ }
+
+-static int sdi_display_resume(struct omap_display *display);
++static int sdi_display_resume(struct omap_dss_device *dssdev);
+
+-static void sdi_display_disable(struct omap_display *display)
++static void sdi_display_disable(struct omap_dss_device *dssdev)
+ {
+- if (display->state == OMAP_DSS_DISPLAY_DISABLED)
++ if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+ return;
+
+- if (display->state == OMAP_DSS_DISPLAY_SUSPENDED)
+- sdi_display_resume(display);
++ if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
++ sdi_display_resume(dssdev);
+
+- display->panel->disable(display);
++ if (dssdev->driver->disable)
++ dssdev->driver->disable(dssdev);
+
+ dispc_enable_lcd_out(0);
+
+@@ -141,16 +154,18 @@ static void sdi_display_disable(struct omap_display *display)
+
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+- display->state = OMAP_DSS_DISPLAY_DISABLED;
++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
++
++ omap_dss_stop_device(dssdev);
+ }
+
+-static int sdi_display_suspend(struct omap_display *display)
++static int sdi_display_suspend(struct omap_dss_device *dssdev)
+ {
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return -EINVAL;
+
+- if (display->panel->suspend)
+- display->panel->suspend(display);
++ if (dssdev->driver->suspend)
++ dssdev->driver->suspend(dssdev);
+
+ dispc_enable_lcd_out(0);
+
+@@ -158,14 +173,14 @@ static int sdi_display_suspend(struct omap_display *display)
+
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+
+- display->state = OMAP_DSS_DISPLAY_SUSPENDED;
++ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+ return 0;
+ }
+
+-static int sdi_display_resume(struct omap_display *display)
++static int sdi_display_resume(struct omap_dss_device *dssdev)
+ {
+- if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
++ if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED)
+ return -EINVAL;
+
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+@@ -175,15 +190,15 @@ static int sdi_display_resume(struct omap_display *display)
+
+ dispc_enable_lcd_out(1);
+
+- if (display->panel->resume)
+- display->panel->resume(display);
++ if (dssdev->driver->resume)
++ dssdev->driver->resume(dssdev);
+
+- display->state = OMAP_DSS_DISPLAY_ACTIVE;
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+ }
+
+-static int sdi_display_set_update_mode(struct omap_display *display,
++static int sdi_display_set_update_mode(struct omap_dss_device *dssdev,
+ enum omap_dss_update_mode mode)
+ {
+ if (mode == OMAP_DSS_UPDATE_MANUAL)
+@@ -201,29 +216,29 @@ static int sdi_display_set_update_mode(struct omap_display *display,
+ }
+
+ static enum omap_dss_update_mode sdi_display_get_update_mode(
+- struct omap_display *display)
++ struct omap_dss_device *dssdev)
+ {
+ return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
+ OMAP_DSS_UPDATE_DISABLED;
+ }
+
+-static void sdi_get_timings(struct omap_display *display,
++static void sdi_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+ {
+- *timings = display->panel->timings;
++ *timings = dssdev->panel.timings;
+ }
+
+-void sdi_init_display(struct omap_display *display)
++void sdi_init_display(struct omap_dss_device *dssdev)
+ {
+ DSSDBG("SDI init\n");
+
+- display->enable = sdi_display_enable;
+- display->disable = sdi_display_disable;
+- display->suspend = sdi_display_suspend;
+- display->resume = sdi_display_resume;
+- display->set_update_mode = sdi_display_set_update_mode;
+- display->get_update_mode = sdi_display_get_update_mode;
+- display->get_timings = sdi_get_timings;
++ dssdev->enable = sdi_display_enable;
++ dssdev->disable = sdi_display_disable;
++ dssdev->suspend = sdi_display_suspend;
++ dssdev->resume = sdi_display_resume;
++ dssdev->set_update_mode = sdi_display_set_update_mode;
++ dssdev->get_update_mode = sdi_display_get_update_mode;
++ dssdev->get_timings = sdi_get_timings;
+ }
+
+ int sdi_init(bool skip_init)
+diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
+index b0f0795..a83d170 100644
+--- a/drivers/video/omap2/dss/venc.c
++++ b/drivers/video/omap2/dss/venc.c
+@@ -31,6 +31,7 @@
+ #include <linux/delay.h>
+ #include <linux/string.h>
+ #include <linux/seq_file.h>
++#include <linux/platform_device.h>
+
+ #include <mach/display.h>
+ #include <mach/cpu.h>
+@@ -292,10 +293,6 @@ static struct {
+ u32 wss_data;
+ } venc;
+
+-static struct omap_panel venc_panel = {
+- .name = "tv-out",
+-};
+-
+ static inline void venc_write_reg(int idx, u32 val)
+ {
+ __raw_writel(val, venc.base + idx);
+@@ -400,7 +397,76 @@ static const struct venc_config *venc_timings_to_config(
+ BUG();
+ }
+
+-int venc_init(void)
++
++
++
++
++/* driver */
++static int venc_panel_probe(struct omap_dss_device *dssdev)
++{
++ //dssdev->name = "tv-out";
++ dssdev->panel.timings = omap_dss_pal_timings;
++
++ return 0;
++}
++
++static void venc_panel_remove(struct omap_dss_device *dssdev)
++{
++}
++
++static int venc_panel_enable(struct omap_dss_device *dssdev)
++{
++ int r = 0;
++
++ /* wait couple of vsyncs until enabling the LCD */
++ msleep(50);
++
++ if (dssdev->platform_enable)
++ r = dssdev->platform_enable(dssdev);
++
++ return r;
++}
++
++static void venc_panel_disable(struct omap_dss_device *dssdev)
++{
++ if (dssdev->platform_disable)
++ dssdev->platform_disable(dssdev);
++
++ /* wait at least 5 vsyncs after disabling the LCD */
++
++ msleep(100);
++}
++
++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 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,
++
++ .driver = {
++ .name = "venc",
++ .owner = THIS_MODULE,
++ },
++};
++/* driver end */
++
++
++
++int venc_init(struct platform_device *pdev)
+ {
+ u8 rev_id;
+
+@@ -408,8 +474,6 @@ int venc_init(void)
+
+ venc.wss_data = 0;
+
+- venc_panel.timings = omap_dss_pal_timings;
+-
+ venc.base = ioremap(VENC_BASE, SZ_1K);
+ if (!venc.base) {
+ DSSERR("can't ioremap VENC\n");
+@@ -423,25 +487,29 @@ int venc_init(void)
+
+ venc_enable_clocks(0);
+
+- return 0;
++ return omap_dss_register_driver(&venc_driver);
++
++ //return 0;
+ }
+
+ void venc_exit(void)
+ {
++ omap_dss_unregister_driver(&venc_driver);
++
+ iounmap(venc.base);
+ }
+
+-static void venc_power_on(struct omap_display *display)
++static void venc_power_on(struct omap_dss_device *dssdev)
+ {
+ venc_enable_clocks(1);
+
+ venc_reset();
+- venc_write_config(venc_timings_to_config(&display->panel->timings));
++ venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+
+- dss_set_venc_output(display->hw_config.u.venc.type);
++ dss_set_venc_output(dssdev->phy.venc.type);
+ dss_set_dac_pwrdn_bgz(1);
+
+- if (display->hw_config.u.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) {
++ if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) {
+ if (cpu_is_omap24xx())
+ venc_write_reg(VENC_OUTPUT_CONTROL, 0x2);
+ else
+@@ -450,29 +518,29 @@ static void venc_power_on(struct omap_display *display)
+ venc_write_reg(VENC_OUTPUT_CONTROL, 0xd);
+ }
+
+- dispc_set_digit_size(display->panel->timings.x_res,
+- display->panel->timings.y_res/2);
++ dispc_set_digit_size(dssdev->panel.timings.x_res,
++ dssdev->panel.timings.y_res/2);
+
+- if (display->hw_config.panel_enable)
+- display->hw_config.panel_enable(display);
++ if (dssdev->platform_enable)
++ dssdev->platform_enable(dssdev);
+
+ dispc_enable_digit_out(1);
+ }
+
+-static void venc_power_off(struct omap_display *display)
++static void venc_power_off(struct omap_dss_device *dssdev)
+ {
+ venc_write_reg(VENC_OUTPUT_CONTROL, 0);
+ dss_set_dac_pwrdn_bgz(0);
+
+ dispc_enable_digit_out(0);
+
+- if (display->hw_config.panel_disable)
+- display->hw_config.panel_disable(display);
++ if (dssdev->platform_disable)
++ dssdev->platform_disable(dssdev);
+
+ venc_enable_clocks(0);
+ }
+
+-static int venc_enable_display(struct omap_display *display)
++static int venc_enable_display(struct omap_dss_device *dssdev)
+ {
+ int r = 0;
+
+@@ -480,43 +548,45 @@ static int venc_enable_display(struct omap_display *display)
+
+ mutex_lock(&venc.venc_lock);
+
+- if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
++ if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+ r = -EINVAL;
+ goto err;
+ }
+
+- venc_power_on(display);
++ venc_power_on(dssdev);
++
++ venc.wss_data = 0;
+
+- display->state = OMAP_DSS_DISPLAY_ACTIVE;
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+ err:
+ mutex_unlock(&venc.venc_lock);
+
+ return r;
+ }
+
+-static void venc_disable_display(struct omap_display *display)
++static void venc_disable_display(struct omap_dss_device *dssdev)
+ {
+ DSSDBG("venc_disable_display\n");
+
+ mutex_lock(&venc.venc_lock);
+
+- if (display->state == OMAP_DSS_DISPLAY_DISABLED)
++ if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+ goto end;
+
+- if (display->state == OMAP_DSS_DISPLAY_SUSPENDED) {
++ if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
+ /* suspended is the same as disabled with venc */
+- display->state = OMAP_DSS_DISPLAY_DISABLED;
++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+ goto end;
+ }
+
+- venc_power_off(display);
++ venc_power_off(dssdev);
+
+- display->state = OMAP_DSS_DISPLAY_DISABLED;
++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+ end:
+ mutex_unlock(&venc.venc_lock);
+ }
+
+-static int venc_display_suspend(struct omap_display *display)
++static int venc_display_suspend(struct omap_dss_device *dssdev)
+ {
+ int r = 0;
+
+@@ -524,21 +594,21 @@ static int venc_display_suspend(struct omap_display *display)
+
+ mutex_lock(&venc.venc_lock);
+
+- if (display->state != OMAP_DSS_DISPLAY_ACTIVE) {
++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
+ r = -EINVAL;
+ goto err;
+ }
+
+- venc_power_off(display);
++ venc_power_off(dssdev);
+
+- display->state = OMAP_DSS_DISPLAY_SUSPENDED;
++ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+ err:
+ mutex_unlock(&venc.venc_lock);
+
+ return r;
+ }
+
+-static int venc_display_resume(struct omap_display *display)
++static int venc_display_resume(struct omap_dss_device *dssdev)
+ {
+ int r = 0;
+
+@@ -546,44 +616,44 @@ static int venc_display_resume(struct omap_display *display)
+
+ mutex_lock(&venc.venc_lock);
+
+- if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) {
++ if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) {
+ r = -EINVAL;
+ goto err;
+ }
+
+- venc_power_on(display);
++ venc_power_on(dssdev);
+
+- display->state = OMAP_DSS_DISPLAY_ACTIVE;
++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+ err:
+ mutex_unlock(&venc.venc_lock);
+
+ return r;
+ }
+
+-static void venc_get_timings(struct omap_display *display,
++static void venc_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+ {
+- *timings = venc_panel.timings;
++ *timings = dssdev->panel.timings;
+ }
+
+-static void venc_set_timings(struct omap_display *display,
++static void venc_set_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+ {
+ DSSDBG("venc_set_timings\n");
+
+ /* Reset WSS data when the TV standard changes. */
+- if (memcmp(&display->panel->timings, timings, sizeof(*timings)))
++ if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+ venc.wss_data = 0;
+
+- display->panel->timings = *timings;
+- if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
++ dssdev->panel.timings = *timings;
++ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+ /* turn the venc off and on to get new timings to use */
+- venc_disable_display(display);
+- venc_enable_display(display);
++ venc_disable_display(dssdev);
++ venc_enable_display(dssdev);
+ }
+ }
+
+-static int venc_check_timings(struct omap_display *display,
++static int venc_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+ {
+ DSSDBG("venc_check_timings\n");
+@@ -597,14 +667,13 @@ static int venc_check_timings(struct omap_display *display,
+ return -EINVAL;
+ }
+
+-static u32 venc_get_wss(struct omap_display *display)
++static u32 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_display *display,
+- u32 wss)
++static int venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
+ {
+ const struct venc_config *config;
+
+@@ -612,7 +681,7 @@ static int venc_set_wss(struct omap_display *display,
+
+ mutex_lock(&venc.venc_lock);
+
+- config = venc_timings_to_config(&display->panel->timings);
++ config = venc_timings_to_config(&dssdev->panel.timings);
+
+ /* Invert due to VENC_L21_WC_CTL:INV=1 */
+ venc.wss_data = (wss ^ 0xfffff) << 8;
+@@ -628,18 +697,19 @@ static int venc_set_wss(struct omap_display *display,
+ return 0;
+ }
+
+-void venc_init_display(struct omap_display *display)
++void venc_init_display(struct omap_dss_device *dssdev)
+ {
+- display->panel = &venc_panel;
+- display->enable = venc_enable_display;
+- display->disable = venc_disable_display;
+- display->suspend = venc_display_suspend;
+- display->resume = venc_display_resume;
+- display->get_timings = venc_get_timings;
+- display->set_timings = venc_set_timings;
+- display->check_timings = venc_check_timings;
+- display->get_wss = venc_get_wss;
+- display->set_wss = venc_set_wss;
++ DSSDBG("init_display\n");
++
++ dssdev->enable = venc_enable_display;
++ dssdev->disable = venc_disable_display;
++ dssdev->suspend = venc_display_suspend;
++ dssdev->resume = venc_display_resume;
++ dssdev->get_timings = venc_get_timings;
++ dssdev->set_timings = venc_set_timings;
++ dssdev->check_timings = venc_check_timings;
++ dssdev->get_wss = venc_get_wss;
++ dssdev->set_wss = venc_set_wss;
+ }
+
+ void venc_dump_regs(struct seq_file *s)
+diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
+index 57e6287..0ca57db 100644
+--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
++++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
+@@ -37,7 +37,7 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ struct omap_overlay *ovl;
+ struct omap_overlay_info info;
+ int r = 0;
+@@ -191,7 +191,7 @@ static int omapfb_update_window(struct fb_info *fbi,
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ u16 dw, dh;
+
+ if (!display)
+@@ -217,7 +217,7 @@ static int omapfb_set_update_mode(struct fb_info *fbi,
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ enum omap_dss_update_mode um;
+ int r;
+
+@@ -253,7 +253,7 @@ static int omapfb_get_update_mode(struct fb_info *fbi,
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ enum omap_dss_update_mode m;
+
+ if (!display || !display->get_update_mode)
+@@ -396,7 +396,7 @@ err:
+ static int omapfb_memory_read(struct fb_info *fbi,
+ struct omapfb_memory_read *mr)
+ {
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+ void *buf;
+@@ -484,7 +484,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+
+ union {
+ struct omapfb_update_window_old uwnd_o;
+diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
+index c3690b8..df5ede3 100644
+--- a/drivers/video/omap2/omapfb/omapfb-main.c
++++ b/drivers/video/omap2/omapfb/omapfb-main.c
+@@ -454,7 +454,7 @@ void set_fb_fix(struct fb_info *fbi)
+ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ unsigned long max_frame_size;
+ unsigned long line_size;
+ int xres_min, yres_min;
+@@ -615,7 +615,7 @@ static int omapfb_release(struct fb_info *fbi, int user)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+
+ DBG("Closing fb with plane index %d\n", ofbi->id);
+
+@@ -1057,7 +1057,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ int do_update = 0;
+ int r = 0;
+
+@@ -1263,7 +1263,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
+ unsigned long paddr)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+- struct omap_display *display;
++ struct omap_dss_device *display;
+ int bytespp;
+
+ display = fb2display(fbi);
+@@ -1307,6 +1307,9 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
+ size = w * h * bytespp;
+ }
+
++ if (!size)
++ return 0;
++
+ return omapfb_alloc_fbmem(fbi, size, paddr);
+ }
+
+@@ -1485,7 +1488,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ struct omapfb2_mem_region *rg = &ofbi->region;
+ unsigned long old_size = rg->size;
+ unsigned long old_paddr = rg->paddr;
+@@ -1563,7 +1566,7 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
+ {
+ struct fb_var_screeninfo *var = &fbi->var;
+ struct fb_fix_screeninfo *fix = &fbi->fix;
+- struct omap_display *display = fb2display(fbi);
++ struct omap_dss_device *display = fb2display(fbi);
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ int r = 0;
+
+@@ -1695,7 +1698,7 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
+ if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
+ fbdev->displays[i]->disable(fbdev->displays[i]);
+
+- omap_dss_put_display(fbdev->displays[i]);
++ omap_dss_put_device(fbdev->displays[i]);
+ }
+
+ dev_set_drvdata(fbdev->dev, NULL);
+@@ -1874,7 +1877,7 @@ int omapfb_mode_to_timings(const char *mode_str,
+ }
+ }
+
+-static int omapfb_set_def_mode(struct omap_display *display, char *mode_str)
++static int omapfb_set_def_mode(struct omap_dss_device *display, char *mode_str)
+ {
+ int r;
+ u8 bpp;
+@@ -1884,7 +1887,7 @@ static int omapfb_set_def_mode(struct omap_display *display, char *mode_str)
+ if (r)
+ return r;
+
+- display->panel->recommended_bpp = bpp;
++ display->panel.recommended_bpp = bpp;
+
+ if (!display->check_timings || !display->set_timings)
+ return -EINVAL;
+@@ -1909,7 +1912,7 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
+
+ while (!r && (this_opt = strsep(&options, ",")) != NULL) {
+ char *p, *display_str, *mode_str;
+- struct omap_display *display;
++ struct omap_dss_device *display;
+ int i;
+
+ p = strchr(this_opt, ':');
+@@ -1950,9 +1953,10 @@ static int omapfb_probe(struct platform_device *pdev)
+ {
+ struct omapfb2_device *fbdev = NULL;
+ int r = 0;
+- int i, t;
++ int i;
+ struct omap_overlay *ovl;
+- struct omap_display *def_display;
++ struct omap_dss_device *def_display;
++ struct omap_dss_device *dssdev;
+
+ DBG("omapfb_probe\n");
+
+@@ -1974,17 +1978,10 @@ static int omapfb_probe(struct platform_device *pdev)
+ platform_set_drvdata(pdev, fbdev);
+
+ fbdev->num_displays = 0;
+- t = omap_dss_get_num_displays();
+- for (i = 0; i < t; i++) {
+- struct omap_display *display;
+- display = omap_dss_get_display(i);
+- if (!display) {
+- dev_err(&pdev->dev, "can't get display %d\n", i);
+- r = -EINVAL;
+- goto cleanup;
+- }
+-
+- fbdev->displays[fbdev->num_displays++] = display;
++ dssdev = NULL;
++ for_each_dss_dev(dssdev) {
++ omap_dss_get_device(dssdev);
++ fbdev->displays[fbdev->num_displays++] = dssdev;
+ }
+
+ if (fbdev->num_displays == 0) {
+@@ -2005,8 +2002,8 @@ static int omapfb_probe(struct platform_device *pdev)
+ /* gfx overlay should be the default one. find a display
+ * connected to that, and use it as default display */
+ ovl = omap_dss_get_overlay(0);
+- if (ovl->manager && ovl->manager->display) {
+- def_display = ovl->manager->display;
++ if (ovl->manager && ovl->manager->device) {
++ def_display = ovl->manager->device;
+ } else {
+ dev_err(&pdev->dev, "cannot find default display\n");
+ r = -EINVAL;
+@@ -2063,7 +2060,7 @@ static int omapfb_probe(struct platform_device *pdev)
+ }
+
+ for (i = 0; i < fbdev->num_displays; i++) {
+- struct omap_display *display = fbdev->displays[i];
++ struct omap_dss_device *display = fbdev->displays[i];
+ u16 w, h;
+
+ if (!display->get_update_mode || !display->update)
+diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
+index e750bc0..6ca8ba6 100644
+--- a/drivers/video/omap2/omapfb/omapfb.h
++++ b/drivers/video/omap2/omapfb/omapfb.h
+@@ -78,7 +78,7 @@ struct omapfb2_device {
+ struct fb_info *fbs[10];
+
+ unsigned num_displays;
+- struct omap_display *displays[10];
++ struct omap_dss_device *displays[10];
+ unsigned num_overlays;
+ struct omap_overlay *overlays[10];
+ unsigned num_managers;
+@@ -115,7 +115,7 @@ int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
+ struct fb_var_screeninfo *var);
+
+ /* find the display connected to this fb, if any */
+-static inline struct omap_display *fb2display(struct fb_info *fbi)
++static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
+ {
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ int i;
+@@ -123,7 +123,7 @@ static inline struct omap_display *fb2display(struct fb_info *fbi)
+ /* XXX: returns the display connected to first attached overlay */
+ for (i = 0; i < ofbi->num_overlays; i++) {
+ if (ofbi->overlays[i]->manager)
+- return ofbi->overlays[i]->manager->display;
++ return ofbi->overlays[i]->manager->device;
+ }
+
+ return NULL;
+--
+1.6.2.4
+