linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4
@ 2011-05-04  7:38 Archit Taneja
  2011-05-04  7:38 ` [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi" Archit Taneja
                   ` (8 more replies)
  0 siblings, 9 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

OMAP4 has a DSI2 module, whose lanes are connected to the secondary lcd panel on
blaze and 4430sdp.
Modify dsi.c driver to register and work multiple DSI devices. Make the
necessary changes needed to introduce DSI2 PLL clocks.

Applies over:

https://gitorious.org/linux-omap-dss2/linux/commits/master

Can be tested on:

https://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone/commits/master

Note:
The patch to enable secondary lcd in through the board file is not a part of
this series. The patch in the above tree can be used to test DSI2 functionality:

TEMP: OMAP: DSS2: Add Secondary LCD data in board-4430sdp.c

Archit Taneja (9):
  OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to
    "omapdss_dsi"
  OMAP: DSS2: DSI: Add extra omap_dss_device argument in functions
    exported by dsi
  OMAP: DSS2: Remove omap_dss_device argument from dsi_pll_init()
  OMAP: DSS2: Pass platform_device as an argument in dsi functions
  OMAP: DSS2: DSI: Use platform_device pointer to get dsi data
  OMAP: DSS2: DSI: Pass pointer to struct to packet_sent_handler isrs
  OMAP4: DSS2: DSI: Changes for DSI2 on OMAP4
  OMAP: DSS2: DSI: Build a platform device instance for DSI2
  OMAP: DSS2: Taal: Use device name in backlight_device_register

 arch/arm/mach-omap2/board-3430sdp.c          |    2 +-
 arch/arm/mach-omap2/board-4430sdp.c          |    3 +-
 arch/arm/mach-omap2/board-devkit8000.c       |    2 +-
 arch/arm/mach-omap2/board-igep0020.c         |    2 +-
 arch/arm/mach-omap2/board-omap3beagle.c      |    2 +-
 arch/arm/mach-omap2/board-omap3evm.c         |    2 +-
 arch/arm/mach-omap2/board-omap3pandora.c     |    2 +-
 arch/arm/mach-omap2/board-omap3stalker.c     |    2 +-
 arch/arm/mach-omap2/board-overo.c            |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c |    2 +-
 arch/arm/mach-omap2/display.c                |    6 +-
 arch/arm/plat-omap/include/plat/display.h    |   39 +-
 drivers/video/omap2/displays/panel-taal.c    |  124 +-
 drivers/video/omap2/dss/core.c               |   14 +-
 drivers/video/omap2/dss/dispc.c              |   16 +-
 drivers/video/omap2/dss/dpi.c                |   36 +-
 drivers/video/omap2/dss/dsi.c                | 1734 +++++++++++++++-----------
 drivers/video/omap2/dss/dss.c                |   48 +-
 drivers/video/omap2/dss/dss.h                |   45 +-
 drivers/video/omap2/dss/dss_features.c       |    5 +-
 drivers/video/omap2/dss/dss_features.h       |    2 +
 21 files changed, 1234 insertions(+), 856 deletions(-)


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  9:40   ` Tony Lindgren
  2011-05-04  7:38 ` [PATCH 2/9] OMAP: DSS2: DSI: Add extra omap_dss_device argument in functions exported by dsi Archit Taneja
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Currently, there are 2 differently named platform devices generated for the 2
DSS DSI modules. In order to use the same driver, the dsi devices should be 2
instances of the same platform device.

Change the platform device name from "omapdss_dsi1" to omapdss_dsi". Propagate
this change across all omap board files which need to use this new name. Don't
create a DSI2 platform device instance for now.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 arch/arm/mach-omap2/board-3430sdp.c          |    2 +-
 arch/arm/mach-omap2/board-4430sdp.c          |    2 +-
 arch/arm/mach-omap2/board-devkit8000.c       |    2 +-
 arch/arm/mach-omap2/board-igep0020.c         |    2 +-
 arch/arm/mach-omap2/board-omap3beagle.c      |    2 +-
 arch/arm/mach-omap2/board-omap3evm.c         |    2 +-
 arch/arm/mach-omap2/board-omap3pandora.c     |    2 +-
 arch/arm/mach-omap2/board-omap3stalker.c     |    2 +-
 arch/arm/mach-omap2/board-overo.c            |    2 +-
 arch/arm/mach-omap2/board-zoom-peripherals.c |    2 +-
 arch/arm/mach-omap2/display.c                |    5 ++---
 drivers/video/omap2/dss/dsi.c                |   18 +++++++++---------
 12 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 9afd087..9da362b 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
 /* VPLL2 for digital video outputs */
 static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 570e83f..eafadb4 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
 };
 static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 65f9fde..81f9c64 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -279,7 +279,7 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
 
 static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 34cf982..279a553 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -487,7 +487,7 @@ static struct omap_dss_board_info igep2_dss_data = {
 
 static struct regulator_consumer_supply igep2_vpll2_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_init_data igep2_vpll2 = {
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 33007fd..8197d0d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -236,7 +236,7 @@ static struct regulator_consumer_supply beagle_vdac_supply =
 
 static struct regulator_consumer_supply beagle_vdvi_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static void __init beagle_display_init(void)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 5a1a916..e5b74f8 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -562,7 +562,7 @@ static struct regulator_init_data omap3_evm_vdac = {
 /* VPLL2 for digital video outputs */
 static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_init_data omap3_evm_vpll2 = {
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 07dba88..3554892 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -347,7 +347,7 @@ static struct regulator_consumer_supply pandora_vdda_dac_supply =
 static struct regulator_consumer_supply pandora_vdds_supplies[] = {
 	REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_consumer_supply pandora_vcc_lcd_supply =
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index a6e0b91..c369e8e 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -459,7 +459,7 @@ static struct regulator_init_data omap3_stalker_vdac = {
 /* VPLL2 for digital video outputs */
 static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_init_data omap3_stalker_vpll2 = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 59ca333..e281c7e 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -380,7 +380,7 @@ static struct regulator_consumer_supply overo_vdda_dac_supply =
 
 static struct regulator_consumer_supply overo_vdds_dsi_supply[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct mtd_partition overo_nand_partitions[] = {
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 8dee754..6f75d7a 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -228,7 +228,7 @@ static struct omap2_hsmmc_info mmc[] = {
 
 static struct regulator_consumer_supply zoom_vpll2_supplies[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
 };
 
 static struct regulator_consumer_supply zoom_vdda_dac_supply =
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index fa83eb3..f0e9cbf 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -74,7 +74,7 @@ static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
 	{ "dss_venc", "omapdss_venc", -1 },
-	{ "dss_dsi1", "omapdss_dsi1", -1 },
+	{ "dss_dsi1", "omapdss_dsi", 0 },
 };
 
 static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
@@ -82,8 +82,7 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
 	{ "dss_venc", "omapdss_venc", -1 },
-	{ "dss_dsi1", "omapdss_dsi1", -1 },
-	{ "dss_dsi2", "omapdss_dsi2", -1 },
+	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
 };
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 3d1dec3..6c528b7 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4128,8 +4128,8 @@ static void dsi_exit(void)
 	DSSDBG("omap_dsi_exit\n");
 }
 
-/* DSI1 HW IP initialisation */
-static int omap_dsi1hw_probe(struct platform_device *pdev)
+/* DSI HW IP initialisation */
+static int omap_dsihw_probe(struct platform_device *pdev)
 {
 	int r;
 	dsi.pdev = pdev;
@@ -4142,28 +4142,28 @@ err_dsi:
 	return r;
 }
 
-static int omap_dsi1hw_remove(struct platform_device *pdev)
+static int omap_dsihw_remove(struct platform_device *pdev)
 {
 	dsi_exit();
 	WARN_ON(dsi.scp_clk_refcount > 0);
 	return 0;
 }
 
-static struct platform_driver omap_dsi1hw_driver = {
-	.probe          = omap_dsi1hw_probe,
-	.remove         = omap_dsi1hw_remove,
+static struct platform_driver omap_dsihw_driver = {
+	.probe          = omap_dsihw_probe,
+	.remove         = omap_dsihw_remove,
 	.driver         = {
-		.name   = "omapdss_dsi1",
+		.name   = "omapdss_dsi",
 		.owner  = THIS_MODULE,
 	},
 };
 
 int dsi_init_platform_driver(void)
 {
-	return platform_driver_register(&omap_dsi1hw_driver);
+	return platform_driver_register(&omap_dsihw_driver);
 }
 
 void dsi_uninit_platform_driver(void)
 {
-	return platform_driver_unregister(&omap_dsi1hw_driver);
+	return platform_driver_unregister(&omap_dsihw_driver);
 }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 2/9] OMAP: DSS2: DSI: Add extra omap_dss_device argument in functions exported by dsi
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
  2011-05-04  7:38 ` [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi" Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  7:38 ` [PATCH 3/9] OMAP: DSS2: Remove omap_dss_device argument from dsi_pll_init() Archit Taneja
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Add pointer to omap_dss_device struct as an argument in the functions which
are exported to dsi panel drivers. This argument will tell the DSI driver
which DSI interface's data it has to choose.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 arch/arm/plat-omap/include/plat/display.h |   35 +++++---
 drivers/video/omap2/displays/panel-taal.c |  120 ++++++++++++++--------------
 drivers/video/omap2/dss/dsi.c             |   48 +++++++-----
 3 files changed, 110 insertions(+), 93 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index bd0f08e..d17a7a8 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -216,18 +216,26 @@ int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
 			     int hs_pol_inv, int vs_pol_inv, int extif_div);
 
 /* DSI */
-void dsi_bus_lock(void);
-void dsi_bus_unlock(void);
-int dsi_vc_dcs_write(int channel, u8 *data, int len);
-int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd);
-int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param);
-int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
-int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
-int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data);
-int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2);
-int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
-int dsi_vc_send_null(int channel);
-int dsi_vc_send_bta_sync(int channel);
+void dsi_bus_lock(struct omap_dss_device *dssdev);
+void dsi_bus_unlock(struct omap_dss_device *dssdev);
+int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+		int len);
+int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel,
+		u8 dcs_cmd);
+int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 param);
+int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
+		u8 *data, int len);
+int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 *buf, int buflen);
+int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 *data);
+int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 *data1, u8 *data2);
+int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
+		u16 len);
+int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
+int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
 
 /* Board specific data */
 struct omap_dss_board_info {
@@ -577,7 +585,8 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
 #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)
 
-void omapdss_dsi_vc_enable_hs(int channel, bool enable);
+void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
+		bool enable);
 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
 
 int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 78ad355..c5a61d0 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -271,7 +271,7 @@ static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
 	int r;
 	u8 buf[1];
 
-	r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1);
+	r = dsi_vc_dcs_read(td->dssdev, td->channel, dcs_cmd, buf, 1);
 
 	if (r < 0)
 		return r;
@@ -283,7 +283,7 @@ static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data)
 
 static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd)
 {
-	return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1);
+	return dsi_vc_dcs_write(td->dssdev, td->channel, &dcs_cmd, 1);
 }
 
 static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
@@ -291,7 +291,7 @@ static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param)
 	u8 buf[2];
 	buf[0] = dcs_cmd;
 	buf[1] = param;
-	return dsi_vc_dcs_write(td->channel, buf, 2);
+	return dsi_vc_dcs_write(td->dssdev, td->channel, buf, 2);
 }
 
 static int taal_sleep_in(struct taal_data *td)
@@ -303,7 +303,7 @@ static int taal_sleep_in(struct taal_data *td)
 	hw_guard_wait(td);
 
 	cmd = DCS_SLEEP_IN;
-	r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1);
+	r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
 	if (r)
 		return r;
 
@@ -409,7 +409,7 @@ static int taal_set_update_window(struct taal_data *td,
 	buf[3] = (x2 >> 8) & 0xff;
 	buf[4] = (x2 >> 0) & 0xff;
 
-	r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
+	r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
 	if (r)
 		return r;
 
@@ -419,11 +419,11 @@ static int taal_set_update_window(struct taal_data *td,
 	buf[3] = (y2 >> 8) & 0xff;
 	buf[4] = (y2 >> 0) & 0xff;
 
-	r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf));
+	r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, buf, sizeof(buf));
 	if (r)
 		return r;
 
-	dsi_vc_send_bta_sync(td->channel);
+	dsi_vc_send_bta_sync(td->dssdev, td->channel);
 
 	return r;
 }
@@ -507,7 +507,7 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
 	if (r)
 		goto err;
 
-	omapdss_dsi_vc_enable_hs(td->channel, true);
+	omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
 
 	r = _taal_enable_te(dssdev, true);
 	if (r)
@@ -565,13 +565,13 @@ static int taal_bl_update_status(struct backlight_device *dev)
 
 	if (td->use_dsi_bl) {
 		if (td->enabled) {
-			dsi_bus_lock();
+			dsi_bus_lock(dssdev);
 
 			r = taal_wake_up(dssdev);
 			if (!r)
 				r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level);
 
-			dsi_bus_unlock();
+			dsi_bus_unlock(dssdev);
 		} else {
 			r = 0;
 		}
@@ -632,13 +632,13 @@ static ssize_t taal_num_errors_show(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock();
+		dsi_bus_lock(dssdev);
 
 		r = taal_wake_up(dssdev);
 		if (!r)
 			r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors);
 
-		dsi_bus_unlock();
+		dsi_bus_unlock(dssdev);
 	} else {
 		r = -ENODEV;
 	}
@@ -662,13 +662,13 @@ static ssize_t taal_hw_revision_show(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock();
+		dsi_bus_lock(dssdev);
 
 		r = taal_wake_up(dssdev);
 		if (!r)
 			r = taal_get_id(td, &id1, &id2, &id3);
 
-		dsi_bus_unlock();
+		dsi_bus_unlock(dssdev);
 	} else {
 		r = -ENODEV;
 	}
@@ -728,7 +728,7 @@ static ssize_t store_cabc_mode(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock();
+		dsi_bus_lock(dssdev);
 
 		if (!td->cabc_broken) {
 			r = taal_wake_up(dssdev);
@@ -740,7 +740,7 @@ static ssize_t store_cabc_mode(struct device *dev,
 				goto err;
 		}
 
-		dsi_bus_unlock();
+		dsi_bus_unlock(dssdev);
 	}
 
 	td->cabc_mode = i;
@@ -749,7 +749,7 @@ static ssize_t store_cabc_mode(struct device *dev,
 
 	return count;
 err:
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 	return r;
 }
@@ -825,14 +825,14 @@ static ssize_t taal_store_ulps(struct device *dev,
 	mutex_lock(&td->lock);
 
 	if (td->enabled) {
-		dsi_bus_lock();
+		dsi_bus_lock(dssdev);
 
 		if (t)
 			r = taal_enter_ulps(dssdev);
 		else
 			r = taal_wake_up(dssdev);
 
-		dsi_bus_unlock();
+		dsi_bus_unlock(dssdev);
 	}
 
 	mutex_unlock(&td->lock);
@@ -876,9 +876,9 @@ static ssize_t taal_store_ulps_timeout(struct device *dev,
 
 	if (td->enabled) {
 		/* taal_wake_up will restart the timer */
-		dsi_bus_lock();
+		dsi_bus_lock(dssdev);
 		r = taal_wake_up(dssdev);
-		dsi_bus_unlock();
+		dsi_bus_unlock(dssdev);
 	}
 
 	mutex_unlock(&td->lock);
@@ -1165,7 +1165,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 
 	taal_hw_reset(dssdev);
 
-	omapdss_dsi_vc_enable_hs(td->channel, false);
+	omapdss_dsi_vc_enable_hs(dssdev, td->channel, false);
 
 	r = taal_sleep_out(td);
 	if (r)
@@ -1222,7 +1222,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 		td->intro_printed = true;
 	}
 
-	omapdss_dsi_vc_enable_hs(td->channel, true);
+	omapdss_dsi_vc_enable_hs(dssdev, td->channel, true);
 
 	return 0;
 err:
@@ -1281,11 +1281,11 @@ static int taal_enable(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	r = taal_power_on(dssdev);
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 
 	if (r)
 		goto err;
@@ -1314,14 +1314,14 @@ static void taal_disable(struct omap_dss_device *dssdev)
 	taal_cancel_ulps_work(dssdev);
 	taal_cancel_esd_work(dssdev);
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
 		taal_wake_up(dssdev);
 		taal_power_off(dssdev);
 	}
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
 
@@ -1345,13 +1345,13 @@ static int taal_suspend(struct omap_dss_device *dssdev)
 	taal_cancel_ulps_work(dssdev);
 	taal_cancel_esd_work(dssdev);
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	r = taal_wake_up(dssdev);
 	if (!r)
 		taal_power_off(dssdev);
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
@@ -1377,11 +1377,11 @@ static int taal_resume(struct omap_dss_device *dssdev)
 		goto err;
 	}
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	r = taal_power_on(dssdev);
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 
 	if (r) {
 		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
@@ -1402,7 +1402,7 @@ static void taal_framedone_cb(int err, void *data)
 {
 	struct omap_dss_device *dssdev = data;
 	dev_dbg(&dssdev->dev, "framedone, err %d\n", err);
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 }
 
 static irqreturn_t taal_te_isr(int irq, void *data)
@@ -1430,7 +1430,7 @@ static irqreturn_t taal_te_isr(int irq, void *data)
 	return IRQ_HANDLED;
 err:
 	dev_err(&dssdev->dev, "start update failed\n");
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	return IRQ_HANDLED;
 }
 
@@ -1443,7 +1443,7 @@ static void taal_te_timeout_work_callback(struct work_struct *work)
 	dev_err(&dssdev->dev, "TE not received for 250ms!\n");
 
 	atomic_set(&td->do_update, 0);
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 }
 
 static int taal_update(struct omap_dss_device *dssdev,
@@ -1456,7 +1456,7 @@ static int taal_update(struct omap_dss_device *dssdev,
 	dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
 
 	mutex_lock(&td->lock);
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	r = taal_wake_up(dssdev);
 	if (r)
@@ -1495,7 +1495,7 @@ static int taal_update(struct omap_dss_device *dssdev,
 	mutex_unlock(&td->lock);
 	return 0;
 err:
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 	return r;
 }
@@ -1507,8 +1507,8 @@ static int taal_sync(struct omap_dss_device *dssdev)
 	dev_dbg(&dssdev->dev, "sync\n");
 
 	mutex_lock(&td->lock);
-	dsi_bus_lock();
-	dsi_bus_unlock();
+	dsi_bus_lock(dssdev);
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 
 	dev_dbg(&dssdev->dev, "sync done\n");
@@ -1546,7 +1546,7 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 	if (td->te_enabled == enable)
 		goto end;
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	if (td->enabled) {
 		r = taal_wake_up(dssdev);
@@ -1560,13 +1560,13 @@ static int taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 
 	td->te_enabled = enable;
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 end:
 	mutex_unlock(&td->lock);
 
 	return 0;
 err:
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 
 	return r;
@@ -1596,7 +1596,7 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 	if (td->rotate == rotate)
 		goto end;
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	if (td->enabled) {
 		r = taal_wake_up(dssdev);
@@ -1610,12 +1610,12 @@ static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 
 	td->rotate = rotate;
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 end:
 	mutex_unlock(&td->lock);
 	return 0;
 err:
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 	return r;
 }
@@ -1644,7 +1644,7 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
 	if (td->mirror == enable)
 		goto end;
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 	if (td->enabled) {
 		r = taal_wake_up(dssdev);
 		if (r)
@@ -1657,12 +1657,12 @@ static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
 
 	td->mirror = enable;
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 end:
 	mutex_unlock(&td->lock);
 	return 0;
 err:
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 	return r;
 }
@@ -1692,7 +1692,7 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
 		goto err1;
 	}
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	r = taal_wake_up(dssdev);
 	if (r)
@@ -1708,11 +1708,11 @@ static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
 	if (r)
 		goto err2;
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 	return 0;
 err2:
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 err1:
 	mutex_unlock(&td->lock);
 	return r;
@@ -1742,7 +1742,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 			dssdev->panel.timings.x_res *
 			dssdev->panel.timings.y_res * 3);
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	r = taal_wake_up(dssdev);
 	if (r)
@@ -1758,7 +1758,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 
 	taal_set_update_window(td, x, y, w, h);
 
-	r = dsi_vc_set_max_rx_packet_size(td->channel, plen);
+	r = dsi_vc_set_max_rx_packet_size(dssdev, td->channel, plen);
 	if (r)
 		goto err2;
 
@@ -1766,7 +1766,7 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 		u8 dcs_cmd = first ? 0x2e : 0x3e;
 		first = 0;
 
-		r = dsi_vc_dcs_read(td->channel, dcs_cmd,
+		r = dsi_vc_dcs_read(dssdev, td->channel, dcs_cmd,
 				buf + buf_used, size - buf_used);
 
 		if (r < 0) {
@@ -1792,9 +1792,9 @@ static int taal_memory_read(struct omap_dss_device *dssdev,
 	r = buf_used;
 
 err3:
-	dsi_vc_set_max_rx_packet_size(td->channel, 1);
+	dsi_vc_set_max_rx_packet_size(dssdev, td->channel, 1);
 err2:
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 err1:
 	mutex_unlock(&td->lock);
 	return r;
@@ -1813,11 +1813,11 @@ static void taal_ulps_work(struct work_struct *work)
 		return;
 	}
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	taal_enter_ulps(dssdev);
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 	mutex_unlock(&td->lock);
 }
 
@@ -1837,7 +1837,7 @@ static void taal_esd_work(struct work_struct *work)
 		return;
 	}
 
-	dsi_bus_lock();
+	dsi_bus_lock(dssdev);
 
 	r = taal_wake_up(dssdev);
 	if (r) {
@@ -1879,7 +1879,7 @@ static void taal_esd_work(struct work_struct *work)
 			goto err;
 	}
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 
 	taal_queue_esd_work(dssdev);
 
@@ -1890,7 +1890,7 @@ err:
 
 	taal_panel_reset(dssdev);
 
-	dsi_bus_unlock();
+	dsi_bus_unlock(dssdev);
 
 	taal_queue_esd_work(dssdev);
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6c528b7..471d1f0 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -354,13 +354,13 @@ void dsi_restore_context(void)
 {
 }
 
-void dsi_bus_lock(void)
+void dsi_bus_lock(struct omap_dss_device *dssdev)
 {
 	down(&dsi.bus_lock);
 }
 EXPORT_SYMBOL(dsi_bus_lock);
 
-void dsi_bus_unlock(void)
+void dsi_bus_unlock(struct omap_dss_device *dssdev)
 {
 	up(&dsi.bus_lock);
 }
@@ -2473,7 +2473,8 @@ static int dsi_vc_config_vp(int channel)
 }
 
 
-void omapdss_dsi_vc_enable_hs(int channel, bool enable)
+void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
+		bool enable)
 {
 	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
 
@@ -2587,7 +2588,7 @@ static int dsi_vc_send_bta(int channel)
 	return 0;
 }
 
-int dsi_vc_send_bta_sync(int channel)
+int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 {
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r = 0;
@@ -2751,14 +2752,15 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
 	return 0;
 }
 
-int dsi_vc_send_null(int channel)
+int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
 {
 	u8 nullpkg[] = {0, 0, 0, 0};
 	return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0);
 }
 EXPORT_SYMBOL(dsi_vc_send_null);
 
-int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len)
+int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
+		u8 *data, int len)
 {
 	int r;
 
@@ -2780,15 +2782,16 @@ int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len)
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
 
-int dsi_vc_dcs_write(int channel, u8 *data, int len)
+int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+		int len)
 {
 	int r;
 
-	r = dsi_vc_dcs_write_nosync(channel, data, len);
+	r = dsi_vc_dcs_write_nosync(dssdev, channel, data, len);
 	if (r)
 		goto err;
 
-	r = dsi_vc_send_bta_sync(channel);
+	r = dsi_vc_send_bta_sync(dssdev, channel);
 	if (r)
 		goto err;
 
@@ -2807,22 +2810,24 @@ err:
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write);
 
-int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd)
+int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd)
 {
-	return dsi_vc_dcs_write(channel, &dcs_cmd, 1);
+	return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_0);
 
-int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param)
+int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 param)
 {
 	u8 buf[2];
 	buf[0] = dcs_cmd;
 	buf[1] = param;
-	return dsi_vc_dcs_write(channel, buf, 2);
+	return dsi_vc_dcs_write(dssdev, channel, buf, 2);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_1);
 
-int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
+int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 *buf, int buflen)
 {
 	u32 val;
 	u8 dt;
@@ -2835,7 +2840,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
 	if (r)
 		goto err;
 
-	r = dsi_vc_send_bta_sync(channel);
+	r = dsi_vc_send_bta_sync(dssdev, channel);
 	if (r)
 		goto err;
 
@@ -2929,11 +2934,12 @@ err:
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read);
 
-int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
+int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 *data)
 {
 	int r;
 
-	r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1);
+	r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, data, 1);
 
 	if (r < 0)
 		return r;
@@ -2945,12 +2951,13 @@ int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data)
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read_1);
 
-int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2)
+int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 *data1, u8 *data2)
 {
 	u8 buf[2];
 	int r;
 
-	r = dsi_vc_dcs_read(channel, dcs_cmd, buf, 2);
+	r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, buf, 2);
 
 	if (r < 0)
 		return r;
@@ -2965,7 +2972,8 @@ int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2)
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read_2);
 
-int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
+int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
+		u16 len)
 {
 	return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
 			len, 0);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 3/9] OMAP: DSS2: Remove omap_dss_device argument from dsi_pll_init()
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
  2011-05-04  7:38 ` [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi" Archit Taneja
  2011-05-04  7:38 ` [PATCH 2/9] OMAP: DSS2: DSI: Add extra omap_dss_device argument in functions exported by dsi Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  7:38 ` [PATCH 4/9] OMAP: DSS2: Pass platform_device as an argument in dsi functions Archit Taneja
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

The function dsi_pll_init() has omap_dss_device argument which is
not used. Remove this argument.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dpi.c |    2 +-
 drivers/video/omap2/dss/dsi.c |    5 ++---
 drivers/video/omap2/dss/dss.h |    3 +--
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index e442b09..426177b 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -189,7 +189,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_clk_enable(DSS_CLK_SYSCK);
-		r = dsi_pll_init(dssdev, 0, 1);
+		r = dsi_pll_init(0, 1);
 		if (r)
 			goto err3;
 	}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 471d1f0..22dd57c 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1470,8 +1470,7 @@ err:
 	return r;
 }
 
-int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
-		bool enable_hsdiv)
+int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
 {
 	int r = 0;
 	enum dsi_pll_power_state pwstate;
@@ -3745,7 +3744,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
 {
 	int r;
 
-	r = dsi_pll_init(dssdev, true, true);
+	r = dsi_pll_init(true, true);
 	if (r)
 		goto err0;
 
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index eea5c7d..40764e0 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -292,8 +292,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
 int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
 		struct dsi_clock_info *cinfo,
 		struct dispc_clock_info *dispc_cinfo);
-int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
-		bool enable_hsdiv);
+int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv);
 void dsi_pll_uninit(bool disconnect_lanes);
 void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
 		u32 fifo_size, enum omap_burst_size *burst_size,
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 4/9] OMAP: DSS2: Pass platform_device as an argument in dsi functions
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
                   ` (2 preceding siblings ...)
  2011-05-04  7:38 ` [PATCH 3/9] OMAP: DSS2: Remove omap_dss_device argument from dsi_pll_init() Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  7:38 ` [PATCH 5/9] OMAP: DSS2: DSI: Use platform_device pointer to get dsi data Archit Taneja
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

The DSI interface is represented as a platform device, using the DSI platform
driver(dsi.c). The current DSI driver design is capable of running only one
instance of a DSI device. On OMAP4, there are 2 very similar DSI modules which
can be represented as instances of "omapdss_dsi" platform device.

Add member "module" in "dssdev.phy.dsi" that tells us which DSI module's lanes
the panel is connected to. Modify dsi.c functions to take the device's
platform_device struct pointer, provide functions dsi_get_dsi_device() and
dsi_get_dsi_device_module() take the panel's omap_dss_device and module number
respectively, and return the platform_device pointer. Currently, the dsi struct
is declared globally and is accessed when dsi data is needed. The new pdev
argument will be used later to provide the platform device's dsi related data.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 arch/arm/plat-omap/include/plat/display.h |    2 +
 drivers/video/omap2/dss/dispc.c           |    8 +-
 drivers/video/omap2/dss/dpi.c             |   30 +-
 drivers/video/omap2/dss/dsi.c             |  934 ++++++++++++++++-------------
 drivers/video/omap2/dss/dss.c             |   12 +-
 drivers/video/omap2/dss/dss.h             |   31 +-
 drivers/video/omap2/dss/dss_features.h    |    1 +
 7 files changed, 573 insertions(+), 445 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index d17a7a8..6305ff6 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -419,6 +419,8 @@ struct omap_dss_device {
 			u8 data2_lane;
 			u8 data2_pol;
 
+			int module;
+
 			bool ext_te;
 			u8 ext_te_gpio;
 		} dsi;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d728904..7927660 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2353,6 +2353,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
 
 unsigned long dispc_fclk_rate(void)
 {
+	struct platform_device *dsidev;
 	unsigned long r = 0;
 
 	switch (dss_get_dispc_clk_source()) {
@@ -2360,7 +2361,8 @@ unsigned long dispc_fclk_rate(void)
 		r = dss_clk_get_rate(DSS_CLK_FCK);
 		break;
 	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
-		r = dsi_get_pll_hsdiv_dispc_rate();
+		dsidev = dsi_get_dsi_device_module(0);
+		r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
 		break;
 	default:
 		BUG();
@@ -2371,6 +2373,7 @@ unsigned long dispc_fclk_rate(void)
 
 unsigned long dispc_lclk_rate(enum omap_channel channel)
 {
+	struct platform_device *dsidev;
 	int lcd;
 	unsigned long r;
 	u32 l;
@@ -2384,7 +2387,8 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
 		r = dss_clk_get_rate(DSS_CLK_FCK);
 		break;
 	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
-		r = dsi_get_pll_hsdiv_dispc_rate();
+		dsidev = dsi_get_dsi_device_module(0);
+		r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
 		break;
 	default:
 		BUG();
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 426177b..97d7985 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -37,8 +37,18 @@
 
 static struct {
 	struct regulator *vdds_dsi_reg;
+	struct platform_device *dsidev;
 } dpi;
 
+static struct platform_device *dpi_get_dsi_device(enum omap_dss_clk_source clk)
+{
+	int dsi_module;
+
+	dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1;
+
+	return dsi_get_dsi_device_module(dsi_module);
+}
+
 static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 {
 	if (dssdev->clocks.dispc.dispc_fclk_src ==
@@ -58,12 +68,12 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft,
 	struct dispc_clock_info dispc_cinfo;
 	int r;
 
-	r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo,
-			&dispc_cinfo);
+	r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req,
+			&dsi_cinfo, &dispc_cinfo);
 	if (r)
 		return r;
 
-	r = dsi_pll_set_clock_div(&dsi_cinfo);
+	r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo);
 	if (r)
 		return r;
 
@@ -189,7 +199,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_clk_enable(DSS_CLK_SYSCK);
-		r = dsi_pll_init(0, 1);
+		r = dsi_pll_init(dpi.dsidev, 0, 1);
 		if (r)
 			goto err3;
 	}
@@ -206,7 +216,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 err4:
 	if (dpi_use_dsi_pll(dssdev))
-		dsi_pll_uninit(true);
+		dsi_pll_uninit(dpi.dsidev, true);
 err3:
 	if (dpi_use_dsi_pll(dssdev))
 		dss_clk_disable(DSS_CLK_SYSCK);
@@ -227,7 +237,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
-		dsi_pll_uninit(true);
+		dsi_pll_uninit(dpi.dsidev, true);
 		dss_clk_disable(DSS_CLK_SYSCK);
 	}
 
@@ -272,7 +282,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		struct dsi_clock_info dsi_cinfo;
-		r = dsi_pll_calc_clock_div_pck(is_tft,
+		r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft,
 				timings->pixel_clock * 1000,
 				&dsi_cinfo, &dispc_cinfo);
 
@@ -319,6 +329,12 @@ int dpi_init_display(struct omap_dss_device *dssdev)
 		dpi.vdds_dsi_reg = vdds_dsi;
 	}
 
