diff options
-rw-r--r-- | drivers/firmware/sysfb.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 4e104f3de4b9..170b7cd0cfcb 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -70,15 +70,41 @@ void sysfb_disable(void) } EXPORT_SYMBOL_GPL(sysfb_disable); +#if defined(CONFIG_PCI) +static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev) +{ + /* + * TODO: Try to integrate this code into the PCI subsystem + */ + int ret; + u16 command; + + ret = pci_read_config_word(pdev, PCI_COMMAND, &command); + if (ret != PCIBIOS_SUCCESSFUL) + return false; + if (!(command & PCI_COMMAND_MEMORY)) + return false; + return true; +} +#else +static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev) +{ + return false; +} +#endif + static __init struct device *sysfb_parent_dev(const struct screen_info *si) { struct pci_dev *pdev; pdev = screen_info_pci_dev(si); - if (IS_ERR(pdev)) + if (IS_ERR(pdev)) { return ERR_CAST(pdev); - else if (pdev) + } else if (pdev) { + if (!sysfb_pci_dev_is_enabled(pdev)) + return ERR_PTR(-ENODEV); return &pdev->dev; + } return NULL; } @@ -99,6 +125,8 @@ static __init int sysfb_init(void) sysfb_apply_efi_quirks(); parent = sysfb_parent_dev(si); + if (IS_ERR(parent)) + goto unlock_mutex; /* try to create a simple-framebuffer device */ compatible = sysfb_parse_mode(si, &mode); |