|
@@ -264,20 +264,43 @@ out:
|
|
|
int drm_load_edid_firmware(struct drm_connector *connector)
|
|
|
{
|
|
|
const char *connector_name = connector->name;
|
|
|
- char *edidname = edid_firmware, *last, *colon;
|
|
|
+ char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
|
|
|
int ret;
|
|
|
struct edid *edid;
|
|
|
|
|
|
- if (*edidname == '\0')
|
|
|
+ if (edid_firmware[0] == '\0')
|
|
|
return 0;
|
|
|
|
|
|
- colon = strchr(edidname, ':');
|
|
|
- if (colon != NULL) {
|
|
|
- if (strncmp(connector_name, edidname, colon - edidname))
|
|
|
- return 0;
|
|
|
- edidname = colon + 1;
|
|
|
- if (*edidname == '\0')
|
|
|
+ /*
|
|
|
+ * If there are multiple edid files specified and separated
|
|
|
+ * by commas, search through the list looking for one that
|
|
|
+ * matches the connector.
|
|
|
+ *
|
|
|
+ * 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;
|
|
|
+ }
|
|
|
+ edidname = fallback;
|
|
|
}
|
|
|
|
|
|
last = edidname + strlen(edidname) - 1;
|
|
@@ -285,6 +308,8 @@ int drm_load_edid_firmware(struct drm_connector *connector)
|
|
|
*last = '\0';
|
|
|
|
|
|
edid = edid_load(connector, edidname, connector_name);
|
|
|
+ kfree(fwstr);
|
|
|
+
|
|
|
if (IS_ERR_OR_NULL(edid))
|
|
|
return 0;
|
|
|
|