+	if (dpi_use_dsi_pll(dssdev)) {
+		enum omap_dss_clk_source dispc_fclk_src =
+			dssdev->clocks.dispc.dispc_fclk_src;
+		dpi.dsidev = dpi_get_dsi_device(dispc_fclk_src);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 22dd57c..c0e272b 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -101,11 +101,11 @@ struct dsi_reg { u16 idx; };
 #define DSI_PLL_CONFIGURATION1		DSI_REG(0x300 + 0x000C)
 #define DSI_PLL_CONFIGURATION2		DSI_REG(0x300 + 0x0010)
 
-#define REG_GET(idx, start, end) \
-	FLD_GET(dsi_read_reg(idx), start, end)
+#define REG_GET(dsidev, idx, start, end) \
+	FLD_GET(dsi_read_reg(dsidev, idx), start, end)
 
-#define REG_FLD_MOD(idx, val, start, end) \
-	dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end))
+#define REG_FLD_MOD(dsidev, idx, val, start, end) \
+	dsi_write_reg(dsidev, idx, FLD_MOD(dsi_read_reg(dsidev, idx), val, start, end))
 
 /* Global interrupts */
 #define DSI_IRQ_VC0		(1 << 0)
@@ -257,8 +257,7 @@ struct dsi_isr_tables {
 	struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
 };
 
-static struct
-{
+static struct dsi_data {
 	struct platform_device *pdev;
 	void __iomem	*base;
 	int irq;
@@ -330,17 +329,31 @@ static struct
 	unsigned scp_clk_refcount;
 } dsi;
 
+static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
+
 #ifdef DEBUG
 static unsigned int dsi_perf;
 module_param_named(dsi_perf, dsi_perf, bool, 0644);
 #endif
 
-static inline void dsi_write_reg(const struct dsi_reg idx, u32 val)
+static inline struct platform_device *dsi_get_dsi_device(struct omap_dss_device *dssdev)
+{
+	return dsi_pdev_map[dssdev->phy.dsi.module];
+}
+
+struct platform_device *dsi_get_dsi_device_module(int module)
+{
+	return dsi_pdev_map[module];
+}
+
+static inline void dsi_write_reg(struct platform_device *dsidev,
+		const struct dsi_reg idx, u32 val)
 {
 	__raw_writel(val, dsi.base + idx.idx);
 }
 
-static inline u32 dsi_read_reg(const struct dsi_reg idx)
+static inline u32 dsi_read_reg(struct platform_device *dsidev,
+		const struct dsi_reg idx)
 {
 	return __raw_readl(dsi.base + idx.idx);
 }
@@ -366,7 +379,7 @@ void dsi_bus_unlock(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL(dsi_bus_unlock);
 
-static bool dsi_bus_is_locked(void)
+static bool dsi_bus_is_locked(struct platform_device *dsidev)
 {
 	return dsi.bus_lock.count == 0;
 }
@@ -376,12 +389,12 @@ static void dsi_completion_handler(void *data, u32 mask)
 	complete((struct completion *)data);
 }
 
-static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
-		int value)
+static inline int wait_for_bit_change(struct platform_device *dsidev,
+		const struct dsi_reg idx, int bitnum, int value)
 {
 	int t = 100000;
 
-	while (REG_GET(idx, bitnum, bitnum) != value) {
+	while (REG_GET(dsidev, idx, bitnum, bitnum) != value) {
 		if (--t == 0)
 			return !value;
 	}
@@ -390,17 +403,17 @@ static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
 }
 
 #ifdef DEBUG
-static void dsi_perf_mark_setup(void)
+static void dsi_perf_mark_setup(struct platform_device *dsidev)
 {
 	dsi.perf_setup_time = ktime_get();
 }
 
-static void dsi_perf_mark_start(void)
+static void dsi_perf_mark_start(struct platform_device *dsidev)
 {
 	dsi.perf_start_time = ktime_get();
 }
 
-static void dsi_perf_show(const char *name)
+static void dsi_perf_show(struct platform_device *dsidev, const char *name)
 {
 	ktime_t t, setup_time, trans_time;
 	u32 total_bytes;
@@ -438,9 +451,9 @@ static void dsi_perf_show(const char *name)
 			total_bytes * 1000 / total_us);
 }
 #else
-#define dsi_perf_mark_setup()
-#define dsi_perf_mark_start()
-#define dsi_perf_show(x)
+#define dsi_perf_mark_setup(x)
+#define dsi_perf_mark_start(x)
+#define dsi_perf_show(x, y)
 #endif
 
 static void print_irq_status(u32 status)
@@ -546,7 +559,8 @@ static void print_irq_status_cio(u32 status)
 }
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
+static void dsi_collect_irq_stats(struct platform_device *dsidev, u32 irqstatus,
+		u32 *vcstatus, u32 ciostatus)
 {
 	int i;
 
@@ -563,12 +577,13 @@ static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
 	spin_unlock(&dsi.irq_stats_lock);
 }
 #else
-#define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus)
+#define dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus)
 #endif
 
 static int debug_irq;
 
-static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus)
+static void dsi_handle_irq_errors(struct platform_device *dsidev, u32 irqstatus,
+		u32 *vcstatus, u32 ciostatus)
 {
 	int i;
 
@@ -638,12 +653,15 @@ static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
 
 static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
 {
+	struct platform_device *dsidev;
 	u32 irqstatus, vcstatus[4], ciostatus;
 	int i;
 
+	dsidev = (struct platform_device *) arg;
+
 	spin_lock(&dsi.irq_lock);
 
-	irqstatus = dsi_read_reg(DSI_IRQSTATUS);
+	irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
 
 	/* IRQ is not for us */
 	if (!irqstatus) {
@@ -651,9 +669,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
 		return IRQ_NONE;
 	}
 
-	dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
+	dsi_write_reg(dsidev, DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
 	/* flush posted write */
-	dsi_read_reg(DSI_IRQSTATUS);
+	dsi_read_reg(dsidev, DSI_IRQSTATUS);
 
 	for (i = 0; i < 4; ++i) {
 		if ((irqstatus & (1 << i)) == 0) {
@@ -661,19 +679,19 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
 			continue;
 		}
 
-		vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i));
+		vcstatus[i] = dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
 
-		dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]);
+		dsi_write_reg(dsidev, DSI_VC_IRQSTATUS(i), vcstatus[i]);
 		/* flush posted write */
-		dsi_read_reg(DSI_VC_IRQSTATUS(i));
+		dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i));
 	}
 
 	if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
-		ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
+		ciostatus = dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS);
 
-		dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
+		dsi_write_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
 		/* flush posted write */
-		dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
+		dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS);
 	} else {
 		ciostatus = 0;
 	}
@@ -691,15 +709,16 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
 
 	dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus);
 
-	dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus);
+	dsi_handle_irq_errors(dsidev, irqstatus, vcstatus, ciostatus);
 
-	dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus);
+	dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus);
 
 	return IRQ_HANDLED;
 }
 
 /* dsi.irq_lock has to be locked by the caller */
-static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array,
+static void _omap_dsi_configure_irqs(struct platform_device *dsidev,
+		struct dsi_isr_data *isr_array,
 		unsigned isr_array_size, u32 default_mask,
 		const struct dsi_reg enable_reg,
 		const struct dsi_reg status_reg)
@@ -720,47 +739,47 @@ static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array,
 		mask |= isr_data->mask;
 	}
 
-	old_mask = dsi_read_reg(enable_reg);
+	old_mask = dsi_read_reg(dsidev, enable_reg);
 	/* clear the irqstatus for newly enabled irqs */
-	dsi_write_reg(status_reg, (mask ^ old_mask) & mask);
-	dsi_write_reg(enable_reg, mask);
+	dsi_write_reg(dsidev, status_reg, (mask ^ old_mask) & mask);
+	dsi_write_reg(dsidev, enable_reg, mask);
 
 	/* flush posted writes */
-	dsi_read_reg(enable_reg);
-	dsi_read_reg(status_reg);
+	dsi_read_reg(dsidev, enable_reg);
+	dsi_read_reg(dsidev, status_reg);
 }
 
 /* dsi.irq_lock has to be locked by the caller */
-static void _omap_dsi_set_irqs(void)
+static void _omap_dsi_set_irqs(struct platform_device *dsidev)
 {
 	u32 mask = DSI_IRQ_ERROR_MASK;
 #ifdef DSI_CATCH_MISSING_TE
 	mask |= DSI_IRQ_TE_TRIGGER;
 #endif
-	_omap_dsi_configure_irqs(dsi.isr_tables.isr_table,
+	_omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table,
 			ARRAY_SIZE(dsi.isr_tables.isr_table), mask,
 			DSI_IRQENABLE, DSI_IRQSTATUS);
 }
 
 /* dsi.irq_lock has to be locked by the caller */
-static void _omap_dsi_set_irqs_vc(int vc)
+static void _omap_dsi_set_irqs_vc(struct platform_device *dsidev, int vc)
 {
-	_omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc],
+	_omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_vc[vc],
 			ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]),
 			DSI_VC_IRQ_ERROR_MASK,
 			DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
 }
 
 /* dsi.irq_lock has to be locked by the caller */
-static void _omap_dsi_set_irqs_cio(void)
+static void _omap_dsi_set_irqs_cio(struct platform_device *dsidev)
 {
-	_omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio,
+	_omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_cio,
 			ARRAY_SIZE(dsi.isr_tables.isr_table_cio),
 			DSI_CIO_IRQ_ERROR_MASK,
 			DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
 }
 
-static void _dsi_initialize_irq(void)
+static void _dsi_initialize_irq(struct platform_device *dsidev)
 {
 	unsigned long flags;
 	int vc;
@@ -769,10 +788,10 @@ static void _dsi_initialize_irq(void)
 
 	memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables));
 
-	_omap_dsi_set_irqs();
+	_omap_dsi_set_irqs(dsidev);
 	for (vc = 0; vc < 4; ++vc)
-		_omap_dsi_set_irqs_vc(vc);
-	_omap_dsi_set_irqs_cio();
+		_omap_dsi_set_irqs_vc(dsidev, vc);
+	_omap_dsi_set_irqs_cio(dsidev);
 
 	spin_unlock_irqrestore(&dsi.irq_lock, flags);
 }
@@ -833,7 +852,8 @@ static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
 	return -EINVAL;
 }
 
-static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
+static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr,
+		void *arg, u32 mask)
 {
 	unsigned long flags;
 	int r;
@@ -844,14 +864,15 @@ static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
 			ARRAY_SIZE(dsi.isr_tables.isr_table));
 
 	if (r == 0)
-		_omap_dsi_set_irqs();
+		_omap_dsi_set_irqs(dsidev);
 
 	spin_unlock_irqrestore(&dsi.irq_lock, flags);
 
 	return r;
 }
 
-static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
+static int dsi_unregister_isr(struct platform_device *dsidev,
+		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
 	unsigned long flags;
 	int r;
@@ -862,15 +883,15 @@ static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask)
 			ARRAY_SIZE(dsi.isr_tables.isr_table));
 
 	if (r == 0)
-		_omap_dsi_set_irqs();
+		_omap_dsi_set_irqs(dsidev);
 
 	spin_unlock_irqrestore(&dsi.irq_lock, flags);
 
 	return r;
 }
 
-static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
-		u32 mask)
+static int dsi_register_isr_vc(struct platform_device *dsidev, int channel,
+		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
 	unsigned long flags;
 	int r;
@@ -882,15 +903,15 @@ static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
 			ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
 
 	if (r == 0)
-		_omap_dsi_set_irqs_vc(channel);
+		_omap_dsi_set_irqs_vc(dsidev, channel);
 
 	spin_unlock_irqrestore(&dsi.irq_lock, flags);
 
 	return r;
 }
 
-static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
-		u32 mask)
+static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel,
+		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
 	unsigned long flags;
 	int r;
@@ -902,14 +923,15 @@ static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg,
 			ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
 
 	if (r == 0)
-		_omap_dsi_set_irqs_vc(channel);
+		_omap_dsi_set_irqs_vc(dsidev, channel);
 
 	spin_unlock_irqrestore(&dsi.irq_lock, flags);
 
 	return r;
 }
 
-static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
+static int dsi_register_isr_cio(struct platform_device *dsidev,
+		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
 	unsigned long flags;
 	int r;
@@ -920,14 +942,15 @@ static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
 			ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
 
 	if (r == 0)
-		_omap_dsi_set_irqs_cio();
+		_omap_dsi_set_irqs_cio(dsidev);
 
 	spin_unlock_irqrestore(&dsi.irq_lock, flags);
 
 	return r;
 }
 
-static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
+static int dsi_unregister_isr_cio(struct platform_device *dsidev,
+		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
 	unsigned long flags;
 	int r;
@@ -938,14 +961,14 @@ static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask)
 			ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
 
 	if (r == 0)
-		_omap_dsi_set_irqs_cio();
+		_omap_dsi_set_irqs_cio(dsidev);
 
 	spin_unlock_irqrestore(&dsi.irq_lock, flags);
 
 	return r;
 }
 
-static u32 dsi_get_errors(void)
+static u32 dsi_get_errors(struct platform_device *dsidev)
 {
 	unsigned long flags;
 	u32 e;
@@ -966,7 +989,8 @@ static inline void enable_clocks(bool enable)
 }
 
 /* source clock for DSI PLL. this could also be PCLKFREE */
-static inline void dsi_enable_pll_clock(bool enable)
+static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
+		bool enable)
 {
 	if (enable)
 		dss_clk_enable(DSS_CLK_SYSCK);
@@ -974,13 +998,13 @@ static inline void dsi_enable_pll_clock(bool enable)
 		dss_clk_disable(DSS_CLK_SYSCK);
 
 	if (enable && dsi.pll_locked) {
-		if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
+		if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
 			DSSERR("cannot lock PLL when enabling clocks\n");
 	}
 }
 
 #ifdef DEBUG
-static void _dsi_print_reset_status(void)
+static void _dsi_print_reset_status(struct platform_device *dsidev)
 {
 	u32 l;
 	int b0, b1, b2;
@@ -991,14 +1015,14 @@ static void _dsi_print_reset_status(void)
 	/* A dummy read using the SCP interface to any DSIPHY register is
 	 * required after DSIPHY reset to complete the reset of the DSI complex
 	 * I/O. */
-	l = dsi_read_reg(DSI_DSIPHY_CFG5);
+	l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
 
 	printk(KERN_DEBUG "DSI resets: ");
 
-	l = dsi_read_reg(DSI_PLL_STATUS);
+	l = dsi_read_reg(dsidev, DSI_PLL_STATUS);
 	printk("PLL (%d) ", FLD_GET(l, 0, 0));
 
-	l = dsi_read_reg(DSI_COMPLEXIO_CFG1);
+	l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
 	printk("CIO (%d) ", FLD_GET(l, 29, 29));
 
 	if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
@@ -1011,7 +1035,7 @@ static void _dsi_print_reset_status(void)
 		b2 = 26;
 	}
 
-	l = dsi_read_reg(DSI_DSIPHY_CFG5);
+	l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
 	printk("PHY (%x%x%x, %d, %d, %d)\n",
 			FLD_GET(l, b0, b0),
 			FLD_GET(l, b1, b1),
@@ -1021,17 +1045,17 @@ static void _dsi_print_reset_status(void)
 			FLD_GET(l, 31, 31));
 }
 #else
-#define _dsi_print_reset_status()
+#define _dsi_print_reset_status(x)
 #endif
 
-static inline int dsi_if_enable(bool enable)
+static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
 {
 	DSSDBG("dsi_if_enable(%d)\n", enable);
 
 	enable = enable ? 1 : 0;
-	REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */
+	REG_FLD_MOD(dsidev, DSI_CTRL, enable, 0, 0); /* IF_EN */
 
-	if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) {
+	if (wait_for_bit_change(dsidev, DSI_CTRL, 0, enable) != enable) {
 			DSSERR("Failed to set dsi_if_enable to %d\n", enable);
 			return -EIO;
 	}
@@ -1039,22 +1063,22 @@ static inline int dsi_if_enable(bool enable)
 	return 0;
 }
 
-unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
+unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
 {
 	return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk;
 }
 
-static unsigned long dsi_get_pll_hsdiv_dsi_rate(void)
+static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
 {
 	return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk;
 }
 
-static unsigned long dsi_get_txbyteclkhs(void)
+static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
 {
 	return dsi.current_cinfo.clkin4ddr / 16;
 }
 
-static unsigned long dsi_fclk_rate(void)
+static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
 {
 	unsigned long r;
 
@@ -1063,7 +1087,7 @@ static unsigned long dsi_fclk_rate(void)
 		r = dss_clk_get_rate(DSS_CLK_FCK);
 	} else {
 		/* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */
-		r = dsi_get_pll_hsdiv_dsi_rate();
+		r = dsi_get_pll_hsdiv_dsi_rate(dsidev);
 	}
 
 	return r;
@@ -1071,6 +1095,7 @@ static unsigned long dsi_fclk_rate(void)
 
 static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	unsigned long dsi_fclk;
 	unsigned lp_clk_div;
 	unsigned long lp_clk;
@@ -1080,7 +1105,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
 	if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max)
 		return -EINVAL;
 
-	dsi_fclk = dsi_fclk_rate();
+	dsi_fclk = dsi_fclk_rate(dsidev);
 
 	lp_clk = dsi_fclk / 2 / lp_clk_div;
 
@@ -1088,25 +1113,26 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
 	dsi.current_cinfo.lp_clk = lp_clk;
 	dsi.current_cinfo.lp_clk_div = lp_clk_div;
 
-	REG_FLD_MOD(DSI_CLK_CTRL, lp_clk_div, 12, 0);   /* LP_CLK_DIVISOR */
+	/* LP_CLK_DIVISOR */
+	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
 
-	REG_FLD_MOD(DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0,
-			21, 21);		/* LP_RX_SYNCHRO_ENABLE */
+	/* LP_RX_SYNCHRO_ENABLE */
+	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, 21, 21);
 
 	return 0;
 }
 
-static void dsi_enable_scp_clk(void)
+static void dsi_enable_scp_clk(struct platform_device *dsidev)
 {
 	if (dsi.scp_clk_refcount++ == 0)
-		REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */
+		REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */
 }
 
-static void dsi_disable_scp_clk(void)
+static void dsi_disable_scp_clk(struct platform_device *dsidev)
 {
 	WARN_ON(dsi.scp_clk_refcount == 0);
 	if (--dsi.scp_clk_refcount == 0)
-		REG_FLD_MOD(DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */
+		REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */
 }
 
 enum dsi_pll_power_state {
@@ -1116,7 +1142,8 @@ enum dsi_pll_power_state {
 	DSI_PLL_POWER_ON_DIV	= 0x3,
 };
 
-static int dsi_pll_power(enum dsi_pll_power_state state)
+static int dsi_pll_power(struct platform_device *dsidev,
+		enum dsi_pll_power_state state)
 {
 	int t = 0;
 
@@ -1125,10 +1152,11 @@ static int dsi_pll_power(enum dsi_pll_power_state state)
 			state == DSI_PLL_POWER_ON_DIV)
 		state = DSI_PLL_POWER_ON_ALL;
 
-	REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30);	/* PLL_PWR_CMD */
+	/* PLL_PWR_CMD */
+	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, state, 31, 30);
 
 	/* PLL_PWR_STATUS */
-	while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) {
+	while (FLD_GET(dsi_read_reg(dsidev, DSI_CLK_CTRL), 29, 28) != state) {
 		if (++t > 1000) {
 			DSSERR("Failed to set DSI PLL power mode to %d\n",
 					state);
@@ -1195,8 +1223,8 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
-		struct dsi_clock_info *dsi_cinfo,
+int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
+		unsigned long req_pck, struct dsi_clock_info *dsi_cinfo,
 		struct dispc_clock_info *dispc_cinfo)
 {
 	struct dsi_clock_info cur, best;
@@ -1332,7 +1360,8 @@ found:
 	return 0;
 }
 
-int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
+int dsi_pll_set_clock_div(struct platform_device *dsidev,
+		struct dsi_clock_info *cinfo)
 {
 	int r = 0;
 	u32 l;
@@ -1393,9 +1422,10 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
 	dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
 			&regm_dsi_end);
 
-	REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
+	/* DSI_PLL_AUTOMODE = manual */
+	REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0);
 
-	l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
+	l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1);
 	l = FLD_MOD(l, 1, 0, 0);		/* DSI_PLL_STOPMODE */
 	/* DSI_PLL_REGN */
 	l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
@@ -1407,7 +1437,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
 	/* DSIPROTO_CLOCK_DIV */
 	l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
 			regm_dsi_start, regm_dsi_end);
-	dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
+	dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
 
 	BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
 
@@ -1419,7 +1449,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
 			0x7;
 	}
 
-	l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
+	l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
 
 	if (dss_has_feature(FEAT_DSI_PLL_FREQSEL))
 		l = FLD_MOD(l, f, 4, 1);	/* DSI_PLL_FREQSEL */
@@ -1430,17 +1460,17 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
 	l = FLD_MOD(l, 1, 13, 13);		/* DSI_PLL_REFEN */
 	l = FLD_MOD(l, 0, 14, 14);		/* DSIPHY_CLKINEN */
 	l = FLD_MOD(l, 1, 20, 20);		/* DSI_HSDIVBYPASS */
-	dsi_write_reg(DSI_PLL_CONFIGURATION2, l);
+	dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
 
-	REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0);	/* DSI_PLL_GO */
+	REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0);	/* DSI_PLL_GO */
 
-	if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) {
+	if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) {
 		DSSERR("dsi pll go bit not going down.\n");
 		r = -EIO;
 		goto err;
 	}
 
-	if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) {
+	if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) {
 		DSSERR("cannot lock PLL\n");
 		r = -EIO;
 		goto err;
@@ -1448,7 +1478,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
 
 	dsi.pll_locked = 1;
 
-	l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
+	l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
 	l = FLD_MOD(l, 0, 0, 0);	/* DSI_PLL_IDLE */
 	l = FLD_MOD(l, 0, 5, 5);	/* DSI_PLL_PLLLPMODE */
 	l = FLD_MOD(l, 0, 6, 6);	/* DSI_PLL_LOWCURRSTBY */
@@ -1463,14 +1493,15 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo)
 	l = FLD_MOD(l, 1, 18, 18);	/* DSI_PROTO_CLOCK_EN */
 	l = FLD_MOD(l, 0, 19, 19);	/* DSI_PROTO_CLOCK_PWDN */
 	l = FLD_MOD(l, 0, 20, 20);	/* DSI_HSDIVBYPASS */
-	dsi_write_reg(DSI_PLL_CONFIGURATION2, l);
+	dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
 
 	DSSDBG("PLL config done\n");
 err:
 	return r;
 }
 
-int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
+int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
+		bool enable_hsdiv)
 {
 	int r = 0;
 	enum dsi_pll_power_state pwstate;
@@ -1491,11 +1522,11 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
 	}
 
 	enable_clocks(1);
-	dsi_enable_pll_clock(1);
+	dsi_enable_pll_clock(dsidev, 1);
 	/*
 	 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
 	 */
-	dsi_enable_scp_clk();
+	dsi_enable_scp_clk(dsidev);
 
 	if (!dsi.vdds_dsi_enabled) {
 		r = regulator_enable(dsi.vdds_dsi_reg);
@@ -1507,7 +1538,7 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
 	/* XXX PLL does not come out of reset without this... */
 	dispc_pck_free_enable(1);
 
-	if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) {
+	if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 0, 1) != 1) {
 		DSSERR("PLL not coming out of reset.\n");
 		r = -ENODEV;
 		dispc_pck_free_enable(0);
@@ -1527,7 +1558,7 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
 	else
 		pwstate = DSI_PLL_POWER_OFF;
 
-	r = dsi_pll_power(pwstate);
+	r = dsi_pll_power(dsidev, pwstate);
 
 	if (r)
 		goto err1;
@@ -1541,31 +1572,32 @@ err1:
 		dsi.vdds_dsi_enabled = false;
 	}
 err0:
-	dsi_disable_scp_clk();
+	dsi_disable_scp_clk(dsidev);
 	enable_clocks(0);
-	dsi_enable_pll_clock(0);
+	dsi_enable_pll_clock(dsidev, 0);
 	return r;
 }
 
-void dsi_pll_uninit(bool disconnect_lanes)
+void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
 {
 	dsi.pll_locked = 0;
-	dsi_pll_power(DSI_PLL_POWER_OFF);
+	dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
 	if (disconnect_lanes) {
 		WARN_ON(!dsi.vdds_dsi_enabled);
 		regulator_disable(dsi.vdds_dsi_reg);
 		dsi.vdds_dsi_enabled = false;
 	}
 
-	dsi_disable_scp_clk();
+	dsi_disable_scp_clk(dsidev);
 	enable_clocks(0);
-	dsi_enable_pll_clock(0);
+	dsi_enable_pll_clock(dsidev, 0);
 
 	DSSDBG("PLL uninit done\n");
 }
 
 void dsi_dump_clocks(struct seq_file *s)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
 	struct dsi_clock_info *cinfo = &dsi.current_cinfo;
 	enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
 
@@ -1606,12 +1638,12 @@ void dsi_dump_clocks(struct seq_file *s)
 			dss_get_generic_clk_source_name(dsi_clk_src),
 			dss_feat_get_clk_source_name(dsi_clk_src));
 
-	seq_printf(s,	"DSI_FCLK\t%lu\n", dsi_fclk_rate());
+	seq_printf(s,	"DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
 
 	seq_printf(s,	"DDR_CLK\t\t%lu\n",
 			cinfo->clkin4ddr / 4);
 
-	seq_printf(s,	"TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs());
+	seq_printf(s,	"TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev));
 
 	seq_printf(s,	"LP_CLK\t\t%lu\n", cinfo->lp_clk);
 
@@ -1714,10 +1746,12 @@ void dsi_dump_irqs(struct seq_file *s)
 
 void dsi_dump_regs(struct seq_file *s)
 {
-#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
+	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
+
+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r))
 
 	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
-	dsi_enable_scp_clk();
+	dsi_enable_scp_clk(dsidev);
 
 	DUMPREG(DSI_REVISION);
 	DUMPREG(DSI_SYSCONFIG);
@@ -1789,7 +1823,7 @@ void dsi_dump_regs(struct seq_file *s)
 	DUMPREG(DSI_PLL_CONFIGURATION1);
 	DUMPREG(DSI_PLL_CONFIGURATION2);
 
-	dsi_disable_scp_clk();
+	dsi_disable_scp_clk(dsidev);
 	dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
 #undef DUMPREG
 }
@@ -1800,15 +1834,16 @@ enum dsi_cio_power_state {
 	DSI_COMPLEXIO_POWER_ULPS	= 0x2,
 };
 
-static int dsi_cio_power(enum dsi_cio_power_state state)
+static int dsi_cio_power(struct platform_device *dsidev,
+		enum dsi_cio_power_state state)
 {
 	int t = 0;
 
 	/* PWR_CMD */
-	REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27);
+	REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG1, state, 28, 27);
 
 	/* PWR_STATUS */
-	while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) {
+	while (FLD_GET(dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1), 26, 25) != state) {
 		if (++t > 1000) {
 			DSSERR("failed to set complexio power state to "
 					"%d\n", state);
@@ -1822,6 +1857,7 @@ static int dsi_cio_power(enum dsi_cio_power_state state)
 
 static void dsi_set_lane_config(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	u32 r;
 
 	int clk_lane   = dssdev->phy.dsi.clk_lane;
@@ -1831,14 +1867,14 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev)
 	int data1_pol  = dssdev->phy.dsi.data1_pol;
 	int data2_pol  = dssdev->phy.dsi.data2_pol;
 
-	r = dsi_read_reg(DSI_COMPLEXIO_CFG1);
+	r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
 	r = FLD_MOD(r, clk_lane, 2, 0);
 	r = FLD_MOD(r, clk_pol, 3, 3);
 	r = FLD_MOD(r, data1_lane, 6, 4);
 	r = FLD_MOD(r, data1_pol, 7, 7);
 	r = FLD_MOD(r, data2_lane, 10, 8);
 	r = FLD_MOD(r, data2_pol, 11, 11);
-	dsi_write_reg(DSI_COMPLEXIO_CFG1, r);
+	dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
 
 	/* The configuration of the DSI complex I/O (number of data lanes,
 	   position, differential order) should not be changed while
@@ -1852,27 +1888,27 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev)
 	   DSI complex I/O configuration is unknown. */
 
 	/*
-	REG_FLD_MOD(DSI_CTRL, 1, 0, 0);
-	REG_FLD_MOD(DSI_CTRL, 0, 0, 0);
-	REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20);
-	REG_FLD_MOD(DSI_CTRL, 1, 0, 0);
+	REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
+	REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0);
+	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20);
+	REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
 	*/
 }
 
-static inline unsigned ns2ddr(unsigned ns)
+static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
 {
 	/* convert time in ns to ddr ticks, rounding up */
 	unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4;
 	return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
 }
 
-static inline unsigned ddr2ns(unsigned ddr)
+static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
 {
 	unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4;
 	return ddr * 1000 * 1000 / (ddr_clk / 1000);
 }
 
-static void dsi_cio_timings(void)
+static void dsi_cio_timings(struct platform_device *dsidev)
 {
 	u32 r;
 	u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit;
@@ -1884,67 +1920,68 @@ static void dsi_cio_timings(void)
 	/* 1 * DDR_CLK = 2 * UI */
 
 	/* min 40ns + 4*UI	max 85ns + 6*UI */
-	ths_prepare = ns2ddr(70) + 2;
+	ths_prepare = ns2ddr(dsidev, 70) + 2;
 
 	/* min 145ns + 10*UI */
-	ths_prepare_ths_zero = ns2ddr(175) + 2;
+	ths_prepare_ths_zero = ns2ddr(dsidev, 175) + 2;
 
 	/* min max(8*UI, 60ns+4*UI) */
-	ths_trail = ns2ddr(60) + 5;
+	ths_trail = ns2ddr(dsidev, 60) + 5;
 
 	/* min 100ns */
-	ths_exit = ns2ddr(145);
+	ths_exit = ns2ddr(dsidev, 145);
 
 	/* tlpx min 50n */
-	tlpx_half = ns2ddr(25);
+	tlpx_half = ns2ddr(dsidev, 25);
 
 	/* min 60ns */
-	tclk_trail = ns2ddr(60) + 2;
+	tclk_trail = ns2ddr(dsidev, 60) + 2;
 
 	/* min 38ns, max 95ns */
-	tclk_prepare = ns2ddr(65);
+	tclk_prepare = ns2ddr(dsidev, 65);
 
 	/* min tclk-prepare + tclk-zero = 300ns */
-	tclk_zero = ns2ddr(260);
+	tclk_zero = ns2ddr(dsidev, 260);
 
 	DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n",
-		ths_prepare, ddr2ns(ths_prepare),
-		ths_prepare_ths_zero, ddr2ns(ths_prepare_ths_zero));
+		ths_prepare, ddr2ns(dsidev, ths_prepare),
+		ths_prepare_ths_zero, ddr2ns(dsidev, ths_prepare_ths_zero));
 	DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n",
-			ths_trail, ddr2ns(ths_trail),
-			ths_exit, ddr2ns(ths_exit));
+			ths_trail, ddr2ns(dsidev, ths_trail),
+			ths_exit, ddr2ns(dsidev, ths_exit));
 
 	DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), "
 			"tclk_zero %u (%uns)\n",
-			tlpx_half, ddr2ns(tlpx_half),
-			tclk_trail, ddr2ns(tclk_trail),
-			tclk_zero, ddr2ns(tclk_zero));
+			tlpx_half, ddr2ns(dsidev, tlpx_half),
+			tclk_trail, ddr2ns(dsidev, tclk_trail),
+			tclk_zero, ddr2ns(dsidev, tclk_zero));
 	DSSDBG("tclk_prepare %u (%uns)\n",
-			tclk_prepare, ddr2ns(tclk_prepare));
+			tclk_prepare, ddr2ns(dsidev, tclk_prepare));
 
 	/* program timings */
 
-	r = dsi_read_reg(DSI_DSIPHY_CFG0);
+	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
 	r = FLD_MOD(r, ths_prepare, 31, 24);
 	r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16);
 	r = FLD_MOD(r, ths_trail, 15, 8);
 	r = FLD_MOD(r, ths_exit, 7, 0);
-	dsi_write_reg(DSI_DSIPHY_CFG0, r);
+	dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r);
 
-	r = dsi_read_reg(DSI_DSIPHY_CFG1);
+	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
 	r = FLD_MOD(r, tlpx_half, 22, 16);
 	r = FLD_MOD(r, tclk_trail, 15, 8);
 	r = FLD_MOD(r, tclk_zero, 7, 0);
-	dsi_write_reg(DSI_DSIPHY_CFG1, r);
+	dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r);
 
-	r = dsi_read_reg(DSI_DSIPHY_CFG2);
+	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
 	r = FLD_MOD(r, tclk_prepare, 7, 0);
