drm/exynos: fix wrong return check for platform_device_register_simple
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / exynos / exynos_drm_hdmi.c
index 7c27df0..6986a1b 100644 (file)
@@ -56,7 +56,7 @@ int exynos_platform_device_hdmi_register(void)
 
        exynos_drm_hdmi_pdev = platform_device_register_simple(
                        "exynos-drm-hdmi", -1, NULL, 0);
-       if (IS_ERR_OR_NULL(exynos_drm_hdmi_pdev))
+       if (IS_ERR(exynos_drm_hdmi_pdev))
                return PTR_ERR(exynos_drm_hdmi_pdev);
 
        return 0;
@@ -205,13 +205,45 @@ static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
                                const struct drm_display_mode *mode,
                                struct drm_display_mode *adjusted_mode)
 {
-       struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+       struct drm_display_mode *m;
+       int mode_ok;
 
        DRM_DEBUG_KMS("%s\n", __FILE__);
 
-       if (hdmi_ops && hdmi_ops->mode_fixup)
-               hdmi_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector, mode,
-                                    adjusted_mode);
+       drm_mode_set_crtcinfo(adjusted_mode, 0);
+
+       mode_ok = drm_hdmi_check_timing(subdrv_dev, adjusted_mode);
+
+       /* just return if user desired mode exists. */
+       if (mode_ok == 0)
+               return;
+
+       /*
+        * otherwise, find the most suitable mode among modes and change it
+        * to adjusted_mode.
+        */
+       list_for_each_entry(m, &connector->modes, head) {
+               mode_ok = drm_hdmi_check_timing(subdrv_dev, m);
+
+               if (mode_ok == 0) {
+                       struct drm_mode_object base;
+                       struct list_head head;
+
+                       DRM_INFO("desired mode doesn't exist so\n");
+                       DRM_INFO("use the most suitable mode among modes.\n");
+
+                       DRM_DEBUG_KMS("Adjusted Mode: [%d]x[%d] [%d]Hz\n",
+                               m->hdisplay, m->vdisplay, m->vrefresh);
+
+                       /* preserve display mode header while copying. */
+                       head = adjusted_mode->head;
+                       base = adjusted_mode->base;
+                       memcpy(adjusted_mode, m, sizeof(*m));
+                       adjusted_mode->head = head;
+                       adjusted_mode->base = base;
+                       break;
+               }
+       }
 }
 
 static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)