X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0669-drm-modes-Rewrite-the-command-line-parser.patch;fp=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0669-drm-modes-Rewrite-the-command-line-parser.patch;h=0000000000000000000000000000000000000000;hb=c2308a7e4adbb2acc8ff149f91d1ca46801c135e;hp=24c25d694409b1465426efcb840b47087066416b;hpb=67dcc43f3a22dc3a7ac07a7065971b426feeb043;p=openwrt%2Fstaging%2Fchunkeey.git diff --git a/target/linux/brcm2708/patches-4.19/950-0669-drm-modes-Rewrite-the-command-line-parser.patch b/target/linux/brcm2708/patches-4.19/950-0669-drm-modes-Rewrite-the-command-line-parser.patch deleted file mode 100644 index 24c25d6944..0000000000 --- a/target/linux/brcm2708/patches-4.19/950-0669-drm-modes-Rewrite-the-command-line-parser.patch +++ /dev/null @@ -1,392 +0,0 @@ -From 3508a8548f13be68b6d098ad99a7bc1fc1810f76 Mon Sep 17 00:00:00 2001 -From: Maxime Ripard -Date: Wed, 19 Jun 2019 12:17:49 +0200 -Subject: [PATCH] drm/modes: Rewrite the command line parser -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -commit e08ab74bd4c7a5fe311bc05f32dbb4f1e7fa3428 upstream. - -Rewrite the command line parser in order to get away from the state machine -parsing the video mode lines. - -Hopefully, this will allow to extend it more easily to support named modes -and / or properties set directly on the command line. - -Reviewed-by: Noralf Trønnes -Signed-off-by: Maxime Ripard -Link: https://patchwork.freedesktop.org/patch/msgid/e32cd4009153b184103554009135c7bf7c9975d7.1560783090.git-series.maxime.ripard@bootlin.com ---- - drivers/gpu/drm/drm_modes.c | 325 +++++++++++++++++++++++------------- - 1 file changed, 210 insertions(+), 115 deletions(-) - ---- a/drivers/gpu/drm/drm_modes.c -+++ b/drivers/gpu/drm/drm_modes.c -@@ -30,6 +30,7 @@ - * authorization from the copyright holder(s) and author(s). - */ - -+#include - #include - #include - #include -@@ -1414,6 +1415,151 @@ void drm_connector_list_update(struct dr - } - EXPORT_SYMBOL(drm_connector_list_update); - -+static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr, -+ struct drm_cmdline_mode *mode) -+{ -+ unsigned int bpp; -+ -+ if (str[0] != '-') -+ return -EINVAL; -+ -+ str++; -+ bpp = simple_strtol(str, end_ptr, 10); -+ if (*end_ptr == str) -+ return -EINVAL; -+ -+ mode->bpp = bpp; -+ mode->bpp_specified = true; -+ -+ return 0; -+} -+ -+static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr, -+ struct drm_cmdline_mode *mode) -+{ -+ unsigned int refresh; -+ -+ if (str[0] != '@') -+ return -EINVAL; -+ -+ str++; -+ refresh = simple_strtol(str, end_ptr, 10); -+ if (*end_ptr == str) -+ return -EINVAL; -+ -+ mode->refresh = refresh; -+ mode->refresh_specified = true; -+ -+ return 0; -+} -+ -+static int drm_mode_parse_cmdline_extra(const char *str, int length, -+ struct drm_connector *connector, -+ struct drm_cmdline_mode *mode) -+{ -+ int i; -+ -+ for (i = 0; i < length; i++) { -+ switch (str[i]) { -+ case 'i': -+ mode->interlace = true; -+ break; -+ case 'm': -+ mode->margins = true; -+ break; -+ case 'D': -+ if (mode->force != DRM_FORCE_UNSPECIFIED) -+ return -EINVAL; -+ -+ if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && -+ (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) -+ mode->force = DRM_FORCE_ON; -+ else -+ mode->force = DRM_FORCE_ON_DIGITAL; -+ break; -+ case 'd': -+ if (mode->force != DRM_FORCE_UNSPECIFIED) -+ return -EINVAL; -+ -+ mode->force = DRM_FORCE_OFF; -+ break; -+ case 'e': -+ if (mode->force != DRM_FORCE_UNSPECIFIED) -+ return -EINVAL; -+ -+ mode->force = DRM_FORCE_ON; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length, -+ bool extras, -+ struct drm_connector *connector, -+ struct drm_cmdline_mode *mode) -+{ -+ const char *str_start = str; -+ bool rb = false, cvt = false; -+ int xres = 0, yres = 0; -+ int remaining, i; -+ char *end_ptr; -+ -+ xres = simple_strtol(str, &end_ptr, 10); -+ if (end_ptr == str) -+ return -EINVAL; -+ -+ if (end_ptr[0] != 'x') -+ return -EINVAL; -+ end_ptr++; -+ -+ str = end_ptr; -+ yres = simple_strtol(str, &end_ptr, 10); -+ if (end_ptr == str) -+ return -EINVAL; -+ -+ remaining = length - (end_ptr - str_start); -+ if (remaining < 0) -+ return -EINVAL; -+ -+ for (i = 0; i < remaining; i++) { -+ switch (end_ptr[i]) { -+ case 'M': -+ cvt = true; -+ break; -+ case 'R': -+ rb = true; -+ break; -+ default: -+ /* -+ * Try to pass that to our extras parsing -+ * function to handle the case where the -+ * extras are directly after the resolution -+ */ -+ if (extras) { -+ int ret = drm_mode_parse_cmdline_extra(end_ptr + i, -+ 1, -+ connector, -+ mode); -+ if (ret) -+ return ret; -+ } else { -+ return -EINVAL; -+ } -+ } -+ } -+ -+ mode->xres = xres; -+ mode->yres = yres; -+ mode->cvt = cvt; -+ mode->rb = rb; -+ -+ return 0; -+} -+ - /** - * drm_mode_parse_command_line_for_connector - parse command line modeline for connector - * @mode_option: optional per connector mode option -@@ -1440,13 +1586,12 @@ bool drm_mode_parse_command_line_for_con - struct drm_cmdline_mode *mode) - { - const char *name; -- unsigned int namelen; -- bool res_specified = false, bpp_specified = false, refresh_specified = false; -- unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; -- bool yres_specified = false, cvt = false, rb = false; -- bool interlace = false, margins = false, was_digit = false; -- int i; -- enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; -+ bool parse_extras = false; -+ unsigned int bpp_off = 0, refresh_off = 0; -+ unsigned int mode_end = 0; -+ char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; -+ char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL; -+ int ret; - - #ifdef CONFIG_FB - if (!mode_option) -@@ -1459,127 +1604,77 @@ bool drm_mode_parse_command_line_for_con - } - - name = mode_option; -- namelen = strlen(name); -- for (i = namelen-1; i >= 0; i--) { -- switch (name[i]) { -- case '@': -- if (!refresh_specified && !bpp_specified && -- !yres_specified && !cvt && !rb && was_digit) { -- refresh = simple_strtol(&name[i+1], NULL, 10); -- refresh_specified = true; -- was_digit = false; -- } else -- goto done; -- break; -- case '-': -- if (!bpp_specified && !yres_specified && !cvt && -- !rb && was_digit) { -- bpp = simple_strtol(&name[i+1], NULL, 10); -- bpp_specified = true; -- was_digit = false; -- } else -- goto done; -- break; -- case 'x': -- if (!yres_specified && was_digit) { -- yres = simple_strtol(&name[i+1], NULL, 10); -- yres_specified = true; -- was_digit = false; -- } else -- goto done; -- break; -- case '0' ... '9': -- was_digit = true; -- break; -- case 'M': -- if (yres_specified || cvt || was_digit) -- goto done; -- cvt = true; -- break; -- case 'R': -- if (yres_specified || cvt || rb || was_digit) -- goto done; -- rb = true; -- break; -- case 'm': -- if (cvt || yres_specified || was_digit) -- goto done; -- margins = true; -- break; -- case 'i': -- if (cvt || yres_specified || was_digit) -- goto done; -- interlace = true; -- break; -- case 'e': -- if (yres_specified || bpp_specified || refresh_specified || -- was_digit || (force != DRM_FORCE_UNSPECIFIED)) -- goto done; - -- force = DRM_FORCE_ON; -- break; -- case 'D': -- if (yres_specified || bpp_specified || refresh_specified || -- was_digit || (force != DRM_FORCE_UNSPECIFIED)) -- goto done; -+ if (!isdigit(name[0])) -+ return false; - -- if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && -- (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) -- force = DRM_FORCE_ON; -- else -- force = DRM_FORCE_ON_DIGITAL; -- break; -- case 'd': -- if (yres_specified || bpp_specified || refresh_specified || -- was_digit || (force != DRM_FORCE_UNSPECIFIED)) -- goto done; -+ /* Try to locate the bpp and refresh specifiers, if any */ -+ bpp_ptr = strchr(name, '-'); -+ if (bpp_ptr) { -+ bpp_off = bpp_ptr - name; -+ mode->bpp_specified = true; -+ } - -- force = DRM_FORCE_OFF; -- break; -- default: -- goto done; -- } -+ refresh_ptr = strchr(name, '@'); -+ if (refresh_ptr) { -+ refresh_off = refresh_ptr - name; -+ mode->refresh_specified = true; - } - -- if (i < 0 && yres_specified) { -- char *ch; -- xres = simple_strtol(name, &ch, 10); -- if ((ch != NULL) && (*ch == 'x')) -- res_specified = true; -- else -- i = ch - name; -- } else if (!yres_specified && was_digit) { -- /* catch mode that begins with digits but has no 'x' */ -- i = 0; -- } --done: -- if (i >= 0) { -- pr_warn("[drm] parse error at position %i in video mode '%s'\n", -- i, name); -- mode->specified = false; -- return false; -+ /* Locate the end of the name / resolution, and parse it */ -+ if (bpp_ptr && refresh_ptr) { -+ mode_end = min(bpp_off, refresh_off); -+ } else if (bpp_ptr) { -+ mode_end = bpp_off; -+ } else if (refresh_ptr) { -+ mode_end = refresh_off; -+ } else { -+ mode_end = strlen(name); -+ parse_extras = true; - } - -- if (res_specified) { -- mode->specified = true; -- mode->xres = xres; -- mode->yres = yres; -+ ret = drm_mode_parse_cmdline_res_mode(name, mode_end, -+ parse_extras, -+ connector, -+ mode); -+ if (ret) -+ return false; -+ mode->specified = true; -+ -+ if (bpp_ptr) { -+ ret = drm_mode_parse_cmdline_bpp(bpp_ptr, &bpp_end_ptr, mode); -+ if (ret) -+ return false; - } - -- if (refresh_specified) { -- mode->refresh_specified = true; -- mode->refresh = refresh; -+ if (refresh_ptr) { -+ ret = drm_mode_parse_cmdline_refresh(refresh_ptr, -+ &refresh_end_ptr, mode); -+ if (ret) -+ return false; - } - -- if (bpp_specified) { -- mode->bpp_specified = true; -- mode->bpp = bpp; -+ /* -+ * Locate the end of the bpp / refresh, and parse the extras -+ * if relevant -+ */ -+ if (bpp_ptr && refresh_ptr) -+ extra_ptr = max(bpp_end_ptr, refresh_end_ptr); -+ else if (bpp_ptr) -+ extra_ptr = bpp_end_ptr; -+ else if (refresh_ptr) -+ extra_ptr = refresh_end_ptr; -+ -+ if (extra_ptr) { -+ int remaining = strlen(name) - (extra_ptr - name); -+ -+ /* -+ * We still have characters to process, while -+ * we shouldn't have any -+ */ -+ if (remaining > 0) -+ return false; - } -- mode->rb = rb; -- mode->cvt = cvt; -- mode->interlace = interlace; -- mode->margins = margins; -- mode->force = force; - - return true; - }