From patchwork Fri May 17 06:38:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Francois Moine X-Patchwork-Id: 2581221 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by patchwork1.kernel.org (Postfix) with ESMTP id 3422C3FD4E for ; Fri, 17 May 2013 06:37:52 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UdEIG-0005Zu-Jb; Fri, 17 May 2013 06:37:32 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UdEI7-0008Pf-EW; Fri, 17 May 2013 06:37:23 +0000 Received: from smtp1-g21.free.fr ([2a01:e0c:1:1599::10]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UdEI4-0008OC-02 for linux-arm-kernel@lists.infradead.org; Fri, 17 May 2013 06:37:21 +0000 Received: from armhf (unknown [IPv6:2a01:e35:2f5c:9de0:212:bfff:fe1e:9ce4]) by smtp1-g21.free.fr (Postfix) with ESMTP id 29348940186; Fri, 17 May 2013 08:36:47 +0200 (CEST) Date: Fri, 17 May 2013 08:38:03 +0200 From: Jean-Francois Moine To: linux-arm-kernel@lists.infradead.org Subject: [PATCH] drm/i2c: nxp-tda998x: fix abort of some i2c exchanges Message-ID: <20130517083803.5f34816e@armhf> X-Mailer: Claws Mail 3.9.1 (GTK+ 2.24.17; arm-unknown-linux-gnueabihf) Mime-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130517_023720_673504_42B88EEF X-CRM114-Status: GOOD ( 16.66 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (moinejf[at]free.fr) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Jason Cooper , David Airlie , dri-devel@lists.freedesktop.org, Rob Clark , Darren Etheridge , Russell King , Sebastian Hesselbarth X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The signals SIGALRM (most often) and SIGPOLL (sometimes) may be raised after irq or some parameter change and this aborts the i2c exchanges. The problem is solved by masking these signals. Signed-off-by: Jean-Francois Moine --- drivers/gpu/drm/i2c/tda998x_drv.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index e68b58a..672d045 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -262,6 +262,28 @@ struct tda998x_priv { #define TDA19989N2 0x0202 #define TDA19988 0x0301 +/* + * the signals SIGALRM (most often) and SIGPOLL (sometimes) + * may be raised after irq or some parameter change + * and this aborts the i2c exchanges + * the problem is solved by masking these signals + */ +static void savesig(sigset_t *p_oldset) +{ + sigset_t newset; + + sigemptyset(&newset); + sigaddset(&newset, SIGALRM); + sigaddset(&newset, SIGPOLL); + + sigprocmask(SIG_BLOCK, &newset, p_oldset); + +} +static void restoresig(sigset_t *p_oldset) +{ + sigprocmask(SIG_SETMASK, p_oldset, NULL); +} + static void cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) { @@ -426,6 +448,7 @@ static void tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) { struct tda998x_priv *priv = to_tda998x_priv(encoder); + sigset_t oldset; /* we only care about on or off: */ if (mode != DRM_MODE_DPMS_ON) @@ -434,6 +457,8 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) if (mode == priv->dpms) return; + savesig(&oldset); + switch (mode) { case DRM_MODE_DPMS_ON: /* enable audio and video ports */ @@ -458,6 +483,8 @@ tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) break; } + restoresig(&oldset); + priv->dpms = mode; } @@ -494,11 +521,14 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) { struct tda998x_priv *priv = to_tda998x_priv(encoder); + sigset_t oldset; uint16_t hs_start, hs_end, line_start, line_end; uint16_t vwin_start, vwin_end, de_start, de_end; uint16_t ref_pix, ref_line, pix_start2; uint8_t reg, div, rep; + savesig(&oldset); + hs_start = mode->hsync_start - mode->hdisplay; hs_end = mode->hsync_end - mode->hdisplay; line_start = 1; @@ -613,6 +643,8 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, /* must be last register set: */ reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); + + restoresig(&oldset); } static enum drm_connector_status @@ -728,15 +760,21 @@ static int tda998x_encoder_get_modes(struct drm_encoder *encoder, struct drm_connector *connector) { - struct edid *edid = (struct edid *)do_get_edid(encoder); + struct edid *edid; + sigset_t oldset; int n = 0; + savesig(&oldset); + + edid = (struct edid *) do_get_edid(encoder); if (edid) { drm_mode_connector_update_edid_property(connector, edid); n = drm_add_edid_modes(connector, edid); kfree(edid); } + restoresig(&oldset); + return n; }