aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/skeletonfb.c
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2006-01-09 23:53:34 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-10 11:01:49 -0500
commitd911233fe6632981086942a6b66e7ae5dabaaadc (patch)
tree6608709b71f04173beb0263c76a66bc1b7b2d4a9 /drivers/video/skeletonfb.c
parentc549dc6422e4b720fed6702d70fddd8cee0f5c9a (diff)
[PATCH] skeletonfb: Documentation update
Update skeletonfb so it reflects recent (and somewhat old) changes of the framebuffer layer. Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/skeletonfb.c')
-rw-r--r--drivers/video/skeletonfb.c482
1 files changed, 383 insertions, 99 deletions
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index a01e7ecc15ed..9b707771d757 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -115,7 +115,8 @@ static struct fb_fix_screeninfo xxxfb_fix __initdata = {
115 /* 115 /*
116 * If your driver supports multiple boards or it supports multiple 116 * If your driver supports multiple boards or it supports multiple
117 * framebuffers, you should make these arrays, or allocate them 117 * framebuffers, you should make these arrays, or allocate them
118 * dynamically (using kmalloc()). 118 * dynamically using framebuffer_alloc() and free them with
119 * framebuffer_release().
119 */ 120 */
120static struct fb_info info; 121static struct fb_info info;
121 122
@@ -179,18 +180,31 @@ static int xxxfb_release(const struct fb_info *info, int user)
179 * intent to only test a mode and not actually set it. The stuff in 180 * intent to only test a mode and not actually set it. The stuff in
180 * modedb.c is a example of this. If the var passed in is slightly 181 * modedb.c is a example of this. If the var passed in is slightly
181 * off by what the hardware can support then we alter the var PASSED in 182 * off by what the hardware can support then we alter the var PASSED in
182 * to what we can do. If the hardware doesn't support mode change 183 * to what we can do.
183 * a -EINVAL will be returned by the upper layers. You don't need to 184 *
184 * implement this function then. If you hardware doesn't support 185 * For values that are off, this function must round them _up_ to the
185 * changing the resolution then this function is not needed. In this 186 * next value that is supported by the hardware. If the value is
186 * case the driver woudl just provide a var that represents the static 187 * greater than the highest value supported by the hardware, then this
187 * state the screen is in. 188 * function must return -EINVAL.
189 *
190 * Exception to the above rule: Some drivers have a fixed mode, ie,
191 * the hardware is already set at boot up, and cannot be changed. In
192 * this case, it is more acceptable that this function just return
193 * a copy of the currently working var (info->var). Better is to not
194 * implement this function, as the upper layer will do the copying
195 * of the current var for you.
196 *
197 * Note: This is the only function where the contents of var can be
198 * freely adjusted after the driver has been registered. If you find
199 * that you have code outside of this function that alters the content
200 * of var, then you are doing something wrong. Note also that the
201 * contents of info->var must be left untouched at all times after
202 * driver registration.
188 * 203 *
189 * Returns negative errno on error, or zero on success. 204 * Returns negative errno on error, or zero on success.
190 */ 205 */
191static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 206static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
192{ 207{
193 const struct xxx_par *par = (const struct xxx_par *) info->par;
194 /* ... */ 208 /* ... */
195 return 0; 209 return 0;
196} 210}
@@ -204,14 +218,39 @@ static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
204 * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in 218 * fb_fix_screeninfo stored in fb_info. It doesn't not alter var in
205 * fb_info since we are using that data. This means we depend on the 219 * fb_info since we are using that data. This means we depend on the
206 * data in var inside fb_info to be supported by the hardware. 220 * data in var inside fb_info to be supported by the hardware.
207 * xxxfb_check_var is always called before xxxfb_set_par to ensure this. 221 *
222 * This function is also used to recover/restore the hardware to a
223 * known working state.
224 *
225 * xxxfb_check_var is always called before xxxfb_set_par to ensure that
226 * the contents of var is always valid.
227 *
208 * Again if you can't change the resolution you don't need this function. 228 * Again if you can't change the resolution you don't need this function.
209 * 229 *
230 * However, even if your hardware does not support mode changing,
231 * a set_par might be needed to at least initialize the hardware to
232 * a known working state, especially if it came back from another
233 * process that also modifies the same hardware, such as X.
234 *
235 * If this is the case, a combination such as the following should work:
236 *
237 * static int xxxfb_check_var(struct fb_var_screeninfo *var,
238 * struct fb_info *info)
239 * {
240 * *var = info->var;
241 * return 0;
242 * }
243 *
244 * static int xxxfb_set_par(struct fb_info *info)
245 * {
246 * init your hardware here
247 * }
248 *
210 * Returns negative errno on error, or zero on success. 249 * Returns negative errno on error, or zero on success.
211 */ 250 */
212static int xxxfb_set_par(struct fb_info *info) 251static int xxxfb_set_par(struct fb_info *info)
213{ 252{
214 struct xxx_par *par = (struct xxx_par *) info->par; 253 struct xxx_par *par = info->par;
215 /* ... */ 254 /* ... */
216 return 0; 255 return 0;
217} 256}
@@ -258,70 +297,110 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
258 * var->{color}.offset contains start of bitfield 297 * var->{color}.offset contains start of bitfield
259 * var->{color}.length contains length of bitfield 298 * var->{color}.length contains length of bitfield
260 * {hardwarespecific} contains width of DAC 299 * {hardwarespecific} contains width of DAC
261 * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) 300 * pseudo_palette[X] is programmed to (X << red.offset) |
301 * (X << green.offset) |
302 * (X << blue.offset)
262 * RAMDAC[X] is programmed to (red, green, blue) 303 * RAMDAC[X] is programmed to (red, green, blue)
304 * color depth = SUM(var->{color}.length)
263 * 305 *
264 * Pseudocolor: 306 * Pseudocolor:
265 * uses offset = 0 && length = DAC register width.
266 * var->{color}.offset is 0 307 * var->{color}.offset is 0
267 * var->{color}.length contains widht of DAC 308 * var->{color}.length contains width of DAC or the number of unique
268 * cmap is not used 309 * colors available (color depth)
269 * DAC[X] is programmed to (red, green, blue) 310 * pseudo_palette is not used
311 * RAMDAC[X] is programmed to (red, green, blue)
312 * color depth = var->{color}.length
313 *
314 * Static pseudocolor:
315 * same as Pseudocolor, but the RAMDAC is not programmed (read-only)
316 *
317 * Mono01/Mono10:
318 * Has only 2 values, black on white or white on black (fg on bg),
319 * var->{color}.offset is 0
320 * white = (1 << var->{color}.length) - 1, black = 0
321 * pseudo_palette is not used
322 * RAMDAC does not exist
323 * color depth is always 2
324 *
270 * Truecolor: 325 * Truecolor:
271 * does not use RAMDAC (usually has 3 of them). 326 * does not use RAMDAC (usually has 3 of them).
272 * var->{color}.offset contains start of bitfield 327 * var->{color}.offset contains start of bitfield
273 * var->{color}.length contains length of bitfield 328 * var->{color}.length contains length of bitfield
274 * cmap is programmed to (red << red.offset) | (green << green.offset) | 329 * pseudo_palette is programmed to (red << red.offset) |
275 * (blue << blue.offset) | (transp << transp.offset) 330 * (green << green.offset) |
331 * (blue << blue.offset) |
332 * (transp << transp.offset)
276 * RAMDAC does not exist 333 * RAMDAC does not exist
334 * color depth = SUM(var->{color}.length})
335 *
336 * The color depth is used by fbcon for choosing the logo and also
337 * for color palette transformation if color depth < 4
338 *
339 * As can be seen from the above, the field bits_per_pixel is _NOT_
340 * a criteria for describing the color visual.
341 *
342 * A common mistake is assuming that bits_per_pixel <= 8 is pseudocolor,
343 * and higher than that, true/directcolor. This is incorrect, one needs
344 * to look at the fix->visual.
345 *
346 * Another common mistake is using bits_per_pixel to calculate the color
347 * depth. The bits_per_pixel field does not directly translate to color
348 * depth. You have to compute for the color depth (using the color
349 * bitfields) and fix->visual as seen above.
350 */
351
352 /*
353 * This is the point where the color is converted to something that
354 * is acceptable by the hardware.
277 */ 355 */
278#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 356#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
279 switch (info->fix.visual) { 357 red = CNVT_TOHW(red, info->var.red.length);
280 case FB_VISUAL_TRUECOLOR: 358 green = CNVT_TOHW(green, info->var.green.length);
281 case FB_VISUAL_PSEUDOCOLOR: 359 blue = CNVT_TOHW(blue, info->var.blue.length);
282 red = CNVT_TOHW(red, info->var.red.length); 360 transp = CNVT_TOHW(transp, info->var.transp.length);
283 green = CNVT_TOHW(green, info->var.green.length);
284 blue = CNVT_TOHW(blue, info->var.blue.length);
285 transp = CNVT_TOHW(transp, info->var.transp.length);
286 break;
287 case FB_VISUAL_DIRECTCOLOR:
288 /* example here assumes 8 bit DAC. Might be different
289 * for your hardware */
290 red = CNVT_TOHW(red, 8);
291 green = CNVT_TOHW(green, 8);
292 blue = CNVT_TOHW(blue, 8);
293 /* hey, there is bug in transp handling... */
294 transp = CNVT_TOHW(transp, 8);
295 break;
296 }
297#undef CNVT_TOHW 361#undef CNVT_TOHW
298 /* Truecolor has hardware independent palette */ 362 /*
299 if (info->fix.visual == FB_VISUAL_TRUECOLOR) { 363 * This is the point where the function feeds the color to the hardware
300 u32 v; 364 * palette after converting the colors to something acceptable by
301 365 * the hardware. Note, only FB_VISUAL_DIRECTCOLOR and
302 if (regno >= 16) 366 * FB_VISUAL_PSEUDOCOLOR visuals need to write to the hardware palette.
303 return -EINVAL; 367 * If you have code that writes to the hardware CLUT, and it's not
304 368 * any of the above visuals, then you are doing something wrong.
305 v = (red << info->var.red.offset) | 369 */
306 (green << info->var.green.offset) | 370 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
307 (blue << info->var.blue.offset) | 371 info->fix.visual == FB_VISUAL_TRUECOLOR)
308 (transp << info->var.transp.offset); 372 write_{red|green|blue|transp}_to_clut();
309 373
310 switch (info->var.bits_per_pixel) { 374 /* This is the point were you need to fill up the contents of
311 case 8: 375 * info->pseudo_palette. This structure is used _only_ by fbcon, thus
312 /* Yes some hand held devices have this. */ 376 * it only contains 16 entries to match the number of colors supported
313 ((u8*)(info->pseudo_palette))[regno] = v; 377 * by the console. The pseudo_palette is used only if the visual is
314 break; 378 * in directcolor or truecolor mode. With other visuals, the
315 case 16: 379 * pseudo_palette is not used. (This might change in the future.)
316 ((u16*)(info->pseudo_palette))[regno] = v; 380 *
317 break; 381 * The contents of the pseudo_palette is in raw pixel format. Ie, each
318 case 24: 382 * entry can be written directly to the framebuffer without any conversion.
319 case 32: 383 * The pseudo_palette is (void *). However, if using the generic
320 ((u32*)(info->pseudo_palette))[regno] = v; 384 * drawing functions (cfb_imageblit, cfb_fillrect), the pseudo_palette
321 break; 385 * must be casted to (u32 *) _regardless_ of the bits per pixel. If the
322 } 386 * driver is using its own drawing functions, then it can use whatever
323 return 0; 387 * size it wants.
388 */
389 if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
390 info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
391 u32 v;
392
393 if (regno >= 16)
394 return -EINVAL;
395
396 v = (red << info->var.red.offset) |
397 (green << info->var.green.offset) |
398 (blue << info->var.blue.offset) |
399 (transp << info->var.transp.offset);
400
401 ((u32*)(info->pseudo_palette))[regno] = v;
324 } 402 }
403
325 /* ... */ 404 /* ... */
326 return 0; 405 return 0;
327} 406}
@@ -340,6 +419,17 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
340static int xxxfb_pan_display(struct fb_var_screeninfo *var, 419static int xxxfb_pan_display(struct fb_var_screeninfo *var,
341 const struct fb_info *info) 420 const struct fb_info *info)
342{ 421{
422 /*
423 * If your hardware does not support panning, _do_ _not_ implement this
424 * function. Creating a dummy function will just confuse user apps.
425 */
426
427 /*
428 * Note that even if this function is fully functional, a setting of
429 * 0 in both xpanstep and ypanstep means that this function will never
430 * get called.
431 */
432
343 /* ... */ 433 /* ... */
344 return 0; 434 return 0;
345} 435}
@@ -349,15 +439,20 @@ static int xxxfb_pan_display(struct fb_var_screeninfo *var,
349 * @blank_mode: the blank mode we want. 439 * @blank_mode: the blank mode we want.
350 * @info: frame buffer structure that represents a single frame buffer 440 * @info: frame buffer structure that represents a single frame buffer
351 * 441 *
352 * Blank the screen if blank_mode != 0, else unblank. Return 0 if 442 * Blank the screen if blank_mode != FB_BLANK_UNBLANK, else unblank.
353 * blanking succeeded, != 0 if un-/blanking failed due to e.g. a 443 * Return 0 if blanking succeeded, != 0 if un-/blanking failed due to
354 * video mode which doesn't support it. Implements VESA suspend 444 * e.g. a video mode which doesn't support it.
355 * and powerdown modes on hardware that supports disabling hsync/vsync:
356 * blank_mode == 2: suspend vsync
357 * blank_mode == 3: suspend hsync
358 * blank_mode == 4: powerdown
359 * 445 *
360 * Returns negative errno on error, or zero on success. 446 * Implements VESA suspend and powerdown modes on hardware that supports
447 * disabling hsync/vsync:
448 *
449 * FB_BLANK_NORMAL = display is blanked, syncs are on.
450 * FB_BLANK_HSYNC_SUSPEND = hsync off
451 * FB_BLANK_VSYNC_SUSPEND = vsync off
452 * FB_BLANK_POWERDOWN = hsync and vsync off
453 *
454 * If implementing this function, at least support FB_BLANK_UNBLANK.
455 * Return !0 for any modes that are unimplemented.
361 * 456 *
362 */ 457 */
363static int xxxfb_blank(int blank_mode, const struct fb_info *info) 458static int xxxfb_blank(int blank_mode, const struct fb_info *info)
@@ -454,6 +549,14 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image)
454 * @data: The actual data used to construct the image on the display. 549 * @data: The actual data used to construct the image on the display.
455 * @cmap: The colormap used for color images. 550 * @cmap: The colormap used for color images.
456 */ 551 */
552
553/*
554 * The generic function, cfb_imageblit, expects that the bitmap scanlines are
555 * padded to the next byte. Most hardware accelerators may require padding to
556 * the next u16 or the next u32. If that is the case, the driver can specify
557 * this by setting info->pixmap.scan_align = 2 or 4. See a more
558 * comprehensive description of the pixmap below.
559 */
457} 560}
458 561
459/** 562/**
@@ -517,6 +620,7 @@ int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
517 */ 620 */
518void xxxfb_rotate(struct fb_info *info, int angle) 621void xxxfb_rotate(struct fb_info *info, int angle)
519{ 622{
623/* Will be deprecated */
520} 624}
521 625
522/** 626/**
@@ -540,6 +644,9 @@ void xxxfb_poll(struct fb_info *info, poll_table *wait)
540 * so we can have consistent display output. 644 * so we can have consistent display output.
541 * 645 *
542 * @info: frame buffer structure that represents a single frame buffer 646 * @info: frame buffer structure that represents a single frame buffer
647 *
648 * If the driver has implemented its own hardware-based drawing function,
649 * implementing this function is highly recommended.
543 */ 650 */
544void xxxfb_sync(struct fb_info *info) 651void xxxfb_sync(struct fb_info *info)
545{ 652{
@@ -549,20 +656,25 @@ void xxxfb_sync(struct fb_info *info)
549 * Initialization 656 * Initialization
550 */ 657 */
551 658
552int __init xxxfb_init(void) 659/* static int __init xxfb_probe (struct device *device) -- for platform devs */
660static int __init xxxfb_probe(struct pci_dev *dev,
661 const_struct pci_device_id *ent)
553{ 662{
663 struct fb_info *info;
664 struct xxx_par *par;
665 struct device = &dev->dev; /* for pci drivers */
554 int cmap_len, retval; 666 int cmap_len, retval;
555 667
556 /* 668 /*
557 * For kernel boot options (in 'video=xxxfb:<options>' format) 669 * Dynamically allocate info and par
558 */ 670 */
559#ifndef MODULE 671 info = framebuffer_alloc(sizeof(struct xxx_par), device);
560 char *option = NULL;
561 672
562 if (fb_get_options("xxxfb", &option)) 673 if (!info) {
563 return -ENODEV; 674 /* goto error path */
564 xxxfb_setup(option); 675 }
565#endif 676
677 par = info->par;
566 678
567 /* 679 /*
568 * Here we set the screen_base to the virtual memory address 680 * Here we set the screen_base to the virtual memory address
@@ -570,18 +682,87 @@ int __init xxxfb_init(void)
570 * from the bus layer and then translate it to virtual memory 682 * from the bus layer and then translate it to virtual memory
571 * space via ioremap. Consult ioport.h. 683 * space via ioremap. Consult ioport.h.
572 */ 684 */
573 info.screen_base = framebuffer_virtual_memory; 685 info->screen_base = framebuffer_virtual_memory;
574 info.fbops = &xxxfb_ops; 686 info->fbops = &xxxfb_ops;
575 info.fix = xxxfb_fix; 687 info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be
576 info.pseudo_palette = pseudo_palette; 688 * used, so mark it as __initdata
577 689 */
690 info->pseudo_palette = pseudo_palette; /* The pseudopalette is an
691 * 16-member array
692 */
578 /* 693 /*
579 * Set up flags to indicate what sort of acceleration your 694 * Set up flags to indicate what sort of acceleration your
580 * driver can provide (pan/wrap/copyarea/etc.) and whether it 695 * driver can provide (pan/wrap/copyarea/etc.) and whether it
581 * is a module -- see FBINFO_* in include/linux/fb.h 696 * is a module -- see FBINFO_* in include/linux/fb.h
697 *
698 * If your hardware can support any of the hardware accelerated functions
699 * fbcon performance will improve if info->flags is set properly.
700 *
701 * FBINFO_HWACCEL_COPYAREA - hardware moves
702 * FBINFO_HWACCEL_FILLRECT - hardware fills
703 * FBINFO_HWACCEL_IMAGEBLIT - hardware mono->color expansion
704 * FBINFO_HWACCEL_YPAN - hardware can pan display in y-axis
705 * FBINFO_HWACCEL_YWRAP - hardware can wrap display in y-axis
706 * FBINFO_HWACCEL_DISABLED - supports hardware accels, but disabled
707 * FBINFO_READS_FAST - if set, prefer moves over mono->color expansion
708 * FBINFO_MISC_TILEBLITTING - hardware can do tile blits
709 *
710 * NOTE: These are for fbcon use only.
711 */
712 info->flags = FBINFO_DEFAULT;
713
714/********************* This stage is optional ******************************/
715 /*
716 * The struct pixmap is a scratch pad for the drawing functions. This
717 * is where the monochrome bitmap is constructed by the higher layers
718 * and then passed to the accelerator. For drivers that uses
719 * cfb_imageblit, you can skip this part. For those that have a more
720 * rigorous requirement, this stage is needed
721 */
722
723 /* PIXMAP_SIZE should be small enough to optimize drawing, but not
724 * large enough that memory is wasted. A safe size is
725 * (max_xres * max_font_height/8). max_xres is driver dependent,
726 * max_font_height is 32.
727 */
728 info->pixmap.addr = kmalloc(PIXMAP_SIZE, GFP_KERNEL);
729 if (!info->pixmap.addr) {
730 /* goto error */
731 }
732
733 info->pixmap.size = PIXMAP_SIZE;
734
735 /*
736 * FB_PIXMAP_SYSTEM - memory is in system ram
737 * FB_PIXMAP_IO - memory is iomapped
738 * FB_PIXMAP_SYNC - if set, will call fb_sync() per access to pixmap,
739 * usually if FB_PIXMAP_IO is set.
740 *
741 * Currently, FB_PIXMAP_IO is unimplemented.
742 */
743 info->pixmap.flags = FB_PIXMAP_SYSTEM;
744
745 /*
746 * scan_align is the number of padding for each scanline. It is in bytes.
747 * Thus for accelerators that need padding to the next u32, put 4 here.
748 */
749 info->pixmap.scan_align = 4;
750
751 /*
752 * buf_align is the amount to be padded for the buffer. For example,
753 * the i810fb needs a scan_align of 2 but expects it to be fed with
754 * dwords, so a buf_align = 4 is required.
582 */ 755 */
583 info.flags = FBINFO_DEFAULT; 756 info->pixmap.buf_align = 4;
584 info.par = current_par; 757
758 /* access_align is how many bits can be accessed from the framebuffer
759 * ie. some epson cards allow 16-bit access only. Most drivers will
760 * be safe with u32 here.
761 *
762 * NOTE: This field is currently unused.
763 */
764 info->pixmap.scan_align = 32
765/***************************** End optional stage ***************************/
585 766
586 /* 767 /*
587 * This should give a reasonable default video mode. The following is 768 * This should give a reasonable default video mode. The following is
@@ -590,42 +771,145 @@ int __init xxxfb_init(void)
590 if (!mode_option) 771 if (!mode_option)
591 mode_option = "640x480@60"; 772 mode_option = "640x480@60";
592 773
593 retval = fb_find_mode(&info.var, &info, mode_option, NULL, 0, NULL, 8); 774 retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8);
594 775
595 if (!retval || retval == 4) 776 if (!retval || retval == 4)
596 return -EINVAL; 777 return -EINVAL;
597 778
598 /* This has to been done !!! */ 779 /* This has to been done !!! */
599 fb_alloc_cmap(&info.cmap, cmap_len, 0); 780 fb_alloc_cmap(info->cmap, cmap_len, 0);
600 781
601 /* 782 /*
602 * The following is done in the case of having hardware with a static 783 * The following is done in the case of having hardware with a static
603 * mode. If we are setting the mode ourselves we don't call this. 784 * mode. If we are setting the mode ourselves we don't call this.
604 */ 785 */
605 info.var = xxxfb_var; 786 info->var = xxxfb_var;
606 787
607 if (register_framebuffer(&info) < 0) 788 /*
789 * For drivers that can...
790 */
791 xxxfb_check_var(&info->var, info);
792
793 /*
794 * Does a call to fb_set_par() before register_framebuffer needed? This
795 * will depend on you and the hardware. If you are sure that your driver
796 * is the only device in the system, a call to fb_set_par() is safe.
797 *
798 * Hardware in x86 systems has a VGA core. Calling set_par() at this
799 * point will corrupt the VGA console, so it might be safer to skip a
800 * call to set_par here and just allow fbcon to do it for you.
801 */
802 /* xxxfb_set_par(info); */
803
804 if (register_framebuffer(info) < 0)
608 return -EINVAL; 805 return -EINVAL;
609 printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, 806 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
610 info.fix.id); 807 info->fix.id);
808 pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */
611 return 0; 809 return 0;
612} 810}
613 811
614 /* 812 /*
615 * Cleanup 813 * Cleanup
616 */ 814 */
815/* static void __exit xxxfb_remove(struct device *device) */
816static void __exit xxxfb_remove(struct pci_dev *dev)
817{
818 struct fb_info *info = pci_get_drv_data(dev);
819 /* or dev_get_drv_data(device); */
820
821 if (info) {
822 unregister_framebuffer(info);
823 fb_dealloc_cmap(&info.cmap);
824 /* ... */
825 framebuffer_release(info);
826 }
827
828 return 0;
829}
617 830
618static void __exit xxxfb_cleanup(void) 831#if CONFIG_PCI
832/* For PCI drivers */
833static struct pci_driver xxxfb_driver = {
834 .name = "xxxfb",
835 .id_table = xxxfb_devices,
836 .probe = xxxfb_probe,
837 .remove = __devexit_p(xxxfb_remove),
838 .suspend = xxxfb_suspend, /* optional */
839 .resume = xxxfb_resume, /* optional */
840};
841
842static int __init xxxfb_init(void)
619{ 843{
620 /* 844 /*
621 * If your driver supports multiple boards, you should unregister and 845 * For kernel boot options (in 'video=xxxfb:<options>' format)
622 * clean up all instances. 846 */
623 */ 847#ifndef MODULE
848 char *option = NULL;
624 849
625 unregister_framebuffer(info); 850 if (fb_get_options("xxxfb", &option))
626 fb_dealloc_cmap(&info.cmap); 851 return -ENODEV;
627 /* ... */ 852 xxxfb_setup(option);
853#endif
854
855 return pci_register_driver(&xxxfb_driver);
856}
857
858static void __exit xxxfb_exit(void)
859{
860 pci_unregister_driver(&xxxfb_driver);
628} 861}
862#else
863#include <linux/platform_device.h>
864/* for platform devices */
865static struct device_driver xxxfb_driver = {
866 .name = "xxxfb",
867 .bus = &platform_bus_type,
868 .probe = xxxfb_probe,
869 .remove = xxxfb_remove,
870 .suspend = xxxfb_suspend, /* optional */
871 .resume = xxxfb_resume, /* optional */
872};
873
874static struct platform_device xxxfb_device = {
875 .name = "xxxfb",
876};
877
878static int __init xxxfb_init(void)
879{
880 int ret;
881 /*
882 * For kernel boot options (in 'video=xxxfb:<options>' format)
883 */
884#ifndef MODULE
885 char *option = NULL;
886
887 if (fb_get_options("xxxfb", &option))
888 return -ENODEV;
889 xxxfb_setup(option);
890#endif
891 ret = driver_register(&xxxfb_driver);
892
893 if (!ret) {
894 ret = platform_device_register(&xxxfb_device);
895 if (ret)
896 driver_unregister(&xxxfb_driver);
897 }
898
899 return ret;
900}
901
902static void __exit xxxfb_exit(void)
903{
904 platform_device_unregister(&xxxfb_device);
905 driver_unregister(&xxxfb_driver);
906}
907#endif
908
909MODULE_LICENSE("GPL");
910module_init(xxxfb_init);
911module_exit(xxxfb_exit);
912
629 913
630 /* 914 /*
631 * Setup 915 * Setup