From patchwork Mon Jul 22 08:30:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Song, Elen" X-Patchwork-Id: 2831167 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 67F8BC0319 for ; Mon, 22 Jul 2013 08:51:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3DAE0201D5 for ; Mon, 22 Jul 2013 08:51:34 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 43ECC201CE for ; Mon, 22 Jul 2013 08:51:29 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1BeC-0002bB-At; Mon, 22 Jul 2013 08:39:15 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1BdB-0001UB-Vt; Mon, 22 Jul 2013 08:38:09 +0000 Received: from eusmtp01.atmel.com ([212.144.249.242]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V1Bd9-0001T7-Bo for linux-arm-kernel@lists.infradead.org; Mon, 22 Jul 2013 08:38:08 +0000 Received: from apsmtp01.atmel.com (10.168.254.31) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server id 14.2.342.3; Mon, 22 Jul 2013 10:37:45 +0200 Received: from shaarm01.corp.atmel.com (10.168.254.13) by apsmtp01.atmel.com (10.168.254.31) with Microsoft SMTP Server id 14.2.342.3; Mon, 22 Jul 2013 16:39:24 +0800 From: Elen Song To: , , Subject: [PATCH 5/8 V3] serial: at91: support run time switch transfer mode Date: Mon, 22 Jul 2013 16:30:28 +0800 Message-ID: <1374481831-24573-6-git-send-email-elen.song@atmel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1374481831-24573-1-git-send-email-elen.song@atmel.com> References: <1374481831-24573-1-git-send-email-elen.song@atmel.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130722_043807_707579_6E34F2B6 X-CRM114-Status: GOOD ( 14.38 ) X-Spam-Score: -3.4 (---) Cc: gregkh@linuxfoundation.org, elen.song@atmel.com, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 We will switch to pio mode when request of dma or pdc fail. But soon or later, when the request is success, the transfer mode can switch to them at next open serial port action. So in startup stage, we should get original transfer mode. Signed-off-by: Elen Song --- drivers/tty/serial/atmel_serial.c | 139 +++++++++++++++++++++---------------- 1 file changed, 80 insertions(+), 59 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 0c15c5b..7bd8607 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -1371,6 +1371,80 @@ static void atmel_tasklet_func(unsigned long data) spin_unlock(&port->lock); } +static int atmel_init_property(struct atmel_uart_port *atmel_port, + struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct atmel_uart_data *pdata = pdev->dev.platform_data; + + if (np) { + /* DMA/PDC usage specification */ + if (of_get_property(np, "atmel,use-dma-rx", NULL)) { + if (of_get_property(np, "dmas", NULL)) { + atmel_port->use_dma_rx = true; + atmel_port->use_pdc_rx = false; + } else { + atmel_port->use_dma_rx = false; + atmel_port->use_pdc_rx = true; + } + } else { + atmel_port->use_dma_rx = false; + atmel_port->use_pdc_rx = false; + } + + if (of_get_property(np, "atmel,use-dma-tx", NULL)) { + if (of_get_property(np, "dmas", NULL)) { + atmel_port->use_dma_tx = true; + atmel_port->use_pdc_tx = false; + } else { + atmel_port->use_dma_tx = false; + atmel_port->use_pdc_tx = true; + } + } else { + atmel_port->use_dma_tx = false; + atmel_port->use_pdc_tx = false; + } + + } else { + atmel_port->use_pdc_rx = pdata->use_dma_rx; + atmel_port->use_pdc_tx = pdata->use_dma_tx; + atmel_port->use_dma_rx = false; + atmel_port->use_dma_tx = false; + } + + return 0; +} + +static void atmel_init_rs485(struct atmel_uart_port *atmel_port, + struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct atmel_uart_data *pdata = pdev->dev.platform_data; + + if (np) { + u32 rs485_delay[2]; + /* rs485 properties */ + if (of_property_read_u32_array(np, "rs485-rts-delay", + rs485_delay, 2) == 0) { + struct serial_rs485 *rs485conf = &atmel_port->rs485; + + rs485conf->delay_rts_before_send = rs485_delay[0]; + rs485conf->delay_rts_after_send = rs485_delay[1]; + rs485conf->flags = 0; + + if (of_get_property(np, "rs485-rx-during-tx", NULL)) + rs485conf->flags |= SER_RS485_RX_DURING_TX; + + if (of_get_property(np, "linux,rs485-enabled-at-boot-time", + NULL)) + rs485conf->flags |= SER_RS485_ENABLED; + } + } else { + atmel_port->rs485 = pdata->rs485; + } + +} + static void atmel_set_ops(struct uart_port *port) { struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); @@ -1409,6 +1483,7 @@ static void atmel_set_ops(struct uart_port *port) */ static int atmel_startup(struct uart_port *port) { + struct platform_device *pdev = to_platform_device(port->dev); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); struct tty_struct *tty = port->state->port.tty; int retval; @@ -1433,6 +1508,8 @@ static int atmel_startup(struct uart_port *port) /* * Initialize DMA (if necessary) */ + atmel_init_property(atmel_port, pdev); + if (atmel_port->prepare_rx) { retval = atmel_port->prepare_rx(port); if (retval < 0) @@ -1878,55 +1955,6 @@ static struct uart_ops atmel_pops = { #endif }; -static void atmel_of_init_port(struct atmel_uart_port *atmel_port, - struct device_node *np) -{ - u32 rs485_delay[2]; - - /* DMA/PDC usage specification */ - if (of_get_property(np, "atmel,use-dma-rx", NULL)) { - if (of_get_property(np, "dmas", NULL)) { - atmel_port->use_dma_rx = true; - atmel_port->use_pdc_rx = false; - } else { - atmel_port->use_dma_rx = false; - atmel_port->use_pdc_rx = true; - } - } else { - atmel_port->use_dma_rx = false; - atmel_port->use_pdc_rx = false; - } - - if (of_get_property(np, "atmel,use-dma-tx", NULL)) { - if (of_get_property(np, "dmas", NULL)) { - atmel_port->use_dma_tx = true; - atmel_port->use_pdc_tx = false; - } else { - atmel_port->use_dma_tx = false; - atmel_port->use_pdc_tx = true; - } - } else { - atmel_port->use_dma_tx = false; - atmel_port->use_pdc_tx = false; - } - - /* rs485 properties */ - if (of_property_read_u32_array(np, "rs485-rts-delay", - rs485_delay, 2) == 0) { - struct serial_rs485 *rs485conf = &atmel_port->rs485; - - rs485conf->delay_rts_before_send = rs485_delay[0]; - rs485conf->delay_rts_after_send = rs485_delay[1]; - rs485conf->flags = 0; - - if (of_get_property(np, "rs485-rx-during-tx", NULL)) - rs485conf->flags |= SER_RS485_RX_DURING_TX; - - if (of_get_property(np, "linux,rs485-enabled-at-boot-time", NULL)) - rs485conf->flags |= SER_RS485_ENABLED; - } -} - /* * Configure the port from the platform device resource info. */ @@ -1936,17 +1964,10 @@ static void atmel_init_port(struct atmel_uart_port *atmel_port, struct uart_port *port = &atmel_port->uart; struct atmel_uart_data *pdata = pdev->dev.platform_data; - if (pdev->dev.of_node) { - atmel_of_init_port(atmel_port, pdev->dev.of_node); - } else { - atmel_port->use_pdc_rx = pdata->use_dma_rx; - atmel_port->use_pdc_tx = pdata->use_dma_tx; - atmel_port->use_dma_rx = false; - atmel_port->use_dma_tx = false; - atmel_port->rs485 = pdata->rs485; - } + if (!atmel_init_property(atmel_port, pdev)) + atmel_set_ops(port); - atmel_set_ops(port); + atmel_init_rs485(atmel_port, pdev); port->iotype = UPIO_MEM; port->flags = UPF_BOOT_AUTOCONF;