diff options
| -rw-r--r-- | linux-core/drm_crtc.c | 7 | ||||
| -rw-r--r-- | linux-core/drm_crtc.h | 1 | ||||
| -rw-r--r-- | linux-core/drm_modes.c | 39 | 
3 files changed, 43 insertions, 4 deletions
| diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index f95facce..16cf62a7 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -286,8 +286,9 @@ void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)  	list_for_each_entry(output, &dev->mode_config.output_list, head) { +		/* set all modes to the unverified state */  		list_for_each_entry_safe(mode, t, &output->modes, head) -			drm_mode_remove(output, mode); +			mode->status = MODE_UNVERIFIED;  		output->status = (*output->funcs->detect)(output); @@ -300,9 +301,7 @@ void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)  		ret = (*output->funcs->get_modes)(output);  		if (ret) { -			/* move the modes over to the main mode list */ -			drm_mode_list_concat(&output->probed_modes, -					     &output->modes); +			drm_mode_output_list_update(output);  		}  		if (maxX && maxY) diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 149bc31f..a15ce0cf 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -59,6 +59,7 @@ enum drm_mode_status {      MODE_ONE_HEIGHT,    /* only one height is supported */      MODE_ONE_SIZE,      /* only one resolution is supported */      MODE_NO_REDUCED,    /* monitor doesn't accept reduced blanking */ +    MODE_UNVERIFIED = -3, /* mode needs to reverified */      MODE_BAD = -2,	/* unspecified reason */      MODE_ERROR	= -1	/* error condition */  }; diff --git a/linux-core/drm_modes.c b/linux-core/drm_modes.c index 54c25137..3293f91d 100644 --- a/linux-core/drm_modes.c +++ b/linux-core/drm_modes.c @@ -517,3 +517,42 @@ void drm_mode_sort(struct list_head *mode_list)  {  	list_sort(mode_list, drm_mode_compare);  } + + +/** + * drm_mode_output_list_update - update the mode list for the output + * @output: the output to update + * + * LOCKING: + * Caller must hold a lock protecting @mode_list. + * + * This moves the modes from the @output probed_modes list + * to the actual mode list. It compares the probed mode against the current + * list and only adds different modes. All modes unverified after this point + * will be removed by the prune invalid modes. + */ +void drm_mode_output_list_update(struct drm_output *output) +{ +	struct drm_display_mode *mode, *t; +	struct drm_display_mode *pmode, *pt; +	int found_it; +	list_for_each_entry_safe(pmode, pt, &output->probed_modes, +				 head) { +		found_it = 0; +		/* go through current modes checking for the new probed mode */ +		list_for_each_entry(mode, &output->modes, head) { +			if (drm_mode_equal(pmode, mode)) { +				found_it = 1; +				/* if equal delete the probed mode */ +				mode->status = pmode->status; +				list_del(&pmode->head); +				kfree(pmode); +				break; +			} +		} + +		if (!found_it) { +			list_move_tail(&pmode->head, &output->modes); +		} +	} +} | 
