From patchwork Tue Aug 21 13:01:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felipe Balbi X-Patchwork-Id: 1355021 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 5ED9940210 for ; Tue, 21 Aug 2012 13:12:09 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1T3o9j-0003g8-H3; Tue, 21 Aug 2012 13:06:03 +0000 Received: from na3sys009aog103.obsmtp.com ([74.125.149.71]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1T3o9c-0003ar-Gs for linux-arm-kernel@lists.infradead.org; Tue, 21 Aug 2012 13:06:00 +0000 Received: from mail-lpp01m010-f41.google.com ([209.85.215.41]) (using TLSv1) by na3sys009aob103.postini.com ([74.125.148.12]) with SMTP ID DSNKUDOHnenzqvM7fxgAa0lSZSFAf6U/lJD9@postini.com; Tue, 21 Aug 2012 06:05:56 PDT Received: by lahd3 with SMTP id d3so3494339lah.28 for ; Tue, 21 Aug 2012 06:05:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=date:from:to:cc:subject:message-id:reply-to:references:mime-version :content-type:content-disposition:in-reply-to:user-agent :x-gm-message-state; bh=RAPTgQR2bSEs9Vn08jg8MoSx83QDDtSQO7+IujqNLm4=; b=XdKn8JJuUlBoVV44Deao2khY9zqAZgefQ2PexHNd7IoT9wu4BtnLC1g4mzoaOmQ99+ GUiYW8/A32ix4pslp3MYXrg1DSfFGIaODGAgoXY/ljEEk45zaYJ58Eylm3R90rXAw0fI dCAZkSg6DAuOHkPfr15eVcuwLHRr8qVdqNx5MFm7XfSSa4re7rFAa9zsgt7zgZ/xAvG3 +C3jM7bKaT1hnhNulIVggjZce2Hfaa46oXfPnXINCSKmckPYXJvo1qz5FF/FUTT97/s8 6hWFTkwxz5jPJ5a3GtRddOgzceY/yBXhdAqm5Q4dgju0LNy/KZO9Cp7xj777LvI80GMd Wgjw== Received: by 10.112.36.130 with SMTP id q2mr7486517lbj.44.1345554332415; Tue, 21 Aug 2012 06:05:32 -0700 (PDT) Received: from localhost (cs78217178.pp.htv.fi. [62.78.217.178]) by mx.google.com with ESMTPS id u10sm420904lbf.11.2012.08.21.06.05.30 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 21 Aug 2012 06:05:31 -0700 (PDT) Date: Tue, 21 Aug 2012 16:01:36 +0300 From: Felipe Balbi To: Felipe Balbi Subject: Re: [PATCH v2 00/13] OMAP Serial patches Message-ID: <20120821130134.GH10347@arwen.pp.htv.fi> References: <1345540555-24359-1-git-send-email-balbi@ti.com> <1345551371-18862-1-git-send-email-balbi@ti.com> MIME-Version: 1.0 In-Reply-To: <1345551371-18862-1-git-send-email-balbi@ti.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Gm-Message-State: ALoCoQmLwpbGp3FvKr0cyvTRrT7aoV+7X25YvswEtrs6XVYJpONBa5LCk7NY6mLZ7On3X49KFZNo X-Spam-Note: CRM114 invocation failed X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [74.125.149.71 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Kevin Hilman , Tony Lindgren , Linux Kernel Mailing List , Santosh Shilimkar , linux-serial@vger.kernel.org, Linux OMAP Mailing List , Shubhrajyoti Datta , Linux ARM Kernel Mailing List , alan@linux.intel.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: balbi@ti.com List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Hi, On Tue, Aug 21, 2012 at 03:15:58PM +0300, Felipe Balbi wrote: > Hi guys, > > here's a series of cleanup patches to the OMAP serial > driver. A later series could be made re-implementing > DMA using the DMA Engine API. Note that for RX DMA > we could be using RX Timeout IRQ as a hint that we better > use PIO instead ;-) > > All patches were tested on my pandaboard, but I'd really > like to receive Tested-by on other platforms. > > After this goes in, I'll probably try to get UART wakeup > working again and only after that look at DMA. > > Changes since v1: > > . improved commit log on patch 9/13 (formerly 10/13) > . removed patch 2/13 > . added a new patch switching from spin_lock_irqsave() to spin_lock and > spin_unlock_irqrestore to spin_unlock > > Retested with my pandaboard, UART continues to work: > > # grep -i uart /proc/interrupts > 106: 124 0 GIC OMAP UART2 > # grep -i uart /proc/interrupts > 106: 189 0 GIC OMAP UART2 > # grep -i uart /proc/interrupts > 106: 255 0 GIC OMAP UART2 > # grep -i uart /proc/interrupts > 106: 321 0 GIC OMAP UART2 > # grep -i uart /proc/interrupts > 106: 387 0 GIC OMAP UART2 > # grep -i uart /proc/interrupts > 106: 453 0 GIC OMAP UART2 > # grep -i uart /proc/interrupts > 106: 519 0 GIC OMAP UART2 > > cheers > > ps: if anyone knows a better test for UART, let me know. > > for convenience of anyone testing, patches are available on my git tree [1] on > branch uart > > [1] git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git uart I have added one extra patch to this series: From 6921efdb13dda7af216b331bb35535d4b53f004a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 21 Aug 2012 15:48:35 +0300 Subject: [PATCH] serial: omap: drop pm_runtime_irq_safe() usage pm_runtime_irq_safe() will essentially do an unbalanced pm_runtime_get_sync() on our parent device, which might cause problems when trying to suspend. In order to prevent that we drop pm_runtime_irq_safe usage in exchange for a little performance hit when we enter our IRQ handler while still suspended. If that happens, what we will do is set the irq_pending flag, do an asynchronous pm_runtime_get() call and return IRQ_HANDLED. When our runtime_resume() callback is executed, we check for that flag, and run our IRQ handler so that we receive/transmit the pending characters. Signed-off-by: Felipe Balbi --- One extra patch to OMAP UART driver. This seems to be working pretty well even after echo mem > /sys/power/state. I can see that I can even wake my pandaboard up by sending a character through serial: # echo mem > /sys/power/state [ 1335.679260] PM: Syncing filesystems ... done. [ 1335.684387] Freezing user space processes ... (elapsed 0.00 seconds) done. [ 1335.691741] Freezing remaining freezable tasks ... (elapsed 0.02 seconds) done. [ 1335.720886] Suspending console(s) (use no_console_suspend to debug) [ 1335.734405] PM: suspend of devices complete after 5.492 msecs [ 1335.735534] PM: late suspend of devices complete after 1.128 msecs [ 1335.737518] PM: noirq suspend of devices complete after 1.952 msecs [ 1335.737518] Disabling non-boot CPUs ... [ 1335.738525] CPU1: shutdown [ 1338.543762] Successfully put all powerdomains to target state [ 1338.543853] Enabling non-boot CPUs ... [ 1338.545654] CPU1: Booted secondary processor [ 1338.546020] CPU1 is up [ 1338.547027] PM: noirq resume of devices complete after 0.976 msecs [ 1338.548400] PM: early resume of devices complete after 0.762 msecs [ 1339.827087] PM: resume of devices complete after 1278.686 msecs [ 1339.890960] Restarting tasks ... done. # # grep -i uart /proc/interrupts 106: 3385 0 GIC OMAP UART2 # echo mem > /sys/power/state [ 1358.015624] PM: Syncing filesystems ... done. [ 1358.020812] Freezing user space processes ... (elapsed 0.00 seconds) done. [ 1358.028167] Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done. [ 1358.055084] Suspending console(s) (use no_console_suspend to debug) [ 1358.068847] PM: suspend of devices complete after 5.633 msecs [ 1358.070007] PM: late suspend of devices complete after 1.126 msecs [ 1358.072051] PM: noirq suspend of devices complete after 2.040 msecs [ 1358.072051] Disabling non-boot CPUs ... [ 1358.073211] CPU1: shutdown [ 1359.104156] Successfully put all powerdomains to target state [ 1359.104278] Enabling non-boot CPUs ... [ 1359.106079] CPU1: Booted secondary processor [ 1359.106475] CPU1 is up [ 1359.107482] PM: noirq resume of devices complete after 1.004 msecs [ 1359.108886] PM: early resume of devices complete after 0.761 msecs [ 1360.414794] PM: resume of devices complete after 1305.836 msecs [ 1360.478668] Restarting tasks ... done. # # grep -i uart /proc/interrupts 106: 3511 0 GIC OMAP UART2 arch/arm/plat-omap/include/plat/omap-serial.h | 1 + drivers/tty/serial/omap-serial.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 743ac80..52328ca 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -130,6 +130,7 @@ struct uart_omap_port { u32 context_loss_cnt; u32 errata; u8 wakeups_enabled; + unsigned int irq_pending:1; struct pm_qos_request pm_qos_request; u32 latency; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index a79658d..7e237f3 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -353,9 +353,13 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) irqreturn_t ret = IRQ_HANDLED; int max_count = 256; - spin_lock(&up->port.lock); - pm_runtime_get_sync(up->dev); + if (pm_runtime_suspended(up->dev)) { + up->irq_pending = true; + pm_runtime_get(up->dev); + return IRQ_HANDLED; + } + spin_lock(&up->port.lock); do { iir = serial_in(up, UART_IIR); if (iir & UART_IIR_NO_INT) { @@ -400,6 +404,7 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); up->port_activity = jiffies; + up->irq_pending = false; return ret; } @@ -1305,7 +1310,6 @@ static int serial_omap_probe(struct platform_device *pdev) pm_runtime_set_autosuspend_delay(&pdev->dev, omap_up_info->autosuspend_timeout); - pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); @@ -1416,6 +1420,9 @@ static int serial_omap_runtime_suspend(struct device *dev) if (!up) return -EINVAL; + if (up->irq_pending) + return -EBUSY; + if (!pdata) return 0; @@ -1452,6 +1459,9 @@ static int serial_omap_runtime_resume(struct device *dev) up->latency = up->calc_latency; schedule_work(&up->qos_work); + + if (up->irq_pending) + serial_omap_irq(up->port.irq, up); } return 0;