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