aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/efifb.c
diff options
context:
space:
mode:
authorMatthew Garrett <mjg@redhat.com>2012-04-16 16:26:05 -0400
committerDave Airlie <airlied@redhat.com>2012-04-24 04:50:18 -0400
commitb4aa0163056b6c70029b6e8619ce07c274351f42 (patch)
tree4cb41bfde5026aeff49656fb07acdf77c9f1fc31 /drivers/video/efifb.c
parent88674088d10ca2538b2efd2559f6620ade8ec373 (diff)
efifb: Implement vga_default_device() (v2)
EFI doesn't typically make use of the legacy VGA ROM, but it may still be configured to pass that through to a given video device. This may lead to an inaccurate choice of default video device. Add support to efifb to pick out the correct active video device. v2: fix if->ifdef Signed-off-by: Matthew Garrett <mjg@redhat.com> Acked-by: hpa@zytor.com Cc: matt.fleming@intel.com Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/video/efifb.c')
-rw-r--r--drivers/video/efifb.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 784139aed079..66ed991ed8ba 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -18,6 +18,8 @@
18 18
19static bool request_mem_succeeded = false; 19static bool request_mem_succeeded = false;
20 20
21static struct pci_dev *default_vga;
22
21static struct fb_var_screeninfo efifb_defined __devinitdata = { 23static struct fb_var_screeninfo efifb_defined __devinitdata = {
22 .activate = FB_ACTIVATE_NOW, 24 .activate = FB_ACTIVATE_NOW,
23 .height = -1, 25 .height = -1,
@@ -298,35 +300,70 @@ static struct fb_ops efifb_ops = {
298 .fb_imageblit = cfb_imageblit, 300 .fb_imageblit = cfb_imageblit,
299}; 301};
300 302
303struct pci_dev *vga_default_device(void)
304{
305 return default_vga;
306}
307
308void vga_set_default_device(struct pci_dev *pdev)
309{
310 default_vga = pdev;
311}
312
301static int __init efifb_setup(char *options) 313static int __init efifb_setup(char *options)
302{ 314{
303 char *this_opt; 315 char *this_opt;
304 int i; 316 int i;
317 struct pci_dev *dev = NULL;
318
319 if (options && *options) {
320 while ((this_opt = strsep(&options, ",")) != NULL) {
321 if (!*this_opt) continue;
322
323 for (i = 0; i < M_UNKNOWN; i++) {
324 if (!strcmp(this_opt, dmi_list[i].optname) &&
325 dmi_list[i].base != 0) {
326 screen_info.lfb_base = dmi_list[i].base;
327 screen_info.lfb_linelength = dmi_list[i].stride;
328 screen_info.lfb_width = dmi_list[i].width;
329 screen_info.lfb_height = dmi_list[i].height;
330 }
331 }
332 if (!strncmp(this_opt, "base:", 5))
333 screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
334 else if (!strncmp(this_opt, "stride:", 7))
335 screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
336 else if (!strncmp(this_opt, "height:", 7))
337 screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
338 else if (!strncmp(this_opt, "width:", 6))
339 screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
340 }
341 }
305 342
306 if (!options || !*options) 343 for_each_pci_dev(dev) {
307 return 0; 344 int i;
308 345
309 while ((this_opt = strsep(&options, ",")) != NULL) { 346 if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
310 if (!*this_opt) continue; 347 continue;
311 348
312 for (i = 0; i < M_UNKNOWN; i++) { 349 for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
313 if (!strcmp(this_opt, dmi_list[i].optname) && 350 resource_size_t start, end;
314 dmi_list[i].base != 0) { 351
315 screen_info.lfb_base = dmi_list[i].base; 352 if (!(pci_resource_flags(dev, i) & IORESOURCE_MEM))
316 screen_info.lfb_linelength = dmi_list[i].stride; 353 continue;
317 screen_info.lfb_width = dmi_list[i].width; 354
318 screen_info.lfb_height = dmi_list[i].height; 355 start = pci_resource_start(dev, i);
319 } 356 end = pci_resource_end(dev, i);
357
358 if (!start || !end)
359 continue;
360
361 if (screen_info.lfb_base >= start &&
362 (screen_info.lfb_base + screen_info.lfb_size) < end)
363 default_vga = dev;
320 } 364 }
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 } 365 }
366
330 return 0; 367 return 0;
331} 368}
332 369