-	dsi_write_reg(DSI_DSIPHY_CFG2, r);
+	dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r);
 }
 
 static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
 		enum dsi_lane lanes)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int clk_lane   = dssdev->phy.dsi.clk_lane;
 	int data1_lane = dssdev->phy.dsi.data1_lane;
 	int data2_lane = dssdev->phy.dsi.data2_lane;
@@ -1977,22 +2014,27 @@ static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
 	 */
 
 	/* Set the lane override configuration */
-	REG_FLD_MOD(DSI_DSIPHY_CFG10, l, 22, 17); /* REGLPTXSCPDAT4TO0DXDY */
+
+	/* REGLPTXSCPDAT4TO0DXDY */
+	REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, l, 22, 17);
 
 	/* Enable lane override */
-	REG_FLD_MOD(DSI_DSIPHY_CFG10, 1, 27, 27); /* ENLPTXSCPDAT */
+
+	/* ENLPTXSCPDAT */
+	REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 1, 27, 27);
 }
 
-static void dsi_cio_disable_lane_override(void)
+static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
 {
 	/* Disable lane override */
-	REG_FLD_MOD(DSI_DSIPHY_CFG10, 0, 27, 27); /* ENLPTXSCPDAT */
+	REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 27, 27); /* ENLPTXSCPDAT */
 	/* Reset the lane override configuration */
-	REG_FLD_MOD(DSI_DSIPHY_CFG10, 0, 22, 17); /* REGLPTXSCPDAT4TO0DXDY */
+	REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17); /* REGLPTXSCPDAT4TO0DXDY */
 }
 
 static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int t;
 	int bits[3];
 	bool in_use[3];
@@ -2024,7 +2066,7 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
 		int i;
 		int ok;
 
-		l = dsi_read_reg(DSI_DSIPHY_CFG5);
+		l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
 
 		ok = 0;
 		for (i = 0; i < 3; ++i) {
@@ -2052,6 +2094,7 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
 
 static int dsi_cio_init(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int r;
 	u32 l;
 
@@ -2060,14 +2103,14 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 	if (dsi.dsi_mux_pads)
 		dsi.dsi_mux_pads(true);
 
-	dsi_enable_scp_clk();
+	dsi_enable_scp_clk(dsidev);
 
 	/* A dummy read using the SCP interface to any DSIPHY register is
 	 * required after DSIPHY reset to complete the reset of the DSI complex
 	 * I/O. */
-	dsi_read_reg(DSI_DSIPHY_CFG5);
+	dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
 
-	if (wait_for_bit_change(DSI_DSIPHY_CFG5, 30, 1) != 1) {
+	if (wait_for_bit_change(dsidev, DSI_DSIPHY_CFG5, 30, 1) != 1) {
 		DSSERR("CIO SCP Clock domain not coming out of reset.\n");
 		r = -EIO;
 		goto err_scp_clk_dom;
@@ -2076,12 +2119,12 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 	dsi_set_lane_config(dssdev);
 
 	/* set TX STOP MODE timer to maximum for this operation */
-	l = dsi_read_reg(DSI_TIMING1);
+	l = dsi_read_reg(dsidev, DSI_TIMING1);
 	l = FLD_MOD(l, 1, 15, 15);	/* FORCE_TX_STOP_MODE_IO */
 	l = FLD_MOD(l, 1, 14, 14);	/* STOP_STATE_X16_IO */
 	l = FLD_MOD(l, 1, 13, 13);	/* STOP_STATE_X4_IO */
 	l = FLD_MOD(l, 0x1fff, 12, 0);	/* STOP_STATE_COUNTER_IO */
-	dsi_write_reg(DSI_TIMING1, l);
+	dsi_write_reg(dsidev, DSI_TIMING1, l);
 
 	if (dsi.ulps_enabled) {
 		DSSDBG("manual ulps exit\n");
@@ -2098,19 +2141,19 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 				DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P);
 	}
 
-	r = dsi_cio_power(DSI_COMPLEXIO_POWER_ON);
+	r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
 	if (r)
 		goto err_cio_pwr;
 
-	if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 29, 1) != 1) {
+	if (wait_for_bit_change(dsidev, DSI_COMPLEXIO_CFG1, 29, 1) != 1) {
 		DSSERR("CIO PWR clock domain not coming out of reset.\n");
 		r = -ENODEV;
 		goto err_cio_pwr_dom;
 	}
 
-	dsi_if_enable(true);
-	dsi_if_enable(false);
-	REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
+	dsi_if_enable(dsidev, true);
+	dsi_if_enable(dsidev, false);
+	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
 
 	r = dsi_cio_wait_tx_clk_esc_reset(dssdev);
 	if (r)
@@ -2124,13 +2167,13 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 
 		/* Disable the override. The lanes should be set to Mark-11
 		 * state by the HW */
-		dsi_cio_disable_lane_override();
+		dsi_cio_disable_lane_override(dsidev);
 	}
 
 	/* FORCE_TX_STOP_MODE_IO */
-	REG_FLD_MOD(DSI_TIMING1, 0, 15, 15);
+	REG_FLD_MOD(dsidev, DSI_TIMING1, 0, 15, 15);
 
-	dsi_cio_timings();
+	dsi_cio_timings(dsidev);
 
 	dsi.ulps_enabled = false;
 
@@ -2139,32 +2182,32 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 	return 0;
 
 err_tx_clk_esc_rst:
-	REG_FLD_MOD(DSI_CLK_CTRL, 0, 20, 20); /* LP_CLK_ENABLE */
+	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 20, 20); /* LP_CLK_ENABLE */
 err_cio_pwr_dom:
-	dsi_cio_power(DSI_COMPLEXIO_POWER_OFF);
+	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
 err_cio_pwr:
 	if (dsi.ulps_enabled)
-		dsi_cio_disable_lane_override();
+		dsi_cio_disable_lane_override(dsidev);
 err_scp_clk_dom:
-	dsi_disable_scp_clk();
+	dsi_disable_scp_clk(dsidev);
 	if (dsi.dsi_mux_pads)
 		dsi.dsi_mux_pads(false);
 	return r;
 }
 
-static void dsi_cio_uninit(void)
+static void dsi_cio_uninit(struct platform_device *dsidev)
 {
-	dsi_cio_power(DSI_COMPLEXIO_POWER_OFF);
-	dsi_disable_scp_clk();
+	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
+	dsi_disable_scp_clk(dsidev);
 	if (dsi.dsi_mux_pads)
 		dsi.dsi_mux_pads(false);
 }
 
-static int _dsi_wait_reset(void)
+static int _dsi_wait_reset(struct platform_device *dsidev)
 {
 	int t = 0;
 
-	while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) {
+	while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) {
 		if (++t > 5) {
 			DSSERR("soft reset failed\n");
 			return -ENODEV;
@@ -2175,14 +2218,15 @@ static int _dsi_wait_reset(void)
 	return 0;
 }
 
-static int _dsi_reset(void)
+static int _dsi_reset(struct platform_device *dsidev)
 {
 	/* Soft reset */
-	REG_FLD_MOD(DSI_SYSCONFIG, 1, 1, 1);
-	return _dsi_wait_reset();
+	REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1);
+	return _dsi_wait_reset(dsidev);
 }
 
-static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
+static void dsi_config_tx_fifo(struct platform_device *dsidev,
+		enum fifo_size size1, enum fifo_size size2,
 		enum fifo_size size3, enum fifo_size size4)
 {
 	u32 r = 0;
@@ -2209,10 +2253,11 @@ static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
 		add += size;
 	}
 
-	dsi_write_reg(DSI_TX_FIFO_VC_SIZE, r);
+	dsi_write_reg(dsidev, DSI_TX_FIFO_VC_SIZE, r);
 }
 
-static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2,
+static void dsi_config_rx_fifo(struct platform_device *dsidev,
+		enum fifo_size size1, enum fifo_size size2,
 		enum fifo_size size3, enum fifo_size size4)
 {
 	u32 r = 0;
@@ -2239,18 +2284,18 @@ static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2,
 		add += size;
 	}
 
-	dsi_write_reg(DSI_RX_FIFO_VC_SIZE, r);
+	dsi_write_reg(dsidev, DSI_RX_FIFO_VC_SIZE, r);
 }
 
-static int dsi_force_tx_stop_mode_io(void)
+static int dsi_force_tx_stop_mode_io(struct platform_device *dsidev)
 {
 	u32 r;
 
-	r = dsi_read_reg(DSI_TIMING1);
+	r = dsi_read_reg(dsidev, DSI_TIMING1);
 	r = FLD_MOD(r, 1, 15, 15);	/* FORCE_TX_STOP_MODE_IO */
-	dsi_write_reg(DSI_TIMING1, r);
+	dsi_write_reg(dsidev, DSI_TIMING1, r);
 
-	if (wait_for_bit_change(DSI_TIMING1, 15, 0) != 0) {
+	if (wait_for_bit_change(dsidev, DSI_TIMING1, 15, 0) != 0) {
 		DSSERR("TX_STOP bit not going down\n");
 		return -EIO;
 	}
@@ -2258,21 +2303,22 @@ static int dsi_force_tx_stop_mode_io(void)
 	return 0;
 }
 
-static bool dsi_vc_is_enabled(int channel)
+static bool dsi_vc_is_enabled(struct platform_device *dsidev, int channel)
 {
-	return REG_GET(DSI_VC_CTRL(channel), 0, 0);
+	return REG_GET(dsidev, DSI_VC_CTRL(channel), 0, 0);
 }
 
 static void dsi_packet_sent_handler_vp(void *data, u32 mask)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
 	const int channel = dsi.update_channel;
 	u8 bit = dsi.te_enabled ? 30 : 31;
 
-	if (REG_GET(DSI_VC_TE(channel), bit, bit) == 0)
+	if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit) == 0)
 		complete((struct completion *)data);
 }
 
-static int dsi_sync_vc_vp(int channel)
+static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel)
 {
 	int r = 0;
 	u8 bit;
@@ -2281,13 +2327,13 @@ static int dsi_sync_vc_vp(int channel)
 
 	bit = dsi.te_enabled ? 30 : 31;
 
-	r = dsi_register_isr_vc(channel, dsi_packet_sent_handler_vp,
+	r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
 		&completion, DSI_VC_IRQ_PACKET_SENT);
 	if (r)
 		goto err0;
 
 	/* Wait for completion only if TE_EN/TE_START is still set */
-	if (REG_GET(DSI_VC_TE(channel), bit, bit)) {
+	if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit)) {
 		if (wait_for_completion_timeout(&completion,
 				msecs_to_jiffies(10)) == 0) {
 			DSSERR("Failed to complete previous frame transfer\n");
@@ -2296,38 +2342,39 @@ static int dsi_sync_vc_vp(int channel)
 		}
 	}
 
-	dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_vp,
+	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
 		&completion, DSI_VC_IRQ_PACKET_SENT);
 
 	return 0;
 err1:
-	dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_vp, &completion,
-		DSI_VC_IRQ_PACKET_SENT);
+	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
+		&completion, DSI_VC_IRQ_PACKET_SENT);
 err0:
 	return r;
 }
 
 static void dsi_packet_sent_handler_l4(void *data, u32 mask)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
 	const int channel = dsi.update_channel;
 
-	if (REG_GET(DSI_VC_CTRL(channel), 5, 5) == 0)
+	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5) == 0)
 		complete((struct completion *)data);
 }
 
-static int dsi_sync_vc_l4(int channel)
+static int dsi_sync_vc_l4(struct platform_device *dsidev, int channel)
 {
 	int r = 0;
 
 	DECLARE_COMPLETION_ONSTACK(completion);
 
-	r = dsi_register_isr_vc(channel, dsi_packet_sent_handler_l4,
+	r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
 		&completion, DSI_VC_IRQ_PACKET_SENT);
 	if (r)
 		goto err0;
 
 	/* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */
-	if (REG_GET(DSI_VC_CTRL(channel), 5, 5)) {
+	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5)) {
 		if (wait_for_completion_timeout(&completion,
 				msecs_to_jiffies(10)) == 0) {
 			DSSERR("Failed to complete previous l4 transfer\n");
@@ -2336,46 +2383,47 @@ static int dsi_sync_vc_l4(int channel)
 		}
 	}
 
-	dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_l4,
+	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
 		&completion, DSI_VC_IRQ_PACKET_SENT);
 
 	return 0;
 err1:
-	dsi_unregister_isr_vc(channel, dsi_packet_sent_handler_l4,
+	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
 		&completion, DSI_VC_IRQ_PACKET_SENT);
 err0:
 	return r;
 }
 
-static int dsi_sync_vc(int channel)
+static int dsi_sync_vc(struct platform_device *dsidev, int channel)
 {
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	WARN_ON(in_interrupt());
 
-	if (!dsi_vc_is_enabled(channel))
+	if (!dsi_vc_is_enabled(dsidev, channel))
 		return 0;
 
 	switch (dsi.vc[channel].mode) {
 	case DSI_VC_MODE_VP:
-		return dsi_sync_vc_vp(channel);
+		return dsi_sync_vc_vp(dsidev, channel);
 	case DSI_VC_MODE_L4:
-		return dsi_sync_vc_l4(channel);
+		return dsi_sync_vc_l4(dsidev, channel);
 	default:
 		BUG();
 	}
 }
 
-static int dsi_vc_enable(int channel, bool enable)
+static int dsi_vc_enable(struct platform_device *dsidev, int channel,
+		bool enable)
 {
 	DSSDBG("dsi_vc_enable channel %d, enable %d\n",
 			channel, enable);
 
 	enable = enable ? 1 : 0;
 
-	REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 0, 0);
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 0, 0);
 
-	if (wait_for_bit_change(DSI_VC_CTRL(channel), 0, enable) != enable) {
+	if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 0, enable) != enable) {
 			DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
 			return -EIO;
 	}
@@ -2383,13 +2431,13 @@ static int dsi_vc_enable(int channel, bool enable)
 	return 0;
 }
 
-static void dsi_vc_initial_config(int channel)
+static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
 {
 	u32 r;
 
 	DSSDBGF("%d", channel);
 
-	r = dsi_read_reg(DSI_VC_CTRL(channel));
+	r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
 
 	if (FLD_GET(r, 15, 15)) /* VC_BUSY */
 		DSSERR("VC(%d) busy when trying to configure it!\n",
@@ -2408,63 +2456,64 @@ static void dsi_vc_initial_config(int channel)
 	r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
 	r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
 
-	dsi_write_reg(DSI_VC_CTRL(channel), r);
+	dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r);
 }
 
-static int dsi_vc_config_l4(int channel)
+static int dsi_vc_config_l4(struct platform_device *dsidev, int channel)
 {
 	if (dsi.vc[channel].mode == DSI_VC_MODE_L4)
 		return 0;
 
 	DSSDBGF("%d", channel);
 
-	dsi_sync_vc(channel);
+	dsi_sync_vc(dsidev, channel);
 
-	dsi_vc_enable(channel, 0);
+	dsi_vc_enable(dsidev, channel, 0);
 
 	/* VC_BUSY */
-	if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) {
+	if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
 		DSSERR("vc(%d) busy when trying to config for L4\n", channel);
 		return -EIO;
 	}
 
-	REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
 
 	/* DCS_CMD_ENABLE */
 	if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
-		REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 30, 30);
+		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 30, 30);
 
-	dsi_vc_enable(channel, 1);
+	dsi_vc_enable(dsidev, channel, 1);
 
 	dsi.vc[channel].mode = DSI_VC_MODE_L4;
 
 	return 0;
 }
 
-static int dsi_vc_config_vp(int channel)
+static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
 {
 	if (dsi.vc[channel].mode == DSI_VC_MODE_VP)
 		return 0;
 
 	DSSDBGF("%d", channel);
 
-	dsi_sync_vc(channel);
+	dsi_sync_vc(dsidev, channel);
 
-	dsi_vc_enable(channel, 0);
+	dsi_vc_enable(dsidev, channel, 0);
 
 	/* VC_BUSY */
-	if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) {
+	if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
 		DSSERR("vc(%d) busy when trying to config for VP\n", channel);
 		return -EIO;
 	}
 
-	REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */
+	/* SOURCE, 1 = video port */
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 1, 1);
 
 	/* DCS_CMD_ENABLE */
 	if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
-		REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 30, 30);
+		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 30, 30);
 
-	dsi_vc_enable(channel, 1);
+	dsi_vc_enable(dsidev, channel, 1);
 
 	dsi.vc[channel].mode = DSI_VC_MODE_VP;
 
@@ -2475,27 +2524,29 @@ static int dsi_vc_config_vp(int channel)
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 		bool enable)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+
 	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
 
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
-	dsi_vc_enable(channel, 0);
-	dsi_if_enable(0);
+	dsi_vc_enable(dsidev, channel, 0);
+	dsi_if_enable(dsidev, 0);
 
-	REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 9, 9);
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 9, 9);
 
-	dsi_vc_enable(channel, 1);
-	dsi_if_enable(1);
+	dsi_vc_enable(dsidev, channel, 1);
+	dsi_if_enable(dsidev, 1);
 
-	dsi_force_tx_stop_mode_io();
+	dsi_force_tx_stop_mode_io(dsidev);
 }
 EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
 
-static void dsi_vc_flush_long_data(int channel)
+static void dsi_vc_flush_long_data(struct platform_device *dsidev, int channel)
 {
-	while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
+	while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
 		u32 val;
-		val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+		val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
 		DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
 				(val >> 0) & 0xff,
 				(val >> 8) & 0xff,
@@ -2541,13 +2592,14 @@ static void dsi_show_rx_ack_with_err(u16 err)
 		DSSERR("\t\tDSI Protocol Violation\n");
 }
 
-static u16 dsi_vc_flush_receive_data(int channel)
+static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev,
+		int channel)
 {
 	/* RX_FIFO_NOT_EMPTY */
-	while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
+	while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
 		u32 val;
 		u8 dt;
-		val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+		val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
 		DSSERR("\trawval %#08x\n", val);
 		dt = FLD_GET(val, 5, 0);
 		if (dt == DSI_DT_RX_ACK_WITH_ERR) {
@@ -2562,7 +2614,7 @@ static u16 dsi_vc_flush_receive_data(int channel)
 		} else if (dt == DSI_DT_RX_DCS_LONG_READ) {
 			DSSERR("\tDCS long response, len %d\n",
 					FLD_GET(val, 23, 8));
-			dsi_vc_flush_long_data(channel);
+			dsi_vc_flush_long_data(dsidev, channel);
 		} else {
 			DSSERR("\tunknown datatype 0x%02x\n", dt);
 		}
@@ -2570,40 +2622,42 @@ static u16 dsi_vc_flush_receive_data(int channel)
 	return 0;
 }
 
-static int dsi_vc_send_bta(int channel)
+static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
 {
 	if (dsi.debug_write || dsi.debug_read)
 		DSSDBG("dsi_vc_send_bta %d\n", channel);
 
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
-	if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {	/* RX_FIFO_NOT_EMPTY */
+	/* RX_FIFO_NOT_EMPTY */
+	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
 		DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
-		dsi_vc_flush_receive_data(channel);
+		dsi_vc_flush_receive_data(dsidev, channel);
 	}
 
-	REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
 
 	return 0;
 }
 
 int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r = 0;
 	u32 err;
 
-	r = dsi_register_isr_vc(channel, dsi_completion_handler,
+	r = dsi_register_isr_vc(dsidev, channel, dsi_completion_handler,
 			&completion, DSI_VC_IRQ_BTA);
 	if (r)
 		goto err0;
 
-	r = dsi_register_isr(dsi_completion_handler, &completion,
+	r = dsi_register_isr(dsidev, dsi_completion_handler, &completion,
 			DSI_IRQ_ERROR_MASK);
 	if (r)
 		goto err1;
 
-	r = dsi_vc_send_bta(channel);
+	r = dsi_vc_send_bta(dsidev, channel);
 	if (r)
 		goto err2;
 
@@ -2614,41 +2668,41 @@ int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel)
 		goto err2;
 	}
 
-	err = dsi_get_errors();
+	err = dsi_get_errors(dsidev);
 	if (err) {
 		DSSERR("Error while sending BTA: %x\n", err);
 		r = -EIO;
 		goto err2;
 	}
 err2:
-	dsi_unregister_isr(dsi_completion_handler, &completion,
+	dsi_unregister_isr(dsidev, dsi_completion_handler, &completion,
 			DSI_IRQ_ERROR_MASK);
 err1:
-	dsi_unregister_isr_vc(channel, dsi_completion_handler,
+	dsi_unregister_isr_vc(dsidev, channel, dsi_completion_handler,
 			&completion, DSI_VC_IRQ_BTA);
 err0:
 	return r;
 }
 EXPORT_SYMBOL(dsi_vc_send_bta_sync);
 
-static inline void dsi_vc_write_long_header(int channel, u8 data_type,
-		u16 len, u8 ecc)
+static inline void dsi_vc_write_long_header(struct platform_device *dsidev,
+		int channel, u8 data_type, u16 len, u8 ecc)
 {
 	u32 val;
 	u8 data_id;
 
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	data_id = data_type | dsi.vc[channel].vc_id << 6;
 
 	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
 		FLD_VAL(ecc, 31, 24);
 
-	dsi_write_reg(DSI_VC_LONG_PACKET_HEADER(channel), val);
+	dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_HEADER(channel), val);
 }
 
-static inline void dsi_vc_write_long_payload(int channel,
-		u8 b1, u8 b2, u8 b3, u8 b4)
+static inline void dsi_vc_write_long_payload(struct platform_device *dsidev,
+		int channel, u8 b1, u8 b2, u8 b3, u8 b4)
 {
 	u32 val;
 
@@ -2657,11 +2711,11 @@ static inline void dsi_vc_write_long_payload(int channel,
 /*	DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
 			b1, b2, b3, b4, val); */
 
-	dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
+	dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
 }
 
-static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
-		u8 ecc)
+static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
+		u8 data_type, u8 *data, u16 len, u8 ecc)
 {
 	/*u32 val; */
 	int i;
@@ -2678,9 +2732,9 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
 		return -EINVAL;
 	}
 
-	dsi_vc_config_l4(channel);
+	dsi_vc_config_l4(dsidev, channel);
 
-	dsi_vc_write_long_header(channel, data_type, len, ecc);
+	dsi_vc_write_long_header(dsidev, channel, data_type, len, ecc);
 
 	p = data;
 	for (i = 0; i < len >> 2; i++) {
@@ -2692,7 +2746,7 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
 		b3 = *p++;
 		b4 = *p++;
 
-		dsi_vc_write_long_payload(channel, b1, b2, b3, b4);
+		dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, b4);
 	}
 
 	i = len % 4;
@@ -2717,27 +2771,28 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
 			break;
 		}
 
-		dsi_vc_write_long_payload(channel, b1, b2, b3, 0);
+		dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, 0);
 	}
 
 	return r;
 }
 
-static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
+static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
+		u8 data_type, u16 data, u8 ecc)
 {
 	u32 r;
 	u8 data_id;
 
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	if (dsi.debug_write)
 		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
 				channel,
 				data_type, data & 0xff, (data >> 8) & 0xff);
 
-	dsi_vc_config_l4(channel);
+	dsi_vc_config_l4(dsidev, channel);
 
-	if (FLD_GET(dsi_read_reg(DSI_VC_CTRL(channel)), 16, 16)) {
+	if (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(channel)), 16, 16)) {
 		DSSERR("ERROR FIFO FULL, aborting transfer\n");
 		return -EINVAL;
 	}
@@ -2746,34 +2801,38 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
 
 	r = (data_id << 0) | (data << 8) | (ecc << 24);
 
-	dsi_write_reg(DSI_VC_SHORT_PACKET_HEADER(channel), r);
+	dsi_write_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel), r);
 
 	return 0;
 }
 
 int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	u8 nullpkg[] = {0, 0, 0, 0};
-	return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0);
+
+	return dsi_vc_send_long(dsidev, channel, DSI_DT_NULL_PACKET, nullpkg,
+		4, 0);
 }
 EXPORT_SYMBOL(dsi_vc_send_null);
 
 int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int r;
 
 	BUG_ON(len == 0);
 
 	if (len == 1) {
-		r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_0,
+		r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_0,
 				data[0], 0);
 	} else if (len == 2) {
-		r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_1,
+		r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_1,
 				data[0] | (data[1] << 8), 0);
 	} else {
 		/* 0x39 = DCS Long Write */
-		r = dsi_vc_send_long(channel, DSI_DT_DCS_LONG_WRITE,
+		r = dsi_vc_send_long(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
 				data, len, 0);
 	}
 
@@ -2784,6 +2843,7 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
 int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 		int len)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int r;
 
 	r = dsi_vc_dcs_write_nosync(dssdev, channel, data, len);
@@ -2794,9 +2854,10 @@ int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 	if (r)
 		goto err;
 
-	if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {	/* RX_FIFO_NOT_EMPTY */
+	/* RX_FIFO_NOT_EMPTY */
+	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) {
 		DSSERR("rx fifo not empty after write, dumping data:\n");
-		dsi_vc_flush_receive_data(channel);
+		dsi_vc_flush_receive_data(dsidev, channel);
 		r = -EIO;
 		goto err;
 	}
@@ -2828,6 +2889,7 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_1);
 int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	u32 val;
 	u8 dt;
 	int r;
@@ -2835,7 +2897,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 	if (dsi.debug_read)
 		DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd);
 
-	r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
+	r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0);
 	if (r)
 		goto err;
 
@@ -2844,13 +2906,13 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		goto err;
 
 	/* RX_FIFO_NOT_EMPTY */
-	if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) {
+	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) {
 		DSSERR("RX fifo empty when trying to read.\n");
 		r = -EIO;
 		goto err;
 	}
 
-	val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+	val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
 	if (dsi.debug_read)
 		DSSDBG("\theader: %08x\n", val);
 	dt = FLD_GET(val, 5, 0);
@@ -2901,7 +2963,8 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		/* two byte checksum ends the packet, not included in len */
 		for (w = 0; w < len + 2;) {
 			int b;
-			val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
+			val = dsi_read_reg(dsidev,
+				DSI_VC_SHORT_PACKET_HEADER(channel));
 			if (dsi.debug_read)
 				DSSDBG("\t\t%02x %02x %02x %02x\n",
 						(val >> 0) & 0xff,
@@ -2974,60 +3037,63 @@ EXPORT_SYMBOL(dsi_vc_dcs_read_2);
 int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len)
 {
-	return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+
+	return dsi_vc_send_short(dsidev, channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
 			len, 0);
 }
 EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
 
-static int dsi_enter_ulps(void)
+static int dsi_enter_ulps(struct platform_device *dsidev)
 {
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r;
 
 	DSSDBGF();
 
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	WARN_ON(dsi.ulps_enabled);
 
 	if (dsi.ulps_enabled)
 		return 0;
 
-	if (REG_GET(DSI_CLK_CTRL, 13, 13)) {
+	if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) {
 		DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n");
 		return -EIO;
 	}
 
-	dsi_sync_vc(0);
-	dsi_sync_vc(1);
-	dsi_sync_vc(2);
-	dsi_sync_vc(3);
+	dsi_sync_vc(dsidev, 0);
+	dsi_sync_vc(dsidev, 1);
+	dsi_sync_vc(dsidev, 2);
+	dsi_sync_vc(dsidev, 3);
 
-	dsi_force_tx_stop_mode_io();
+	dsi_force_tx_stop_mode_io(dsidev);
 
-	dsi_vc_enable(0, false);
-	dsi_vc_enable(1, false);
-	dsi_vc_enable(2, false);
-	dsi_vc_enable(3, false);
+	dsi_vc_enable(dsidev, 0, false);
+	dsi_vc_enable(dsidev, 1, false);
+	dsi_vc_enable(dsidev, 2, false);
+	dsi_vc_enable(dsidev, 3, false);
 
-	if (REG_GET(DSI_COMPLEXIO_CFG2, 16, 16)) {	/* HS_BUSY */
+	if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 16, 16)) {	/* HS_BUSY */
 		DSSERR("HS busy when enabling ULPS\n");
 		return -EIO;
 	}
 
-	if (REG_GET(DSI_COMPLEXIO_CFG2, 17, 17)) {	/* LP_BUSY */
+	if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 17, 17)) {	/* LP_BUSY */
 		DSSERR("LP busy when enabling ULPS\n");
 		return -EIO;
 	}
 
-	r = dsi_register_isr_cio(dsi_completion_handler, &completion,
+	r = dsi_register_isr_cio(dsidev, dsi_completion_handler, &completion,
 			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
 	if (r)
 		return r;
 
 	/* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
 	/* LANEx_ULPS_SIG2 */
-	REG_FLD_MOD(DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2), 7, 5);
+	REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2),
+		7, 5);
 
 	if (wait_for_completion_timeout(&completion,
 				msecs_to_jiffies(1000)) == 0) {
@@ -3036,24 +3102,25 @@ static int dsi_enter_ulps(void)
 		goto err;
 	}
 
-	dsi_unregister_isr_cio(dsi_completion_handler, &completion,
+	dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
 			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
 
-	dsi_cio_power(DSI_COMPLEXIO_POWER_ULPS);
+	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
 
-	dsi_if_enable(false);
+	dsi_if_enable(dsidev, false);
 
 	dsi.ulps_enabled = true;
 
 	return 0;
 
 err:
-	dsi_unregister_isr_cio(dsi_completion_handler, &completion,
+	dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion,
 			DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
 	return r;
 }
 
-static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
+static void dsi_set_lp_rx_timeout(struct platform_device *dsidev,
+		unsigned ticks, bool x4, bool x16)
 {
 	unsigned long fck;
 	unsigned long total_ticks;
@@ -3062,14 +3129,14 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
 	BUG_ON(ticks > 0x1fff);
 
 	/* ticks in DSI_FCK */
-	fck = dsi_fclk_rate();
+	fck = dsi_fclk_rate(dsidev);
 
-	r = dsi_read_reg(DSI_TIMING2);
+	r = dsi_read_reg(dsidev, DSI_TIMING2);
 	r = FLD_MOD(r, 1, 15, 15);	/* LP_RX_TO */
 	r = FLD_MOD(r, x16 ? 1 : 0, 14, 14);	/* LP_RX_TO_X16 */
 	r = FLD_MOD(r, x4 ? 1 : 0, 13, 13);	/* LP_RX_TO_X4 */
 	r = FLD_MOD(r, ticks, 12, 0);	/* LP_RX_COUNTER */
-	dsi_write_reg(DSI_TIMING2, r);
+	dsi_write_reg(dsidev, DSI_TIMING2, r);
 
 	total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
 
@@ -3079,7 +3146,8 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16)
 			(total_ticks * 1000) / (fck / 1000 / 1000));
 }
 
-static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
+static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks,
+		bool x8, bool x16)
 {
 	unsigned long fck;
 	unsigned long total_ticks;
@@ -3088,14 +3156,14 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
 	BUG_ON(ticks > 0x1fff);
 
 	/* ticks in DSI_FCK */
-	fck = dsi_fclk_rate();
+	fck = dsi_fclk_rate(dsidev);
 
-	r = dsi_read_reg(DSI_TIMING1);
+	r = dsi_read_reg(dsidev, DSI_TIMING1);
 	r = FLD_MOD(r, 1, 31, 31);	/* TA_TO */
 	r = FLD_MOD(r, x16 ? 1 : 0, 30, 30);	/* TA_TO_X16 */
 	r = FLD_MOD(r, x8 ? 1 : 0, 29, 29);	/* TA_TO_X8 */
 	r = FLD_MOD(r, ticks, 28, 16);	/* TA_TO_COUNTER */
-	dsi_write_reg(DSI_TIMING1, r);
+	dsi_write_reg(dsidev, DSI_TIMING1, r);
 
 	total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1);
 
@@ -3105,7 +3173,8 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16)
 			(total_ticks * 1000) / (fck / 1000 / 1000));
 }
 
-static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
+static void dsi_set_stop_state_counter(struct platform_device *dsidev,
+		unsigned ticks, bool x4, bool x16)
 {
 	unsigned long fck;
 	unsigned long total_ticks;
@@ -3114,14 +3183,14 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
 	BUG_ON(ticks > 0x1fff);
 
 	/* ticks in DSI_FCK */
-	fck = dsi_fclk_rate();
+	fck = dsi_fclk_rate(dsidev);
 
-	r = dsi_read_reg(DSI_TIMING1);
+	r = dsi_read_reg(dsidev, DSI_TIMING1);
 	r = FLD_MOD(r, 1, 15, 15);	/* FORCE_TX_STOP_MODE_IO */
 	r = FLD_MOD(r, x16 ? 1 : 0, 14, 14);	/* STOP_STATE_X16_IO */
 	r = FLD_MOD(r, x4 ? 1 : 0, 13, 13);	/* STOP_STATE_X4_IO */
 	r = FLD_MOD(r, ticks, 12, 0);	/* STOP_STATE_COUNTER_IO */
-	dsi_write_reg(DSI_TIMING1, r);
+	dsi_write_reg(dsidev, DSI_TIMING1, r);
 
 	total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
 
@@ -3131,7 +3200,8 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16)
 			(total_ticks * 1000) / (fck / 1000 / 1000));
 }
 
