93604a5ade
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
134 lines
3.1 KiB
C
134 lines
3.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Based on the fbdev code in drivers/video/fbdev/core/fb_cmdline:
|
|
*
|
|
* Copyright (C) 2014 Intel Corp
|
|
* Copyright (C) 1994 Martin Schaller
|
|
*
|
|
* 2001 - Documented with DocBook
|
|
* - Brad Douglas <brad@neruo.com>
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file COPYING in the main directory of this archive
|
|
* for more details.
|
|
*
|
|
* Authors:
|
|
* Daniel Vetter <daniel.vetter@ffwll.ch>
|
|
*/
|
|
|
|
#include <linux/fb.h> /* for FB_MAX */
|
|
#include <linux/init.h>
|
|
|
|
#include <video/cmdline.h>
|
|
|
|
/*
|
|
* FB_MAX is the maximum number of framebuffer devices and also
|
|
* the maximum number of video= parameters. Although not directly
|
|
* related to each other, it makes sense to keep it that way.
|
|
*/
|
|
static const char *video_options[FB_MAX] __read_mostly;
|
|
static const char *video_option __read_mostly;
|
|
static int video_of_only __read_mostly;
|
|
|
|
static const char *__video_get_option_string(const char *name)
|
|
{
|
|
const char *options = NULL;
|
|
size_t name_len = 0;
|
|
|
|
if (name)
|
|
name_len = strlen(name);
|
|
|
|
if (name_len) {
|
|
unsigned int i;
|
|
const char *opt;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(video_options); ++i) {
|
|
if (!video_options[i])
|
|
continue;
|
|
if (video_options[i][0] == '\0')
|
|
continue;
|
|
opt = video_options[i];
|
|
if (!strncmp(opt, name, name_len) && opt[name_len] == ':')
|
|
options = opt + name_len + 1;
|
|
}
|
|
}
|
|
|
|
/* No match, return global options */
|
|
if (!options)
|
|
options = video_option;
|
|
|
|
return options;
|
|
}
|
|
|
|
/**
|
|
* video_get_options - get kernel boot parameters
|
|
* @name: name of the output as it would appear in the boot parameter
|
|
* line (video=<name>:<options>)
|
|
*
|
|
* Looks up the video= options for the given name. Names are connector
|
|
* names with DRM, or driver names with fbdev. If no video option for
|
|
* the name has been specified, the function returns the global video=
|
|
* setting. A @name of NULL always returns the global video setting.
|
|
*
|
|
* Returns:
|
|
* The string of video options for the given name, or NULL if no video
|
|
* option has been specified.
|
|
*/
|
|
const char *video_get_options(const char *name)
|
|
{
|
|
return __video_get_option_string(name);
|
|
}
|
|
EXPORT_SYMBOL(video_get_options);
|
|
|
|
bool __video_get_options(const char *name, const char **options, bool is_of)
|
|
{
|
|
bool enabled = true;
|
|
const char *opt = NULL;
|
|
|
|
if (video_of_only && !is_of)
|
|
enabled = false;
|
|
|
|
opt = __video_get_option_string(name);
|
|
|
|
if (options)
|
|
*options = opt;
|
|
|
|
return enabled;
|
|
}
|
|
EXPORT_SYMBOL(__video_get_options);
|
|
|
|
/*
|
|
* Process command line options for video adapters. This function is
|
|
* a __setup and __init function. It only stores the options. Drivers
|
|
* have to call video_get_options() as necessary.
|
|
*/
|
|
static int __init video_setup(char *options)
|
|
{
|
|
if (!options || !*options)
|
|
goto out;
|
|
|
|
if (!strncmp(options, "ofonly", 6)) {
|
|
video_of_only = true;
|
|
goto out;
|
|
}
|
|
|
|
if (strchr(options, ':')) {
|
|
/* named */
|
|
size_t i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(video_options); i++) {
|
|
if (!video_options[i]) {
|
|
video_options[i] = options;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
/* global */
|
|
video_option = options;
|
|
}
|
|
|
|
out:
|
|
return 1;
|
|
}
|
|
__setup("video=", video_setup);
|