linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] OMAPDSS: dss device model changes
@ 2012-09-19  8:30 Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 1/8] OMAPDSS: omap_dss_register_device() doesn't take display index Tomi Valkeinen
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev
  Cc: Tomi Valkeinen, Steve Sakoman, Lajos Molnar, Jassi Brar,
	Grazvydas Ignotas, Vaibhav Hiremath

Hi,

This series contains patches that change how omapdss's panel devices
(omap_dss_device) are initialized and registered. There are two patches that
change behaviour, the rest should be just cleanups:

The patch "omap_dss_register_device() doesn't take display index" affects the
number for the "displayX" sysfs files. This hopefully doesn't affect the
userspace, as the number has never been a clear indication of what the
particular display is.

The patch "register only one display device per output" affects how panel
devices are created. Currently we support multiple panels per output, i.e. you
could have DVI and an LCD displays using the same DPI output, as long as the
DVI and LCD are not used at the same time.

This patch changes the omapdss driver to only register one display device per
output. If there are multiple displays for the output, either the first one is
picked or, if def_display has been defined in kernel parameters and the
def_display is one of the displays for this output, the def_display is picked.
See the patch for more information.

My belief is that neither patch should break things, but there's the
possibility. So I've tried to cc people who might have an opinion about this,
or perhaps test their setup with these patches.

The series is based on the latest omapdss master branch, and is available at:

git://gitorious.org/linux-omap-dss2/linux.git work/devtree-base

 Tomi

Tomi Valkeinen (8):
  OMAPDSS: omap_dss_register_device() doesn't take display index
  OMAPDSS: Add dss_get_default_display_name()
  OMAPDSS: register only one display device per output
  OMAPDSS: explicitely initialize dssdev->channel for new displays
  OMAPDSS: handle errors in dss_init_device
  OMAPDSS: cleanup dss_recheck_connections
  OMAPDSS: cleanup dss_recheck_connections further
  OMAPDSS: alloc dssdevs dynamically

 drivers/video/omap2/dss/core.c    |   91 +++++++++++++++++++------------------
 drivers/video/omap2/dss/display.c |   85 +++++++++++++++++++++++++++++++---
 drivers/video/omap2/dss/dpi.c     |   58 ++++++++++++++++++-----
 drivers/video/omap2/dss/dsi.c     |   62 +++++++++++++++++++------
 drivers/video/omap2/dss/dss.h     |   15 +++---
 drivers/video/omap2/dss/hdmi.c    |   70 ++++++++++++++++++++++------
 drivers/video/omap2/dss/overlay.c |   69 ----------------------------
 drivers/video/omap2/dss/rfbi.c    |   58 ++++++++++++++++++-----
 drivers/video/omap2/dss/sdi.c     |   58 ++++++++++++++++++-----
 drivers/video/omap2/dss/venc.c    |   60 +++++++++++++++++++-----
 10 files changed, 428 insertions(+), 198 deletions(-)

-- 
1.7.9.5


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

* [PATCH 1/8] OMAPDSS: omap_dss_register_device() doesn't take display index
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 2/8] OMAPDSS: Add dss_get_default_display_name() Tomi Valkeinen
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

We used to have all the displays of the board in one list, and we made a
"displayX" directory in the sysfs, where X was the index of the display
in the list.

This doesn't work anymore with device tree, as there's no single list to
get the number from, and it doesn't work very well even with non-DT as
we need to do some tricks to get the index nowadays.

This patch changes omap_dss_register_device() so that it doesn't take
disp_num as a parameter anymore, but uses a private increasing counter
for the display number.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/core.c |    9 +++++----
 drivers/video/omap2/dss/dpi.c  |    2 +-
 drivers/video/omap2/dss/dsi.c  |    2 +-
 drivers/video/omap2/dss/dss.h  |    2 +-
 drivers/video/omap2/dss/hdmi.c |    2 +-
 drivers/video/omap2/dss/rfbi.c |    2 +-
 drivers/video/omap2/dss/sdi.c  |    2 +-
 drivers/video/omap2/dss/venc.c |    2 +-
 8 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 58bd9c2..20c8bc8 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -450,16 +450,17 @@ static void omap_dss_dev_release(struct device *dev)
 	reset_device(dev, 0);
 }
 
+static int disp_num_counter;
+
 int omap_dss_register_device(struct omap_dss_device *dssdev,
-		struct device *parent, int disp_num)
+		struct device *parent)
 {
-	WARN_ON(!dssdev->driver_name);
-
 	reset_device(&dssdev->dev, 1);
+
 	dssdev->dev.bus = &dss_bus_type;
 	dssdev->dev.parent = parent;
 	dssdev->dev.release = omap_dss_dev_release;
-	dev_set_name(&dssdev->dev, "display%d", disp_num);
+	dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
 	return device_register(&dssdev->dev);
 }
 
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 5ccce9b..703fc1d 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -388,7 +388,7 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 			continue;
 		}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
+		r = omap_dss_register_device(dssdev, &pdev->dev);
 		if (r)
 			DSSERR("device %s register failed: %d\n",
 					dssdev->name, r);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 8d815e3..f7078fc 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5027,7 +5027,7 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
 			continue;
 		}
 
