From patchwork Tue Oct 22 14:44:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sylvain Rochet X-Patchwork-Id: 3083351 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2EA02BF924 for ; Tue, 22 Oct 2013 14:45:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D825A20458 for ; Tue, 22 Oct 2013 14:44:59 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3BECF201F0 for ; Tue, 22 Oct 2013 14:44:58 +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 1VYdCS-0005TX-Rg; Tue, 22 Oct 2013 14:44:48 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VYdCQ-000588-Bf; Tue, 22 Oct 2013 14:44:46 +0000 Received: from atreides.gradator.net ([212.85.155.42]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VYdCM-00056v-OT for linux-arm-kernel@lists.infradead.org; Tue, 22 Oct 2013 14:44:43 +0000 Received: from gradator by atreides.gradator.net with local (Exim 4.72) (envelope-from ) id 1VYdC0-0003YL-JT for linux-arm-kernel@lists.infradead.org; Tue, 22 Oct 2013 16:44:20 +0200 Date: Tue, 22 Oct 2013 16:44:20 +0200 From: Sylvain Rochet To: linux-arm-kernel@lists.infradead.org Message-ID: <20131022144420.GA12871@gradator.net> MIME-Version: 1.0 User-Agent: Mutt/1.5.21 (2010-09-15) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: gradator@atreides.gradator.net X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Subject: BUG: Atmel AT91 LCD Blanking hang (atmel_hlcdfb) X-SA-Exim-Version: 4.2.1 (built Mon, 22 Mar 2010 06:26:47 +0000) X-SA-Exim-Scanned: Yes (on atreides.gradator.net) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131022_104442_904156_24362F82 X-CRM114-Status: GOOD ( 15.74 ) X-Spam-Score: -2.3 (--) 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 X-Virus-Scanned: ClamAV using ClamSMTP Hi, Kernel used: linux-3.10.y stable Git branch (currently 3.10.17) + linux-3.10-at91 Git branch # echo "4" > /sys/class/graphics/fb0/blank never ends atmel_lcdfb_core.c, atmel_lcdfb_blank() calls atmel_hlcdfb.c, atmel_hlcdfb_stop() which waits for ATMEL_LCDC_BASEISR.LCDC_BASEISR_DMA to be set if ATMEL_LCDC_STOP_NOWAIT flag is not set. But it never happens, thus atmel_hlcdfb_stop() is going to wait indefinitely. It never happens because ATMEL_LCDC_BASEISR status register is cleared upon reading and interrupt routine atmel_hlcdfb_interrupt() is also reading the same register. Any triggered interrupt will clear this DMA bit while atmel_hlcdfb_stop() is currently msleep()ing. The issue does not seem obvious to fix for me, since it requires some synching between the interrupt handler and the userland request to blank. I am not proud of, but I currently fixed the issue by asserting the ATMEL_LCDC_STOP_NOWAIT flag to all atmel_hlcdfb_stop() calls. I attached the patch for reference purposes, but it is broken since it also change the atmel_lcdfb.c behavior, hardware I don't have and which probably doesn't need to be fixed. Anyway, I am not a design guru, but reading a register which clears itself at reading at two or more locations should probably be something to avoid. Regards, Sylvain diff --git a/drivers/video/atmel_lcdfb_core.c b/drivers/video/atmel_lcdfb_core.c index df7eb27..08669ce 100644 --- a/drivers/video/atmel_lcdfb_core.c +++ b/drivers/video/atmel_lcdfb_core.c @@ -304,7 +304,7 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo) might_sleep(); if (sinfo->dev_data->stop) - sinfo->dev_data->stop(sinfo, 0); + sinfo->dev_data->stop(sinfo, ATMEL_LCDC_STOP_NOWAIT); if (sinfo->dev_data->start) sinfo->dev_data->start(sinfo); } @@ -477,7 +477,7 @@ static int atmel_lcdfb_blank(int blank_mode, struct fb_info *info) break; case FB_BLANK_POWERDOWN: if (sinfo->dev_data->stop) - sinfo->dev_data->stop(sinfo, 0); + sinfo->dev_data->stop(sinfo, ATMEL_LCDC_STOP_NOWAIT); break; default: return -EINVAL;