diff options
Diffstat (limited to 'drivers/gpu/drm/udl/udl_connector.c')
| -rw-r--r-- | drivers/gpu/drm/udl/udl_connector.c | 31 | 
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index b3b2cedf674..fe5cdbcf263 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -22,13 +22,17 @@  static u8 *udl_get_edid(struct udl_device *udl)  {  	u8 *block; -	char rbuf[3]; +	char *rbuf;  	int ret, i;  	block = kmalloc(EDID_LENGTH, GFP_KERNEL);  	if (block == NULL)  		return NULL; +	rbuf = kmalloc(2, GFP_KERNEL); +	if (rbuf == NULL) +		goto error; +  	for (i = 0; i < EDID_LENGTH; i++) {  		ret = usb_control_msg(udl->ddev->usbdev,  				      usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02), @@ -36,16 +40,17 @@ static u8 *udl_get_edid(struct udl_device *udl)  				      HZ);  		if (ret < 1) {  			DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret); -			i--;  			goto error;  		}  		block[i] = rbuf[1];  	} +	kfree(rbuf);  	return block;  error:  	kfree(block); +	kfree(rbuf);  	return NULL;  } @@ -57,6 +62,14 @@ static int udl_get_modes(struct drm_connector *connector)  	edid = (struct edid *)udl_get_edid(udl); +	/* +	 * We only read the main block, but if the monitor reports extension +	 * blocks then the drm edid code expects them to be present, so patch +	 * the extension count to 0. +	 */ +	edid->checksum += edid->extensions; +	edid->extensions = 0; +  	drm_mode_connector_update_edid_property(connector, edid);  	ret = drm_add_edid_modes(connector, edid);  	kfree(edid); @@ -84,7 +97,8 @@ udl_detect(struct drm_connector *connector, bool force)  	return connector_status_connected;  } -struct drm_encoder *udl_best_single_encoder(struct drm_connector *connector) +static struct drm_encoder* +udl_best_single_encoder(struct drm_connector *connector)  {  	int enc_id = connector->encoder_ids[0];  	struct drm_mode_object *obj; @@ -97,8 +111,9 @@ struct drm_encoder *udl_best_single_encoder(struct drm_connector *connector)  	return encoder;  } -int udl_connector_set_property(struct drm_connector *connector, struct drm_property *property, -			       uint64_t val) +static int udl_connector_set_property(struct drm_connector *connector, +				      struct drm_property *property, +				      uint64_t val)  {  	return 0;  } @@ -110,13 +125,13 @@ static void udl_connector_destroy(struct drm_connector *connector)  	kfree(connector);  } -struct drm_connector_helper_funcs udl_connector_helper_funcs = { +static struct drm_connector_helper_funcs udl_connector_helper_funcs = {  	.get_modes = udl_get_modes,  	.mode_valid = udl_mode_valid,  	.best_encoder = udl_best_single_encoder,  }; -struct drm_connector_funcs udl_connector_funcs = { +static struct drm_connector_funcs udl_connector_funcs = {  	.dpms = drm_helper_connector_dpms,  	.detect = udl_detect,  	.fill_modes = drm_helper_probe_single_connector_modes, @@ -138,7 +153,7 @@ int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder)  	drm_sysfs_connector_add(connector);  	drm_mode_connector_attach_encoder(connector, encoder); -	drm_connector_attach_property(connector, +	drm_object_attach_property(&connector->base,  				      dev->mode_config.dirty_info_property,  				      1);  	return 0;  |