From patchwork Thu May 12 15:37:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic Desroches X-Patchwork-Id: 9083221 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D2CF49F372 for ; Thu, 12 May 2016 15:38:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E19D52024D for ; Thu, 12 May 2016 15:38:57 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0FFE5201EC for ; Thu, 12 May 2016 15:38:57 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1b0sg1-0007Lw-MU; Thu, 12 May 2016 15:37:25 +0000 Received: from eusmtp01.atmel.com ([212.144.249.242]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1b0sfz-0007HJ-BF for linux-arm-kernel@lists.infradead.org; Thu, 12 May 2016 15:37:24 +0000 Received: from ibiza.corp.atmel.com (10.161.101.13) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server id 14.3.235.1; Thu, 12 May 2016 17:36:57 +0200 From: Ludovic Desroches To: , Subject: [PATCH 1/3] tty/serial: atmel: re-integrate status check in irq handler Date: Thu, 12 May 2016 17:37:34 +0200 Message-ID: <1463067456-6983-1-git-send-email-ludovic.desroches@atmel.com> X-Mailer: git-send-email 2.5.0 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160512_083723_750024_4BB81498 X-CRM114-Status: GOOD ( 12.50 ) X-Spam-Score: -5.6 (-----) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-arm-kernel@lists.infradead.org, Ludovic Desroches , linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org, jslaby@suse.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Nicolas Ferre The IRQ status check and related actions was done in the tasklet without benefit. So, move it back to the IRQ context to simplify IRQ handling and having the possibility to split the tasklet in two separated ones for receive and transmit actions. Signed-off-by: Nicolas Ferre Signed-off-by: Ludovic Desroches --- drivers/tty/serial/atmel_serial.c | 43 ++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 954941d..8854ac6 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -146,9 +146,7 @@ struct atmel_uart_port { struct scatterlist sg_tx; struct scatterlist sg_rx; struct tasklet_struct tasklet; - unsigned int irq_status; unsigned int irq_status_prev; - unsigned int status_change; unsigned int tx_len; struct circ_buf rx_ring; @@ -1237,14 +1235,27 @@ atmel_handle_status(struct uart_port *port, unsigned int pending, unsigned int status) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + unsigned int status_change; if (pending & (ATMEL_US_RIIC | ATMEL_US_DSRIC | ATMEL_US_DCDIC | ATMEL_US_CTSIC)) { - atmel_port->irq_status = status; - atmel_port->status_change = atmel_port->irq_status ^ - atmel_port->irq_status_prev; + status_change = status ^ atmel_port->irq_status_prev; atmel_port->irq_status_prev = status; - tasklet_schedule(&atmel_port->tasklet); + + if (status_change & (ATMEL_US_RI | ATMEL_US_DSR + | ATMEL_US_DCD | ATMEL_US_CTS)) { + /* TODO: All reads to CSR will clear these interrupts! */ + if (status_change & ATMEL_US_RI) + port->icount.rng++; + if (status_change & ATMEL_US_DSR) + port->icount.dsr++; + if (status_change & ATMEL_US_DCD) + uart_handle_dcd_change(port, !(status & ATMEL_US_DCD)); + if (status_change & ATMEL_US_CTS) + uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); + + wake_up_interruptible(&port->state->port.delta_msr_wait); + } } } @@ -1575,31 +1586,12 @@ static void atmel_tasklet_func(unsigned long data) { struct uart_port *port = (struct uart_port *)data; struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - unsigned int status = atmel_port->irq_status; - unsigned int status_change = atmel_port->status_change; /* The interrupt handler does not take the lock */ spin_lock(&port->lock); atmel_port->schedule_tx(port); - if (status_change & (ATMEL_US_RI | ATMEL_US_DSR - | ATMEL_US_DCD | ATMEL_US_CTS)) { - /* TODO: All reads to CSR will clear these interrupts! */ - if (status_change & ATMEL_US_RI) - port->icount.rng++; - if (status_change & ATMEL_US_DSR) - port->icount.dsr++; - if (status_change & ATMEL_US_DCD) - uart_handle_dcd_change(port, !(status & ATMEL_US_DCD)); - if (status_change & ATMEL_US_CTS) - uart_handle_cts_change(port, !(status & ATMEL_US_CTS)); - - wake_up_interruptible(&port->state->port.delta_msr_wait); - - atmel_port->status_change = 0; - } - atmel_port->schedule_rx(port); spin_unlock(&port->lock); @@ -1833,7 +1825,6 @@ static int atmel_startup(struct uart_port *port) /* Save current CSR for comparison in atmel_tasklet_func() */ atmel_port->irq_status_prev = atmel_get_lines_status(port); - atmel_port->irq_status = atmel_port->irq_status_prev; /* * Finally, enable the serial port