drm: Mark constant arrays of drm_display_mode const
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / drm_edid.c
index c1a26217a5305ee65a07b85fa77e4c15db77436b..af60d9be963278268b47909d7001efafa4841cb6 100644 (file)
@@ -240,7 +240,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
                        .addr   = DDC_ADDR,
                        .flags  = I2C_M_RD,
                        .len    = len,
-                       .buf    = buf + start,
+                       .buf    = buf,
                }
        };
 
@@ -253,7 +253,7 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
 static u8 *
 drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
 {
-       int i, j = 0;
+       int i, j = 0, valid_extensions = 0;
        u8 *block, *new;
 
        if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
@@ -280,14 +280,28 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
 
        for (j = 1; j <= block[0x7e]; j++) {
                for (i = 0; i < 4; i++) {
-                       if (drm_do_probe_ddc_edid(adapter, block, j,
-                                                 EDID_LENGTH))
+                       if (drm_do_probe_ddc_edid(adapter,
+                                 block + (valid_extensions + 1) * EDID_LENGTH,
+                                 j, EDID_LENGTH))
                                goto out;
-                       if (drm_edid_block_valid(block + j * EDID_LENGTH))
+                       if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) {
+                               valid_extensions++;
                                break;
+                       }
                }
                if (i == 4)
-                       goto carp;
+                       dev_warn(connector->dev->dev,
+                        "%s: Ignoring invalid EDID block %d.\n",
+                        drm_get_connector_name(connector), j);
+       }
+
+       if (valid_extensions != block[0x7e]) {
+               block[EDID_LENGTH-1] += block[0x7e] - valid_extensions;
+               block[0x7e] = valid_extensions;
+               new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
+               if (!new)
+                       goto out;
+               block = new;
        }
 
        return block;
@@ -435,12 +449,11 @@ static void edid_fixup_preferred(struct drm_connector *connector,
 struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
                                           int hsize, int vsize, int fresh)
 {
+       struct drm_display_mode *mode = NULL;
        int i;
-       struct drm_display_mode *ptr, *mode;
 
-       mode = NULL;
        for (i = 0; i < drm_num_dmt_modes; i++) {
-               ptr = &drm_dmt_modes[i];
+               const struct drm_display_mode *ptr = &drm_dmt_modes[i];
                if (hsize == ptr->hdisplay &&
                        vsize == ptr->vdisplay &&
                        fresh == drm_mode_vrefresh(ptr)) {
@@ -871,7 +884,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
 }
 
 static bool
-mode_is_rb(struct drm_display_mode *mode)
+mode_is_rb(const struct drm_display_mode *mode)
 {
        return (mode->htotal - mode->hdisplay == 160) &&
               (mode->hsync_end - mode->hdisplay == 80) &&
@@ -880,7 +893,8 @@ mode_is_rb(struct drm_display_mode *mode)
 }
 
 static bool
-mode_in_hsync_range(struct drm_display_mode *mode, struct edid *edid, u8 *t)
+mode_in_hsync_range(const struct drm_display_mode *mode,
+                   struct edid *edid, u8 *t)
 {
        int hsync, hmin, hmax;
 
@@ -896,7 +910,8 @@ mode_in_hsync_range(struct drm_display_mode *mode, struct edid *edid, u8 *t)
 }
 
 static bool
-mode_in_vsync_range(struct drm_display_mode *mode, struct edid *edid, u8 *t)
+mode_in_vsync_range(const struct drm_display_mode *mode,
+                   struct edid *edid, u8 *t)
 {
        int vsync, vmin, vmax;
 
@@ -927,7 +942,7 @@ range_pixel_clock(struct edid *edid, u8 *t)
 }
 
 static bool
-mode_in_range(struct drm_display_mode *mode, struct edid *edid,
+mode_in_range(const struct drm_display_mode *mode, struct edid *edid,
              struct detailed_timing *timing)
 {
        u32 max_clock;
@@ -1458,7 +1473,7 @@ int drm_add_modes_noedid(struct drm_connector *connector,
                        int hdisplay, int vdisplay)
 {
        int i, count, num_modes = 0;
-       struct drm_display_mode *mode, *ptr;
+       struct drm_display_mode *mode;
        struct drm_device *dev = connector->dev;
 
        count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
@@ -1468,7 +1483,7 @@ int drm_add_modes_noedid(struct drm_connector *connector,
                vdisplay = 0;
 
        for (i = 0; i < count; i++) {
-               ptr = &drm_dmt_modes[i];
+               const struct drm_display_mode *ptr = &drm_dmt_modes[i];
                if (hdisplay && vdisplay) {
                        /*
                         * Only when two are valid, they will be used to check