iwlwifi: adding pci device ids to iwl_hw_card_ids
[linux-2.6] / drivers / video / gbefb.c
1 /*
2  *  SGI GBE frame buffer driver
3  *
4  *  Copyright (C) 1999 Silicon Graphics, Inc. - Jeffrey Newquist
5  *  Copyright (C) 2002 Vivien Chappelier <vivien.chappelier@linux-mips.org>
6  *
7  *  This file is subject to the terms and conditions of the GNU General Public
8  *  License. See the file COPYING in the main directory of this archive for
9  *  more details.
10  */
11
12 #include <linux/delay.h>
13 #include <linux/platform_device.h>
14 #include <linux/dma-mapping.h>
15 #include <linux/errno.h>
16 #include <linux/fb.h>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/mm.h>
21 #include <linux/module.h>
22
23 #ifdef CONFIG_X86
24 #include <asm/mtrr.h>
25 #endif
26 #ifdef CONFIG_MIPS
27 #include <asm/addrspace.h>
28 #endif
29 #include <asm/byteorder.h>
30 #include <asm/io.h>
31 #include <asm/tlbflush.h>
32
33 #include <video/gbe.h>
34
35 static struct sgi_gbe *gbe;
36
37 struct gbefb_par {
38         struct fb_var_screeninfo var;
39         struct gbe_timing_info timing;
40         int valid;
41 };
42
43 #ifdef CONFIG_SGI_IP32
44 #define GBE_BASE        0x16000000 /* SGI O2 */
45 #endif
46
47 #ifdef CONFIG_X86_VISWS
48 #define GBE_BASE        0xd0000000 /* SGI Visual Workstation */
49 #endif
50
51 /* macro for fastest write-though access to the framebuffer */
52 #ifdef CONFIG_MIPS
53 #ifdef CONFIG_CPU_R10000
54 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
55 #else
56 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
57 #endif
58 #endif
59 #ifdef CONFIG_X86
60 #define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)
61 #endif
62
63 /*
64  *  RAM we reserve for the frame buffer. This defines the maximum screen
65  *  size
66  */
67 #if CONFIG_FB_GBE_MEM > 8
68 #error GBE Framebuffer cannot use more than 8MB of memory
69 #endif
70
71 #define TILE_SHIFT 16
72 #define TILE_SIZE (1 << TILE_SHIFT)
73 #define TILE_MASK (TILE_SIZE - 1)
74
75 static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
76 static void *gbe_mem;
77 static dma_addr_t gbe_dma_addr;
78 unsigned long gbe_mem_phys;
79
80 static struct {
81         uint16_t *cpu;
82         dma_addr_t dma;
83 } gbe_tiles;
84
85 static int gbe_revision;
86
87 static int ypan, ywrap;
88
89 static uint32_t pseudo_palette[16];
90
91 static char *mode_option __initdata = NULL;
92
93 /* default CRT mode */
94 static struct fb_var_screeninfo default_var_CRT __initdata = {
95         /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
96         .xres           = 640,
97         .yres           = 480,
98         .xres_virtual   = 640,
99         .yres_virtual   = 480,
100         .xoffset        = 0,
101         .yoffset        = 0,
102         .bits_per_pixel = 8,
103         .grayscale      = 0,
104         .red            = { 0, 8, 0 },
105         .green          = { 0, 8, 0 },
106         .blue           = { 0, 8, 0 },
107         .transp         = { 0, 0, 0 },
108         .nonstd         = 0,
109         .activate       = 0,
110         .height         = -1,
111         .width          = -1,
112         .accel_flags    = 0,
113         .pixclock       = 39722,        /* picoseconds */
114         .left_margin    = 48,
115         .right_margin   = 16,
116         .upper_margin   = 33,
117         .lower_margin   = 10,
118         .hsync_len      = 96,
119         .vsync_len      = 2,
120         .sync           = 0,
121         .vmode          = FB_VMODE_NONINTERLACED,
122 };
123
124 /* default LCD mode */
125 static struct fb_var_screeninfo default_var_LCD __initdata = {
126         /* 1600x1024, 8 bpp */
127         .xres           = 1600,
128         .yres           = 1024,
129         .xres_virtual   = 1600,
130         .yres_virtual   = 1024,
131         .xoffset        = 0,
132         .yoffset        = 0,
133         .bits_per_pixel = 8,
134         .grayscale      = 0,
135         .red            = { 0, 8, 0 },
136         .green          = { 0, 8, 0 },
137         .blue           = { 0, 8, 0 },
138         .transp         = { 0, 0, 0 },
139         .nonstd         = 0,
140         .activate       = 0,
141         .height         = -1,
142         .width          = -1,
143         .accel_flags    = 0,
144         .pixclock       = 9353,
145         .left_margin    = 20,
146         .right_margin   = 30,
147         .upper_margin   = 37,
148         .lower_margin   = 3,
149         .hsync_len      = 20,
150         .vsync_len      = 3,
151         .sync           = 0,
152         .vmode          = FB_VMODE_NONINTERLACED
153 };
154
155 /* default modedb mode */
156 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
157 static struct fb_videomode default_mode_CRT __initdata = {
158         .refresh        = 60,
159         .xres           = 640,
160         .yres           = 480,
161         .pixclock       = 39722,
162         .left_margin    = 48,
163         .right_margin   = 16,
164         .upper_margin   = 33,
165         .lower_margin   = 10,
166         .hsync_len      = 96,
167         .vsync_len      = 2,
168         .sync           = 0,
169         .vmode          = FB_VMODE_NONINTERLACED,
170 };
171 /* 1600x1024 SGI flatpanel 1600sw */
172 static struct fb_videomode default_mode_LCD __initdata = {
173         /* 1600x1024, 8 bpp */
174         .xres           = 1600,
175         .yres           = 1024,
176         .pixclock       = 9353,
177         .left_margin    = 20,
178         .right_margin   = 30,
179         .upper_margin   = 37,
180         .lower_margin   = 3,
181         .hsync_len      = 20,
182         .vsync_len      = 3,
183         .vmode          = FB_VMODE_NONINTERLACED,
184 };
185
186 struct fb_videomode *default_mode __initdata = &default_mode_CRT;
187 struct fb_var_screeninfo *default_var __initdata = &default_var_CRT;
188
189 static int flat_panel_enabled = 0;
190
191 static void gbe_reset(void)
192 {
193         /* Turn on dotclock PLL */
194         gbe->ctrlstat = 0x300aa000;
195 }
196
197
198 /*
199  * Function:    gbe_turn_off
200  * Parameters:  (None)
201  * Description: This should turn off the monitor and gbe.  This is used
202  *              when switching between the serial console and the graphics
203  *              console.
204  */
205
206 void gbe_turn_off(void)
207 {
208         int i;
209         unsigned int val, x, y, vpixen_off;
210
211         /* check if pixel counter is on */
212         val = gbe->vt_xy;
213         if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
214                 return;
215
216         /* turn off DMA */
217         val = gbe->ovr_control;
218         SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);
219         gbe->ovr_control = val;
220         udelay(1000);
221         val = gbe->frm_control;
222         SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
223         gbe->frm_control = val;
224         udelay(1000);
225         val = gbe->did_control;
226         SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);
227         gbe->did_control = val;
228         udelay(1000);
229
230         /* We have to wait through two vertical retrace periods before
231          * the pixel DMA is turned off for sure. */
232         for (i = 0; i < 10000; i++) {
233                 val = gbe->frm_inhwctrl;
234                 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {
235                         udelay(10);
236                 } else {
237                         val = gbe->ovr_inhwctrl;
238                         if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {
239                                 udelay(10);
240                         } else {
241                                 val = gbe->did_inhwctrl;
242                                 if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {
243                                         udelay(10);
244                                 } else
245                                         break;
246                         }
247                 }
248         }
249         if (i == 10000)
250                 printk(KERN_ERR "gbefb: turn off DMA timed out\n");
251
252         /* wait for vpixen_off */
253         val = gbe->vt_vpixen;
254         vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);
255
256         for (i = 0; i < 100000; i++) {
257                 val = gbe->vt_xy;
258                 x = GET_GBE_FIELD(VT_XY, X, val);
259                 y = GET_GBE_FIELD(VT_XY, Y, val);
260                 if (y < vpixen_off)
261                         break;
262                 udelay(1);
263         }
264         if (i == 100000)
265                 printk(KERN_ERR
266                        "gbefb: wait for vpixen_off timed out\n");
267         for (i = 0; i < 10000; i++) {
268                 val = gbe->vt_xy;
269                 x = GET_GBE_FIELD(VT_XY, X, val);
270                 y = GET_GBE_FIELD(VT_XY, Y, val);
271                 if (y > vpixen_off)
272                         break;
273                 udelay(1);
274         }
275         if (i == 10000)
276                 printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");
277
278         /* turn off pixel counter */
279         val = 0;
280         SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
281         gbe->vt_xy = val;
282         udelay(10000);
283         for (i = 0; i < 10000; i++) {
284                 val = gbe->vt_xy;
285                 if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
286                         udelay(10);
287                 else
288                         break;
289         }
290         if (i == 10000)
291                 printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");
292
293         /* turn off dot clock */
294         val = gbe->dotclock;
295         SET_GBE_FIELD(DOTCLK, RUN, val, 0);
296         gbe->dotclock = val;
297         udelay(10000);
298         for (i = 0; i < 10000; i++) {
299                 val = gbe->dotclock;
300                 if (GET_GBE_FIELD(DOTCLK, RUN, val))
301                         udelay(10);
302                 else
303                         break;
304         }
305         if (i == 10000)
306                 printk(KERN_ERR "gbefb: turn off dotclock timed out\n");
307
308         /* reset the frame DMA FIFO */
309         val = gbe->frm_size_tile;
310         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);
311         gbe->frm_size_tile = val;
312         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);
313         gbe->frm_size_tile = val;
314 }
315
316 static void gbe_turn_on(void)
317 {
318         unsigned int val, i;
319
320         /*
321          * Check if pixel counter is off, for unknown reason this
322          * code hangs Visual Workstations
323          */
324         if (gbe_revision < 2) {
325                 val = gbe->vt_xy;
326                 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)
327                         return;
328         }
329
330         /* turn on dot clock */
331         val = gbe->dotclock;
332         SET_GBE_FIELD(DOTCLK, RUN, val, 1);
333         gbe->dotclock = val;
334         udelay(10000);
335         for (i = 0; i < 10000; i++) {
336                 val = gbe->dotclock;
337                 if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
338                         udelay(10);
339                 else
340                         break;
341         }
342         if (i == 10000)
343                 printk(KERN_ERR "gbefb: turn on dotclock timed out\n");
344
345         /* turn on pixel counter */
346         val = 0;
347         SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
348         gbe->vt_xy = val;
349         udelay(10000);
350         for (i = 0; i < 10000; i++) {
351                 val = gbe->vt_xy;
352                 if (GET_GBE_FIELD(VT_XY, FREEZE, val))
353                         udelay(10);
354                 else
355                         break;
356         }
357         if (i == 10000)
358                 printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");
359
360         /* turn on DMA */
361         val = gbe->frm_control;
362         SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);
363         gbe->frm_control = val;
364         udelay(1000);
365         for (i = 0; i < 10000; i++) {
366                 val = gbe->frm_inhwctrl;
367                 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)
368                         udelay(10);
369                 else
370                         break;
371         }
372         if (i == 10000)
373                 printk(KERN_ERR "gbefb: turn on DMA timed out\n");
374 }
375
376 /*
377  *  Blank the display.
378  */
379 static int gbefb_blank(int blank, struct fb_info *info)
380 {
381         /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
382         switch (blank) {
383         case FB_BLANK_UNBLANK:          /* unblank */
384                 gbe_turn_on();
385                 break;
386
387         case FB_BLANK_NORMAL:           /* blank */
388                 gbe_turn_off();
389                 break;
390
391         default:
392                 /* Nothing */
393                 break;
394         }
395         return 0;
396 }
397
398 /*
399  *  Setup flatpanel related registers.
400  */
401 static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
402 {
403         int fp_wid, fp_hgt, fp_vbs, fp_vbe;
404         u32 outputVal = 0;
405
406         SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
407                 (timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
408         SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
409                 (timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
410         gbe->vt_flags = outputVal;
411
412         /* Turn on the flat panel */
413         fp_wid = 1600;
414         fp_hgt = 1024;
415         fp_vbs = 0;
416         fp_vbe = 1600;
417         timing->pll_m = 4;
418         timing->pll_n = 1;
419         timing->pll_p = 0;
420
421         outputVal = 0;
422         SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
423         SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
424         gbe->fp_de = outputVal;
425         outputVal = 0;
426         SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
427         gbe->fp_hdrv = outputVal;
428         outputVal = 0;
429         SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
430         SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
431         gbe->fp_vdrv = outputVal;
432 }
433
434 struct gbe_pll_info {
435         int clock_rate;
436         int fvco_min;
437         int fvco_max;
438 };
439
440 static struct gbe_pll_info gbe_pll_table[2] = {
441         { 20, 80, 220 },
442         { 27, 80, 220 },
443 };
444
445 static int compute_gbe_timing(struct fb_var_screeninfo *var,
446                               struct gbe_timing_info *timing)
447 {
448         int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
449         int pixclock;
450         struct gbe_pll_info *gbe_pll;
451
452         if (gbe_revision < 2)
453                 gbe_pll = &gbe_pll_table[0];
454         else
455                 gbe_pll = &gbe_pll_table[1];
456
457         /* Determine valid resolution and timing
458          * GBE crystal runs at 20Mhz or 27Mhz
459          * pll_m, pll_n, pll_p define the following frequencies
460          * fvco = pll_m * 20Mhz / pll_n
461          * fout = fvco / (2**pll_p) */
462         best_error = 1000000000;
463         best_n = best_m = best_p = 0;
464         for (pll_p = 0; pll_p < 4; pll_p++)
465                 for (pll_m = 1; pll_m < 256; pll_m++)
466                         for (pll_n = 1; pll_n < 64; pll_n++) {
467                                 pixclock = (1000000 / gbe_pll->clock_rate) *
468                                                 (pll_n << pll_p) / pll_m;
469
470                                 error = var->pixclock - pixclock;
471
472                                 if (error < 0)
473                                         error = -error;
474
475                                 if (error < best_error &&
476                                     pll_m / pll_n >
477                                     gbe_pll->fvco_min / gbe_pll->clock_rate &&
478                                     pll_m / pll_n <
479                                     gbe_pll->fvco_max / gbe_pll->clock_rate) {
480                                         best_error = error;
481                                         best_m = pll_m;
482                                         best_n = pll_n;
483                                         best_p = pll_p;
484                                 }
485                         }
486
487         if (!best_n || !best_m)
488                 return -EINVAL; /* Resolution to high */
489
490         pixclock = (1000000 / gbe_pll->clock_rate) *
491                 (best_n << best_p) / best_m;
492
493         /* set video timing information */
494         if (timing) {
495                 timing->width = var->xres;
496                 timing->height = var->yres;
497                 timing->pll_m = best_m;
498                 timing->pll_n = best_n;
499                 timing->pll_p = best_p;
500                 timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
501                         (timing->pll_n << timing->pll_p);
502                 timing->htotal = var->left_margin + var->xres +
503                                 var->right_margin + var->hsync_len;
504                 timing->vtotal = var->upper_margin + var->yres +
505                                 var->lower_margin + var->vsync_len;
506                 timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
507                                 1000 / timing->vtotal;
508                 timing->hblank_start = var->xres;
509                 timing->vblank_start = var->yres;
510                 timing->hblank_end = timing->htotal;
511                 timing->hsync_start = var->xres + var->right_margin + 1;
512                 timing->hsync_end = timing->hsync_start + var->hsync_len;
513                 timing->vblank_end = timing->vtotal;
514                 timing->vsync_start = var->yres + var->lower_margin + 1;
515                 timing->vsync_end = timing->vsync_start + var->vsync_len;
516         }
517
518         return pixclock;
519 }
520
521 static void gbe_set_timing_info(struct gbe_timing_info *timing)
522 {
523         int temp;
524         unsigned int val;
525
526         /* setup dot clock PLL */
527         val = 0;
528         SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
529         SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
530         SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
531         SET_GBE_FIELD(DOTCLK, RUN, val, 0);     /* do not start yet */
532         gbe->dotclock = val;
533         udelay(10000);
534
535         /* setup pixel counter */
536         val = 0;
537         SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
538         SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
539         gbe->vt_xymax = val;
540
541         /* setup video timing signals */
542         val = 0;
543         SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
544         SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
545         gbe->vt_vsync = val;
546         val = 0;
547         SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
548         SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
549         gbe->vt_hsync = val;
550         val = 0;
551         SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
552         SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
553         gbe->vt_vblank = val;
554         val = 0;
555         SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
556                       timing->hblank_start - 5);
557         SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
558                       timing->hblank_end - 3);
559         gbe->vt_hblank = val;
560
561         /* setup internal timing signals */
562         val = 0;
563         SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
564         SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
565         gbe->vt_vcmap = val;
566         val = 0;
567         SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
568         SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
569         gbe->vt_hcmap = val;
570
571         val = 0;
572         temp = timing->vblank_start - timing->vblank_end - 1;
573         if (temp > 0)
574                 temp = -temp;
575
576         if (flat_panel_enabled)
577                 gbefb_setup_flatpanel(timing);
578
579         SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
580         if (timing->hblank_end >= 20)
581                 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
582                               timing->hblank_end - 20);
583         else
584                 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
585                               timing->htotal - (20 - timing->hblank_end));
586         gbe->did_start_xy = val;
587
588         val = 0;
589         SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
590         if (timing->hblank_end >= GBE_CRS_MAGIC)
591                 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
592                               timing->hblank_end - GBE_CRS_MAGIC);
593         else
594                 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
595                               timing->htotal - (GBE_CRS_MAGIC -
596                                                 timing->hblank_end));
597         gbe->crs_start_xy = val;
598
599         val = 0;
600         SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
601         SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
602         gbe->vc_start_xy = val;
603
604         val = 0;
605         temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
606         if (temp < 0)
607                 temp += timing->htotal; /* allow blank to wrap around */
608
609         SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
610         SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
611                       ((temp + timing->width -
612                         GBE_PIXEN_MAGIC_OFF) % timing->htotal));
613         gbe->vt_hpixen = val;
614
615         val = 0;
616         SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
617         SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
618         gbe->vt_vpixen = val;
619
620         /* turn off sync on green */
621         val = 0;
622         SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
623         gbe->vt_flags = val;
624 }
625
626 /*
627  *  Set the hardware according to 'par'.
628  */
629
630 static int gbefb_set_par(struct fb_info *info)
631 {
632         int i;
633         unsigned int val;
634         int wholeTilesX, partTilesX, maxPixelsPerTileX;
635         int height_pix;
636         int xpmax, ypmax;       /* Monitor resolution */
637         int bytesPerPixel;      /* Bytes per pixel */
638         struct gbefb_par *par = (struct gbefb_par *) info->par;
639
640         compute_gbe_timing(&info->var, &par->timing);
641
642         bytesPerPixel = info->var.bits_per_pixel / 8;
643         info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
644         xpmax = par->timing.width;
645         ypmax = par->timing.height;
646
647         /* turn off GBE */
648         gbe_turn_off();
649
650         /* set timing info */
651         gbe_set_timing_info(&par->timing);
652
653         /* initialize DIDs */
654         val = 0;
655         switch (bytesPerPixel) {
656         case 1:
657                 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
658                 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
659                 break;
660         case 2:
661                 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
662                 info->fix.visual = FB_VISUAL_TRUECOLOR;
663                 break;
664         case 4:
665                 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
666                 info->fix.visual = FB_VISUAL_TRUECOLOR;
667                 break;
668         }
669         SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
670
671         for (i = 0; i < 32; i++)
672                 gbe->mode_regs[i] = val;
673
674         /* Initialize interrupts */
675         gbe->vt_intr01 = 0xffffffff;
676         gbe->vt_intr23 = 0xffffffff;
677
678         /* HACK:
679            The GBE hardware uses a tiled memory to screen mapping. Tiles are
680            blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
681            16bit and 32 bit modes (64 kB). They cover the screen with partial
682            tiles on the right and/or bottom of the screen if needed.
683            For exemple in 640x480 8 bit mode the mapping is:
684
685            <-------- 640 ----->
686            <---- 512 ----><128|384 offscreen>
687            ^  ^
688            | 128    [tile 0]        [tile 1]
689            |  v
690            ^
691            4 128    [tile 2]        [tile 3]
692            8  v
693            0  ^
694            128    [tile 4]        [tile 5]
695            |  v
696            |  ^
697            v  96    [tile 6]        [tile 7]
698            32 offscreen
699
700            Tiles have the advantage that they can be allocated individually in
701            memory. However, this mapping is not linear at all, which is not
702            really convienient. In order to support linear addressing, the GBE
703            DMA hardware is fooled into thinking the screen is only one tile
704            large and but has a greater height, so that the DMA transfer covers
705            the same region.
706            Tiles are still allocated as independent chunks of 64KB of
707            continuous physical memory and remapped so that the kernel sees the
708            framebuffer as a continuous virtual memory. The GBE tile table is
709            set up so that each tile references one of these 64k blocks:
710
711            GBE -> tile list    framebuffer           TLB   <------------ CPU
712                   [ tile 0 ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     ^
713                      ...           ...              ...       linear virtual FB
714                   [ tile n ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     v
715
716
717            The GBE hardware is then told that the buffer is 512*tweaked_height,
718            with tweaked_height = real_width*real_height/pixels_per_tile.
719            Thus the GBE hardware will scan the first tile, filing the first 64k
720            covered region of the screen, and then will proceed to the next
721            tile, until the whole screen is covered.
722
723            Here is what would happen at 640x480 8bit:
724
725            normal tiling               linear
726            ^   11111111111111112222    11111111111111111111  ^
727            128 11111111111111112222    11111111111111111111 102 lines
728                11111111111111112222    11111111111111111111  v
729            V   11111111111111112222    11111111222222222222
730                33333333333333334444    22222222222222222222
731                33333333333333334444    22222222222222222222
732                <      512     >        <  256 >               102*640+256 = 64k
733
734            NOTE: The only mode for which this is not working is 800x600 8bit,
735            as 800*600/512 = 937.5 which is not integer and thus causes
736            flickering.
737            I guess this is not so important as one can use 640x480 8bit or
738            800x600 16bit anyway.
739          */
740
741         /* Tell gbe about the tiles table location */
742         /* tile_ptr -> [ tile 1 ] -> FB mem */
743         /*             [ tile 2 ] -> FB mem */
744         /*               ...                */
745         val = 0;
746         SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
747         SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0); /* do not start */
748         SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
749         gbe->frm_control = val;
750
751         maxPixelsPerTileX = 512 / bytesPerPixel;
752         wholeTilesX = 1;
753         partTilesX = 0;
754
755         /* Initialize the framebuffer */
756         val = 0;
757         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
758         SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
759
760         switch (bytesPerPixel) {
761         case 1:
762                 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
763                               GBE_FRM_DEPTH_8);
764                 break;
765         case 2:
766                 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
767                               GBE_FRM_DEPTH_16);
768                 break;
769         case 4:
770                 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
771                               GBE_FRM_DEPTH_32);
772                 break;
773         }
774         gbe->frm_size_tile = val;
775
776         /* compute tweaked height */
777         height_pix = xpmax * ypmax / maxPixelsPerTileX;
778
779         val = 0;
780         SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
781         gbe->frm_size_pixel = val;
782
783         /* turn off DID and overlay DMA */
784         gbe->did_control = 0;
785         gbe->ovr_width_tile = 0;
786
787         /* Turn off mouse cursor */
788         gbe->crs_ctl = 0;
789
790         /* Turn on GBE */
791         gbe_turn_on();
792
793         /* Initialize the gamma map */
794         udelay(10);
795         for (i = 0; i < 256; i++)
796                 gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
797
798         /* Initialize the color map */
799         for (i = 0; i < 256; i++) {
800                 int j;
801
802                 for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
803                         udelay(10);
804                 if (j == 1000)
805                         printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
806
807                 gbe->cmap[i] = (i << 8) | (i << 16) | (i << 24);
808         }
809
810         return 0;
811 }
812
813 static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
814                              struct fb_var_screeninfo *var)
815 {
816         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
817         strcpy(fix->id, "SGI GBE");
818         fix->smem_start = (unsigned long) gbe_mem;
819         fix->smem_len = gbe_mem_size;
820         fix->type = FB_TYPE_PACKED_PIXELS;
821         fix->type_aux = 0;
822         fix->accel = FB_ACCEL_NONE;
823         switch (var->bits_per_pixel) {
824         case 8:
825                 fix->visual = FB_VISUAL_PSEUDOCOLOR;
826                 break;
827         default:
828                 fix->visual = FB_VISUAL_TRUECOLOR;
829                 break;
830         }
831         fix->ywrapstep = 0;
832         fix->xpanstep = 0;
833         fix->ypanstep = 0;
834         fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
835         fix->mmio_start = GBE_BASE;
836         fix->mmio_len = sizeof(struct sgi_gbe);
837 }
838
839 /*
840  *  Set a single color register. The values supplied are already
841  *  rounded down to the hardware's capabilities (according to the
842  *  entries in the var structure). Return != 0 for invalid regno.
843  */
844
845 static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
846                              unsigned blue, unsigned transp,
847                              struct fb_info *info)
848 {
849         int i;
850
851         if (regno > 255)
852                 return 1;
853         red >>= 8;
854         green >>= 8;
855         blue >>= 8;
856
857         if (info->var.bits_per_pixel <= 8) {
858                 /* wait for the color map FIFO to have a free entry */
859                 for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
860                         udelay(10);
861                 if (i == 1000) {
862                         printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
863                         return 1;
864                 }
865                 gbe->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
866         } else if (regno < 16) {
867                 switch (info->var.bits_per_pixel) {
868                 case 15:
869                 case 16:
870                         red >>= 3;
871                         green >>= 3;
872                         blue >>= 3;
873                         pseudo_palette[regno] =
874                                 (red << info->var.red.offset) |
875                                 (green << info->var.green.offset) |
876                                 (blue << info->var.blue.offset);
877                         break;
878                 case 32:
879                         pseudo_palette[regno] =
880                                 (red << info->var.red.offset) |
881                                 (green << info->var.green.offset) |
882                                 (blue << info->var.blue.offset);
883                         break;
884                 }
885         }
886
887         return 0;
888 }
889
890 /*
891  *  Check video mode validity, eventually modify var to best match.
892  */
893 static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
894 {
895         unsigned int line_length;
896         struct gbe_timing_info timing;
897
898         /* Limit bpp to 8, 16, and 32 */
899         if (var->bits_per_pixel <= 8)
900                 var->bits_per_pixel = 8;
901         else if (var->bits_per_pixel <= 16)
902                 var->bits_per_pixel = 16;
903         else if (var->bits_per_pixel <= 32)
904                 var->bits_per_pixel = 32;
905         else
906                 return -EINVAL;
907
908         /* Check the mode can be mapped linearly with the tile table trick. */
909         /* This requires width x height x bytes/pixel be a multiple of 512 */
910         if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
911                 return -EINVAL;
912
913         var->grayscale = 0;     /* No grayscale for now */
914
915         if ((var->pixclock = compute_gbe_timing(var, &timing)) < 0)
916                 return(-EINVAL);
917
918         /* Adjust virtual resolution, if necessary */
919         if (var->xres > var->xres_virtual || (!ywrap && !ypan))
920                 var->xres_virtual = var->xres;
921         if (var->yres > var->yres_virtual || (!ywrap && !ypan))
922                 var->yres_virtual = var->yres;
923
924         if (var->vmode & FB_VMODE_CONUPDATE) {
925                 var->vmode |= FB_VMODE_YWRAP;
926                 var->xoffset = info->var.xoffset;
927                 var->yoffset = info->var.yoffset;
928         }
929
930         /* No grayscale for now */
931         var->grayscale = 0;
932
933         /* Memory limit */
934         line_length = var->xres_virtual * var->bits_per_pixel / 8;
935         if (line_length * var->yres_virtual > gbe_mem_size)
936                 return -ENOMEM; /* Virtual resolution too high */
937
938         switch (var->bits_per_pixel) {
939         case 8:
940                 var->red.offset = 0;
941                 var->red.length = 8;
942                 var->green.offset = 0;
943                 var->green.length = 8;
944                 var->blue.offset = 0;
945                 var->blue.length = 8;
946                 var->transp.offset = 0;
947                 var->transp.length = 0;
948                 break;
949         case 16:                /* RGB 1555 */
950                 var->red.offset = 10;
951                 var->red.length = 5;
952                 var->green.offset = 5;
953                 var->green.length = 5;
954                 var->blue.offset = 0;
955                 var->blue.length = 5;
956                 var->transp.offset = 0;
957                 var->transp.length = 0;
958                 break;
959         case 32:                /* RGB 8888 */
960                 var->red.offset = 24;
961                 var->red.length = 8;
962                 var->green.offset = 16;
963                 var->green.length = 8;
964                 var->blue.offset = 8;
965                 var->blue.length = 8;
966                 var->transp.offset = 0;
967                 var->transp.length = 8;
968                 break;
969         }
970         var->red.msb_right = 0;
971         var->green.msb_right = 0;
972         var->blue.msb_right = 0;
973         var->transp.msb_right = 0;
974
975         var->left_margin = timing.htotal - timing.hsync_end;
976         var->right_margin = timing.hsync_start - timing.width;
977         var->upper_margin = timing.vtotal - timing.vsync_end;
978         var->lower_margin = timing.vsync_start - timing.height;
979         var->hsync_len = timing.hsync_end - timing.hsync_start;
980         var->vsync_len = timing.vsync_end - timing.vsync_start;
981
982         return 0;
983 }
984
985 static int gbefb_mmap(struct fb_info *info,
986                         struct vm_area_struct *vma)
987 {
988         unsigned long size = vma->vm_end - vma->vm_start;
989         unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
990         unsigned long addr;
991         unsigned long phys_addr, phys_size;
992         u16 *tile;
993
994         /* check range */
995         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
996                 return -EINVAL;
997         if (offset + size > gbe_mem_size)
998                 return -EINVAL;
999
1000         /* remap using the fastest write-through mode on architecture */
1001         /* try not polluting the cache when possible */
1002         pgprot_val(vma->vm_page_prot) =
1003                 pgprot_fb(pgprot_val(vma->vm_page_prot));
1004
1005         vma->vm_flags |= VM_IO | VM_RESERVED;
1006
1007         /* look for the starting tile */
1008         tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1009         addr = vma->vm_start;
1010         offset &= TILE_MASK;
1011
1012         /* remap each tile separately */
1013         do {
1014                 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1015                 if ((offset + size) < TILE_SIZE)
1016                         phys_size = size;
1017                 else
1018                         phys_size = TILE_SIZE - offset;
1019
1020                 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1021                                                 phys_size, vma->vm_page_prot))
1022                         return -EAGAIN;
1023
1024                 offset = 0;
1025                 size -= phys_size;
1026                 addr += phys_size;
1027                 tile++;
1028         } while (size);
1029
1030         return 0;
1031 }
1032
1033 static struct fb_ops gbefb_ops = {
1034         .owner          = THIS_MODULE,
1035         .fb_check_var   = gbefb_check_var,
1036         .fb_set_par     = gbefb_set_par,
1037         .fb_setcolreg   = gbefb_setcolreg,
1038         .fb_mmap        = gbefb_mmap,
1039         .fb_blank       = gbefb_blank,
1040         .fb_fillrect    = cfb_fillrect,
1041         .fb_copyarea    = cfb_copyarea,
1042         .fb_imageblit   = cfb_imageblit,
1043 };
1044
1045 /*
1046  * sysfs
1047  */
1048
1049 static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1050 {
1051         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1052 }
1053
1054 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1055
1056 static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1057 {
1058         return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1059 }
1060
1061 static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1062
1063 static void __devexit gbefb_remove_sysfs(struct device *dev)
1064 {
1065         device_remove_file(dev, &dev_attr_size);
1066         device_remove_file(dev, &dev_attr_revision);
1067 }
1068
1069 static void gbefb_create_sysfs(struct device *dev)
1070 {
1071         device_create_file(dev, &dev_attr_size);
1072         device_create_file(dev, &dev_attr_revision);
1073 }
1074
1075 /*
1076  * Initialization
1077  */
1078
1079 int __init gbefb_setup(char *options)
1080 {
1081         char *this_opt;
1082
1083         if (!options || !*options)
1084                 return 0;
1085
1086         while ((this_opt = strsep(&options, ",")) != NULL) {
1087                 if (!strncmp(this_opt, "monitor:", 8)) {
1088                         if (!strncmp(this_opt + 8, "crt", 3)) {
1089                                 flat_panel_enabled = 0;
1090                                 default_var = &default_var_CRT;
1091                                 default_mode = &default_mode_CRT;
1092                         } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1093                                    !strncmp(this_opt + 8, "lcd", 3)) {
1094                                 flat_panel_enabled = 1;
1095                                 default_var = &default_var_LCD;
1096                                 default_mode = &default_mode_LCD;
1097                         }
1098                 } else if (!strncmp(this_opt, "mem:", 4)) {
1099                         gbe_mem_size = memparse(this_opt + 4, &this_opt);
1100                         if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1101                                 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1102                         if (gbe_mem_size < TILE_SIZE)
1103                                 gbe_mem_size = TILE_SIZE;
1104                 } else
1105                         mode_option = this_opt;
1106         }
1107         return 0;
1108 }
1109
1110 static int __init gbefb_probe(struct platform_device *p_dev)
1111 {
1112         int i, ret = 0;
1113         struct fb_info *info;
1114         struct gbefb_par *par;
1115 #ifndef MODULE
1116         char *options = NULL;
1117 #endif
1118
1119         info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1120         if (!info)
1121                 return -ENOMEM;
1122
1123 #ifndef MODULE
1124         if (fb_get_options("gbefb", &options))
1125                 return -ENODEV;
1126         gbefb_setup(options);
1127 #endif
1128
1129         if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1130                 printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1131                 ret = -EBUSY;
1132                 goto out_release_framebuffer;
1133         }
1134
1135         gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
1136         if (!gbe) {
1137                 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1138                 ret = -ENXIO;
1139                 goto out_release_mem_region;
1140         }
1141         gbe_revision = gbe->ctrlstat & 15;
1142
1143         gbe_tiles.cpu =
1144                 dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1145                                    &gbe_tiles.dma, GFP_KERNEL);
1146         if (!gbe_tiles.cpu) {
1147                 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1148                 ret = -ENOMEM;
1149                 goto out_unmap;
1150         }
1151
1152         if (gbe_mem_phys) {
1153                 /* memory was allocated at boot time */
1154                 gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
1155                 if (!gbe_mem) {
1156                         printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1157                         ret = -ENOMEM;
1158                         goto out_tiles_free;
1159                 }
1160
1161                 gbe_dma_addr = 0;
1162         } else {
1163                 /* try to allocate memory with the classical allocator
1164                  * this has high chance to fail on low memory machines */
1165                 gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1166                                              GFP_KERNEL);
1167                 if (!gbe_mem) {
1168                         printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1169                         ret = -ENOMEM;
1170                         goto out_tiles_free;
1171                 }
1172
1173                 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1174         }
1175
1176 #ifdef CONFIG_X86
1177         mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1178 #endif
1179
1180         /* map framebuffer memory into tiles table */
1181         for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1182                 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1183
1184         info->fbops = &gbefb_ops;
1185         info->pseudo_palette = pseudo_palette;
1186         info->flags = FBINFO_DEFAULT;
1187         info->screen_base = gbe_mem;
1188         fb_alloc_cmap(&info->cmap, 256, 0);
1189
1190         /* reset GBE */
1191         gbe_reset();
1192
1193         par = info->par;
1194         /* turn on default video mode */
1195         if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1196                          default_mode, 8) == 0)
1197                 par->var = *default_var;
1198         info->var = par->var;
1199         gbefb_check_var(&par->var, info);
1200         gbefb_encode_fix(&info->fix, &info->var);
1201
1202         if (register_framebuffer(info) < 0) {
1203                 printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1204                 ret = -ENXIO;
1205                 goto out_gbe_unmap;
1206         }
1207
1208         platform_set_drvdata(p_dev, info);
1209         gbefb_create_sysfs(&p_dev->dev);
1210
1211         printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1212                info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1213                gbe_mem_size >> 10);
1214
1215         return 0;
1216
1217 out_gbe_unmap:
1218         if (gbe_dma_addr)
1219                 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1220         else
1221                 iounmap(gbe_mem);
1222 out_tiles_free:
1223         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1224                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1225 out_unmap:
1226         iounmap(gbe);
1227 out_release_mem_region:
1228         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1229 out_release_framebuffer:
1230         framebuffer_release(info);
1231
1232         return ret;
1233 }
1234
1235 static int __devexit gbefb_remove(struct platform_device* p_dev)
1236 {
1237         struct fb_info *info = platform_get_drvdata(p_dev);
1238
1239         unregister_framebuffer(info);
1240         gbe_turn_off();
1241         if (gbe_dma_addr)
1242                 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1243         else
1244                 iounmap(gbe_mem);
1245         dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1246                           (void *)gbe_tiles.cpu, gbe_tiles.dma);
1247         release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1248         iounmap(gbe);
1249         gbefb_remove_sysfs(&p_dev->dev);
1250         framebuffer_release(info);
1251
1252         return 0;
1253 }
1254
1255 static struct platform_driver gbefb_driver = {
1256         .probe = gbefb_probe,
1257         .remove = __devexit_p(gbefb_remove),
1258         .driver = {
1259                 .name = "gbefb",
1260         },
1261 };
1262
1263 static struct platform_device *gbefb_device;
1264
1265 int __init gbefb_init(void)
1266 {
1267         int ret = platform_driver_register(&gbefb_driver);
1268         if (!ret) {
1269                 gbefb_device = platform_device_alloc("gbefb", 0);
1270                 if (gbefb_device) {
1271                         ret = platform_device_add(gbefb_device);
1272                 } else {
1273                         ret = -ENOMEM;
1274                 }
1275                 if (ret) {
1276                         platform_device_put(gbefb_device);
1277                         platform_driver_unregister(&gbefb_driver);
1278                 }
1279         }
1280         return ret;
1281 }
1282
1283 void __exit gbefb_exit(void)
1284 {
1285         platform_device_unregister(gbefb_device);
1286         platform_driver_unregister(&gbefb_driver);
1287 }
1288
1289 module_init(gbefb_init);
1290 module_exit(gbefb_exit);
1291
1292 MODULE_LICENSE("GPL");