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

fbdev: Handle video= parameter in video/cmdline.c

Handle the command-line parameter video= in video/cmdline.c. Implement
the fbdev helper fb_get_options() on top. Will allows to handle the
kernel parameter in DRM without fbdev dependencies.

Note that __video_get_options() has the meaning of its return value
inverted compared to fb_get_options(). The new helper returns true if
the adapter has been enabled, and false otherwise.

There is the ofonly parameter, which disables output for non-OF-based
framebuffers. It is only for offb and looks like a workaround. The actual
purpose it not clear to me. Use 'video=off' or 'nomodeset' instead.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230209135509.7786-9-tzimmermann@suse.de

+172 -88
+1 -1
drivers/gpu/drm/Kconfig
··· 10 10 depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA 11 11 select DRM_PANEL_ORIENTATION_QUIRKS 12 12 select HDMI 13 - select FB_CMDLINE 14 13 select I2C 15 14 select DMA_SHARED_BUFFER 16 15 select SYNC_FILE 17 16 # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate 18 17 # device and dmabuf fd. Let's make sure that is available for our userspace. 19 18 select KCMP 19 + select VIDEO_CMDLINE 20 20 select VIDEO_NOMODESET 21 21 help 22 22 Kernel-level support for the Direct Rendering Infrastructure (DRI)
+3
drivers/video/Kconfig
··· 11 11 Support tracking and hand-over of aperture ownership. Required 12 12 by graphics drivers for firmware-provided framebuffers. 13 13 14 + config VIDEO_CMDLINE 15 + bool 16 + 14 17 config VIDEO_NOMODESET 15 18 bool 16 19 default n
+1
drivers/video/Makefile
··· 2 2 3 3 obj-$(CONFIG_APERTURE_HELPERS) += aperture.o 4 4 obj-$(CONFIG_VGASTATE) += vgastate.o 5 + obj-$(CONFIG_VIDEO_CMDLINE) += cmdline.o 5 6 obj-$(CONFIG_VIDEO_NOMODESET) += nomodeset.o 6 7 obj-$(CONFIG_HDMI) += hdmi.o 7 8
+133
drivers/video/cmdline.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Based on the fbdev code in drivers/video/fbdev/core/fb_cmdline: 4 + * 5 + * Copyright (C) 2014 Intel Corp 6 + * Copyright (C) 1994 Martin Schaller 7 + * 8 + * 2001 - Documented with DocBook 9 + * - Brad Douglas <brad@neruo.com> 10 + * 11 + * This file is subject to the terms and conditions of the GNU General Public 12 + * License. See the file COPYING in the main directory of this archive 13 + * for more details. 14 + * 15 + * Authors: 16 + * Daniel Vetter <daniel.vetter@ffwll.ch> 17 + */ 18 + 19 + #include <linux/fb.h> /* for FB_MAX */ 20 + #include <linux/init.h> 21 + 22 + #include <video/cmdline.h> 23 + 24 + /* 25 + * FB_MAX is the maximum number of framebuffer devices and also 26 + * the maximum number of video= parameters. Although not directly 27 + * related to each other, it makes sense to keep it that way. 28 + */ 29 + static const char *video_options[FB_MAX] __read_mostly; 30 + static const char *video_option __read_mostly; 31 + static int video_of_only __read_mostly; 32 + 33 + static const char *__video_get_option_string(const char *name) 34 + { 35 + const char *options = NULL; 36 + size_t name_len = 0; 37 + 38 + if (name) 39 + name_len = strlen(name); 40 + 41 + if (name_len) { 42 + unsigned int i; 43 + const char *opt; 44 + 45 + for (i = 0; i < ARRAY_SIZE(video_options); ++i) { 46 + if (!video_options[i]) 47 + continue; 48 + if (video_options[i][0] == '\0') 49 + continue; 50 + opt = video_options[i]; 51 + if (!strncmp(opt, name, name_len) && opt[name_len] == ':') 52 + options = opt + name_len + 1; 53 + } 54 + } 55 + 56 + /* No match, return global options */ 57 + if (!options) 58 + options = video_option; 59 + 60 + return options; 61 + } 62 + 63 + /** 64 + * video_get_options - get kernel boot parameters 65 + * @name: name of the output as it would appear in the boot parameter 66 + * line (video=<name>:<options>) 67 + * 68 + * Looks up the video= options for the given name. Names are connector 69 + * names with DRM, or driver names with fbdev. If no video option for 70 + * the name has been specified, the function returns the global video= 71 + * setting. A @name of NULL always returns the global video setting. 72 + * 73 + * Returns: 74 + * The string of video options for the given name, or NULL if no video 75 + * option has been specified. 76 + */ 77 + const char *video_get_options(const char *name) 78 + { 79 + return __video_get_option_string(name); 80 + } 81 + EXPORT_SYMBOL(video_get_options); 82 + 83 + bool __video_get_options(const char *name, const char **options, bool is_of) 84 + { 85 + bool enabled = true; 86 + const char *opt = NULL; 87 + 88 + if (video_of_only && !is_of) 89 + enabled = false; 90 + 91 + opt = __video_get_option_string(name); 92 + 93 + if (options) 94 + *options = opt; 95 + 96 + return enabled; 97 + } 98 + EXPORT_SYMBOL(__video_get_options); 99 + 100 + /* 101 + * Process command line options for video adapters. This function is 102 + * a __setup and __init function. It only stores the options. Drivers 103 + * have to call video_get_options() as necessary. 104 + */ 105 + static int __init video_setup(char *options) 106 + { 107 + if (!options || !*options) 108 + goto out; 109 + 110 + if (!strncmp(options, "ofonly", 6)) { 111 + video_of_only = true; 112 + goto out; 113 + } 114 + 115 + if (strchr(options, ':')) { 116 + /* named */ 117 + size_t i; 118 + 119 + for (i = 0; i < ARRAY_SIZE(video_options); i++) { 120 + if (!video_options[i]) { 121 + video_options[i] = options; 122 + break; 123 + } 124 + } 125 + } else { 126 + /* global */ 127 + video_option = options; 128 + } 129 + 130 + out: 131 + return 1; 132 + } 133 + __setup("video=", video_setup);
+1 -4
drivers/video/fbdev/Kconfig
··· 3 3 # fbdev configuration 4 4 # 5 5 6 - config FB_CMDLINE 7 - bool 8 - 9 6 config FB_NOTIFY 10 7 bool 11 8 12 9 menuconfig FB 13 10 tristate "Support for frame buffer devices" 14 - select FB_CMDLINE 15 11 select FB_NOTIFY 12 + select VIDEO_CMDLINE 16 13 help 17 14 The frame buffer device provides an abstraction for the graphics 18 15 hardware. It represents the frame buffer of some video hardware and
+1 -2
drivers/video/fbdev/core/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 - obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o 3 2 obj-$(CONFIG_FB_NOTIFY) += fb_notify.o 4 3 obj-$(CONFIG_FB) += fb.o 5 4 fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ 6 - modedb.o fbcvt.o 5 + modedb.o fbcvt.o fb_cmdline.o 7 6 fb-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o 8 7 9 8 ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE),y)
+12 -81
drivers/video/fbdev/core/fb_cmdline.c
··· 14 14 * Authors: 15 15 * Daniel Vetter <daniel.vetter@ffwll.ch> 16 16 */ 17 - #include <linux/init.h> 17 + 18 + #include <linux/export.h> 18 19 #include <linux/fb.h> 20 + #include <linux/string.h> 19 21 20 - static char *video_options[FB_MAX] __read_mostly; 21 - static const char *fb_mode_option __read_mostly; 22 - static int ofonly __read_mostly; 23 - 24 - static const char *__fb_get_options(const char *name) 25 - { 26 - const char *options = NULL; 27 - size_t name_len = 0; 28 - 29 - if (name) 30 - name_len = strlen(name); 31 - 32 - if (name_len) { 33 - unsigned int i; 34 - const char *opt; 35 - 36 - for (i = 0; i < ARRAY_SIZE(video_options); ++i) { 37 - if (!video_options[i]) 38 - continue; 39 - if (video_options[i][0] == '\0') 40 - continue; 41 - opt = video_options[i]; 42 - if (!strncmp(opt, name, name_len) && opt[name_len] == ':') 43 - options = opt + name_len + 1; 44 - } 45 - } 46 - 47 - /* No match, return global options */ 48 - if (!options) 49 - options = fb_mode_option; 50 - 51 - return options; 52 - } 22 + #include <video/cmdline.h> 53 23 54 24 /** 55 25 * fb_get_options - get kernel boot parameters ··· 35 65 */ 36 66 int fb_get_options(const char *name, char **option) 37 67 { 38 - int retval = 0; 39 - const char *options; 68 + const char *options = NULL; 69 + bool is_of = false; 70 + bool enabled; 40 71 41 - if (name && ofonly && strncmp(name, "offb", 4)) 42 - retval = 1; 72 + if (name) 73 + is_of = strncmp(name, "offb", 4); 43 74 44 - options = __fb_get_options(name); 75 + enabled = __video_get_options(name, &options, is_of); 45 76 46 77 if (options) { 47 78 if (!strncmp(options, "off", 3)) 48 - retval = 1; 79 + enabled = false; 49 80 } 50 81 51 82 if (option) { ··· 56 85 *option = NULL; 57 86 } 58 87 59 - return retval; 88 + return enabled ? 0 : 1; // 0 on success, 1 otherwise 60 89 } 61 90 EXPORT_SYMBOL(fb_get_options); 62 - 63 - /** 64 - * video_setup - process command line options 65 - * @options: string of options 66 - * 67 - * Process command line options for frame buffer subsystem. 68 - * 69 - * NOTE: This function is a __setup and __init function. 70 - * It only stores the options. Drivers have to call 71 - * fb_get_options() as necessary. 72 - */ 73 - static int __init video_setup(char *options) 74 - { 75 - if (!options || !*options) 76 - goto out; 77 - 78 - if (!strncmp(options, "ofonly", 6)) { 79 - ofonly = 1; 80 - goto out; 81 - } 82 - 83 - if (strchr(options, ':')) { 84 - /* named */ 85 - int i; 86 - 87 - for (i = 0; i < FB_MAX; i++) { 88 - if (video_options[i] == NULL) { 89 - video_options[i] = options; 90 - break; 91 - } 92 - } 93 - } else { 94 - /* global */ 95 - fb_mode_option = options; 96 - } 97 - 98 - out: 99 - return 1; 100 - } 101 - __setup("video=", video_setup);
+20
include/video/cmdline.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef VIDEO_CMDLINE_H 4 + #define VIDEO_CMDLINE_H 5 + 6 + #include <linux/types.h> 7 + 8 + #if defined(CONFIG_VIDEO_CMDLINE) 9 + const char *video_get_options(const char *name); 10 + 11 + /* exported for compatibility with fbdev; don't use in new code */ 12 + bool __video_get_options(const char *name, const char **option, bool is_of); 13 + #else 14 + static inline const char *video_get_options(const char *name) 15 + { 16 + return NULL; 17 + } 18 + #endif 19 + 20 + #endif