2 * linux/drivers/video/fbmem.c
4 * Copyright (C) 1994 Martin Schaller
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
11 #include <linux/config.h>
12 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/errno.h>
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
18 #include <linux/major.h>
19 #include <linux/malloc.h>
20 #include <linux/mman.h>
21 #include <linux/tty.h>
22 #include <linux/console.h>
23 #include <linux/init.h>
24 #include <linux/proc_fs.h>
26 #include <linux/kmod.h>
28 #include <linux/devfs_fs_kernel.h>
30 #if defined(__mc68000__) || defined(CONFIG_APUS)
31 #include <asm/setup.h>
35 #include <asm/uaccess.h>
37 #include <asm/pgtable.h>
40 #include <video/fbcon.h>
43 * Frame buffer device initialization and setup routines
46 extern int acornfb_init(void);
47 extern int acornfb_setup(char*);
48 extern int amifb_init(void);
49 extern int amifb_setup(char*);
50 extern int atafb_init(void);
51 extern int atafb_setup(char*);
52 extern int macfb_init(void);
53 extern int macfb_setup(char*);
54 extern int cyberfb_init(void);
55 extern int cyberfb_setup(char*);
56 extern int pm2fb_init(void);
57 extern int pm2fb_setup(char*);
58 extern int cyber2000fb_init(void);
59 extern int cyber2000fb_setup(char*);
60 extern int retz3fb_init(void);
61 extern int retz3fb_setup(char*);
62 extern int clgenfb_init(void);
63 extern int clgenfb_setup(char*);
64 extern int hitfb_init(void);
65 extern int hitfb_setup(char*);
66 extern int vfb_init(void);
67 extern int vfb_setup(char*);
68 extern int offb_init(void);
69 extern int offb_setup(char*);
70 extern int atyfb_init(void);
71 extern int atyfb_setup(char*);
72 extern int aty128fb_init(void);
73 extern int aty128fb_setup(char*);
74 extern int igafb_init(void);
75 extern int igafb_setup(char*);
76 extern int imsttfb_init(void);
77 extern int imsttfb_setup(char*);
78 extern int dnfb_init(void);
79 extern int tgafb_init(void);
80 extern int tgafb_setup(char*);
81 extern int virgefb_init(void);
82 extern int virgefb_setup(char*);
83 extern int resolver_video_setup(char*);
84 extern int s3triofb_init(void);
85 extern int s3triofb_setup(char*);
86 extern int vesafb_init(void);
87 extern int vesafb_setup(char*);
88 extern int vga16fb_init(void);
89 extern int vga16fb_setup(char*);
90 extern int hgafb_init(void);
91 extern int hgafb_setup(char*);
92 extern int matroxfb_init(void);
93 extern int matroxfb_setup(char*);
94 extern int hpfb_init(void);
95 extern int hpfb_setup(char*);
96 extern int sbusfb_init(void);
97 extern int sbusfb_setup(char*);
98 extern int valkyriefb_init(void);
99 extern int valkyriefb_setup(char*);
100 extern int control_init(void);
101 extern int control_setup(char*);
102 extern int g364fb_init(void);
103 extern void sa1100fb_init(void);
104 extern void sa1100fb_setup(char*);
105 extern int fm2fb_init(void);
106 extern int fm2fb_setup(char*);
107 extern int q40fb_init(void);
108 extern int sun3fb_init(void);
109 extern int sun3fb_setup(char *);
110 extern int sgivwfb_init(void);
111 extern int sgivwfb_setup(char*);
112 extern int rivafb_init(void);
113 extern int rivafb_setup(char*);
114 extern int tdfxfb_init(void);
115 extern int tdfxfb_setup(char*);
116 extern int sisfb_init(void);
117 extern int sisfb_setup(char*);
123 } fb_drivers
[] __initdata
= {
124 #ifdef CONFIG_FB_SBUS
126 * Sbusfb must be initialized _before_ other frame buffer devices that
129 { "sbus", sbusfb_init
, sbusfb_setup
},
131 #ifdef CONFIG_FB_3DFX
132 { "tdfx", tdfxfb_init
, tdfxfb_setup
},
134 #ifdef CONFIG_FB_SGIVW
135 { "sgivw", sgivwfb_init
, sgivwfb_setup
},
137 #ifdef CONFIG_FB_RETINAZ3
138 { "retz3", retz3fb_init
, retz3fb_setup
},
140 #ifdef CONFIG_FB_ACORN
141 { "acorn", acornfb_init
, acornfb_setup
},
143 #ifdef CONFIG_FB_AMIGA
144 { "amifb", amifb_init
, amifb_setup
},
146 #ifdef CONFIG_FB_ATARI
147 { "atafb", atafb_init
, atafb_setup
},
150 { "macfb", macfb_init
, macfb_setup
},
152 #ifdef CONFIG_FB_CYBER
153 { "cyber", cyberfb_init
, cyberfb_setup
},
155 #ifdef CONFIG_FB_CYBER2000
156 { "cyber2000", cyber2000fb_init
, cyber2000fb_setup
},
159 { "pm2fb", pm2fb_init
, pm2fb_setup
},
161 #ifdef CONFIG_FB_CLGEN
162 { "clgen", clgenfb_init
, clgenfb_setup
},
165 { "atyfb", atyfb_init
, atyfb_setup
},
167 #ifdef CONFIG_FB_MATROX
168 { "matrox", matroxfb_init
, matroxfb_setup
},
170 #ifdef CONFIG_FB_ATY128
171 { "aty128fb", aty128fb_init
, aty128fb_setup
},
175 * Offb must be initialized _after_ all other frame buffer devices
176 * that use PCI probing and PCI resources! [ Geert ]
178 { "offb", offb_init
, offb_setup
},
181 { "igafb", igafb_init
, igafb_setup
},
183 #ifdef CONFIG_FB_IMSTT
184 { "imsttfb", imsttfb_init
, imsttfb_setup
},
187 { "apollo", dnfb_init
, NULL
},
190 { "q40fb", q40fb_init
, NULL
},
192 #ifdef CONFIG_FB_S3TRIO
193 { "s3trio", s3triofb_init
, s3triofb_setup
},
196 { "tga", tgafb_init
, tgafb_setup
},
198 #ifdef CONFIG_FB_VIRGE
199 { "virge", virgefb_init
, virgefb_setup
},
201 #ifdef CONFIG_FB_RIVA
202 { "riva", rivafb_init
, rivafb_setup
},
204 #ifdef CONFIG_FB_VESA
205 { "vesa", vesafb_init
, vesafb_setup
},
207 #ifdef CONFIG_FB_VGA16
208 { "vga16", vga16fb_init
, vga16fb_setup
},
211 { "hga", hgafb_init
, hgafb_setup
},
213 #ifdef CONFIG_FB_HP300
214 { "hpfb", hpfb_init
, hpfb_setup
},
216 #ifdef CONFIG_FB_CONTROL
217 { "controlfb", control_init
, control_setup
},
219 #ifdef CONFIG_FB_VALKYRIE
220 { "valkyriefb", valkyriefb_init
, valkyriefb_setup
},
222 #ifdef CONFIG_FB_G364
223 { "g364", g364fb_init
, NULL
},
225 #ifdef CONFIG_FB_SA1100
226 { "sa1100", sa1100fb_init
, sa1100fb_setup
},
229 { "fm2fb", fm2fb_init
, fm2fb_setup
},
231 #ifdef CONFIG_FB_SUN3
232 { "sun3", sun3fb_init
, sun3fb_setup
},
235 { "hitfb", hitfb_init
, hitfb_setup
},
237 #ifdef CONFIG_GSP_RESOLVER
238 /* Not a real frame buffer device... */
239 { "resolver", NULL
, resolver_video_setup
},
242 { "sisfb", sisfb_init
, sisfb_setup
},
244 #ifdef CONFIG_FB_VIRTUAL
245 /* Must be last to avoid that vfb becomes your primary display */
246 { "vfb", vfb_init
, vfb_setup
},
250 #define NUM_FB_DRIVERS (sizeof(fb_drivers)/sizeof(*fb_drivers))
252 extern const char *global_mode_option
;
254 static initcall_t pref_init_funcs
[FB_MAX
];
255 static int num_pref_init_funcs __initdata
= 0;
258 struct fb_info
*registered_fb
[FB_MAX
];
259 int num_registered_fb
= 0;
260 extern int fbcon_softback_size
;
262 static int first_fb_vc
= 0;
263 static int last_fb_vc
= MAX_NR_CONSOLES
-1;
264 static int fbcon_is_default
= 1;
266 static int fbmem_read_proc(char *buf
, char **start
, off_t offset
,
267 int len
, int *eof
, void *private)
273 for (fi
= registered_fb
; fi
< ®istered_fb
[FB_MAX
] && len
< 4000; fi
++)
275 clen
+= sprintf(buf
+ clen
, "%d %s\n",
276 GET_FB_IDX((*fi
)->node
),
278 *start
= buf
+ offset
;
283 return clen
< len
? clen
: len
;
287 fb_read(struct file
*file
, char *buf
, size_t count
, loff_t
*ppos
)
289 unsigned long p
= *ppos
;
290 struct inode
*inode
= file
->f_dentry
->d_inode
;
291 int fbidx
= GET_FB_IDX(inode
->i_rdev
);
292 struct fb_info
*info
= registered_fb
[fbidx
];
293 struct fb_ops
*fb
= info
->fbops
;
294 struct fb_fix_screeninfo fix
;
296 if (! fb
|| ! info
->disp
)
299 fb
->fb_get_fix(&fix
,PROC_CONSOLE(info
), info
);
300 if (p
>= fix
.smem_len
)
302 if (count
>= fix
.smem_len
)
303 count
= fix
.smem_len
;
304 if (count
+ p
> fix
.smem_len
)
305 count
= fix
.smem_len
- p
;
309 base_addr
= info
->disp
->screen_base
;
310 count
-= copy_to_user(buf
, base_addr
+p
, count
);
319 fb_write(struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
)
321 unsigned long p
= *ppos
;
322 struct inode
*inode
= file
->f_dentry
->d_inode
;
323 int fbidx
= GET_FB_IDX(inode
->i_rdev
);
324 struct fb_info
*info
= registered_fb
[fbidx
];
325 struct fb_ops
*fb
= info
->fbops
;
326 struct fb_fix_screeninfo fix
;
329 if (! fb
|| ! info
->disp
)
332 fb
->fb_get_fix(&fix
, PROC_CONSOLE(info
), info
);
333 if (p
> fix
.smem_len
)
335 if (count
>= fix
.smem_len
)
336 count
= fix
.smem_len
;
338 if (count
+ p
> fix
.smem_len
) {
339 count
= fix
.smem_len
- p
;
345 base_addr
= info
->disp
->screen_base
;
346 count
-= copy_from_user(base_addr
+p
, buf
, count
);
356 static void try_to_load(int fb
)
360 sprintf(modname
, "fb%d", fb
);
361 request_module(modname
);
363 #endif /* CONFIG_KMOD */
366 fb_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
,
369 int fbidx
= GET_FB_IDX(inode
->i_rdev
);
370 struct fb_info
*info
= registered_fb
[fbidx
];
371 struct fb_ops
*fb
= info
->fbops
;
373 struct fb_var_screeninfo var
;
374 struct fb_fix_screeninfo fix
;
375 struct fb_con2fbmap con2fb
;
381 case FBIOGET_VSCREENINFO
:
382 if ((i
= fb
->fb_get_var(&var
, PROC_CONSOLE(info
), info
)))
384 return copy_to_user((void *) arg
, &var
,
385 sizeof(var
)) ? -EFAULT
: 0;
386 case FBIOPUT_VSCREENINFO
:
387 if (copy_from_user(&var
, (void *) arg
, sizeof(var
)))
389 i
= var
.activate
& FB_ACTIVATE_ALL
390 ? set_all_vcs(fbidx
, fb
, &var
, info
)
391 : fb
->fb_set_var(&var
, PROC_CONSOLE(info
), info
);
394 if (copy_to_user((void *) arg
, &var
, sizeof(var
)))
397 case FBIOGET_FSCREENINFO
:
398 if ((i
= fb
->fb_get_fix(&fix
, PROC_CONSOLE(info
), info
)))
400 return copy_to_user((void *) arg
, &fix
, sizeof(fix
)) ?
403 if (copy_from_user(&cmap
, (void *) arg
, sizeof(cmap
)))
405 return (fb
->fb_set_cmap(&cmap
, 0, PROC_CONSOLE(info
), info
));
407 if (copy_from_user(&cmap
, (void *) arg
, sizeof(cmap
)))
409 return (fb
->fb_get_cmap(&cmap
, 0, PROC_CONSOLE(info
), info
));
410 case FBIOPAN_DISPLAY
:
411 if (copy_from_user(&var
, (void *) arg
, sizeof(var
)))
413 if ((i
=fb
->fb_pan_display(&var
, PROC_CONSOLE(info
), info
)))
415 if (copy_to_user((void *) arg
, &var
, sizeof(var
)))
418 case FBIOGET_CON2FBMAP
:
419 if (copy_from_user(&con2fb
, (void *)arg
, sizeof(con2fb
)))
421 if (con2fb
.console
< 1 || con2fb
.console
> MAX_NR_CONSOLES
)
423 con2fb
.framebuffer
= con2fb_map
[con2fb
.console
-1];
424 return copy_to_user((void *)arg
, &con2fb
,
425 sizeof(con2fb
)) ? -EFAULT
: 0;
426 case FBIOPUT_CON2FBMAP
:
427 if (copy_from_user(&con2fb
, (void *)arg
, sizeof(con2fb
)))
429 if (con2fb
.console
< 0 || con2fb
.console
> MAX_NR_CONSOLES
)
431 if (con2fb
.framebuffer
< 0 || con2fb
.framebuffer
>= FB_MAX
)
434 if (!registered_fb
[con2fb
.framebuffer
])
435 try_to_load(con2fb
.framebuffer
);
436 #endif /* CONFIG_KMOD */
437 if (!registered_fb
[con2fb
.framebuffer
])
439 if (con2fb
.console
!= 0)
440 set_con2fb_map(con2fb
.console
-1, con2fb
.framebuffer
);
443 for (i
= 0; i
< MAX_NR_CONSOLES
; i
++)
444 set_con2fb_map(i
, con2fb
.framebuffer
);
447 if (info
->blank
== 0)
449 (*info
->blank
)(arg
, info
);
452 return fb
->fb_ioctl(inode
, file
, cmd
, arg
, PROC_CONSOLE(info
),
458 fb_mmap(struct file
*file
, struct vm_area_struct
* vma
)
460 int fbidx
= GET_FB_IDX(file
->f_dentry
->d_inode
->i_rdev
);
461 struct fb_info
*info
= registered_fb
[fbidx
];
462 struct fb_ops
*fb
= info
->fbops
;
464 #if !defined(__sparc__) || defined(__sparc_v9__)
465 struct fb_fix_screeninfo fix
;
466 struct fb_var_screeninfo var
;
471 if (vma
->vm_pgoff
> (~0UL >> PAGE_SHIFT
))
473 off
= vma
->vm_pgoff
<< PAGE_SHIFT
;
477 return fb
->fb_mmap(info
, file
, vma
);
479 #if defined(__sparc__) && !defined(__sparc_v9__)
480 /* Should never get here, all fb drivers should have their own
486 fb
->fb_get_fix(&fix
, PROC_CONSOLE(info
), info
);
488 /* frame buffer memory */
489 start
= fix
.smem_start
;
490 len
= PAGE_ALIGN((start
& ~PAGE_MASK
)+fix
.smem_len
);
492 /* memory mapped io */
494 fb
->fb_get_var(&var
, PROC_CONSOLE(info
), info
);
497 start
= fix
.mmio_start
;
498 len
= PAGE_ALIGN((start
& ~PAGE_MASK
)+fix
.mmio_len
);
501 if ((vma
->vm_end
- vma
->vm_start
+ off
) > len
)
504 vma
->vm_pgoff
= off
>> PAGE_SHIFT
;
505 #if defined(__sparc_v9__)
506 vma
->vm_flags
|= (VM_SHM
| VM_LOCKED
);
508 unsigned long align
, j
;
509 for (align
= 0x400000; align
> PAGE_SIZE
; align
>>= 3)
510 if (len
>= align
&& !((start
& ~PAGE_MASK
) & (align
- 1)))
512 if (align
> PAGE_SIZE
&& vma
->vm_start
& (align
- 1)) {
513 /* align as much as possible */
514 struct vm_area_struct
*vmm
;
515 j
= (-vma
->vm_start
) & (align
- 1);
516 vmm
= find_vma(current
->mm
, vma
->vm_start
);
517 if (!vmm
|| vmm
->vm_start
>= vma
->vm_end
+ j
) {
523 if (io_remap_page_range(vma
->vm_start
, off
,
524 vma
->vm_end
- vma
->vm_start
, vma
->vm_page_prot
, 0))
526 vma
->vm_flags
|= VM_IO
;
528 #if defined(__mc68000__)
529 #if defined(CONFIG_SUN3)
530 pgprot_val(vma
->vm_page_prot
) |= SUN3_PAGE_NOCACHE
;
532 if (CPU_IS_020_OR_030
)
533 pgprot_val(vma
->vm_page_prot
) |= _PAGE_NOCACHE030
;
534 if (CPU_IS_040_OR_060
) {
535 pgprot_val(vma
->vm_page_prot
) &= _CACHEMASK040
;
536 /* Use no-cache mode, serialized */
537 pgprot_val(vma
->vm_page_prot
) |= _PAGE_NOCACHE_S
;
540 #elif defined(__powerpc__)
541 pgprot_val(vma
->vm_page_prot
) |= _PAGE_NO_CACHE
|_PAGE_GUARDED
;
542 #elif defined(__alpha__)
543 /* Caching is off in the I/O space quadrant by design. */
544 #elif defined(__i386__)
545 if (boot_cpu_data
.x86
> 3)
546 pgprot_val(vma
->vm_page_prot
) |= _PAGE_PCD
;
547 #elif defined(__mips__)
548 pgprot_val(vma
->vm_page_prot
) &= ~_CACHE_MASK
;
549 pgprot_val(vma
->vm_page_prot
) |= _CACHE_UNCACHED
;
550 #elif defined(__arm__)
551 #if defined(CONFIG_CPU_32) && !defined(CONFIG_ARCH_ACORN)
552 /* On Acorn architectures, we want to keep the framebuffer
555 pgprot_val(vma
->vm_page_prot
) &= ~(PTE_CACHEABLE
| PTE_BUFFERABLE
);
557 #elif defined(__sh__)
558 pgprot_val(vma
->vm_page_prot
) &= ~_PAGE_CACHABLE
;
560 #warning What do we have to do here??
562 if (io_remap_page_range(vma
->vm_start
, off
,
563 vma
->vm_end
- vma
->vm_start
, vma
->vm_page_prot
))
565 #endif /* !__sparc_v9__ */
567 #endif /* !sparc32 */
570 #if 1 /* to go away in 2.5.0 */
571 int GET_FB_IDX(kdev_t rdev
)
573 int fbidx
= MINOR(rdev
);
575 int newfbidx
= fbidx
>> 5;
576 static int warned
= 0;
577 if (!(warned
& (1<<newfbidx
))) {
578 warned
|= 1<<newfbidx
;
579 printk("Warning: Remapping obsolete /dev/fb* minor %d to %d\n",
589 fb_open(struct inode
*inode
, struct file
*file
)
591 int fbidx
= GET_FB_IDX(inode
->i_rdev
);
592 struct fb_info
*info
;
596 if (!(info
= registered_fb
[fbidx
]))
598 #endif /* CONFIG_KMOD */
599 if (!(info
= registered_fb
[fbidx
]))
601 if (info
->fbops
->owner
)
602 __MOD_INC_USE_COUNT(info
->fbops
->owner
);
603 if (info
->fbops
->fb_open
) {
604 res
= info
->fbops
->fb_open(info
,1);
605 if (res
&& info
->fbops
->owner
)
606 __MOD_DEC_USE_COUNT(info
->fbops
->owner
);
612 fb_release(struct inode
*inode
, struct file
*file
)
614 int fbidx
= GET_FB_IDX(inode
->i_rdev
);
615 struct fb_info
*info
= registered_fb
[fbidx
];
617 if (info
->fbops
->fb_release
)
618 info
->fbops
->fb_release(info
,1);
619 if (info
->fbops
->owner
)
620 __MOD_DEC_USE_COUNT(info
->fbops
->owner
);
624 static struct file_operations fb_fops
= {
634 static devfs_handle_t devfs_handle
= NULL
;
637 register_framebuffer(struct fb_info
*fb_info
)
641 static int fb_ever_opened
[FB_MAX
];
642 static int first
= 1;
644 if (num_registered_fb
== FB_MAX
)
647 for (i
= 0 ; i
< FB_MAX
; i
++)
648 if (!registered_fb
[i
])
650 fb_info
->node
= MKDEV(FB_MAJOR
, i
);
651 registered_fb
[i
] = fb_info
;
652 if (!fb_ever_opened
[i
]) {
653 struct module
*owner
= fb_info
->fbops
->owner
;
655 * We assume initial frame buffer devices can be opened this
658 for (j
= 0; j
< MAX_NR_CONSOLES
; j
++)
659 if (con2fb_map
[j
] == i
) {
661 __MOD_INC_USE_COUNT(owner
);
662 if (!fb_info
->fbops
->fb_open
)
664 if (!fb_info
->fbops
->fb_open(fb_info
,0))
667 __MOD_DEC_USE_COUNT(owner
);
669 fb_ever_opened
[i
] = 1;
674 take_over_console(&fb_con
, first_fb_vc
, last_fb_vc
, fbcon_is_default
);
676 sprintf (name_buf
, "%d", i
);
677 fb_info
->devfs_handle
=
678 devfs_register (devfs_handle
, name_buf
, DEVFS_FL_DEFAULT
,
679 FB_MAJOR
, i
, S_IFCHR
| S_IRUGO
| S_IWUGO
,
686 unregister_framebuffer(struct fb_info
*fb_info
)
690 i
= GET_FB_IDX(fb_info
->node
);
691 for (j
= 0; j
< MAX_NR_CONSOLES
; j
++)
692 if (con2fb_map
[j
] == i
)
694 if (!registered_fb
[i
])
696 devfs_unregister (fb_info
->devfs_handle
);
697 fb_info
->devfs_handle
= NULL
;
698 devfs_unregister (fb_info
->devfs_lhandle
);
699 fb_info
->devfs_lhandle
= NULL
;
700 registered_fb
[i
]=NULL
;
710 create_proc_read_entry("fb", 0, 0, fbmem_read_proc
, NULL
);
712 devfs_handle
= devfs_mk_dir (NULL
, "fb", 0, NULL
);
713 if (devfs_register_chrdev(FB_MAJOR
,"fb",&fb_fops
))
714 printk("unable to get major %d for fb devs\n", FB_MAJOR
);
717 * Probe for all builtin frame buffer devices
719 for (i
= 0; i
< num_pref_init_funcs
; i
++)
720 pref_init_funcs
[i
]();
722 for (i
= 0; i
< NUM_FB_DRIVERS
; i
++)
723 if (fb_drivers
[i
].init
)
724 fb_drivers
[i
].init();
728 * Command line options
731 int __init
video_setup(char *options
)
735 if (!options
|| !*options
)
738 if (!strncmp(options
, "scrollback:", 11)) {
741 fbcon_softback_size
= simple_strtoul(options
, &options
, 0);
742 if (*options
== 'k' || *options
== 'K') {
743 fbcon_softback_size
*= 1024;
753 if (!strncmp(options
, "map:", 4)) {
756 for (i
= 0, j
= 0; i
< MAX_NR_CONSOLES
; i
++) {
759 con2fb_map
[i
] = (options
[j
++]-'0') % FB_MAX
;
764 if (!strncmp(options
, "vc:", 3)) {
767 first_fb_vc
= simple_strtoul(options
, &options
, 10) - 1;
770 if (*options
++ == '-')
771 last_fb_vc
= simple_strtoul(options
, &options
, 10) - 1;
772 fbcon_is_default
= 0;
775 if (num_pref_init_funcs
== FB_MAX
)
778 for (i
= 0; i
< NUM_FB_DRIVERS
; i
++) {
779 j
= strlen(fb_drivers
[i
].name
);
780 if (!strncmp(options
, fb_drivers
[i
].name
, j
) &&
782 if (!strcmp(options
+j
+1, "off"))
783 fb_drivers
[i
].init
= NULL
;
785 if (fb_drivers
[i
].init
) {
786 pref_init_funcs
[num_pref_init_funcs
++] =
788 fb_drivers
[i
].init
= NULL
;
790 if (fb_drivers
[i
].setup
)
791 fb_drivers
[i
].setup(options
+j
+1);
798 * If we get here no fb was specified.
799 * We consider the argument to be a global video mode option.
801 global_mode_option
= options
;
805 __setup("video=", video_setup
);
808 * Visible symbols for modules
811 EXPORT_SYMBOL(register_framebuffer
);
812 EXPORT_SYMBOL(unregister_framebuffer
);
813 EXPORT_SYMBOL(registered_fb
);
814 EXPORT_SYMBOL(num_registered_fb
);
815 #if 1 /* to go away in 2.5.0 */
816 EXPORT_SYMBOL(GET_FB_IDX
);