summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Paauwe <bob.j.paauwe@intel.com>2015-08-27 13:04:13 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-09-08 07:45:51 -0400
commit96206e2922c114b13cadefa03b9f340b58fee13c (patch)
tree7c3853455297f4511fa7aba5337f229fbf84f1ef
parentf8aeb41c4b7e9de0a4df4ed1ba78cd6ee5c87281 (diff)
dtrm/edid: Allow comma separated edid binaries. (v3)
Allow comma separated filenames in the edid_firmware parameter. For example: edid_firmware=eDP-1:edid/1280x480.bin,DP-2:edid/1920x1080.bin v2: Use strsep() to simplify parsing of comma seperated string. (Matt) Move initial bail before strdup. (Matt) v3: Changed conditionals after while loop to make more readable (Jani) Updated kernel-parameters.txt to reflect changes (Jani) Reviewed-by: Jani Nikula <jani.nikula@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Bob Paauwe <bob.j.paauwe@intel.com> [danvet: Flatten else control flow and appease checkpatch.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--Documentation/kernel-parameters.txt15
-rw-r--r--drivers/gpu/drm/drm_edid_load.c41
2 files changed, 42 insertions, 14 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 1d6f0459cd7b..caf0fd4cdecd 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -927,11 +927,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
927 The filter can be disabled or changed to another 927 The filter can be disabled or changed to another
928 driver later using sysfs. 928 driver later using sysfs.
929 929
930 drm_kms_helper.edid_firmware=[<connector>:]<file> 930 drm_kms_helper.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
931 Broken monitors, graphic adapters and KVMs may 931 Broken monitors, graphic adapters, KVMs and EDIDless
932 send no or incorrect EDID data sets. This parameter 932 panels may send no or incorrect EDID data sets.
933 allows to specify an EDID data set in the 933 This parameter allows to specify an EDID data sets
934 /lib/firmware directory that is used instead. 934 in the /lib/firmware directory that are used instead.
935 Generic built-in EDID data sets are used, if one of 935 Generic built-in EDID data sets are used, if one of
936 edid/1024x768.bin, edid/1280x1024.bin, 936 edid/1024x768.bin, edid/1280x1024.bin,
937 edid/1680x1050.bin, or edid/1920x1080.bin is given 937 edid/1680x1050.bin, or edid/1920x1080.bin is given
@@ -940,7 +940,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
940 available in Documentation/EDID/HOWTO.txt. An EDID 940 available in Documentation/EDID/HOWTO.txt. An EDID
941 data set will only be used for a particular connector, 941 data set will only be used for a particular connector,
942 if its name and a colon are prepended to the EDID 942 if its name and a colon are prepended to the EDID
943 name. 943 name. Each connector may use a unique EDID data
944 set by separating the files with a comma. An EDID
945 data set with no connector name will be used for
946 any connectors not explicitly specified.
944 947
945 dscc4.setup= [NET] 948 dscc4.setup= [NET]
946 949
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
index c5605fe4907e..1f445e9bd768 100644
--- a/drivers/gpu/drm/drm_edid_load.c
+++ b/drivers/gpu/drm/drm_edid_load.c
@@ -264,20 +264,43 @@ out:
264int drm_load_edid_firmware(struct drm_connector *connector) 264int drm_load_edid_firmware(struct drm_connector *connector)
265{ 265{
266 const char *connector_name = connector->name; 266 const char *connector_name = connector->name;
267 char *edidname = edid_firmware, *last, *colon; 267 char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
268 int ret; 268 int ret;
269 struct edid *edid; 269 struct edid *edid;
270 270
271 if (*edidname == '\0') 271 if (edid_firmware[0] == '\0')
272 return 0; 272 return 0;
273 273
274 colon = strchr(edidname, ':'); 274 /*
275 if (colon != NULL) { 275 * If there are multiple edid files specified and separated
276 if (strncmp(connector_name, edidname, colon - edidname)) 276 * by commas, search through the list looking for one that
277 return 0; 277 * matches the connector.
278 edidname = colon + 1; 278 *
279 if (*edidname == '\0') 279 * If there's one or more that don't't specify a connector, keep
280 * the last one found one as a fallback.
281 */
282 fwstr = kstrdup(edid_firmware, GFP_KERNEL);
283 edidstr = fwstr;
284
285 while ((edidname = strsep(&edidstr, ","))) {
286 colon = strchr(edidname, ':');
287 if (colon != NULL) {
288 if (strncmp(connector_name, edidname, colon - edidname))
289 continue;
290 edidname = colon + 1;
291 break;
292 }
293
294 if (*edidname != '\0') /* corner case: multiple ',' */
295 fallback = edidname;
296 }
297
298 if (!edidname) {
299 if (!fallback) {
300 kfree(fwstr);
280 return 0; 301 return 0;
302 }
303 edidname = fallback;
281 } 304 }
282 305
283 last = edidname + strlen(edidname) - 1; 306 last = edidname + strlen(edidname) - 1;
@@ -285,6 +308,8 @@ int drm_load_edid_firmware(struct drm_connector *connector)
285 *last = '\0'; 308 *last = '\0';
286 309
287 edid = edid_load(connector, edidname, connector_name); 310 edid = edid_load(connector, edidname, connector_name);
311 kfree(fwstr);
312
288 if (IS_ERR_OR_NULL(edid)) 313 if (IS_ERR_OR_NULL(edid))
289 return 0; 314 return 0;
290 315