Line data Source code
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 12 : static const char *__video_get_option_string(const char *name) 34 : { 35 12 : const char *options = NULL; 36 12 : size_t name_len = 0; 37 : 38 12 : if (name) 39 12 : name_len = strlen(name); 40 : 41 12 : if (name_len) { 42 : unsigned int i; 43 : const char *opt; 44 : 45 384 : for (i = 0; i < ARRAY_SIZE(video_options); ++i) { 46 384 : if (!video_options[i]) 47 384 : continue; 48 0 : if (video_options[i][0] == '\0') 49 0 : continue; 50 0 : opt = video_options[i]; 51 0 : if (!strncmp(opt, name, name_len) && opt[name_len] == ':') 52 0 : options = opt + name_len + 1; 53 : } 54 : } 55 : 56 : /* No match, return global options */ 57 12 : if (!options) 58 12 : options = video_option; 59 : 60 12 : 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 12 : const char *video_get_options(const char *name) 78 : { 79 12 : return __video_get_option_string(name); 80 : } 81 : EXPORT_SYMBOL(video_get_options); 82 : 83 0 : bool __video_get_options(const char *name, const char **options, bool is_of) 84 : { 85 0 : bool enabled = true; 86 0 : const char *opt = NULL; 87 : 88 0 : if (video_of_only && !is_of) 89 0 : enabled = false; 90 : 91 0 : opt = __video_get_option_string(name); 92 : 93 0 : if (options) 94 0 : *options = opt; 95 : 96 0 : 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 0 : static int __init video_setup(char *options) 106 : { 107 0 : if (!options || !*options) 108 : goto out; 109 : 110 0 : if (!strncmp(options, "ofonly", 6)) { 111 0 : video_of_only = true; 112 0 : goto out; 113 : } 114 : 115 0 : if (strchr(options, ':')) { 116 : /* named */ 117 : size_t i; 118 : 119 0 : for (i = 0; i < ARRAY_SIZE(video_options); i++) { 120 0 : if (!video_options[i]) { 121 0 : video_options[i] = options; 122 0 : break; 123 : } 124 : } 125 : } else { 126 : /* global */ 127 0 : video_option = options; 128 : } 129 : 130 : out: 131 0 : return 1; 132 : } 133 : __setup("video=", video_setup);