-		r = omap_dss_register_device(dssdev, &dsidev->dev, i);
+		r = omap_dss_register_device(dssdev, &dsidev->dev);
 		if (r)
 			DSSERR("device %s register failed: %d\n",
 					dssdev->name, r);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5e9fd769..7bac8ee 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -185,7 +185,7 @@ int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
 int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
 
 int omap_dss_register_device(struct omap_dss_device *dssdev,
-		struct device *parent, int disp_num);
+		struct device *parent);
 void omap_dss_unregister_device(struct omap_dss_device *dssdev);
 void omap_dss_unregister_child_devices(struct device *parent);
 
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 83f1845..bb07143 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -923,7 +923,7 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 			continue;
 		}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
+		r = omap_dss_register_device(dssdev, &pdev->dev);
 		if (r)
 			DSSERR("device %s register failed: %d\n",
 					dssdev->name, r);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 2e520d3..845b4e7 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -959,7 +959,7 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
 			continue;
 		}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
+		r = omap_dss_register_device(dssdev, &pdev->dev);
 		if (r)
 			DSSERR("device %s register failed: %d\n",
 				dssdev->name, r);
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 66c8de4..c9a9045 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -212,7 +212,7 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
 			continue;
 		}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
+		r = omap_dss_register_device(dssdev, &pdev->dev);
 		if (r)
 			DSSERR("device %s register failed: %d\n",
 					dssdev->name, r);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 17b3102..60bfc58 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -752,7 +752,7 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
 			continue;
 		}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
+		r = omap_dss_register_device(dssdev, &pdev->dev);
 		if (r)
 			DSSERR("device %s register failed: %d\n",
 					dssdev->name, r);
-- 
1.7.9.5


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

* [PATCH 2/8] OMAPDSS: Add dss_get_default_display_name()
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 1/8] OMAPDSS: omap_dss_register_device() doesn't take display index Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 3/8] OMAPDSS: register only one display device per output Tomi Valkeinen
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

Add function dss_get_default_display_name() which returns the name of
the default display, given from the board file or via module parameters.
The default display name can be used by output drivers to decide which
display is the wanted one.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/core.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 20c8bc8..315f557 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -57,6 +57,11 @@ bool dss_debug;
 module_param_named(debug, dss_debug, bool, 0644);
 #endif
 
+const char *dss_get_default_display_name(void)
+{
+	return core.default_display_name;
+}
+
 /* REGULATORS */
 
 struct regulator *dss_get_vdds_dsi(void)
-- 
1.7.9.5


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

* [PATCH 3/8] OMAPDSS: register only one display device per output
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 1/8] OMAPDSS: omap_dss_register_device() doesn't take display index Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 2/8] OMAPDSS: Add dss_get_default_display_name() Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 4/8] OMAPDSS: explicitely initialize dssdev->channel for new displays Tomi Valkeinen
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

We have boards with multiple panel devices connected to the same
physical output, of which only one panel can be enabled at one time.
Examples of these are Overo, where you can use different daughter boards
that have different LCDs, and 3430SDP which has an LCD and a DVI output
and a physical switch to select the active display.

These are supported by omapdss so that we add all the possible display
devices at probe, but the displays are inactive until somebody enables
one. At this point the panel driver starts using the DSS, thus reserving
the physcal resource and excluding the other panels.

This is problematic:
- Panel drivers can't allocate their resources properly at probe(),
  because the resources can be shared with other panels. Thus they can
  be only reserved at enable time.
- Managing this in omapdss is confusing. It's not natural to have
  child devices, which may not even exist (for example, a daughterboard
  that is not connected).

Only some boards have multiple displays per output, and of those, only
very few have possibility of switching the display during runtime.
Because of the above points:
- We don't want to make omapdss and all the panel drivers more complex
  just because some boards have complex setups.
- Only few boards support runtime switching, and afaik even then it's
  not required. So we don't need to support runtime switching.

Thus we'll change to a model where we will have only one display device
per output and this cannot be (currently) changed at runtime. We'll
still have the possibility to select the display from multiple options
during boot with the default display option.

This patch accomplishes the above by changing how the output drivers
register the display device. Instead of registering all the devices
given from the board file, we'll only register one. If the default
display option is set, the output driver selects that display from its
displays. If the default display is not set, or the default display is
not one of the output's displays, the output driver selects the first
display.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/dpi.c  |   47 ++++++++++++++++++++++++++-------
 drivers/video/omap2/dss/dsi.c  |   51 ++++++++++++++++++++++++++---------
 drivers/video/omap2/dss/dss.h  |    1 +
 drivers/video/omap2/dss/hdmi.c |   57 ++++++++++++++++++++++++++++++----------
 drivers/video/omap2/dss/rfbi.c |   47 ++++++++++++++++++++++++++-------
 drivers/video/omap2/dss/sdi.c  |   47 ++++++++++++++++++++++++++-------
 drivers/video/omap2/dss/venc.c |   47 ++++++++++++++++++++++++++-------
 7 files changed, 231 insertions(+), 66 deletions(-)

diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 703fc1d..6f9a199 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -371,10 +371,14 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
 	return 0;
 }
 
-static void __init dpi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -382,16 +386,39 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
 		if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
 			continue;
 
-		r = dpi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
+		if (def_dssdev = NULL)
+			def_dssdev = dssdev;
+
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) = 0) {
+			def_dssdev = dssdev;
+			break;
 		}
+	}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+	return def_dssdev;
+}
+
+static void __init dpi_probe_pdata(struct platform_device *pdev)
+{
+	struct omap_dss_device *dssdev;
+	int r;
+
+	dssdev = dpi_find_dssdev(pdev);
+
+	if (!dssdev)
+		return;
+
+	r = dpi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		return;
+	}
+
+	r = omap_dss_register_device(dssdev, &pdev->dev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		return;
 	}
 }
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index f7078fc..ee9ae52 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5006,11 +5006,15 @@ static void dsi_put_clocks(struct platform_device *dsidev)
 		clk_put(dsi->sys_clk);
 }
 
-static void __init dsi_probe_pdata(struct platform_device *dsidev)
+static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev)
 {
-	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-	struct omap_dss_board_info *pdata = dsidev->dev.platform_data;
-	int i, r;
+	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -5021,16 +5025,39 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
 		if (dssdev->phy.dsi.module != dsi->module_id)
 			continue;
 
-		r = dsi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
+		if (def_dssdev = NULL)
+			def_dssdev = dssdev;
+
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) = 0) {
+			def_dssdev = dssdev;
+			break;
 		}
+	}
 
-		r = omap_dss_register_device(dssdev, &dsidev->dev);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+	return def_dssdev;
+}
+
+static void __init dsi_probe_pdata(struct platform_device *dsidev)
+{
+	struct omap_dss_device *dssdev;
+	int r;
+
+	dssdev = dsi_find_dssdev(dsidev);
+
+	if (!dssdev)
+		return;
+
+	r = dsi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		return;
+	}
+
+	r = omap_dss_register_device(dssdev, &dsidev->dev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		return;
 	}
 }
 
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7bac8ee..a977826 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -175,6 +175,7 @@ struct seq_file;
 struct platform_device;
 
 /* core */
+const char *dss_get_default_display_name(void);
 struct bus_type *dss_get_bus(void);
 struct regulator *dss_get_vdds_dsi(void);
 struct regulator *dss_get_vdds_sdi(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index bb07143..76d100b 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -901,32 +901,61 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
 
 #endif
 
-static void __init hdmi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int r, i;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
-		struct omap_dss_hdmi_data *priv = dssdev->data;
 
 		if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
 			continue;
 
-		hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
-		hdmi.ls_oe_gpio = priv->ls_oe_gpio;
-		hdmi.hpd_gpio = priv->hpd_gpio;
+		if (def_dssdev = NULL)
+			def_dssdev = dssdev;
 
-		r = hdmi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) = 0) {
+			def_dssdev = dssdev;
+			break;
 		}
+	}
+
+	return def_dssdev;
+}
+
+static void __init hdmi_probe_pdata(struct platform_device *pdev)
+{
+	struct omap_dss_device *dssdev;
+	struct omap_dss_hdmi_data *priv;
+	int r;
 
-		r = omap_dss_register_device(dssdev, &pdev->dev);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+	dssdev = hdmi_find_dssdev(pdev);
+
+	if (!dssdev)
+		return;
+
+	priv = dssdev->data;
+
+	hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
+	hdmi.ls_oe_gpio = priv->ls_oe_gpio;
+	hdmi.hpd_gpio = priv->hpd_gpio;
+
+	r = hdmi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		return;
+	}
+
+	r = omap_dss_register_device(dssdev, &pdev->dev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		return;
 	}
 }
 
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 845b4e7..1127037 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -942,10 +942,14 @@ static int __init rfbi_init_display(struct omap_dss_device *dssdev)
 	return 0;
 }
 
-static void __init rfbi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -953,16 +957,39 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
 		if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
 			continue;
 
-		r = rfbi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
+		if (def_dssdev = NULL)
+			def_dssdev = dssdev;
+
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) = 0) {
+			def_dssdev = dssdev;
+			break;
 		}
+	}
+
+	return def_dssdev;
+}
+
+static void __init rfbi_probe_pdata(struct platform_device *pdev)
+{
+	struct omap_dss_device *dssdev;
+	int r;
+
+	dssdev = rfbi_find_dssdev(pdev);
 
-		r = omap_dss_register_device(dssdev, &pdev->dev);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-				dssdev->name, r);
+	if (!dssdev)
+		return;
+
+	r = rfbi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		return;
+	}
+
+	r = omap_dss_register_device(dssdev, &pdev->dev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		return;
 	}
 }
 
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index c9a9045..0aaa7f3 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -195,10 +195,14 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev)
 	return 0;
 }
 
-static void __init sdi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -206,16 +210,39 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
 		if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
 			continue;
 
-		r = sdi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
+		if (def_dssdev = NULL)
+			def_dssdev = dssdev;
+
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) = 0) {
+			def_dssdev = dssdev;
+			break;
 		}
+	}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+	return def_dssdev;
+}
+
+static void __init sdi_probe_pdata(struct platform_device *pdev)
+{
+	struct omap_dss_device *dssdev;
+	int r;
+
+	dssdev = sdi_find_dssdev(pdev);
+
+	if (!dssdev)
+		return;
+
+	r = sdi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		return;
+	}
+
+	r = omap_dss_register_device(dssdev, &pdev->dev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		return;
 	}
 }
 
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 60bfc58..b9c0a8f 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -735,10 +735,14 @@ static void venc_put_clocks(void)
 		clk_put(venc.tv_dac_clk);
 }
 
-static void __init venc_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int r, i;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -746,16 +750,39 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
 		if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
 			continue;
 
-		r = venc_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
+		if (def_dssdev = NULL)
+			def_dssdev = dssdev;
+
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) = 0) {
+			def_dssdev = dssdev;
+			break;
 		}
+	}
+
+	return def_dssdev;
+}
+
+static void __init venc_probe_pdata(struct platform_device *pdev)
+{
+	struct omap_dss_device *dssdev;
+	int r;
+
+	dssdev = venc_find_dssdev(pdev);
+
+	if (!dssdev)
+		return;
+
+	r = venc_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		return;
+	}
 
-		r = omap_dss_register_device(dssdev, &pdev->dev);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+	r = omap_dss_register_device(dssdev, &pdev->dev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		return;
 	}
 }
 
-- 
1.7.9.5


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

* [PATCH 4/8] OMAPDSS: explicitely initialize dssdev->channel for new displays
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
                   ` (2 preceding siblings ...)
  2012-09-19  8:30 ` [PATCH 3/8] OMAPDSS: register only one display device per output Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 5/8] OMAPDSS: handle errors in dss_init_device Tomi Valkeinen
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

HDMI and VENC outputs always use the DIGIT output from DISPC. The dssdev
struct contains "channel" field which is used to specify the DISPC
output for the display, but this was not used for HDMI and VENC.

This patch fills the channel field explicitely for HDMI and VENC
displays so that we can always rely on the channel field.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/hdmi.c |    2 ++
 drivers/video/omap2/dss/venc.c |    2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 76d100b..3b10e18 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -946,6 +946,8 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 	hdmi.ls_oe_gpio = priv->ls_oe_gpio;
 	hdmi.hpd_gpio = priv->hpd_gpio;
 
+	dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
 	r = hdmi_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index b9c0a8f..88fa6ea 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -773,6 +773,8 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
 	if (!dssdev)
 		return;
 
+	dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
 	r = venc_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
-- 
1.7.9.5


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

* [PATCH 5/8] OMAPDSS: handle errors in dss_init_device
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
                   ` (3 preceding siblings ...)
  2012-09-19  8:30 ` [PATCH 4/8] OMAPDSS: explicitely initialize dssdev->channel for new displays Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 6/8] OMAPDSS: cleanup dss_recheck_connections Tomi Valkeinen
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

Add error handling to dss_init_device(), which has, for some reason,
been missing.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/core.c    |    4 +++-
 drivers/video/omap2/dss/display.c |   23 ++++++++++++++++++-----
 drivers/video/omap2/dss/dss.h     |    2 +-
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 315f557..9315ece 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -358,7 +358,9 @@ static int dss_driver_probe(struct device *dev)
 				dev_name(dev), dssdev->driver_name,
 				dssdrv->driver.name);
 
-	dss_init_device(core.pdev, dssdev);
+	r = dss_init_device(core.pdev, dssdev);
+	if (r)
+		return r;
 
 	force = core.default_display_name &&
 		strcmp(core.default_display_name, dssdev->name) = 0;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 5f09d503..f719010 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -320,26 +320,39 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_default_get_timings);
 
-void dss_init_device(struct platform_device *pdev,
+int dss_init_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev)
 {
 	struct device_attribute *attr;
-	int i;
-	int r;
+	int i, r;
 
 	/* create device sysfs files */
 	i = 0;
 	while ((attr = display_sysfs_attrs[i++]) != NULL) {
 		r = device_create_file(&dssdev->dev, attr);
-		if (r)
+		if (r) {
+			for (i = i - 2; i >= 0; i--) {
+				attr = display_sysfs_attrs[i];
+				device_remove_file(&dssdev->dev, attr);
+			}
+
 			DSSERR("failed to create sysfs file\n");
+			return r;
+		}
 	}
 
 	/* create display? sysfs links */
 	r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
 			dev_name(&dssdev->dev));
-	if (r)
+	if (r) {
+		while ((attr = display_sysfs_attrs[i++]) != NULL)
+			device_remove_file(&dssdev->dev, attr);
+
 		DSSERR("failed to create sysfs display link\n");
+		return r;
+	}
+
+	return 0;
 }
 
 void dss_uninit_device(struct platform_device *pdev,
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index a977826..98e8273 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -228,7 +228,7 @@ int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
 void dss_disable_all_devices(void);
 
-void dss_init_device(struct platform_device *pdev,
+int dss_init_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev);
 void dss_uninit_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev);
-- 
1.7.9.5


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

* [PATCH 6/8] OMAPDSS: cleanup dss_recheck_connections
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
                   ` (4 preceding siblings ...)
  2012-09-19  8:30 ` [PATCH 5/8] OMAPDSS: handle errors in dss_init_device Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 7/8] OMAPDSS: cleanup dss_recheck_connections further Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 8/8] OMAPDSS: alloc dssdevs dynamically Tomi Valkeinen
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

