mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-30 15:50:10 -04:00
drm/modes: Move named modes parsing to a separate function
The current construction of the named mode parsing doesn't allow to extend it easily. Let's move it to a separate function so we can add more parameters and modes. In order for the tests to still pass, some extra checks are needed, so it's not a 1:1 move. Reviewed-by: Noralf Trønnes <noralf@tronnes.org> Tested-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com> Link: https://lore.kernel.org/r/20220728-rpi-analog-tv-properties-v9-9-24b168e5bcd5@cerno.tech Signed-off-by: Maxime Ripard <maxime@cerno.tech>
This commit is contained in:
@@ -1755,6 +1755,51 @@ static const char * const drm_named_modes_whitelist[] = {
|
||||
"PAL",
|
||||
};
|
||||
|
||||
static int drm_mode_parse_cmdline_named_mode(const char *name,
|
||||
unsigned int name_end,
|
||||
struct drm_cmdline_mode *cmdline_mode)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!name_end)
|
||||
return 0;
|
||||
|
||||
/* If the name starts with a digit, it's not a named mode */
|
||||
if (isdigit(name[0]))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If there's an equal sign in the name, the command-line
|
||||
* contains only an option and no mode.
|
||||
*/
|
||||
if (strnchr(name, name_end, '='))
|
||||
return 0;
|
||||
|
||||
/* The connection status extras can be set without a mode. */
|
||||
if (name_end == 1 &&
|
||||
(name[0] == 'd' || name[0] == 'D' || name[0] == 'e'))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We're sure we're a named mode at this point, iterate over the
|
||||
* list of modes we're aware of.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
|
||||
int ret;
|
||||
|
||||
ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
|
||||
if (ret != name_end)
|
||||
continue;
|
||||
|
||||
strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
|
||||
cmdline_mode->specified = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector
|
||||
* @mode_option: optional per connector mode option
|
||||
@@ -1791,7 +1836,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
|
||||
const char *options_ptr = NULL;
|
||||
char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL;
|
||||
int i, len, ret;
|
||||
int len, ret;
|
||||
|
||||
memset(mode, 0, sizeof(*mode));
|
||||
mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
|
||||
@@ -1832,18 +1877,19 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
|
||||
parse_extras = true;
|
||||
}
|
||||
|
||||
/* First check for a named mode */
|
||||
for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
|
||||
ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
|
||||
if (ret == mode_end) {
|
||||
if (refresh_ptr)
|
||||
return false; /* named + refresh is invalid */
|
||||
if (!mode_end)
|
||||
return false;
|
||||
|
||||
strcpy(mode->name, drm_named_modes_whitelist[i]);
|
||||
mode->specified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = drm_mode_parse_cmdline_named_mode(name, mode_end, mode);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Having a mode that starts by a letter (and thus is named) and
|
||||
* an at-sign (used to specify a refresh rate) is disallowed.
|
||||
*/
|
||||
if (ret && refresh_ptr)
|
||||
return false;
|
||||
|
||||
/* No named mode? Check for a normal mode argument, e.g. 1024x768 */
|
||||
if (!mode->specified && isdigit(name[0])) {
|
||||
|
||||
Reference in New Issue
Block a user