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>
This commit is contained in:
parent
f8aeb41c4b
commit
96206e2922
@ -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.
|
|||||||
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,
|
|||||||
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)
|
|||||||
*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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user