dss_recheck_connections is quite a mess. With the previous commit that
initializes the channel field for HDMI and VENC displays, we can greatly
simplify the dss_recheck_connections.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/overlay.c |   49 +++++--------------------------------
 1 file changed, 6 insertions(+), 43 deletions(-)

diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index e3d4068..1bf05ef 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -109,52 +109,15 @@ void dss_init_overlays(struct platform_device *pdev)
  * selected, connect always. */
 void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 {
-	int i;
-	struct omap_overlay_manager *lcd_mgr;
-	struct omap_overlay_manager *tv_mgr;
-	struct omap_overlay_manager *lcd2_mgr = NULL;
-	struct omap_overlay_manager *lcd3_mgr = NULL;
 	struct omap_overlay_manager *mgr = NULL;
+	int i;
 
-	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
-	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
-	if (dssdev->channel = OMAP_DSS_CHANNEL_LCD3) {
-		if (!lcd3_mgr->device || force) {
-			if (lcd3_mgr->device)
-				lcd3_mgr->unset_device(lcd3_mgr);
-			lcd3_mgr->set_device(lcd3_mgr, dssdev);
-			mgr = lcd3_mgr;
-		}
-	} else if (dssdev->channel = OMAP_DSS_CHANNEL_LCD2) {
-		if (!lcd2_mgr->device || force) {
-			if (lcd2_mgr->device)
-				lcd2_mgr->unset_device(lcd2_mgr);
-			lcd2_mgr->set_device(lcd2_mgr, dssdev);
-			mgr = lcd2_mgr;
-		}
-	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
-			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
-		if (!lcd_mgr->device || force) {
-			if (lcd_mgr->device)
-				lcd_mgr->unset_device(lcd_mgr);
-			lcd_mgr->set_device(lcd_mgr, dssdev);
-			mgr = lcd_mgr;
-		}
-	}
+	mgr =  omap_dss_get_overlay_manager(dssdev->channel);
 
-	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
-			|| dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
-		if (!tv_mgr->device || force) {
-			if (tv_mgr->device)
-				tv_mgr->unset_device(tv_mgr);
-			tv_mgr->set_device(tv_mgr, dssdev);
-			mgr = tv_mgr;
-		}
+	if (!mgr->device || force) {
+		if (mgr->device)
+			mgr->unset_device(mgr);
+		mgr->set_device(mgr, dssdev);
 	}
 
 	if (mgr) {
-- 
1.7.9.5


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

* [PATCH 7/8] OMAPDSS: cleanup dss_recheck_connections further
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
                   ` (5 preceding siblings ...)
  2012-09-19  8:30 ` [PATCH 6/8] OMAPDSS: cleanup dss_recheck_connections Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  2012-09-19  8:30 ` [PATCH 8/8] OMAPDSS: alloc dssdevs dynamically Tomi Valkeinen
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

Cleanup dss_recheck_connections, move and rename it to a static
dss_init_connections function inside display.c. Improve the function to
return errors, and implement a matching dss_uninit_connections that can
be used to free the mgr->dssdev link.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/core.c    |    5 ---
 drivers/video/omap2/dss/display.c |   62 +++++++++++++++++++++++++++++++++++--
 drivers/video/omap2/dss/dss.h     |    1 -
 drivers/video/omap2/dss/overlay.c |   32 -------------------
 4 files changed, 60 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 9315ece..c4fd768 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -352,7 +352,6 @@ static int dss_driver_probe(struct device *dev)
 	int r;
 	struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
 	struct omap_dss_device *dssdev = to_dss_device(dev);
-	bool force;
 
 	DSSDBG("driver_probe: dev %s/%s, drv %s\n",
 				dev_name(dev), dssdev->driver_name,
@@ -362,10 +361,6 @@ static int dss_driver_probe(struct device *dev)
 	if (r)
 		return r;
 
-	force = core.default_display_name &&
-		strcmp(core.default_display_name, dssdev->name) = 0;
-	dss_recheck_connections(dssdev, force);
-
 	r = dssdrv->probe(dssdev);
 
 	if (r) {
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index f719010..db83ae8 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -320,11 +320,66 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_default_get_timings);
 
+/*
+ * Connect dssdev to a manager if the manager is free or if force is specified.
+ * Connect all overlays to that manager if they are free or if force is
+ * specified.
+ */
+static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
+{
+	struct omap_overlay_manager *mgr;
+	int i, r;
+
+	WARN_ON(dssdev->manager);
+
+	mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+	if (mgr->device && !force)
+		return 0;
+
+	if (mgr->device)
+		mgr->unset_device(mgr);
+
+	r = mgr->set_device(mgr, dssdev);
+	if (r) {
+		DSSERR("failed to set initial manager\n");
+		return r;
+	}
+
+	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+		struct omap_overlay *ovl = omap_dss_get_overlay(i);
+
+		if (!ovl->manager || force) {
+			if (ovl->manager)
+				ovl->unset_manager(ovl);
+
+			r = ovl->set_manager(ovl, mgr);
+			if (r) {
+				DSSERR("failed to set initial overlay\n");
+				return r;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void dss_uninit_connections(struct omap_dss_device *dssdev)
+{
+	if (dssdev->manager)
+		dssdev->manager->unset_device(dssdev->manager);
+}
+
 int dss_init_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev)
 {
 	struct device_attribute *attr;
 	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	bool force;
+
+	force = def_disp_name && strcmp(def_disp_name, dssdev->name) = 0;
+	dss_init_connections(dssdev, force);
 
 	/* create device sysfs files */
 	i = 0;
@@ -336,6 +391,8 @@ int dss_init_device(struct platform_device *pdev,
 				device_remove_file(&dssdev->dev, attr);
 			}
 
+			dss_uninit_connections(dssdev);
+
 			DSSERR("failed to create sysfs file\n");
 			return r;
 		}
@@ -348,6 +405,8 @@ int dss_init_device(struct platform_device *pdev,
 		while ((attr = display_sysfs_attrs[i++]) != NULL)
 			device_remove_file(&dssdev->dev, attr);
 
+		dss_uninit_connections(dssdev);
+
 		DSSERR("failed to create sysfs display link\n");
 		return r;
 	}
@@ -366,8 +425,7 @@ void dss_uninit_device(struct platform_device *pdev,
 	while ((attr = display_sysfs_attrs[i++]) != NULL)
 		device_remove_file(&dssdev->dev, attr);
 
-	if (dssdev->manager)
-		dssdev->manager->unset_device(dssdev->manager);
+	dss_uninit_connections(dssdev);
 }
 
 static int dss_suspend_device(struct device *dev, void *data)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 98e8273..7a3fea6 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -263,7 +263,6 @@ void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr);
 void dss_init_overlays(struct platform_device *pdev);
 void dss_uninit_overlays(struct platform_device *pdev);
 void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
-void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
 int dss_ovl_simple_check(struct omap_overlay *ovl,
 		const struct omap_overlay_info *info);
 int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 1bf05ef..52455a0 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -105,38 +105,6 @@ void dss_init_overlays(struct platform_device *pdev)
 	}
 }
 
-/* connect overlays to the new device, if not already connected. if force
- * selected, connect always. */
-void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
-{
-	struct omap_overlay_manager *mgr = NULL;
-	int i;
-
-	mgr =  omap_dss_get_overlay_manager(dssdev->channel);
-
-	if (!mgr->device || force) {
-		if (mgr->device)
-			mgr->unset_device(mgr);
-		mgr->set_device(mgr, dssdev);
-	}
-
-	if (mgr) {
-		dispc_runtime_get();
-
-		for (i = 0; i < dss_feat_get_num_ovls(); i++) {
-			struct omap_overlay *ovl;
-			ovl = omap_dss_get_overlay(i);
-			if (!ovl->manager || force) {
-				if (ovl->manager)
-					ovl->unset_manager(ovl);
-				ovl->set_manager(ovl, mgr);
-			}
-		}
-
-		dispc_runtime_put();
-	}
-}
-
 void dss_uninit_overlays(struct platform_device *pdev)
 {
 	int i;
-- 
1.7.9.5


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

* [PATCH 8/8] OMAPDSS: alloc dssdevs dynamically
  2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
                   ` (6 preceding siblings ...)
  2012-09-19  8:30 ` [PATCH 7/8] OMAPDSS: cleanup dss_recheck_connections further Tomi Valkeinen
@ 2012-09-19  8:30 ` Tomi Valkeinen
  7 siblings, 0 replies; 9+ messages in thread
From: Tomi Valkeinen @ 2012-09-19  8:30 UTC (permalink / raw)
  To: archit, linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

We currently create omap_dss_devices statically in board files, and use
those devices directly in the omapdss driver. This model prevents us
from having the platform data (which the dssdevs in board files
practically are) as read-only, and it's also different than what we will
use with device tree.

This patch changes the model to be in line with DT model: we allocate
the dssdevs dynamically, and initialize them according to the data in
the board file's dssdev (basically we memcopy the dssdev fields).

The allocation and registration is done in the following steps in the
output drivers:

- Use dss_alloc_and_init_device to allocate and initialize the device.
  The function uses kalloc and device_initialize to accomplish this.
- Call dss_copy_device_pdata to copy the data from the board file's
  dssdev
- Use dss_add_device to register the device.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/core.c |   72 ++++++++++++++++++++--------------------
 drivers/video/omap2/dss/dpi.c  |   17 +++++++---
 drivers/video/omap2/dss/dsi.c  |   15 +++++++--
 drivers/video/omap2/dss/dss.h  |   11 +++---
 drivers/video/omap2/dss/hdmi.c |   15 +++++++--
 drivers/video/omap2/dss/rfbi.c |   17 +++++++---
 drivers/video/omap2/dss/sdi.c  |   17 +++++++---
 drivers/video/omap2/dss/venc.c |   17 +++++++---
 8 files changed, 119 insertions(+), 62 deletions(-)

diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c4fd768..b2af72d 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/suspend.h>
+#include <linux/slab.h>
 
 #include <video/omapdss.h>
 
@@ -418,55 +419,44 @@ void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
 EXPORT_SYMBOL(omap_dss_unregister_driver);
 
 /* DEVICE */
-static void reset_device(struct device *dev, int check)
-{
-	u8 *dev_p = (u8 *)dev;
-	u8 *dev_end = dev_p + sizeof(*dev);
-	void *saved_pdata;
-
-	saved_pdata = dev->platform_data;
-	if (check) {
-		/*
-		 * Check if there is any other setting than platform_data
-		 * in struct device; warn that these will be reset by our
-		 * init.
-		 */
-		dev->platform_data = NULL;
-		while (dev_p < dev_end) {
-			if (*dev_p) {
-				WARN("%s: struct device fields will be "
-						"discarded\n",
-				     __func__);
-				break;
-			}
-			dev_p++;
-		}
-	}
-	memset(dev, 0, sizeof(*dev));
-	dev->platform_data = saved_pdata;
-}
-
 
 static void omap_dss_dev_release(struct device *dev)
 {
-	reset_device(dev, 0);
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	kfree(dssdev);
 }
 
 static int disp_num_counter;
 
-int omap_dss_register_device(struct omap_dss_device *dssdev,
-		struct device *parent)
+struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
 {
-	reset_device(&dssdev->dev, 1);
+	struct omap_dss_device *dssdev;
+
+	dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL);
+	if (!dssdev)
+		return NULL;
 
 	dssdev->dev.bus = &dss_bus_type;
 	dssdev->dev.parent = parent;
 	dssdev->dev.release = omap_dss_dev_release;
 	dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
-	return device_register(&dssdev->dev);
+
+	device_initialize(&dssdev->dev);
+
+	return dssdev;
 }
 
-void omap_dss_unregister_device(struct omap_dss_device *dssdev)
+int dss_add_device(struct omap_dss_device *dssdev)
+{
+	return device_add(&dssdev->dev);
+}
+
+void dss_put_device(struct omap_dss_device *dssdev)
+{
+	put_device(&dssdev->dev);
+}
+
+void dss_unregister_device(struct omap_dss_device *dssdev)
 {
 	device_unregister(&dssdev->dev);
 }
@@ -474,15 +464,25 @@ void omap_dss_unregister_device(struct omap_dss_device *dssdev)
 static int dss_unregister_dss_dev(struct device *dev, void *data)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
-	omap_dss_unregister_device(dssdev);
+	dss_unregister_device(dssdev);
 	return 0;
 }
 
