1 /*
2  * Framebuffer driver for EFI/UEFI based system
3  *
4  * (c) 2006 Edgar Hucek <gimli@dark-green.com>
5  * Original efi driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
6  *
7  */
8 
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/fb.h>
13 #include <linux/platform_device.h>
14 #include <linux/screen_info.h>
15 #include <linux/dmi.h>
16 #include <linux/pci.h>
17 #include <video/vga.h>
18 
19 static bool request_mem_succeeded = false;
20 
21 static struct fb_var_screeninfo efifb_defined __devinitdata = {
22 	.activate		= FB_ACTIVATE_NOW,
23 	.height			= -1,
24 	.width			= -1,
25 	.right_margin		= 32,
26 	.upper_margin		= 16,
27 	.lower_margin		= 4,
28 	.vsync_len		= 4,
29 	.vmode			= FB_VMODE_NONINTERLACED,
30 };
31 
32 static struct fb_fix_screeninfo efifb_fix __devinitdata = {
33 	.id			= "EFI VGA",
34 	.type			= FB_TYPE_PACKED_PIXELS,
35 	.accel			= FB_ACCEL_NONE,
36 	.visual			= FB_VISUAL_TRUECOLOR,
37 };
38 
39 enum {
40 	M_I17,		/* 17-Inch iMac */
41 	M_I20,		/* 20-Inch iMac */
42 	M_I20_SR,	/* 20-Inch iMac (Santa Rosa) */
43 	M_I24,		/* 24-Inch iMac */
44 	M_I24_8_1,	/* 24-Inch iMac, 8,1th gen */
45 	M_I24_10_1,	/* 24-Inch iMac, 10,1th gen */
46 	M_I27_11_1,	/* 27-Inch iMac, 11,1th gen */
47 	M_MINI,		/* Mac Mini */
48 	M_MINI_3_1,	/* Mac Mini, 3,1th gen */
49 	M_MINI_4_1,	/* Mac Mini, 4,1th gen */
50 	M_MB,		/* MacBook */
51 	M_MB_2,		/* MacBook, 2nd rev. */
52 	M_MB_3,		/* MacBook, 3rd rev. */
53 	M_MB_5_1,	/* MacBook, 5th rev. */
54 	M_MB_6_1,	/* MacBook, 6th rev. */
55 	M_MB_7_1,	/* MacBook, 7th rev. */
56 	M_MB_SR,	/* MacBook, 2nd gen, (Santa Rosa) */
57 	M_MBA,		/* MacBook Air */
58 	M_MBA_3,	/* Macbook Air, 3rd rev */
59 	M_MBP,		/* MacBook Pro */
60 	M_MBP_2,	/* MacBook Pro 2nd gen */
61 	M_MBP_2_2,	/* MacBook Pro 2,2nd gen */
62 	M_MBP_SR,	/* MacBook Pro (Santa Rosa) */
63 	M_MBP_4,	/* MacBook Pro, 4th gen */
64 	M_MBP_5_1,    /* MacBook Pro, 5,1th gen */
65 	M_MBP_5_2,	/* MacBook Pro, 5,2th gen */
66 	M_MBP_5_3,	/* MacBook Pro, 5,3rd gen */
67 	M_MBP_6_1,	/* MacBook Pro, 6,1th gen */
68 	M_MBP_6_2,	/* MacBook Pro, 6,2th gen */
69 	M_MBP_7_1,	/* MacBook Pro, 7,1th gen */
70 	M_MBP_8_2,	/* MacBook Pro, 8,2nd gen */
71 	M_UNKNOWN	/* placeholder */
72 };
73 
74 #define OVERRIDE_NONE	0x0
75 #define OVERRIDE_BASE	0x1
76 #define OVERRIDE_STRIDE	0x2
77 #define OVERRIDE_HEIGHT	0x4
78 #define OVERRIDE_WIDTH	0x8
79 
80 static struct efifb_dmi_info {
81 	char *optname;
82 	unsigned long base;
83 	int stride;
84 	int width;
85 	int height;
86 	int flags;
87 } dmi_list[] __initdata = {
88 	[M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
89 	[M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */
90 	[M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE },
91 	[M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */
92 	[M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
93 	[M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE },
94 	[M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE },
95 	[M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE },
96 	[M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE },
97 	[M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
98 	[M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
99 	[M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
100 	[M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
101 	[M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
102 	[M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
103 	/* 11" Macbook Air 3,1 passes the wrong stride */
104 	[M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE },
105 	[M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
106 	[M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */
107 	[M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
108 	[M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
109 	[M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
110 	[M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
111 	[M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
112 	[M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE },
113 	[M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE },
114 	[M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE },
115 	[M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE },
116 	[M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE },
117 	[M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE }
118 };
119 
120 static int set_system(const struct dmi_system_id *id);
121 
122 #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid)		\
123 	{ set_system, name, {					\
124 		DMI_MATCH(DMI_BIOS_VENDOR, vendor),		\
125 		DMI_MATCH(DMI_PRODUCT_NAME, name) },		\
126 	  &dmi_list[enumid] }
127 
128 static const struct dmi_system_id dmi_system_table[] __initconst = {
129 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17),
130 	/* At least one of these two will be right; maybe both? */
131 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20),
132 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20),
133 	/* At least one of these two will be right; maybe both? */
134 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
135 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
136 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
137 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1),
138 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1),
139 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1),
140 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
141 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1),
142 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1),
143 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
144 	/* At least one of these two will be right; maybe both? */
145 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
146 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB),
147 	/* At least one of these two will be right; maybe both? */
148 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
149 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
150 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
151 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1),
152 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1),
153 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1),
154 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
155 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3),
156 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
157 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
158 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2),
159 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
160 	EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
161 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
162 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
163 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1),
164 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2),
165 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3),
166 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1),
167 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2),
168 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1),
169 	EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2),
170 	{},
171 };
172 
173 #define choose_value(dmivalue, fwvalue, field, flags) ({	\
174 		typeof(fwvalue) _ret_ = fwvalue;		\
175 		if ((flags) & (field))				\
176 			_ret_ = dmivalue;			\
177 		else if ((fwvalue) == 0)			\
178 			_ret_ = dmivalue;			\
179 		_ret_;						\
180 	})
181 
set_system(const struct dmi_system_id * id)182 static int set_system(const struct dmi_system_id *id)
183 {
184 	struct efifb_dmi_info *info = id->driver_data;
185 
186 	if (info->base == 0 && info->height == 0 && info->width == 0
187 			&& info->stride == 0)
188 		return 0;
189 
190 	/* Trust the bootloader over the DMI tables */
191 	if (screen_info.lfb_base == 0) {
192 #if defined(CONFIG_PCI)
193 		struct pci_dev *dev = NULL;
194 		int found_bar = 0;
195 #endif
196 		if (info->base) {
197 			screen_info.lfb_base = choose_value(info->base,
198 				screen_info.lfb_base, OVERRIDE_BASE,
199 				info->flags);
200 
201 #if defined(CONFIG_PCI)
202 			/* make sure that the address in the table is actually
203 			 * on a VGA device's PCI BAR */
204 
205 			for_each_pci_dev(dev) {
206 				int i;
207 				if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
208 					continue;
209 				for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
210 					resource_size_t start, end;
211 
212 					start = pci_resource_start(dev, i);
213 					if (start == 0)
214 						break;
215 					end = pci_resource_end(dev, i);
216 					if (screen_info.lfb_base >= start &&
217 					    screen_info.lfb_base < end) {
218 						found_bar = 1;
219 					}
220 				}
221 			}
222 			if (!found_bar)
223 				screen_info.lfb_base = 0;
224 #endif
225 		}
226 	}
227 	if (screen_info.lfb_base) {
228 		screen_info.lfb_linelength = choose_value(info->stride,
229 			screen_info.lfb_linelength, OVERRIDE_STRIDE,
230 			info->flags);
231 		screen_info.lfb_width = choose_value(info->width,
232 			screen_info.lfb_width, OVERRIDE_WIDTH,
233 			info->flags);
234 		screen_info.lfb_height = choose_value(info->height,
235 			screen_info.lfb_height, OVERRIDE_HEIGHT,
236 			info->flags);
237 		if (screen_info.orig_video_isVGA == 0)
238 			screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
239 	} else {
240 		screen_info.lfb_linelength = 0;
241 		screen_info.lfb_width = 0;
242 		screen_info.lfb_height = 0;
243 		screen_info.orig_video_isVGA = 0;
244 		return 0;
245 	}
246 
247 	printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x "
248 			 "(%dx%d, stride %d)\n", id->ident,
249 			 screen_info.lfb_base, screen_info.lfb_width,
250 			 screen_info.lfb_height, screen_info.lfb_linelength);
251 
252 
253 	return 1;
254 }
255 
efifb_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * info)256 static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
257 			   unsigned blue, unsigned transp,
258 			   struct fb_info *info)
259 {
260 	/*
261 	 *  Set a single color register. The values supplied are
262 	 *  already rounded down to the hardware's capabilities
263 	 *  (according to the entries in the `var' structure). Return
264 	 *  != 0 for invalid regno.
265 	 */
266 
267 	if (regno >= info->cmap.len)
268 		return 1;
269 
270 	if (regno < 16) {
271 		red   >>= 8;
272 		green >>= 8;
273 		blue  >>= 8;
274 		((u32 *)(info->pseudo_palette))[regno] =
275 			(red   << info->var.red.offset)   |
276 			(green << info->var.green.offset) |
277 			(blue  << info->var.blue.offset);
278 	}
279 	return 0;
280 }
281 
efifb_destroy(struct fb_info * info)282 static void efifb_destroy(struct fb_info *info)
283 {
284 	if (info->screen_base)
285 		iounmap(info->screen_base);
286 	if (request_mem_succeeded)
287 		release_mem_region(info->apertures->ranges[0].base,
288 				   info->apertures->ranges[0].size);
289 	framebuffer_release(info);
290 }
291 
292 static struct fb_ops efifb_ops = {
293 	.owner		= THIS_MODULE,
294 	.fb_destroy	= efifb_destroy,
295 	.fb_setcolreg	= efifb_setcolreg,
296 	.fb_fillrect	= cfb_fillrect,
297 	.fb_copyarea	= cfb_copyarea,
298 	.fb_imageblit	= cfb_imageblit,
299 };
300 
efifb_setup(char * options)301 static int __init efifb_setup(char *options)
302 {
303 	char *this_opt;
304 	int i;
305 
306 	if (!options || !*options)
307 		return 0;
308 
309 	while ((this_opt = strsep(&options, ",")) != NULL) {
310 		if (!*this_opt) continue;
311 
312 		for (i = 0; i < M_UNKNOWN; i++) {
313 			if (!strcmp(this_opt, dmi_list[i].optname) &&
314 					dmi_list[i].base != 0) {
315 				screen_info.lfb_base = dmi_list[i].base;
316 				screen_info.lfb_linelength = dmi_list[i].stride;
317 				screen_info.lfb_width = dmi_list[i].width;
318 				screen_info.lfb_height = dmi_list[i].height;
319 			}
320 		}
321 		if (!strncmp(this_opt, "base:", 5))
322 			screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
323 		else if (!strncmp(this_opt, "stride:", 7))
324 			screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
325 		else if (!strncmp(this_opt, "height:", 7))
326 			screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
327 		else if (!strncmp(this_opt, "width:", 6))
328 			screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
329 	}
330 	return 0;
331 }
332 
efifb_probe(struct platform_device * dev)333 static int __init efifb_probe(struct platform_device *dev)
334 {
335 	struct fb_info *info;
336 	int err;
337 	unsigned int size_vmode;
338 	unsigned int size_remap;
339 	unsigned int size_total;
340 
341 	if (!screen_info.lfb_depth)
342 		screen_info.lfb_depth = 32;
343 	if (!screen_info.pages)
344 		screen_info.pages = 1;
345 	if (!screen_info.lfb_base) {
346 		printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
347 		return -ENODEV;
348 	}
349 	printk(KERN_INFO "efifb: probing for efifb\n");
350 
351 	/* just assume they're all unset if any are */
352 	if (!screen_info.blue_size) {
353 		screen_info.blue_size = 8;
354 		screen_info.blue_pos = 0;
355 		screen_info.green_size = 8;
356 		screen_info.green_pos = 8;
357 		screen_info.red_size = 8;
358 		screen_info.red_pos = 16;
359 		screen_info.rsvd_size = 8;
360 		screen_info.rsvd_pos = 24;
361 	}
362 
363 	efifb_fix.smem_start = screen_info.lfb_base;
364 	efifb_defined.bits_per_pixel = screen_info.lfb_depth;
365 	efifb_defined.xres = screen_info.lfb_width;
366 	efifb_defined.yres = screen_info.lfb_height;
367 	efifb_fix.line_length = screen_info.lfb_linelength;
368 
369 	/*   size_vmode -- that is the amount of memory needed for the
370 	 *                 used video mode, i.e. the minimum amount of
371 	 *                 memory we need. */
372 	size_vmode = efifb_defined.yres * efifb_fix.line_length;
373 
374 	/*   size_total -- all video memory we have. Used for
375 	 *                 entries, ressource allocation and bounds
376 	 *                 checking. */
377 	size_total = screen_info.lfb_size;
378 	if (size_total < size_vmode)
379 		size_total = size_vmode;
380 
381 	/*   size_remap -- the amount of video memory we are going to
382 	 *                 use for efifb.  With modern cards it is no
383 	 *                 option to simply use size_total as that
384 	 *                 wastes plenty of kernel address space. */
385 	size_remap  = size_vmode * 2;
386 	if (size_remap > size_total)
387 		size_remap = size_total;
388 	if (size_remap % PAGE_SIZE)
389 		size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
390 	efifb_fix.smem_len = size_remap;
391 
392 	if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
393 		request_mem_succeeded = true;
394 	} else {
395 		/* We cannot make this fatal. Sometimes this comes from magic
396 		   spaces our resource handlers simply don't know about */
397 		printk(KERN_WARNING
398 		       "efifb: cannot reserve video memory at 0x%lx\n",
399 			efifb_fix.smem_start);
400 	}
401 
402 	info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
403 	if (!info) {
404 		printk(KERN_ERR "efifb: cannot allocate framebuffer\n");
405 		err = -ENOMEM;
406 		goto err_release_mem;
407 	}
408 	info->pseudo_palette = info->par;
409 	info->par = NULL;
410 
411 	info->apertures = alloc_apertures(1);
412 	if (!info->apertures) {
413 		err = -ENOMEM;
414 		goto err_release_fb;
415 	}
416 	info->apertures->ranges[0].base = efifb_fix.smem_start;
417 	info->apertures->ranges[0].size = size_remap;
418 
419 	info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
420 	if (!info->screen_base) {
421 		printk(KERN_ERR "efifb: abort, cannot ioremap video memory "
422 				"0x%x @ 0x%lx\n",
423 			efifb_fix.smem_len, efifb_fix.smem_start);
424 		err = -EIO;
425 		goto err_release_fb;
426 	}
427 
428 	printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, "
429 	       "using %dk, total %dk\n",
430 	       efifb_fix.smem_start, info->screen_base,
431 	       size_remap/1024, size_total/1024);
432 	printk(KERN_INFO "efifb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
433 	       efifb_defined.xres, efifb_defined.yres,
434 	       efifb_defined.bits_per_pixel, efifb_fix.line_length,
435 	       screen_info.pages);
436 
437 	efifb_defined.xres_virtual = efifb_defined.xres;
438 	efifb_defined.yres_virtual = efifb_fix.smem_len /
439 					efifb_fix.line_length;
440 	printk(KERN_INFO "efifb: scrolling: redraw\n");
441 	efifb_defined.yres_virtual = efifb_defined.yres;
442 
443 	/* some dummy values for timing to make fbset happy */
444 	efifb_defined.pixclock     = 10000000 / efifb_defined.xres *
445 					1000 / efifb_defined.yres;
446 	efifb_defined.left_margin  = (efifb_defined.xres / 8) & 0xf8;
447 	efifb_defined.hsync_len    = (efifb_defined.xres / 8) & 0xf8;
448 
449 	efifb_defined.red.offset    = screen_info.red_pos;
450 	efifb_defined.red.length    = screen_info.red_size;
451 	efifb_defined.green.offset  = screen_info.green_pos;
452 	efifb_defined.green.length  = screen_info.green_size;
453 	efifb_defined.blue.offset   = screen_info.blue_pos;
454 	efifb_defined.blue.length   = screen_info.blue_size;
455 	efifb_defined.transp.offset = screen_info.rsvd_pos;
456 	efifb_defined.transp.length = screen_info.rsvd_size;
457 
458 	printk(KERN_INFO "efifb: %s: "
459 	       "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
460 	       "Truecolor",
461 	       screen_info.rsvd_size,
462 	       screen_info.red_size,
463 	       screen_info.green_size,
464 	       screen_info.blue_size,
465 	       screen_info.rsvd_pos,
466 	       screen_info.red_pos,
467 	       screen_info.green_pos,
468 	       screen_info.blue_pos);
469 
470 	efifb_fix.ypanstep  = 0;
471 	efifb_fix.ywrapstep = 0;
472 
473 	info->fbops = &efifb_ops;
474 	info->var = efifb_defined;
475 	info->fix = efifb_fix;
476 	info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
477 
478 	if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) {
479 		printk(KERN_ERR "efifb: cannot allocate colormap\n");
480 		goto err_unmap;
481 	}
482 	if ((err = register_framebuffer(info)) < 0) {
483 		printk(KERN_ERR "efifb: cannot register framebuffer\n");
484 		goto err_fb_dealoc;
485 	}
486 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
487 		info->node, info->fix.id);
488 	return 0;
489 
490 err_fb_dealoc:
491 	fb_dealloc_cmap(&info->cmap);
492 err_unmap:
493 	iounmap(info->screen_base);
494 err_release_fb:
495 	framebuffer_release(info);
496 err_release_mem:
497 	if (request_mem_succeeded)
498 		release_mem_region(efifb_fix.smem_start, size_total);
499 	return err;
500 }
501 
502 static struct platform_driver efifb_driver = {
503 	.driver	= {
504 		.name	= "efifb",
505 	},
506 };
507 
508 static struct platform_device efifb_device = {
509 	.name	= "efifb",
510 };
511 
efifb_init(void)512 static int __init efifb_init(void)
513 {
514 	int ret;
515 	char *option = NULL;
516 
517 	dmi_check_system(dmi_system_table);
518 
519 	if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
520 		return -ENODEV;
521 
522 	if (fb_get_options("efifb", &option))
523 		return -ENODEV;
524 	efifb_setup(option);
525 
526 	/* We don't get linelength from UGA Draw Protocol, only from
527 	 * EFI Graphics Protocol.  So if it's not in DMI, and it's not
528 	 * passed in from the user, we really can't use the framebuffer.
529 	 */
530 	if (!screen_info.lfb_linelength)
531 		return -ENODEV;
532 
533 	ret = platform_device_register(&efifb_device);
534 	if (ret)
535 		return ret;
536 
537 	/*
538 	 * This is not just an optimization.  We will interfere
539 	 * with a real driver if we get reprobed, so don't allow
540 	 * it.
541 	 */
542 	ret = platform_driver_probe(&efifb_driver, efifb_probe);
543 	if (ret) {
544 		platform_device_unregister(&efifb_device);
545 		return ret;
546 	}
547 
548 	return ret;
549 }
550 module_init(efifb_init);
551 
552 MODULE_LICENSE("GPL");
553