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
					
				
			
		
					 2 changed files with 63 additions and 20 deletions
				
			
		| 
						 | 
					@ -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,14 +300,23 @@ 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) {
 | 
							while ((this_opt = strsep(&options, ",")) != NULL) {
 | 
				
			||||||
			if (!*this_opt) continue;
 | 
								if (!*this_opt) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -327,6 +338,32 @@ static int __init efifb_setup(char *options)
 | 
				
			||||||
			else if (!strncmp(this_opt, "width:", 6))
 | 
								else if (!strncmp(this_opt, "width:", 6))
 | 
				
			||||||
				screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
 | 
									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…
	
	Add table
		Add a link
		
	
		Reference in a new issue