-void omap_dss_unregister_child_devices(struct device *parent)
+void dss_unregister_child_devices(struct device *parent)
 {
 	device_for_each_child(parent, NULL, dss_unregister_dss_dev);
 }
 
+void dss_copy_device_pdata(struct omap_dss_device *dst,
+		const struct omap_dss_device *src)
+{
+	u8 *d = (u8 *)dst;
+	u8 *s = (u8 *)src;
+	size_t dsize = sizeof(struct device);
+
+	memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize);
+}
+
 /* BUS */
 static int __init omap_dss_bus_register(void)
 {
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 6f9a199..fac19d3 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -399,25 +399,34 @@ static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *p
 	return def_dssdev;
 }
 
-static void __init dpi_probe_pdata(struct platform_device *pdev)
+static void __init dpi_probe_pdata(struct platform_device *dpidev)
 {
+	struct omap_dss_device *plat_dssdev;
 	struct omap_dss_device *dssdev;
 	int r;
 
-	dssdev = dpi_find_dssdev(pdev);
+	plat_dssdev = dpi_find_dssdev(dpidev);
 
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&dpidev->dev);
 	if (!dssdev)
 		return;
 
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
 	r = dpi_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 
-	r = omap_dss_register_device(dssdev, &pdev->dev);
+	r = dss_add_device(dssdev);
 	if (r) {
 		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 }
