diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 09:21:09 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 09:21:09 -0700 |
commit | 757c26b804428ef10888b8e00f34994dbe361d3a (patch) | |
tree | 4695afbf476ce9818bc01d34d4c266811365296c /drivers/gpu/drm/drm_modes.c | |
parent | e08dc1325feaf49eec392ee52feb2974ec3f5155 (diff) | |
parent | 5a96a899bbdee86024ab9ea6d02b9e242faacbed (diff) | |
download | op-kernel-dev-757c26b804428ef10888b8e00f34994dbe361d3a.zip op-kernel-dev-757c26b804428ef10888b8e00f34994dbe361d3a.tar.gz |
Merge branch 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (135 commits)
drm/radeon/kms: fix DP training for DPEncoderService revision bigger than 1.1
drm/radeon/kms: add missing vddci setting on NI+
drm/radeon: Add a rmb() in IH processing
drm/radeon: ATOM Endian fix for atombios_crtc_program_pll()
drm/radeon: Fix the definition of RADEON_BUF_SWAP_32BIT
drm/radeon: Do an MMIO read on interrupts when not uisng MSIs
drm/radeon: Writeback endian fixes
drm/radeon: Remove a bunch of useless _iomem casts
drm/gem: add support for private objects
DRM: clean up and document parsing of video= parameter
DRM: Radeon: Fix section mismatch.
drm: really make debug levels match in edid failure code
drm/radeon/kms: fix i2c map for rv250/280
drm/nouveau/gr: disable fifo access and idle before suspend ctx unload
drm/nouveau: pass flag to engine fini() method on suspend
drm/nouveau: replace nv04_graph_fifo_access() use with direct reg bashing
drm/nv40/gr: rewrite/split context takedown functions
drm/nouveau: detect disabled device in irq handler and return IRQ_NONE
drm/nouveau: ignore connector type when deciding digital/analog on DVI-I
drm/nouveau: Add a quirk for Gigabyte NX86T
...
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 87 |
1 files changed, 60 insertions, 27 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index c2d32f2..ad74fb4 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -994,9 +994,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, { const char *name; unsigned int namelen; - int res_specified = 0, bpp_specified = 0, refresh_specified = 0; + bool res_specified = false, bpp_specified = false, refresh_specified = false; unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; - int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; + bool yres_specified = false, cvt = false, rb = false; + bool interlace = false, margins = false, was_digit = false; int i; enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; @@ -1015,54 +1016,65 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, for (i = namelen-1; i >= 0; i--) { switch (name[i]) { case '@': - namelen = i; if (!refresh_specified && !bpp_specified && - !yres_specified) { + !yres_specified && !cvt && !rb && was_digit) { refresh = simple_strtol(&name[i+1], NULL, 10); - refresh_specified = 1; - if (cvt || rb) - cvt = 0; + refresh_specified = true; + was_digit = false; } else goto done; break; case '-': - namelen = i; - if (!bpp_specified && !yres_specified) { + if (!bpp_specified && !yres_specified && !cvt && + !rb && was_digit) { bpp = simple_strtol(&name[i+1], NULL, 10); - bpp_specified = 1; - if (cvt || rb) - cvt = 0; + bpp_specified = true; + was_digit = false; } else goto done; break; case 'x': - if (!yres_specified) { + if (!yres_specified && was_digit) { yres = simple_strtol(&name[i+1], NULL, 10); - yres_specified = 1; + yres_specified = true; + was_digit = false; } else goto done; case '0' ... '9': + was_digit = true; break; case 'M': - if (!yres_specified) - cvt = 1; + if (yres_specified || cvt || was_digit) + goto done; + cvt = true; break; case 'R': - if (cvt) - rb = 1; + if (yres_specified || cvt || rb || was_digit) + goto done; + rb = true; break; case 'm': - if (!cvt) - margins = 1; + if (cvt || yres_specified || was_digit) + goto done; + margins = true; break; case 'i': - if (!cvt) - interlace = 1; + if (cvt || yres_specified || was_digit) + goto done; + interlace = true; break; case 'e': + if (yres_specified || bpp_specified || refresh_specified || + was_digit || (force != DRM_FORCE_UNSPECIFIED)) + goto done; + force = DRM_FORCE_ON; break; case 'D': + if (yres_specified || bpp_specified || refresh_specified || + was_digit || (force != DRM_FORCE_UNSPECIFIED)) + goto done; + if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) force = DRM_FORCE_ON; @@ -1070,17 +1082,37 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, force = DRM_FORCE_ON_DIGITAL; break; case 'd': + if (yres_specified || bpp_specified || refresh_specified || + was_digit || (force != DRM_FORCE_UNSPECIFIED)) + goto done; + force = DRM_FORCE_OFF; break; default: goto done; } } + if (i < 0 && yres_specified) { - xres = simple_strtol(name, NULL, 10); - res_specified = 1; + char *ch; + xres = simple_strtol(name, &ch, 10); + if ((ch != NULL) && (*ch == 'x')) + res_specified = true; + else + i = ch - name; + } else if (!yres_specified && was_digit) { + /* catch mode that begins with digits but has no 'x' */ + i = 0; } done: + if (i >= 0) { + printk(KERN_WARNING + "parse error at position %i in video mode '%s'\n", + i, name); + mode->specified = false; + return false; + } + if (res_specified) { mode->specified = true; mode->xres = xres; @@ -1096,9 +1128,10 @@ done: mode->bpp_specified = true; mode->bpp = bpp; } - mode->rb = rb ? true : false; - mode->cvt = cvt ? true : false; - mode->interlace = interlace ? true : false; + mode->rb = rb; + mode->cvt = cvt; + mode->interlace = interlace; + mode->margins = margins; mode->force = force; return true; |