summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firmware/sysfb.c32
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);