@@ -433,7 +442,7 @@ static int __init omap_dpi_probe(struct platform_device *pdev)
 
 static int __exit omap_dpi_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
 
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ee9ae52..1dd019c 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -5040,23 +5040,32 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p
 
 static void __init dsi_probe_pdata(struct platform_device *dsidev)
 {
+	struct omap_dss_device *plat_dssdev;
 	struct omap_dss_device *dssdev;
 	int r;
 
-	dssdev = dsi_find_dssdev(dsidev);
+	plat_dssdev = dsi_find_dssdev(dsidev);
 
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&dsidev->dev);
 	if (!dssdev)
 		return;
 
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
 	r = dsi_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 
-	r = omap_dss_register_device(dssdev, &dsidev->dev);
+	r = dss_add_device(dssdev);
 	if (r) {
 		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 }
@@ -5184,7 +5193,7 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
 
 	WARN_ON(dsi->scp_clk_refcount > 0);
 
-	omap_dss_unregister_child_devices(&dsidev->dev);
+	dss_unregister_child_devices(&dsidev->dev);
 
 	pm_runtime_disable(&dsidev->dev);
 
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7a3fea6..417d305 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -185,10 +185,13 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
 int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
 int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
 
-int omap_dss_register_device(struct omap_dss_device *dssdev,
-		struct device *parent);
-void omap_dss_unregister_device(struct omap_dss_device *dssdev);
-void omap_dss_unregister_child_devices(struct device *parent);
+struct omap_dss_device *dss_alloc_and_init_device(struct device *parent);
+int dss_add_device(struct omap_dss_device *dssdev);
+void dss_unregister_device(struct omap_dss_device *dssdev);
+void dss_unregister_child_devices(struct device *parent);
+void dss_put_device(struct omap_dss_device *dssdev);
+void dss_copy_device_pdata(struct omap_dss_device *dst,
+		const struct omap_dss_device *src);
 
 /* apply */
 void dss_apply_init(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 3b10e18..23daf7d 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -931,15 +931,22 @@ static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *
 
 static void __init hdmi_probe_pdata(struct platform_device *pdev)
 {
+	struct omap_dss_device *plat_dssdev;
 	struct omap_dss_device *dssdev;
 	struct omap_dss_hdmi_data *priv;
 	int r;
 
-	dssdev = hdmi_find_dssdev(pdev);
+	plat_dssdev = hdmi_find_dssdev(pdev);
 
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&pdev->dev);
 	if (!dssdev)
 		return;
 
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
 	priv = dssdev->data;
 
 	hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
@@ -951,12 +958,14 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 	r = hdmi_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 
-	r = omap_dss_register_device(dssdev, &pdev->dev);
+	r = dss_add_device(dssdev);
 	if (r) {
 		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 }
@@ -1020,7 +1029,7 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
 {
 	device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
 
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
 
 	hdmi_panel_exit();
 
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 1127037..38d9b8e 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -970,25 +970,34 @@ static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *
 	return def_dssdev;
 }
 
-static void __init rfbi_probe_pdata(struct platform_device *pdev)
+static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
 {
+	struct omap_dss_device *plat_dssdev;
 	struct omap_dss_device *dssdev;
 	int r;
 
-	dssdev = rfbi_find_dssdev(pdev);
+	plat_dssdev = rfbi_find_dssdev(rfbidev);
 
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&rfbidev->dev);
 	if (!dssdev)
 		return;
 
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
 	r = rfbi_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 
-	r = omap_dss_register_device(dssdev, &pdev->dev);
+	r = dss_add_device(dssdev);
 	if (r) {
 		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 }
@@ -1055,7 +1064,7 @@ err_runtime_get:
 
 static int __exit omap_rfbihw_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0aaa7f3..919ff72 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -223,25 +223,34 @@ static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *p
 	return def_dssdev;
 }
 