-static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
+static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
+		unsigned ticks, bool x4, bool x16)
 {
 	unsigned long fck;
 	unsigned long total_ticks;
@@ -3140,14 +3210,14 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
 	BUG_ON(ticks > 0x1fff);
 
 	/* ticks in TxByteClkHS */
-	fck = dsi_get_txbyteclkhs();
+	fck = dsi_get_txbyteclkhs(dsidev);
 
-	r = dsi_read_reg(DSI_TIMING2);
+	r = dsi_read_reg(dsidev, DSI_TIMING2);
 	r = FLD_MOD(r, 1, 31, 31);	/* HS_TX_TO */
 	r = FLD_MOD(r, x16 ? 1 : 0, 30, 30);	/* HS_TX_TO_X16 */
 	r = FLD_MOD(r, x4 ? 1 : 0, 29, 29);	/* HS_TX_TO_X8 (4 really) */
 	r = FLD_MOD(r, ticks, 28, 16);	/* HS_TX_TO_COUNTER */
-	dsi_write_reg(DSI_TIMING2, r);
+	dsi_write_reg(dsidev, DSI_TIMING2, r);
 
 	total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1);
 
@@ -3158,24 +3228,25 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16)
 }
 static int dsi_proto_config(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	u32 r;
 	int buswidth = 0;
 
-	dsi_config_tx_fifo(DSI_FIFO_SIZE_32,
+	dsi_config_tx_fifo(dsidev, DSI_FIFO_SIZE_32,
 			DSI_FIFO_SIZE_32,
 			DSI_FIFO_SIZE_32,
 			DSI_FIFO_SIZE_32);
 
-	dsi_config_rx_fifo(DSI_FIFO_SIZE_32,
+	dsi_config_rx_fifo(dsidev, DSI_FIFO_SIZE_32,
 			DSI_FIFO_SIZE_32,
 			DSI_FIFO_SIZE_32,
 			DSI_FIFO_SIZE_32);
 
 	/* XXX what values for the timeouts? */
-	dsi_set_stop_state_counter(0x1000, false, false);
-	dsi_set_ta_timeout(0x1fff, true, true);
-	dsi_set_lp_rx_timeout(0x1fff, true, true);
-	dsi_set_hs_tx_timeout(0x1fff, true, true);
+	dsi_set_stop_state_counter(dsidev, 0x1000, false, false);
+	dsi_set_ta_timeout(dsidev, 0x1fff, true, true);
+	dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
+	dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
 
 	switch (dssdev->ctrl.pixel_size) {
 	case 16:
@@ -3191,7 +3262,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
 		BUG();
 	}
 
-	r = dsi_read_reg(DSI_CTRL);
+	r = dsi_read_reg(dsidev, DSI_CTRL);
 	r = FLD_MOD(r, 1, 1, 1);	/* CS_RX_EN */
 	r = FLD_MOD(r, 1, 2, 2);	/* ECC_RX_EN */
 	r = FLD_MOD(r, 1, 3, 3);	/* TX_FIFO_ARBITRATION */
@@ -3207,18 +3278,19 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
 		r = FLD_MOD(r, 0, 25, 25);
 	}
 
-	dsi_write_reg(DSI_CTRL, r);
+	dsi_write_reg(dsidev, DSI_CTRL, r);
 
-	dsi_vc_initial_config(0);
-	dsi_vc_initial_config(1);
-	dsi_vc_initial_config(2);
-	dsi_vc_initial_config(3);
+	dsi_vc_initial_config(dsidev, 0);
+	dsi_vc_initial_config(dsidev, 1);
+	dsi_vc_initial_config(dsidev, 2);
+	dsi_vc_initial_config(dsidev, 3);
 
 	return 0;
 }
 
 static void dsi_proto_timings(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
 	unsigned tclk_pre, tclk_post;
 	unsigned ths_prepare, ths_prepare_ths_zero, ths_zero;
@@ -3228,25 +3300,25 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 	unsigned ths_eot;
 	u32 r;
 
-	r = dsi_read_reg(DSI_DSIPHY_CFG0);
+	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
 	ths_prepare = FLD_GET(r, 31, 24);
 	ths_prepare_ths_zero = FLD_GET(r, 23, 16);
 	ths_zero = ths_prepare_ths_zero - ths_prepare;
 	ths_trail = FLD_GET(r, 15, 8);
 	ths_exit = FLD_GET(r, 7, 0);
 
-	r = dsi_read_reg(DSI_DSIPHY_CFG1);
+	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
 	tlpx = FLD_GET(r, 22, 16) * 2;
 	tclk_trail = FLD_GET(r, 15, 8);
 	tclk_zero = FLD_GET(r, 7, 0);
 
-	r = dsi_read_reg(DSI_DSIPHY_CFG2);
+	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
 	tclk_prepare = FLD_GET(r, 7, 0);
 
 	/* min 8*UI */
 	tclk_pre = 20;
 	/* min 60ns + 52*UI */
-	tclk_post = ns2ddr(60) + 26;
+	tclk_post = ns2ddr(dsidev, 60) + 26;
 
 	/* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */
 	if (dssdev->phy.dsi.data1_lane != 0 &&
@@ -3262,10 +3334,10 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 	BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255);
 	BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255);
 
-	r = dsi_read_reg(DSI_CLK_TIMING);
+	r = dsi_read_reg(dsidev, DSI_CLK_TIMING);
 	r = FLD_MOD(r, ddr_clk_pre, 15, 8);
 	r = FLD_MOD(r, ddr_clk_post, 7, 0);
-	dsi_write_reg(DSI_CLK_TIMING, r);
+	dsi_write_reg(dsidev, DSI_CLK_TIMING, r);
 
 	DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n",
 			ddr_clk_pre,
@@ -3279,7 +3351,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 
 	r = FLD_VAL(enter_hs_mode_lat, 31, 16) |
 		FLD_VAL(exit_hs_mode_lat, 15, 0);
-	dsi_write_reg(DSI_VM_TIMING7, r);
+	dsi_write_reg(dsidev, DSI_VM_TIMING7, r);
 
 	DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
 			enter_hs_mode_lat, exit_hs_mode_lat);
@@ -3289,25 +3361,26 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 #define DSI_DECL_VARS \
 	int __dsi_cb = 0; u32 __dsi_cv = 0;
 
-#define DSI_FLUSH(ch) \
+#define DSI_FLUSH(dsidev, ch) \
 	if (__dsi_cb > 0) { \
 		/*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \
-		dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \
+		dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \
 		__dsi_cb = __dsi_cv = 0; \
 	}
 
-#define DSI_PUSH(ch, data) \
+#define DSI_PUSH(dsidev, ch, data) \
 	do { \
 		__dsi_cv |= (data) << (__dsi_cb * 8); \
 		/*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \
 		if (++__dsi_cb > 3) \
-			DSI_FLUSH(ch); \
+			DSI_FLUSH(dsidev, ch); \
 	} while (0)
 
 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 */
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int first = 1;
 	int fifo_stalls = 0;
 	int max_dsi_packet_size;
@@ -3375,35 +3448,35 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
 #if 1
 		/* using fifo not empty */
 		/* TX_FIFO_NOT_EMPTY */
-		while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) {
+		while (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(0)), 5, 5)) {
 			fifo_stalls++;
 			if (fifo_stalls > 0xfffff) {
 				DSSERR("fifo stalls overflow, pixels left %d\n",
 						pixels_left);
-				dsi_if_enable(0);
+				dsi_if_enable(dsidev, 0);
 				return -EIO;
 			}
 			udelay(1);
 		}
 #elif 1
 		/* using fifo emptiness */
-		while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 <
+		while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 <
 				max_dsi_packet_size) {
 			fifo_stalls++;
 			if (fifo_stalls > 0xfffff) {
 				DSSERR("fifo stalls overflow, pixels left %d\n",
 					       pixels_left);
-				dsi_if_enable(0);
+				dsi_if_enable(dsidev, 0);
 				return -EIO;
 			}
 		}
 #else
-		while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) {
+		while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) {
 			fifo_stalls++;
 			if (fifo_stalls > 0xfffff) {
 				DSSERR("fifo stalls overflow, pixels left %d\n",
 					       pixels_left);
-				dsi_if_enable(0);
+				dsi_if_enable(dsidev, 0);
 				return -EIO;
 			}
 		}
@@ -3412,17 +3485,17 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
 
 		pixels_left -= pixels;
 
-		dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE,
+		dsi_vc_write_long_header(dsidev, 0, DSI_DT_DCS_LONG_WRITE,
 				1 + pixels * bytespp, 0);
 
-		DSI_PUSH(0, dcs_cmd);
+		DSI_PUSH(dsidev, 0, dcs_cmd);
 
 		while (pixels-- > 0) {
 			u32 pix = __raw_readl(data++);
 
-			DSI_PUSH(0, (pix >> 16) & 0xff);
-			DSI_PUSH(0, (pix >> 8) & 0xff);
-			DSI_PUSH(0, (pix >> 0) & 0xff);
+			DSI_PUSH(dsidev, 0, (pix >> 16) & 0xff);
+			DSI_PUSH(dsidev, 0, (pix >> 8) & 0xff);
+			DSI_PUSH(dsidev, 0, (pix >> 0) & 0xff);
 
 			current_x++;
 			if (current_x == x+w) {
@@ -3431,7 +3504,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
 			}
 		}
 
-		DSI_FLUSH(0);
+		DSI_FLUSH(dsidev, 0);
 	}
 
 	return 0;
@@ -3440,6 +3513,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
 static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 		u16 x, u16 y, u16 w, u16 h)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	unsigned bytespp;
 	unsigned bytespl;
 	unsigned bytespf;
@@ -3457,7 +3531,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
 			x, y, w, h);
 
-	dsi_vc_config_vp(channel);
+	dsi_vc_config_vp(dsidev, channel);
 
 	bytespp	= dssdev->ctrl.pixel_size / 8;
 	bytespl = w * bytespp;
@@ -3478,15 +3552,16 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 		total_len += (bytespf % packet_payload) + 1;
 
 	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
-	dsi_write_reg(DSI_VC_TE(channel), l);
+	dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
 
-	dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0);
+	dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
+		packet_len, 0);
 
 	if (dsi.te_enabled)
 		l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
 	else
 		l = FLD_MOD(l, 1, 31, 31); /* TE_START */
-	dsi_write_reg(DSI_VC_TE(channel), l);
+	dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
 
 	/* We put SIDLEMODE to no-idle for the duration of the transfer,
 	 * because DSS interrupts are not capable of waking up the CPU and the
@@ -3496,7 +3571,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	 */
 	dispc_disable_sidle();
 
-	dsi_perf_mark_start();
+	dsi_perf_mark_start(dsidev);
 
 	r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work,
 			msecs_to_jiffies(250));
@@ -3507,9 +3582,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	if (dsi.te_enabled) {
 		/* disable LP_RX_TO, so that we can receive TE.  Time to wait
 		 * for TE is longer than the timer allows */
-		REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
+		REG_FLD_MOD(dsidev, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
 
-		dsi_vc_send_bta(channel);
+		dsi_vc_send_bta(dsidev, channel);
 
 #ifdef DSI_CATCH_MISSING_TE
 		mod_timer(&dsi.te_timer, jiffies + msecs_to_jiffies(250));
@@ -3524,20 +3599,20 @@ static void dsi_te_timeout(unsigned long arg)
 }
 #endif
 
-static void dsi_handle_framedone(int error)
+static void dsi_handle_framedone(struct platform_device *dsidev, int error)
 {
 	/* SIDLEMODE back to smart-idle */
 	dispc_enable_sidle();
 
 	if (dsi.te_enabled) {
 		/* enable LP_RX_TO again after the TE */
-		REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
+		REG_FLD_MOD(dsidev, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
 	}
 
 	dsi.framedone_callback(error, dsi.framedone_data);
 
 	if (!error)
-		dsi_perf_show("DISPC");
+		dsi_perf_show(dsidev, "DISPC");
 }
 
 static void dsi_framedone_timeout_work_callback(struct work_struct *work)
@@ -3551,11 +3626,13 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
 
 	DSSERR("Framedone not received for 250ms!\n");
 
-	dsi_handle_framedone(-ETIMEDOUT);
+	dsi_handle_framedone(dsi.pdev, -ETIMEDOUT);
 }
 
 static void dsi_framedone_irq_callback(void *data, u32 mask)
 {
+	struct omap_dss_device *dssdev = (struct omap_dss_device *) data;
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
 	 * turns itself off. However, DSI still has the pixels in its buffers,
 	 * and is sending the data.
@@ -3563,7 +3640,7 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
 
 	__cancel_delayed_work(&dsi.framedone_timeout_work);
 
-	dsi_handle_framedone(0);
+	dsi_handle_framedone(dsidev, 0);
 
 #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
 	dispc_fake_vsync_irq();
@@ -3574,6 +3651,7 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
 				    u16 *x, u16 *y, u16 *w, u16 *h,
 				    bool enlarge_update_area)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	u16 dw, dh;
 
 	dssdev->driver->get_resolution(dssdev, &dw, &dh);
@@ -3593,7 +3671,7 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
 	if (*w == 0 || *h == 0)
 		return -EINVAL;
 
-	dsi_perf_mark_setup();
+	dsi_perf_mark_setup(dsidev);
 
 	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
 		dss_setup_partial_planes(dssdev, x, y, w, h,
@@ -3610,6 +3688,8 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
 		u16 x, u16 y, u16 w, u16 h,
 		void (*callback)(int, void *), void *data)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+
 	dsi.update_channel = channel;
 
 	/* OMAP DSS cannot send updates of odd widths.
@@ -3636,7 +3716,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
 		if (r)
 			return r;
 
-		dsi_perf_show("L4");
+		dsi_perf_show(dsidev, "L4");
 		callback(0, data);
 	}
 
@@ -3650,7 +3730,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 {
 	int r;
 
-	r = omap_dispc_register_isr(dsi_framedone_irq_callback, NULL,
+	r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev,
 			DISPC_IRQ_FRAMEDONE);
 	if (r) {
 		DSSERR("can't get FRAMEDONE irq\n");
@@ -3684,12 +3764,13 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 
 static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
 {
-	omap_dispc_unregister_isr(dsi_framedone_irq_callback, NULL,
+	omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev,
 			DISPC_IRQ_FRAMEDONE);
 }
 
 static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	struct dsi_clock_info cinfo;
 	int r;
 
@@ -3705,7 +3786,7 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
 		return r;
 	}
 
-	r = dsi_pll_set_clock_div(&cinfo);
+	r = dsi_pll_set_clock_div(dsidev, &cinfo);
 	if (r) {
 		DSSERR("Failed to set dsi clocks\n");
 		return r;
@@ -3716,11 +3797,12 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
 
 static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	struct dispc_clock_info dispc_cinfo;
 	int r;
 	unsigned long long fck;
 
-	fck = dsi_get_pll_hsdiv_dispc_rate();
+	fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
 
 	dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div;
 	dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div;
@@ -3742,9 +3824,10 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
 
 static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int r;
 
-	r = dsi_pll_init(true, true);
+	r = dsi_pll_init(dsidev, true, true);
 	if (r)
 		goto err0;
 
@@ -3767,34 +3850,34 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
 	if (r)
 		goto err2;
 
-	_dsi_print_reset_status();
+	_dsi_print_reset_status(dsidev);
 
 	dsi_proto_timings(dssdev);
 	dsi_set_lp_clk_divisor(dssdev);
 
 	if (1)
-		_dsi_print_reset_status();
+		_dsi_print_reset_status(dsidev);
 
 	r = dsi_proto_config(dssdev);
 	if (r)
 		goto err3;
 
 	/* enable interface */
-	dsi_vc_enable(0, 1);
-	dsi_vc_enable(1, 1);
-	dsi_vc_enable(2, 1);
-	dsi_vc_enable(3, 1);
-	dsi_if_enable(1);
-	dsi_force_tx_stop_mode_io();
+	dsi_vc_enable(dsidev, 0, 1);
+	dsi_vc_enable(dsidev, 1, 1);
+	dsi_vc_enable(dsidev, 2, 1);
+	dsi_vc_enable(dsidev, 3, 1);
+	dsi_if_enable(dsidev, 1);
+	dsi_force_tx_stop_mode_io(dsidev);
 
 	return 0;
 err3:
-	dsi_cio_uninit();
+	dsi_cio_uninit(dsidev);
 err2:
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
 err1:
-	dsi_pll_uninit(true);
+	dsi_pll_uninit(dsidev, true);
 err0:
 	return r;
 }
@@ -3802,45 +3885,48 @@ err0:
 static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+
 	if (enter_ulps && !dsi.ulps_enabled)
-		dsi_enter_ulps();
+		dsi_enter_ulps(dsidev);
 
 	/* disable interface */
-	dsi_if_enable(0);
-	dsi_vc_enable(0, 0);
-	dsi_vc_enable(1, 0);
-	dsi_vc_enable(2, 0);
-	dsi_vc_enable(3, 0);
+	dsi_if_enable(dsidev, 0);
+	dsi_vc_enable(dsidev, 0, 0);
+	dsi_vc_enable(dsidev, 1, 0);
+	dsi_vc_enable(dsidev, 2, 0);
+	dsi_vc_enable(dsidev, 3, 0);
 
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
-	dsi_cio_uninit();
-	dsi_pll_uninit(disconnect_lanes);
+	dsi_cio_uninit(dsidev);
+	dsi_pll_uninit(dsidev, disconnect_lanes);
 }
 
-static int dsi_core_init(void)
+static int dsi_core_init(struct platform_device *dsidev)
 {
 	/* Autoidle */
-	REG_FLD_MOD(DSI_SYSCONFIG, 1, 0, 0);
+	REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 0, 0);
 
 	/* ENWAKEUP */
-	REG_FLD_MOD(DSI_SYSCONFIG, 1, 2, 2);
+	REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 2, 2);
 
 	/* SIDLEMODE smart-idle */
-	REG_FLD_MOD(DSI_SYSCONFIG, 2, 4, 3);
+	REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 2, 4, 3);
 
-	_dsi_initialize_irq();
+	_dsi_initialize_irq(dsidev);
 
 	return 0;
 }
 
 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
 	int r = 0;
 
 	DSSDBG("dsi_display_enable\n");
 
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	mutex_lock(&dsi.lock);
 
@@ -3851,13 +3937,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 	}
 
 	enable_clocks(1);
-	dsi_enable_pll_clock(1);
+	dsi_enable_pll_clock(dsidev, 1);
 
-	r = _dsi_reset();
+	r = _dsi_reset(dsidev);
 	if (r)
 		goto err1;
 
-	dsi_core_init();
+	dsi_core_init(dsidev);
 
 	r = dsi_display_init_dispc(dssdev);
 	if (r)
@@ -3875,7 +3961,7 @@ err2:
 	dsi_display_uninit_dispc(dssdev);
 err1:
 	enable_clocks(0);
-	dsi_enable_pll_clock(0);
+	dsi_enable_pll_clock(dsidev, 0);
 	omap_dss_stop_device(dssdev);
 err0:
 	mutex_unlock(&dsi.lock);
@@ -3887,9 +3973,11 @@ EXPORT_SYMBOL(omapdss_dsi_display_enable);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+
 	DSSDBG("dsi_display_disable\n");
 
-	WARN_ON(!dsi_bus_is_locked());
+	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	mutex_lock(&dsi.lock);
 
@@ -3898,7 +3986,7 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 	dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
 
 	enable_clocks(0);
-	dsi_enable_pll_clock(0);
+	dsi_enable_pll_clock(dsidev, 0);
 
 	omap_dss_stop_device(dssdev);
 
@@ -4001,23 +4089,23 @@ void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 }
 EXPORT_SYMBOL(omap_dsi_release_vc);
 
-void dsi_wait_pll_hsdiv_dispc_active(void)
+void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
 {
-	if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1)
+	if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 7, 1) != 1)
 		DSSERR("%s (%s) not active\n",
 			dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
 			dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
 }
 
-void dsi_wait_pll_hsdiv_dsi_active(void)
+void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
 {
-	if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1)
+	if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 8, 1) != 1)
 		DSSERR("%s (%s) not active\n",
 			dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
 			dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
 }
 
-static void dsi_calc_clock_param_ranges(void)
+static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
 {
 	dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
 	dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
@@ -4028,7 +4116,7 @@ static void dsi_calc_clock_param_ranges(void)
 	dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
 }
 
-static int dsi_init(struct platform_device *pdev)
+static int dsi_init(struct platform_device *dsidev)
 {
 	struct omap_display_platform_data *dss_plat_data;
 	struct omap_dss_board_info *board_info;
@@ -4036,7 +4124,9 @@ static int dsi_init(struct platform_device *pdev)
 	int r, i;
 	struct resource *dsi_mem;
 
-	dss_plat_data = pdev->dev.platform_data;
+	dsi_pdev_map[dsidev->id] = dsidev;
+
+	dss_plat_data = dsidev->dev.platform_data;
 	board_info = dss_plat_data->board_data;
 	dsi.dsi_mux_pads = board_info->dsi_mux_pads;
 
@@ -4097,12 +4187,12 @@ static int dsi_init(struct platform_device *pdev)
 		dsi.vc[i].vc_id = 0;
 	}
 
-	dsi_calc_clock_param_ranges();
+	dsi_calc_clock_param_ranges(dsidev);
 
 	enable_clocks(1);
 
-	rev = dsi_read_reg(DSI_REVISION);
-	dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n",
+	rev = dsi_read_reg(dsidev, DSI_REVISION);
+	dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
 	       FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
 
 	enable_clocks(0);
@@ -4115,7 +4205,7 @@ err1:
 	return r;
 }
 
