diff options
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 87 |
1 files changed, 60 insertions, 27 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index c2d32f20e2fb..ad74fb4dc542 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -994,9 +994,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
994 | { | 994 | { |
995 | const char *name; | 995 | const char *name; |
996 | unsigned int namelen; | 996 | unsigned int namelen; |
997 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; | 997 | bool res_specified = false, bpp_specified = false, refresh_specified = false; |
998 | unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; | 998 | unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; |
999 | int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; | 999 | bool yres_specified = false, cvt = false, rb = false; |
1000 | bool interlace = false, margins = false, was_digit = false; | ||
1000 | int i; | 1001 | int i; |
1001 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; | 1002 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; |
1002 | 1003 | ||
@@ -1015,54 +1016,65 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1015 | for (i = namelen-1; i >= 0; i--) { | 1016 | for (i = namelen-1; i >= 0; i--) { |
1016 | switch (name[i]) { | 1017 | switch (name[i]) { |
1017 | case '@': | 1018 | case '@': |
1018 | namelen = i; | ||
1019 | if (!refresh_specified && !bpp_specified && | 1019 | if (!refresh_specified && !bpp_specified && |
1020 | !yres_specified) { | 1020 | !yres_specified && !cvt && !rb && was_digit) { |
1021 | refresh = simple_strtol(&name[i+1], NULL, 10); | 1021 | refresh = simple_strtol(&name[i+1], NULL, 10); |
1022 | refresh_specified = 1; | 1022 | refresh_specified = true; |
1023 | if (cvt || rb) | 1023 | was_digit = false; |
1024 | cvt = 0; | ||
1025 | } else | 1024 | } else |
1026 | goto done; | 1025 | goto done; |
1027 | break; | 1026 | break; |
1028 | case '-': | 1027 | case '-': |
1029 | namelen = i; | 1028 | if (!bpp_specified && !yres_specified && !cvt && |
1030 | if (!bpp_specified && !yres_specified) { | 1029 | !rb && was_digit) { |
1031 | bpp = simple_strtol(&name[i+1], NULL, 10); | 1030 | bpp = simple_strtol(&name[i+1], NULL, 10); |
1032 | bpp_specified = 1; | 1031 | bpp_specified = true; |
1033 | if (cvt || rb) | 1032 | was_digit = false; |
1034 | cvt = 0; | ||
1035 | } else | 1033 | } else |
1036 | goto done; | 1034 | goto done; |
1037 | break; | 1035 | break; |
1038 | case 'x': | 1036 | case 'x': |
1039 | if (!yres_specified) { | 1037 | if (!yres_specified && was_digit) { |
1040 | yres = simple_strtol(&name[i+1], NULL, 10); | 1038 | yres = simple_strtol(&name[i+1], NULL, 10); |
1041 | yres_specified = 1; | 1039 | yres_specified = true; |
1040 | was_digit = false; | ||
1042 | } else | 1041 | } else |
1043 | goto done; | 1042 | goto done; |
1044 | case '0' ... '9': | 1043 | case '0' ... '9': |
1044 | was_digit = true; | ||
1045 | break; | 1045 | break; |
1046 | case 'M': | 1046 | case 'M': |
1047 | if (!yres_specified) | 1047 | if (yres_specified || cvt || was_digit) |
1048 | cvt = 1; | 1048 | goto done; |
1049 | cvt = true; | ||
1049 | break; | 1050 | break; |
1050 | case 'R': | 1051 | case 'R': |
1051 | if (cvt) | 1052 | if (yres_specified || cvt || rb || was_digit) |
1052 | rb = 1; | 1053 | goto done; |
1054 | rb = true; | ||
1053 | break; | 1055 | break; |
1054 | case 'm': | 1056 | case 'm': |
1055 | if (!cvt) | 1057 | if (cvt || yres_specified || was_digit) |
1056 | margins = 1; | 1058 | goto done; |
1059 | margins = true; | ||
1057 | break; | 1060 | break; |
1058 | case 'i': | 1061 | case 'i': |
1059 | if (!cvt) | 1062 | if (cvt || yres_specified || was_digit) |
1060 | interlace = 1; | 1063 | goto done; |
1064 | interlace = true; | ||
1061 | break; | 1065 | break; |
1062 | case 'e': | 1066 | case 'e': |
1067 | if (yres_specified || bpp_specified || refresh_specified || | ||
1068 | was_digit || (force != DRM_FORCE_UNSPECIFIED)) | ||
1069 | goto done; | ||
1070 | |||
1063 | force = DRM_FORCE_ON; | 1071 | force = DRM_FORCE_ON; |
1064 | break; | 1072 | break; |
1065 | case 'D': | 1073 | case 'D': |
1074 | if (yres_specified || bpp_specified || refresh_specified || | ||
1075 | was_digit || (force != DRM_FORCE_UNSPECIFIED)) | ||
1076 | goto done; | ||
1077 | |||
1066 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && | 1078 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && |
1067 | (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) | 1079 | (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) |
1068 | force = DRM_FORCE_ON; | 1080 | force = DRM_FORCE_ON; |
@@ -1070,17 +1082,37 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, | |||
1070 | force = DRM_FORCE_ON_DIGITAL; | 1082 | force = DRM_FORCE_ON_DIGITAL; |
1071 | break; | 1083 | break; |
1072 | case 'd': | 1084 | case 'd': |
1085 | if (yres_specified || bpp_specified || refresh_specified || | ||
1086 | was_digit || (force != DRM_FORCE_UNSPECIFIED)) | ||
1087 | goto done; | ||
1088 | |||
1073 | force = DRM_FORCE_OFF; | 1089 | force = DRM_FORCE_OFF; |
1074 | break; | 1090 | break; |
1075 | default: | 1091 | default: |
1076 | goto done; | 1092 | goto done; |
1077 | } | 1093 | } |
1078 | } | 1094 | } |
1095 | |||
1079 | if (i < 0 && yres_specified) { | 1096 | if (i < 0 && yres_specified) { |
1080 | xres = simple_strtol(name, NULL, 10); | 1097 | char *ch; |
1081 | res_specified = 1; | 1098 | xres = simple_strtol(name, &ch, 10); |
1099 | if ((ch != NULL) && (*ch == 'x')) | ||
1100 | res_specified = true; | ||
1101 | else | ||
1102 | i = ch - name; | ||
1103 | } else if (!yres_specified && was_digit) { | ||
1104 | /* catch mode that begins with digits but has no 'x' */ | ||
1105 | i = 0; | ||
1082 | } | 1106 | } |
1083 | done: | 1107 | done: |
1108 | if (i >= 0) { | ||
1109 | printk(KERN_WARNING | ||
1110 | "parse error at position %i in video mode '%s'\n", | ||
1111 | i, name); | ||
1112 | mode->specified = false; | ||
1113 | return false; | ||
1114 | } | ||
1115 | |||
1084 | if (res_specified) { | 1116 | if (res_specified) { |
1085 | mode->specified = true; | 1117 | mode->specified = true; |
1086 | mode->xres = xres; | 1118 | mode->xres = xres; |
@@ -1096,9 +1128,10 @@ done: | |||
1096 | mode->bpp_specified = true; | 1128 | mode->bpp_specified = true; |
1097 | mode->bpp = bpp; | 1129 | mode->bpp = bpp; |
1098 | } | 1130 | } |
1099 | mode->rb = rb ? true : false; | 1131 | mode->rb = rb; |
1100 | mode->cvt = cvt ? true : false; | 1132 | mode->cvt = cvt; |
1101 | mode->interlace = interlace ? true : false; | 1133 | mode->interlace = interlace; |
1134 | mode->margins = margins; | ||
1102 | mode->force = force; | 1135 | mode->force = force; |
1103 | 1136 | ||
1104 | return true; | 1137 | return true; |