Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.13-rc2 684 lines 25 kB view raw
1/* 2 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device 3 * 4 * Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com) 5 * 6 * Created 28 Dec 1997 by Geert Uytterhoeven 7 * 8 * 9 * I have started rewriting this driver as a example of the upcoming new API 10 * The primary goal is to remove the console code from fbdev and place it 11 * into fbcon.c. This reduces the code and makes writing a new fbdev driver 12 * easy since the author doesn't need to worry about console internals. It 13 * also allows the ability to run fbdev without a console/tty system on top 14 * of it. 15 * 16 * First the roles of struct fb_info and struct display have changed. Struct 17 * display will go away. The way the the new framebuffer console code will 18 * work is that it will act to translate data about the tty/console in 19 * struct vc_data to data in a device independent way in struct fb_info. Then 20 * various functions in struct fb_ops will be called to store the device 21 * dependent state in the par field in struct fb_info and to change the 22 * hardware to that state. This allows a very clean separation of the fbdev 23 * layer from the console layer. It also allows one to use fbdev on its own 24 * which is a bounus for embedded devices. The reason this approach works is 25 * for each framebuffer device when used as a tty/console device is allocated 26 * a set of virtual terminals to it. Only one virtual terminal can be active 27 * per framebuffer device. We already have all the data we need in struct 28 * vc_data so why store a bunch of colormaps and other fbdev specific data 29 * per virtual terminal. 30 * 31 * As you can see doing this makes the con parameter pretty much useless 32 * for struct fb_ops functions, as it should be. Also having struct 33 * fb_var_screeninfo and other data in fb_info pretty much eliminates the 34 * need for get_fix and get_var. Once all drivers use the fix, var, and cmap 35 * fbcon can be written around these fields. This will also eliminate the 36 * need to regenerate struct fb_var_screeninfo, struct fb_fix_screeninfo 37 * struct fb_cmap every time get_var, get_fix, get_cmap functions are called 38 * as many drivers do now. 39 * 40 * This file is subject to the terms and conditions of the GNU General Public 41 * License. See the file COPYING in the main directory of this archive for 42 * more details. 43 */ 44 45#include <linux/module.h> 46#include <linux/kernel.h> 47#include <linux/errno.h> 48#include <linux/string.h> 49#include <linux/mm.h> 50#include <linux/tty.h> 51#include <linux/slab.h> 52#include <linux/delay.h> 53#include <linux/fb.h> 54#include <linux/init.h> 55 56 /* 57 * This is just simple sample code. 58 * 59 * No warranty that it actually compiles. 60 * Even less warranty that it actually works :-) 61 */ 62 63/* 64 * If your driver supports multiple boards, you should make the 65 * below data types arrays, or allocate them dynamically (using kmalloc()). 66 */ 67 68/* 69 * This structure defines the hardware state of the graphics card. Normally 70 * you place this in a header file in linux/include/video. This file usually 71 * also includes register information. That allows other driver subsystems 72 * and userland applications the ability to use the same header file to 73 * avoid duplicate work and easy porting of software. 74 */ 75struct xxx_par; 76 77/* 78 * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo 79 * if we don't use modedb. If we do use modedb see xxxfb_init how to use it 80 * to get a fb_var_screeninfo. Otherwise define a default var as well. 81 */ 82static struct fb_fix_screeninfo xxxfb_fix __initdata = { 83 .id = "FB's name", 84 .type = FB_TYPE_PACKED_PIXELS, 85 .visual = FB_VISUAL_PSEUDOCOLOR, 86 .xpanstep = 1, 87 .ypanstep = 1, 88 .ywrapstep = 1, 89 .accel = FB_ACCEL_NONE, 90}; 91 92 /* 93 * Modern graphical hardware not only supports pipelines but some 94 * also support multiple monitors where each display can have its 95 * its own unique data. In this case each display could be 96 * represented by a separate framebuffer device thus a separate 97 * struct fb_info. Now the struct xxx_par represents the graphics 98 * hardware state thus only one exist per card. In this case the 99 * struct xxx_par for each graphics card would be shared between 100 * every struct fb_info that represents a framebuffer on that card. 101 * This allows when one display changes it video resolution (info->var) 102 * the other displays know instantly. Each display can always be 103 * aware of the entire hardware state that affects it because they share 104 * the same xxx_par struct. The other side of the coin is multiple 105 * graphics cards that pass data around until it is finally displayed 106 * on one monitor. Such examples are the voodoo 1 cards and high end 107 * NUMA graphics servers. For this case we have a bunch of pars, each 108 * one that represents a graphics state, that belong to one struct 109 * fb_info. Their you would want to have *par point to a array of device 110 * states and have each struct fb_ops function deal with all those 111 * states. I hope this covers every possible hardware design. If not 112 * feel free to send your ideas at jsimmons@users.sf.net 113 */ 114 115 /* 116 * If your driver supports multiple boards or it supports multiple 117 * framebuffers, you should make these arrays, or allocate them 118 * dynamically (using kmalloc()). 119 */ 120static struct fb_info info; 121 122 /* 123 * Each one represents the state of the hardware. Most hardware have 124 * just one hardware state. These here represent the default state(s). 125 */ 126static struct xxx_par __initdata current_par; 127 128int xxxfb_init(void); 129int xxxfb_setup(char*); 130 131/** 132 * xxxfb_open - Optional function. Called when the framebuffer is 133 * first accessed. 134 * @info: frame buffer structure that represents a single frame buffer 135 * @user: tell us if the userland (value=1) or the console is accessing 136 * the framebuffer. 137 * 138 * This function is the first function called in the framebuffer api. 139 * Usually you don't need to provide this function. The case where it 140 * is used is to change from a text mode hardware state to a graphics 141 * mode state. 142 * 143 * Returns negative errno on error, or zero on success. 144 */ 145static int xxxfb_open(const struct fb_info *info, int user) 146{ 147 return 0; 148} 149 150/** 151 * xxxfb_release - Optional function. Called when the framebuffer 152 * device is closed. 153 * @info: frame buffer structure that represents a single frame buffer 154 * @user: tell us if the userland (value=1) or the console is accessing 155 * the framebuffer. 156 * 157 * Thus function is called when we close /dev/fb or the framebuffer 158 * console system is released. Usually you don't need this function. 159 * The case where it is usually used is to go from a graphics state 160 * to a text mode state. 161 * 162 * Returns negative errno on error, or zero on success. 163 */ 164static int xxxfb_release(const struct fb_info *info, int user) 165{ 166 return 0; 167} 168 169/** 170 * xxxfb_check_var - Optional function. Validates a var passed in. 171 * @var: frame buffer variable screen structure 172 * @info: frame buffer structure that represents a single frame buffer 173 * 174 * Checks to see if the hardware supports the state requested by 175 * var passed in. This function does not alter the hardware state!!! 176 * This means the data stored in struct fb_info and struct xxx_par do 177 * not change. This includes the var inside of struct fb_info. 178 * Do NOT change these. This function can be called on its own if we 179 * 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 * 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 * a -EINVAL will be returned by the upper layers. You don't need to 184 * implement this function then. If you hardware doesn't support 185 * changing the resolution then this function is not needed. In this 186 * case the driver woudl just provide a var that represents the static 187 * state the screen is in. 188 * 189 * Returns negative errno on error, or zero on success. 190 */ 191static int xxxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 192{ 193 const struct xxx_par *par = (const struct xxx_par *) info->par; 194 /* ... */ 195 return 0; 196} 197 198/** 199 * xxxfb_set_par - Optional function. Alters the hardware state. 200 * @info: frame buffer structure that represents a single frame buffer 201 * 202 * Using the fb_var_screeninfo in fb_info we set the resolution of the 203 * this particular framebuffer. This function alters the par AND the 204 * 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 206 * 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. 208 * Again if you can't change the resolution you don't need this function. 209 * 210 * Returns negative errno on error, or zero on success. 211 */ 212static int xxxfb_set_par(struct fb_info *info) 213{ 214 struct xxx_par *par = (struct xxx_par *) info->par; 215 /* ... */ 216 return 0; 217} 218 219/** 220 * xxxfb_setcolreg - Optional function. Sets a color register. 221 * @regno: Which register in the CLUT we are programming 222 * @red: The red value which can be up to 16 bits wide 223 * @green: The green value which can be up to 16 bits wide 224 * @blue: The blue value which can be up to 16 bits wide. 225 * @transp: If supported, the alpha value which can be up to 16 bits wide. 226 * @info: frame buffer info structure 227 * 228 * Set a single color register. The values supplied have a 16 bit 229 * magnitude which needs to be scaled in this function for the hardware. 230 * Things to take into consideration are how many color registers, if 231 * any, are supported with the current color visual. With truecolor mode 232 * no color palettes are supported. Here a pseudo palette is created 233 * which we store the value in pseudo_palette in struct fb_info. For 234 * pseudocolor mode we have a limited color palette. To deal with this 235 * we can program what color is displayed for a particular pixel value. 236 * DirectColor is similar in that we can program each color field. If 237 * we have a static colormap we don't need to implement this function. 238 * 239 * Returns negative errno on error, or zero on success. 240 */ 241static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, 242 unsigned blue, unsigned transp, 243 const struct fb_info *info) 244{ 245 if (regno >= 256) /* no. of hw registers */ 246 return -EINVAL; 247 /* 248 * Program hardware... do anything you want with transp 249 */ 250 251 /* grayscale works only partially under directcolor */ 252 if (info->var.grayscale) { 253 /* grayscale = 0.30*R + 0.59*G + 0.11*B */ 254 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 255 } 256 257 /* Directcolor: 258 * var->{color}.offset contains start of bitfield 259 * var->{color}.length contains length of bitfield 260 * {hardwarespecific} contains width of DAC 261 * cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset) 262 * RAMDAC[X] is programmed to (red, green, blue) 263 * 264 * Pseudocolor: 265 * uses offset = 0 && length = DAC register width. 266 * var->{color}.offset is 0 267 * var->{color}.length contains widht of DAC 268 * cmap is not used 269 * DAC[X] is programmed to (red, green, blue) 270 * Truecolor: 271 * does not use RAMDAC (usually has 3 of them). 272 * var->{color}.offset contains start of bitfield 273 * var->{color}.length contains length of bitfield 274 * cmap is programmed to (red << red.offset) | (green << green.offset) | 275 * (blue << blue.offset) | (transp << transp.offset) 276 * RAMDAC does not exist 277 */ 278#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 279 switch (info->fix.visual) { 280 case FB_VISUAL_TRUECOLOR: 281 case FB_VISUAL_PSEUDOCOLOR: 282 red = CNVT_TOHW(red, info->var.red.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 298 /* Truecolor has hardware independent palette */ 299 if (info->fix.visual == FB_VISUAL_TRUECOLOR) { 300 u32 v; 301 302 if (regno >= 16) 303 return -EINVAL; 304 305 v = (red << info->var.red.offset) | 306 (green << info->var.green.offset) | 307 (blue << info->var.blue.offset) | 308 (transp << info->var.transp.offset); 309 310 switch (info->var.bits_per_pixel) { 311 case 8: 312 /* Yes some hand held devices have this. */ 313 ((u8*)(info->pseudo_palette))[regno] = v; 314 break; 315 case 16: 316 ((u16*)(info->pseudo_palette))[regno] = v; 317 break; 318 case 24: 319 case 32: 320 ((u32*)(info->pseudo_palette))[regno] = v; 321 break; 322 } 323 return 0; 324 } 325 /* ... */ 326 return 0; 327} 328 329/** 330 * xxxfb_pan_display - NOT a required function. Pans the display. 331 * @var: frame buffer variable screen structure 332 * @info: frame buffer structure that represents a single frame buffer 333 * 334 * Pan (or wrap, depending on the `vmode' field) the display using the 335 * `xoffset' and `yoffset' fields of the `var' structure. 336 * If the values don't fit, return -EINVAL. 337 * 338 * Returns negative errno on error, or zero on success. 339 */ 340static int xxxfb_pan_display(struct fb_var_screeninfo *var, 341 const struct fb_info *info) 342{ 343 /* ... */ 344 return 0; 345} 346 347/** 348 * xxxfb_blank - NOT a required function. Blanks the display. 349 * @blank_mode: the blank mode we want. 350 * @info: frame buffer structure that represents a single frame buffer 351 * 352 * Blank the screen if blank_mode != 0, else unblank. Return 0 if 353 * blanking succeeded, != 0 if un-/blanking failed due to e.g. a 354 * video mode which doesn't support it. Implements VESA suspend 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 * 360 * Returns negative errno on error, or zero on success. 361 * 362 */ 363static int xxxfb_blank(int blank_mode, const struct fb_info *info) 364{ 365 /* ... */ 366 return 0; 367} 368 369/* ------------ Accelerated Functions --------------------- */ 370 371/* 372 * We provide our own functions if we have hardware acceleration 373 * or non packed pixel format layouts. If we have no hardware 374 * acceleration, we can use a generic unaccelerated function. If using 375 * a pack pixel format just use the functions in cfb_*.c. Each file 376 * has one of the three different accel functions we support. 377 */ 378 379/** 380 * xxxfb_fillrect - REQUIRED function. Can use generic routines if 381 * non acclerated hardware and packed pixel based. 382 * Draws a rectangle on the screen. 383 * 384 * @info: frame buffer structure that represents a single frame buffer 385 * @region: The structure representing the rectangular region we 386 * wish to draw to. 387 * 388 * This drawing operation places/removes a retangle on the screen 389 * depending on the rastering operation with the value of color which 390 * is in the current color depth format. 391 */ 392void xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region) 393{ 394/* Meaning of struct fb_fillrect 395 * 396 * @dx: The x and y corrdinates of the upper left hand corner of the 397 * @dy: area we want to draw to. 398 * @width: How wide the rectangle is we want to draw. 399 * @height: How tall the rectangle is we want to draw. 400 * @color: The color to fill in the rectangle with. 401 * @rop: The raster operation. We can draw the rectangle with a COPY 402 * of XOR which provides erasing effect. 403 */ 404} 405 406/** 407 * xxxfb_copyarea - REQUIRED function. Can use generic routines if 408 * non acclerated hardware and packed pixel based. 409 * Copies one area of the screen to another area. 410 * 411 * @info: frame buffer structure that represents a single frame buffer 412 * @area: Structure providing the data to copy the framebuffer contents 413 * from one region to another. 414 * 415 * This drawing operation copies a rectangular area from one area of the 416 * screen to another area. 417 */ 418void xxxfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) 419{ 420/* 421 * @dx: The x and y coordinates of the upper left hand corner of the 422 * @dy: destination area on the screen. 423 * @width: How wide the rectangle is we want to copy. 424 * @height: How tall the rectangle is we want to copy. 425 * @sx: The x and y coordinates of the upper left hand corner of the 426 * @sy: source area on the screen. 427 */ 428} 429 430 431/** 432 * xxxfb_imageblit - REQUIRED function. Can use generic routines if 433 * non acclerated hardware and packed pixel based. 434 * Copies a image from system memory to the screen. 435 * 436 * @info: frame buffer structure that represents a single frame buffer 437 * @image: structure defining the image. 438 * 439 * This drawing operation draws a image on the screen. It can be a 440 * mono image (needed for font handling) or a color image (needed for 441 * tux). 442 */ 443void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image) 444{ 445/* 446 * @dx: The x and y coordinates of the upper left hand corner of the 447 * @dy: destination area to place the image on the screen. 448 * @width: How wide the image is we want to copy. 449 * @height: How tall the image is we want to copy. 450 * @fg_color: For mono bitmap images this is color data for 451 * @bg_color: the foreground and background of the image to 452 * write directly to the frmaebuffer. 453 * @depth: How many bits represent a single pixel for this image. 454 * @data: The actual data used to construct the image on the display. 455 * @cmap: The colormap used for color images. 456 */ 457} 458 459/** 460 * xxxfb_cursor - REQUIRED function. If your hardware lacks support 461 * for a cursor you can use the default cursor whose 462 * function is called soft_cursor. It will always 463 * work since it uses xxxfb_imageblit function which 464 * is required. 465 * 466 * @info: frame buffer structure that represents a single frame buffer 467 * @cursor: structure defining the cursor to draw. 468 * 469 * This operation is used to set or alter the properities of the 470 * cursor. 471 * 472 * Returns negative errno on error, or zero on success. 473 */ 474int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 475{ 476/* 477 * @set: Which fields we are altering in struct fb_cursor 478 * @enable: Disable or enable the cursor 479 * @rop: The bit operation we want to do. 480 * @mask: This is the cursor mask bitmap. 481 * @dest: A image of the area we are going to display the cursor. 482 * Used internally by the driver. 483 * @hot: The hot spot. 484 * @image: The actual data for the cursor image. 485 * 486 * NOTES ON FLAGS (cursor->set): 487 * 488 * FB_CUR_SETIMAGE - the cursor image has changed (cursor->image.data) 489 * FB_CUR_SETPOS - the cursor position has changed (cursor->image.dx|dy) 490 * FB_CUR_SETHOT - the cursor hot spot has changed (cursor->hot.dx|dy) 491 * FB_CUR_SETCMAP - the cursor colors has changed (cursor->fg_color|bg_color) 492 * FB_CUR_SETSHAPE - the cursor bitmask has changed (cursor->mask) 493 * FB_CUR_SETSIZE - the cursor size has changed (cursor->width|height) 494 * FB_CUR_SETALL - everything has changed 495 * 496 * NOTES ON ROPs (cursor->rop, Raster Operation) 497 * 498 * ROP_XOR - cursor->image.data XOR cursor->mask 499 * ROP_COPY - curosr->image.data AND cursor->mask 500 * 501 * OTHER NOTES: 502 * 503 * - fbcon only supports a 2-color cursor (cursor->image.depth = 1) 504 * - The fb_cursor structure, @cursor, _will_ always contain valid 505 * fields, whether any particular bitfields in cursor->set is set 506 * or not. 507 */ 508} 509 510/** 511 * xxxfb_rotate - NOT a required function. If your hardware 512 * supports rotation the whole screen then 513 * you would provide a hook for this. 514 * 515 * @info: frame buffer structure that represents a single frame buffer 516 * @angle: The angle we rotate the screen. 517 * 518 * This operation is used to set or alter the properities of the 519 * cursor. 520 */ 521void xxxfb_rotate(struct fb_info *info, int angle) 522{ 523} 524 525/** 526 * xxxfb_poll - NOT a required function. The purpose of this 527 * function is to provide a way for some process 528 * to wait until a specific hardware event occurs 529 * for the framebuffer device. 530 * 531 * @info: frame buffer structure that represents a single frame buffer 532 * @wait: poll table where we store process that await a event. 533 */ 534void xxxfb_poll(struct fb_info *info, poll_table *wait) 535{ 536} 537 538/** 539 * xxxfb_sync - NOT a required function. Normally the accel engine 540 * for a graphics card take a specific amount of time. 541 * Often we have to wait for the accelerator to finish 542 * its operation before we can write to the framebuffer 543 * so we can have consistent display output. 544 * 545 * @info: frame buffer structure that represents a single frame buffer 546 */ 547void xxxfb_sync(struct fb_info *info) 548{ 549} 550 551 /* 552 * Initialization 553 */ 554 555int __init xxxfb_init(void) 556{ 557 int cmap_len, retval; 558 559 /* 560 * For kernel boot options (in 'video=xxxfb:<options>' format) 561 */ 562#ifndef MODULE 563 char *option = NULL; 564 565 if (fb_get_options("xxxfb", &option)) 566 return -ENODEV; 567 xxxfb_setup(option); 568#endif 569 570 /* 571 * Here we set the screen_base to the virtual memory address 572 * for the framebuffer. Usually we obtain the resource address 573 * from the bus layer and then translate it to virtual memory 574 * space via ioremap. Consult ioport.h. 575 */ 576 info.screen_base = framebuffer_virtual_memory; 577 info.fbops = &xxxfb_ops; 578 info.fix = xxxfb_fix; 579 info.pseudo_palette = pseudo_palette; 580 581 /* 582 * Set up flags to indicate what sort of acceleration your 583 * driver can provide (pan/wrap/copyarea/etc.) and whether it 584 * is a module -- see FBINFO_* in include/linux/fb.h 585 */ 586 info.flags = FBINFO_DEFAULT; 587 info.par = current_par; 588 589 /* 590 * This should give a reasonable default video mode. The following is 591 * done when we can set a video mode. 592 */ 593 if (!mode_option) 594 mode_option = "640x480@60"; 595 596 retval = fb_find_mode(&info.var, &info, mode_option, NULL, 0, NULL, 8); 597 598 if (!retval || retval == 4) 599 return -EINVAL; 600 601 /* This has to been done !!! */ 602 fb_alloc_cmap(&info.cmap, cmap_len, 0); 603 604 /* 605 * The following is done in the case of having hardware with a static 606 * mode. If we are setting the mode ourselves we don't call this. 607 */ 608 info.var = xxxfb_var; 609 610 if (register_framebuffer(&info) < 0) 611 return -EINVAL; 612 printk(KERN_INFO "fb%d: %s frame buffer device\n", info.node, 613 info.fix.id); 614 return 0; 615} 616 617 /* 618 * Cleanup 619 */ 620 621static void __exit xxxfb_cleanup(void) 622{ 623 /* 624 * If your driver supports multiple boards, you should unregister and 625 * clean up all instances. 626 */ 627 628 unregister_framebuffer(info); 629 fb_dealloc_cmap(&info.cmap); 630 /* ... */ 631} 632 633 /* 634 * Setup 635 */ 636 637/* 638 * Only necessary if your driver takes special options, 639 * otherwise we fall back on the generic fb_setup(). 640 */ 641int __init xxxfb_setup(char *options) 642{ 643 /* Parse user speficied options (`video=xxxfb:') */ 644} 645 646/* ------------------------------------------------------------------------- */ 647 648 /* 649 * Frame buffer operations 650 */ 651 652static struct fb_ops xxxfb_ops = { 653 .owner = THIS_MODULE, 654 .fb_open = xxxfb_open, 655 .fb_read = xxxfb_read, 656 .fb_write = xxxfb_write, 657 .fb_release = xxxfb_release, 658 .fb_check_var = xxxfb_check_var, 659 .fb_set_par = xxxfb_set_par, 660 .fb_setcolreg = xxxfb_setcolreg, 661 .fb_blank = xxxfb_blank, 662 .fb_pan_display = xxxfb_pan_display, 663 .fb_fillrect = xxxfb_fillrect, /* Needed !!! */ 664 .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ 665 .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ 666 .fb_cursor = xxxfb_cursor, /* Needed !!! */ 667 .fb_rotate = xxxfb_rotate, 668 .fb_poll = xxxfb_poll, 669 .fb_sync = xxxfb_sync, 670 .fb_ioctl = xxxfb_ioctl, 671 .fb_mmap = xxxfb_mmap, 672}; 673 674/* ------------------------------------------------------------------------- */ 675 676 677 /* 678 * Modularization 679 */ 680 681module_init(xxxfb_init); 682module_exit(xxxfb_cleanup); 683 684MODULE_LICENSE("GPL");