diff options
Diffstat (limited to 'drivers/firmware/sysfb.c')
| -rw-r--r-- | drivers/firmware/sysfb.c | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 921f61507ae8..889e5b05c739 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -39,6 +39,8 @@ static struct platform_device *pd; static DEFINE_MUTEX(disable_lock); static bool disabled; +static struct device *sysfb_parent_dev(const struct screen_info *si); + static bool sysfb_unregister(void) { if (IS_ERR_OR_NULL(pd)) @@ -52,6 +54,7 @@ static bool sysfb_unregister(void) /** * sysfb_disable() - disable the Generic System Framebuffers support + * @dev: the device to check if non-NULL * * This disables the registration of system framebuffer devices that match the * generic drivers that make use of the system framebuffer set up by firmware. @@ -61,17 +64,42 @@ static bool sysfb_unregister(void) * Context: The function can sleep. A @disable_lock mutex is acquired to serialize * against sysfb_init(), that registers a system framebuffer device. */ -void sysfb_disable(void) +void sysfb_disable(struct device *dev) { + struct screen_info *si = &screen_info; + struct device *parent; + mutex_lock(&disable_lock); - sysfb_unregister(); - disabled = true; + parent = sysfb_parent_dev(si); + if (!dev || !parent || dev == parent) { + sysfb_unregister(); + disabled = true; + } mutex_unlock(&disable_lock); } EXPORT_SYMBOL_GPL(sysfb_disable); +/** + * sysfb_handles_screen_info() - reports if sysfb handles the global screen_info + * + * Callers can use sysfb_handles_screen_info() to determine whether the Generic + * System Framebuffers (sysfb) can handle the global screen_info data structure + * or not. Drivers might need this information to know if they have to setup the + * system framebuffer, or if they have to delegate this action to sysfb instead. + * + * Returns: + * True if sysfb handles the global screen_info data structure. + */ +bool sysfb_handles_screen_info(void) +{ + const struct screen_info *si = &screen_info; + + return !!screen_info_video_type(si); +} +EXPORT_SYMBOL_GPL(sysfb_handles_screen_info); + #if defined(CONFIG_PCI) -static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev) +static bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev) { /* * TODO: Try to integrate this code into the PCI subsystem @@ -87,13 +115,13 @@ static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev) return true; } #else -static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev) +static 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) +static struct device *sysfb_parent_dev(const struct screen_info *si) { struct pci_dev *pdev; @@ -115,6 +143,7 @@ static __init int sysfb_init(void) { struct screen_info *si = &screen_info; struct device *parent; + unsigned int type; struct simplefb_platform_data mode; const char *name; bool compatible; @@ -142,17 +171,26 @@ static __init int sysfb_init(void) goto put_device; } + type = screen_info_video_type(si); + /* if the FB is incompatible, create a legacy framebuffer device */ - if (si->orig_video_isVGA == VIDEO_TYPE_EFI) - name = "efi-framebuffer"; - else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB) - name = "vesa-framebuffer"; - else if (si->orig_video_isVGA == VIDEO_TYPE_VGAC) - name = "vga-framebuffer"; - else if (si->orig_video_isVGA == VIDEO_TYPE_EGAC) + switch (type) { + case VIDEO_TYPE_EGAC: name = "ega-framebuffer"; - else + break; + case VIDEO_TYPE_VGAC: + name = "vga-framebuffer"; + break; + case VIDEO_TYPE_VLFB: + name = "vesa-framebuffer"; + break; + case VIDEO_TYPE_EFI: + name = "efi-framebuffer"; + break; + default: name = "platform-framebuffer"; + break; + } pd = platform_device_alloc(name, 0); if (!pd) { |