-static void dsi_exit(void)
+static void dsi_exit(struct platform_device *dsidev)
 {
 	if (dsi.vdds_dsi_reg != NULL) {
 		if (dsi.vdds_dsi_enabled) {
@@ -4136,11 +4226,11 @@ static void dsi_exit(void)
 }
 
 /* DSI HW IP initialisation */
-static int omap_dsihw_probe(struct platform_device *pdev)
+static int omap_dsihw_probe(struct platform_device *dsidev)
 {
 	int r;
-	dsi.pdev = pdev;
-	r = dsi_init(pdev);
+	dsi.pdev = dsidev;
+	r = dsi_init(dsidev);
 	if (r) {
 		DSSERR("Failed to initialize DSI\n");
 		goto err_dsi;
@@ -4149,9 +4239,9 @@ err_dsi:
 	return r;
 }
 
-static int omap_dsihw_remove(struct platform_device *pdev)
+static int omap_dsihw_remove(struct platform_device *dsidev)
 {
-	dsi_exit();
+	dsi_exit(dsidev);
 	WARN_ON(dsi.scp_clk_refcount > 0);
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index c8cd83e..30f4c02 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -302,6 +302,7 @@ void dss_dump_regs(struct seq_file *s)
 
 void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 {
+	struct platform_device *dsidev;
 	int b;
 	u8 start, end;
 
@@ -311,7 +312,8 @@ void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 		break;
 	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
 		b = 1;
-		dsi_wait_pll_hsdiv_dispc_active();
+		dsidev = dsi_get_dsi_device_module(0);
+		dsi_wait_pll_hsdiv_dispc_active(dsidev);
 		break;
 	default:
 		BUG();
@@ -326,6 +328,7 @@ void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 
 void dss_select_dsi_clk_source(enum omap_dss_clk_source clk_src)
 {
+	struct platform_device *dsidev;
 	int b;
 
 	switch (clk_src) {
@@ -334,7 +337,8 @@ void dss_select_dsi_clk_source(enum omap_dss_clk_source clk_src)
 		break;
 	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
 		b = 1;
-		dsi_wait_pll_hsdiv_dsi_active();
+		dsidev = dsi_get_dsi_device_module(0);
+		dsi_wait_pll_hsdiv_dsi_active(dsidev);
 		break;
 	default:
 		BUG();
@@ -348,6 +352,7 @@ void dss_select_dsi_clk_source(enum omap_dss_clk_source clk_src)
 void dss_select_lcd_clk_source(enum omap_channel channel,
 		enum omap_dss_clk_source clk_src)
 {
+	struct platform_device *dsidev;
 	int b, ix, pos;
 
 	if (!dss_has_feature(FEAT_LCD_CLK_SRC))
@@ -360,7 +365,8 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
 	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
 		BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
 		b = 1;
-		dsi_wait_pll_hsdiv_dispc_active();
+		dsidev = dsi_get_dsi_device_module(0);
+		dsi_wait_pll_hsdiv_dispc_active(dsidev);
 		break;
 	default:
 		BUG();
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 40764e0..bca64f9 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -287,18 +287,21 @@ void dsi_restore_context(void);
 
 int dsi_init_display(struct omap_dss_device *display);
 void dsi_irq_handler(void);
-unsigned long dsi_get_pll_hsdiv_dispc_rate(void);
-int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo);
-int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
-		struct dsi_clock_info *cinfo,
+unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
+int dsi_pll_set_clock_div(struct platform_device *dsidev,
+		struct dsi_clock_info *cinfo);
+int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
+		unsigned long req_pck, struct dsi_clock_info *cinfo,
 		struct dispc_clock_info *dispc_cinfo);
-int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv);
-void dsi_pll_uninit(bool disconnect_lanes);
+int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
+		bool enable_hsdiv);
+void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
 void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
 		u32 fifo_size, enum omap_burst_size *burst_size,
 		u32 *fifo_low, u32 *fifo_high);
-void dsi_wait_pll_hsdiv_dispc_active(void);
-void dsi_wait_pll_hsdiv_dsi_active(void);
+void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
+void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
+struct platform_device *dsi_get_dsi_device_module(int  module);
 #else
 static inline int dsi_init_platform_driver(void)
 {
@@ -307,17 +310,23 @@ static inline int dsi_init_platform_driver(void)
 static inline void dsi_uninit_platform_driver(void)
 {
 }
-static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void)
+static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
 {
 	WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
 	return 0;
 }
-static inline void dsi_wait_pll_hsdiv_dispc_active(void)
+static inline void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
 {
 }
-static inline void dsi_wait_pll_hsdiv_dsi_active(void)
+static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
 {
 }
+static inline struct platform_device *dsi_get_device_module(int module)
+{
+	WARN("%s: DSI not compiled in, returning platform device as NULL\n",
+			__func__);
+	return NULL;
+}
 #endif
 
 /* DPI */
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 5668fec..857162b 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -23,6 +23,7 @@
 #define MAX_DSS_MANAGERS	3
 #define MAX_DSS_OVERLAYS	3
 #define MAX_DSS_LCD_MANAGERS	2
+#define MAX_NUM_DSI		2
 
 /* DSS has feature id */
 enum dss_feat_id {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 5/9] OMAP: DSS2: DSI: Use platform_device pointer to get dsi data
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
                   ` (3 preceding siblings ...)
  2011-05-04  7:38 ` [PATCH 4/9] OMAP: DSS2: Pass platform_device as an argument in dsi functions Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  7:38 ` [PATCH 6/9] OMAP: DSS2: DSI: Pass pointer to struct to packet_sent_handler isrs Archit Taneja
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

The dsi related data structure currently creates one global instance of itself
which is accessed by dsi functions. Remove this global structure instance and
declare the struct as dsi_data. Modify dsi_init() to allocate a "dsi_data"
structure for each platform device instance. Link this data with the device's
platform_device pointer. Create the function dsi_get_dsi_data() which takes
the pdev and return a pointer to the device's dsi_data.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |  655 +++++++++++++++++++++++++----------------
 1 files changed, 395 insertions(+), 260 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index c0e272b..627869e 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -34,6 +34,7 @@
 #include <linux/wait.h>
 #include <linux/workqueue.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 
 #include <plat/display.h>
 #include <plat/clock.h>
@@ -257,7 +258,7 @@ struct dsi_isr_tables {
 	struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
 };
 
-static struct dsi_data {
+struct dsi_data {
 	struct platform_device *pdev;
 	void __iomem	*base;
 	int irq;
@@ -327,7 +328,7 @@ static struct dsi_data {
 	unsigned long lpdiv_max;
 
 	unsigned scp_clk_refcount;
-} dsi;
+};
 
 static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
 
@@ -336,6 +337,11 @@ static unsigned int dsi_perf;
 module_param_named(dsi_perf, dsi_perf, bool, 0644);
 #endif
 
+static inline struct dsi_data *dsi_get_dsi_data(struct platform_device *dsidev)
+{
+	return dev_get_drvdata(&dsidev->dev);
+}
+
 static inline struct platform_device *dsi_get_dsi_device(struct omap_dss_device *dssdev)
 {
 	return dsi_pdev_map[dssdev->phy.dsi.module];
@@ -349,13 +355,17 @@ struct platform_device *dsi_get_dsi_device_module(int module)
 static inline void dsi_write_reg(struct platform_device *dsidev,
 		const struct dsi_reg idx, u32 val)
 {
-	__raw_writel(val, dsi.base + idx.idx);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	__raw_writel(val, dsi->base + idx.idx);
 }
 
 static inline u32 dsi_read_reg(struct platform_device *dsidev,
 		const struct dsi_reg idx)
 {
-	return __raw_readl(dsi.base + idx.idx);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	return __raw_readl(dsi->base + idx.idx);
 }
 
 
@@ -369,19 +379,27 @@ void dsi_restore_context(void)
 
 void dsi_bus_lock(struct omap_dss_device *dssdev)
 {
-	down(&dsi.bus_lock);
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	down(&dsi->bus_lock);
 }
 EXPORT_SYMBOL(dsi_bus_lock);
 
 void dsi_bus_unlock(struct omap_dss_device *dssdev)
 {
-	up(&dsi.bus_lock);
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	up(&dsi->bus_lock);
 }
 EXPORT_SYMBOL(dsi_bus_unlock);
 
 static bool dsi_bus_is_locked(struct platform_device *dsidev)
 {
-	return dsi.bus_lock.count == 0;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	return dsi->bus_lock.count == 0;
 }
 
 static void dsi_completion_handler(void *data, u32 mask)
@@ -405,16 +423,19 @@ static inline int wait_for_bit_change(struct platform_device *dsidev,
 #ifdef DEBUG
 static void dsi_perf_mark_setup(struct platform_device *dsidev)
 {
-	dsi.perf_setup_time = ktime_get();
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	dsi->perf_setup_time = ktime_get();
 }
 
 static void dsi_perf_mark_start(struct platform_device *dsidev)
 {
-	dsi.perf_start_time = ktime_get();
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	dsi->perf_start_time = ktime_get();
 }
 
 static void dsi_perf_show(struct platform_device *dsidev, const char *name)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	ktime_t t, setup_time, trans_time;
 	u32 total_bytes;
 	u32 setup_us, trans_us, total_us;
@@ -424,21 +445,21 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
 
 	t = ktime_get();
 
-	setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time);
+	setup_time = ktime_sub(dsi->perf_start_time, dsi->perf_setup_time);
 	setup_us = (u32)ktime_to_us(setup_time);
 	if (setup_us == 0)
 		setup_us = 1;
 
-	trans_time = ktime_sub(t, dsi.perf_start_time);
+	trans_time = ktime_sub(t, dsi->perf_start_time);
 	trans_us = (u32)ktime_to_us(trans_time);
 	if (trans_us == 0)
 		trans_us = 1;
 
 	total_us = setup_us + trans_us;
 
-	total_bytes = dsi.update_region.w *
-		dsi.update_region.h *
-		dsi.update_region.device->ctrl.pixel_size / 8;
+	total_bytes = dsi->update_region.w *
+		dsi->update_region.h *
+		dsi->update_region.device->ctrl.pixel_size / 8;
 
 	printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
 			"%u bytes, %u kbytes/sec\n",
@@ -562,19 +583,20 @@ static void print_irq_status_cio(u32 status)
 static void dsi_collect_irq_stats(struct platform_device *dsidev, u32 irqstatus,
 		u32 *vcstatus, u32 ciostatus)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int i;
 
-	spin_lock(&dsi.irq_stats_lock);
+	spin_lock(&dsi->irq_stats_lock);
 
-	dsi.irq_stats.irq_count++;
-	dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs);
+	dsi->irq_stats.irq_count++;
+	dss_collect_irq_stats(irqstatus, dsi->irq_stats.dsi_irqs);
 
 	for (i = 0; i < 4; ++i)
-		dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]);
+		dss_collect_irq_stats(vcstatus[i], dsi->irq_stats.vc_irqs[i]);
 
-	dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs);
+	dss_collect_irq_stats(ciostatus, dsi->irq_stats.cio_irqs);
 
-	spin_unlock(&dsi.irq_stats_lock);
+	spin_unlock(&dsi->irq_stats_lock);
 }
 #else
 #define dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus)
@@ -585,14 +607,15 @@ static int debug_irq;
 static void dsi_handle_irq_errors(struct platform_device *dsidev, u32 irqstatus,
 		u32 *vcstatus, u32 ciostatus)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int i;
 
 	if (irqstatus & DSI_IRQ_ERROR_MASK) {
 		DSSERR("DSI error, irqstatus %x\n", irqstatus);
 		print_irq_status(irqstatus);
-		spin_lock(&dsi.errors_lock);
-		dsi.errors |= irqstatus & DSI_IRQ_ERROR_MASK;
-		spin_unlock(&dsi.errors_lock);
+		spin_lock(&dsi->errors_lock);
+		dsi->errors |= irqstatus & DSI_IRQ_ERROR_MASK;
+		spin_unlock(&dsi->errors_lock);
 	} else if (debug_irq) {
 		print_irq_status(irqstatus);
 	}
@@ -654,18 +677,20 @@ static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables,
 static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
 {
 	struct platform_device *dsidev;
+	struct dsi_data *dsi;
 	u32 irqstatus, vcstatus[4], ciostatus;
 	int i;
 
 	dsidev = (struct platform_device *) arg;
+	dsi = dsi_get_dsi_data(dsidev);
 
-	spin_lock(&dsi.irq_lock);
+	spin_lock(&dsi->irq_lock);
 
 	irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
 
 	/* IRQ is not for us */
 	if (!irqstatus) {
-		spin_unlock(&dsi.irq_lock);
+		spin_unlock(&dsi->irq_lock);
 		return IRQ_NONE;
 	}
 
@@ -698,16 +723,17 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
 
 #ifdef DSI_CATCH_MISSING_TE
 	if (irqstatus & DSI_IRQ_TE_TRIGGER)
-		del_timer(&dsi.te_timer);
+		del_timer(&dsi->te_timer);
 #endif
 
 	/* make a copy and unlock, so that isrs can unregister
 	 * themselves */
-	memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables));
+	memcpy(&dsi->isr_tables_copy, &dsi->isr_tables,
+		sizeof(dsi->isr_tables));
 
-	spin_unlock(&dsi.irq_lock);
+	spin_unlock(&dsi->irq_lock);
 
-	dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus);
+	dsi_handle_isrs(&dsi->isr_tables_copy, irqstatus, vcstatus, ciostatus);
 
 	dsi_handle_irq_errors(dsidev, irqstatus, vcstatus, ciostatus);
 
@@ -716,7 +742,7 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-/* dsi.irq_lock has to be locked by the caller */
+/* dsi->irq_lock has to be locked by the caller */
 static void _omap_dsi_configure_irqs(struct platform_device *dsidev,
 		struct dsi_isr_data *isr_array,
 		unsigned isr_array_size, u32 default_mask,
@@ -749,51 +775,57 @@ static void _omap_dsi_configure_irqs(struct platform_device *dsidev,
 	dsi_read_reg(dsidev, status_reg);
 }
 
-/* dsi.irq_lock has to be locked by the caller */
+/* dsi->irq_lock has to be locked by the caller */
 static void _omap_dsi_set_irqs(struct platform_device *dsidev)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	u32 mask = DSI_IRQ_ERROR_MASK;
 #ifdef DSI_CATCH_MISSING_TE
 	mask |= DSI_IRQ_TE_TRIGGER;
 #endif
-	_omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table,
-			ARRAY_SIZE(dsi.isr_tables.isr_table), mask,
+	_omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table,
+			ARRAY_SIZE(dsi->isr_tables.isr_table), mask,
 			DSI_IRQENABLE, DSI_IRQSTATUS);
 }
 
-/* dsi.irq_lock has to be locked by the caller */
+/* dsi->irq_lock has to be locked by the caller */
 static void _omap_dsi_set_irqs_vc(struct platform_device *dsidev, int vc)
 {
-	_omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_vc[vc],
-			ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]),
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	_omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_vc[vc],
+			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]),
 			DSI_VC_IRQ_ERROR_MASK,
 			DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc));
 }
 
-/* dsi.irq_lock has to be locked by the caller */
+/* dsi->irq_lock has to be locked by the caller */
 static void _omap_dsi_set_irqs_cio(struct platform_device *dsidev)
 {
-	_omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_cio,
-			ARRAY_SIZE(dsi.isr_tables.isr_table_cio),
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	_omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_cio,
+			ARRAY_SIZE(dsi->isr_tables.isr_table_cio),
 			DSI_CIO_IRQ_ERROR_MASK,
 			DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS);
 }
 
 static void _dsi_initialize_irq(struct platform_device *dsidev)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	int vc;
 
-	spin_lock_irqsave(&dsi.irq_lock, flags);
+	spin_lock_irqsave(&dsi->irq_lock, flags);
 
-	memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables));
+	memset(&dsi->isr_tables, 0, sizeof(dsi->isr_tables));
 
 	_omap_dsi_set_irqs(dsidev);
 	for (vc = 0; vc < 4; ++vc)
 		_omap_dsi_set_irqs_vc(dsidev, vc);
 	_omap_dsi_set_irqs_cio(dsidev);
 
-	spin_unlock_irqrestore(&dsi.irq_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 }
 
 static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
@@ -855,18 +887,19 @@ static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask,
 static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr,
 		void *arg, u32 mask)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	int r;
 
-	spin_lock_irqsave(&dsi.irq_lock, flags);
+	spin_lock_irqsave(&dsi->irq_lock, flags);
 
-	r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table,
-			ARRAY_SIZE(dsi.isr_tables.isr_table));
+	r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table,
+			ARRAY_SIZE(dsi->isr_tables.isr_table));
 
 	if (r == 0)
 		_omap_dsi_set_irqs(dsidev);
 
-	spin_unlock_irqrestore(&dsi.irq_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
 	return r;
 }
@@ -874,18 +907,19 @@ static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr,
 static int dsi_unregister_isr(struct platform_device *dsidev,
 		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	int r;
 
-	spin_lock_irqsave(&dsi.irq_lock, flags);
+	spin_lock_irqsave(&dsi->irq_lock, flags);
 
-	r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table,
-			ARRAY_SIZE(dsi.isr_tables.isr_table));
+	r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table,
+			ARRAY_SIZE(dsi->isr_tables.isr_table));
 
 	if (r == 0)
 		_omap_dsi_set_irqs(dsidev);
 
-	spin_unlock_irqrestore(&dsi.irq_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
 	return r;
 }
@@ -893,19 +927,20 @@ static int dsi_unregister_isr(struct platform_device *dsidev,
 static int dsi_register_isr_vc(struct platform_device *dsidev, int channel,
 		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	int r;
 
-	spin_lock_irqsave(&dsi.irq_lock, flags);
+	spin_lock_irqsave(&dsi->irq_lock, flags);
 
 	r = _dsi_register_isr(isr, arg, mask,
-			dsi.isr_tables.isr_table_vc[channel],
-			ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
+			dsi->isr_tables.isr_table_vc[channel],
+			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
 
 	if (r == 0)
 		_omap_dsi_set_irqs_vc(dsidev, channel);
 
-	spin_unlock_irqrestore(&dsi.irq_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
 	return r;
 }
@@ -913,19 +948,20 @@ static int dsi_register_isr_vc(struct platform_device *dsidev, int channel,
 static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel,
 		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	int r;
 
-	spin_lock_irqsave(&dsi.irq_lock, flags);
+	spin_lock_irqsave(&dsi->irq_lock, flags);
 
 	r = _dsi_unregister_isr(isr, arg, mask,
-			dsi.isr_tables.isr_table_vc[channel],
-			ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel]));
+			dsi->isr_tables.isr_table_vc[channel],
+			ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel]));
 
 	if (r == 0)
 		_omap_dsi_set_irqs_vc(dsidev, channel);
 
-	spin_unlock_irqrestore(&dsi.irq_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
 	return r;
 }
@@ -933,18 +969,19 @@ static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel,
 static int dsi_register_isr_cio(struct platform_device *dsidev,
 		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	int r;
 
-	spin_lock_irqsave(&dsi.irq_lock, flags);
+	spin_lock_irqsave(&dsi->irq_lock, flags);
 
-	r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
-			ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
+	r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
+			ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
 
 	if (r == 0)
 		_omap_dsi_set_irqs_cio(dsidev);
 
-	spin_unlock_irqrestore(&dsi.irq_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
 	return r;
 }
@@ -952,30 +989,32 @@ static int dsi_register_isr_cio(struct platform_device *dsidev,
 static int dsi_unregister_isr_cio(struct platform_device *dsidev,
 		omap_dsi_isr_t isr, void *arg, u32 mask)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	int r;
 
-	spin_lock_irqsave(&dsi.irq_lock, flags);
+	spin_lock_irqsave(&dsi->irq_lock, flags);
 
-	r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio,
-			ARRAY_SIZE(dsi.isr_tables.isr_table_cio));
+	r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio,
+			ARRAY_SIZE(dsi->isr_tables.isr_table_cio));
 
 	if (r == 0)
 		_omap_dsi_set_irqs_cio(dsidev);
 
-	spin_unlock_irqrestore(&dsi.irq_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_lock, flags);
 
 	return r;
 }
 
 static u32 dsi_get_errors(struct platform_device *dsidev)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	u32 e;
-	spin_lock_irqsave(&dsi.errors_lock, flags);
-	e = dsi.errors;
-	dsi.errors = 0;
-	spin_unlock_irqrestore(&dsi.errors_lock, flags);
+	spin_lock_irqsave(&dsi->errors_lock, flags);
+	e = dsi->errors;
+	dsi->errors = 0;
+	spin_unlock_irqrestore(&dsi->errors_lock, flags);
 	return e;
 }
 
@@ -992,12 +1031,14 @@ static inline void enable_clocks(bool enable)
 static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
 		bool enable)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	if (enable)
 		dss_clk_enable(DSS_CLK_SYSCK);
 	else
 		dss_clk_disable(DSS_CLK_SYSCK);
 
-	if (enable && dsi.pll_locked) {
+	if (enable && dsi->pll_locked) {
 		if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
 			DSSERR("cannot lock PLL when enabling clocks\n");
 	}
@@ -1065,17 +1106,23 @@ static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
 
 unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
 {
-	return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk;
 }
 
 static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
 {
-	return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk;
 }
 
 static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
 {
-	return dsi.current_cinfo.clkin4ddr / 16;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	return dsi->current_cinfo.clkin4ddr / 16;
 }
 
 static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
@@ -1096,13 +1143,14 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
 static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long dsi_fclk;
 	unsigned lp_clk_div;
 	unsigned long lp_clk;
 
 	lp_clk_div = dssdev->clocks.dsi.lp_clk_div;
 
-	if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max)
+	if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max)
 		return -EINVAL;
 
 	dsi_fclk = dsi_fclk_rate(dsidev);
@@ -1110,8 +1158,8 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
 	lp_clk = dsi_fclk / 2 / lp_clk_div;
 
 	DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk);
-	dsi.current_cinfo.lp_clk = lp_clk;
-	dsi.current_cinfo.lp_clk_div = lp_clk_div;
+	dsi->current_cinfo.lp_clk = lp_clk;
+	dsi->current_cinfo.lp_clk_div = lp_clk_div;
 
 	/* LP_CLK_DIVISOR */
 	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
@@ -1124,14 +1172,18 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev)
 
 static void dsi_enable_scp_clk(struct platform_device *dsidev)
 {
-	if (dsi.scp_clk_refcount++ == 0)
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	if (dsi->scp_clk_refcount++ == 0)
 		REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */
 }
 
 static void dsi_disable_scp_clk(struct platform_device *dsidev)
 {
-	WARN_ON(dsi.scp_clk_refcount == 0);
-	if (--dsi.scp_clk_refcount == 0)
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	WARN_ON(dsi->scp_clk_refcount == 0);
+	if (--dsi->scp_clk_refcount == 0)
 		REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */
 }
 
@@ -1172,16 +1224,19 @@ static int dsi_pll_power(struct platform_device *dsidev,
 static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
 		struct dsi_clock_info *cinfo)
 {
-	if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max)
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max)
 		return -EINVAL;
 
-	if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max)
+	if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max)
 		return -EINVAL;
 
-	if (cinfo->regm_dispc > dsi.regm_dispc_max)
+	if (cinfo->regm_dispc > dsi->regm_dispc_max)
 		return -EINVAL;
 
-	if (cinfo->regm_dsi > dsi.regm_dsi_max)
+	if (cinfo->regm_dsi > dsi->regm_dsi_max)
 		return -EINVAL;
 
 	if (cinfo->use_sys_clk) {
@@ -1200,7 +1255,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
 
 	cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1));
 
-	if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min)
+	if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
 		return -EINVAL;
 
 	cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
@@ -1227,6 +1282,7 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
 		unsigned long req_pck, struct dsi_clock_info *dsi_cinfo,
 		struct dispc_clock_info *dispc_cinfo)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	struct dsi_clock_info cur, best;
 	struct dispc_clock_info best_dispc;
 	int min_fck_per_pck;
@@ -1237,10 +1293,10 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft,
 
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
-	if (req_pck == dsi.cache_req_pck &&
-			dsi.cache_cinfo.clkin == dss_sys_clk) {
+	if (req_pck == dsi->cache_req_pck &&
+			dsi->cache_cinfo.clkin == dss_sys_clk) {
 		DSSDBG("DSI clock info found from cache\n");
-		*dsi_cinfo = dsi.cache_cinfo;
+		*dsi_cinfo = dsi->cache_cinfo;
 		dispc_find_clk_divs(is_tft, req_pck,
 			dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo);
 		return 0;
@@ -1270,17 +1326,17 @@ retry:
 	/* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
 	/* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
 	/* To reduce PLL lock time, keep Fint high (around 2 MHz) */
-	for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) {
+	for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
 		if (cur.highfreq == 0)
 			cur.fint = cur.clkin / cur.regn;
 		else
 			cur.fint = cur.clkin / (2 * cur.regn);
 
-		if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min)
+		if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
 			continue;
 
 		/* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
-		for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) {
+		for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
 			unsigned long a, b;
 
 			a = 2 * cur.regm * (cur.clkin/1000);
@@ -1292,7 +1348,7 @@ retry:
 
 			/* dsi_pll_hsdiv_dispc_clk(MHz) =
 			 * DSIPHY(MHz) / regm_dispc  < 173MHz/186Mhz */
-			for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max;
+			for (cur.regm_dispc = 1; cur.regm_dispc < dsi->regm_dispc_max;
 					++cur.regm_dispc) {
 				struct dispc_clock_info cur_dispc;
 				cur.dsi_pll_hsdiv_dispc_clk =
@@ -1353,9 +1409,9 @@ found:
 	if (dispc_cinfo)
 		*dispc_cinfo = best_dispc;
 
-	dsi.cache_req_pck = req_pck;
-	dsi.cache_clk_freq = 0;
-	dsi.cache_cinfo = best;
+	dsi->cache_req_pck = req_pck;
+	dsi->cache_clk_freq = 0;
+	dsi->cache_cinfo = best;
 
 	return 0;
 }
@@ -1363,6 +1419,7 @@ found:
 int dsi_pll_set_clock_div(struct platform_device *dsidev,
 		struct dsi_clock_info *cinfo)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int r = 0;
 	u32 l;
 	int f = 0;
@@ -1371,20 +1428,20 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
 
 	DSSDBGF();
 
-	dsi.current_cinfo.use_sys_clk = cinfo->use_sys_clk;
-	dsi.current_cinfo.highfreq = cinfo->highfreq;
+	dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk;
+	dsi->current_cinfo.highfreq = cinfo->highfreq;
 
-	dsi.current_cinfo.fint = cinfo->fint;
-	dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr;
-	dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk =
+	dsi->current_cinfo.fint = cinfo->fint;
+	dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
+	dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk =
 			cinfo->dsi_pll_hsdiv_dispc_clk;
-	dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk =
+	dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk =
 			cinfo->dsi_pll_hsdiv_dsi_clk;
 
-	dsi.current_cinfo.regn = cinfo->regn;
-	dsi.current_cinfo.regm = cinfo->regm;
-	dsi.current_cinfo.regm_dispc = cinfo->regm_dispc;
-	dsi.current_cinfo.regm_dsi = cinfo->regm_dsi;
+	dsi->current_cinfo.regn = cinfo->regn;
+	dsi->current_cinfo.regm = cinfo->regm;
+	dsi->current_cinfo.regm_dispc = cinfo->regm_dispc;
+	dsi->current_cinfo.regm_dsi = cinfo->regm_dsi;
 
 	DSSDBG("DSI Fint %ld\n", cinfo->fint);
 
@@ -1439,7 +1496,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
 			regm_dsi_start, regm_dsi_end);
 	dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
 
-	BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max);
+	BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max);
 
 	if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
 		f = cinfo->fint < 1000000 ? 0x3 :
@@ -1476,7 +1533,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,
 		goto err;
 	}
 
-	dsi.pll_locked = 1;
+	dsi->pll_locked = 1;
 
 	l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
 	l = FLD_MOD(l, 0, 0, 0);	/* DSI_PLL_IDLE */
@@ -1503,22 +1560,23 @@ err:
 int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
 		bool enable_hsdiv)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int r = 0;
 	enum dsi_pll_power_state pwstate;
 
 	DSSDBG("PLL init\n");
 
-	if (dsi.vdds_dsi_reg == NULL) {
+	if (dsi->vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
 
-		vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
+		vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
 
 		if (IS_ERR(vdds_dsi)) {
 			DSSERR("can't get VDDS_DSI regulator\n");
 			return PTR_ERR(vdds_dsi);
 		}
 
-		dsi.vdds_dsi_reg = vdds_dsi;
+		dsi->vdds_dsi_reg = vdds_dsi;
 	}
 
 	enable_clocks(1);
@@ -1528,11 +1586,11 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
 	 */
 	dsi_enable_scp_clk(dsidev);
 
-	if (!dsi.vdds_dsi_enabled) {
-		r = regulator_enable(dsi.vdds_dsi_reg);
+	if (!dsi->vdds_dsi_enabled) {
+		r = regulator_enable(dsi->vdds_dsi_reg);
 		if (r)
 			goto err0;
-		dsi.vdds_dsi_enabled = true;
+		dsi->vdds_dsi_enabled = true;
 	}
 
 	/* XXX PLL does not come out of reset without this... */
@@ -1567,9 +1625,9 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
 
 	return 0;
 err1:
-	if (dsi.vdds_dsi_enabled) {
-		regulator_disable(dsi.vdds_dsi_reg);
-		dsi.vdds_dsi_enabled = false;
+	if (dsi->vdds_dsi_enabled) {
+		regulator_disable(dsi->vdds_dsi_reg);
+		dsi->vdds_dsi_enabled = false;
 	}
 err0:
 	dsi_disable_scp_clk(dsidev);
@@ -1580,12 +1638,14 @@ err0:
 
 void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
 {
-	dsi.pll_locked = 0;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	dsi->pll_locked = 0;
 	dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
 	if (disconnect_lanes) {
-		WARN_ON(!dsi.vdds_dsi_enabled);
-		regulator_disable(dsi.vdds_dsi_reg);
-		dsi.vdds_dsi_enabled = false;
+		WARN_ON(!dsi->vdds_dsi_enabled);
+		regulator_disable(dsi->vdds_dsi_reg);
+		dsi->vdds_dsi_enabled = false;
 	}
 
 	dsi_disable_scp_clk(dsidev);
@@ -1598,7 +1658,8 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
 void dsi_dump_clocks(struct seq_file *s)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
-	struct dsi_clock_info *cinfo = &dsi.current_cinfo;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	struct dsi_clock_info *cinfo = &dsi->current_cinfo;
 	enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
 
 	dispc_clk_src = dss_get_dispc_clk_source();
@@ -1658,16 +1719,18 @@ void dsi_dump_clocks(struct seq_file *s)
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 void dsi_dump_irqs(struct seq_file *s)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	struct dsi_irq_stats stats;
 
-	spin_lock_irqsave(&dsi.irq_stats_lock, flags);
+	spin_lock_irqsave(&dsi->irq_stats_lock, flags);
 
-	stats = dsi.irq_stats;
-	memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats));
-	dsi.irq_stats.last_reset = jiffies;
+	stats = dsi->irq_stats;
+	memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats));
+	dsi->irq_stats.last_reset = jiffies;
 
-	spin_unlock_irqrestore(&dsi.irq_stats_lock, flags);
+	spin_unlock_irqrestore(&dsi->irq_stats_lock, flags);
 
 	seq_printf(s, "period %u ms\n",
 			jiffies_to_msecs(jiffies - stats.last_reset));
@@ -1897,14 +1960,18 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev)
 
 static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	/* convert time in ns to ddr ticks, rounding up */
-	unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4;
+	unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
 	return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
 }
 
 static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
 {
-	unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4;
 	return ddr * 1000 * 1000 / (ddr_clk / 1000);
 }
 
@@ -2095,13 +2162,14 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
 static int dsi_cio_init(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int r;
 	u32 l;
 
 	DSSDBGF();
 
-	if (dsi.dsi_mux_pads)
-		dsi.dsi_mux_pads(true);
+	if (dsi->dsi_mux_pads)
+		dsi->dsi_mux_pads(true);
 
 	dsi_enable_scp_clk(dsidev);
 
@@ -2126,7 +2194,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 	l = FLD_MOD(l, 0x1fff, 12, 0);	/* STOP_STATE_COUNTER_IO */
 	dsi_write_reg(dsidev, DSI_TIMING1, l);
 
-	if (dsi.ulps_enabled) {
+	if (dsi->ulps_enabled) {
 		DSSDBG("manual ulps exit\n");
 
 		/* ULPS is exited by Mark-1 state for 1ms, followed by
@@ -2159,7 +2227,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 	if (r)
 		goto err_tx_clk_esc_rst;
 
-	if (dsi.ulps_enabled) {
+	if (dsi->ulps_enabled) {
 		/* Keep Mark-1 state for 1ms (as per DSI spec) */
 		ktime_t wait = ns_to_ktime(1000 * 1000);
 		set_current_state(TASK_UNINTERRUPTIBLE);
@@ -2175,7 +2243,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 
 	dsi_cio_timings(dsidev);
 
-	dsi.ulps_enabled = false;
+	dsi->ulps_enabled = false;
 
 	DSSDBG("CIO init done\n");
 
@@ -2186,21 +2254,23 @@ err_tx_clk_esc_rst:
 err_cio_pwr_dom:
 	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
 err_cio_pwr:
-	if (dsi.ulps_enabled)
+	if (dsi->ulps_enabled)
 		dsi_cio_disable_lane_override(dsidev);
 err_scp_clk_dom:
 	dsi_disable_scp_clk(dsidev);
-	if (dsi.dsi_mux_pads)
-		dsi.dsi_mux_pads(false);
+	if (dsi->dsi_mux_pads)
+		dsi->dsi_mux_pads(false);
 	return r;
 }
 
 static void dsi_cio_uninit(struct platform_device *dsidev)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
 	dsi_disable_scp_clk(dsidev);
-	if (dsi.dsi_mux_pads)
-		dsi.dsi_mux_pads(false);
+	if (dsi->dsi_mux_pads)
+		dsi->dsi_mux_pads(false);
 }
 
 static int _dsi_wait_reset(struct platform_device *dsidev)
@@ -2229,18 +2299,19 @@ static void dsi_config_tx_fifo(struct platform_device *dsidev,
 		enum fifo_size size1, enum fifo_size size2,
 		enum fifo_size size3, enum fifo_size size4)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	u32 r = 0;
 	int add = 0;
 	int i;
 
-	dsi.vc[0].fifo_size = size1;
-	dsi.vc[1].fifo_size = size2;
-	dsi.vc[2].fifo_size = size3;
-	dsi.vc[3].fifo_size = size4;
+	dsi->vc[0].fifo_size = size1;
+	dsi->vc[1].fifo_size = size2;
+	dsi->vc[2].fifo_size = size3;
+	dsi->vc[3].fifo_size = size4;
 
 	for (i = 0; i < 4; i++) {
 		u8 v;
-		int size = dsi.vc[i].fifo_size;
+		int size = dsi->vc[i].fifo_size;
 
 		if (add + size > 4) {
 			DSSERR("Illegal FIFO configuration\n");
@@ -2260,18 +2331,19 @@ static void dsi_config_rx_fifo(struct platform_device *dsidev,
 		enum fifo_size size1, enum fifo_size size2,
 		enum fifo_size size3, enum fifo_size size4)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	u32 r = 0;
 	int add = 0;
 	int i;
 
-	dsi.vc[0].fifo_size = size1;
-	dsi.vc[1].fifo_size = size2;
-	dsi.vc[2].fifo_size = size3;
-	dsi.vc[3].fifo_size = size4;
+	dsi->vc[0].fifo_size = size1;
+	dsi->vc[1].fifo_size = size2;
+	dsi->vc[2].fifo_size = size3;
+	dsi->vc[3].fifo_size = size4;
 
 	for (i = 0; i < 4; i++) {
 		u8 v;
-		int size = dsi.vc[i].fifo_size;
+		int size = dsi->vc[i].fifo_size;
 
 		if (add + size > 4) {
 			DSSERR("Illegal FIFO configuration\n");
@@ -2311,8 +2383,9 @@ static bool dsi_vc_is_enabled(struct platform_device *dsidev, int channel)
 static void dsi_packet_sent_handler_vp(void *data, u32 mask)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
-	const int channel = dsi.update_channel;
-	u8 bit = dsi.te_enabled ? 30 : 31;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	const int channel = dsi->update_channel;
+	u8 bit = dsi->te_enabled ? 30 : 31;
 
 	if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit) == 0)
 		complete((struct completion *)data);
@@ -2320,12 +2393,13 @@ static void dsi_packet_sent_handler_vp(void *data, u32 mask)
 
 static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int r = 0;
 	u8 bit;
 
 	DECLARE_COMPLETION_ONSTACK(completion);
 
-	bit = dsi.te_enabled ? 30 : 31;
+	bit = dsi->te_enabled ? 30 : 31;
 
 	r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
 		&completion, DSI_VC_IRQ_PACKET_SENT);
@@ -2356,7 +2430,8 @@ err0:
 static void dsi_packet_sent_handler_l4(void *data, u32 mask)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
-	const int channel = dsi.update_channel;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	const int channel = dsi->update_channel;
 
 	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5) == 0)
 		complete((struct completion *)data);
@@ -2396,6 +2471,8 @@ err0:
 
 static int dsi_sync_vc(struct platform_device *dsidev, int channel)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
 	WARN_ON(in_interrupt());
@@ -2403,7 +2480,7 @@ static int dsi_sync_vc(struct platform_device *dsidev, int channel)
 	if (!dsi_vc_is_enabled(dsidev, channel))
 		return 0;
 
-	switch (dsi.vc[channel].mode) {
+	switch (dsi->vc[channel].mode) {
 	case DSI_VC_MODE_VP:
 		return dsi_sync_vc_vp(dsidev, channel);
 	case DSI_VC_MODE_L4:
@@ -2461,7 +2538,9 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
 
 static int dsi_vc_config_l4(struct platform_device *dsidev, int channel)
 {
-	if (dsi.vc[channel].mode == DSI_VC_MODE_L4)
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	if (dsi->vc[channel].mode == DSI_VC_MODE_L4)
 		return 0;
 
 	DSSDBGF("%d", channel);
@@ -2484,14 +2563,16 @@ static int dsi_vc_config_l4(struct platform_device *dsidev, int channel)
 
 	dsi_vc_enable(dsidev, channel, 1);
 
-	dsi.vc[channel].mode = DSI_VC_MODE_L4;
+	dsi->vc[channel].mode = DSI_VC_MODE_L4;
 
 	return 0;
 }
 
 static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
 {
-	if (dsi.vc[channel].mode == DSI_VC_MODE_VP)
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	if (dsi->vc[channel].mode == DSI_VC_MODE_VP)
 		return 0;
 
 	DSSDBGF("%d", channel);
@@ -2515,7 +2596,7 @@ static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
 
 	dsi_vc_enable(dsidev, channel, 1);
 
-	dsi.vc[channel].mode = DSI_VC_MODE_VP;
+	dsi->vc[channel].mode = DSI_VC_MODE_VP;
 
 	return 0;
 }
@@ -2624,7 +2705,9 @@ static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev,
 
 static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
 {
-	if (dsi.debug_write || dsi.debug_read)
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	if (dsi->debug_write || dsi->debug_read)
 		DSSDBG("dsi_vc_send_bta %d\n", channel);
 
 	WARN_ON(!dsi_bus_is_locked(dsidev));
@@ -2688,12 +2771,13 @@ EXPORT_SYMBOL(dsi_vc_send_bta_sync);
 static inline void dsi_vc_write_long_header(struct platform_device *dsidev,
 		int channel, u8 data_type, u16 len, u8 ecc)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	u32 val;
 	u8 data_id;
 
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
-	data_id = data_type | dsi.vc[channel].vc_id << 6;
+	data_id = data_type | dsi->vc[channel].vc_id << 6;
 
 	val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
 		FLD_VAL(ecc, 31, 24);
@@ -2718,16 +2802,17 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
 		u8 data_type, u8 *data, u16 len, u8 ecc)
 {
 	/*u32 val; */
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int i;
 	u8 *p;
 	int r = 0;
 	u8 b1, b2, b3, b4;
 
-	if (dsi.debug_write)
+	if (dsi->debug_write)
 		DSSDBG("dsi_vc_send_long, %d bytes\n", len);
 
 	/* len + header */
-	if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) {
+	if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) {
 		DSSERR("unable to send long packet: packet too long.\n");
 		return -EINVAL;
 	}
@@ -2738,7 +2823,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
 
 	p = data;
 	for (i = 0; i < len >> 2; i++) {
-		if (dsi.debug_write)
+		if (dsi->debug_write)
 			DSSDBG("\tsending full packet %d\n", i);
 
 		b1 = *p++;
@@ -2753,7 +2838,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
 	if (i) {
 		b1 = 0; b2 = 0; b3 = 0;
 
-		if (dsi.debug_write)
+		if (dsi->debug_write)
 			DSSDBG("\tsending remainder bytes %d\n", i);
 
 		switch (i) {
@@ -2780,12 +2865,13 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
 static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
 		u8 data_type, u16 data, u8 ecc)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	u32 r;
 	u8 data_id;
 
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
-	if (dsi.debug_write)
+	if (dsi->debug_write)
 		DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
 				channel,
 				data_type, data & 0xff, (data >> 8) & 0xff);
@@ -2797,7 +2883,7 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
 		return -EINVAL;
 	}
 
-	data_id = data_type | dsi.vc[channel].vc_id << 6;
+	data_id = data_type | dsi->vc[channel].vc_id << 6;
 
 	r = (data_id << 0) | (data << 8) | (ecc << 24);
 
@@ -2890,11 +2976,12 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	u32 val;
 	u8 dt;
 	int r;
 
-	if (dsi.debug_read)
+	if (dsi->debug_read)
 		DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd);
 
 	r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0);
@@ -2913,7 +3000,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 	}
 
 	val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
-	if (dsi.debug_read)
+	if (dsi->debug_read)
 		DSSDBG("\theader: %08x\n", val);
 	dt = FLD_GET(val, 5, 0);
 	if (dt == DSI_DT_RX_ACK_WITH_ERR) {
@@ -2924,7 +3011,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 
 	} else if (dt == DSI_DT_RX_SHORT_READ_1) {
 		u8 data = FLD_GET(val, 15, 8);
-		if (dsi.debug_read)
+		if (dsi->debug_read)
 			DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
 
 		if (buflen < 1) {
@@ -2937,7 +3024,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		return 1;
 	} else if (dt == DSI_DT_RX_SHORT_READ_2) {
 		u16 data = FLD_GET(val, 23, 8);
-		if (dsi.debug_read)
+		if (dsi->debug_read)
 			DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
 
 		if (buflen < 2) {
@@ -2952,7 +3039,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 	} else if (dt == DSI_DT_RX_DCS_LONG_READ) {
 		int w;
 		int len = FLD_GET(val, 23, 8);
-		if (dsi.debug_read)
+		if (dsi->debug_read)
 			DSSDBG("\tDCS long response, len %d\n", len);
 
 		if (len > buflen) {
@@ -2965,7 +3052,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 			int b;
 			val = dsi_read_reg(dsidev,
 				DSI_VC_SHORT_PACKET_HEADER(channel));
-			if (dsi.debug_read)
+			if (dsi->debug_read)
 				DSSDBG("\t\t%02x %02x %02x %02x\n",
 						(val >> 0) & 0xff,
 						(val >> 8) & 0xff,
@@ -3046,6 +3133,7 @@ EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
 
 static int dsi_enter_ulps(struct platform_device *dsidev)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	DECLARE_COMPLETION_ONSTACK(completion);
 	int r;
 
@@ -3053,9 +3141,9 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
 
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
-	WARN_ON(dsi.ulps_enabled);
+	WARN_ON(dsi->ulps_enabled);
 
-	if (dsi.ulps_enabled)
+	if (dsi->ulps_enabled)
 		return 0;
 
 	if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) {
@@ -3109,7 +3197,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
 
 	dsi_if_enable(dsidev, false);
 
-	dsi.ulps_enabled = true;
+	dsi->ulps_enabled = true;
 
 	return 0;
 
@@ -3381,6 +3469,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
 {
 	/* Note: supports only 24bit colors in 32bit container */
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int first = 1;
 	int fifo_stalls = 0;
 	int max_dsi_packet_size;
@@ -3419,7 +3508,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev,
 	 * 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_dsi_packet_size = dsi->vc[0].fifo_size * 32 * 4;
 
 	/* we seem to get better perf if we divide the tx fifo to half,
 	   and while the other half is being sent, we fill the other half
@@ -3514,6 +3603,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 		u16 x, u16 y, u16 w, u16 h)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned bytespp;
 	unsigned bytespl;
 	unsigned bytespf;
@@ -3522,7 +3612,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	unsigned packet_len;
 	u32 l;
 	int r;
-	const unsigned channel = dsi.update_channel;
+	const unsigned channel = dsi->update_channel;
 	/* line buffer is 1024 x 24bits */
 	/* XXX: for some reason using full buffer size causes considerable TX
 	 * slowdown with update sizes that fill the whole buffer */
@@ -3557,7 +3647,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
 		packet_len, 0);
 
-	if (dsi.te_enabled)
+	if (dsi->te_enabled)
 		l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
 	else
 		l = FLD_MOD(l, 1, 31, 31); /* TE_START */
@@ -3573,13 +3663,13 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 
 	dsi_perf_mark_start(dsidev);
 
-	r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work,
+	r = queue_delayed_work(dsi->workqueue, &dsi->framedone_timeout_work,
 			msecs_to_jiffies(250));
 	BUG_ON(r == 0);
 
 	dss_start_update(dssdev);
 
-	if (dsi.te_enabled) {
+	if (dsi->te_enabled) {
 		/* disable LP_RX_TO, so that we can receive TE.  Time to wait
 		 * for TE is longer than the timer allows */
 		REG_FLD_MOD(dsidev, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
@@ -3587,7 +3677,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 		dsi_vc_send_bta(dsidev, channel);
 
 #ifdef DSI_CATCH_MISSING_TE
-		mod_timer(&dsi.te_timer, jiffies + msecs_to_jiffies(250));
+		mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250));
 #endif
 	}
 }
@@ -3601,15 +3691,17 @@ static void dsi_te_timeout(unsigned long arg)
 
 static void dsi_handle_framedone(struct platform_device *dsidev, int error)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	/* SIDLEMODE back to smart-idle */
 	dispc_enable_sidle();
 
-	if (dsi.te_enabled) {
+	if (dsi->te_enabled) {
 		/* enable LP_RX_TO again after the TE */
 		REG_FLD_MOD(dsidev, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
 	}
 
-	dsi.framedone_callback(error, dsi.framedone_data);
+	dsi->framedone_callback(error, dsi->framedone_data);
 
 	if (!error)
 		dsi_perf_show(dsidev, "DISPC");
@@ -3617,6 +3709,8 @@ static void dsi_handle_framedone(struct platform_device *dsidev, int error)
 
 static void dsi_framedone_timeout_work_callback(struct work_struct *work)
 {
+	struct dsi_data *dsi = container_of(work, struct dsi_data,
+			framedone_timeout_work.work);
 	/* XXX While extremely unlikely, we could get FRAMEDONE interrupt after
 	 * 250ms which would conflict with this timeout work. What should be
 	 * done is first cancel the transfer on the HW, and then cancel the
@@ -3626,19 +3720,21 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)
 
 	DSSERR("Framedone not received for 250ms!\n");
 
-	dsi_handle_framedone(dsi.pdev, -ETIMEDOUT);
+	dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);
 }
 
 static void dsi_framedone_irq_callback(void *data, u32 mask)
 {
 	struct omap_dss_device *dssdev = (struct omap_dss_device *) data;
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
 	 * turns itself off. However, DSI still has the pixels in its buffers,
 	 * and is sending the data.
 	 */
 
-	__cancel_delayed_work(&dsi.framedone_timeout_work);
+	__cancel_delayed_work(&dsi->framedone_timeout_work);
 
 	dsi_handle_framedone(dsidev, 0);
 
@@ -3689,8 +3785,9 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
 		void (*callback)(int, void *), void *data)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 
-	dsi.update_channel = channel;
+	dsi->update_channel = channel;
 
 	/* OMAP DSS cannot send updates of odd widths.
 	 * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
@@ -3699,14 +3796,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev,
 	BUG_ON(x % 2 == 1);
 
 	if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
-		dsi.framedone_callback = callback;
-		dsi.framedone_data = data;
+		dsi->framedone_callback = callback;
+		dsi->framedone_data = data;
 
-		dsi.update_region.x = x;
-		dsi.update_region.y = y;
-		dsi.update_region.w = w;
-		dsi.update_region.h = h;
-		dsi.update_region.device = dssdev;
+		dsi->update_region.x = x;
+		dsi->update_region.y = y;
+		dsi->update_region.w = w;
+		dsi->update_region.h = h;
+		dsi->update_region.device = dssdev;
 
 		dsi_update_screen_dispc(dssdev, x, y, w, h);
 	} else {
@@ -3886,8 +3983,9 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 
-	if (enter_ulps && !dsi.ulps_enabled)
+	if (enter_ulps && !dsi->ulps_enabled)
 		dsi_enter_ulps(dsidev);
 
 	/* disable interface */
@@ -3922,13 +4020,14 @@ static int dsi_core_init(struct platform_device *dsidev)
 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int r = 0;
 
 	DSSDBG("dsi_display_enable\n");
 
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
-	mutex_lock(&dsi.lock);
+	mutex_lock(&dsi->lock);
 
 	r = omap_dss_start_device(dssdev);
 	if (r) {
@@ -3953,7 +4052,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
 	if (r)
 		goto err2;
 
-	mutex_unlock(&dsi.lock);
+	mutex_unlock(&dsi->lock);
 
 	return 0;
 
@@ -3964,7 +4063,7 @@ err1:
 	dsi_enable_pll_clock(dsidev, 0);
 	omap_dss_stop_device(dssdev);
 err0:
-	mutex_unlock(&dsi.lock);
+	mutex_unlock(&dsi->lock);
 	DSSDBG("dsi_display_enable FAILED\n");
 	return r;
 }
@@ -3974,12 +4073,13 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 		bool disconnect_lanes, bool enter_ulps)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 
 	DSSDBG("dsi_display_disable\n");
 
 	WARN_ON(!dsi_bus_is_locked(dsidev));
 
-	mutex_lock(&dsi.lock);
+	mutex_lock(&dsi->lock);
 
 	dsi_display_uninit_dispc(dssdev);
 
@@ -3990,13 +4090,16 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
 
 	omap_dss_stop_device(dssdev);
 
-	mutex_unlock(&dsi.lock);
+	mutex_unlock(&dsi->lock);
 }
 EXPORT_SYMBOL(omapdss_dsi_display_disable);
 
 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
-	dsi.te_enabled = enable;
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	dsi->te_enabled = enable;
 	return 0;
 }
 EXPORT_SYMBOL(omapdss_dsi_enable_te);
@@ -4016,23 +4119,26 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
 
 int dsi_init_display(struct omap_dss_device *dssdev)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	DSSDBG("DSI init\n");
 
 	/* XXX these should be figured out dynamically */
 	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
 		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
 
-	if (dsi.vdds_dsi_reg == NULL) {
+	if (dsi->vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
 
-		vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi");
+		vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi");
 
 		if (IS_ERR(vdds_dsi)) {
 			DSSERR("can't get VDDS_DSI regulator\n");
 			return PTR_ERR(vdds_dsi);
 		}
 
-		dsi.vdds_dsi_reg = vdds_dsi;
+		dsi->vdds_dsi_reg = vdds_dsi;
 	}
 
 	return 0;
@@ -4040,11 +4146,13 @@ int dsi_init_display(struct omap_dss_device *dssdev)
 
 int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
-		if (!dsi.vc[i].dssdev) {
-			dsi.vc[i].dssdev = dssdev;
+	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
+		if (!dsi->vc[i].dssdev) {
+			dsi->vc[i].dssdev = dssdev;
 			*channel = i;
 			return 0;
 		}
@@ -4057,6 +4165,9 @@ EXPORT_SYMBOL(omap_dsi_request_vc);
 
 int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	if (vc_id < 0 || vc_id > 3) {
 		DSSERR("VC ID out of range\n");
 		return -EINVAL;
@@ -4067,13 +4178,13 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id)
 		return -EINVAL;
 	}
 
-	if (dsi.vc[channel].dssdev != dssdev) {
+	if (dsi->vc[channel].dssdev != dssdev) {
 		DSSERR("Virtual Channel not allocated to display %s\n",
 			dssdev->name);
 		return -EINVAL;
 	}
 
-	dsi.vc[channel].vc_id = vc_id;
+	dsi->vc[channel].vc_id = vc_id;
 
 	return 0;
 }
@@ -4081,10 +4192,13 @@ EXPORT_SYMBOL(omap_dsi_set_vc_id);
 
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel)
 {
+	struct platform_device *dsidev = dsi_get_dsi_device(dssdev);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	if ((channel >= 0 && channel <= 3) &&
-		dsi.vc[channel].dssdev == dssdev) {
-		dsi.vc[channel].dssdev = NULL;
-		dsi.vc[channel].vc_id = 0;
+		dsi->vc[channel].dssdev == dssdev) {
+		dsi->vc[channel].dssdev = NULL;
+		dsi->vc[channel].vc_id = 0;
 	}
 }
 EXPORT_SYMBOL(omap_dsi_release_vc);
@@ -4107,13 +4221,15 @@ void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
 
 static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
 {
-	dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
-	dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
-	dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
-	dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
-	dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
-	dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
-	dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
+	dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
+	dsi->regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
+	dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
+	dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
+	dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
+	dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
 }
 
 static int dsi_init(struct platform_device *dsidev)
@@ -4123,68 +4239,79 @@ static int dsi_init(struct platform_device *dsidev)
 	u32 rev;
 	int r, i;
 	struct resource *dsi_mem;
+	struct dsi_data *dsi;
+
+	dsi = kzalloc(sizeof(*dsi), GFP_KERNEL);
+	if (!dsi) {
+		r = -ENOMEM;
+		goto err0;
+	}
 
+	dsi->pdev = dsidev;
 	dsi_pdev_map[dsidev->id] = dsidev;
+	dev_set_drvdata(&dsidev->dev, dsi);
 
 	dss_plat_data = dsidev->dev.platform_data;
 	board_info = dss_plat_data->board_data;
-	dsi.dsi_mux_pads = board_info->dsi_mux_pads;
+	dsi->dsi_mux_pads = board_info->dsi_mux_pads;
 
-	spin_lock_init(&dsi.irq_lock);
-	spin_lock_init(&dsi.errors_lock);
-	dsi.errors = 0;
+	spin_lock_init(&dsi->irq_lock);
+	spin_lock_init(&dsi->errors_lock);
+	dsi->errors = 0;
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-	spin_lock_init(&dsi.irq_stats_lock);
-	dsi.irq_stats.last_reset = jiffies;
+	spin_lock_init(&dsi->irq_stats_lock);
+	dsi->irq_stats.last_reset = jiffies;
 #endif
 
-	mutex_init(&dsi.lock);
-	sema_init(&dsi.bus_lock, 1);
+	mutex_init(&dsi->lock);
+	sema_init(&dsi->bus_lock, 1);
 
-	dsi.workqueue = create_singlethread_workqueue("dsi");
-	if (dsi.workqueue == NULL)
-		return -ENOMEM;
+	dsi->workqueue = create_singlethread_workqueue(dev_name(&dsidev->dev));
+	if (dsi->workqueue == NULL) {
+		r = -ENOMEM;
+		goto err1;
+	}
 
-	INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work,
+	INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work,
 			dsi_framedone_timeout_work_callback);
 
 #ifdef DSI_CATCH_MISSING_TE
-	init_timer(&dsi.te_timer);
-	dsi.te_timer.function = dsi_te_timeout;
-	dsi.te_timer.data = 0;
+	init_timer(&dsi->te_timer);
+	dsi->te_timer.function = dsi_te_timeout;
+	dsi->te_timer.data = 0;
 #endif
-	dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0);
+	dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
 	if (!dsi_mem) {
 		DSSERR("can't get IORESOURCE_MEM DSI\n");
 		r = -EINVAL;
-		goto err1;
+		goto err2;
 	}
-	dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem));
-	if (!dsi.base) {
+	dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem));
+	if (!dsi->base) {
 		DSSERR("can't ioremap DSI\n");
 		r = -ENOMEM;
-		goto err1;
+		goto err2;
 	}
-	dsi.irq	= platform_get_irq(dsi.pdev, 0);
-	if (dsi.irq < 0) {
+	dsi->irq = platform_get_irq(dsi->pdev, 0);
+	if (dsi->irq < 0) {
 		DSSERR("platform_get_irq failed\n");
 		r = -ENODEV;
-		goto err2;
+		goto err3;
 	}
 
-	r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED,
-		"OMAP DSI1", dsi.pdev);
+	r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED,
+		dev_name(&dsidev->dev), dsi->pdev);
 	if (r < 0) {
 		DSSERR("request_irq failed\n");
-		goto err2;
+		goto err3;
 	}
 
 	/* DSI VCs initialization */
-	for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) {
-		dsi.vc[i].mode = DSI_VC_MODE_L4;
-		dsi.vc[i].dssdev = NULL;
-		dsi.vc[i].vc_id = 0;
+	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
+		dsi->vc[i].mode = DSI_VC_MODE_L4;
+		dsi->vc[i].dssdev = NULL;
+		dsi->vc[i].vc_id = 0;
 	}
 
 	dsi_calc_clock_param_ranges(dsidev);
@@ -4198,29 +4325,35 @@ static int dsi_init(struct platform_device *dsidev)
 	enable_clocks(0);
 
 	return 0;
+err3:
+	iounmap(dsi->base);
 err2:
-	iounmap(dsi.base);
+	destroy_workqueue(dsi->workqueue);
 err1:
-	destroy_workqueue(dsi.workqueue);
+	kfree(dsi);
+err0:
 	return r;
 }
 
 static void dsi_exit(struct platform_device *dsidev)
 {
-	if (dsi.vdds_dsi_reg != NULL) {
-		if (dsi.vdds_dsi_enabled) {
-			regulator_disable(dsi.vdds_dsi_reg);
-			dsi.vdds_dsi_enabled = false;
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
+	if (dsi->vdds_dsi_reg != NULL) {
+		if (dsi->vdds_dsi_enabled) {
+			regulator_disable(dsi->vdds_dsi_reg);
+			dsi->vdds_dsi_enabled = false;
 		}
 
-		regulator_put(dsi.vdds_dsi_reg);
-		dsi.vdds_dsi_reg = NULL;
+		regulator_put(dsi->vdds_dsi_reg);
+		dsi->vdds_dsi_reg = NULL;
 	}
 
-	free_irq(dsi.irq, dsi.pdev);
-	iounmap(dsi.base);
+	free_irq(dsi->irq, dsi->pdev);
+	iounmap(dsi->base);
 
-	destroy_workqueue(dsi.workqueue);
+	destroy_workqueue(dsi->workqueue);
+	kfree(dsi);
 
 	DSSDBG("omap_dsi_exit\n");
 }
@@ -4229,7 +4362,7 @@ static void dsi_exit(struct platform_device *dsidev)
 static int omap_dsihw_probe(struct platform_device *dsidev)
 {
 	int r;
-	dsi.pdev = dsidev;
+
 	r = dsi_init(dsidev);
 	if (r) {
 		DSSERR("Failed to initialize DSI\n");
@@ -4241,8 +4374,10 @@ err_dsi:
 
 static int omap_dsihw_remove(struct platform_device *dsidev)
 {
+	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+
 	dsi_exit(dsidev);
-	WARN_ON(dsi.scp_clk_refcount > 0);
+	WARN_ON(dsi->scp_clk_refcount > 0);
 	return 0;
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 6/9] OMAP: DSS2: DSI: Pass pointer to struct to packet_sent_handler isrs
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
                   ` (4 preceding siblings ...)
  2011-05-04  7:38 ` [PATCH 5/9] OMAP: DSS2: DSI: Use platform_device pointer to get dsi data Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  7:38 ` [PATCH 7/9] OMAP4: DSS2: DSI: Changes for DSI2 on OMAP4 Archit Taneja
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

dsi_packet_sent_handler_vp() and dsi_packet_sent_handler_l4() currently
receive the completion parameter as their argument. This is not sufficient
information to differentiate between DSI1 and DSI2 platform devices.

Pass the struct "dsi_packet_sent_handler_data" to the packet_sent_handler
isrs, these contain the platform_device pointer of the DSI device and the
pointer to the completion struct.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   43 +++++++++++++++++++++++-----------------
 1 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 627869e..a8478be 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -330,6 +330,11 @@ struct dsi_data {
 	unsigned scp_clk_refcount;
 };
 
+struct dsi_packet_sent_handler_data {
+	struct platform_device *dsidev;
+	struct completion *completion;
+};
+
 static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
 
 #ifdef DEBUG
@@ -2382,27 +2387,28 @@ static bool dsi_vc_is_enabled(struct platform_device *dsidev, int channel)
 
 static void dsi_packet_sent_handler_vp(void *data, u32 mask)
 {
-	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
-	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	struct dsi_packet_sent_handler_data *vp_data =
+		(struct dsi_packet_sent_handler_data *) data;
+	struct dsi_data *dsi = dsi_get_dsi_data(vp_data->dsidev);
 	const int channel = dsi->update_channel;
 	u8 bit = dsi->te_enabled ? 30 : 31;
 
-	if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit) == 0)
-		complete((struct completion *)data);
+	if (REG_GET(vp_data->dsidev, DSI_VC_TE(channel), bit, bit) == 0)
+		complete(vp_data->completion);
 }
 
 static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel)
 {
 	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	DECLARE_COMPLETION_ONSTACK(completion);
+	struct dsi_packet_sent_handler_data vp_data = { dsidev, &completion };
 	int r = 0;
 	u8 bit;
 
-	DECLARE_COMPLETION_ONSTACK(completion);
-
 	bit = dsi->te_enabled ? 30 : 31;
 
 	r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
-		&completion, DSI_VC_IRQ_PACKET_SENT);
+		&vp_data, DSI_VC_IRQ_PACKET_SENT);
 	if (r)
 		goto err0;
 
