~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/video/vesafb.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * framebuffer driver for VBE 2.0 compliant graphic boards
  3  *
  4  * switching to graphics mode happens at boot time (while
  5  * running in real mode, see arch/i386/video.S).
  6  *
  7  * (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  8  *
  9  */
 10 
 11 #include <linux/module.h>
 12 #include <linux/kernel.h>
 13 #include <linux/errno.h>
 14 #include <linux/string.h>
 15 #include <linux/mm.h>
 16 #include <linux/tty.h>
 17 #include <linux/malloc.h>
 18 #include <linux/delay.h>
 19 #include <linux/fb.h>
 20 #include <linux/console.h>
 21 #include <linux/selection.h>
 22 #include <linux/ioport.h>
 23 #include <linux/init.h>
 24 
 25 #include <asm/io.h>
 26 #include <asm/mtrr.h>
 27 
 28 #include <video/fbcon.h>
 29 #include <video/fbcon-cfb8.h>
 30 #include <video/fbcon-cfb16.h>
 31 #include <video/fbcon-cfb24.h>
 32 #include <video/fbcon-cfb32.h>
 33 #include <video/fbcon-mac.h>
 34 
 35 #define dac_reg (0x3c8)
 36 #define dac_val (0x3c9)
 37 
 38 /* --------------------------------------------------------------------- */
 39 
 40 /*
 41  * card parameters
 42  */
 43 
 44 /* card */
 45 unsigned long video_base; /* physical addr */
 46 int   video_size;
 47 char *video_vbase;        /* mapped */
 48 
 49 /* mode */
 50 static int  video_bpp;
 51 static int  video_width;
 52 static int  video_height;
 53 static int  video_height_virtual;
 54 static int  video_type = FB_TYPE_PACKED_PIXELS;
 55 static int  video_visual;
 56 static int  video_linelength;
 57 static int  video_cmap_len;
 58 
 59 /* --------------------------------------------------------------------- */
 60 
 61 static struct fb_var_screeninfo vesafb_defined = {
 62         0,0,0,0,        /* W,H, W, H (virtual) load xres,xres_virtual*/
 63         0,0,            /* virtual -> visible no offset */
 64         8,              /* depth -> load bits_per_pixel */
 65         0,              /* greyscale ? */
 66         {0,0,0},        /* R */
 67         {0,0,0},        /* G */
 68         {0,0,0},        /* B */
 69         {0,0,0},        /* transparency */
 70         0,              /* standard pixel format */
 71         FB_ACTIVATE_NOW,
 72         -1,-1,
 73         0,
 74         0L,0L,0L,0L,0L,
 75         0L,0L,0,        /* No sync info */
 76         FB_VMODE_NONINTERLACED,
 77         {0,0,0,0,0,0}
 78 };
 79 
 80 static struct display disp;
 81 static struct fb_info fb_info;
 82 static struct { u_short blue, green, red, pad; } palette[256];
 83 static union {
 84 #ifdef FBCON_HAS_CFB16
 85     u16 cfb16[16];
 86 #endif
 87 #ifdef FBCON_HAS_CFB24
 88     u32 cfb24[16];
 89 #endif
 90 #ifdef FBCON_HAS_CFB32
 91     u32 cfb32[16];
 92 #endif
 93 } fbcon_cmap;
 94 
 95 static int             inverse   = 0;
 96 static int             mtrr      = 0;
 97 static int             currcon   = 0;
 98 
 99 static int             pmi_setpal = 0;  /* pmi for palette changes ??? */
100 static int             ypan       = 0;  /* 0..nothing, 1..ypan, 2..ywrap */
101 static unsigned short  *pmi_base  = 0;
102 static void            (*pmi_start)(void);
103 static void            (*pmi_pal)(void);
104 
105 static struct display_switch vesafb_sw;
106 
107 /* --------------------------------------------------------------------- */
108 
109 static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
110                               struct fb_info *info)
111 {
112         int offset;
113 
114         if (!ypan)
115                 return -EINVAL;
116         if (var->xoffset)
117                 return -EINVAL;
118         if (var->yoffset > var->yres_virtual)
119                 return -EINVAL;
120         if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual)
121                 return -EINVAL;
122 
123         offset = (var->yoffset * video_linelength + var->xoffset) / 4;
124 
125         __asm__ __volatile__(
126                 "call *(%%edi)"
127                 : /* no return value */
128                 : "a" (0x4f07),         /* EAX */
129                   "b" (0),              /* EBX */
130                   "c" (offset),         /* ECX */
131                   "d" (offset >> 16),   /* EDX */
132                   "D" (&pmi_start));    /* EDI */
133         return 0;
134 }
135 
136 static int vesafb_update_var(int con, struct fb_info *info)
137 {
138         if (con == currcon && ypan) {
139                 struct fb_var_screeninfo *var = &fb_display[currcon].var;
140                 return vesafb_pan_display(var,con,info);
141         }
142         return 0;
143 }
144 
145 static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,
146                          struct fb_info *info)
147 {
148         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
149         strcpy(fix->id,"VESA VGA");
150 
151         fix->smem_start=video_base;
152         fix->smem_len=video_size;
153         fix->type = video_type;
154         fix->visual = video_visual;
155         fix->xpanstep  = 0;
156         fix->ypanstep  = ypan     ? 1 : 0;
157         fix->ywrapstep = (ypan>1) ? 1 : 0;
158         fix->line_length=video_linelength;
159         return 0;
160 }
161 
162 static int vesafb_get_var(struct fb_var_screeninfo *var, int con,
163                          struct fb_info *info)
164 {
165         if(con==-1)
166                 memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
167         else
168                 *var=fb_display[con].var;
169         return 0;
170 }
171 
172 static void vesafb_set_disp(int con)
173 {
174         struct fb_fix_screeninfo fix;
175         struct display *display;
176         struct display_switch *sw;
177         
178         if (con >= 0)
179                 display = &fb_display[con];
180         else
181                 display = &disp;        /* used during initialization */
182 
183         vesafb_get_fix(&fix, con, 0);
184 
185         memset(display, 0, sizeof(struct display));
186         display->screen_base = video_vbase;
187         display->visual = fix.visual;
188         display->type = fix.type;
189         display->type_aux = fix.type_aux;
190         display->ypanstep = fix.ypanstep;
191         display->ywrapstep = fix.ywrapstep;
192         display->line_length = fix.line_length;
193         display->next_line = fix.line_length;
194         display->can_soft_blank = 0;
195         display->inverse = inverse;
196         vesafb_get_var(&display->var, -1, &fb_info);
197 
198         switch (video_bpp) {
199 #ifdef FBCON_HAS_CFB8
200         case 8:
201                 sw = &fbcon_cfb8;
202                 break;
203 #endif
204 #ifdef FBCON_HAS_CFB16
205         case 15:
206         case 16:
207                 sw = &fbcon_cfb16;
208                 display->dispsw_data = fbcon_cmap.cfb16;
209                 break;
210 #endif
211 #ifdef FBCON_HAS_CFB24
212         case 24:
213                 sw = &fbcon_cfb24;
214                 display->dispsw_data = fbcon_cmap.cfb24;
215                 break;
216 #endif
217 #ifdef FBCON_HAS_CFB32
218         case 32:
219                 sw = &fbcon_cfb32;
220                 display->dispsw_data = fbcon_cmap.cfb32;
221                 break;
222 #endif
223         default:
224 #ifdef FBCON_HAS_MAC
225                 sw = &fbcon_mac;
226                 break;
227 #else
228                 sw = &fbcon_dummy;
229                 return;
230 #endif
231         }
232         memcpy(&vesafb_sw, sw, sizeof(*sw));
233         display->dispsw = &vesafb_sw;
234         if (!ypan) {
235                 display->scrollmode = SCROLL_YREDRAW;
236                 vesafb_sw.bmove = fbcon_redraw_bmove;
237         }
238 }
239 
240 static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
241                           struct fb_info *info)
242 {
243         static int first = 1;
244 
245         if (var->xres           != vesafb_defined.xres           ||
246             var->yres           != vesafb_defined.yres           ||
247             var->xres_virtual   != vesafb_defined.xres_virtual   ||
248             var->yres_virtual   >  video_height_virtual          ||
249             var->yres_virtual   <  video_height                  ||
250             var->xoffset                                         ||
251             var->bits_per_pixel != vesafb_defined.bits_per_pixel ||
252             var->nonstd) {
253                 if (first) {
254                         printk(KERN_ERR "Vesafb does not support changing the video mode\n");
255                         first = 0;
256                 }
257                 return -EINVAL;
258         }
259 
260         if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
261                 return 0;
262 
263         if (ypan) {
264                 if (vesafb_defined.yres_virtual != var->yres_virtual) {
265                         vesafb_defined.yres_virtual = var->yres_virtual;
266                         if (con != -1) {
267                                 fb_display[con].var = vesafb_defined;
268                                 info->changevar(con);
269                         }
270                 }
271 
272                 if (var->yoffset != vesafb_defined.yoffset)
273                         return vesafb_pan_display(var,con,info);
274                 return 0;
275         }
276 
277         if (var->yoffset)
278                 return -EINVAL;
279         return 0;
280 }
281 
282 static int vesa_getcolreg(unsigned regno, unsigned *red, unsigned *green,
283                           unsigned *blue, unsigned *transp,
284                           struct fb_info *fb_info)
285 {
286         /*
287          *  Read a single color register and split it into colors/transparent.
288          *  Return != 0 for invalid regno.
289          */
290 
291         if (regno >= video_cmap_len)
292                 return 1;
293 
294         *red   = palette[regno].red;
295         *green = palette[regno].green;
296         *blue  = palette[regno].blue;
297         *transp = 0;
298         return 0;
299 }
300 
301 #ifdef FBCON_HAS_CFB8
302 
303 static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
304 {
305         struct { u_char blue, green, red, pad; } entry;
306 
307         if (pmi_setpal) {
308                 entry.red   = red   >> 10;
309                 entry.green = green >> 10;
310                 entry.blue  = blue  >> 10;
311                 entry.pad   = 0;
312                 __asm__ __volatile__(
313                 "call *(%%esi)"
314                 : /* no return value */
315                 : "a" (0x4f09),         /* EAX */
316                   "b" (0),              /* EBX */
317                   "c" (1),              /* ECX */
318                   "d" (regno),          /* EDX */
319                   "D" (&entry),         /* EDI */
320                   "S" (&pmi_pal));      /* ESI */
321         } else {
322                 /* without protected mode interface, try VGA registers... */
323                 outb_p(regno,       dac_reg);
324                 outb_p(red   >> 10, dac_val);
325                 outb_p(green >> 10, dac_val);
326                 outb_p(blue  >> 10, dac_val);
327         }
328 }
329 
330 #endif
331 
332 static int vesa_setcolreg(unsigned regno, unsigned red, unsigned green,
333                           unsigned blue, unsigned transp,
334                           struct fb_info *fb_info)
335 {
336         /*
337          *  Set a single color register. The values supplied are
338          *  already rounded down to the hardware's capabilities
339          *  (according to the entries in the `var' structure). Return
340          *  != 0 for invalid regno.
341          */
342         
343         if (regno >= video_cmap_len)
344                 return 1;
345 
346         palette[regno].red   = red;
347         palette[regno].green = green;
348         palette[regno].blue  = blue;
349         
350         switch (video_bpp) {
351 #ifdef FBCON_HAS_CFB8
352         case 8:
353                 vesa_setpalette(regno,red,green,blue);
354                 break;
355 #endif
356 #ifdef FBCON_HAS_CFB16
357         case 15:
358         case 16:
359                 if (vesafb_defined.red.offset == 10) {
360                         /* 1:5:5:5 */
361                         fbcon_cmap.cfb16[regno] =
362                                 ((red   & 0xf800) >>  1) |
363                                 ((green & 0xf800) >>  6) |
364                                 ((blue  & 0xf800) >> 11);
365                 } else {
366                         /* 0:5:6:5 */
367                         fbcon_cmap.cfb16[regno] =
368                                 ((red   & 0xf800)      ) |
369                                 ((green & 0xfc00) >>  5) |
370                                 ((blue  & 0xf800) >> 11);
371                 }
372                 break;
373 #endif
374 #ifdef FBCON_HAS_CFB24
375         case 24:
376                 red   >>= 8;
377                 green >>= 8;
378                 blue  >>= 8;
379                 fbcon_cmap.cfb24[regno] =
380                         (red   << vesafb_defined.red.offset)   |
381                         (green << vesafb_defined.green.offset) |
382                         (blue  << vesafb_defined.blue.offset);
383                 break;
384 #endif
385 #ifdef FBCON_HAS_CFB32
386         case 32:
387                 red   >>= 8;
388                 green >>= 8;
389                 blue  >>= 8;
390                 fbcon_cmap.cfb32[regno] =
391                         (red   << vesafb_defined.red.offset)   |
392                         (green << vesafb_defined.green.offset) |
393                         (blue  << vesafb_defined.blue.offset);
394                 break;
395 #endif
396     }
397     return 0;
398 }
399 
400 static void do_install_cmap(int con, struct fb_info *info)
401 {
402         if (con != currcon)
403                 return;
404         if (fb_display[con].cmap.len)
405                 fb_set_cmap(&fb_display[con].cmap, 1, vesa_setcolreg, info);
406         else
407                 fb_set_cmap(fb_default_cmap(video_cmap_len), 1, vesa_setcolreg,
408                             info);
409 }
410 
411 static int vesafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
412                            struct fb_info *info)
413 {
414         if (con == currcon) /* current console? */
415                 return fb_get_cmap(cmap, kspc, vesa_getcolreg, info);
416         else if (fb_display[con].cmap.len) /* non default colormap? */
417                 fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
418         else
419                 fb_copy_cmap(fb_default_cmap(video_cmap_len),
420                      cmap, kspc ? 0 : 2);
421         return 0;
422 }
423 
424 static int vesafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
425                            struct fb_info *info)
426 {
427         int err;
428 
429         if (!fb_display[con].cmap.len) {        /* no colormap allocated? */
430                 err = fb_alloc_cmap(&fb_display[con].cmap,video_cmap_len,0);
431                 if (err)
432                         return err;
433         }
434         if (con == currcon)                     /* current console? */
435                 return fb_set_cmap(cmap, kspc, vesa_setcolreg, info);
436         else
437                 fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
438         return 0;
439 }
440 
441 static struct fb_ops vesafb_ops = {
442         owner:          THIS_MODULE,
443         fb_get_fix:     vesafb_get_fix,
444         fb_get_var:     vesafb_get_var,
445         fb_set_var:     vesafb_set_var,
446         fb_get_cmap:    vesafb_get_cmap,
447         fb_set_cmap:    vesafb_set_cmap,
448         fb_pan_display: vesafb_pan_display,
449 };
450 
451 int __init vesafb_setup(char *options)
452 {
453         char *this_opt;
454         
455         fb_info.fontname[0] = '\0';
456         
457         if (!options || !*options)
458                 return 0;
459         
460         for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
461                 if (!*this_opt) continue;
462                 
463                 if (! strcmp(this_opt, "inverse"))
464                         inverse=1;
465                 else if (! strcmp(this_opt, "redraw"))
466                         ypan=0;
467                 else if (! strcmp(this_opt, "ypan"))
468                         ypan=1;
469                 else if (! strcmp(this_opt, "ywrap"))
470                         ypan=2;
471                 else if (! strcmp(this_opt, "vgapal"))
472                         pmi_setpal=0;
473                 else if (! strcmp(this_opt, "pmipal"))
474                         pmi_setpal=1;
475                 else if (! strcmp(this_opt, "mtrr"))
476                         mtrr=1;
477                 else if (!strncmp(this_opt, "font:", 5))
478                         strcpy(fb_info.fontname, this_opt+5);
479         }
480         return 0;
481 }
482 
483 static int vesafb_switch(int con, struct fb_info *info)
484 {
485         /* Do we have to save the colormap? */
486         if (fb_display[currcon].cmap.len)
487                 fb_get_cmap(&fb_display[currcon].cmap, 1, vesa_getcolreg,
488                             info);
489         
490         currcon = con;
491         /* Install new colormap */
492         do_install_cmap(con, info);
493         vesafb_update_var(con,info);
494         return 1;
495 }
496 
497 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
498 
499 static void vesafb_blank(int blank, struct fb_info *info)
500 {
501         /* Not supported */
502 }
503 
504 int __init vesafb_init(void)
505 {
506         int i,j;
507 
508         if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
509                 return -ENXIO;
510 
511         video_base          = screen_info.lfb_base;
512         video_bpp           = screen_info.lfb_depth;
513         if (15 == video_bpp)
514                 video_bpp = 16;
515         video_width         = screen_info.lfb_width;
516         video_height        = screen_info.lfb_height;
517         video_linelength    = screen_info.lfb_linelength;
518         video_size          = screen_info.lfb_size * 65536;
519         video_visual = (video_bpp == 8) ?
520                 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
521 
522         if (!request_mem_region(video_base, video_size, "vesafb")) {
523                 printk(KERN_ERR
524                        "vesafb: abort, cannot reserve video memory at 0x%lx\n",
525                         video_base);
526                 return -EBUSY;
527         }
528 
529         video_vbase = ioremap(video_base, video_size);
530         if (!video_vbase) {
531                 release_mem_region(video_base, video_size);
532                 printk(KERN_ERR
533                        "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
534                         video_size, video_base);
535                 return -EIO;
536         }
537 
538         printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
539                video_base, video_vbase, video_size/1024);
540         printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
541                video_width, video_height, video_bpp, video_linelength, screen_info.pages);
542 
543         if (screen_info.vesapm_seg) {
544                 printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
545                        screen_info.vesapm_seg,screen_info.vesapm_off);
546         }
547 
548         if (screen_info.vesapm_seg < 0xc000)
549                 ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
550 
551         if (ypan || pmi_setpal) {
552                 pmi_base  = (unsigned short*)bus_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
553                 pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
554                 pmi_pal   = (void*)((char*)pmi_base + pmi_base[2]);
555                 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
556                 if (pmi_base[3]) {
557                         printk(KERN_INFO "vesafb: pmi: ports = ");
558                                 for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
559                                         printk("%x ",pmi_base[i]);
560                         printk("\n");
561                         if (pmi_base[i] != 0xffff) {
562                                 /*
563                                  * memory areas not supported (yet?)
564                                  *
565                                  * Rules are: we have to set up a descriptor for the requested
566                                  * memory area and pass it in the ES register to the BIOS function.
567                                  */
568                                 printk(KERN_INFO "vesafb: can't handle memory requests, pmi disabled\n");
569                                 ypan = pmi_setpal = 0;
570                         }
571                 }
572         }
573 
574         vesafb_defined.xres=video_width;
575         vesafb_defined.yres=video_height;
576         vesafb_defined.xres_virtual=video_width;
577         vesafb_defined.yres_virtual=video_size / video_linelength;
578         vesafb_defined.bits_per_pixel=video_bpp;
579 
580         if (ypan && vesafb_defined.yres_virtual > video_height) {
581                 printk(KERN_INFO "vesafb: scrolling: %s using protected mode interface, yres_virtual=%d\n",
582                        (ypan > 1) ? "ywrap" : "ypan",vesafb_defined.yres_virtual);
583         } else {
584                 printk(KERN_INFO "vesafb: scrolling: redraw\n");
585                 vesafb_defined.yres_virtual = video_height;
586                 ypan = 0;
587         }
588         video_height_virtual = vesafb_defined.yres_virtual;
589 
590         /* some dummy values for timing to make fbset happy */
591         vesafb_defined.pixclock     = 10000000 / video_width * 1000 / video_height;
592         vesafb_defined.left_margin  = (video_width / 8) & 0xf8;
593         vesafb_defined.right_margin = 32;
594         vesafb_defined.upper_margin = 16;
595         vesafb_defined.lower_margin = 4;
596         vesafb_defined.hsync_len    = (video_width / 8) & 0xf8;
597         vesafb_defined.vsync_len    = 4;
598 
599         if (video_bpp > 8) {
600                 vesafb_defined.red.offset    = screen_info.red_pos;
601                 vesafb_defined.red.length    = screen_info.red_size;
602                 vesafb_defined.green.offset  = screen_info.green_pos;
603                 vesafb_defined.green.length  = screen_info.green_size;
604                 vesafb_defined.blue.offset   = screen_info.blue_pos;
605                 vesafb_defined.blue.length   = screen_info.blue_size;
606                 vesafb_defined.transp.offset = screen_info.rsvd_pos;
607                 vesafb_defined.transp.length = screen_info.rsvd_size;
608                 printk(KERN_INFO "vesafb: directcolor: "
609                        "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
610                        screen_info.rsvd_size,
611                        screen_info.red_size,
612                        screen_info.green_size,
613                        screen_info.blue_size,
614                        screen_info.rsvd_pos,
615                        screen_info.red_pos,
616                        screen_info.green_pos,
617                        screen_info.blue_pos);
618                 video_cmap_len = 16;
619         } else {
620                 vesafb_defined.red.length   = 6;
621                 vesafb_defined.green.length = 6;
622                 vesafb_defined.blue.length  = 6;
623                 for(i = 0; i < 16; i++) {
624                         j = color_table[i];
625                         palette[i].red   = default_red[j];
626                         palette[i].green = default_grn[j];
627                         palette[i].blue  = default_blu[j];
628                 }
629                 video_cmap_len = 256;
630         }
631 
632         /* request failure does not faze us, as vgacon probably has this
633          * region already (FIXME) */
634         request_region(0x3c0, 32, "vesafb");
635 
636         if (mtrr) {
637                 int temp_size = video_size;
638                 while (mtrr_add(video_base, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
639                         temp_size >>= 1;
640                 }
641         }
642         
643         strcpy(fb_info.modename, "VESA VGA");
644         fb_info.changevar = NULL;
645         fb_info.node = -1;
646         fb_info.fbops = &vesafb_ops;
647         fb_info.disp=&disp;
648         fb_info.switch_con=&vesafb_switch;
649         fb_info.updatevar=&vesafb_update_var;
650         fb_info.blank=&vesafb_blank;
651         fb_info.flags=FBINFO_FLAG_DEFAULT;
652         vesafb_set_disp(-1);
653 
654         if (register_framebuffer(&fb_info)<0)
655                 return -EINVAL;
656 
657         printk(KERN_INFO "fb%d: %s frame buffer device\n",
658                GET_FB_IDX(fb_info.node), fb_info.modename);
659         return 0;
660 }
661 
662 /*
663  * Overrides for Emacs so that we follow Linus's tabbing style.
664  * ---------------------------------------------------------------------------
665  * Local variables:
666  * c-basic-offset: 8
667  * End:
668  */
669 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.