diff options
author | Matthew Garrett <mjg@redhat.com> | 2012-04-16 16:26:05 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-04-24 04:50:18 -0400 |
commit | b4aa0163056b6c70029b6e8619ce07c274351f42 (patch) | |
tree | 4cb41bfde5026aeff49656fb07acdf77c9f1fc31 /drivers/video/efifb.c | |
parent | 88674088d10ca2538b2efd2559f6620ade8ec373 (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.c | 77 |
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 | ||
19 | static bool request_mem_succeeded = false; | 19 | static bool request_mem_succeeded = false; |
20 | 20 | ||
21 | static struct pci_dev *default_vga; | ||
22 | |||
21 | static struct fb_var_screeninfo efifb_defined __devinitdata = { | 23 | static 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 | ||
303 | struct pci_dev *vga_default_device(void) | ||
304 | { | ||
305 | return default_vga; | ||
306 | } | ||
307 | |||
308 | void vga_set_default_device(struct pci_dev *pdev) | ||
309 | { | ||
310 | default_vga = pdev; | ||
311 | } | ||
312 | |||
301 | static int __init efifb_setup(char *options) | 313 | static 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 | ||