From patchwork Tue Aug 21 09:15:50 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felipe Balbi X-Patchwork-Id: 1353191 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 4658840210 for ; Tue, 21 Aug 2012 09:23:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755402Ab2HUJW6 (ORCPT ); Tue, 21 Aug 2012 05:22:58 -0400 Received: from na3sys009aog127.obsmtp.com ([74.125.149.107]:36074 "EHLO na3sys009aog127.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755368Ab2HUJUW (ORCPT ); Tue, 21 Aug 2012 05:20:22 -0400 Received: from mail-lpp01m010-f52.google.com ([209.85.215.52]) (using TLSv1) by na3sys009aob127.postini.com ([74.125.148.12]) with SMTP ID DSNKUDNS1aGBniqxXH/QjsIw3v5Oa21X67AG@postini.com; Tue, 21 Aug 2012 02:20:21 PDT Received: by lage4 with SMTP id e4so5918786lag.39 for ; Tue, 21 Aug 2012 02:20:19 -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=aqkZD8robm+ak5abJd+caZnxdJxpVgv8hLimfawYtVY=; b=F9W1EPuzZ+hy/2mV0nuc88QcEYJU4Mpz+3N1HUCEOdjEXsMikwHT7EzzlNtvXBSa9Q /SF1PxQH1lFfHYrueaL+mXLSvTHv9qhBJyAsdEKswWJBPcxefRcWUENbIBjV5MSp53kO wTW6vbJctk/2t5UEaFw91mKjnp4UPD7stRMSvAxRcHATrdWbKT6x29XBI3Zp5D23C3MB EUv27e7ZHa/F/YUkkE4J+ddnreoWLWF3wt3JuaCZutUEnj8bs1qc5qULtSJH/yEnKehO WZj0s3xf+boooFzAIs95aYtkmPrFNwt9n+YRklpyX2rdmabbYHpJJ2kOGTvlvJUiM+bx aFPg== Received: by 10.152.122.9 with SMTP id lo9mr17038953lab.41.1345540819681; Tue, 21 Aug 2012 02:20:19 -0700 (PDT) Received: from localhost (cs78217178.pp.htv.fi. [62.78.217.178]) by mx.google.com with ESMTPS id j3sm286942lbh.0.2012.08.21.02.20.17 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 21 Aug 2012 02:20:18 -0700 (PDT) From: Felipe Balbi To: alan@linux.intel.com Cc: Tony Lindgren , Kevin Hilman , Linux OMAP Mailing List , Linux ARM Kernel Mailing List , linux-serial@vger.kernel.org, Linux Kernel Mailing List , Santosh Shilimkar , Shubhrajyoti Datta , Felipe Balbi Subject: [RFC/PATCH 08/13] serial: omap: refactor receive_chars() into rdi/rlsi handlers Date: Tue, 21 Aug 2012 12:15:50 +0300 Message-Id: <1345540555-24359-9-git-send-email-balbi@ti.com> X-Mailer: git-send-email 1.7.12.rc3 In-Reply-To: <1345540555-24359-1-git-send-email-balbi@ti.com> References: <1345540555-24359-1-git-send-email-balbi@ti.com> X-Gm-Message-State: ALoCoQn8c2d/7EXxz5jidnjK8RHT6e+4edPVB49iPao+ZjS9TQ0nXrOkkyVIPfrlpAXj9GmpxSmo Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.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. Signed-off-by: Felipe Balbi --- drivers/tty/serial/omap-serial.c | 203 +++++++++++++++++++-------------------- 1 file changed, 100 insertions(+), 103 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 1ca08b8..74a4f0a 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,52 +343,55 @@ 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; + 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) - goto out; - lsr = serial_in(up, UART_LSR); + do { + iir = serial_in(up, UART_IIR); + if (iir & UART_IIR_NO_INT) + 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;