From patchwork Tue Aug 21 12:16:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felipe Balbi X-Patchwork-Id: 1354831 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 378E93FC81 for ; Tue, 21 Aug 2012 12:27:15 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1T3nU4-0005XE-Q0; Tue, 21 Aug 2012 12:23:01 +0000 Received: from na3sys009aog121.obsmtp.com ([74.125.149.145]) by merlin.infradead.org with smtps (Exim 4.76 #1 (Red Hat Linux)) id 1T3nRg-0004P4-7e for linux-arm-kernel@lists.infradead.org; Tue, 21 Aug 2012 12:20:38 +0000 Received: from mail-lb0-f179.google.com ([209.85.217.179]) (using TLSv1) by na3sys009aob121.postini.com ([74.125.148.12]) with SMTP ID DSNKUDN9Dvx8eKxYrklDscTtwlh1oGb6XoB5@postini.com; Tue, 21 Aug 2012 05:20:31 PDT Received: by lbao2 with SMTP id o2so3173402lba.38 for ; Tue, 21 Aug 2012 05:20:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=9m3AYHjlpX1GxPhCnmIVFmEl6qzcT7yTcfBCRqkTvaw=; b=P2Kj3w5u36EY1Yt5qd36o5AUPQW+uUiQbAwDl8lX6eTNxREH38lwIfO+bL/m/cfaZe kcTRNmsC5J8A/vRbvP7kr+3VtSMQ1j1MVwipSRiOG+vjCYdTtjl6rva1MT6Fuse+QTpO O16dGuP75dpQ7v1X3J3upd3Huipv7ylniYQ/ZhJwlUCBLaIk4yPqlV1JBwFcnGUMQJ3W 4AXCO0OYbLGEBd8+Sy3WuLgJgd+yfDgbMtzVNDG3zZGEDuF/hfujUkAmZ2mQoZyDuWDr UXzjvpuFKFqU6R7ZLqWgBlsTJwU4u9B1w9a9XqKaj5XdAFF11HNRKfuWHiFITCIQ0Ufp foew== Received: by 10.152.108.144 with SMTP id hk16mr17304880lab.2.1345551628436; Tue, 21 Aug 2012 05:20:28 -0700 (PDT) Received: from localhost (cs78217178.pp.htv.fi. [62.78.217.178]) by mx.google.com with ESMTPS id r8sm391771lba.15.2012.08.21.05.20.26 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 21 Aug 2012 05:20:27 -0700 (PDT) From: Felipe Balbi To: alan@linux.intel.com Subject: [PATCH v2 07/13] serial: omap: refactor receive_chars() into rdi/rlsi handlers Date: Tue, 21 Aug 2012 15:16:05 +0300 Message-Id: <1345551371-18862-8-git-send-email-balbi@ti.com> X-Mailer: git-send-email 1.7.12.rc3 In-Reply-To: <1345551371-18862-1-git-send-email-balbi@ti.com> References: <1345540555-24359-1-git-send-email-balbi@ti.com> <1345551371-18862-1-git-send-email-balbi@ti.com> X-Gm-Message-State: ALoCoQm+YZ6iVM0Ehyy1ticsKrFvIFMYKmDKMNsbvXeCEREqfk/Ndw30eEjrEDB/RifVH4Wg1qFv 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.145 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 , Felipe Balbi , Santosh Shilimkar , linux-serial@vger.kernel.org, Linux OMAP Mailing List , Shubhrajyoti Datta , Linux ARM Kernel Mailing List X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org receive_chars() was getting too big and too difficult to follow. By splitting it into separate RDI and RSLI handlers, we have smaller functions which are easy to understand and only touch the pieces which they need to touch. Acked-by: Santosh Shilimkar Signed-off-by: Felipe Balbi --- drivers/tty/serial/omap-serial.c | 207 +++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 105 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 2d3e64e..fe9852b 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -195,74 +195,6 @@ static void serial_omap_stop_rx(struct uart_port *port) pm_runtime_put_autosuspend(up->dev); } -static inline void receive_chars(struct uart_omap_port *up, - unsigned int *status) -{ - struct tty_struct *tty = up->port.state->port.tty; - unsigned int flag, lsr = *status; - unsigned char ch = 0; - int max_count = 256; - - do { - if (likely(lsr & UART_LSR_DR)) - ch = serial_in(up, UART_RX); - flag = TTY_NORMAL; - up->port.icount.rx++; - - if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { - /* - * For statistics only - */ - if (lsr & UART_LSR_BI) { - lsr &= ~(UART_LSR_FE | UART_LSR_PE); - up->port.icount.brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ - if (uart_handle_break(&up->port)) - goto ignore_char; - } else if (lsr & UART_LSR_PE) { - up->port.icount.parity++; - } else if (lsr & UART_LSR_FE) { - up->port.icount.frame++; - } - - if (lsr & UART_LSR_OE) - up->port.icount.overrun++; - - /* - * Mask off conditions which should be ignored. - */ - lsr &= up->port.read_status_mask; - -#ifdef CONFIG_SERIAL_OMAP_CONSOLE - if (up->port.line == up->port.cons->index) { - /* Recover the break flag from console xmit */ - lsr |= up->lsr_break_flag; - } -#endif - if (lsr & UART_LSR_BI) - flag = TTY_BREAK; - else if (lsr & UART_LSR_PE) - flag = TTY_PARITY; - else if (lsr & UART_LSR_FE) - flag = TTY_FRAME; - } - - if (uart_handle_sysrq_char(&up->port, ch)) - goto ignore_char; - uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); -ignore_char: - lsr = serial_in(up, UART_LSR); - } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); - spin_unlock(&up->port.lock); - tty_flip_buffer_push(tty); - spin_lock(&up->port.lock); -} - static void transmit_chars(struct uart_omap_port *up) { struct circ_buf *xmit = &up->port.state->xmit; @@ -341,6 +273,68 @@ static unsigned int check_modem_status(struct uart_omap_port *up) return status; } +static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) +{ + unsigned int flag; + + up->port.icount.rx++; + flag = TTY_NORMAL; + + if (lsr & UART_LSR_BI) { + flag = TTY_BREAK; + lsr &= ~(UART_LSR_FE | UART_LSR_PE); + up->port.icount.brk++; + /* + * We do the SysRQ and SAK checking + * here because otherwise the break + * may get masked by ignore_status_mask + * or read_status_mask. + */ + if (uart_handle_break(&up->port)) + return; + + } + + if (lsr & UART_LSR_PE) { + flag = TTY_PARITY; + up->port.icount.parity++; + } + + if (lsr & UART_LSR_FE) { + flag = TTY_FRAME; + up->port.icount.frame++; + } + + if (lsr & UART_LSR_OE) + up->port.icount.overrun++; + +#ifdef CONFIG_SERIAL_OMAP_CONSOLE + if (up->port.line == up->port.cons->index) { + /* Recover the break flag from console xmit */ + lsr |= up->lsr_break_flag; + } +#endif + uart_insert_char(&up->port, lsr, UART_LSR_OE, 0, flag); +} + +static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) +{ + unsigned char ch = 0; + unsigned int flag; + + if (!(lsr & UART_LSR_DR)) + return; + + ch = serial_in(up, UART_RX); + flag = TTY_NORMAL; + up->port.icount.rx++; + + if (uart_handle_sysrq_char(&up->port, ch)) + return; + + uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); +} + /** * serial_omap_irq() - This handles the interrupt from one port * @irq: uart port irq number @@ -349,55 +343,58 @@ static unsigned int check_modem_status(struct uart_omap_port *up) static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) { struct uart_omap_port *up = dev_id; + struct tty_struct *tty = up->port.state->port.tty; unsigned int iir, lsr; unsigned int type; unsigned long flags; irqreturn_t ret = IRQ_HANDLED; + int max_count = 256; spin_lock_irqsave(&up->port.lock, flags); pm_runtime_get_sync(up->dev); - iir = serial_in(up, UART_IIR); -again: - if (iir & UART_IIR_NO_INT) { - ret = IRQ_NONE; - goto out; - } - lsr = serial_in(up, UART_LSR); + do { + iir = serial_in(up, UART_IIR); + if (iir & UART_IIR_NO_INT) { + ret = IRQ_NONE; + break; + } - /* extract IRQ type from IIR register */ - type = iir & 0x3e; + lsr = serial_in(up, UART_LSR); - switch (type) { - case UART_IIR_MSI: - check_modem_status(up); - break; - case UART_IIR_THRI: - if (lsr & UART_LSR_THRE) - transmit_chars(up); - break; - case UART_IIR_RDI: - if (lsr & UART_LSR_DR) - receive_chars(up, &lsr); - break; - case UART_IIR_RLSI: - if (lsr & UART_LSR_BRK_ERROR_BITS) - receive_chars(up, &lsr); - break; - case UART_IIR_RX_TIMEOUT: - receive_chars(up, &lsr); - break; - case UART_IIR_CTS_RTS_DSR: - iir = serial_in(up, UART_IIR); - goto again; - case UART_IIR_XOFF: - /* FALLTHROUGH */ - default: - break; - } + /* extract IRQ type from IIR register */ + type = iir & 0x3e; + + switch (type) { + case UART_IIR_MSI: + check_modem_status(up); + break; + case UART_IIR_THRI: + if (lsr & UART_LSR_THRE) + transmit_chars(up); + break; + case UART_IIR_RX_TIMEOUT: + /* FALLTHROUGH */ + case UART_IIR_RDI: + serial_omap_rdi(up, lsr); + break; + case UART_IIR_RLSI: + serial_omap_rlsi(up, lsr); + break; + case UART_IIR_CTS_RTS_DSR: + /* simply try again */ + break; + case UART_IIR_XOFF: + /* FALLTHROUGH */ + default: + break; + } + } while (!(iir & UART_IIR_NO_INT) && max_count--); -out: spin_unlock_irqrestore(&up->port.lock, flags); + + tty_flip_buffer_push(tty); + pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); up->port_activity = jiffies;