aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 65ef011fa8ba..288ea2f32772 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -27,7 +27,9 @@
27 * Dave Airlie <airlied@linux.ie> 27 * Dave Airlie <airlied@linux.ie>
28 * Jesse Barnes <jesse.barnes@intel.com> 28 * Jesse Barnes <jesse.barnes@intel.com>
29 */ 29 */
30#include <linux/kernel.h>
30#include <linux/sysrq.h> 31#include <linux/sysrq.h>
32#include <linux/slab.h>
31#include <linux/fb.h> 33#include <linux/fb.h>
32#include "drmP.h" 34#include "drmP.h"
33#include "drm_crtc.h" 35#include "drm_crtc.h"
@@ -50,21 +52,6 @@ int drm_fb_helper_add_connector(struct drm_connector *connector)
50} 52}
51EXPORT_SYMBOL(drm_fb_helper_add_connector); 53EXPORT_SYMBOL(drm_fb_helper_add_connector);
52 54
53static int my_atoi(const char *name)
54{
55 int val = 0;
56
57 for (;; name++) {
58 switch (*name) {
59 case '0' ... '9':
60 val = 10*val+(*name-'0');
61 break;
62 default:
63 return val;
64 }
65 }
66}
67
68/** 55/**
69 * drm_fb_helper_connector_parse_command_line - parse command line for connector 56 * drm_fb_helper_connector_parse_command_line - parse command line for connector
70 * @connector - connector to parse line for 57 * @connector - connector to parse line for
@@ -111,7 +98,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con
111 namelen = i; 98 namelen = i;
112 if (!refresh_specified && !bpp_specified && 99 if (!refresh_specified && !bpp_specified &&
113 !yres_specified) { 100 !yres_specified) {
114 refresh = my_atoi(&name[i+1]); 101 refresh = simple_strtol(&name[i+1], NULL, 10);
115 refresh_specified = 1; 102 refresh_specified = 1;
116 if (cvt || rb) 103 if (cvt || rb)
117 cvt = 0; 104 cvt = 0;
@@ -121,7 +108,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con
121 case '-': 108 case '-':
122 namelen = i; 109 namelen = i;
123 if (!bpp_specified && !yres_specified) { 110 if (!bpp_specified && !yres_specified) {
124 bpp = my_atoi(&name[i+1]); 111 bpp = simple_strtol(&name[i+1], NULL, 10);
125 bpp_specified = 1; 112 bpp_specified = 1;
126 if (cvt || rb) 113 if (cvt || rb)
127 cvt = 0; 114 cvt = 0;
@@ -130,7 +117,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con
130 break; 117 break;
131 case 'x': 118 case 'x':
132 if (!yres_specified) { 119 if (!yres_specified) {
133 yres = my_atoi(&name[i+1]); 120 yres = simple_strtol(&name[i+1], NULL, 10);
134 yres_specified = 1; 121 yres_specified = 1;
135 } else 122 } else
136 goto done; 123 goto done;
@@ -156,7 +143,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con
156 force = DRM_FORCE_ON; 143 force = DRM_FORCE_ON;
157 break; 144 break;
158 case 'D': 145 case 'D':
159 if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) || 146 if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
160 (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) 147 (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
161 force = DRM_FORCE_ON; 148 force = DRM_FORCE_ON;
162 else 149 else
@@ -170,7 +157,7 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *con
170 } 157 }
171 } 158 }
172 if (i < 0 && yres_specified) { 159 if (i < 0 && yres_specified) {
173 xres = my_atoi(name); 160 xres = simple_strtol(name, NULL, 10);
174 res_specified = 1; 161 res_specified = 1;
175 } 162 }
176done: 163done:
@@ -297,6 +284,8 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
297 .help_msg = "force-fb(V)", 284 .help_msg = "force-fb(V)",
298 .action_msg = "Restore framebuffer console", 285 .action_msg = "Restore framebuffer console",
299}; 286};
287#else
288static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
300#endif 289#endif
301 290
302static void drm_fb_helper_on(struct fb_info *info) 291static void drm_fb_helper_on(struct fb_info *info)
@@ -373,11 +362,9 @@ static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
373 mutex_unlock(&dev->mode_config.mutex); 362 mutex_unlock(&dev->mode_config.mutex);
374 } 363 }
375 } 364 }
376 if (dpms_mode == DRM_MODE_DPMS_OFF) { 365 mutex_lock(&dev->mode_config.mutex);
377 mutex_lock(&dev->mode_config.mutex); 366 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
378 crtc_funcs->dpms(crtc, dpms_mode); 367 mutex_unlock(&dev->mode_config.mutex);
379 mutex_unlock(&dev->mode_config.mutex);
380 }
381 } 368 }
382 } 369 }
383} 370}
@@ -385,18 +372,23 @@ static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
385int drm_fb_helper_blank(int blank, struct fb_info *info) 372int drm_fb_helper_blank(int blank, struct fb_info *info)
386{ 373{
387 switch (blank) { 374 switch (blank) {
375 /* Display: On; HSync: On, VSync: On */
388 case FB_BLANK_UNBLANK: 376 case FB_BLANK_UNBLANK:
389 drm_fb_helper_on(info); 377 drm_fb_helper_on(info);
390 break; 378 break;
379 /* Display: Off; HSync: On, VSync: On */
391 case FB_BLANK_NORMAL: 380 case FB_BLANK_NORMAL:
392 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); 381 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
393 break; 382 break;
383 /* Display: Off; HSync: Off, VSync: On */
394 case FB_BLANK_HSYNC_SUSPEND: 384 case FB_BLANK_HSYNC_SUSPEND:
395 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); 385 drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
396 break; 386 break;
387 /* Display: Off; HSync: On, VSync: Off */
397 case FB_BLANK_VSYNC_SUSPEND: 388 case FB_BLANK_VSYNC_SUSPEND:
398 drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND); 389 drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
399 break; 390 break;
391 /* Display: Off; HSync: Off, VSync: Off */
400 case FB_BLANK_POWERDOWN: 392 case FB_BLANK_POWERDOWN:
401 drm_fb_helper_off(info, DRM_MODE_DPMS_OFF); 393 drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
402 break; 394 break;
@@ -603,11 +595,10 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
603 return -EINVAL; 595 return -EINVAL;
604 596
605 /* Need to resize the fb object !!! */ 597 /* Need to resize the fb object !!! */
606 if (var->xres > fb->width || var->yres > fb->height) { 598 if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) {
607 DRM_ERROR("Requested width/height is greater than current fb " 599 DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb "
608 "object %dx%d > %dx%d\n", var->xres, var->yres, 600 "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel,
609 fb->width, fb->height); 601 fb->width, fb->height, fb->bits_per_pixel);
610 DRM_ERROR("Need resizing code.\n");
611 return -EINVAL; 602 return -EINVAL;
612 } 603 }
613 604
@@ -692,7 +683,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
692 int i; 683 int i;
693 684
694 if (var->pixclock != 0) { 685 if (var->pixclock != 0) {
695 DRM_ERROR("PIXEL CLCOK SET\n"); 686 DRM_ERROR("PIXEL CLOCK SET\n");
696 return -EINVAL; 687 return -EINVAL;
697 } 688 }
698 689
@@ -905,8 +896,13 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
905 896
906 if (new_fb) { 897 if (new_fb) {
907 info->var.pixclock = 0; 898 info->var.pixclock = 0;
908 if (register_framebuffer(info) < 0) 899 ret = fb_alloc_cmap(&info->cmap, modeset->crtc->gamma_size, 0);
900 if (ret)
901 return ret;
902 if (register_framebuffer(info) < 0) {
903 fb_dealloc_cmap(&info->cmap);
909 return -EINVAL; 904 return -EINVAL;
905 }
910 } else { 906 } else {
911 drm_fb_helper_set_par(info); 907 drm_fb_helper_set_par(info);
912 } 908 }
@@ -936,6 +932,7 @@ void drm_fb_helper_free(struct drm_fb_helper *helper)
936 unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); 932 unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
937 } 933 }
938 drm_fb_helper_crtc_free(helper); 934 drm_fb_helper_crtc_free(helper);
935 fb_dealloc_cmap(&helper->fb->fbdev->cmap);
939} 936}
940EXPORT_SYMBOL(drm_fb_helper_free); 937EXPORT_SYMBOL(drm_fb_helper_free);
941 938