@@ -2417,34 +2423,35 @@ static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel)
 	}
 
 	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
-		&completion, DSI_VC_IRQ_PACKET_SENT);
+		&vp_data, DSI_VC_IRQ_PACKET_SENT);
 
 	return 0;
 err1:
 	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp,
-		&completion, DSI_VC_IRQ_PACKET_SENT);
+		&vp_data, DSI_VC_IRQ_PACKET_SENT);
 err0:
 	return r;
 }
 
 static void dsi_packet_sent_handler_l4(void *data, u32 mask)
 {
-	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
-	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
+	struct dsi_packet_sent_handler_data *l4_data =
+		(struct dsi_packet_sent_handler_data *) data;
+	struct dsi_data *dsi = dsi_get_dsi_data(l4_data->dsidev);
 	const int channel = dsi->update_channel;
 
-	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5) == 0)
-		complete((struct completion *)data);
+	if (REG_GET(l4_data->dsidev, DSI_VC_CTRL(channel), 5, 5) == 0)
+		complete(l4_data->completion);
 }
 
 static int dsi_sync_vc_l4(struct platform_device *dsidev, int channel)
 {
-	int r = 0;
-
 	DECLARE_COMPLETION_ONSTACK(completion);
+	struct dsi_packet_sent_handler_data l4_data = { dsidev, &completion };
+	int r = 0;
 
 	r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
-		&completion, DSI_VC_IRQ_PACKET_SENT);
+		&l4_data, DSI_VC_IRQ_PACKET_SENT);
 	if (r)
 		goto err0;
 
@@ -2459,12 +2466,12 @@ static int dsi_sync_vc_l4(struct platform_device *dsidev, int channel)
 	}
 
 	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
-		&completion, DSI_VC_IRQ_PACKET_SENT);
+		&l4_data, DSI_VC_IRQ_PACKET_SENT);
 
 	return 0;
 err1:
 	dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4,
-		&completion, DSI_VC_IRQ_PACKET_SENT);
+		&l4_data, DSI_VC_IRQ_PACKET_SENT);
 err0:
 	return r;
 }
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 7/9] OMAP4: DSS2: DSI: Changes for DSI2 on OMAP4
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
                   ` (5 preceding siblings ...)
  2011-05-04  7:38 ` [PATCH 6/9] OMAP: DSS2: DSI: Pass pointer to struct to packet_sent_handler isrs Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  7:38 ` [PATCH 8/9] OMAP: DSS2: DSI: Build a platform device instance for DSI2 Archit Taneja
  2011-05-04  7:38 ` [PATCH 9/9] OMAP: DSS2: Taal: Use device name in backlight_device_register Archit Taneja
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Introduce DSI2 PLL clock sources needed by LCD2 channel and DSI2 Protocol
engine and DISPC Functional clock. Do the following:

- Modify dss_get_dsi_clk_source() and dss_select_dsi_clk_source() to take the
  dsi module number as an argument.
- Create debugfs files for dsi2, split the corresponding debugfs functions.
- Split packet_sent_handler irqs for dsi1 and dsi2.
- Allow DPI to use these new clock sources.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 arch/arm/plat-omap/include/plat/display.h |    2 +
 drivers/video/omap2/dss/core.c            |   14 ++++--
 drivers/video/omap2/dss/dispc.c           |    8 +++
 drivers/video/omap2/dss/dpi.c             |    6 ++-
 drivers/video/omap2/dss/dsi.c             |   73 ++++++++++++++++++++++------
 drivers/video/omap2/dss/dss.c             |   36 +++++++++++---
 drivers/video/omap2/dss/dss.h             |   15 ++++--
 drivers/video/omap2/dss/dss_features.c    |    5 ++-
 drivers/video/omap2/dss/dss_features.h    |    1 +
 9 files changed, 126 insertions(+), 34 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 6305ff6..5568984 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -181,6 +181,8 @@ enum omap_dss_clk_source {
 						 * OMAP4: PLL1_CLK1 */
 	OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,	/* OMAP3: DSI2_PLL_FCLK
 						 * OMAP4: PLL1_CLK2 */
+	OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,	/* OMAP4: PLL2_CLK1 */
+	OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,	/* OMAP4: PLL2_CLK2 */
 };
 
 /* RFBI */
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 9bcb0b8..9c52e38 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -127,8 +127,11 @@ static int dss_initialize_debugfs(void)
 #endif
 
 #if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
-	debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
-			&dsi_dump_irqs, &dss_debug_fops);
+	debugfs_create_file("dsi1_irq", S_IRUGO, dss_debugfs_dir,
+			&dsi1_dump_irqs, &dss_debug_fops);
+	if (dss_has_feature(FEAT_DSS_DSI2))
+		debugfs_create_file("dsi2_irq", S_IRUGO, dss_debugfs_dir,
+			&dsi2_dump_irqs, &dss_debug_fops);
 #endif
 
 	debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
@@ -140,8 +143,11 @@ static int dss_initialize_debugfs(void)
 			&rfbi_dump_regs, &dss_debug_fops);
 #endif
 #ifdef CONFIG_OMAP2_DSS_DSI
-	debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir,
-			&dsi_dump_regs, &dss_debug_fops);
+	debugfs_create_file("dsi1", S_IRUGO, dss_debugfs_dir,
+			&dsi1_dump_regs, &dss_debug_fops);
+	if (dss_has_feature(FEAT_DSS_DSI2))
+		debugfs_create_file("dsi2", S_IRUGO, dss_debugfs_dir,
+				&dsi2_dump_regs, &dss_debug_fops);
 #endif
 #ifdef CONFIG_OMAP2_DSS_VENC
 	debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 7927660..92a1172 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2364,6 +2364,10 @@ unsigned long dispc_fclk_rate(void)
 		dsidev = dsi_get_dsi_device_module(0);
 		r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
 		break;
+	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+		dsidev = dsi_get_dsi_device_module(1);
+		r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+		break;
 	default:
 		BUG();
 	}
@@ -2390,6 +2394,10 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
 		dsidev = dsi_get_dsi_device_module(0);
 		r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
 		break;
+	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+		dsidev = dsi_get_dsi_device_module(1);
+		r = dsi_get_pll_hsdiv_dispc_rate(dsidev);
+		break;
 	default:
 		BUG();
 	}
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 97d7985..7f65ee2 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -53,8 +53,12 @@ static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev)
 {
 	if (dssdev->clocks.dispc.dispc_fclk_src ==
 			OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
+			dssdev->clocks.dispc.dispc_fclk_src ==
+			OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC ||
 			dssdev->clocks.dispc.channel.lcd_clk_src ==
-			OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)
+			OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ||
+			dssdev->clocks.dispc.channel.lcd_clk_src ==
+			OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC)
 		return true;
 	else
 		return false;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index a8478be..eead89a 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1134,7 +1134,7 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
 {
 	unsigned long r;
 
-	if (dss_get_dsi_clk_source() == OMAP_DSS_CLK_SRC_FCK) {
+	if (dss_get_dsi_clk_source(dsidev->id) == OMAP_DSS_CLK_SRC_FCK) {
 		/* DSI FCLK source is DSS_CLK_FCK */
 		r = dss_clk_get_rate(DSS_CLK_FCK);
 	} else {
@@ -1660,19 +1660,18 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
 	DSSDBG("PLL uninit done\n");
 }
 
-void dsi_dump_clocks(struct seq_file *s)
+static void dsi_dump_clocks(struct platform_device *dsidev, struct seq_file *s)
 {
-	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
 	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	struct dsi_clock_info *cinfo = &dsi->current_cinfo;
 	enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
 
 	dispc_clk_src = dss_get_dispc_clk_source();
-	dsi_clk_src = dss_get_dsi_clk_source();
+	dsi_clk_src = dss_get_dsi_clk_source(dsidev->id);
 
 	enable_clocks(1);
 
-	seq_printf(s,	"- DSI PLL -\n");
+	seq_printf(s,	"- DSI%d PLL -\n", dsidev->id + 1);
 
 	seq_printf(s,	"dsi pll source = %s\n",
 			cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree");
@@ -1698,7 +1697,7 @@ void dsi_dump_clocks(struct seq_file *s)
 			dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
 			"off" : "on");
 
-	seq_printf(s,	"- DSI -\n");
+	seq_printf(s,	"- DSI%d -\n", dsidev->id + 1);
 
 	seq_printf(s,	"dsi fclk source = %s (%s)\n",
 			dss_get_generic_clk_source_name(dsi_clk_src),
@@ -1721,10 +1720,21 @@ void dsi_dump_clocks(struct seq_file *s)
 	enable_clocks(0);
 }
 
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
-void dsi_dump_irqs(struct seq_file *s)
+void dsi1_dump_clocks(struct seq_file *s)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
+	dsi_dump_clocks(dsidev, s);
+}
+
+void dsi2_dump_clocks(struct seq_file *s)
+{
+	struct platform_device *dsidev = dsi_get_dsi_device_module(1);
+	dsi_dump_clocks(dsidev, s);
+}
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+static void dsi_dump_irqs(struct platform_device *dsidev, struct seq_file *s)
+{
 	struct dsi_data *dsi = dsi_get_dsi_data(dsidev);
 	unsigned long flags;
 	struct dsi_irq_stats stats;
@@ -1744,7 +1754,7 @@ void dsi_dump_irqs(struct seq_file *s)
 #define PIS(x) \
 	seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]);
 
-	seq_printf(s, "-- DSI interrupts --\n");
+	seq_printf(s, "-- DSI%d interrupts --\n", dsidev->id + 1);
 	PIS(VC0);
 	PIS(VC1);
 	PIS(VC2);
@@ -1810,12 +1820,22 @@ void dsi_dump_irqs(struct seq_file *s)
 	PIS(ULPSACTIVENOT_ALL1);
 #undef PIS
 }
-#endif
 
-void dsi_dump_regs(struct seq_file *s)
+void dsi1_dump_irqs(struct seq_file *s)
 {
 	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
+	dsi_dump_irqs(dsidev, s);
+}
+
+void dsi2_dump_irqs(struct seq_file *s)
+{
+	struct platform_device *dsidev = dsi_get_dsi_device_module(1);
+	dsi_dump_irqs(dsidev, s);
+}
+#endif
 
+static void dsi_dump_regs(struct platform_device *dsidev, struct seq_file *s)
+{
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r))
 
 	dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
@@ -1896,6 +1916,18 @@ void dsi_dump_regs(struct seq_file *s)
 #undef DUMPREG
 }
 
+void dsi1_dump_regs(struct seq_file *s)
+{
+	struct platform_device *dsidev = dsi_get_dsi_device_module(0);
+	dsi_dump_regs(dsidev, s);
+}
+
+void dsi2_dump_regs(struct seq_file *s)
+{
+	struct platform_device *dsidev = dsi_get_dsi_device_module(1);
+	dsi_dump_regs(dsidev, s);
+}
+
 enum dsi_cio_power_state {
 	DSI_COMPLEXIO_POWER_OFF		= 0x0,
 	DSI_COMPLEXIO_POWER_ON		= 0x1,
@@ -3833,9 +3865,13 @@ EXPORT_SYMBOL(omap_dsi_update);
 static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 {
 	int r;
+	u32 irq;
+
+	irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
+		DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
 
 	r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev,
-			DISPC_IRQ_FRAMEDONE);
+			irq);
 	if (r) {
 		DSSERR("can't get FRAMEDONE irq\n");
 		return r;
@@ -3868,8 +3904,13 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 
 static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
 {
+	u32 irq;
+
+	irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
+		DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
+
 	omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev,
-			DISPC_IRQ_FRAMEDONE);
+			irq);
 }
 
 static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
@@ -3940,7 +3981,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
 		goto err1;
 
 	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
-	dss_select_dsi_clk_source(dssdev->clocks.dsi.dsi_fclk_src);
+	dss_select_dsi_clk_source(dsidev->id, dssdev->clocks.dsi.dsi_fclk_src);
 	dss_select_lcd_clk_source(dssdev->manager->id,
 			dssdev->clocks.dispc.channel.lcd_clk_src);
 
@@ -3979,7 +4020,7 @@ err3:
 	dsi_cio_uninit(dsidev);
 err2:
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
-	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
+	dss_select_dsi_clk_source(dsidev->id, OMAP_DSS_CLK_SRC_FCK);
 err1:
 	dsi_pll_uninit(dsidev, true);
 err0:
@@ -4003,7 +4044,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
 	dsi_vc_enable(dsidev, 3, 0);
 
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
-	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
+	dss_select_dsi_clk_source(dsidev->id, OMAP_DSS_CLK_SRC_FCK);
 	dsi_cio_uninit(dsidev);
 	dsi_pll_uninit(dsidev, disconnect_lanes);
 }
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 30f4c02..be4eb69 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -75,7 +75,7 @@ static struct {
 	struct dss_clock_info cache_dss_cinfo;
 	struct dispc_clock_info cache_dispc_cinfo;
 
-	enum omap_dss_clk_source dsi_clk_source;
+	enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
 	enum omap_dss_clk_source dispc_clk_source;
 	enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
 
@@ -315,6 +315,11 @@ void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 		dsidev = dsi_get_dsi_device_module(0);
 		dsi_wait_pll_hsdiv_dispc_active(dsidev);
 		break;
+	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+		b = 2;
+		dsidev = dsi_get_dsi_device_module(1);
+		dsi_wait_pll_hsdiv_dispc_active(dsidev);
+		break;
 	default:
 		BUG();
 	}
@@ -326,7 +331,8 @@ void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
 	dss.dispc_clk_source = clk_src;
 }
 
