aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-25 04:23:14 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-25 04:23:14 -0400
commitc0ca7c38c5d35c12a9b94ef42842b325dfd2a3cd (patch)
tree2190b0a91130b8b9c7f0e562ea5d28a885f3eb19 /drivers/video
parent524d9f48a64dbe1ec3a276b57ac2a422fc14af07 (diff)
parent5274484b821bb2cf34a697624ef14084c31b16ce (diff)
Merge omapdss single-dssdev series
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 are 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. OMAPDSS: alloc dssdevs dynamically OMAPDSS: cleanup dss_recheck_connections further OMAPDSS: cleanup dss_recheck_connections OMAPDSS: handle errors in dss_init_device OMAPDSS: explicitely initialize dssdev->channel for new displays OMAPDSS: register only one display device per output OMAPDSS: Add dss_get_default_display_name() OMAPDSS: omap_dss_register_device() doesn't take display index
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/core.c91
-rw-r--r--drivers/video/omap2/dss/display.c85
-rw-r--r--drivers/video/omap2/dss/dpi.c58
-rw-r--r--drivers/video/omap2/dss/dsi.c62
-rw-r--r--drivers/video/omap2/dss/dss.h15
-rw-r--r--drivers/video/omap2/dss/hdmi.c70
-rw-r--r--drivers/video/omap2/dss/overlay.c69
-rw-r--r--drivers/video/omap2/dss/rfbi.c58
-rw-r--r--drivers/video/omap2/dss/sdi.c58
-rw-r--r--drivers/video/omap2/dss/venc.c60
10 files changed, 428 insertions, 198 deletions
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 58bd9c27369d..b2af72dc20bd 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -33,6 +33,7 @@
33#include <linux/device.h> 33#include <linux/device.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35#include <linux/suspend.h> 35#include <linux/suspend.h>
36#include <linux/slab.h>
36 37
37#include <video/omapdss.h> 38#include <video/omapdss.h>
38 39
@@ -57,6 +58,11 @@ bool dss_debug;
57module_param_named(debug, dss_debug, bool, 0644); 58module_param_named(debug, dss_debug, bool, 0644);
58#endif 59#endif
59 60
61const char *dss_get_default_display_name(void)
62{
63 return core.default_display_name;
64}
65
60/* REGULATORS */ 66/* REGULATORS */
61 67
62struct regulator *dss_get_vdds_dsi(void) 68struct regulator *dss_get_vdds_dsi(void)
@@ -347,17 +353,14 @@ static int dss_driver_probe(struct device *dev)
347 int r; 353 int r;
348 struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver); 354 struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
349 struct omap_dss_device *dssdev = to_dss_device(dev); 355 struct omap_dss_device *dssdev = to_dss_device(dev);
350 bool force;
351 356
352 DSSDBG("driver_probe: dev %s/%s, drv %s\n", 357 DSSDBG("driver_probe: dev %s/%s, drv %s\n",
353 dev_name(dev), dssdev->driver_name, 358 dev_name(dev), dssdev->driver_name,
354 dssdrv->driver.name); 359 dssdrv->driver.name);
355 360
356 dss_init_device(core.pdev, dssdev); 361 r = dss_init_device(core.pdev, dssdev);
357 362 if (r)
358 force = core.default_display_name && 363 return r;
359 strcmp(core.default_display_name, dssdev->name) == 0;
360 dss_recheck_connections(dssdev, force);
361 364
362 r = dssdrv->probe(dssdev); 365 r = dssdrv->probe(dssdev);
363 366
@@ -416,54 +419,44 @@ void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
416EXPORT_SYMBOL(omap_dss_unregister_driver); 419EXPORT_SYMBOL(omap_dss_unregister_driver);
417 420
418/* DEVICE */ 421/* DEVICE */
419static void reset_device(struct device *dev, int check)
420{
421 u8 *dev_p = (u8 *)dev;
422 u8 *dev_end = dev_p + sizeof(*dev);
423 void *saved_pdata;
424
425 saved_pdata = dev->platform_data;
426 if (check) {
427 /*
428 * Check if there is any other setting than platform_data
429 * in struct device; warn that these will be reset by our
430 * init.
431 */
432 dev->platform_data = NULL;
433 while (dev_p < dev_end) {
434 if (*dev_p) {
435 WARN("%s: struct device fields will be "
436 "discarded\n",
437 __func__);
438 break;
439 }
440 dev_p++;
441 }
442 }
443 memset(dev, 0, sizeof(*dev));
444 dev->platform_data = saved_pdata;
445}
446
447 422
448static void omap_dss_dev_release(struct device *dev) 423static void omap_dss_dev_release(struct device *dev)
449{ 424{
450 reset_device(dev, 0); 425 struct omap_dss_device *dssdev = to_dss_device(dev);
426 kfree(dssdev);
451} 427}
452 428
453int omap_dss_register_device(struct omap_dss_device *dssdev, 429static int disp_num_counter;
454 struct device *parent, int disp_num) 430
431struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
455{ 432{
456 WARN_ON(!dssdev->driver_name); 433 struct omap_dss_device *dssdev;
434
435 dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL);
436 if (!dssdev)
437 return NULL;
457 438
458 reset_device(&dssdev->dev, 1);
459 dssdev->dev.bus = &dss_bus_type; 439 dssdev->dev.bus = &dss_bus_type;
460 dssdev->dev.parent = parent; 440 dssdev->dev.parent = parent;
461 dssdev->dev.release = omap_dss_dev_release; 441 dssdev->dev.release = omap_dss_dev_release;
462 dev_set_name(&dssdev->dev, "display%d", disp_num); 442 dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
463 return device_register(&dssdev->dev); 443
444 device_initialize(&dssdev->dev);
445
446 return dssdev;
447}
448
449int dss_add_device(struct omap_dss_device *dssdev)
450{
451 return device_add(&dssdev->dev);
452}
453
454void dss_put_device(struct omap_dss_device *dssdev)
455{
456 put_device(&dssdev->dev);
464} 457}
465 458
466void omap_dss_unregister_device(struct omap_dss_device *dssdev) 459void dss_unregister_device(struct omap_dss_device *dssdev)
467{ 460{
468 device_unregister(&dssdev->dev); 461 device_unregister(&dssdev->dev);
469} 462}
@@ -471,15 +464,25 @@ void omap_dss_unregister_device(struct omap_dss_device *dssdev)
471static int dss_unregister_dss_dev(struct device *dev, void *data) 464static int dss_unregister_dss_dev(struct device *dev, void *data)
472{ 465{
473 struct omap_dss_device *dssdev = to_dss_device(dev); 466 struct omap_dss_device *dssdev = to_dss_device(dev);
474 omap_dss_unregister_device(dssdev); 467 dss_unregister_device(dssdev);
475 return 0; 468 return 0;
476} 469}
477 470
478void omap_dss_unregister_child_devices(struct device *parent) 471void dss_unregister_child_devices(struct device *parent)
479{ 472{
480 device_for_each_child(parent, NULL, dss_unregister_dss_dev); 473 device_for_each_child(parent, NULL, dss_unregister_dss_dev);
481} 474}
482 475
476void dss_copy_device_pdata(struct omap_dss_device *dst,
477 const struct omap_dss_device *src)
478{
479 u8 *d = (u8 *)dst;
480 u8 *s = (u8 *)src;
481 size_t dsize = sizeof(struct device);
482
483 memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize);
484}
485
483/* BUS */ 486/* BUS */
484static int __init omap_dss_bus_register(void) 487static int __init omap_dss_bus_register(void)
485{ 488{
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 5f09d503d619..db83ae81a713 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -320,26 +320,98 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
320} 320}
321EXPORT_SYMBOL(omapdss_default_get_timings); 321EXPORT_SYMBOL(omapdss_default_get_timings);
322 322
323void dss_init_device(struct platform_device *pdev, 323/*
324 * Connect dssdev to a manager if the manager is free or if force is specified.
325 * Connect all overlays to that manager if they are free or if force is
326 * specified.
327 */
328static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
329{
330 struct omap_overlay_manager *mgr;
331 int i, r;
332
333 WARN_ON(dssdev->manager);
334
335 mgr = omap_dss_get_overlay_manager(dssdev->channel);
336
337 if (mgr->device && !force)
338 return 0;
339
340 if (mgr->device)
341 mgr->unset_device(mgr);
342
343 r = mgr->set_device(mgr, dssdev);
344 if (r) {
345 DSSERR("failed to set initial manager\n");
346 return r;
347 }
348
349 for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
350 struct omap_overlay *ovl = omap_dss_get_overlay(i);
351
352 if (!ovl->manager || force) {
353 if (ovl->manager)
354 ovl->unset_manager(ovl);
355
356 r = ovl->set_manager(ovl, mgr);
357 if (r) {
358 DSSERR("failed to set initial overlay\n");
359 return r;
360 }
361 }
362 }
363
364 return 0;
365}
366
367static void dss_uninit_connections(struct omap_dss_device *dssdev)
368{
369 if (dssdev->manager)
370 dssdev->manager->unset_device(dssdev->manager);
371}
372
373int dss_init_device(struct platform_device *pdev,
324 struct omap_dss_device *dssdev) 374 struct omap_dss_device *dssdev)
325{ 375{
326 struct device_attribute *attr; 376 struct device_attribute *attr;
327 int i; 377 int i, r;
328 int r; 378 const char *def_disp_name = dss_get_default_display_name();
379 bool force;
380
381 force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
382 dss_init_connections(dssdev, force);
329 383
330 /* create device sysfs files */ 384 /* create device sysfs files */
331 i = 0; 385 i = 0;
332 while ((attr = display_sysfs_attrs[i++]) != NULL) { 386 while ((attr = display_sysfs_attrs[i++]) != NULL) {
333 r = device_create_file(&dssdev->dev, attr); 387 r = device_create_file(&dssdev->dev, attr);
334 if (r) 388 if (r) {
389 for (i = i - 2; i >= 0; i--) {
390 attr = display_sysfs_attrs[i];
391 device_remove_file(&dssdev->dev, attr);
392 }
393
394 dss_uninit_connections(dssdev);
395
335 DSSERR("failed to create sysfs file\n"); 396 DSSERR("failed to create sysfs file\n");
397 return r;
398 }
336 } 399 }
337 400
338 /* create display? sysfs links */ 401 /* create display? sysfs links */
339 r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj, 402 r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
340 dev_name(&dssdev->dev)); 403 dev_name(&dssdev->dev));
341 if (r) 404 if (r) {
405 while ((attr = display_sysfs_attrs[i++]) != NULL)
406 device_remove_file(&dssdev->dev, attr);
407
408 dss_uninit_connections(dssdev);
409
342 DSSERR("failed to create sysfs display link\n"); 410 DSSERR("failed to create sysfs display link\n");
411 return r;
412 }
413
414 return 0;
343} 415}
344 416
345void dss_uninit_device(struct platform_device *pdev, 417void dss_uninit_device(struct platform_device *pdev,
@@ -353,8 +425,7 @@ void dss_uninit_device(struct platform_device *pdev,
353 while ((attr = display_sysfs_attrs[i++]) != NULL) 425 while ((attr = display_sysfs_attrs[i++]) != NULL)
354 device_remove_file(&dssdev->dev, attr); 426 device_remove_file(&dssdev->dev, attr);
355 427
356 if (dssdev->manager) 428 dss_uninit_connections(dssdev);
357 dssdev->manager->unset_device(dssdev->manager);
358} 429}
359 430
360static int dss_suspend_device(struct device *dev, void *data) 431static int dss_suspend_device(struct device *dev, void *data)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 5ccce9b69e42..fac19d39ab18 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)
371 return 0; 371 return 0;
372} 372}
373 373
374static void __init dpi_probe_pdata(struct platform_device *pdev) 374static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
375{ 375{
376 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 376 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
377 int i, r; 377 const char *def_disp_name = dss_get_default_display_name();
378 struct omap_dss_device *def_dssdev;
379 int i;
380
381 def_dssdev = NULL;
378 382
379 for (i = 0; i < pdata->num_devices; ++i) { 383 for (i = 0; i < pdata->num_devices; ++i) {
380 struct omap_dss_device *dssdev = pdata->devices[i]; 384 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -382,16 +386,48 @@ static void __init dpi_probe_pdata(struct platform_device *pdev)
382 if (dssdev->type != OMAP_DISPLAY_TYPE_DPI) 386 if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
383 continue; 387 continue;
384 388
385 r = dpi_init_display(dssdev); 389 if (def_dssdev == NULL)
386 if (r) { 390 def_dssdev = dssdev;
387 DSSERR("device %s init failed: %d\n", dssdev->name, r); 391
388 continue; 392 if (def_disp_name != NULL &&
393 strcmp(dssdev->name, def_disp_name) == 0) {
394 def_dssdev = dssdev;
395 break;
389 } 396 }
397 }
390 398
391 r = omap_dss_register_device(dssdev, &pdev->dev, i); 399 return def_dssdev;
392 if (r) 400}
393 DSSERR("device %s register failed: %d\n", 401
394 dssdev->name, r); 402static void __init dpi_probe_pdata(struct platform_device *dpidev)
403{
404 struct omap_dss_device *plat_dssdev;
405 struct omap_dss_device *dssdev;
406 int r;
407
408 plat_dssdev = dpi_find_dssdev(dpidev);
409
410 if (!plat_dssdev)
411 return;
412
413 dssdev = dss_alloc_and_init_device(&dpidev->dev);
414 if (!dssdev)
415 return;
416
417 dss_copy_device_pdata(dssdev, plat_dssdev);
418
419 r = dpi_init_display(dssdev);
420 if (r) {
421 DSSERR("device %s init failed: %d\n", dssdev->name, r);
422 dss_put_device(dssdev);
423 return;
424 }
425
426 r = dss_add_device(dssdev);
427 if (r) {
428 DSSERR("device %s register failed: %d\n", dssdev->name, r);
429 dss_put_device(dssdev);
430 return;
395 } 431 }
396} 432}
397 433
@@ -406,7 +442,7 @@ static int __init omap_dpi_probe(struct platform_device *pdev)
406 442
407static int __exit omap_dpi_remove(struct platform_device *pdev) 443static int __exit omap_dpi_remove(struct platform_device *pdev)
408{ 444{
409 omap_dss_unregister_child_devices(&pdev->dev); 445 dss_unregister_child_devices(&pdev->dev);
410 446
411 return 0; 447 return 0;
412} 448}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 8d815e39e45d..1dd019cf9649 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)
5006 clk_put(dsi->sys_clk); 5006 clk_put(dsi->sys_clk);
5007} 5007}
5008 5008
5009static void __init dsi_probe_pdata(struct platform_device *dsidev) 5009static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev)
5010{ 5010{
5011 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5011 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
5012 struct omap_dss_board_info *pdata = dsidev->dev.platform_data; 5012 struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
5013 int i, r; 5013 const char *def_disp_name = dss_get_default_display_name();
5014 struct omap_dss_device *def_dssdev;
5015 int i;
5016
5017 def_dssdev = NULL;
5014 5018
5015 for (i = 0; i < pdata->num_devices; ++i) { 5019 for (i = 0; i < pdata->num_devices; ++i) {
5016 struct omap_dss_device *dssdev = pdata->devices[i]; 5020 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -5021,16 +5025,48 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)
5021 if (dssdev->phy.dsi.module != dsi->module_id) 5025 if (dssdev->phy.dsi.module != dsi->module_id)
5022 continue; 5026 continue;
5023 5027
5024 r = dsi_init_display(dssdev); 5028 if (def_dssdev == NULL)
5025 if (r) { 5029 def_dssdev = dssdev;
5026 DSSERR("device %s init failed: %d\n", dssdev->name, r); 5030
5027 continue; 5031 if (def_disp_name != NULL &&
5032 strcmp(dssdev->name, def_disp_name) == 0) {
5033 def_dssdev = dssdev;
5034 break;
5028 } 5035 }
5036 }
5029 5037
5030 r = omap_dss_register_device(dssdev, &dsidev->dev, i); 5038 return def_dssdev;
5031 if (r) 5039}
5032 DSSERR("device %s register failed: %d\n", 5040
5033 dssdev->name, r); 5041static void __init dsi_probe_pdata(struct platform_device *dsidev)
5042{
5043 struct omap_dss_device *plat_dssdev;
5044 struct omap_dss_device *dssdev;
5045 int r;
5046
5047 plat_dssdev = dsi_find_dssdev(dsidev);
5048
5049 if (!plat_dssdev)
5050 return;
5051
5052 dssdev = dss_alloc_and_init_device(&dsidev->dev);
5053 if (!dssdev)
5054 return;
5055
5056 dss_copy_device_pdata(dssdev, plat_dssdev);
5057
5058 r = dsi_init_display(dssdev);
5059 if (r) {
5060 DSSERR("device %s init failed: %d\n", dssdev->name, r);
5061 dss_put_device(dssdev);
5062 return;
5063 }
5064
5065 r = dss_add_device(dssdev);
5066 if (r) {
5067 DSSERR("device %s register failed: %d\n", dssdev->name, r);
5068 dss_put_device(dssdev);
5069 return;
5034 } 5070 }
5035} 5071}
5036 5072
@@ -5157,7 +5193,7 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5157 5193
5158 WARN_ON(dsi->scp_clk_refcount > 0); 5194 WARN_ON(dsi->scp_clk_refcount > 0);
5159 5195
5160 omap_dss_unregister_child_devices(&dsidev->dev); 5196 dss_unregister_child_devices(&dsidev->dev);
5161 5197
5162 pm_runtime_disable(&dsidev->dev); 5198 pm_runtime_disable(&dsidev->dev);
5163 5199
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 5e9fd7691728..417d30571747 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -175,6 +175,7 @@ struct seq_file;
175struct platform_device; 175struct platform_device;
176 176
177/* core */ 177/* core */
178const char *dss_get_default_display_name(void);
178struct bus_type *dss_get_bus(void); 179struct bus_type *dss_get_bus(void);
179struct regulator *dss_get_vdds_dsi(void); 180struct regulator *dss_get_vdds_dsi(void);
180struct regulator *dss_get_vdds_sdi(void); 181struct regulator *dss_get_vdds_sdi(void);
@@ -184,10 +185,13 @@ void dss_dsi_disable_pads(int dsi_id, unsigned lane_mask);
184int dss_set_min_bus_tput(struct device *dev, unsigned long tput); 185int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
185int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)); 186int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
186 187
187int omap_dss_register_device(struct omap_dss_device *dssdev, 188struct omap_dss_device *dss_alloc_and_init_device(struct device *parent);
188 struct device *parent, int disp_num); 189int dss_add_device(struct omap_dss_device *dssdev);
189void omap_dss_unregister_device(struct omap_dss_device *dssdev); 190void dss_unregister_device(struct omap_dss_device *dssdev);
190void omap_dss_unregister_child_devices(struct device *parent); 191void dss_unregister_child_devices(struct device *parent);
192void dss_put_device(struct omap_dss_device *dssdev);
193void dss_copy_device_pdata(struct omap_dss_device *dst,
194 const struct omap_dss_device *src);
191 195
192/* apply */ 196/* apply */
193void dss_apply_init(void); 197void dss_apply_init(void);
@@ -227,7 +231,7 @@ int dss_suspend_all_devices(void);
227int dss_resume_all_devices(void); 231int dss_resume_all_devices(void);
228void dss_disable_all_devices(void); 232void dss_disable_all_devices(void);
229 233
230void dss_init_device(struct platform_device *pdev, 234int dss_init_device(struct platform_device *pdev,
231 struct omap_dss_device *dssdev); 235 struct omap_dss_device *dssdev);
232void dss_uninit_device(struct platform_device *pdev, 236void dss_uninit_device(struct platform_device *pdev,
233 struct omap_dss_device *dssdev); 237 struct omap_dss_device *dssdev);
@@ -262,7 +266,6 @@ void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr);
262void dss_init_overlays(struct platform_device *pdev); 266void dss_init_overlays(struct platform_device *pdev);
263void dss_uninit_overlays(struct platform_device *pdev); 267void dss_uninit_overlays(struct platform_device *pdev);
264void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr); 268void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
265void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
266int dss_ovl_simple_check(struct omap_overlay *ovl, 269int dss_ovl_simple_check(struct omap_overlay *ovl,
267 const struct omap_overlay_info *info); 270 const struct omap_overlay_info *info);
268int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, 271int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 83f18458a406..23daf7dcf54a 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -901,32 +901,72 @@ int hdmi_audio_config(struct omap_dss_audio *audio)
901 901
902#endif 902#endif
903 903
904static void __init hdmi_probe_pdata(struct platform_device *pdev) 904static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
905{ 905{
906 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 906 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
907 int r, i; 907 const char *def_disp_name = dss_get_default_display_name();
908 struct omap_dss_device *def_dssdev;
909 int i;
910
911 def_dssdev = NULL;
908 912
909 for (i = 0; i < pdata->num_devices; ++i) { 913 for (i = 0; i < pdata->num_devices; ++i) {
910 struct omap_dss_device *dssdev = pdata->devices[i]; 914 struct omap_dss_device *dssdev = pdata->devices[i];
911 struct omap_dss_hdmi_data *priv = dssdev->data;
912 915
913 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI) 916 if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
914 continue; 917 continue;
915 918
916 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio; 919 if (def_dssdev == NULL)
917 hdmi.ls_oe_gpio = priv->ls_oe_gpio; 920 def_dssdev = dssdev;
918 hdmi.hpd_gpio = priv->hpd_gpio;
919 921
920 r = hdmi_init_display(dssdev); 922 if (def_disp_name != NULL &&
921 if (r) { 923 strcmp(dssdev->name, def_disp_name) == 0) {
922 DSSERR("device %s init failed: %d\n", dssdev->name, r); 924 def_dssdev = dssdev;
923 continue; 925 break;
924 } 926 }
927 }
928
929 return def_dssdev;
930}
925 931
926 r = omap_dss_register_device(dssdev, &pdev->dev, i); 932static void __init hdmi_probe_pdata(struct platform_device *pdev)
927 if (r) 933{
928 DSSERR("device %s register failed: %d\n", 934 struct omap_dss_device *plat_dssdev;
929 dssdev->name, r); 935 struct omap_dss_device *dssdev;
936 struct omap_dss_hdmi_data *priv;
937 int r;
938
939 plat_dssdev = hdmi_find_dssdev(pdev);
940
941 if (!plat_dssdev)
942 return;
943
944 dssdev = dss_alloc_and_init_device(&pdev->dev);
945 if (!dssdev)
946 return;
947
948 dss_copy_device_pdata(dssdev, plat_dssdev);
949
950 priv = dssdev->data;
951
952 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
953 hdmi.ls_oe_gpio = priv->ls_oe_gpio;
954 hdmi.hpd_gpio = priv->hpd_gpio;
955
956 dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
957
958 r = hdmi_init_display(dssdev);
959 if (r) {
960 DSSERR("device %s init failed: %d\n", dssdev->name, r);
961 dss_put_device(dssdev);
962 return;
963 }
964
965 r = dss_add_device(dssdev);
966 if (r) {
967 DSSERR("device %s register failed: %d\n", dssdev->name, r);
968 dss_put_device(dssdev);
969 return;
930 } 970 }
931} 971}
932 972
@@ -989,7 +1029,7 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
989{ 1029{
990 device_for_each_child(&pdev->dev, NULL, hdmi_remove_child); 1030 device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
991 1031
992 omap_dss_unregister_child_devices(&pdev->dev); 1032 dss_unregister_child_devices(&pdev->dev);
993 1033
994 hdmi_panel_exit(); 1034 hdmi_panel_exit();
995 1035
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index e3d406875afd..52455a0609cb 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -105,75 +105,6 @@ void dss_init_overlays(struct platform_device *pdev)
105 } 105 }
106} 106}
107 107
108/* connect overlays to the new device, if not already connected. if force
109 * selected, connect always. */
110void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
111{
112 int i;
113 struct omap_overlay_manager *lcd_mgr;
114 struct omap_overlay_manager *tv_mgr;
115 struct omap_overlay_manager *lcd2_mgr = NULL;
116 struct omap_overlay_manager *lcd3_mgr = NULL;
117 struct omap_overlay_manager *mgr = NULL;
118
119 lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
120 tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
121 if (dss_has_feature(FEAT_MGR_LCD3))
122 lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
123 if (dss_has_feature(FEAT_MGR_LCD2))
124 lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
125
126 if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
127 if (!lcd3_mgr->device || force) {
128 if (lcd3_mgr->device)
129 lcd3_mgr->unset_device(lcd3_mgr);
130 lcd3_mgr->set_device(lcd3_mgr, dssdev);
131 mgr = lcd3_mgr;
132 }
133 } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
134 if (!lcd2_mgr->device || force) {
135 if (lcd2_mgr->device)
136 lcd2_mgr->unset_device(lcd2_mgr);
137 lcd2_mgr->set_device(lcd2_mgr, dssdev);
138 mgr = lcd2_mgr;
139 }
140 } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
141 && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
142 if (!lcd_mgr->device || force) {
143 if (lcd_mgr->device)
144 lcd_mgr->unset_device(lcd_mgr);
145 lcd_mgr->set_device(lcd_mgr, dssdev);
146 mgr = lcd_mgr;
147 }
148 }
149
150 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
151 || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
152 if (!tv_mgr->device || force) {
153 if (tv_mgr->device)
154 tv_mgr->unset_device(tv_mgr);
155 tv_mgr->set_device(tv_mgr, dssdev);
156 mgr = tv_mgr;
157 }
158 }
159
160 if (mgr) {
161 dispc_runtime_get();
162
163 for (i = 0; i < dss_feat_get_num_ovls(); i++) {
164 struct omap_overlay *ovl;
165 ovl = omap_dss_get_overlay(i);
166 if (!ovl->manager || force) {
167 if (ovl->manager)
168 ovl->unset_manager(ovl);
169 ovl->set_manager(ovl, mgr);
170 }
171 }
172
173 dispc_runtime_put();
174 }
175}
176
177void dss_uninit_overlays(struct platform_device *pdev) 108void dss_uninit_overlays(struct platform_device *pdev)
178{ 109{
179 int i; 110 int i;
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 2e520d3085c8..38d9b8ecbe3c 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)
942 return 0; 942 return 0;
943} 943}
944 944
945static void __init rfbi_probe_pdata(struct platform_device *pdev) 945static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
946{ 946{
947 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 947 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
948 int i, r; 948 const char *def_disp_name = dss_get_default_display_name();
949 struct omap_dss_device *def_dssdev;
950 int i;
951
952 def_dssdev = NULL;
949 953
950 for (i = 0; i < pdata->num_devices; ++i) { 954 for (i = 0; i < pdata->num_devices; ++i) {
951 struct omap_dss_device *dssdev = pdata->devices[i]; 955 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -953,16 +957,48 @@ static void __init rfbi_probe_pdata(struct platform_device *pdev)
953 if (dssdev->type != OMAP_DISPLAY_TYPE_DBI) 957 if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
954 continue; 958 continue;
955 959
956 r = rfbi_init_display(dssdev); 960 if (def_dssdev == NULL)
957 if (r) { 961 def_dssdev = dssdev;
958 DSSERR("device %s init failed: %d\n", dssdev->name, r); 962
959 continue; 963 if (def_disp_name != NULL &&
964 strcmp(dssdev->name, def_disp_name) == 0) {
965 def_dssdev = dssdev;
966 break;
960 } 967 }
968 }
969
970 return def_dssdev;
971}
972
973static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
974{
975 struct omap_dss_device *plat_dssdev;
976 struct omap_dss_device *dssdev;
977 int r;
978
979 plat_dssdev = rfbi_find_dssdev(rfbidev);
961 980
962 r = omap_dss_register_device(dssdev, &pdev->dev, i); 981 if (!plat_dssdev)
963 if (r) 982 return;
964 DSSERR("device %s register failed: %d\n", 983
965 dssdev->name, r); 984 dssdev = dss_alloc_and_init_device(&rfbidev->dev);
985 if (!dssdev)
986 return;
987
988 dss_copy_device_pdata(dssdev, plat_dssdev);
989
990 r = rfbi_init_display(dssdev);
991 if (r) {
992 DSSERR("device %s init failed: %d\n", dssdev->name, r);
993 dss_put_device(dssdev);
994 return;
995 }
996
997 r = dss_add_device(dssdev);
998 if (r) {
999 DSSERR("device %s register failed: %d\n", dssdev->name, r);
1000 dss_put_device(dssdev);
1001 return;
966 } 1002 }
967} 1003}
968 1004
@@ -1028,7 +1064,7 @@ err_runtime_get:
1028 1064
1029static int __exit omap_rfbihw_remove(struct platform_device *pdev) 1065static int __exit omap_rfbihw_remove(struct platform_device *pdev)
1030{ 1066{
1031 omap_dss_unregister_child_devices(&pdev->dev); 1067 dss_unregister_child_devices(&pdev->dev);
1032 pm_runtime_disable(&pdev->dev); 1068 pm_runtime_disable(&pdev->dev);
1033 return 0; 1069 return 0;
1034} 1070}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 66c8de4365d6..919ff728c502 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)
195 return 0; 195 return 0;
196} 196}
197 197
198static void __init sdi_probe_pdata(struct platform_device *pdev) 198static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
199{ 199{
200 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 200 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
201 int i, r; 201 const char *def_disp_name = dss_get_default_display_name();
202 struct omap_dss_device *def_dssdev;
203 int i;
204
205 def_dssdev = NULL;
202 206
203 for (i = 0; i < pdata->num_devices; ++i) { 207 for (i = 0; i < pdata->num_devices; ++i) {
204 struct omap_dss_device *dssdev = pdata->devices[i]; 208 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -206,16 +210,48 @@ static void __init sdi_probe_pdata(struct platform_device *pdev)
206 if (dssdev->type != OMAP_DISPLAY_TYPE_SDI) 210 if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
207 continue; 211 continue;
208 212
209 r = sdi_init_display(dssdev); 213 if (def_dssdev == NULL)
210 if (r) { 214 def_dssdev = dssdev;
211 DSSERR("device %s init failed: %d\n", dssdev->name, r); 215
212 continue; 216 if (def_disp_name != NULL &&
217 strcmp(dssdev->name, def_disp_name) == 0) {
218 def_dssdev = dssdev;
219 break;
213 } 220 }
221 }
222
223 return def_dssdev;
224}
225
226static void __init sdi_probe_pdata(struct platform_device *sdidev)
227{
228 struct omap_dss_device *plat_dssdev;
229 struct omap_dss_device *dssdev;
230 int r;
214 231
215 r = omap_dss_register_device(dssdev, &pdev->dev, i); 232 plat_dssdev = sdi_find_dssdev(sdidev);
216 if (r) 233
217 DSSERR("device %s register failed: %d\n", 234 if (!plat_dssdev)
218 dssdev->name, r); 235 return;
236
237 dssdev = dss_alloc_and_init_device(&sdidev->dev);
238 if (!dssdev)
239 return;
240
241 dss_copy_device_pdata(dssdev, plat_dssdev);
242
243 r = sdi_init_display(dssdev);
244 if (r) {
245 DSSERR("device %s init failed: %d\n", dssdev->name, r);
246 dss_put_device(dssdev);
247 return;
248 }
249
250 r = dss_add_device(dssdev);
251 if (r) {
252 DSSERR("device %s register failed: %d\n", dssdev->name, r);
253 dss_put_device(dssdev);
254 return;
219 } 255 }
220} 256}
221 257
@@ -228,7 +264,7 @@ static int __init omap_sdi_probe(struct platform_device *pdev)
228 264
229static int __exit omap_sdi_remove(struct platform_device *pdev) 265static int __exit omap_sdi_remove(struct platform_device *pdev)
230{ 266{
231 omap_dss_unregister_child_devices(&pdev->dev); 267 dss_unregister_child_devices(&pdev->dev);
232 268
233 return 0; 269 return 0;
234} 270}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 17b31029a793..996779c0204c 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)
735 clk_put(venc.tv_dac_clk); 735 clk_put(venc.tv_dac_clk);
736} 736}
737 737
738static void __init venc_probe_pdata(struct platform_device *pdev) 738static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
739{ 739{
740 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 740 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
741 int r, i; 741 const char *def_disp_name = dss_get_default_display_name();
742 struct omap_dss_device *def_dssdev;
743 int i;
744
745 def_dssdev = NULL;
742 746
743 for (i = 0; i < pdata->num_devices; ++i) { 747 for (i = 0; i < pdata->num_devices; ++i) {
744 struct omap_dss_device *dssdev = pdata->devices[i]; 748 struct omap_dss_device *dssdev = pdata->devices[i];
@@ -746,16 +750,50 @@ static void __init venc_probe_pdata(struct platform_device *pdev)
746 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) 750 if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
747 continue; 751 continue;
748 752
749 r = venc_init_display(dssdev); 753 if (def_dssdev == NULL)
750 if (r) { 754 def_dssdev = dssdev;
751 DSSERR("device %s init failed: %d\n", dssdev->name, r); 755
752 continue; 756 if (def_disp_name != NULL &&
757 strcmp(dssdev->name, def_disp_name) == 0) {
758 def_dssdev = dssdev;
759 break;
753 } 760 }
761 }
762
763 return def_dssdev;
764}
765
766static void __init venc_probe_pdata(struct platform_device *vencdev)
767{
768 struct omap_dss_device *plat_dssdev;
769 struct omap_dss_device *dssdev;
770 int r;
771
772 plat_dssdev = venc_find_dssdev(vencdev);
773
774 if (!plat_dssdev)
775 return;
776
777 dssdev = dss_alloc_and_init_device(&vencdev->dev);
778 if (!dssdev)
779 return;
754 780
755 r = omap_dss_register_device(dssdev, &pdev->dev, i); 781 dss_copy_device_pdata(dssdev, plat_dssdev);
756 if (r) 782
757 DSSERR("device %s register failed: %d\n", 783 dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
758 dssdev->name, r); 784
785 r = venc_init_display(dssdev);
786 if (r) {
787 DSSERR("device %s init failed: %d\n", dssdev->name, r);
788 dss_put_device(dssdev);
789 return;
790 }
791
792 r = dss_add_device(dssdev);
793 if (r) {
794 DSSERR("device %s register failed: %d\n", dssdev->name, r);
795 dss_put_device(dssdev);
796 return;
759 } 797 }
760} 798}
761 799
@@ -819,7 +857,7 @@ err_runtime_get:
819 857
820static int __exit omap_venchw_remove(struct platform_device *pdev) 858static int __exit omap_venchw_remove(struct platform_device *pdev)
821{ 859{
822 omap_dss_unregister_child_devices(&pdev->dev); 860 dss_unregister_child_devices(&pdev->dev);
823 861
824 if (venc.vdda_dac_reg != NULL) { 862 if (venc.vdda_dac_reg != NULL) {
825 regulator_put(venc.vdda_dac_reg); 863 regulator_put(venc.vdda_dac_reg);