upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / video / omap2 / dss / core.c
1 /*
2  * linux/drivers/video/omap2/dss/core.c
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
6  *
7  * Some code and ideas taken from drivers/video/omap/ driver
8  * by Imre Deak.
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License version 2 as published by
12  * the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  * more details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #define DSS_SUBSYS_NAME "CORE"
24
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/clk.h>
28 #include <linux/err.h>
29 #include <linux/platform_device.h>
30 #include <linux/seq_file.h>
31 #include <linux/debugfs.h>
32 #include <linux/io.h>
33 #include <linux/device.h>
34 #include <linux/regulator/consumer.h>
35
36 #include <plat/display.h>
37 #include <plat/clock.h>
38
39 #include "dss.h"
40
41 static struct {
42         struct platform_device *pdev;
43         int             ctx_id;
44
45         struct clk      *dss_ick;
46         struct clk      *dss1_fck;
47         struct clk      *dss2_fck;
48         struct clk      *dss_54m_fck;
49         struct clk      *dss_96m_fck;
50         unsigned        num_clks_enabled;
51
52         struct regulator *vdds_dsi_reg;
53         struct regulator *vdds_sdi_reg;
54         struct regulator *vdda_dac_reg;
55 } core;
56
57 static void dss_clk_enable_all_no_ctx(void);
58 static void dss_clk_disable_all_no_ctx(void);
59 static void dss_clk_enable_no_ctx(enum dss_clock clks);
60 static void dss_clk_disable_no_ctx(enum dss_clock clks);
61
62 static char *def_disp_name;
63 module_param_named(def_disp, def_disp_name, charp, 0);
64 MODULE_PARM_DESC(def_disp_name, "default display name");
65
66 #ifdef DEBUG
67 unsigned int dss_debug;
68 module_param_named(debug, dss_debug, bool, 0644);
69 #endif
70
71 /* CONTEXT */
72 static int dss_get_ctx_id(void)
73 {
74         struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
75         int r;
76
77         if (!pdata->get_last_off_on_transaction_id)
78                 return 0;
79         r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
80         if (r < 0) {
81                 dev_err(&core.pdev->dev, "getting transaction ID failed, "
82                                 "will force context restore\n");
83                 r = -1;
84         }
85         return r;
86 }
87
88 int dss_need_ctx_restore(void)
89 {
90         int id = dss_get_ctx_id();
91
92         if (id < 0 || id != core.ctx_id) {
93                 DSSDBG("ctx id %d -> id %d\n",
94                                 core.ctx_id, id);
95                 core.ctx_id = id;
96                 return 1;
97         } else {
98                 return 0;
99         }
100 }
101
102 static void save_all_ctx(void)
103 {
104         DSSDBG("save context\n");
105
106         dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
107
108         dss_save_context();
109         dispc_save_context();
110 #ifdef CONFIG_OMAP2_DSS_DSI
111         dsi_save_context();
112 #endif
113
114         dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
115 }
116
117 static void restore_all_ctx(void)
118 {
119         DSSDBG("restore context\n");
120
121         dss_clk_enable_all_no_ctx();
122
123         dss_restore_context();
124         dispc_restore_context();
125 #ifdef CONFIG_OMAP2_DSS_DSI
126         dsi_restore_context();
127 #endif
128
129         dss_clk_disable_all_no_ctx();
130 }
131
132 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
133 /* CLOCKS */
134 static void core_dump_clocks(struct seq_file *s)
135 {
136         int i;
137         struct clk *clocks[5] = {
138                 core.dss_ick,
139                 core.dss1_fck,
140                 core.dss2_fck,
141                 core.dss_54m_fck,
142                 core.dss_96m_fck
143         };
144
145         seq_printf(s, "- CORE -\n");
146
147         seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
148
149         for (i = 0; i < 5; i++) {
150                 if (!clocks[i])
151                         continue;
152                 seq_printf(s, "%-15s\t%lu\t%d\n",
153                                 clocks[i]->name,
154                                 clk_get_rate(clocks[i]),
155                                 clocks[i]->usecount);
156         }
157 }
158 #endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
159
160 static int dss_get_clock(struct clk **clock, const char *clk_name)
161 {
162         struct clk *clk;
163
164         clk = clk_get(&core.pdev->dev, clk_name);
165
166         if (IS_ERR(clk)) {
167                 DSSERR("can't get clock %s", clk_name);
168                 return PTR_ERR(clk);
169         }
170
171         *clock = clk;
172
173         DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
174
175         return 0;
176 }
177
178 static int dss_get_clocks(void)
179 {
180         int r;
181
182         core.dss_ick = NULL;
183         core.dss1_fck = NULL;
184         core.dss2_fck = NULL;
185         core.dss_54m_fck = NULL;
186         core.dss_96m_fck = NULL;
187
188         r = dss_get_clock(&core.dss_ick, "ick");
189         if (r)
190                 goto err;
191
192         r = dss_get_clock(&core.dss1_fck, "dss1_fck");
193         if (r)
194                 goto err;
195
196         r = dss_get_clock(&core.dss2_fck, "dss2_fck");
197         if (r)
198                 goto err;
199
200         r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
201         if (r)
202                 goto err;
203
204         r = dss_get_clock(&core.dss_96m_fck, "video_fck");
205         if (r)
206                 goto err;
207
208         return 0;
209
210 err:
211         if (core.dss_ick)
212                 clk_put(core.dss_ick);
213         if (core.dss1_fck)
214                 clk_put(core.dss1_fck);
215         if (core.dss2_fck)
216                 clk_put(core.dss2_fck);
217         if (core.dss_54m_fck)
218                 clk_put(core.dss_54m_fck);
219         if (core.dss_96m_fck)
220                 clk_put(core.dss_96m_fck);
221
222         return r;
223 }
224
225 static void dss_put_clocks(void)
226 {
227         if (core.dss_96m_fck)
228                 clk_put(core.dss_96m_fck);
229         clk_put(core.dss_54m_fck);
230         clk_put(core.dss1_fck);
231         clk_put(core.dss2_fck);
232         clk_put(core.dss_ick);
233 }
234
235 unsigned long dss_clk_get_rate(enum dss_clock clk)
236 {
237         switch (clk) {
238         case DSS_CLK_ICK:
239                 return clk_get_rate(core.dss_ick);
240         case DSS_CLK_FCK1:
241                 return clk_get_rate(core.dss1_fck);
242         case DSS_CLK_FCK2:
243                 return clk_get_rate(core.dss2_fck);
244         case DSS_CLK_54M:
245                 return clk_get_rate(core.dss_54m_fck);
246         case DSS_CLK_96M:
247                 return clk_get_rate(core.dss_96m_fck);
248         }
249
250         BUG();
251         return 0;
252 }
253
254 static unsigned count_clk_bits(enum dss_clock clks)
255 {
256         unsigned num_clks = 0;
257
258         if (clks & DSS_CLK_ICK)
259                 ++num_clks;
260         if (clks & DSS_CLK_FCK1)
261                 ++num_clks;
262         if (clks & DSS_CLK_FCK2)
263                 ++num_clks;
264         if (clks & DSS_CLK_54M)
265                 ++num_clks;
266         if (clks & DSS_CLK_96M)
267                 ++num_clks;
268
269         return num_clks;
270 }
271
272 static void dss_clk_enable_no_ctx(enum dss_clock clks)
273 {
274         unsigned num_clks = count_clk_bits(clks);
275
276         if (clks & DSS_CLK_ICK)
277                 clk_enable(core.dss_ick);
278         if (clks & DSS_CLK_FCK1)
279                 clk_enable(core.dss1_fck);
280         if (clks & DSS_CLK_FCK2)
281                 clk_enable(core.dss2_fck);
282         if (clks & DSS_CLK_54M)
283                 clk_enable(core.dss_54m_fck);
284         if (clks & DSS_CLK_96M)
285                 clk_enable(core.dss_96m_fck);
286
287         core.num_clks_enabled += num_clks;
288 }
289
290 void dss_clk_enable(enum dss_clock clks)
291 {
292         bool check_ctx = core.num_clks_enabled == 0;
293
294         dss_clk_enable_no_ctx(clks);
295
296         if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
297                 restore_all_ctx();
298 }
299
300 static void dss_clk_disable_no_ctx(enum dss_clock clks)
301 {
302         unsigned num_clks = count_clk_bits(clks);
303
304         if (clks & DSS_CLK_ICK)
305                 clk_disable(core.dss_ick);
306         if (clks & DSS_CLK_FCK1)
307                 clk_disable(core.dss1_fck);
308         if (clks & DSS_CLK_FCK2)
309                 clk_disable(core.dss2_fck);
310         if (clks & DSS_CLK_54M)
311                 clk_disable(core.dss_54m_fck);
312         if (clks & DSS_CLK_96M)
313                 clk_disable(core.dss_96m_fck);
314
315         core.num_clks_enabled -= num_clks;
316 }
317
318 void dss_clk_disable(enum dss_clock clks)
319 {
320         if (cpu_is_omap34xx()) {
321                 unsigned num_clks = count_clk_bits(clks);
322
323                 BUG_ON(core.num_clks_enabled < num_clks);
324
325                 if (core.num_clks_enabled == num_clks)
326                         save_all_ctx();
327         }
328
329         dss_clk_disable_no_ctx(clks);
330 }
331
332 static void dss_clk_enable_all_no_ctx(void)
333 {
334         enum dss_clock clks;
335
336         clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
337         if (cpu_is_omap34xx())
338                 clks |= DSS_CLK_96M;
339         dss_clk_enable_no_ctx(clks);
340 }
341
342 static void dss_clk_disable_all_no_ctx(void)
343 {
344         enum dss_clock clks;
345
346         clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
347         if (cpu_is_omap34xx())
348                 clks |= DSS_CLK_96M;
349         dss_clk_disable_no_ctx(clks);
350 }
351
352 static void dss_clk_disable_all(void)
353 {
354         enum dss_clock clks;
355
356         clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
357         if (cpu_is_omap34xx())
358                 clks |= DSS_CLK_96M;
359         dss_clk_disable(clks);
360 }
361
362 /* REGULATORS */
363
364 struct regulator *dss_get_vdds_dsi(void)
365 {
366         struct regulator *reg;
367
368         if (core.vdds_dsi_reg != NULL)
369                 return core.vdds_dsi_reg;
370
371         reg = regulator_get(&core.pdev->dev, "vdds_dsi");
372         if (!IS_ERR(reg))
373                 core.vdds_dsi_reg = reg;
374
375         return reg;
376 }
377
378 struct regulator *dss_get_vdds_sdi(void)
379 {
380         struct regulator *reg;
381
382         if (core.vdds_sdi_reg != NULL)
383                 return core.vdds_sdi_reg;
384
385         reg = regulator_get(&core.pdev->dev, "vdds_sdi");
386         if (!IS_ERR(reg))
387                 core.vdds_sdi_reg = reg;
388
389         return reg;
390 }
391
392 struct regulator *dss_get_vdda_dac(void)
393 {
394         struct regulator *reg;
395
396         if (core.vdda_dac_reg != NULL)
397                 return core.vdda_dac_reg;
398
399         reg = regulator_get(&core.pdev->dev, "vdda_dac");
400         if (!IS_ERR(reg))
401                 core.vdda_dac_reg = reg;
402
403         return reg;
404 }
405
406 /* DEBUGFS */
407 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
408 static void dss_debug_dump_clocks(struct seq_file *s)
409 {
410         core_dump_clocks(s);
411         dss_dump_clocks(s);
412         dispc_dump_clocks(s);
413 #ifdef CONFIG_OMAP2_DSS_DSI
414         dsi_dump_clocks(s);
415 #endif
416 }
417
418 static int dss_debug_show(struct seq_file *s, void *unused)
419 {
420         void (*func)(struct seq_file *) = s->private;
421         func(s);
422         return 0;
423 }
424
425 static int dss_debug_open(struct inode *inode, struct file *file)
426 {
427         return single_open(file, dss_debug_show, inode->i_private);
428 }
429
430 static const struct file_operations dss_debug_fops = {
431         .open           = dss_debug_open,
432         .read           = seq_read,
433         .llseek         = seq_lseek,
434         .release        = single_release,
435 };
436
437 static struct dentry *dss_debugfs_dir;
438
439 static int dss_initialize_debugfs(void)
440 {
441         dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
442         if (IS_ERR(dss_debugfs_dir)) {
443                 int err = PTR_ERR(dss_debugfs_dir);
444                 dss_debugfs_dir = NULL;
445                 return err;
446         }
447
448         debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
449                         &dss_debug_dump_clocks, &dss_debug_fops);
450
451 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
452         debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir,
453                         &dispc_dump_irqs, &dss_debug_fops);
454 #endif
455
456 #if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS)
457         debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir,
458                         &dsi_dump_irqs, &dss_debug_fops);
459 #endif
460
461         debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
462                         &dss_dump_regs, &dss_debug_fops);
463         debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir,
464                         &dispc_dump_regs, &dss_debug_fops);
465 #ifdef CONFIG_OMAP2_DSS_RFBI
466         debugfs_create_file("rfbi", S_IRUGO, dss_debugfs_dir,
467                         &rfbi_dump_regs, &dss_debug_fops);
468 #endif
469 #ifdef CONFIG_OMAP2_DSS_DSI
470         debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir,
471                         &dsi_dump_regs, &dss_debug_fops);
472 #endif
473 #ifdef CONFIG_OMAP2_DSS_VENC
474         debugfs_create_file("venc", S_IRUGO, dss_debugfs_dir,
475                         &venc_dump_regs, &dss_debug_fops);
476 #endif
477         return 0;
478 }
479
480 static void dss_uninitialize_debugfs(void)
481 {
482         if (dss_debugfs_dir)
483                 debugfs_remove_recursive(dss_debugfs_dir);
484 }
485 #else /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
486 static inline int dss_initialize_debugfs(void)
487 {
488         return 0;
489 }
490 static inline void dss_uninitialize_debugfs(void)
491 {
492 }
493 #endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
494
495 /* PLATFORM DEVICE */
496 static int omap_dss_probe(struct platform_device *pdev)
497 {
498         struct omap_dss_board_info *pdata = pdev->dev.platform_data;
499         int skip_init = 0;
500         int r;
501         int i;
502
503         core.pdev = pdev;
504
505         dss_init_overlay_managers(pdev);
506         dss_init_overlays(pdev);
507
508         r = dss_get_clocks();
509         if (r)
510                 goto err_clocks;
511
512         dss_clk_enable_all_no_ctx();
513
514         core.ctx_id = dss_get_ctx_id();
515         DSSDBG("initial ctx id %u\n", core.ctx_id);
516
517 #ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
518         /* DISPC_CONTROL */
519         if (omap_readl(0x48050440) & 1) /* LCD enabled? */
520                 skip_init = 1;
521 #endif
522
523         r = dss_init(skip_init);
524         if (r) {
525                 DSSERR("Failed to initialize DSS\n");
526                 goto err_dss;
527         }
528
529         r = rfbi_init();
530         if (r) {
531                 DSSERR("Failed to initialize rfbi\n");
532                 goto err_rfbi;
533         }
534
535         r = dpi_init(pdev);
536         if (r) {
537                 DSSERR("Failed to initialize dpi\n");
538                 goto err_dpi;
539         }
540
541         r = dispc_init();
542         if (r) {
543                 DSSERR("Failed to initialize dispc\n");
544                 goto err_dispc;
545         }
546
547         r = venc_init(pdev);
548         if (r) {
549                 DSSERR("Failed to initialize venc\n");
550                 goto err_venc;
551         }
552
553         if (cpu_is_omap34xx()) {
554                 r = sdi_init(skip_init);
555                 if (r) {
556                         DSSERR("Failed to initialize SDI\n");
557                         goto err_sdi;
558                 }
559
560                 r = dsi_init(pdev);
561                 if (r) {
562                         DSSERR("Failed to initialize DSI\n");
563                         goto err_dsi;
564                 }
565         }
566
567         r = dss_initialize_debugfs();
568         if (r)
569                 goto err_debugfs;
570
571         for (i = 0; i < pdata->num_devices; ++i) {
572                 struct omap_dss_device *dssdev = pdata->devices[i];
573
574                 r = omap_dss_register_device(dssdev);
575                 if (r) {
576                         DSSERR("device %d %s register failed %d\n", i,
577                                 dssdev->name ?: "unnamed", r);
578
579                         while (--i >= 0)
580                                 omap_dss_unregister_device(pdata->devices[i]);
581
582                         goto err_register;
583                 }
584
585                 if (def_disp_name && strcmp(def_disp_name, dssdev->name) == 0)
586                         pdata->default_device = dssdev;
587         }
588
589         dss_clk_disable_all();
590
591         return 0;
592
593 err_register:
594         dss_uninitialize_debugfs();
595 err_debugfs:
596         if (cpu_is_omap34xx())
597                 dsi_exit();
598 err_dsi:
599         if (cpu_is_omap34xx())
600                 sdi_exit();
601 err_sdi:
602         venc_exit();
603 err_venc:
604         dispc_exit();
605 err_dispc:
606         dpi_exit();
607 err_dpi:
608         rfbi_exit();
609 err_rfbi:
610         dss_exit();
611 err_dss:
612         dss_clk_disable_all_no_ctx();
613         dss_put_clocks();
614 err_clocks:
615
616         return r;
617 }
618
619 static int omap_dss_remove(struct platform_device *pdev)
620 {
621         struct omap_dss_board_info *pdata = pdev->dev.platform_data;
622         int i;
623         int c;
624
625         dss_uninitialize_debugfs();
626
627         venc_exit();
628         dispc_exit();
629         dpi_exit();
630         rfbi_exit();
631         if (cpu_is_omap34xx()) {
632                 dsi_exit();
633                 sdi_exit();
634         }
635
636         dss_exit();
637
638         /* these should be removed at some point */
639         c = core.dss_ick->usecount;
640         if (c > 0) {
641                 DSSERR("warning: dss_ick usecount %d, disabling\n", c);
642                 while (c-- > 0)
643                         clk_disable(core.dss_ick);
644         }
645
646         c = core.dss1_fck->usecount;
647         if (c > 0) {
648                 DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
649                 while (c-- > 0)
650                         clk_disable(core.dss1_fck);
651         }
652
653         c = core.dss2_fck->usecount;
654         if (c > 0) {
655                 DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
656                 while (c-- > 0)
657                         clk_disable(core.dss2_fck);
658         }
659
660         c = core.dss_54m_fck->usecount;
661         if (c > 0) {
662                 DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
663                 while (c-- > 0)
664                         clk_disable(core.dss_54m_fck);
665         }
666
667         if (core.dss_96m_fck) {
668                 c = core.dss_96m_fck->usecount;
669                 if (c > 0) {
670                         DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
671                                         c);
672                         while (c-- > 0)
673                                 clk_disable(core.dss_96m_fck);
674                 }
675         }
676
677         dss_put_clocks();
678
679         dss_uninit_overlays(pdev);
680         dss_uninit_overlay_managers(pdev);
681
682         for (i = 0; i < pdata->num_devices; ++i)
683                 omap_dss_unregister_device(pdata->devices[i]);
684
685         return 0;
686 }
687
688 static void omap_dss_shutdown(struct platform_device *pdev)
689 {
690         DSSDBG("shutdown\n");
691         dss_disable_all_devices();
692 }
693
694 static int omap_dss_suspend(struct platform_device *pdev, pm_message_t state)
695 {
696         DSSDBG("suspend %d\n", state.event);
697
698         return dss_suspend_all_devices();
699 }
700
701 static int omap_dss_resume(struct platform_device *pdev)
702 {
703         DSSDBG("resume\n");
704
705         return dss_resume_all_devices();
706 }
707
708 static struct platform_driver omap_dss_driver = {
709         .probe          = omap_dss_probe,
710         .remove         = omap_dss_remove,
711         .shutdown       = omap_dss_shutdown,
712         .suspend        = omap_dss_suspend,
713         .resume         = omap_dss_resume,
714         .driver         = {
715                 .name   = "omapdss",
716                 .owner  = THIS_MODULE,
717         },
718 };
719
720 /* BUS */
721 static int dss_bus_match(struct device *dev, struct device_driver *driver)
722 {
723         struct omap_dss_device *dssdev = to_dss_device(dev);
724
725         DSSDBG("bus_match. dev %s/%s, drv %s\n",
726                         dev_name(dev), dssdev->driver_name, driver->name);
727
728         return strcmp(dssdev->driver_name, driver->name) == 0;
729 }
730
731 static ssize_t device_name_show(struct device *dev,
732                 struct device_attribute *attr, char *buf)
733 {
734         struct omap_dss_device *dssdev = to_dss_device(dev);
735         return snprintf(buf, PAGE_SIZE, "%s\n",
736                         dssdev->name ?
737                         dssdev->name : "");
738 }
739
740 static struct device_attribute default_dev_attrs[] = {
741         __ATTR(name, S_IRUGO, device_name_show, NULL),
742         __ATTR_NULL,
743 };
744
745 static ssize_t driver_name_show(struct device_driver *drv, char *buf)
746 {
747         struct omap_dss_driver *dssdrv = to_dss_driver(drv);
748         return snprintf(buf, PAGE_SIZE, "%s\n",
749                         dssdrv->driver.name ?
750                         dssdrv->driver.name : "");
751 }
752 static struct driver_attribute default_drv_attrs[] = {
753         __ATTR(name, S_IRUGO, driver_name_show, NULL),
754         __ATTR_NULL,
755 };
756
757 static struct bus_type dss_bus_type = {
758         .name = "omapdss",
759         .match = dss_bus_match,
760         .dev_attrs = default_dev_attrs,
761         .drv_attrs = default_drv_attrs,
762 };
763
764 static void dss_bus_release(struct device *dev)
765 {
766         DSSDBG("bus_release\n");
767 }
768
769 static struct device dss_bus = {
770         .release = dss_bus_release,
771 };
772
773 struct bus_type *dss_get_bus(void)
774 {
775         return &dss_bus_type;
776 }
777
778 /* DRIVER */
779 static int dss_driver_probe(struct device *dev)
780 {
781         int r;
782         struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
783         struct omap_dss_device *dssdev = to_dss_device(dev);
784         struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
785         bool force;
786
787         DSSDBG("driver_probe: dev %s/%s, drv %s\n",
788                                 dev_name(dev), dssdev->driver_name,
789                                 dssdrv->driver.name);
790
791         dss_init_device(core.pdev, dssdev);
792
793         force = pdata->default_device == dssdev;
794         dss_recheck_connections(dssdev, force);
795
796         r = dssdrv->probe(dssdev);
797
798         if (r) {
799                 DSSERR("driver probe failed: %d\n", r);
800                 dss_uninit_device(core.pdev, dssdev);
801                 return r;
802         }
803
804         DSSDBG("probe done for device %s\n", dev_name(dev));
805
806         dssdev->driver = dssdrv;
807
808         return 0;
809 }
810
811 static int dss_driver_remove(struct device *dev)
812 {
813         struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
814         struct omap_dss_device *dssdev = to_dss_device(dev);
815
816         DSSDBG("driver_remove: dev %s/%s\n", dev_name(dev),
817                         dssdev->driver_name);
818
819         dssdrv->remove(dssdev);
820
821         dss_uninit_device(core.pdev, dssdev);
822
823         dssdev->driver = NULL;
824
825         return 0;
826 }
827
828 int omap_dss_register_driver(struct omap_dss_driver *dssdriver)
829 {
830         dssdriver->driver.bus = &dss_bus_type;
831         dssdriver->driver.probe = dss_driver_probe;
832         dssdriver->driver.remove = dss_driver_remove;
833
834         if (dssdriver->get_resolution == NULL)
835                 dssdriver->get_resolution = omapdss_default_get_resolution;
836         if (dssdriver->get_recommended_bpp == NULL)
837                 dssdriver->get_recommended_bpp =
838                         omapdss_default_get_recommended_bpp;
839
840         return driver_register(&dssdriver->driver);
841 }
842 EXPORT_SYMBOL(omap_dss_register_driver);
843
844 void omap_dss_unregister_driver(struct omap_dss_driver *dssdriver)
845 {
846         driver_unregister(&dssdriver->driver);
847 }
848 EXPORT_SYMBOL(omap_dss_unregister_driver);
849
850 /* DEVICE */
851 static void reset_device(struct device *dev, int check)
852 {
853         u8 *dev_p = (u8 *)dev;
854         u8 *dev_end = dev_p + sizeof(*dev);
855         void *saved_pdata;
856
857         saved_pdata = dev->platform_data;
858         if (check) {
859                 /*
860                  * Check if there is any other setting than platform_data
861                  * in struct device; warn that these will be reset by our
862                  * init.
863                  */
864                 dev->platform_data = NULL;
865                 while (dev_p < dev_end) {
866                         if (*dev_p) {
867                                 WARN("%s: struct device fields will be "
868                                                 "discarded\n",
869                                      __func__);
870                                 break;
871                         }
872                         dev_p++;
873                 }
874         }
875         memset(dev, 0, sizeof(*dev));
876         dev->platform_data = saved_pdata;
877 }
878
879
880 static void omap_dss_dev_release(struct device *dev)
881 {
882         reset_device(dev, 0);
883 }
884
885 int omap_dss_register_device(struct omap_dss_device *dssdev)
886 {
887         static int dev_num;
888
889         WARN_ON(!dssdev->driver_name);
890
891         reset_device(&dssdev->dev, 1);
892         dssdev->dev.bus = &dss_bus_type;
893         dssdev->dev.parent = &dss_bus;
894         dssdev->dev.release = omap_dss_dev_release;
895         dev_set_name(&dssdev->dev, "display%d", dev_num++);
896         return device_register(&dssdev->dev);
897 }
898
899 void omap_dss_unregister_device(struct omap_dss_device *dssdev)
900 {
901         device_unregister(&dssdev->dev);
902 }
903
904 /* BUS */
905 static int omap_dss_bus_register(void)
906 {
907         int r;
908
909         r = bus_register(&dss_bus_type);
910         if (r) {
911                 DSSERR("bus register failed\n");
912                 return r;
913         }
914
915         dev_set_name(&dss_bus, "omapdss");
916         r = device_register(&dss_bus);
917         if (r) {
918                 DSSERR("bus driver register failed\n");
919                 bus_unregister(&dss_bus_type);
920                 return r;
921         }
922
923         return 0;
924 }
925
926 /* INIT */
927
928 #ifdef CONFIG_OMAP2_DSS_MODULE
929 static void omap_dss_bus_unregister(void)
930 {
931         device_unregister(&dss_bus);
932
933         bus_unregister(&dss_bus_type);
934 }
935
936 static int __init omap_dss_init(void)
937 {
938         int r;
939
940         r = omap_dss_bus_register();
941         if (r)
942                 return r;
943
944         r = platform_driver_register(&omap_dss_driver);
945         if (r) {
946                 omap_dss_bus_unregister();
947                 return r;
948         }
949
950         return 0;
951 }
952
953 static void __exit omap_dss_exit(void)
954 {
955         if (core.vdds_dsi_reg != NULL) {
956                 regulator_put(core.vdds_dsi_reg);
957                 core.vdds_dsi_reg = NULL;
958         }
959
960         if (core.vdds_sdi_reg != NULL) {
961                 regulator_put(core.vdds_sdi_reg);
962                 core.vdds_sdi_reg = NULL;
963         }
964
965         if (core.vdda_dac_reg != NULL) {
966                 regulator_put(core.vdda_dac_reg);
967                 core.vdda_dac_reg = NULL;
968         }
969
970         platform_driver_unregister(&omap_dss_driver);
971
972         omap_dss_bus_unregister();
973 }
974
975 module_init(omap_dss_init);
976 module_exit(omap_dss_exit);
977 #else
978 static int __init omap_dss_init(void)
979 {
980         return omap_dss_bus_register();
981 }
982
983 static int __init omap_dss_init2(void)
984 {
985         return platform_driver_register(&omap_dss_driver);
986 }
987
988 core_initcall(omap_dss_init);
989 device_initcall(omap_dss_init2);
990 #endif
991
992 MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
993 MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
994 MODULE_LICENSE("GPL v2");
995