-void dss_select_dsi_clk_source(enum omap_dss_clk_source clk_src)
+void dss_select_dsi_clk_source(int dsi_module,
+		enum omap_dss_clk_source clk_src)
 {
 	struct platform_device *dsidev;
 	int b;
@@ -336,17 +342,24 @@ void dss_select_dsi_clk_source(enum omap_dss_clk_source clk_src)
 		b = 0;
 		break;
 	case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
+		BUG_ON(dsi_module != 0);
 		b = 1;
 		dsidev = dsi_get_dsi_device_module(0);
 		dsi_wait_pll_hsdiv_dsi_active(dsidev);
 		break;
+	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
+		BUG_ON(dsi_module != 1);
+		b = 1;
+		dsidev = dsi_get_dsi_device_module(1);
+		dsi_wait_pll_hsdiv_dsi_active(dsidev);
+		break;
 	default:
 		BUG();
 	}
 
 	REG_FLD_MOD(DSS_CONTROL, b, 1, 1);	/* DSI_CLK_SWITCH */
 
-	dss.dsi_clk_source = clk_src;
+	dss.dsi_clk_source[dsi_module] = clk_src;
 }
 
 void dss_select_lcd_clk_source(enum omap_channel channel,
@@ -368,6 +381,12 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
 		dsidev = dsi_get_dsi_device_module(0);
 		dsi_wait_pll_hsdiv_dispc_active(dsidev);
 		break;
+	case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
+		BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2);
+		b = 1;
+		dsidev = dsi_get_dsi_device_module(1);
+		dsi_wait_pll_hsdiv_dispc_active(dsidev);
+		break;
 	default:
 		BUG();
 	}
@@ -384,9 +403,9 @@ enum omap_dss_clk_source dss_get_dispc_clk_source(void)
 	return dss.dispc_clk_source;
 }
 
-enum omap_dss_clk_source dss_get_dsi_clk_source(void)
+enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module)
 {
-	return dss.dsi_clk_source;
+	return dss.dsi_clk_source[dsi_module];
 }
 
 enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
@@ -717,7 +736,8 @@ static int dss_init(void)
 
 	dss.dpll4_m4_ck = dpll4_m4_ck;
 
-	dss.dsi_clk_source = OMAP_DSS_CLK_SRC_FCK;
+	dss.dsi_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
+	dss.dsi_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
 	dss.dispc_clk_source = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
 	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
@@ -1066,7 +1086,9 @@ void dss_debug_dump_clocks(struct seq_file *s)
 	dss_dump_clocks(s);
 	dispc_dump_clocks(s);
 #ifdef CONFIG_OMAP2_DSS_DSI
-	dsi_dump_clocks(s);
+	dsi1_dump_clocks(s);
+	if (dss_has_feature(FEAT_DSS_DSI2))
+		dsi2_dump_clocks(s);
 #endif
 }
 #endif
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index bca64f9..216c87a 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -240,11 +240,12 @@ int dss_sdi_enable(void);
 void dss_sdi_disable(void);
 
 void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src);
-void dss_select_dsi_clk_source(enum omap_dss_clk_source clk_src);
+void dss_select_dsi_clk_source(int dsi_module,
+		enum omap_dss_clk_source clk_src);
 void dss_select_lcd_clk_source(enum omap_channel channel,
 		enum omap_dss_clk_source clk_src);
 enum omap_dss_clk_source dss_get_dispc_clk_source(void);
-enum omap_dss_clk_source dss_get_dsi_clk_source(void);
+enum omap_dss_clk_source dss_get_dsi_clk_source(int dsi_module);
 enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
 
 void dss_set_venc_output(enum omap_dss_venc_type type);
@@ -278,9 +279,13 @@ static inline void sdi_exit(void)
 int dsi_init_platform_driver(void);
 void dsi_uninit_platform_driver(void);
 
-void dsi_dump_clocks(struct seq_file *s);
-void dsi_dump_irqs(struct seq_file *s);
-void dsi_dump_regs(struct seq_file *s);
+void dsi1_dump_clocks(struct seq_file *s);
+void dsi1_dump_irqs(struct seq_file *s);
+void dsi1_dump_regs(struct seq_file *s);
+
+void dsi2_dump_clocks(struct seq_file *s);
+void dsi2_dump_irqs(struct seq_file *s);
+void dsi2_dump_regs(struct seq_file *s);
 
 void dsi_save_context(void);
 void dsi_restore_context(void);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index f8c9503..2809239 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -193,6 +193,8 @@ static const char * const omap4_dss_clk_source_names[] = {
 	[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]	= "PLL1_CLK1",
 	[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]	= "PLL1_CLK2",
 	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_FCLK",
+	[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC]	= "PLL2_CLK1",
+	[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]	= "PLL2_CLK2",
 };
 
 static const struct dss_param_range omap2_dss_param_range[] = {
@@ -292,7 +294,8 @@ static const struct omap_dss_features omap4_dss_features = {
 		FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
 		FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
 		FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
-		FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH,
+		FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
+		FEAT_DSS_DSI2,
 
 	.num_mgrs = 3,
 	.num_ovls = 3,
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 857162b..cc74523 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -47,6 +47,7 @@ enum dss_feat_id {
 	FEAT_DSI_DCS_CMD_CONFIG_VC	= 1 << 15,
 	FEAT_DSI_VC_OCP_WIDTH		= 1 << 16,
 	FEAT_DSI_REVERSE_TXCLKESC	= 1 << 17,
+	FEAT_DSS_DSI2			= 1 << 18,
 };
 
 /* DSS register field id */
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 8/9] OMAP: DSS2: DSI: Build a platform device instance for DSI2
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
                   ` (6 preceding siblings ...)
  2011-05-04  7:38 ` [PATCH 7/9] OMAP4: DSS2: DSI: Changes for DSI2 on OMAP4 Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  2011-05-04  7:38 ` [PATCH 9/9] OMAP: DSS2: Taal: Use device name in backlight_device_register Archit Taneja
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Create a platform device instance for DSI2. Use "dss_dsi2" hwmod name and
"omapdss_dsi" platfrom device name to build the platform_device instance. Add
"omapdss_dsi.1" as a regulator consumer for "vdds_dsi".

Signed-off-by: Archit Taneja <archit@ti.com>
---
 arch/arm/mach-omap2/board-4430sdp.c |    1 +
 arch/arm/mach-omap2/display.c       |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index eafadb4..1f48499 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -376,6 +376,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
 static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
 	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"),
 };
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index f0e9cbf..07ac97d 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -83,6 +83,7 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
 	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
+	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
 };
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 9/9] OMAP: DSS2: Taal: Use device name in backlight_device_register
  2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
                   ` (7 preceding siblings ...)
  2011-05-04  7:38 ` [PATCH 8/9] OMAP: DSS2: DSI: Build a platform device instance for DSI2 Archit Taneja
@ 2011-05-04  7:38 ` Archit Taneja
  8 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04  7:38 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Panel Taal driver uses the string "taal" to register for a backlight device.
This causes backlight_device_register() to fail when a second taal panel
is added. Use dev_name(&dssdev->dev) as a parameter instead of the string.

Note: This will break backlight related sysfs commands. Use the name as
generated by the DSS2 driver, in the form "displayi", which represents
the ith registered display device.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index c5a61d0..17244cb 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1031,8 +1031,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
 		props.max_brightness = 127;
 
 	props.type = BACKLIGHT_RAW;
-	bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
-					  &taal_bl_ops, &props);
+	bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev,
+					dssdev, &taal_bl_ops, &props);
 	if (IS_ERR(bldev)) {
 		r = PTR_ERR(bldev);
 		goto err_bl;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04  7:38 ` [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi" Archit Taneja
@ 2011-05-04  9:40   ` Tony Lindgren
  2011-05-04 10:53     ` Tomi Valkeinen
                       ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Tony Lindgren @ 2011-05-04  9:40 UTC (permalink / raw)
  To: Archit Taneja; +Cc: tomi.valkeinen, linux-omap

* Archit Taneja <archit@ti.com> [110504 10:30]:
> --- a/arch/arm/mach-omap2/board-3430sdp.c
> +++ b/arch/arm/mach-omap2/board-3430sdp.c
> @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
>  /* VPLL2 for digital video outputs */
>  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
>  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
>  };
>  
>  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> index 570e83f..eafadb4 100644
> --- a/arch/arm/mach-omap2/board-4430sdp.c
> +++ b/arch/arm/mach-omap2/board-4430sdp.c
> @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
>  };
>  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
>  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
>  };
...

Looks like we should first combine all this cut and paste data
for each board file into some common init function to cut
down the "crazy churn".

Tony

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04  9:40   ` Tony Lindgren
@ 2011-05-04 10:53     ` Tomi Valkeinen
  2011-05-04 11:21       ` Tomi Valkeinen
  2011-05-04 12:17       ` Tony Lindgren
  2011-05-05 11:36     ` Tomi Valkeinen
  2011-06-07 13:11     ` Tomi Valkeinen
  2 siblings, 2 replies; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-04 10:53 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Archit Taneja, linux-omap

On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> * Archit Taneja <archit@ti.com> [110504 10:30]:
> > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> >  /* VPLL2 for digital video outputs */
> >  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> >  };
> >  
> >  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > index 570e83f..eafadb4 100644
> > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
> >  };
> >  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> >  };
> ...
> 
> Looks like we should first combine all this cut and paste data
> for each board file into some common init function to cut
> down the "crazy churn".

I was actually thinking about this earlier today.

All the boards I have seen use vdds_dsi the same way (depending on the
omap version, though). For OMAP3 it comes from VPPL2 and for OMAP4 it's
VCXIO. Optimally a common piece of code would just set up the regulator
properly.

But I think in the end the config has to come from the board data, as I
don't see that the above config would be the only possibility. The
vdds_dsi could be supplied from anywhere (with suitable voltage, of
course), as far as I understand.

What we could do is:

1. The board file tells the common display code which regulator is used
for vdds_dsi, and the common code can setup the regulator supply for all
DSS devices which need it (omapdss_dss, omapdss_dsi1, omapdss_dsi2).

I guess this needs dynamically adding the regulator supply in display.c,
and I'm not quite sure if that's possible. We have to look at this.

2. The common code could default to the power source that is most
commonly used, so the board file would have to config the regulator only
if it uses a non-common one.

Together 1. and 2. would remove the DSS regulator stuff totally from the
board files. But regulators for the panels would still be in the board
files, of course.

 Tomi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04 10:53     ` Tomi Valkeinen
@ 2011-05-04 11:21       ` Tomi Valkeinen
  2011-05-04 12:11         ` Archit Taneja
  2011-05-04 12:17       ` Tony Lindgren
  1 sibling, 1 reply; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-04 11:21 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Archit Taneja, linux-omap

On Wed, 2011-05-04 at 13:53 +0300, Tomi Valkeinen wrote:
> On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> > * Archit Taneja <archit@ti.com> [110504 10:30]:
> > > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > > @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> > >  /* VPLL2 for digital video outputs */
> > >  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > >  
> > >  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> > > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > > index 570e83f..eafadb4 100644
> > > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > > @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
> > >  };
> > >  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > ...
> > 
> > Looks like we should first combine all this cut and paste data
> > for each board file into some common init function to cut
> > down the "crazy churn".
> 
> I was actually thinking about this earlier today.
> 
> All the boards I have seen use vdds_dsi the same way (depending on the
> omap version, though). For OMAP3 it comes from VPPL2 and for OMAP4 it's
> VCXIO. Optimally a common piece of code would just set up the regulator
> properly.
> 
> But I think in the end the config has to come from the board data, as I
> don't see that the above config would be the only possibility. The
> vdds_dsi could be supplied from anywhere (with suitable voltage, of
> course), as far as I understand.
> 
> What we could do is:
> 
> 1. The board file tells the common display code which regulator is used
> for vdds_dsi, and the common code can setup the regulator supply for all
> DSS devices which need it (omapdss_dss, omapdss_dsi1, omapdss_dsi2).
> 
> I guess this needs dynamically adding the regulator supply in display.c,
> and I'm not quite sure if that's possible. We have to look at this.

I don't see how this would be possible. As far as I see, the regulator
consumers have to be given statically at init time. We could get the
whole VPLL2 or VCXIO supply array from a common display code, but that
would prevent adding any other consumers to those regulators, so that's
not an option either.

 Tomi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04 11:21       ` Tomi Valkeinen
@ 2011-05-04 12:11         ` Archit Taneja
  0 siblings, 0 replies; 31+ messages in thread
From: Archit Taneja @ 2011-05-04 12:11 UTC (permalink / raw)
  To: Valkeinen, Tomi; +Cc: Tony Lindgren, linux-omap@vger.kernel.org

On Wednesday 04 May 2011 04:51 PM, Valkeinen, Tomi wrote:
> On Wed, 2011-05-04 at 13:53 +0300, Tomi Valkeinen wrote:
>> On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
>>> * Archit Taneja<archit@ti.com>  [110504 10:30]:
>>>> --- a/arch/arm/mach-omap2/board-3430sdp.c
>>>> +++ b/arch/arm/mach-omap2/board-3430sdp.c
>>>> @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
>>>>   /* VPLL2 for digital video outputs */
>>>>   static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
>>>>   	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
>>>> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
>>>> +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
>>>>   };
>>>>
>>>>   static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
>>>> diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
>>>> index 570e83f..eafadb4 100644
>>>> --- a/arch/arm/mach-omap2/board-4430sdp.c
>>>> +++ b/arch/arm/mach-omap2/board-4430sdp.c
>>>> @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
>>>>   };
>>>>   static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
>>>>   	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
>>>> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
>>>> +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
>>>>   };
>>> ...
>>>
>>> Looks like we should first combine all this cut and paste data
>>> for each board file into some common init function to cut
>>> down the "crazy churn".
>>
>> I was actually thinking about this earlier today.
>>
>> All the boards I have seen use vdds_dsi the same way (depending on the
>> omap version, though). For OMAP3 it comes from VPPL2 and for OMAP4 it's
>> VCXIO. Optimally a common piece of code would just set up the regulator
>> properly.
>>
>> But I think in the end the config has to come from the board data, as I
>> don't see that the above config would be the only possibility. The
>> vdds_dsi could be supplied from anywhere (with suitable voltage, of
>> course), as far as I understand.
>>
>> What we could do is:
>>
>> 1. The board file tells the common display code which regulator is used
>> for vdds_dsi, and the common code can setup the regulator supply for all
>> DSS devices which need it (omapdss_dss, omapdss_dsi1, omapdss_dsi2).
>>
>> I guess this needs dynamically adding the regulator supply in display.c,
>> and I'm not quite sure if that's possible. We have to look at this.
>
> I don't see how this would be possible. As far as I see, the regulator
> consumers have to be given statically at init time. We could get the
> whole VPLL2 or VCXIO supply array from a common display code, but that
> would prevent adding any other consumers to those regulators, so that's
> not an option either.

Also, I think the twl driver expects all the regulators to come from the 
twl4030_platform_data struct, so if we set vpll2 to NULL in 
twl4030_platform_data and declare it in our common display code, the twl 
driver will throw an error.

Archit

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04 10:53     ` Tomi Valkeinen
  2011-05-04 11:21       ` Tomi Valkeinen
@ 2011-05-04 12:17       ` Tony Lindgren
  1 sibling, 0 replies; 31+ messages in thread
From: Tony Lindgren @ 2011-05-04 12:17 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, linux-omap

* Tomi Valkeinen <tomi.valkeinen@ti.com> [110504 03:50]:
> On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> > * Archit Taneja <archit@ti.com> [110504 10:30]:
> > > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > > @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> > >  /* VPLL2 for digital video outputs */
> > >  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > >  
> > >  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> > > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > > index 570e83f..eafadb4 100644
> > > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > > @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
> > >  };
> > >  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > ...
> > 
> > Looks like we should first combine all this cut and paste data
> > for each board file into some common init function to cut
> > down the "crazy churn".
> 
> I was actually thinking about this earlier today.
> 
> All the boards I have seen use vdds_dsi the same way (depending on the
> omap version, though). For OMAP3 it comes from VPPL2 and for OMAP4 it's
> VCXIO. Optimally a common piece of code would just set up the regulator
> properly.
> 
> But I think in the end the config has to come from the board data, as I
> don't see that the above config would be the only possibility. The
> vdds_dsi could be supplied from anywhere (with suitable voltage, of
> course), as far as I understand.
> 
> What we could do is:
> 
> 1. The board file tells the common display code which regulator is used
> for vdds_dsi, and the common code can setup the regulator supply for all
> DSS devices which need it (omapdss_dss, omapdss_dsi1, omapdss_dsi2).
> 
> I guess this needs dynamically adding the regulator supply in display.c,
> and I'm not quite sure if that's possible. We have to look at this.
> 
> 2. The common code could default to the power source that is most
> commonly used, so the board file would have to config the regulator only
> if it uses a non-common one.
> 
> Together 1. and 2. would remove the DSS regulator stuff totally from the
> board files. But regulators for the panels would still be in the board
> files, of course.

Sounds doable. And you could still allow overriding it if the typical
configuration does not work.

Regards,

Tony

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04  9:40   ` Tony Lindgren
  2011-05-04 10:53     ` Tomi Valkeinen
@ 2011-05-05 11:36     ` Tomi Valkeinen
  2011-05-05 11:50       ` Tony Lindgren
  2011-05-05 13:02       ` Mark Brown
  2011-06-07 13:11     ` Tomi Valkeinen
  2 siblings, 2 replies; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-05 11:36 UTC (permalink / raw)
  To: Tony Lindgren, Liam Girdwood, Mark Brown; +Cc: Archit Taneja, linux-omap

On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> * Archit Taneja <archit@ti.com> [110504 10:30]:
> > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> >  /* VPLL2 for digital video outputs */
> >  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> >  };
> >  
> >  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > index 570e83f..eafadb4 100644
> > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
> >  };
> >  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> >  };
> ...
> 
> Looks like we should first combine all this cut and paste data
> for each board file into some common init function to cut
> down the "crazy churn".

Sorry, I don't see how this would be possible with the regulator
framework. What we would need is to setup some
regulator_consumer_supplies dynamically depending on the omap and on the
given parameters.

Adding Liam and Mark for possible comments. A short summary of the
situation:

OMAP display subsystem (DSS) HW needs a few power supplies (vdds_dsi,
vdds_sdi, vdda_dac), depending on the OMAP version. All the known boards
have the standard TWL power chip which provides these powers, and they
are connected almost always the same way. However, there's no reason
that the powers for DSS couldn't be provided from some other source.

As an example, on OMAP3 we could have:
(regulator -> name -> driver)
VDDA_DAC -> "vdda_dac" -> omapdss_venc
VPLL2 -> "vdds_dsi" -> omapdss
VPLL2 -> "vdds_dsi" -> omapdss_dsi

So currently we have REGULATOR_SUPPLY defines for each board in all the
board files which support display. It would be much better to have an
overrideable standard setup for the DSS powers, but this would require
dynamically setting up the regulator_consumer_supplies. And I can't see
how this could be done, except dynamically creating the
regulator_consumer_supply array before initializing the TWL chip, but as
DSS is not the only user of those powers the end result could be quite a
mess with changes needed in every board file.

 Tomi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-05 11:36     ` Tomi Valkeinen
@ 2011-05-05 11:50       ` Tony Lindgren
  2011-05-05 11:58         ` Tomi Valkeinen
  2011-05-05 13:03         ` Tomi Valkeinen
  2011-05-05 13:02       ` Mark Brown
  1 sibling, 2 replies; 31+ messages in thread
From: Tony Lindgren @ 2011-05-05 11:50 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Liam Girdwood, Mark Brown, Archit Taneja, linux-omap

* Tomi Valkeinen <tomi.valkeinen@ti.com> [110505 04:33]:
> On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> > 
> > Looks like we should first combine all this cut and paste data
> > for each board file into some common init function to cut
> > down the "crazy churn".
> 
> Sorry, I don't see how this would be possible with the regulator
> framework. What we would need is to setup some
> regulator_consumer_supplies dynamically depending on the omap and on the
> given parameters.
> 
> Adding Liam and Mark for possible comments. A short summary of the
> situation:
> 
> OMAP display subsystem (DSS) HW needs a few power supplies (vdds_dsi,
> vdds_sdi, vdda_dac), depending on the OMAP version. All the known boards
> have the standard TWL power chip which provides these powers, and they
> are connected almost always the same way. However, there's no reason
> that the powers for DSS couldn't be provided from some other source.
> 
> As an example, on OMAP3 we could have:
> (regulator -> name -> driver)
> VDDA_DAC -> "vdda_dac" -> omapdss_venc
> VPLL2 -> "vdds_dsi" -> omapdss
> VPLL2 -> "vdds_dsi" -> omapdss_dsi
> 
> So currently we have REGULATOR_SUPPLY defines for each board in all the
> board files which support display. It would be much better to have an
> overrideable standard setup for the DSS powers, but this would require
> dynamically setting up the regulator_consumer_supplies. And I can't see
> how this could be done, except dynamically creating the
> regulator_consumer_supply array before initializing the TWL chip, but as
> DSS is not the only user of those powers the end result could be quite a
> mess with changes needed in every board file.

What if you just do all common DSS REGULATOR_SUPPLY entries in the common
platform init code for DSS? Then just set the regulator_init_data pointers
based on the desired configuration.

Or maybe I misunderstood your problem..

Tony


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-05 11:50       ` Tony Lindgren
@ 2011-05-05 11:58         ` Tomi Valkeinen
  2011-05-05 13:03         ` Tomi Valkeinen
  1 sibling, 0 replies; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-05 11:58 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Liam Girdwood, Mark Brown, Archit Taneja, linux-omap

On Thu, 2011-05-05 at 04:50 -0700, Tony Lindgren wrote:
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [110505 04:33]:
> > On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> > > 
> > > Looks like we should first combine all this cut and paste data
> > > for each board file into some common init function to cut
> > > down the "crazy churn".
> > 
> > Sorry, I don't see how this would be possible with the regulator
> > framework. What we would need is to setup some
> > regulator_consumer_supplies dynamically depending on the omap and on the
> > given parameters.
> > 
> > Adding Liam and Mark for possible comments. A short summary of the
> > situation:
> > 
> > OMAP display subsystem (DSS) HW needs a few power supplies (vdds_dsi,
> > vdds_sdi, vdda_dac), depending on the OMAP version. All the known boards
> > have the standard TWL power chip which provides these powers, and they
> > are connected almost always the same way. However, there's no reason
> > that the powers for DSS couldn't be provided from some other source.
> > 
> > As an example, on OMAP3 we could have:
> > (regulator -> name -> driver)
> > VDDA_DAC -> "vdda_dac" -> omapdss_venc
> > VPLL2 -> "vdds_dsi" -> omapdss
> > VPLL2 -> "vdds_dsi" -> omapdss_dsi
> > 
> > So currently we have REGULATOR_SUPPLY defines for each board in all the
> > board files which support display. It would be much better to have an
> > overrideable standard setup for the DSS powers, but this would require
> > dynamically setting up the regulator_consumer_supplies. And I can't see
> > how this could be done, except dynamically creating the
> > regulator_consumer_supply array before initializing the TWL chip, but as
> > DSS is not the only user of those powers the end result could be quite a
> > mess with changes needed in every board file.
> 
> What if you just do all common DSS REGULATOR_SUPPLY entries in the common
> platform init code for DSS? Then just set the regulator_init_data pointers
> based on the desired configuration.
> 
> Or maybe I misunderstood your problem..

The problem with that approach is that there could be other users for
the same regulator, so the consumer_supplies list could also need to
contain some other entries than dss.

Then again, I guess those cases are minority, so we would still get
majority of the board files cleaned up.

Thanks for the idea, I'll try this approach.

 Tomi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-05 11:36     ` Tomi Valkeinen
  2011-05-05 11:50       ` Tony Lindgren
@ 2011-05-05 13:02       ` Mark Brown
  2011-05-09 15:34         ` Tomi Valkeinen
  1 sibling, 1 reply; 31+ messages in thread
From: Mark Brown @ 2011-05-05 13:02 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Thu, May 05, 2011 at 02:36:48PM +0300, Tomi Valkeinen wrote:

> So currently we have REGULATOR_SUPPLY defines for each board in all the
> board files which support display. It would be much better to have an
> overrideable standard setup for the DSS powers, but this would require
> dynamically setting up the regulator_consumer_supplies. And I can't see
> how this could be done, except dynamically creating the
> regulator_consumer_supply array before initializing the TWL chip, but as
> DSS is not the only user of those powers the end result could be quite a
> mess with changes needed in every board file.

I'm not sure I see a problem that needs solving here?  This wiring is
all totally system specific.  Once we have viable device tree for
relevant platforms I'd expect to see these things mapped in the device
tree for the system with a standard regulator API device tree mapping.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-05 11:50       ` Tony Lindgren
  2011-05-05 11:58         ` Tomi Valkeinen
@ 2011-05-05 13:03         ` Tomi Valkeinen
  1 sibling, 0 replies; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-05 13:03 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Liam Girdwood, Mark Brown, Archit Taneja, linux-omap

On Thu, 2011-05-05 at 04:50 -0700, Tony Lindgren wrote:
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [110505 04:33]:
> > On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> > > 
> > > Looks like we should first combine all this cut and paste data
> > > for each board file into some common init function to cut
> > > down the "crazy churn".
> > 
> > Sorry, I don't see how this would be possible with the regulator
> > framework. What we would need is to setup some
> > regulator_consumer_supplies dynamically depending on the omap and on the
> > given parameters.
> > 
> > Adding Liam and Mark for possible comments. A short summary of the
> > situation:
> > 
> > OMAP display subsystem (DSS) HW needs a few power supplies (vdds_dsi,
> > vdds_sdi, vdda_dac), depending on the OMAP version. All the known boards
> > have the standard TWL power chip which provides these powers, and they
> > are connected almost always the same way. However, there's no reason
> > that the powers for DSS couldn't be provided from some other source.
> > 
> > As an example, on OMAP3 we could have:
> > (regulator -> name -> driver)
> > VDDA_DAC -> "vdda_dac" -> omapdss_venc
> > VPLL2 -> "vdds_dsi" -> omapdss
> > VPLL2 -> "vdds_dsi" -> omapdss_dsi
> > 
> > So currently we have REGULATOR_SUPPLY defines for each board in all the
> > board files which support display. It would be much better to have an
> > overrideable standard setup for the DSS powers, but this would require
> > dynamically setting up the regulator_consumer_supplies. And I can't see
> > how this could be done, except dynamically creating the
> > regulator_consumer_supply array before initializing the TWL chip, but as
> > DSS is not the only user of those powers the end result could be quite a
> > mess with changes needed in every board file.
> 
> What if you just do all common DSS REGULATOR_SUPPLY entries in the common
> platform init code for DSS? Then just set the regulator_init_data pointers
> based on the desired configuration.
> 
> Or maybe I misunderstood your problem..

I made a test patch for this (below), but after looking at OMAP3 and 4
TRMs, I don't think this is going to be very good solution. It looks
like on OMAP3 the VPLL2 is used (at least) for DSI and CSI. On OMAP4
VCXIO is used for vdda_dpll_mpu, vdda_dpll_core_audio,
vdda_dpll_iva_per, vdda_dsi[1:2], vdda_csi2[1:2], vdda_usba0otg_1p8v.

VPLL2 and VCXIO do not look like to be dedicated for DSS, so I'm
guessing it's more than normal to have more users for the regulators
than just DSS (but they just aren't implemented currently).

Another option that came to my mind is defining simple macros like:

#define OMAP_DSS_REG_SUPPLY_DSS REGULATOR_SUPPLY("vdds_dsi", "omapdss")
#define OMAP_DSS_REG_SUPPLY_DSI1 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1")

And then use them instead:

static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
	OMAP_DSS_REG_SUPPLY_DSS,
	OMAP_DSS_REG_SUPPLY_DSI1,
};

But that is quite minor improvement, and I'm not even sure if it's an
improvement...

 Tomi


diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 9afd087..dedc150 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -394,16 +394,6 @@ static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = {
 	REGULATOR_SUPPLY("vcc", "spi1.0"),
 };
 
-static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
-	REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
-};
-
-/* VPLL2 for digital video outputs */
-static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
-};
-
 static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
 	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
 };
@@ -531,8 +521,8 @@ static struct regulator_init_data sdp3430_vdac = {
 		.valid_ops_mask		= REGULATOR_CHANGE_MODE
 					| REGULATOR_CHANGE_STATUS,
 	},
-	.num_consumer_supplies	= ARRAY_SIZE(sdp3430_vdda_dac_supplies),
-	.consumer_supplies	= sdp3430_vdda_dac_supplies,
+	.num_consumer_supplies	= ARRAY_SIZE(omap_std_vdda_dac_supplies),
+	.consumer_supplies	= omap_std_vdda_dac_supplies,
 };
 
 static struct regulator_init_data sdp3430_vpll2 = {
@@ -546,8 +536,8 @@ static struct regulator_init_data sdp3430_vpll2 = {
 		.valid_ops_mask		= REGULATOR_CHANGE_MODE
 					| REGULATOR_CHANGE_STATUS,
 	},
-	.num_consumer_supplies	= ARRAY_SIZE(sdp3430_vpll2_supplies),
-	.consumer_supplies	= sdp3430_vpll2_supplies,
+	.num_consumer_supplies	= ARRAY_SIZE(omap_std_vdds_dsi_supplies),
+	.consumer_supplies	= omap_std_vdds_dsi_supplies,
 };
 
 static struct twl4030_codec_audio_data sdp3430_audio;
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 570e83f..bef42bb 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -373,10 +373,6 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
 		.dev_name = "omap_hsmmc.0",
 	},
 };
-static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
-};
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
 {
@@ -525,8 +521,8 @@ static struct regulator_init_data sdp4430_vcxio = {
 					| REGULATOR_CHANGE_STATUS,
 		.always_on	= true,
 	},
-	.num_consumer_supplies	= ARRAY_SIZE(sdp4430_vcxio_supply),
-	.consumer_supplies	= sdp4430_vcxio_supply,
+	.num_consumer_supplies	= ARRAY_SIZE(omap_std_vdds_dsi_supplies),
+	.consumer_supplies	= omap_std_vdds_dsi_supplies,
 };
 
 static struct regulator_init_data sdp4430_vdac = {
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 7dc836e..98a4863 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -21,11 +21,22 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/regulator/machine.h>
 
 #include <plat/display.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
+struct regulator_consumer_supply omap_std_vdda_dac_supplies[] = {
+	REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
+};
+
+struct regulator_consumer_supply omap_std_vdds_dsi_supplies[] = {
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi2"),
+};
+
 static struct platform_device omap_display_device = {
 	.name          = "omapdss",
 	.id            = -1,
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index bd0f08e..bd8c302 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -24,6 +24,7 @@
 #include <linux/kobject.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
 #include <asm/atomic.h>
 
 #define DISPC_IRQ_FRAMEDONE		(1 << 0)
@@ -248,6 +249,9 @@ static inline int omap_display_init(struct omap_dss_board_info *board_data)
 }
 #endif
 
+extern struct regulator_consumer_supply omap_std_vdda_dac_supplies[1];
+extern struct regulator_consumer_supply omap_std_vdds_dsi_supplies[3];
+
 struct omap_display_platform_data {
 	struct omap_dss_board_info *board_data;
 	/* TODO: Additional members to be added when PM is considered */



^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-05 13:02       ` Mark Brown
@ 2011-05-09 15:34         ` Tomi Valkeinen
  2011-05-09 19:19           ` Mark Brown
  0 siblings, 1 reply; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-09 15:34 UTC (permalink / raw)
  To: Mark Brown; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Thu, 2011-05-05 at 14:02 +0100, Mark Brown wrote:
> On Thu, May 05, 2011 at 02:36:48PM +0300, Tomi Valkeinen wrote:
> 
> > So currently we have REGULATOR_SUPPLY defines for each board in all the
> > board files which support display. It would be much better to have an
> > overrideable standard setup for the DSS powers, but this would require
> > dynamically setting up the regulator_consumer_supplies. And I can't see
> > how this could be done, except dynamically creating the
> > regulator_consumer_supply array before initializing the TWL chip, but as
> > DSS is not the only user of those powers the end result could be quite a
> > mess with changes needed in every board file.
> 
> I'm not sure I see a problem that needs solving here?  This wiring is
> all totally system specific.  Once we have viable device tree for
> relevant platforms I'd expect to see these things mapped in the device
> tree for the system with a standard regulator API device tree mapping.

I think there are two things here:

The first is that we want to avoid unnecessary board file changes, and
as almost all boards configure the DSS powers the same way, it'd be nice
to have a default config for these.

The second thing is that even if the power source for vdds_dsi may be
configured differently on different boards, the same vdds_dsi goes to
multiple DSS HW blocks inside OMAP, each represented by a separate
omap_device. So it'd be much nicer to configure just the vdds_dsi power
in the board file, but let the omap display code configure the
regulators properly for all the DSS HW blocks in that particular OMAP.

I'm not familiar with the capabilities of the device tree, so it may
solve these neatly (at least from kernel's perspective). I guess Tony
just wants to try to minimize arch/arm changes wherever possible due to
the recent arch/arm dispute.

 Tomi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-09 15:34         ` Tomi Valkeinen
@ 2011-05-09 19:19           ` Mark Brown
  2011-05-10 12:30             ` Tomi Valkeinen
  0 siblings, 1 reply; 31+ messages in thread
From: Mark Brown @ 2011-05-09 19:19 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Mon, May 09, 2011 at 06:34:34PM +0300, Tomi Valkeinen wrote:

> The first is that we want to avoid unnecessary board file changes, and
> as almost all boards configure the DSS powers the same way, it'd be nice
> to have a default config for these.

Right, makes sense.

> The second thing is that even if the power source for vdds_dsi may be
> configured differently on different boards, the same vdds_dsi goes to
> multiple DSS HW blocks inside OMAP, each represented by a separate
> omap_device. So it'd be much nicer to configure just the vdds_dsi power
> in the board file, but let the omap display code configure the
> regulators properly for all the DSS HW blocks in that particular OMAP.

For this I'd suggest setting up an arrangement with supplies where you
have one thing on the OMAP is supplied by board configuration and then
it has child supplies within the device but right now that's not so easy
to do.  I was just writing some stuff for that this afternoon but it'll
be next week before I can test it properly.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-09 19:19           ` Mark Brown
@ 2011-05-10 12:30             ` Tomi Valkeinen
  2011-05-10 13:47               ` Mark Brown
  0 siblings, 1 reply; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-10 12:30 UTC (permalink / raw)
  To: Mark Brown; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Mon, 2011-05-09 at 21:19 +0200, Mark Brown wrote:
> On Mon, May 09, 2011 at 06:34:34PM +0300, Tomi Valkeinen wrote:

> > The second thing is that even if the power source for vdds_dsi may be
> > configured differently on different boards, the same vdds_dsi goes to
> > multiple DSS HW blocks inside OMAP, each represented by a separate
> > omap_device. So it'd be much nicer to configure just the vdds_dsi power
> > in the board file, but let the omap display code configure the
> > regulators properly for all the DSS HW blocks in that particular OMAP.
> 
> For this I'd suggest setting up an arrangement with supplies where you
> have one thing on the OMAP is supplied by board configuration and then
> it has child supplies within the device but right now that's not so easy
> to do.  I was just writing some stuff for that this afternoon but it'll
> be next week before I can test it properly.

This sounds just the thing we need here. Do you think there's a chance
the code could get merged in the next window? And I'm also happy to test
the code with omapdss, whenever you have something ready.

I think we'll go forward with this patch set in a modified form: we'll
leave the board files untouched and add the DSS driver parts (which is
99% of the patch set) with a small hack which makes things work with the
current device setup.

This means we won't be able to use the second DSI LCD yet, but getting
the biggest bulk of code in is more important.

 Tomi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-10 12:30             ` Tomi Valkeinen
@ 2011-05-10 13:47               ` Mark Brown
  2011-05-11  9:23                 ` Tomi Valkeinen
  0 siblings, 1 reply; 31+ messages in thread
From: Mark Brown @ 2011-05-10 13:47 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Tue, May 10, 2011 at 03:30:52PM +0300, Tomi Valkeinen wrote:

> This sounds just the thing we need here. Do you think there's a chance
> the code could get merged in the next window? And I'm also happy to test
> the code with omapdss, whenever you have something ready.

Patch is below, tested with my "hey look, this compiles!" test plan -
I'd be a bit surprised if it ran straight off.

>From 819cc21f22b1f570f7d5d8fe981bbb03e28bdb9d Mon Sep 17 00:00:00 2001
From: Mark Brown <broonie@opensource.wolfsonmicro.com>
Date: Mon, 9 May 2011 13:07:41 +0200
Subject: [PATCH] regulator: Refactor supply implementation to work as regular consumers

Currently the regulator supply implementation is somewhat complex and
fragile as it doesn't look like standard consumers but is instead a
parallel implementation. This causes issues with locking and reference
counting.

Move the implementation over to using standard consumers to address this.
Rather than only notifying the supply on the first enable/disable we do so
every time the regulator is enabled or disabled, simplifying locking as we
don't need to hold a lock on the consumer we are about to enable.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/regulator/core.c         |   99 +++++++++++++-------------------------
 include/linux/regulator/driver.h |    4 +-
 2 files changed, 35 insertions(+), 68 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 58452ac..38bb499 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -81,8 +81,7 @@ struct regulator {
 };
 
 static int _regulator_is_enabled(struct regulator_dev *rdev);
-static int _regulator_disable(struct regulator_dev *rdev,
-		struct regulator_dev **supply_rdev_ptr);
+static int _regulator_disable(struct regulator_dev *rdev);
 static int _regulator_get_voltage(struct regulator_dev *rdev);
 static int _regulator_get_current_limit(struct regulator_dev *rdev);
 static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
@@ -90,6 +89,9 @@ static void _notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data);
 static int _regulator_do_set_voltage(struct regulator_dev *rdev,
 				     int min_uV, int max_uV);
+static struct regulator *create_regulator(struct regulator_dev *rdev,
+					  struct device *dev,
+					  const char *supply_name);
 
 static const char *rdev_get_name(struct regulator_dev *rdev)
 {
@@ -922,21 +924,18 @@ out:
  * core if it's child is enabled.
  */
 static int set_supply(struct regulator_dev *rdev,
-	struct regulator_dev *supply_rdev)
+		      struct regulator_dev *supply_rdev)
 {
 	int err;
 
-	err = sysfs_create_link(&rdev->dev.kobj, &supply_rdev->dev.kobj,
-				"supply");
-	if (err) {
-		rdev_err(rdev, "could not add device link %s err %d\n",
-			 supply_rdev->dev.kobj.name, err);
-		       goto out;
+	rdev->supply = create_regulator(rdev, &rdev->dev, "SUPPLY");
+	if (IS_ERR(rdev->supply)) {
+		err = PTR_ERR(rdev->supply);
+		rdev->supply = NULL;
+		return err;
 	}
-	rdev->supply = supply_rdev;
-	list_add(&rdev->slist, &supply_rdev->supply_list);
-out:
-	return err;
+
+	return 0;
 }
 
 /**
@@ -1294,19 +1293,6 @@ static int _regulator_enable(struct regulator_dev *rdev)
 {
 	int ret, delay;
 
-	if (rdev->use_count == 0) {
-		/* do we need to enable the supply regulator first */
-		if (rdev->supply) {
-			mutex_lock(&rdev->supply->mutex);
-			ret = _regulator_enable(rdev->supply);
-			mutex_unlock(&rdev->supply->mutex);
-			if (ret < 0) {
-				rdev_err(rdev, "failed to enable: %d\n", ret);
-				return ret;
-			}
-		}
-	}
-
 	/* check voltage and requested load before enabling */
 	if (rdev->constraints &&
 	    (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS))
@@ -1381,19 +1367,27 @@ int regulator_enable(struct regulator *regulator)
 	struct regulator_dev *rdev = regulator->rdev;
 	int ret = 0;
 
+	if (rdev->supply) {
+		ret = regulator_enable(rdev->supply);
+		if (ret != 0)
+			return ret;
+	}
+
 	mutex_lock(&rdev->mutex);
 	ret = _regulator_enable(rdev);
 	mutex_unlock(&rdev->mutex);
+
+	if (ret != 0)
+		regulator_disable(rdev->supply);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(regulator_enable);
 
 /* locks held by regulator_disable() */
-static int _regulator_disable(struct regulator_dev *rdev,
-		struct regulator_dev **supply_rdev_ptr)
+static int _regulator_disable(struct regulator_dev *rdev)
 {
 	int ret = 0;
-	*supply_rdev_ptr = NULL;
 
 	if (WARN(rdev->use_count <= 0,
 		 "unbalanced disables for %s\n", rdev_get_name(rdev)))
@@ -1420,9 +1414,6 @@ static int _regulator_disable(struct regulator_dev *rdev,
 					     NULL);
 		}
 
-		/* decrease our supplies ref count and disable if required */
-		*supply_rdev_ptr = rdev->supply;
-
 		rdev->use_count = 0;
 	} else if (rdev->use_count > 1) {
 
@@ -1433,6 +1424,7 @@ static int _regulator_disable(struct regulator_dev *rdev,
 
 		rdev->use_count--;
 	}
+
 	return ret;
 }
 
@@ -1451,29 +1443,21 @@ static int _regulator_disable(struct regulator_dev *rdev,
 int regulator_disable(struct regulator *regulator)
 {
 	struct regulator_dev *rdev = regulator->rdev;
-	struct regulator_dev *supply_rdev = NULL;
 	int ret = 0;
 
 	mutex_lock(&rdev->mutex);
-	ret = _regulator_disable(rdev, &supply_rdev);
+	ret = _regulator_disable(rdev);
 	mutex_unlock(&rdev->mutex);
 
-	/* decrease our supplies ref count and disable if required */
-	while (supply_rdev != NULL) {
-		rdev = supply_rdev;
-
-		mutex_lock(&rdev->mutex);
-		_regulator_disable(rdev, &supply_rdev);
-		mutex_unlock(&rdev->mutex);
-	}
+	if (ret == 0 && rdev->supply)
+		regulator_disable(rdev->supply);
 
 	return ret;
 }
 EXPORT_SYMBOL_GPL(regulator_disable);
 
 /* locks held by regulator_force_disable() */
-static int _regulator_force_disable(struct regulator_dev *rdev,
-		struct regulator_dev **supply_rdev_ptr)
+static int _regulator_force_disable(struct regulator_dev *rdev)
 {
 	int ret = 0;
 
@@ -1490,10 +1474,6 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
 			REGULATOR_EVENT_DISABLE, NULL);
 	}
 
-	/* decrease our supplies ref count and disable if required */
-	*supply_rdev_ptr = rdev->supply;
-
-	rdev->use_count = 0;
 	return ret;
 }
 
@@ -1509,16 +1489,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
 int regulator_force_disable(struct regulator *regulator)
 {
 	struct regulator_dev *rdev = regulator->rdev;
-	struct regulator_dev *supply_rdev = NULL;
 	int ret;
 
 	mutex_lock(&rdev->mutex);
 	regulator->uA_load = 0;
-	ret = _regulator_force_disable(rdev, &supply_rdev);
+	ret = _regulator_force_disable(regulator->rdev);
 	mutex_unlock(&rdev->mutex);
 
-	if (supply_rdev)
-		regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev)));
+	if (rdev->supply)
+		while (rdev->open_count--)
+			regulator_disable(rdev->supply);
 
 	return ret;
 }
@@ -2117,7 +2097,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
 	/* get input voltage */
 	input_uV = 0;
 	if (rdev->supply)
-		input_uV = _regulator_get_voltage(rdev->supply);
+		input_uV = regulator_get_voltage(rdev->supply);
 	if (input_uV <= 0)
 		input_uV = rdev->constraints->input_uV;
 	if (input_uV <= 0) {
@@ -2187,17 +2167,8 @@ EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
 static void _notifier_call_chain(struct regulator_dev *rdev,
 				  unsigned long event, void *data)
 {
-	struct regulator_dev *_rdev;
-
 	/* call rdev chain first */
 	blocking_notifier_call_chain(&rdev->notifier, event, NULL);
-
-	/* now notify regulator we supply */
-	list_for_each_entry(_rdev, &rdev->supply_list, slist) {
-		mutex_lock(&_rdev->mutex);
-		_notifier_call_chain(_rdev, event, data);
-		mutex_unlock(&_rdev->mutex);
-	}
 }
 
 /**
@@ -2570,9 +2541,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
 	rdev->owner = regulator_desc->owner;
 	rdev->desc = regulator_desc;
 	INIT_LIST_HEAD(&rdev->consumer_list);
-	INIT_LIST_HEAD(&rdev->supply_list);
 	INIT_LIST_HEAD(&rdev->list);
-	INIT_LIST_HEAD(&rdev->slist);
 	BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
 
 	/* preform any regulator specific init */
@@ -2684,7 +2653,7 @@ void regulator_unregister(struct regulator_dev *rdev)
 	unset_regulator_supplies(rdev);
 	list_del(&rdev->list);
 	if (rdev->supply)
-		sysfs_remove_link(&rdev->dev.kobj, "supply");
+		regulator_put(rdev->supply);
 	device_unregister(&rdev->dev);
 	kfree(rdev->constraints);
 	mutex_unlock(&regulator_list_mutex);
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 6c433b8..1a80bc7 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -188,18 +188,16 @@ struct regulator_dev {
 
 	/* lists we belong to */
 	struct list_head list; /* list of all regulators */
-	struct list_head slist; /* list of supplied regulators */
 
 	/* lists we own */
 	struct list_head consumer_list; /* consumers we supply */
-	struct list_head supply_list; /* regulators we supply */
 
 	struct blocking_notifier_head notifier;
 	struct mutex mutex; /* consumer lock */
 	struct module *owner;
 	struct device dev;
 	struct regulation_constraints *constraints;
-	struct regulator_dev *supply;	/* for tree */
+	struct regulator *supply;	/* for tree */
 
 	void *reg_data;		/* regulator_dev data */
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-10 13:47               ` Mark Brown
@ 2011-05-11  9:23                 ` Tomi Valkeinen
  2011-05-11 12:12                   ` Mark Brown
  0 siblings, 1 reply; 31+ messages in thread
From: Tomi Valkeinen @ 2011-05-11  9:23 UTC (permalink / raw)
  To: Mark Brown; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Tue, 2011-05-10 at 15:47 +0200, Mark Brown wrote:
> On Tue, May 10, 2011 at 03:30:52PM +0300, Tomi Valkeinen wrote:
> 
> > This sounds just the thing we need here. Do you think there's a chance
> > the code could get merged in the next window? And I'm also happy to test
> > the code with omapdss, whenever you have something ready.
> 
> Patch is below, tested with my "hey look, this compiles!" test plan -
> I'd be a bit surprised if it ran straight off.

So how should the regulator be set up?

If we currently have in the board file:

static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"),
};

static struct regulator_init_data sdp4430_vcxio = {
	.constraints = {
		...
	},
	.num_consumer_supplies	= ARRAY_SIZE(sdp4430_vcxio_supply),
	.consumer_supplies	= sdp4430_vcxio_supply,
};

I should setup a fixed regulator, which is supplied from VCXIO, and
omapdss will get its powers from this fixed regulator?

So, in the common display file:

static struct regulator_consumer_supply fixed_supply[] = {
	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.1"),
};

static struct regulator_init_data fixed_reg_init_data = {
	.constraints = {
		...
	},
	.num_consumer_supplies	= ARRAY_SIZE(fixed_supply),
	.consumer_supplies	= fixed_supply,
};

static struct fixed_voltage_config omap_dss_fixed_reg_data = {
	.supply_name = "what should this be?",
	.init_data = &fixed_reg_init_data,
};

static struct platform_device omap_dss_fixed_reg_device = {
	.name	= "reg-fixed-voltage",
	.id	= 0,
	.dev	= {
		.platform_data	= &omap_dss_fixed_reg_data,
	},
};

And in the board file:

static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
	REGULATOR_SUPPLY("what should this be?", "reg-fixed-voltage.0"),
};

static struct regulator_init_data sdp4430_vcxio = {
	.constraints = {
		...
	},
	.num_consumer_supplies	= ARRAY_SIZE(sdp4430_vcxio_supply),
	.consumer_supplies	= sdp4430_vcxio_supply,
};

If so, it's again slightly difficult. I want to do the common display
stuff in a one place, used by all the boards. If I setup the fixed
regulator in the common file, I need to give it an id which may conflict
with a possible fixed regulator set up in the board file.

Or am I totally on the wrong track here =)?

 Tomi



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-11  9:23                 ` Tomi Valkeinen
@ 2011-05-11 12:12                   ` Mark Brown
  2011-06-07 11:44                     ` Tomi Valkeinen
  0 siblings, 1 reply; 31+ messages in thread
From: Mark Brown @ 2011-05-11 12:12 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Wed, May 11, 2011 at 12:23:45PM +0300, Tomi Valkeinen wrote:

> So how should the regulator be set up?

You need to create a new regulator of some kind and then provide a way
for machines to set the supply_regulator in the init_data.

> I should setup a fixed regulator, which is supplied from VCXIO, and
> omapdss will get its powers from this fixed regulator?

Yes, and the example code I've deleted all looks about right.

> static struct fixed_voltage_config omap_dss_fixed_reg_data = {
> 	.supply_name = "what should this be?",
> 	.init_data = &fixed_reg_init_data,
> };

The supply name shold be supplied by the board - it's whatever the
supply that's shared by all the regulators in the OMAP is.

> static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> 	REGULATOR_SUPPLY("what should this be?", "reg-fixed-voltage.0"),
> };

You don't need to specify a supply to hook the supplies up.  This is a
bit of a wart, but it's the current API - it's specified in the child
regulator rather than the parent which is the other way around to
consumers.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-11 12:12                   ` Mark Brown
@ 2011-06-07 11:44                     ` Tomi Valkeinen
  2011-06-07 12:08                       ` Mark Brown
  0 siblings, 1 reply; 31+ messages in thread
From: Tomi Valkeinen @ 2011-06-07 11:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

Hi Mark,

Waking up this old thread again.

On Wed, 2011-05-11 at 14:12 +0200, Mark Brown wrote:
> On Wed, May 11, 2011 at 12:23:45PM +0300, Tomi Valkeinen wrote:
> 
> > So how should the regulator be set up?
> 
> You need to create a new regulator of some kind and then provide a way
> for machines to set the supply_regulator in the init_data.

What should this "new regulator of some kind" be? I was trying out with
fixed regulator, but I'm not quite sure if that's good here.

I don't want a full controllable regulator, but just a virtual "route"
regulator, which mirrors the state of the parent regulator.

(Well, I don't actually want that, I want to dynamically add some
REGULATOR_SUPPLYs to an existing regulator, but afaik that's not
possible.)

Can the fixed regulator be used like that?

Using a new regulator like this also means that there is a dependency
between the new regulator and the used source supply. I haven't solved
this yet, as the twl driver seems to add the regulators at some later
stage.

Below is my test patch for reference. It doesn't do the work in a common
file, so it's just for testing.

 Tomi

diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 2647a95..fb477f1 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -22,6 +22,7 @@
 #include <linux/i2c/twl.h>
 #include <linux/gpio_keys.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
 #include <linux/leds.h>
 #include <linux/leds_pwm.h>
 
@@ -277,10 +278,47 @@ static int omap_ethernet_init(void)
 	return status;
 }
 
+static struct regulator_consumer_supply fixed_supply[] = {
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_init_data fixed_reg_init_data = {
+	.supply_regulator = "VCXIO",
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 1800000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask	 = REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+		.always_on	= true,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(fixed_supply),
+	.consumer_supplies      = fixed_supply,
+};
+
+static struct fixed_voltage_config omap_dss_fixed_reg_data = {
+	.gpio = -EINVAL,
+	.supply_name = "dss-regulator",
+	.init_data = &fixed_reg_init_data,
+	.enabled_at_boot = 1,
+	.microvolts = 1800000,
+};
+
+static struct platform_device omap_dss_fixed_reg_device = {
+	.name   = "reg-fixed-voltage",
+	.id     = 3,
+	.dev    = {
+		.platform_data  = &omap_dss_fixed_reg_data,
+	},
+};
+
 static struct platform_device *sdp4430_devices[] __initdata = {
 	&sdp4430_gpio_keys_device,
 	&sdp4430_leds_gpio,
 	&sdp4430_leds_pwm,
+	&omap_dss_fixed_reg_device,
 };
 
 static struct omap_board_config_kernel sdp4430_config[] __initdata = {
@@ -339,8 +377,6 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
 	},
 };
 static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
 };
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)



^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-06-07 11:44                     ` Tomi Valkeinen
@ 2011-06-07 12:08                       ` Mark Brown
  0 siblings, 0 replies; 31+ messages in thread
From: Mark Brown @ 2011-06-07 12:08 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Tony Lindgren, Liam Girdwood, Archit Taneja, linux-omap

On Tue, Jun 07, 2011 at 02:44:58PM +0300, Tomi Valkeinen wrote:
> On Wed, 2011-05-11 at 14:12 +0200, Mark Brown wrote:
> > On Wed, May 11, 2011 at 12:23:45PM +0300, Tomi Valkeinen wrote:

> > You need to create a new regulator of some kind and then provide a way
> > for machines to set the supply_regulator in the init_data.

> What should this "new regulator of some kind" be? I was trying out with
> fixed regulator, but I'm not quite sure if that's good here.

It should be a regulator that does what you want.

> I don't want a full controllable regulator, but just a virtual "route"
> regulator, which mirrors the state of the parent regulator.

If it's not doing what you want then make a new one.

> Using a new regulator like this also means that there is a dependency
> between the new regulator and the used source supply. I haven't solved
> this yet, as the twl driver seems to add the regulators at some later
> stage.

I'm sorry but I can't parse what you're saying here at all.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-05-04  9:40   ` Tony Lindgren
  2011-05-04 10:53     ` Tomi Valkeinen
  2011-05-05 11:36     ` Tomi Valkeinen
@ 2011-06-07 13:11     ` Tomi Valkeinen
  2011-06-13  9:54       ` Tomi Valkeinen
  2011-06-13 13:27       ` Tony Lindgren
  2 siblings, 2 replies; 31+ messages in thread
From: Tomi Valkeinen @ 2011-06-07 13:11 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Archit Taneja, linux-omap

Hi Tony,

On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> * Archit Taneja <archit@ti.com> [110504 10:30]:
> > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> >  /* VPLL2 for digital video outputs */
> >  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> >  };
> >  
> >  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > index 570e83f..eafadb4 100644
> > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
> >  };
> >  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> >  };
> ...
> 
> Looks like we should first combine all this cut and paste data
> for each board file into some common init function to cut
> down the "crazy churn".

I haven't been able to do this in a clean way. The regulator framework
is rather static in this area, and adding the data for REGULATOR_SUPPLYs
dynamically based on OMAP version is something I haven't been able to
do.

The best option I've found out is defining helper macros to add those
consumers. An example patch below with 3430sdp and 4430sdp boards
modified.

This would allow boards to setup the regulators whatever way they want,
but the 99% of the boards could just use the macros.

It's still not as good as I'd want, because the source regulator is also
the same for a particular OMAP version for 99% of the boards. So there's
no real need to use those those macros in the board file, a common
display file should be able to set everything up. But as I said, I
haven't found out any way to do this.

What is your opinion of this approach?

 Tomi



diff --git a/arch/arm/mach-omap2/board-3430sdp.c
b/arch/arm/mach-omap2/board-3430sdp.c
index ae2963a..69b7e6f 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -308,13 +308,12 @@ static struct regulator_consumer_supply
sdp3430_vaux3_supplies[] = {
 };
 
 static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
-	REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
+	OMAP_DSS_VENC_SUPPLIES,
 };
 
 /* VPLL2 for digital video outputs */
 static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	OMAP_DSS_SUPPLIES,
 };
 
 static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
diff --git a/arch/arm/mach-omap2/board-4430sdp.c
b/arch/arm/mach-omap2/board-4430sdp.c
index 2647a95..80bbf61 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -339,8 +339,7 @@ static struct regulator_consumer_supply
sdp4430_vmmc_supply[] = {
 	},
 };
 static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
-	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+	OMAP_DSS_SUPPLIES,
 };
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index bb39738..557b400 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -636,4 +636,12 @@ int omap_rfbi_update(struct omap_dss_device
*dssdev,
 int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
 		int data_lines);
 
+#define OMAP_DSS_SUPPLIES \
+	REGULATOR_SUPPLY("vdds_sdi", "omapdss_dss"), \
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"), \
+	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1")
+
+#define OMAP_DSS_VENC_SUPPLIES \
+	REGULATOR_SUPPLY("vdda_dac", "omapdss_venc")
+
 #endif



^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-06-07 13:11     ` Tomi Valkeinen
@ 2011-06-13  9:54       ` Tomi Valkeinen
  2011-06-13 13:27       ` Tony Lindgren
  1 sibling, 0 replies; 31+ messages in thread
From: Tomi Valkeinen @ 2011-06-13  9:54 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Archit Taneja, linux-omap

Tony, Ping.

I'd like this DSS regulator issue decided on way or another, as it's
stopping us getting Blaze board's panels working on mainline, and also
preventing me from porting the old omapfb drivers to DSS2.

 Tomi

On Tue, 2011-06-07 at 16:11 +0300, Tomi Valkeinen wrote:
> Hi Tony,
> 
> On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> > * Archit Taneja <archit@ti.com> [110504 10:30]:
> > > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > > @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> > >  /* VPLL2 for digital video outputs */
> > >  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > >  
> > >  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> > > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > > index 570e83f..eafadb4 100644
> > > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > > @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
> > >  };
> > >  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > ...
> > 
> > Looks like we should first combine all this cut and paste data
> > for each board file into some common init function to cut
> > down the "crazy churn".
> 
> I haven't been able to do this in a clean way. The regulator framework
> is rather static in this area, and adding the data for REGULATOR_SUPPLYs
> dynamically based on OMAP version is something I haven't been able to
> do.
> 
> The best option I've found out is defining helper macros to add those
> consumers. An example patch below with 3430sdp and 4430sdp boards
> modified.
> 
> This would allow boards to setup the regulators whatever way they want,
> but the 99% of the boards could just use the macros.
> 
> It's still not as good as I'd want, because the source regulator is also
> the same for a particular OMAP version for 99% of the boards. So there's
> no real need to use those those macros in the board file, a common
> display file should be able to set everything up. But as I said, I
> haven't found out any way to do this.
> 
> What is your opinion of this approach?
> 
>  Tomi
> 
> 
> 
> diff --git a/arch/arm/mach-omap2/board-3430sdp.c
> b/arch/arm/mach-omap2/board-3430sdp.c
> index ae2963a..69b7e6f 100644
> --- a/arch/arm/mach-omap2/board-3430sdp.c
> +++ b/arch/arm/mach-omap2/board-3430sdp.c
> @@ -308,13 +308,12 @@ static struct regulator_consumer_supply
> sdp3430_vaux3_supplies[] = {
>  };
>  
>  static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> -	REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
> +	OMAP_DSS_VENC_SUPPLIES,
>  };
>  
>  /* VPLL2 for digital video outputs */
>  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> +	OMAP_DSS_SUPPLIES,
>  };
>  
>  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> diff --git a/arch/arm/mach-omap2/board-4430sdp.c
> b/arch/arm/mach-omap2/board-4430sdp.c
> index 2647a95..80bbf61 100644
> --- a/arch/arm/mach-omap2/board-4430sdp.c
> +++ b/arch/arm/mach-omap2/board-4430sdp.c
> @@ -339,8 +339,7 @@ static struct regulator_consumer_supply
> sdp4430_vmmc_supply[] = {
>  	},
>  };
>  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> +	OMAP_DSS_SUPPLIES,
>  };
>  
>  static int omap4_twl6030_hsmmc_late_init(struct device *dev)
> diff --git a/include/video/omapdss.h b/include/video/omapdss.h
> index bb39738..557b400 100644
> --- a/include/video/omapdss.h
> +++ b/include/video/omapdss.h
> @@ -636,4 +636,12 @@ int omap_rfbi_update(struct omap_dss_device
> *dssdev,
>  int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
>  		int data_lines);
>  
> +#define OMAP_DSS_SUPPLIES \
> +	REGULATOR_SUPPLY("vdds_sdi", "omapdss_dss"), \
> +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"), \
> +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1")
> +
> +#define OMAP_DSS_VENC_SUPPLIES \
> +	REGULATOR_SUPPLY("vdda_dac", "omapdss_venc")
> +
>  #endif
> 
> 



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi"
  2011-06-07 13:11     ` Tomi Valkeinen
  2011-06-13  9:54       ` Tomi Valkeinen
@ 2011-06-13 13:27       ` Tony Lindgren
  1 sibling, 0 replies; 31+ messages in thread
From: Tony Lindgren @ 2011-06-13 13:27 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: Archit Taneja, linux-omap

* Tomi Valkeinen <tomi.valkeinen@ti.com> [110607 06:07]:
> Hi Tony,
> 
> On Wed, 2011-05-04 at 12:40 +0300, Tony Lindgren wrote:
> > * Archit Taneja <archit@ti.com> [110504 10:30]:
> > > --- a/arch/arm/mach-omap2/board-3430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-3430sdp.c
> > > @@ -401,7 +401,7 @@ static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
> > >  /* VPLL2 for digital video outputs */
> > >  static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > >  
> > >  static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
> > > diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> > > index 570e83f..eafadb4 100644
> > > --- a/arch/arm/mach-omap2/board-4430sdp.c
> > > +++ b/arch/arm/mach-omap2/board-4430sdp.c
> > > @@ -375,7 +375,7 @@ static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
> > >  };
> > >  static struct regulator_consumer_supply sdp4430_vcxio_supply[] = {
> > >  	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
> > > -	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
> > > +	REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi.0"),
> > >  };
> > ...
> > 
> > Looks like we should first combine all this cut and paste data
> > for each board file into some common init function to cut
> > down the "crazy churn".
> 
> I haven't been able to do this in a clean way. The regulator framework
> is rather static in this area, and adding the data for REGULATOR_SUPPLYs
> dynamically based on OMAP version is something I haven't been able to
> do.
> 
> The best option I've found out is defining helper macros to add those
> consumers. An example patch below with 3430sdp and 4430sdp boards
> modified.
> 
> This would allow boards to setup the regulators whatever way they want,
> but the 99% of the boards could just use the macros.
> 
> It's still not as good as I'd want, because the source regulator is also
> the same for a particular OMAP version for 99% of the boards. So there's
> no real need to use those those macros in the board file, a common
> display file should be able to set everything up. But as I said, I
> haven't found out any way to do this.
> 
> What is your opinion of this approach?

Well I guess the macros are a step in the right direction. Eventually
we should have just one istance of the regulator_consumer_supply and
just populate that instead of cloning it in each board file.

Regards,

Tony

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2011-06-13 13:27 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-04  7:38 [PATCH 0/9] MAP: DSS2: DSI2 for secondary lcd panel on OMAP4 Archit Taneja
2011-05-04  7:38 ` [PATCH 1/9] OMAP: DSS2: Change DSI platform device name from "omapdss_dsi1" to "omapdss_dsi" Archit Taneja
2011-05-04  9:40   ` Tony Lindgren
2011-05-04 10:53     ` Tomi Valkeinen
2011-05-04 11:21       ` Tomi Valkeinen
2011-05-04 12:11         ` Archit Taneja
2011-05-04 12:17       ` Tony Lindgren
2011-05-05 11:36     ` Tomi Valkeinen
2011-05-05 11:50       ` Tony Lindgren
2011-05-05 11:58         ` Tomi Valkeinen
2011-05-05 13:03         ` Tomi Valkeinen
2011-05-05 13:02       ` Mark Brown
2011-05-09 15:34         ` Tomi Valkeinen
2011-05-09 19:19           ` Mark Brown
2011-05-10 12:30             ` Tomi Valkeinen
2011-05-10 13:47               ` Mark Brown
2011-05-11  9:23                 ` Tomi Valkeinen
2011-05-11 12:12                   ` Mark Brown
2011-06-07 11:44                     ` Tomi Valkeinen
2011-06-07 12:08                       ` Mark Brown
2011-06-07 13:11     ` Tomi Valkeinen
2011-06-13  9:54       ` Tomi Valkeinen
2011-06-13 13:27       ` Tony Lindgren
2011-05-04  7:38 ` [PATCH 2/9] OMAP: DSS2: DSI: Add extra omap_dss_device argument in functions exported by dsi Archit Taneja
2011-05-04  7:38 ` [PATCH 3/9] OMAP: DSS2: Remove omap_dss_device argument from dsi_pll_init() Archit Taneja
2011-05-04  7:38 ` [PATCH 4/9] OMAP: DSS2: Pass platform_device as an argument in dsi functions Archit Taneja
2011-05-04  7:38 ` [PATCH 5/9] OMAP: DSS2: DSI: Use platform_device pointer to get dsi data Archit Taneja
2011-05-04  7:38 ` [PATCH 6/9] OMAP: DSS2: DSI: Pass pointer to struct to packet_sent_handler isrs Archit Taneja
2011-05-04  7:38 ` [PATCH 7/9] OMAP4: DSS2: DSI: Changes for DSI2 on OMAP4 Archit Taneja
2011-05-04  7:38 ` [PATCH 8/9] OMAP: DSS2: DSI: Build a platform device instance for DSI2 Archit Taneja
2011-05-04  7:38 ` [PATCH 9/9] OMAP: DSS2: Taal: Use device name in backlight_device_register Archit Taneja

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).