aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-10 06:58:29 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-18 09:15:05 -0400
commit5274484b821bb2cf34a697624ef14084c31b16ce (patch)
treea5b99b98eb685414b5ff87233da5556ce80ad2f6 /drivers/video
parent5eeb55f8703d2af3181599c085b21ce023a0f942 (diff)
OMAPDSS: alloc dssdevs dynamically
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>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/core.c72
-rw-r--r--drivers/video/omap2/dss/dpi.c17
-rw-r--r--drivers/video/omap2/dss/dsi.c15
-rw-r--r--drivers/video/omap2/dss/dss.h11
-rw-r--r--drivers/video/omap2/dss/hdmi.c15
-rw-r--r--drivers/video/omap2/dss/rfbi.c17
-rw-r--r--drivers/video/omap2/dss/sdi.c17
-rw-r--r--drivers/video/omap2/dss/venc.c17
8 files changed, 119 insertions, 62 deletions
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c4fd7687f3a..b2af72dc20b 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
@@ -418,55 +419,44 @@ void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
418EXPORT_SYMBOL(omap_dss_unregister_driver); 419EXPORT_SYMBOL(omap_dss_unregister_driver);
419 420
420/* DEVICE */ 421/* DEVICE */
421static void reset_device(struct device *dev, int check)
422{
423 u8 *dev_p = (u8 *)dev;
424 u8 *dev_end = dev_p + sizeof(*dev);
425 void *saved_pdata;
426
427 saved_pdata = dev->platform_data;
428 if (check) {
429 /*
430 * Check if there is any other setting than platform_data
431 * in struct device; warn that these will be reset by our
432 * init.
433 */
434 dev->platform_data = NULL;
435 while (dev_p < dev_end) {
436 if (*dev_p) {
437 WARN("%s: struct device fields will be "
438 "discarded\n",
439 __func__);
440 break;
441 }
442 dev_p++;
443 }
444 }
445 memset(dev, 0, sizeof(*dev));
446 dev->platform_data = saved_pdata;
447}
448
449 422
450static void omap_dss_dev_release(struct device *dev) 423static void omap_dss_dev_release(struct device *dev)
451{ 424{
452 reset_device(dev, 0); 425 struct omap_dss_device *dssdev = to_dss_device(dev);
426 kfree(dssdev);
453} 427}
454 428
455static int disp_num_counter; 429static int disp_num_counter;
456 430
457int omap_dss_register_device(struct omap_dss_device *dssdev, 431struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
458 struct device *parent)
459{ 432{
460 reset_device(&dssdev->dev, 1); 433 struct omap_dss_device *dssdev;
434
435 dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL);
436 if (!dssdev)
437 return NULL;
461 438
462 dssdev->dev.bus = &dss_bus_type; 439 dssdev->dev.bus = &dss_bus_type;
463 dssdev->dev.parent = parent; 440 dssdev->dev.parent = parent;
464 dssdev->dev.release = omap_dss_dev_release; 441 dssdev->dev.release = omap_dss_dev_release;
465 dev_set_name(&dssdev->dev, "display%d", disp_num_counter++); 442 dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
466 return device_register(&dssdev->dev); 443
444 device_initialize(&dssdev->dev);
445
446 return dssdev;
467} 447}
468 448
469void omap_dss_unregister_device(struct omap_dss_device *dssdev) 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);
457}
458
459void dss_unregister_device(struct omap_dss_device *dssdev)
470{ 460{
471 device_unregister(&dssdev->dev); 461 device_unregister(&dssdev->dev);
472} 462}
@@ -474,15 +464,25 @@ void omap_dss_unregister_device(struct omap_dss_device *dssdev)
474static int dss_unregister_dss_dev(struct device *dev, void *data) 464static int dss_unregister_dss_dev(struct device *dev, void *data)
475{ 465{
476 struct omap_dss_device *dssdev = to_dss_device(dev); 466 struct omap_dss_device *dssdev = to_dss_device(dev);
477 omap_dss_unregister_device(dssdev); 467 dss_unregister_device(dssdev);
478 return 0; 468 return 0;
479} 469}
480 470
481void omap_dss_unregister_child_devices(struct device *parent) 471void dss_unregister_child_devices(struct device *parent)
482{ 472{
483 device_for_each_child(parent, NULL, dss_unregister_dss_dev); 473 device_for_each_child(parent, NULL, dss_unregister_dss_dev);
484} 474}
485 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
486/* BUS */ 486/* BUS */
487static int __init omap_dss_bus_register(void) 487static int __init omap_dss_bus_register(void)
488{ 488{
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 6f9a199a68a..fac19d39ab1 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
399 return def_dssdev; 399 return def_dssdev;
400} 400}
401 401
402static void __init dpi_probe_pdata(struct platform_device *pdev) 402static void __init dpi_probe_pdata(struct platform_device *dpidev)
403{ 403{
404 struct omap_dss_device *plat_dssdev;
404 struct omap_dss_device *dssdev; 405 struct omap_dss_device *dssdev;
405 int r; 406 int r;
406 407
407 dssdev = dpi_find_dssdev(pdev); 408 plat_dssdev = dpi_find_dssdev(dpidev);
408 409
410 if (!plat_dssdev)
411 return;
412
413 dssdev = dss_alloc_and_init_device(&dpidev->dev);
409 if (!dssdev) 414 if (!dssdev)
410 return; 415 return;
411 416
417 dss_copy_device_pdata(dssdev, plat_dssdev);
418
412 r = dpi_init_display(dssdev); 419 r = dpi_init_display(dssdev);
413 if (r) { 420 if (r) {
414 DSSERR("device %s init failed: %d\n", dssdev->name, r); 421 DSSERR("device %s init failed: %d\n", dssdev->name, r);
422 dss_put_device(dssdev);
415 return; 423 return;
416 } 424 }
417 425
418 r = omap_dss_register_device(dssdev, &pdev->dev); 426 r = dss_add_device(dssdev);
419 if (r) { 427 if (r) {
420 DSSERR("device %s register failed: %d\n", dssdev->name, r); 428 DSSERR("device %s register failed: %d\n", dssdev->name, r);
429 dss_put_device(dssdev);
421 return; 430 return;
422 } 431 }
423} 432}
@@ -433,7 +442,7 @@ static int __init omap_dpi_probe(struct platform_device *pdev)
433 442
434static int __exit omap_dpi_remove(struct platform_device *pdev) 443static int __exit omap_dpi_remove(struct platform_device *pdev)
435{ 444{
436 omap_dss_unregister_child_devices(&pdev->dev); 445 dss_unregister_child_devices(&pdev->dev);
437 446
438 return 0; 447 return 0;
439} 448}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ee9ae526f5c..1dd019cf964 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
5040 5040
5041static void __init dsi_probe_pdata(struct platform_device *dsidev) 5041static void __init dsi_probe_pdata(struct platform_device *dsidev)
5042{ 5042{
5043 struct omap_dss_device *plat_dssdev;
5043 struct omap_dss_device *dssdev; 5044 struct omap_dss_device *dssdev;
5044 int r; 5045 int r;
5045 5046
5046 dssdev = dsi_find_dssdev(dsidev); 5047 plat_dssdev = dsi_find_dssdev(dsidev);
5047 5048
5049 if (!plat_dssdev)
5050 return;
5051
5052 dssdev = dss_alloc_and_init_device(&dsidev->dev);
5048 if (!dssdev) 5053 if (!dssdev)
5049 return; 5054 return;
5050 5055
5056 dss_copy_device_pdata(dssdev, plat_dssdev);
5057
5051 r = dsi_init_display(dssdev); 5058 r = dsi_init_display(dssdev);
5052 if (r) { 5059 if (r) {
5053 DSSERR("device %s init failed: %d\n", dssdev->name, r); 5060 DSSERR("device %s init failed: %d\n", dssdev->name, r);
5061 dss_put_device(dssdev);
5054 return; 5062 return;
5055 } 5063 }
5056 5064
5057 r = omap_dss_register_device(dssdev, &dsidev->dev); 5065 r = dss_add_device(dssdev);
5058 if (r) { 5066 if (r) {
5059 DSSERR("device %s register failed: %d\n", dssdev->name, r); 5067 DSSERR("device %s register failed: %d\n", dssdev->name, r);
5068 dss_put_device(dssdev);
5060 return; 5069 return;
5061 } 5070 }
5062} 5071}
@@ -5184,7 +5193,7 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5184 5193
5185 WARN_ON(dsi->scp_clk_refcount > 0); 5194 WARN_ON(dsi->scp_clk_refcount > 0);
5186 5195
5187 omap_dss_unregister_child_devices(&dsidev->dev); 5196 dss_unregister_child_devices(&dsidev->dev);
5188 5197
5189 pm_runtime_disable(&dsidev->dev); 5198 pm_runtime_disable(&dsidev->dev);
5190 5199
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 7a3fea66b41..417d3057174 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);
185int dss_set_min_bus_tput(struct device *dev, unsigned long tput); 185int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
186int 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 *));
187 187
188int omap_dss_register_device(struct omap_dss_device *dssdev, 188struct omap_dss_device *dss_alloc_and_init_device(struct device *parent);
189 struct device *parent); 189int dss_add_device(struct omap_dss_device *dssdev);
190void omap_dss_unregister_device(struct omap_dss_device *dssdev); 190void dss_unregister_device(struct omap_dss_device *dssdev);
191void 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);
192 195
193/* apply */ 196/* apply */
194void dss_apply_init(void); 197void dss_apply_init(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 3b10e18efa2..23daf7dcf54 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 *
931 931
932static void __init hdmi_probe_pdata(struct platform_device *pdev) 932static void __init hdmi_probe_pdata(struct platform_device *pdev)
933{ 933{
934 struct omap_dss_device *plat_dssdev;
934 struct omap_dss_device *dssdev; 935 struct omap_dss_device *dssdev;
935 struct omap_dss_hdmi_data *priv; 936 struct omap_dss_hdmi_data *priv;
936 int r; 937 int r;
937 938
938 dssdev = hdmi_find_dssdev(pdev); 939 plat_dssdev = hdmi_find_dssdev(pdev);
939 940
941 if (!plat_dssdev)
942 return;
943
944 dssdev = dss_alloc_and_init_device(&pdev->dev);
940 if (!dssdev) 945 if (!dssdev)
941 return; 946 return;
942 947
948 dss_copy_device_pdata(dssdev, plat_dssdev);
949
943 priv = dssdev->data; 950 priv = dssdev->data;
944 951
945 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio; 952 hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
@@ -951,12 +958,14 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
951 r = hdmi_init_display(dssdev); 958 r = hdmi_init_display(dssdev);
952 if (r) { 959 if (r) {
953 DSSERR("device %s init failed: %d\n", dssdev->name, r); 960 DSSERR("device %s init failed: %d\n", dssdev->name, r);
961 dss_put_device(dssdev);
954 return; 962 return;
955 } 963 }
956 964
957 r = omap_dss_register_device(dssdev, &pdev->dev); 965 r = dss_add_device(dssdev);
958 if (r) { 966 if (r) {
959 DSSERR("device %s register failed: %d\n", dssdev->name, r); 967 DSSERR("device %s register failed: %d\n", dssdev->name, r);
968 dss_put_device(dssdev);
960 return; 969 return;
961 } 970 }
962} 971}
@@ -1020,7 +1029,7 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1020{ 1029{
1021 device_for_each_child(&pdev->dev, NULL, hdmi_remove_child); 1030 device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
1022 1031
1023 omap_dss_unregister_child_devices(&pdev->dev); 1032 dss_unregister_child_devices(&pdev->dev);
1024 1033
1025 hdmi_panel_exit(); 1034 hdmi_panel_exit();
1026 1035
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 1127037cb9d..38d9b8ecbe3 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 *
970 return def_dssdev; 970 return def_dssdev;
971} 971}
972 972
973static void __init rfbi_probe_pdata(struct platform_device *pdev) 973static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
974{ 974{
975 struct omap_dss_device *plat_dssdev;
975 struct omap_dss_device *dssdev; 976 struct omap_dss_device *dssdev;
976 int r; 977 int r;
977 978
978 dssdev = rfbi_find_dssdev(pdev); 979 plat_dssdev = rfbi_find_dssdev(rfbidev);
979 980
981 if (!plat_dssdev)
982 return;
983
984 dssdev = dss_alloc_and_init_device(&rfbidev->dev);
980 if (!dssdev) 985 if (!dssdev)
981 return; 986 return;
982 987
988 dss_copy_device_pdata(dssdev, plat_dssdev);
989
983 r = rfbi_init_display(dssdev); 990 r = rfbi_init_display(dssdev);
984 if (r) { 991 if (r) {
985 DSSERR("device %s init failed: %d\n", dssdev->name, r); 992 DSSERR("device %s init failed: %d\n", dssdev->name, r);
993 dss_put_device(dssdev);
986 return; 994 return;
987 } 995 }
988 996
989 r = omap_dss_register_device(dssdev, &pdev->dev); 997 r = dss_add_device(dssdev);
990 if (r) { 998 if (r) {
991 DSSERR("device %s register failed: %d\n", dssdev->name, r); 999 DSSERR("device %s register failed: %d\n", dssdev->name, r);
1000 dss_put_device(dssdev);
992 return; 1001 return;
993 } 1002 }
994} 1003}
@@ -1055,7 +1064,7 @@ err_runtime_get:
1055 1064
1056static int __exit omap_rfbihw_remove(struct platform_device *pdev) 1065static int __exit omap_rfbihw_remove(struct platform_device *pdev)
1057{ 1066{
1058 omap_dss_unregister_child_devices(&pdev->dev); 1067 dss_unregister_child_devices(&pdev->dev);
1059 pm_runtime_disable(&pdev->dev); 1068 pm_runtime_disable(&pdev->dev);
1060 return 0; 1069 return 0;
1061} 1070}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 0aaa7f35874..919ff728c50 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
223 return def_dssdev; 223 return def_dssdev;
224} 224}
225 225
226static void __init sdi_probe_pdata(struct platform_device *pdev) 226static void __init sdi_probe_pdata(struct platform_device *sdidev)
227{ 227{
228 struct omap_dss_device *plat_dssdev;
228 struct omap_dss_device *dssdev; 229 struct omap_dss_device *dssdev;
229 int r; 230 int r;
230 231
231 dssdev = sdi_find_dssdev(pdev); 232 plat_dssdev = sdi_find_dssdev(sdidev);
232 233
234 if (!plat_dssdev)
235 return;
236
237 dssdev = dss_alloc_and_init_device(&sdidev->dev);
233 if (!dssdev) 238 if (!dssdev)
234 return; 239 return;
235 240
241 dss_copy_device_pdata(dssdev, plat_dssdev);
242
236 r = sdi_init_display(dssdev); 243 r = sdi_init_display(dssdev);
237 if (r) { 244 if (r) {
238 DSSERR("device %s init failed: %d\n", dssdev->name, r); 245 DSSERR("device %s init failed: %d\n", dssdev->name, r);
246 dss_put_device(dssdev);
239 return; 247 return;
240 } 248 }
241 249
242 r = omap_dss_register_device(dssdev, &pdev->dev); 250 r = dss_add_device(dssdev);
243 if (r) { 251 if (r) {
244 DSSERR("device %s register failed: %d\n", dssdev->name, r); 252 DSSERR("device %s register failed: %d\n", dssdev->name, r);
253 dss_put_device(dssdev);
245 return; 254 return;
246 } 255 }
247} 256}
@@ -255,7 +264,7 @@ static int __init omap_sdi_probe(struct platform_device *pdev)
255 264
256static int __exit omap_sdi_remove(struct platform_device *pdev) 265static int __exit omap_sdi_remove(struct platform_device *pdev)
257{ 266{
258 omap_dss_unregister_child_devices(&pdev->dev); 267 dss_unregister_child_devices(&pdev->dev);
259 268
260 return 0; 269 return 0;
261} 270}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 88fa6ea77e7..996779c0204 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 *
763 return def_dssdev; 763 return def_dssdev;
764} 764}
765 765
766static void __init venc_probe_pdata(struct platform_device *pdev) 766static void __init venc_probe_pdata(struct platform_device *vencdev)
767{ 767{
768 struct omap_dss_device *plat_dssdev;
768 struct omap_dss_device *dssdev; 769 struct omap_dss_device *dssdev;
769 int r; 770 int r;
770 771
771 dssdev = venc_find_dssdev(pdev); 772 plat_dssdev = venc_find_dssdev(vencdev);
772 773
774 if (!plat_dssdev)
775 return;
776
777 dssdev = dss_alloc_and_init_device(&vencdev->dev);
773 if (!dssdev) 778 if (!dssdev)
774 return; 779 return;
775 780
781 dss_copy_device_pdata(dssdev, plat_dssdev);
782
776 dssdev->channel = OMAP_DSS_CHANNEL_DIGIT; 783 dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
777 784
778 r = venc_init_display(dssdev); 785 r = venc_init_display(dssdev);
779 if (r) { 786 if (r) {
780 DSSERR("device %s init failed: %d\n", dssdev->name, r); 787 DSSERR("device %s init failed: %d\n", dssdev->name, r);
788 dss_put_device(dssdev);
781 return; 789 return;
782 } 790 }
783 791
784 r = omap_dss_register_device(dssdev, &pdev->dev); 792 r = dss_add_device(dssdev);
785 if (r) { 793 if (r) {
786 DSSERR("device %s register failed: %d\n", dssdev->name, r); 794 DSSERR("device %s register failed: %d\n", dssdev->name, r);
795 dss_put_device(dssdev);
787 return; 796 return;
788 } 797 }
789} 798}
@@ -848,7 +857,7 @@ err_runtime_get:
848 857
849static int __exit omap_venchw_remove(struct platform_device *pdev) 858static int __exit omap_venchw_remove(struct platform_device *pdev)
850{ 859{
851 omap_dss_unregister_child_devices(&pdev->dev); 860 dss_unregister_child_devices(&pdev->dev);
852 861
853 if (venc.vdda_dac_reg != NULL) { 862 if (venc.vdda_dac_reg != NULL) {
854 regulator_put(venc.vdda_dac_reg); 863 regulator_put(venc.vdda_dac_reg);