diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_acpi.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_acpi.c | 53 | 
1 files changed, 51 insertions, 2 deletions
| diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c index 7cfe91fc05f2..e78430001f07 100644 --- a/drivers/gpu/drm/i915/display/intel_acpi.c +++ b/drivers/gpu/drm/i915/display/intel_acpi.c @@ -186,13 +186,16 @@ void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915)  {  	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);  	acpi_handle dhandle; +	union acpi_object *obj;  	dhandle = ACPI_HANDLE(&pdev->dev);  	if (!dhandle)  		return; -	acpi_evaluate_dsm(dhandle, &intel_dsm_guid2, INTEL_DSM_REVISION_ID, -			  INTEL_DSM_FN_GET_BIOS_DATA_FUNCS_SUPPORTED, NULL); +	obj = acpi_evaluate_dsm(dhandle, &intel_dsm_guid2, INTEL_DSM_REVISION_ID, +				INTEL_DSM_FN_GET_BIOS_DATA_FUNCS_SUPPORTED, NULL); +	if (obj) +		ACPI_FREE(obj);  }  /* @@ -282,3 +285,49 @@ void intel_acpi_device_id_update(struct drm_i915_private *dev_priv)  	}  	drm_connector_list_iter_end(&conn_iter);  } + +/* NOTE: The connector order must be final before this is called. */ +void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915) +{ +	struct drm_connector_list_iter conn_iter; +	struct drm_device *drm_dev = &i915->drm; +	struct fwnode_handle *fwnode = NULL; +	struct drm_connector *connector; +	struct acpi_device *adev; + +	drm_connector_list_iter_begin(drm_dev, &conn_iter); +	drm_for_each_connector_iter(connector, &conn_iter) { +		/* Always getting the next, even when the last was not used. */ +		fwnode = device_get_next_child_node(drm_dev->dev, fwnode); +		if (!fwnode) +			break; + +		switch (connector->connector_type) { +		case DRM_MODE_CONNECTOR_LVDS: +		case DRM_MODE_CONNECTOR_eDP: +		case DRM_MODE_CONNECTOR_DSI: +			/* +			 * Integrated displays have a specific address 0x1f on +			 * most Intel platforms, but not on all of them. +			 */ +			adev = acpi_find_child_device(ACPI_COMPANION(drm_dev->dev), +						      0x1f, 0); +			if (adev) { +				connector->fwnode = +					fwnode_handle_get(acpi_fwnode_handle(adev)); +				break; +			} +			fallthrough; +		default: +			connector->fwnode = fwnode_handle_get(fwnode); +			break; +		} +	} +	drm_connector_list_iter_end(&conn_iter); +	/* +	 * device_get_next_child_node() takes a reference on the fwnode, if +	 * we stopped iterating because we are out of connectors we need to +	 * put this, otherwise fwnode is NULL and the put is a no-op. +	 */ +	fwnode_handle_put(fwnode); +} | 