-static void __init sdi_probe_pdata(struct platform_device *pdev)
+static void __init sdi_probe_pdata(struct platform_device *sdidev)
 {
+	struct omap_dss_device *plat_dssdev;
 	struct omap_dss_device *dssdev;
 	int r;
 
-	dssdev = sdi_find_dssdev(pdev);
+	plat_dssdev = sdi_find_dssdev(sdidev);
 
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&sdidev->dev);
 	if (!dssdev)
 		return;
 
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
 	r = sdi_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 
-	r = omap_dss_register_device(dssdev, &pdev->dev);
+	r = dss_add_device(dssdev);
 	if (r) {
 		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 }
@@ -255,7 +264,7 @@ static int __init omap_sdi_probe(struct platform_device *pdev)
 
 static int __exit omap_sdi_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
 
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 88fa6ea..996779c 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -763,27 +763,36 @@ static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *
 	return def_dssdev;
 }
 
-static void __init venc_probe_pdata(struct platform_device *pdev)
+static void __init venc_probe_pdata(struct platform_device *vencdev)
 {
+	struct omap_dss_device *plat_dssdev;
 	struct omap_dss_device *dssdev;
 	int r;
 
-	dssdev = venc_find_dssdev(pdev);
+	plat_dssdev = venc_find_dssdev(vencdev);
 
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&vencdev->dev);
 	if (!dssdev)
 		return;
 
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
 	dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
 
 	r = venc_init_display(dssdev);
 	if (r) {
 		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 
-	r = omap_dss_register_device(dssdev, &pdev->dev);
+	r = dss_add_device(dssdev);
 	if (r) {
 		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
 		return;
 	}
 }
@@ -848,7 +857,7 @@ err_runtime_get:
 
 static int __exit omap_venchw_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
 
 	if (venc.vdda_dac_reg != NULL) {
 		regulator_put(venc.vdda_dac_reg);
-- 
1.7.9.5


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

end of thread, other threads:[~2012-09-19  8:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-19  8:30 [PATCH 0/8] OMAPDSS: dss device model changes Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 1/8] OMAPDSS: omap_dss_register_device() doesn't take display index Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 2/8] OMAPDSS: Add dss_get_default_display_name() Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 3/8] OMAPDSS: register only one display device per output Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 4/8] OMAPDSS: explicitely initialize dssdev->channel for new displays Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 5/8] OMAPDSS: handle errors in dss_init_device Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 6/8] OMAPDSS: cleanup dss_recheck_connections Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 7/8] OMAPDSS: cleanup dss_recheck_connections further Tomi Valkeinen
2012-09-19  8:30 ` [PATCH 8/8] OMAPDSS: alloc dssdevs dynamically Tomi Valkeinen

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).