Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'x86-fb-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fb changes from Ingo Molnar:
"This tree includes preparatory patches for SimpleDRM driver support,
by David Herrmann. They clean up x86 framebuffer support by creating
simplefb devices wherever possible. More background can be found at

http://lwn.net/Articles/558104/"

* 'x86-fb-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
fbdev: fbcon: select VT_HW_CONSOLE_BINDING
fbdev: efifb: bind to efi-framebuffer
fbdev: vesafb: bind to platform-framebuffer device
fbdev: simplefb: add common x86 RGB formats
x86: sysfb: move EFI quirks from efifb to sysfb
x86: provide platform-devices for boot-framebuffers
fbdev: simplefb: mark as fw and allocate apertures
fbdev: simplefb: add init through platform_data

+666 -330
+26
arch/x86/Kconfig
··· 2270 2270 2271 2271 source "drivers/rapidio/Kconfig" 2272 2272 2273 + config X86_SYSFB 2274 + bool "Mark VGA/VBE/EFI FB as generic system framebuffer" 2275 + help 2276 + Firmwares often provide initial graphics framebuffers so the BIOS, 2277 + bootloader or kernel can show basic video-output during boot for 2278 + user-guidance and debugging. Historically, x86 used the VESA BIOS 2279 + Extensions and EFI-framebuffers for this, which are mostly limited 2280 + to x86. 2281 + This option, if enabled, marks VGA/VBE/EFI framebuffers as generic 2282 + framebuffers so the new generic system-framebuffer drivers can be 2283 + used on x86. If the framebuffer is not compatible with the generic 2284 + modes, it is adverticed as fallback platform framebuffer so legacy 2285 + drivers like efifb, vesafb and uvesafb can pick it up. 2286 + If this option is not selected, all system framebuffers are always 2287 + marked as fallback platform framebuffers as usual. 2288 + 2289 + Note: Legacy fbdev drivers, including vesafb, efifb, uvesafb, will 2290 + not be able to pick up generic system framebuffers if this option 2291 + is selected. You are highly encouraged to enable simplefb as 2292 + replacement if you select this option. simplefb can correctly deal 2293 + with generic system framebuffers. But you should still keep vesafb 2294 + and others enabled as fallback if a system framebuffer is 2295 + incompatible with simplefb. 2296 + 2297 + If unsure, say Y. 2298 + 2273 2299 endmenu 2274 2300 2275 2301
+98
arch/x86/include/asm/sysfb.h
··· 1 + #ifndef _ARCH_X86_KERNEL_SYSFB_H 2 + #define _ARCH_X86_KERNEL_SYSFB_H 3 + 4 + /* 5 + * Generic System Framebuffers on x86 6 + * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify it 9 + * under the terms of the GNU General Public License as published by the Free 10 + * Software Foundation; either version 2 of the License, or (at your option) 11 + * any later version. 12 + */ 13 + 14 + #include <linux/kernel.h> 15 + #include <linux/platform_data/simplefb.h> 16 + #include <linux/screen_info.h> 17 + 18 + enum { 19 + M_I17, /* 17-Inch iMac */ 20 + M_I20, /* 20-Inch iMac */ 21 + M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ 22 + M_I24, /* 24-Inch iMac */ 23 + M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ 24 + M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ 25 + M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ 26 + M_MINI, /* Mac Mini */ 27 + M_MINI_3_1, /* Mac Mini, 3,1th gen */ 28 + M_MINI_4_1, /* Mac Mini, 4,1th gen */ 29 + M_MB, /* MacBook */ 30 + M_MB_2, /* MacBook, 2nd rev. */ 31 + M_MB_3, /* MacBook, 3rd rev. */ 32 + M_MB_5_1, /* MacBook, 5th rev. */ 33 + M_MB_6_1, /* MacBook, 6th rev. */ 34 + M_MB_7_1, /* MacBook, 7th rev. */ 35 + M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ 36 + M_MBA, /* MacBook Air */ 37 + M_MBA_3, /* Macbook Air, 3rd rev */ 38 + M_MBP, /* MacBook Pro */ 39 + M_MBP_2, /* MacBook Pro 2nd gen */ 40 + M_MBP_2_2, /* MacBook Pro 2,2nd gen */ 41 + M_MBP_SR, /* MacBook Pro (Santa Rosa) */ 42 + M_MBP_4, /* MacBook Pro, 4th gen */ 43 + M_MBP_5_1, /* MacBook Pro, 5,1th gen */ 44 + M_MBP_5_2, /* MacBook Pro, 5,2th gen */ 45 + M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ 46 + M_MBP_6_1, /* MacBook Pro, 6,1th gen */ 47 + M_MBP_6_2, /* MacBook Pro, 6,2th gen */ 48 + M_MBP_7_1, /* MacBook Pro, 7,1th gen */ 49 + M_MBP_8_2, /* MacBook Pro, 8,2nd gen */ 50 + M_UNKNOWN /* placeholder */ 51 + }; 52 + 53 + struct efifb_dmi_info { 54 + char *optname; 55 + unsigned long base; 56 + int stride; 57 + int width; 58 + int height; 59 + int flags; 60 + }; 61 + 62 + #ifdef CONFIG_EFI 63 + 64 + extern struct efifb_dmi_info efifb_dmi_list[]; 65 + void sysfb_apply_efi_quirks(void); 66 + 67 + #else /* CONFIG_EFI */ 68 + 69 + static inline void sysfb_apply_efi_quirks(void) 70 + { 71 + } 72 + 73 + #endif /* CONFIG_EFI */ 74 + 75 + #ifdef CONFIG_X86_SYSFB 76 + 77 + bool parse_mode(const struct screen_info *si, 78 + struct simplefb_platform_data *mode); 79 + int create_simplefb(const struct screen_info *si, 80 + const struct simplefb_platform_data *mode); 81 + 82 + #else /* CONFIG_X86_SYSFB */ 83 + 84 + static inline bool parse_mode(const struct screen_info *si, 85 + struct simplefb_platform_data *mode) 86 + { 87 + return false; 88 + } 89 + 90 + static inline int create_simplefb(const struct screen_info *si, 91 + const struct simplefb_platform_data *mode) 92 + { 93 + return -EINVAL; 94 + } 95 + 96 + #endif /* CONFIG_X86_SYSFB */ 97 + 98 + #endif /* _ARCH_X86_KERNEL_SYSFB_H */
+3
arch/x86/kernel/Makefile
··· 103 103 obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 104 104 obj-$(CONFIG_OF) += devicetree.o 105 105 obj-$(CONFIG_UPROBES) += uprobes.o 106 + obj-y += sysfb.o 107 + obj-$(CONFIG_X86_SYSFB) += sysfb_simplefb.o 108 + obj-$(CONFIG_EFI) += sysfb_efi.o 106 109 107 110 obj-$(CONFIG_PERF_EVENTS) += perf_regs.o 108 111 obj-$(CONFIG_TRACING) += tracepoint.o
+74
arch/x86/kernel/sysfb.c
··· 1 + /* 2 + * Generic System Framebuffers on x86 3 + * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the Free 7 + * Software Foundation; either version 2 of the License, or (at your option) 8 + * any later version. 9 + */ 10 + 11 + /* 12 + * Simple-Framebuffer support for x86 systems 13 + * Create a platform-device for any available boot framebuffer. The 14 + * simple-framebuffer platform device is already available on DT systems, so 15 + * this module parses the global "screen_info" object and creates a suitable 16 + * platform device compatible with the "simple-framebuffer" DT object. If 17 + * the framebuffer is incompatible, we instead create a legacy 18 + * "vesa-framebuffer", "efi-framebuffer" or "platform-framebuffer" device and 19 + * pass the screen_info as platform_data. This allows legacy drivers 20 + * to pick these devices up without messing with simple-framebuffer drivers. 21 + * The global "screen_info" is still valid at all times. 22 + * 23 + * If CONFIG_X86_SYSFB is not selected, we never register "simple-framebuffer" 24 + * platform devices, but only use legacy framebuffer devices for 25 + * backwards compatibility. 26 + * 27 + * TODO: We set the dev_id field of all platform-devices to 0. This allows 28 + * other x86 OF/DT parsers to create such devices, too. However, they must 29 + * start at offset 1 for this to work. 30 + */ 31 + 32 + #include <linux/err.h> 33 + #include <linux/init.h> 34 + #include <linux/kernel.h> 35 + #include <linux/mm.h> 36 + #include <linux/platform_data/simplefb.h> 37 + #include <linux/platform_device.h> 38 + #include <linux/screen_info.h> 39 + #include <asm/sysfb.h> 40 + 41 + static __init int sysfb_init(void) 42 + { 43 + struct screen_info *si = &screen_info; 44 + struct simplefb_platform_data mode; 45 + struct platform_device *pd; 46 + const char *name; 47 + bool compatible; 48 + int ret; 49 + 50 + sysfb_apply_efi_quirks(); 51 + 52 + /* try to create a simple-framebuffer device */ 53 + compatible = parse_mode(si, &mode); 54 + if (compatible) { 55 + ret = create_simplefb(si, &mode); 56 + if (!ret) 57 + return 0; 58 + } 59 + 60 + /* if the FB is incompatible, create a legacy framebuffer device */ 61 + if (si->orig_video_isVGA == VIDEO_TYPE_EFI) 62 + name = "efi-framebuffer"; 63 + else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB) 64 + name = "vesa-framebuffer"; 65 + else 66 + name = "platform-framebuffer"; 67 + 68 + pd = platform_device_register_resndata(NULL, name, 0, 69 + NULL, 0, si, sizeof(*si)); 70 + return IS_ERR(pd) ? PTR_ERR(pd) : 0; 71 + } 72 + 73 + /* must execute after PCI subsystem for EFI quirks */ 74 + device_initcall(sysfb_init);
+214
arch/x86/kernel/sysfb_efi.c
··· 1 + /* 2 + * Generic System Framebuffers on x86 3 + * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> 4 + * 5 + * EFI Quirks Copyright (c) 2006 Edgar Hucek <gimli@dark-green.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the Free 9 + * Software Foundation; either version 2 of the License, or (at your option) 10 + * any later version. 11 + */ 12 + 13 + /* 14 + * EFI Quirks 15 + * Several EFI systems do not correctly advertise their boot framebuffers. 16 + * Hence, we use this static table of known broken machines and fix up the 17 + * information so framebuffer drivers can load corectly. 18 + */ 19 + 20 + #include <linux/dmi.h> 21 + #include <linux/err.h> 22 + #include <linux/init.h> 23 + #include <linux/kernel.h> 24 + #include <linux/mm.h> 25 + #include <linux/pci.h> 26 + #include <linux/screen_info.h> 27 + #include <video/vga.h> 28 + #include <asm/sysfb.h> 29 + 30 + enum { 31 + OVERRIDE_NONE = 0x0, 32 + OVERRIDE_BASE = 0x1, 33 + OVERRIDE_STRIDE = 0x2, 34 + OVERRIDE_HEIGHT = 0x4, 35 + OVERRIDE_WIDTH = 0x8, 36 + }; 37 + 38 + struct efifb_dmi_info efifb_dmi_list[] = { 39 + [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 40 + [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ 41 + [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, 42 + [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ 43 + [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 44 + [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, 45 + [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, 46 + [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, 47 + [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, 48 + [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 49 + [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 50 + [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 51 + [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 52 + [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 53 + [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 54 + /* 11" Macbook Air 3,1 passes the wrong stride */ 55 + [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, 56 + [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 57 + [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ 58 + [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 59 + [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, 60 + [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 61 + [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, 62 + [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 63 + [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, 64 + [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 65 + [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, 66 + [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 67 + [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 68 + [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } 69 + }; 70 + 71 + #define choose_value(dmivalue, fwvalue, field, flags) ({ \ 72 + typeof(fwvalue) _ret_ = fwvalue; \ 73 + if ((flags) & (field)) \ 74 + _ret_ = dmivalue; \ 75 + else if ((fwvalue) == 0) \ 76 + _ret_ = dmivalue; \ 77 + _ret_; \ 78 + }) 79 + 80 + static int __init efifb_set_system(const struct dmi_system_id *id) 81 + { 82 + struct efifb_dmi_info *info = id->driver_data; 83 + 84 + if (info->base == 0 && info->height == 0 && info->width == 0 && 85 + info->stride == 0) 86 + return 0; 87 + 88 + /* Trust the bootloader over the DMI tables */ 89 + if (screen_info.lfb_base == 0) { 90 + #if defined(CONFIG_PCI) 91 + struct pci_dev *dev = NULL; 92 + int found_bar = 0; 93 + #endif 94 + if (info->base) { 95 + screen_info.lfb_base = choose_value(info->base, 96 + screen_info.lfb_base, OVERRIDE_BASE, 97 + info->flags); 98 + 99 + #if defined(CONFIG_PCI) 100 + /* make sure that the address in the table is actually 101 + * on a VGA device's PCI BAR */ 102 + 103 + for_each_pci_dev(dev) { 104 + int i; 105 + if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) 106 + continue; 107 + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 108 + resource_size_t start, end; 109 + 110 + start = pci_resource_start(dev, i); 111 + if (start == 0) 112 + break; 113 + end = pci_resource_end(dev, i); 114 + if (screen_info.lfb_base >= start && 115 + screen_info.lfb_base < end) { 116 + found_bar = 1; 117 + } 118 + } 119 + } 120 + if (!found_bar) 121 + screen_info.lfb_base = 0; 122 + #endif 123 + } 124 + } 125 + if (screen_info.lfb_base) { 126 + screen_info.lfb_linelength = choose_value(info->stride, 127 + screen_info.lfb_linelength, OVERRIDE_STRIDE, 128 + info->flags); 129 + screen_info.lfb_width = choose_value(info->width, 130 + screen_info.lfb_width, OVERRIDE_WIDTH, 131 + info->flags); 132 + screen_info.lfb_height = choose_value(info->height, 133 + screen_info.lfb_height, OVERRIDE_HEIGHT, 134 + info->flags); 135 + if (screen_info.orig_video_isVGA == 0) 136 + screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; 137 + } else { 138 + screen_info.lfb_linelength = 0; 139 + screen_info.lfb_width = 0; 140 + screen_info.lfb_height = 0; 141 + screen_info.orig_video_isVGA = 0; 142 + return 0; 143 + } 144 + 145 + printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " 146 + "(%dx%d, stride %d)\n", id->ident, 147 + screen_info.lfb_base, screen_info.lfb_width, 148 + screen_info.lfb_height, screen_info.lfb_linelength); 149 + 150 + return 1; 151 + } 152 + 153 + #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ 154 + { \ 155 + efifb_set_system, \ 156 + name, \ 157 + { \ 158 + DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ 159 + DMI_MATCH(DMI_PRODUCT_NAME, name) \ 160 + }, \ 161 + &efifb_dmi_list[enumid] \ 162 + } 163 + 164 + static const struct dmi_system_id efifb_dmi_system_table[] __initconst = { 165 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), 166 + /* At least one of these two will be right; maybe both? */ 167 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), 168 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), 169 + /* At least one of these two will be right; maybe both? */ 170 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), 171 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), 172 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), 173 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), 174 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), 175 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), 176 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), 177 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), 178 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), 179 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), 180 + /* At least one of these two will be right; maybe both? */ 181 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), 182 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), 183 + /* At least one of these two will be right; maybe both? */ 184 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), 185 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), 186 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), 187 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), 188 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), 189 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), 190 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), 191 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3), 192 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), 193 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), 194 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), 195 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), 196 + EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), 197 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), 198 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), 199 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), 200 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), 201 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), 202 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), 203 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), 204 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), 205 + EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2), 206 + {}, 207 + }; 208 + 209 + __init void sysfb_apply_efi_quirks(void) 210 + { 211 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || 212 + !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) 213 + dmi_check_system(efifb_dmi_system_table); 214 + }
+95
arch/x86/kernel/sysfb_simplefb.c
··· 1 + /* 2 + * Generic System Framebuffers on x86 3 + * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License as published by the Free 7 + * Software Foundation; either version 2 of the License, or (at your option) 8 + * any later version. 9 + */ 10 + 11 + /* 12 + * simple-framebuffer probing 13 + * Try to convert "screen_info" into a "simple-framebuffer" compatible mode. 14 + * If the mode is incompatible, we return "false" and let the caller create 15 + * legacy nodes instead. 16 + */ 17 + 18 + #include <linux/err.h> 19 + #include <linux/init.h> 20 + #include <linux/kernel.h> 21 + #include <linux/mm.h> 22 + #include <linux/platform_data/simplefb.h> 23 + #include <linux/platform_device.h> 24 + #include <linux/screen_info.h> 25 + #include <asm/sysfb.h> 26 + 27 + static const char simplefb_resname[] = "BOOTFB"; 28 + static const struct simplefb_format formats[] = SIMPLEFB_FORMATS; 29 + 30 + /* try parsing x86 screen_info into a simple-framebuffer mode struct */ 31 + __init bool parse_mode(const struct screen_info *si, 32 + struct simplefb_platform_data *mode) 33 + { 34 + const struct simplefb_format *f; 35 + __u8 type; 36 + unsigned int i; 37 + 38 + type = si->orig_video_isVGA; 39 + if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI) 40 + return false; 41 + 42 + for (i = 0; i < ARRAY_SIZE(formats); ++i) { 43 + f = &formats[i]; 44 + if (si->lfb_depth == f->bits_per_pixel && 45 + si->red_size == f->red.length && 46 + si->red_pos == f->red.offset && 47 + si->green_size == f->green.length && 48 + si->green_pos == f->green.offset && 49 + si->blue_size == f->blue.length && 50 + si->blue_pos == f->blue.offset && 51 + si->rsvd_size == f->transp.length && 52 + si->rsvd_pos == f->transp.offset) { 53 + mode->format = f->name; 54 + mode->width = si->lfb_width; 55 + mode->height = si->lfb_height; 56 + mode->stride = si->lfb_linelength; 57 + return true; 58 + } 59 + } 60 + 61 + return false; 62 + } 63 + 64 + __init int create_simplefb(const struct screen_info *si, 65 + const struct simplefb_platform_data *mode) 66 + { 67 + struct platform_device *pd; 68 + struct resource res; 69 + unsigned long len; 70 + 71 + /* don't use lfb_size as it may contain the whole VMEM instead of only 72 + * the part that is occupied by the framebuffer */ 73 + len = mode->height * mode->stride; 74 + len = PAGE_ALIGN(len); 75 + if (len > si->lfb_size << 16) { 76 + printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); 77 + return -EINVAL; 78 + } 79 + 80 + /* setup IORESOURCE_MEM as framebuffer memory */ 81 + memset(&res, 0, sizeof(res)); 82 + res.flags = IORESOURCE_MEM; 83 + res.name = simplefb_resname; 84 + res.start = si->lfb_base; 85 + res.end = si->lfb_base + len - 1; 86 + if (res.end <= res.start) 87 + return -EINVAL; 88 + 89 + pd = platform_device_register_resndata(NULL, "simple-framebuffer", 0, 90 + &res, 1, mode, sizeof(*mode)); 91 + if (IS_ERR(pd)) 92 + return PTR_ERR(pd); 93 + 94 + return 0; 95 + }
+2 -3
drivers/video/Kconfig
··· 2457 2457 2458 2458 config FB_SIMPLE 2459 2459 bool "Simple framebuffer support" 2460 - depends on (FB = y) && OF 2460 + depends on (FB = y) 2461 2461 select FB_CFB_FILLRECT 2462 2462 select FB_CFB_COPYAREA 2463 2463 select FB_CFB_IMAGEBLIT ··· 2469 2469 pre-allocated frame buffer surface. 2470 2470 2471 2471 Configuration re: surface address, size, and format must be provided 2472 - through device tree, or potentially plain old platform data in the 2473 - future. 2472 + through device tree, or plain old platform data. 2474 2473 2475 2474 source "drivers/video/omap/Kconfig" 2476 2475 source "drivers/video/omap2/Kconfig"
+2 -1
drivers/video/console/Kconfig
··· 92 92 93 93 config FRAMEBUFFER_CONSOLE 94 94 tristate "Framebuffer Console support" 95 - depends on FB 95 + depends on FB && !UML 96 + select VT_HW_CONSOLE_BINDING 96 97 select CRC32 97 98 select FONT_SUPPORT 98 99 help
+29 -273
drivers/video/efifb.c
··· 15 15 #include <linux/dmi.h> 16 16 #include <linux/pci.h> 17 17 #include <video/vga.h> 18 + #include <asm/sysfb.h> 18 19 19 20 static bool request_mem_succeeded = false; 20 21 ··· 38 37 .accel = FB_ACCEL_NONE, 39 38 .visual = FB_VISUAL_TRUECOLOR, 40 39 }; 41 - 42 - enum { 43 - M_I17, /* 17-Inch iMac */ 44 - M_I20, /* 20-Inch iMac */ 45 - M_I20_SR, /* 20-Inch iMac (Santa Rosa) */ 46 - M_I24, /* 24-Inch iMac */ 47 - M_I24_8_1, /* 24-Inch iMac, 8,1th gen */ 48 - M_I24_10_1, /* 24-Inch iMac, 10,1th gen */ 49 - M_I27_11_1, /* 27-Inch iMac, 11,1th gen */ 50 - M_MINI, /* Mac Mini */ 51 - M_MINI_3_1, /* Mac Mini, 3,1th gen */ 52 - M_MINI_4_1, /* Mac Mini, 4,1th gen */ 53 - M_MB, /* MacBook */ 54 - M_MB_2, /* MacBook, 2nd rev. */ 55 - M_MB_3, /* MacBook, 3rd rev. */ 56 - M_MB_5_1, /* MacBook, 5th rev. */ 57 - M_MB_6_1, /* MacBook, 6th rev. */ 58 - M_MB_7_1, /* MacBook, 7th rev. */ 59 - M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */ 60 - M_MBA, /* MacBook Air */ 61 - M_MBA_3, /* Macbook Air, 3rd rev */ 62 - M_MBP, /* MacBook Pro */ 63 - M_MBP_2, /* MacBook Pro 2nd gen */ 64 - M_MBP_2_2, /* MacBook Pro 2,2nd gen */ 65 - M_MBP_SR, /* MacBook Pro (Santa Rosa) */ 66 - M_MBP_4, /* MacBook Pro, 4th gen */ 67 - M_MBP_5_1, /* MacBook Pro, 5,1th gen */ 68 - M_MBP_5_2, /* MacBook Pro, 5,2th gen */ 69 - M_MBP_5_3, /* MacBook Pro, 5,3rd gen */ 70 - M_MBP_6_1, /* MacBook Pro, 6,1th gen */ 71 - M_MBP_6_2, /* MacBook Pro, 6,2th gen */ 72 - M_MBP_7_1, /* MacBook Pro, 7,1th gen */ 73 - M_MBP_8_2, /* MacBook Pro, 8,2nd gen */ 74 - M_UNKNOWN /* placeholder */ 75 - }; 76 - 77 - #define OVERRIDE_NONE 0x0 78 - #define OVERRIDE_BASE 0x1 79 - #define OVERRIDE_STRIDE 0x2 80 - #define OVERRIDE_HEIGHT 0x4 81 - #define OVERRIDE_WIDTH 0x8 82 - 83 - static struct efifb_dmi_info { 84 - char *optname; 85 - unsigned long base; 86 - int stride; 87 - int width; 88 - int height; 89 - int flags; 90 - } dmi_list[] __initdata = { 91 - [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 92 - [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, /* guess */ 93 - [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050, OVERRIDE_NONE }, 94 - [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, /* guess */ 95 - [M_I24_8_1] = { "imac8", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 96 - [M_I24_10_1] = { "imac10", 0xc0010000, 2048 * 4, 1920, 1080, OVERRIDE_NONE }, 97 - [M_I27_11_1] = { "imac11", 0xc0010000, 2560 * 4, 2560, 1440, OVERRIDE_NONE }, 98 - [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768, OVERRIDE_NONE }, 99 - [M_MINI_3_1] = { "mini31", 0x40010000, 1024 * 4, 1024, 768, OVERRIDE_NONE }, 100 - [M_MINI_4_1] = { "mini41", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 101 - [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 102 - [M_MB_5_1] = { "macbook51", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 103 - [M_MB_6_1] = { "macbook61", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 104 - [M_MB_7_1] = { "macbook71", 0x80010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 105 - [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 106 - /* 11" Macbook Air 3,1 passes the wrong stride */ 107 - [M_MBA_3] = { "mba3", 0, 2048 * 4, 0, 0, OVERRIDE_STRIDE }, 108 - [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 109 - [M_MBP_2] = { "mbp2", 0, 0, 0, 0, OVERRIDE_NONE }, /* placeholder */ 110 - [M_MBP_2_2] = { "mbp22", 0x80010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 111 - [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, 112 - [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 113 - [M_MBP_5_1] = { "mbp51", 0xc0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, 114 - [M_MBP_5_2] = { "mbp52", 0xc0010000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 115 - [M_MBP_5_3] = { "mbp53", 0xd0010000, 2048 * 4, 1440, 900, OVERRIDE_NONE }, 116 - [M_MBP_6_1] = { "mbp61", 0x90030000, 2048 * 4, 1920, 1200, OVERRIDE_NONE }, 117 - [M_MBP_6_2] = { "mbp62", 0x90030000, 2048 * 4, 1680, 1050, OVERRIDE_NONE }, 118 - [M_MBP_7_1] = { "mbp71", 0xc0010000, 2048 * 4, 1280, 800, OVERRIDE_NONE }, 119 - [M_MBP_8_2] = { "mbp82", 0x90010000, 1472 * 4, 1440, 900, OVERRIDE_NONE }, 120 - [M_UNKNOWN] = { NULL, 0, 0, 0, 0, OVERRIDE_NONE } 121 - }; 122 - 123 - static int set_system(const struct dmi_system_id *id); 124 - 125 - #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ 126 - { set_system, name, { \ 127 - DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ 128 - DMI_MATCH(DMI_PRODUCT_NAME, name) }, \ 129 - &dmi_list[enumid] } 130 - 131 - static const struct dmi_system_id dmi_system_table[] __initconst = { 132 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17), 133 - /* At least one of these two will be right; maybe both? */ 134 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20), 135 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20), 136 - /* At least one of these two will be right; maybe both? */ 137 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24), 138 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24), 139 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR), 140 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac8,1", M_I24_8_1), 141 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac10,1", M_I24_10_1), 142 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac11,1", M_I27_11_1), 143 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI), 144 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini3,1", M_MINI_3_1), 145 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "Macmini4,1", M_MINI_4_1), 146 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB), 147 - /* At least one of these two will be right; maybe both? */ 148 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB), 149 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB), 150 - /* At least one of these two will be right; maybe both? */ 151 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB), 152 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB), 153 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB), 154 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook5,1", M_MB_5_1), 155 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook6,1", M_MB_6_1), 156 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook7,1", M_MB_7_1), 157 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA), 158 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir3,1", M_MBA_3), 159 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP), 160 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2), 161 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,2", M_MBP_2_2), 162 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2), 163 - EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR), 164 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR), 165 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4), 166 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,1", M_MBP_5_1), 167 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,2", M_MBP_5_2), 168 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro5,3", M_MBP_5_3), 169 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,1", M_MBP_6_1), 170 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro6,2", M_MBP_6_2), 171 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro7,1", M_MBP_7_1), 172 - EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro8,2", M_MBP_8_2), 173 - {}, 174 - }; 175 - 176 - #define choose_value(dmivalue, fwvalue, field, flags) ({ \ 177 - typeof(fwvalue) _ret_ = fwvalue; \ 178 - if ((flags) & (field)) \ 179 - _ret_ = dmivalue; \ 180 - else if ((fwvalue) == 0) \ 181 - _ret_ = dmivalue; \ 182 - _ret_; \ 183 - }) 184 - 185 - static int set_system(const struct dmi_system_id *id) 186 - { 187 - struct efifb_dmi_info *info = id->driver_data; 188 - 189 - if (info->base == 0 && info->height == 0 && info->width == 0 190 - && info->stride == 0) 191 - return 0; 192 - 193 - /* Trust the bootloader over the DMI tables */ 194 - if (screen_info.lfb_base == 0) { 195 - #if defined(CONFIG_PCI) 196 - struct pci_dev *dev = NULL; 197 - int found_bar = 0; 198 - #endif 199 - if (info->base) { 200 - screen_info.lfb_base = choose_value(info->base, 201 - screen_info.lfb_base, OVERRIDE_BASE, 202 - info->flags); 203 - 204 - #if defined(CONFIG_PCI) 205 - /* make sure that the address in the table is actually 206 - * on a VGA device's PCI BAR */ 207 - 208 - for_each_pci_dev(dev) { 209 - int i; 210 - if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) 211 - continue; 212 - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 213 - resource_size_t start, end; 214 - 215 - start = pci_resource_start(dev, i); 216 - if (start == 0) 217 - break; 218 - end = pci_resource_end(dev, i); 219 - if (screen_info.lfb_base >= start && 220 - screen_info.lfb_base < end) { 221 - found_bar = 1; 222 - } 223 - } 224 - } 225 - if (!found_bar) 226 - screen_info.lfb_base = 0; 227 - #endif 228 - } 229 - } 230 - if (screen_info.lfb_base) { 231 - screen_info.lfb_linelength = choose_value(info->stride, 232 - screen_info.lfb_linelength, OVERRIDE_STRIDE, 233 - info->flags); 234 - screen_info.lfb_width = choose_value(info->width, 235 - screen_info.lfb_width, OVERRIDE_WIDTH, 236 - info->flags); 237 - screen_info.lfb_height = choose_value(info->height, 238 - screen_info.lfb_height, OVERRIDE_HEIGHT, 239 - info->flags); 240 - if (screen_info.orig_video_isVGA == 0) 241 - screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; 242 - } else { 243 - screen_info.lfb_linelength = 0; 244 - screen_info.lfb_width = 0; 245 - screen_info.lfb_height = 0; 246 - screen_info.orig_video_isVGA = 0; 247 - return 0; 248 - } 249 - 250 - printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " 251 - "(%dx%d, stride %d)\n", id->ident, 252 - screen_info.lfb_base, screen_info.lfb_width, 253 - screen_info.lfb_height, screen_info.lfb_linelength); 254 - 255 - 256 - return 1; 257 - } 258 40 259 41 static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, 260 42 unsigned blue, unsigned transp, ··· 96 312 default_vga = pdev; 97 313 } 98 314 99 - static int __init efifb_setup(char *options) 315 + static int efifb_setup(char *options) 100 316 { 101 317 char *this_opt; 102 318 int i; ··· 107 323 if (!*this_opt) continue; 108 324 109 325 for (i = 0; i < M_UNKNOWN; i++) { 110 - if (!strcmp(this_opt, dmi_list[i].optname) && 111 - dmi_list[i].base != 0) { 112 - screen_info.lfb_base = dmi_list[i].base; 113 - screen_info.lfb_linelength = dmi_list[i].stride; 114 - screen_info.lfb_width = dmi_list[i].width; 115 - screen_info.lfb_height = dmi_list[i].height; 326 + if (!strcmp(this_opt, efifb_dmi_list[i].optname) && 327 + efifb_dmi_list[i].base != 0) { 328 + screen_info.lfb_base = efifb_dmi_list[i].base; 329 + screen_info.lfb_linelength = efifb_dmi_list[i].stride; 330 + screen_info.lfb_width = efifb_dmi_list[i].width; 331 + screen_info.lfb_height = efifb_dmi_list[i].height; 116 332 } 117 333 } 118 334 if (!strncmp(this_opt, "base:", 5)) ··· 153 369 return 0; 154 370 } 155 371 156 - static int __init efifb_probe(struct platform_device *dev) 372 + static int efifb_probe(struct platform_device *dev) 157 373 { 158 374 struct fb_info *info; 159 375 int err; 160 376 unsigned int size_vmode; 161 377 unsigned int size_remap; 162 378 unsigned int size_total; 379 + char *option = NULL; 380 + 381 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 382 + return -ENODEV; 383 + 384 + if (fb_get_options("efifb", &option)) 385 + return -ENODEV; 386 + efifb_setup(option); 387 + 388 + /* We don't get linelength from UGA Draw Protocol, only from 389 + * EFI Graphics Protocol. So if it's not in DMI, and it's not 390 + * passed in from the user, we really can't use the framebuffer. 391 + */ 392 + if (!screen_info.lfb_linelength) 393 + return -ENODEV; 163 394 164 395 if (!screen_info.lfb_depth) 165 396 screen_info.lfb_depth = 32; ··· 338 539 } 339 540 340 541 static struct platform_driver efifb_driver = { 341 - .driver = { 342 - .name = "efifb", 542 + .driver = { 543 + .name = "efi-framebuffer", 544 + .owner = THIS_MODULE, 343 545 }, 546 + .probe = efifb_probe, 344 547 }; 345 548 346 - static struct platform_device efifb_device = { 347 - .name = "efifb", 348 - }; 349 - 350 - static int __init efifb_init(void) 351 - { 352 - int ret; 353 - char *option = NULL; 354 - 355 - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || 356 - !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) 357 - dmi_check_system(dmi_system_table); 358 - 359 - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 360 - return -ENODEV; 361 - 362 - if (fb_get_options("efifb", &option)) 363 - return -ENODEV; 364 - efifb_setup(option); 365 - 366 - /* We don't get linelength from UGA Draw Protocol, only from 367 - * EFI Graphics Protocol. So if it's not in DMI, and it's not 368 - * passed in from the user, we really can't use the framebuffer. 369 - */ 370 - if (!screen_info.lfb_linelength) 371 - return -ENODEV; 372 - 373 - ret = platform_device_register(&efifb_device); 374 - if (ret) 375 - return ret; 376 - 377 - /* 378 - * This is not just an optimization. We will interfere 379 - * with a real driver if we get reprobed, so don't allow 380 - * it. 381 - */ 382 - ret = platform_driver_probe(&efifb_driver, efifb_probe); 383 - if (ret) { 384 - platform_device_unregister(&efifb_device); 385 - return ret; 386 - } 387 - 388 - return ret; 389 - } 390 - module_init(efifb_init); 391 - 549 + module_platform_driver(efifb_driver); 392 550 MODULE_LICENSE("GPL");
+44 -14
drivers/video/simplefb.c
··· 24 24 #include <linux/fb.h> 25 25 #include <linux/io.h> 26 26 #include <linux/module.h> 27 + #include <linux/platform_data/simplefb.h> 27 28 #include <linux/platform_device.h> 28 29 29 30 static struct fb_fix_screeninfo simplefb_fix = { ··· 74 73 .fb_imageblit = cfb_imageblit, 75 74 }; 76 75 77 - struct simplefb_format { 78 - const char *name; 79 - u32 bits_per_pixel; 80 - struct fb_bitfield red; 81 - struct fb_bitfield green; 82 - struct fb_bitfield blue; 83 - struct fb_bitfield transp; 84 - }; 85 - 86 - static struct simplefb_format simplefb_formats[] = { 87 - { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, 88 - }; 76 + static struct simplefb_format simplefb_formats[] = SIMPLEFB_FORMATS; 89 77 90 78 struct simplefb_params { 91 79 u32 width; ··· 129 139 return 0; 130 140 } 131 141 142 + static int simplefb_parse_pd(struct platform_device *pdev, 143 + struct simplefb_params *params) 144 + { 145 + struct simplefb_platform_data *pd = pdev->dev.platform_data; 146 + int i; 147 + 148 + params->width = pd->width; 149 + params->height = pd->height; 150 + params->stride = pd->stride; 151 + 152 + params->format = NULL; 153 + for (i = 0; i < ARRAY_SIZE(simplefb_formats); i++) { 154 + if (strcmp(pd->format, simplefb_formats[i].name)) 155 + continue; 156 + 157 + params->format = &simplefb_formats[i]; 158 + break; 159 + } 160 + 161 + if (!params->format) { 162 + dev_err(&pdev->dev, "Invalid format value\n"); 163 + return -EINVAL; 164 + } 165 + 166 + return 0; 167 + } 168 + 132 169 static int simplefb_probe(struct platform_device *pdev) 133 170 { 134 171 int ret; ··· 166 149 if (fb_get_options("simplefb", NULL)) 167 150 return -ENODEV; 168 151 169 - ret = simplefb_parse_dt(pdev, &params); 152 + ret = -ENODEV; 153 + if (pdev->dev.platform_data) 154 + ret = simplefb_parse_pd(pdev, &params); 155 + else if (pdev->dev.of_node) 156 + ret = simplefb_parse_dt(pdev, &params); 157 + 170 158 if (ret) 171 159 return ret; 172 160 ··· 202 180 info->var.blue = params.format->blue; 203 181 info->var.transp = params.format->transp; 204 182 183 + info->apertures = alloc_apertures(1); 184 + if (!info->apertures) { 185 + framebuffer_release(info); 186 + return -ENOMEM; 187 + } 188 + info->apertures->ranges[0].base = info->fix.smem_start; 189 + info->apertures->ranges[0].size = info->fix.smem_len; 190 + 205 191 info->fbops = &simplefb_ops; 206 - info->flags = FBINFO_DEFAULT; 192 + info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE; 207 193 info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, 208 194 info->fix.smem_len); 209 195 if (!info->screen_base) {
+16 -39
drivers/video/vesafb.c
··· 29 29 30 30 /* --------------------------------------------------------------------- */ 31 31 32 - static struct fb_var_screeninfo vesafb_defined __initdata = { 32 + static struct fb_var_screeninfo vesafb_defined = { 33 33 .activate = FB_ACTIVATE_NOW, 34 34 .height = -1, 35 35 .width = -1, ··· 40 40 .vmode = FB_VMODE_NONINTERLACED, 41 41 }; 42 42 43 - static struct fb_fix_screeninfo vesafb_fix __initdata = { 43 + static struct fb_fix_screeninfo vesafb_fix = { 44 44 .id = "VESA VGA", 45 45 .type = FB_TYPE_PACKED_PIXELS, 46 46 .accel = FB_ACCEL_NONE, ··· 48 48 49 49 static int inverse __read_mostly; 50 50 static int mtrr __read_mostly; /* disable mtrr */ 51 - static int vram_remap __initdata; /* Set amount of memory to be used */ 52 - static int vram_total __initdata; /* Set total amount of memory */ 51 + static int vram_remap; /* Set amount of memory to be used */ 52 + static int vram_total; /* Set total amount of memory */ 53 53 static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ 54 54 static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ 55 55 static void (*pmi_start)(void) __read_mostly; ··· 192 192 .fb_imageblit = cfb_imageblit, 193 193 }; 194 194 195 - static int __init vesafb_setup(char *options) 195 + static int vesafb_setup(char *options) 196 196 { 197 197 char *this_opt; 198 198 ··· 226 226 return 0; 227 227 } 228 228 229 - static int __init vesafb_probe(struct platform_device *dev) 229 + static int vesafb_probe(struct platform_device *dev) 230 230 { 231 231 struct fb_info *info; 232 232 int i, err; 233 233 unsigned int size_vmode; 234 234 unsigned int size_remap; 235 235 unsigned int size_total; 236 + char *option = NULL; 237 + 238 + /* ignore error return of fb_get_options */ 239 + fb_get_options("vesafb", &option); 240 + vesafb_setup(option); 236 241 237 242 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) 238 243 return -ENODEV; ··· 501 496 } 502 497 503 498 static struct platform_driver vesafb_driver = { 504 - .driver = { 505 - .name = "vesafb", 499 + .driver = { 500 + .name = "vesa-framebuffer", 501 + .owner = THIS_MODULE, 506 502 }, 503 + .probe = vesafb_probe, 507 504 }; 508 505 509 - static struct platform_device *vesafb_device; 510 - 511 - static int __init vesafb_init(void) 512 - { 513 - int ret; 514 - char *option = NULL; 515 - 516 - /* ignore error return of fb_get_options */ 517 - fb_get_options("vesafb", &option); 518 - vesafb_setup(option); 519 - 520 - vesafb_device = platform_device_alloc("vesafb", 0); 521 - if (!vesafb_device) 522 - return -ENOMEM; 523 - 524 - ret = platform_device_add(vesafb_device); 525 - if (!ret) { 526 - ret = platform_driver_probe(&vesafb_driver, vesafb_probe); 527 - if (ret) 528 - platform_device_del(vesafb_device); 529 - } 530 - 531 - if (ret) { 532 - platform_device_put(vesafb_device); 533 - vesafb_device = NULL; 534 - } 535 - 536 - return ret; 537 - } 538 - module_init(vesafb_init); 539 - 506 + module_platform_driver(vesafb_driver); 540 507 MODULE_LICENSE("GPL");
+63
include/linux/platform_data/simplefb.h
··· 1 + /* 2 + * simplefb.h - Simple Framebuffer Device 3 + * 4 + * Copyright (C) 2013 David Herrmann <dh.herrmann@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + */ 11 + 12 + #ifndef __PLATFORM_DATA_SIMPLEFB_H__ 13 + #define __PLATFORM_DATA_SIMPLEFB_H__ 14 + 15 + #include <drm/drm_fourcc.h> 16 + #include <linux/fb.h> 17 + #include <linux/kernel.h> 18 + 19 + /* format array, use it to initialize a "struct simplefb_format" array */ 20 + #define SIMPLEFB_FORMATS \ 21 + { \ 22 + { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0}, DRM_FORMAT_RGB565 }, \ 23 + { "x1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {0, 0}, DRM_FORMAT_XRGB1555 }, \ 24 + { "a1r5g5b5", 16, {10, 5}, {5, 5}, {0, 5}, {15, 1}, DRM_FORMAT_ARGB1555 }, \ 25 + { "r8g8b8", 24, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_RGB888 }, \ 26 + { "x8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {0, 0}, DRM_FORMAT_XRGB8888 }, \ 27 + { "a8r8g8b8", 32, {16, 8}, {8, 8}, {0, 8}, {24, 8}, DRM_FORMAT_ARGB8888 }, \ 28 + { "x2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {0, 0}, DRM_FORMAT_XRGB2101010 }, \ 29 + { "a2r10g10b10", 32, {20, 10}, {10, 10}, {0, 10}, {30, 2}, DRM_FORMAT_ARGB2101010 }, \ 30 + } 31 + 32 + /* 33 + * Data-Format for Simple-Framebuffers 34 + * @name: unique 0-terminated name that can be used to identify the mode 35 + * @red,green,blue: Offsets and sizes of the single RGB parts 36 + * @transp: Offset and size of the alpha bits. length=0 means no alpha 37 + * @fourcc: 32bit DRM four-CC code (see drm_fourcc.h) 38 + */ 39 + struct simplefb_format { 40 + const char *name; 41 + u32 bits_per_pixel; 42 + struct fb_bitfield red; 43 + struct fb_bitfield green; 44 + struct fb_bitfield blue; 45 + struct fb_bitfield transp; 46 + u32 fourcc; 47 + }; 48 + 49 + /* 50 + * Simple-Framebuffer description 51 + * If the arch-boot code creates simple-framebuffers without DT support, it 52 + * can pass the width, height, stride and format via this platform-data object. 53 + * The framebuffer location must be given as IORESOURCE_MEM resource. 54 + * @format must be a format as described in "struct simplefb_format" above. 55 + */ 56 + struct simplefb_platform_data { 57 + u32 width; 58 + u32 height; 59 + u32 stride; 60 + const char *format; 61 + }; 62 + 63 + #endif /* __PLATFORM_DATA_SIMPLEFB_H__ */