aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/udl/udl_connector.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/udl/udl_connector.c')
-rw-r--r--drivers/gpu/drm/udl/udl_connector.c31
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 b3b2cedf6745..fe5cdbcf2636 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -22,13 +22,17 @@
22static u8 *udl_get_edid(struct udl_device *udl) 22static u8 *udl_get_edid(struct udl_device *udl)
23{ 23{
24 u8 *block; 24 u8 *block;
25 char rbuf[3]; 25 char *rbuf;
26 int ret, i; 26 int ret, i;
27 27
28 block = kmalloc(EDID_LENGTH, GFP_KERNEL); 28 block = kmalloc(EDID_LENGTH, GFP_KERNEL);
29 if (block == NULL) 29 if (block == NULL)
30 return NULL; 30 return NULL;
31 31
32 rbuf = kmalloc(2, GFP_KERNEL);
33 if (rbuf == NULL)
34 goto error;
35
32 for (i = 0; i < EDID_LENGTH; i++) { 36 for (i = 0; i < EDID_LENGTH; i++) {
33 ret = usb_control_msg(udl->ddev->usbdev, 37 ret = usb_control_msg(udl->ddev->usbdev,
34 usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02), 38 usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02),
@@ -36,16 +40,17 @@ static u8 *udl_get_edid(struct udl_device *udl)
36 HZ); 40 HZ);
37 if (ret < 1) { 41 if (ret < 1) {
38 DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret); 42 DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret);
39 i--;
40 goto error; 43 goto error;
41 } 44 }
42 block[i] = rbuf[1]; 45 block[i] = rbuf[1];
43 } 46 }
44 47
48 kfree(rbuf);
45 return block; 49 return block;
46 50
47error: 51error:
48 kfree(block); 52 kfree(block);
53 kfree(rbuf);
49 return NULL; 54 return NULL;
50} 55}
51 56
@@ -57,6 +62,14 @@ static int udl_get_modes(struct drm_connector *connector)
57 62
58 edid = (struct edid *)udl_get_edid(udl); 63 edid = (struct edid *)udl_get_edid(udl);
59 64
65 /*
66 * We only read the main block, but if the monitor reports extension
67 * blocks then the drm edid code expects them to be present, so patch
68 * the extension count to 0.
69 */
70 edid->checksum += edid->extensions;
71 edid->extensions = 0;
72
60 drm_mode_connector_update_edid_property(connector, edid); 73 drm_mode_connector_update_edid_property(connector, edid);
61 ret = drm_add_edid_modes(connector, edid); 74 ret = drm_add_edid_modes(connector, edid);
62 kfree(edid); 75 kfree(edid);
@@ -84,7 +97,8 @@ udl_detect(struct drm_connector *connector, bool force)
84 return connector_status_connected; 97 return connector_status_connected;
85} 98}
86 99
87struct drm_encoder *udl_best_single_encoder(struct drm_connector *connector) 100static struct drm_encoder*
101udl_best_single_encoder(struct drm_connector *connector)
88{ 102{
89 int enc_id = connector->encoder_ids[0]; 103 int enc_id = connector->encoder_ids[0];
90 struct drm_mode_object *obj; 104 struct drm_mode_object *obj;
@@ -97,8 +111,9 @@ struct drm_encoder *udl_best_single_encoder(struct drm_connector *connector)
97 return encoder; 111 return encoder;
98} 112}
99 113
100int udl_connector_set_property(struct drm_connector *connector, struct drm_property *property, 114static int udl_connector_set_property(struct drm_connector *connector,
101 uint64_t val) 115 struct drm_property *property,
116 uint64_t val)
102{ 117{
103 return 0; 118 return 0;
104} 119}
@@ -110,13 +125,13 @@ static void udl_connector_destroy(struct drm_connector *connector)
110 kfree(connector); 125 kfree(connector);
111} 126}
112 127
113struct drm_connector_helper_funcs udl_connector_helper_funcs = { 128static struct drm_connector_helper_funcs udl_connector_helper_funcs = {
114 .get_modes = udl_get_modes, 129 .get_modes = udl_get_modes,
115 .mode_valid = udl_mode_valid, 130 .mode_valid = udl_mode_valid,
116 .best_encoder = udl_best_single_encoder, 131 .best_encoder = udl_best_single_encoder,
117}; 132};
118 133
119struct drm_connector_funcs udl_connector_funcs = { 134static struct drm_connector_funcs udl_connector_funcs = {
120 .dpms = drm_helper_connector_dpms, 135 .dpms = drm_helper_connector_dpms,
121 .detect = udl_detect, 136 .detect = udl_detect,
122 .fill_modes = drm_helper_probe_single_connector_modes, 137 .fill_modes = drm_helper_probe_single_connector_modes,
@@ -138,7 +153,7 @@ int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder)
138 drm_sysfs_connector_add(connector); 153 drm_sysfs_connector_add(connector);
139 drm_mode_connector_attach_encoder(connector, encoder); 154 drm_mode_connector_attach_encoder(connector, encoder);
140 155
141 drm_connector_attach_property(connector, 156 drm_object_attach_property(&connector->base,
142 dev->mode_config.dirty_info_property, 157 dev->mode_config.dirty_info_property,
143 1); 158 1);
144 return 0; 159 return 0;