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>
This commit is contained in:
parent
88674088d1
commit
b4aa016305
|
@ -17,4 +17,10 @@
|
||||||
#define vga_readb(x) (*(x))
|
#define vga_readb(x) (*(x))
|
||||||
#define vga_writeb(x, y) (*(y) = (x))
|
#define vga_writeb(x, y) (*(y) = (x))
|
||||||
|
|
||||||
|
#ifdef CONFIG_FB_EFI
|
||||||
|
#define __ARCH_HAS_VGA_DEFAULT_DEVICE
|
||||||
|
extern struct pci_dev *vga_default_device(void);
|
||||||
|
extern void vga_set_default_device(struct pci_dev *pdev);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _ASM_X86_VGA_H */
|
#endif /* _ASM_X86_VGA_H */
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
static bool request_mem_succeeded = false;
|
static bool request_mem_succeeded = false;
|
||||||
|
|
||||||
|
static struct pci_dev *default_vga;
|
||||||
|
|
||||||
static struct fb_var_screeninfo efifb_defined __devinitdata = {
|
static struct fb_var_screeninfo efifb_defined __devinitdata = {
|
||||||
.activate = FB_ACTIVATE_NOW,
|
.activate = FB_ACTIVATE_NOW,
|
||||||
.height = -1,
|
.height = -1,
|
||||||
|
@ -298,35 +300,70 @@ static struct fb_ops efifb_ops = {
|
||||||
.fb_imageblit = cfb_imageblit,
|
.fb_imageblit = cfb_imageblit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pci_dev *vga_default_device(void)
|
||||||
|
{
|
||||||
|
return default_vga;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vga_set_default_device(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
default_vga = pdev;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init efifb_setup(char *options)
|
static int __init efifb_setup(char *options)
|
||||||
{
|
{
|
||||||
char *this_opt;
|
char *this_opt;
|
||||||
int i;
|
int i;
|
||||||
|
struct pci_dev *dev = NULL;
|
||||||
|
|
||||||
if (!options || !*options)
|
if (options && *options) {
|
||||||
return 0;
|
while ((this_opt = strsep(&options, ",")) != NULL) {
|
||||||
|
if (!*this_opt) continue;
|
||||||
|
|
||||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
for (i = 0; i < M_UNKNOWN; i++) {
|
||||||
if (!*this_opt) continue;
|
if (!strcmp(this_opt, dmi_list[i].optname) &&
|
||||||
|
dmi_list[i].base != 0) {
|
||||||
for (i = 0; i < M_UNKNOWN; i++) {
|
screen_info.lfb_base = dmi_list[i].base;
|
||||||
if (!strcmp(this_opt, dmi_list[i].optname) &&
|
screen_info.lfb_linelength = dmi_list[i].stride;
|
||||||
dmi_list[i].base != 0) {
|
screen_info.lfb_width = dmi_list[i].width;
|
||||||
screen_info.lfb_base = dmi_list[i].base;
|
screen_info.lfb_height = dmi_list[i].height;
|
||||||
screen_info.lfb_linelength = dmi_list[i].stride;
|
}
|
||||||
screen_info.lfb_width = dmi_list[i].width;
|
|
||||||
screen_info.lfb_height = dmi_list[i].height;
|
|
||||||
}
|
}
|
||||||
|
if (!strncmp(this_opt, "base:", 5))
|
||||||
|
screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
|
||||||
|
else if (!strncmp(this_opt, "stride:", 7))
|
||||||
|
screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
|
||||||
|
else if (!strncmp(this_opt, "height:", 7))
|
||||||
|
screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
|
||||||
|
else if (!strncmp(this_opt, "width:", 6))
|
||||||
|
screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
|
||||||
}
|
}
|
||||||
if (!strncmp(this_opt, "base:", 5))
|
|
||||||
screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
|
|
||||||
else if (!strncmp(this_opt, "stride:", 7))
|
|
||||||
screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
|
|
||||||
else if (!strncmp(this_opt, "height:", 7))
|
|
||||||
screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
|
|
||||||
else if (!strncmp(this_opt, "width:", 6))
|
|
||||||
screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_each_pci_dev(dev) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||||
|
resource_size_t start, end;
|
||||||
|
|
||||||
|
if (!(pci_resource_flags(dev, i) & IORESOURCE_MEM))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
start = pci_resource_start(dev, i);
|
||||||
|
end = pci_resource_end(dev, i);
|
||||||
|
|
||||||
|
if (!start || !end)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (screen_info.lfb_base >= start &&
|
||||||
|
(screen_info.lfb_base + screen_info.lfb_size) < end)
|
||||||
|
default_vga = dev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue