Commit 96206e29 authored by Bob Paauwe's avatar Bob Paauwe Committed by Daniel Vetter

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: default avatarJani Nikula <jani.nikula@intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarBob Paauwe <bob.j.paauwe@intel.com>
[danvet: Flatten else control flow and appease checkpatch.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent f8aeb41c
...@@ -927,11 +927,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -927,11 +927,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
The filter can be disabled or changed to another The filter can be disabled or changed to another
driver later using sysfs. driver later using sysfs.
drm_kms_helper.edid_firmware=[<connector>:]<file> drm_kms_helper.edid_firmware=[<connector>:]<file>[,[<connector>:]<file>]
Broken monitors, graphic adapters and KVMs may Broken monitors, graphic adapters, KVMs and EDIDless
send no or incorrect EDID data sets. This parameter panels may send no or incorrect EDID data sets.
allows to specify an EDID data set in the This parameter allows to specify an EDID data sets
/lib/firmware directory that is used instead. in the /lib/firmware directory that are used instead.
Generic built-in EDID data sets are used, if one of Generic built-in EDID data sets are used, if one of
edid/1024x768.bin, edid/1280x1024.bin, edid/1024x768.bin, edid/1280x1024.bin,
edid/1680x1050.bin, or edid/1920x1080.bin is given edid/1680x1050.bin, or edid/1920x1080.bin is given
...@@ -940,7 +940,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -940,7 +940,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
available in Documentation/EDID/HOWTO.txt. An EDID available in Documentation/EDID/HOWTO.txt. An EDID
data set will only be used for a particular connector, data set will only be used for a particular connector,
if its name and a colon are prepended to the EDID if its name and a colon are prepended to the EDID
name. name. Each connector may use a unique EDID data
set by separating the files with a comma. An EDID
data set with no connector name will be used for
any connectors not explicitly specified.
dscc4.setup= [NET] dscc4.setup= [NET]
......
...@@ -264,20 +264,43 @@ static void *edid_load(struct drm_connector *connector, const char *name, ...@@ -264,20 +264,43 @@ static void *edid_load(struct drm_connector *connector, const char *name,
int drm_load_edid_firmware(struct drm_connector *connector) int drm_load_edid_firmware(struct drm_connector *connector)
{ {
const char *connector_name = connector->name; const char *connector_name = connector->name;
char *edidname = edid_firmware, *last, *colon; char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
int ret; int ret;
struct edid *edid; struct edid *edid;
if (*edidname == '\0') if (edid_firmware[0] == '\0')
return 0; return 0;
colon = strchr(edidname, ':'); /*
if (colon != NULL) { * If there are multiple edid files specified and separated
if (strncmp(connector_name, edidname, colon - edidname)) * by commas, search through the list looking for one that
return 0; * matches the connector.
edidname = colon + 1; *
if (*edidname == '\0') * If there's one or more that don't't specify a connector, keep
* the last one found one as a fallback.
*/
fwstr = kstrdup(edid_firmware, GFP_KERNEL);
edidstr = fwstr;
while ((edidname = strsep(&edidstr, ","))) {
colon = strchr(edidname, ':');
if (colon != NULL) {
if (strncmp(connector_name, edidname, colon - edidname))
continue;
edidname = colon + 1;
break;
}
if (*edidname != '\0') /* corner case: multiple ',' */
fallback = edidname;
}
if (!edidname) {
if (!fallback) {
kfree(fwstr);
return 0; return 0;
}
edidname = fallback;
} }
last = edidname + strlen(edidname) - 1; last = edidname + strlen(edidname) - 1;
...@@ -285,6 +308,8 @@ int drm_load_edid_firmware(struct drm_connector *connector) ...@@ -285,6 +308,8 @@ int drm_load_edid_firmware(struct drm_connector *connector)
*last = '\0'; *last = '\0';
edid = edid_load(connector, edidname, connector_name); edid = edid_load(connector, edidname, connector_name);
kfree(fwstr);
if (IS_ERR_OR_NULL(edid)) if (IS_ERR_OR_NULL(edid))
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment