From patchwork Tue Mar 13 12:27:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 7261 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id CDDB223E12 for ; Tue, 13 Mar 2012 12:28:24 +0000 (UTC) Received: from mail-ee0-f52.google.com (mail-ee0-f52.google.com [74.125.83.52]) by fiordland.canonical.com (Postfix) with ESMTP id B4B04A1856E for ; Tue, 13 Mar 2012 12:28:24 +0000 (UTC) Received: by eekd4 with SMTP id d4so132569eek.11 for ; Tue, 13 Mar 2012 05:28:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:mime-version:content-type :x-gm-message-state; bh=MEF663tIZ9+KwhwF0HtdBELvCDEMVtxmw/VtXfsdzm4=; b=o7AXhEh19aI5WmGq3TkC6vSQZfwnO5xE5oJMYKnfvWbJBaVihqBbsNhAOrKGUuUe1P 5ihbvLfXvE/OuxRFBH03qWbv5Mkjivllg4B1H5YukKCO6Beep5jfXLvZ/VvPpZK01l0S vLkESEpuMsA0Use1K5IcVzDfWPZJGa7BHulyuvNTAPInRQbai8AtBE1O0Pd3kxfReBko lfQAZEVFA+I6vEha6fOlmHSDMaflV99BpZZPp6ZOyTcZtcJiAvjBKZfw0GZatmZ7iso+ 2vdM9IzdF7SufOtulxw2wdYB/bo+YOWqO4+yAceW4YbIkBrz2lwQM0j936tgkmc4kX6Z bbaA== Received: by 10.50.184.228 with SMTP id ex4mr4405318igc.50.1331641704165; Tue, 13 Mar 2012 05:28:24 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.53.18 with SMTP id k18csp63740ibg; Tue, 13 Mar 2012 05:28:23 -0700 (PDT) Received: by 10.14.28.137 with SMTP id g9mr2339893eea.94.1331641702551; Tue, 13 Mar 2012 05:28:22 -0700 (PDT) Received: from eu1sys200aog118.obsmtp.com (eu1sys200aog118.obsmtp.com. [207.126.144.145]) by mx.google.com with SMTP id w54si137664eef.102.2012.03.13.05.28.12 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 13 Mar 2012 05:28:22 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) client-ip=207.126.144.145; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.145 is neither permitted nor denied by best guess record for domain of linus.walleij@stericsson.com) smtp.mail=linus.walleij@stericsson.com Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob118.postini.com ([207.126.147.11]) with SMTP ID DSNKT189UQnjqaKxtj1O0tMqjljmybXa6nJK@postini.com; Tue, 13 Mar 2012 12:28:21 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id B669AE7; Tue, 13 Mar 2012 12:27:19 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 6F48D1F7; Tue, 13 Mar 2012 10:49:50 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id B9986A8072; Tue, 13 Mar 2012 13:27:25 +0100 (CET) Received: from steludxu4075.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Tue, 13 Mar 2012 13:27:30 +0100 From: Linus Walleij To: Greg Kroah-Hartman , , Chanho Min Cc: , Russell King , Jong-Sung Kim , Linus Walleij , , Shreshtha Kumar Sahu Subject: [PATCH v3] serial: PL011: clear pending interrupts Date: Tue, 13 Mar 2012 13:27:23 +0100 Message-ID: <1331641643-25929-1-git-send-email-linus.walleij@stericsson.com> X-Mailer: git-send-email 1.7.8 MIME-Version: 1.0 X-Gm-Message-State: ALoCoQn4WfkPlvNTnhE/3C7Bq1Tcy1DFxFXIFmqtvQEzh1cRYcLj6u1QSdAhM1HJPB5QlSo/EwP5 From: Linus Walleij Chanho Min reported that when the boot loader transfers control to the kernel, there may be pending interrupts causing the UART to lock up in an eternal loop trying to pick tokens from the FIFO (since the RX interrupt flag indicates there are tokens) while in practice there are no tokens - in fact there is only a pending IRQ flag. This patch address the issue with a combination of two patches suggested by Russell King that clears and mask all interrupts at probe() and clears any pending error and RX interrupts at port startup time. We suspect the spurious interrupts are a side-effect of switching the UART from FIFO to non-FIFO mode. Cc: stable@kernel.org Cc: Shreshtha Kumar Sahu Cc: Jong-Sung Kim Reported-by: Chanho Min Suggested-by: Russell King Signed-off-by: Linus Walleij --- ChangeLog v1->v2: - Instead of making the IRQ fastpath account for spurious IRQs with zero characters, make sure to clear out any pending IRQ flags in startup(). ChangeLog v2->v3: - Attempt to clear out any spuriously appearing RX interrups in startup() instead of in the interrupt handler. Let's see if this works. --- drivers/tty/serial/amba-pl011.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 6800f5f..7e01399 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1381,6 +1381,10 @@ static int pl011_startup(struct uart_port *port) uap->port.uartclk = clk_get_rate(uap->clk); + /* Clear pending error and receive interrupts */ + writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS | + UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR); + /* * Allocate the IRQ */ @@ -1417,10 +1421,6 @@ static int pl011_startup(struct uart_port *port) cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; writew(cr, uap->port.membase + UART011_CR); - /* Clear pending error interrupts */ - writew(UART011_OEIS | UART011_BEIS | UART011_PEIS | UART011_FEIS, - uap->port.membase + UART011_ICR); - /* * initialise the old status of the modem signals */ @@ -1435,6 +1435,9 @@ static int pl011_startup(struct uart_port *port) * as well. */ spin_lock_irq(&uap->port.lock); + /* Clear out any spuriously appearing RX interrupts */ + writew(UART011_RTIS | UART011_RXIS, + uap->port.membase + UART011_ICR); uap->im = UART011_RTIM; if (!pl011_dma_rx_running(uap)) uap->im |= UART011_RXIM; @@ -1927,6 +1930,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto unmap; } + /* Ensure interrupts from this UART are masked and cleared */ + writew(0, uap->port.membase + UART011_IMSC); + writew(0xffff, uap->port.membase + UART011_ICR); + uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx;