From patchwork Thu Nov 11 14:44:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 317452 X-Patchwork-Delegate: lethal@linux-sh.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oABEin9C014351 for ; Thu, 11 Nov 2010 14:44:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756779Ab0KKOoq (ORCPT ); Thu, 11 Nov 2010 09:44:46 -0500 Received: from mailout-de.gmx.net ([213.165.64.22]:56870 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with SMTP id S1756872Ab0KKOop (ORCPT ); Thu, 11 Nov 2010 09:44:45 -0500 Received: (qmail invoked by alias); 11 Nov 2010 14:44:43 -0000 Received: from p50898DEB.dip0.t-ipconnect.de (EHLO axis700.grange) [80.137.141.235] by mail.gmx.net (mp014) with SMTP; 11 Nov 2010 15:44:43 +0100 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX1/+/IEXNvH+uKCBr2GfTdrQJZVXF+8JG7RmE/avS/ bE7d8dXjoAxacW Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1PGYOS-00018V-4Y; Thu, 11 Nov 2010 15:44:52 +0100 Date: Thu, 11 Nov 2010 15:44:52 +0100 (CET) From: Guennadi Liakhovetski To: linux-fbdev@vger.kernel.org cc: linux-sh@vger.kernel.org, Erik Gilling , Andrew Morton , Dave Airlie , Geert Uytterhoeven , Paul Mundt Subject: [PATCH 2/4 v3] fbdev: export fb_edid_add_monspecs() for modules, improve algorithm In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Y-GMX-Trusted: 0 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 11 Nov 2010 14:44:49 +0000 (UTC) diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index a0b5a93..b25399a 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -973,58 +973,56 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) DPRINTK("========================================\n"); } +/** + * fb_edid_add_monspecs() - add monitor video modes from E-EDID data + * @edid: 128 byte array with an E-EDID block + * @spacs: monitor specs to be extended + */ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) { unsigned char *block; - struct fb_videomode *mode, *m; - int num = 0, i, first = 1; + struct fb_videomode *m; + int num = 0, i; + u8 edt[(128 - 4) / DETAILED_TIMING_DESCRIPTION_SIZE]; - if (edid == NULL) + if (!edid) return; if (!edid_checksum(edid)) return; - if (edid[0] != 0x2) + if (edid[0] != 0x2 || + edid[2] < 4 || edid[2] > 128 - DETAILED_TIMING_DESCRIPTION_SIZE) return; - mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); - if (mode == NULL) - return; - - block = edid + edid[0x2]; + block = edid + edid[2]; DPRINTK(" Extended Detailed Timings\n"); - for (i = 0; i < (128 - edid[0x2]) / DETAILED_TIMING_DESCRIPTION_SIZE; - i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) { - if (!(block[0] == 0x00 && block[1] == 0x00)) { - get_detailed_timing(block, &mode[num]); - if (first) { - mode[num].flag |= FB_MODE_IS_FIRST; - first = 0; - } - num++; - } - } + for (i = 0; i < (128 - edid[2]) / DETAILED_TIMING_DESCRIPTION_SIZE; + i++, block += DETAILED_TIMING_DESCRIPTION_SIZE) + if (PIXEL_CLOCK) + edt[num++] = block - edid; /* Yikes, EDID data is totally useless */ - if (!num) { - kfree(mode); + if (!num) return; - } m = kzalloc((specs->modedb_len + num) * sizeof(struct fb_videomode), GFP_KERNEL); - if (!m) { - kfree(mode); + if (!m) return; + + memcpy(m, specs->modedb, specs->modedb_len * sizeof(struct fb_videomode)); + + for (i = specs->modedb_len; i < specs->modedb_len + num; i++) { + get_detailed_timing(edid + edt[i - specs->modedb_len], &m[i]); + if (i == specs->modedb_len) + m[i].flag |= FB_MODE_IS_FIRST; + pr_debug("Adding %ux%u@%u\n", m[i].xres, m[i].yres, m[i].refresh); } - memmove(m, specs->modedb, specs->modedb_len * sizeof(struct fb_videomode)); - memmove(m + specs->modedb_len, mode, num * sizeof(struct fb_videomode)); - kfree(mode); kfree(specs->modedb); specs->modedb = m; specs->modedb_len = specs->modedb_len + num; @@ -1346,6 +1344,9 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) { specs = NULL; } +void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) +{ +} void fb_destroy_modedb(struct fb_videomode *modedb) { } @@ -1453,6 +1454,7 @@ EXPORT_SYMBOL(fb_firmware_edid); EXPORT_SYMBOL(fb_parse_edid); EXPORT_SYMBOL(fb_edid_to_monspecs); +EXPORT_SYMBOL(fb_edid_add_monspecs); EXPORT_SYMBOL(fb_get_mode); EXPORT_SYMBOL(fb_validate_mode); EXPORT_SYMBOL(fb_destroy_modedb);