drm/fb-helper: Make load_lut and gamma_set/gamma_get hooks optional

Check whether the crtc provides the load_lut callback before calling it.
This allows the driver to provide the hook only for those CRTCs that
actually have the hardware support for it.

Also check whether the driver provided the fb_helper gamma_set/gamma_get
hooks. It's a driver bug if it allows non-truecolor fbdev visuals w/o
these hooks, but auditing all the drivers is too tedious. So just slap
a big WARN_ON() there and bail out before things start to explode.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@gmail.com>
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index dff2058..3d13ca6e2 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -168,6 +168,9 @@
 	uint16_t *r_base, *g_base, *b_base;
 	int i;
 
+	if (helper->funcs->gamma_get == NULL)
+		return;
+
 	r_base = crtc->gamma_store;
 	g_base = r_base + crtc->gamma_size;
 	b_base = g_base + crtc->gamma_size;
@@ -597,6 +600,14 @@
 		return 0;
 	}
 
+	/*
+	 * The driver really shouldn't advertise pseudo/directcolor
+	 * visuals if it can't deal with the palette.
+	 */
+	if (WARN_ON(!fb_helper->funcs->gamma_set ||
+		    !fb_helper->funcs->gamma_get))
+		return -EINVAL;
+
 	pindex = regno;
 
 	if (fb->bits_per_pixel == 16) {
@@ -677,7 +688,8 @@
 			if (rc)
 				goto out;
 		}
-		crtc_funcs->load_lut(crtc);
+		if (crtc_funcs->load_lut)
+			crtc_funcs->load_lut(crtc);
 	}
  out:
 	drm_modeset_unlock_all(dev);