From patchwork Wed Apr 16 17:17:17 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Yanovich X-Patchwork-Id: 4003261 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 F0C6FBFF02 for ; Wed, 16 Apr 2014 17:22:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E9D1620374 for ; Wed, 16 Apr 2014 17:22:41 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DF6AD2027D for ; Wed, 16 Apr 2014 17:22:40 +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 1WaTVl-0001Og-Eh; Wed, 16 Apr 2014 17:20:37 +0000 Received: from mail-lb0-x22f.google.com ([2a00:1450:4010:c04::22f]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WaTUm-0006hA-QZ for linux-arm-kernel@lists.infradead.org; Wed, 16 Apr 2014 17:19:37 +0000 Received: by mail-lb0-f175.google.com with SMTP id w7so8401805lbi.34 for ; Wed, 16 Apr 2014 10:19:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=enteiPcpVVaYRqn+ovBz4riU77MLroPIXAMIAkQQNrM=; b=v1Lk7OpFjkVFZS1qPIaws4VzbEixYJrwHGvj7WSJ8OE50/9QZApV7GaY+J5aaJZOca PSVCsm8Ig006l06vcd3CC3abgo3wyjDTt11vgfuh2bDPgAqDUVUwd0asvFKDWtwTQZ88 qmMzAPFsDLo56TrywRFopPm47jIKPDXurl6VeFqIMCf3AwUr+otbvxaPpJLh9crClXiv QBOyxHKpQylSwsDDpIAsT6fmqR1qgxDIMflPW1nzFoAkTRVG/qVkFhMrzEXI+keIrEUm XdO8NLhql2QPzesecjVryrdpIE9SaU4qPhfv0GKXXyghzmNiFDAryfHwt1RW0kJMkMTi /j7g== X-Received: by 10.112.1.233 with SMTP id 9mr3577248lbp.29.1397668753181; Wed, 16 Apr 2014 10:19:13 -0700 (PDT) Received: from host5.omatika.ru (0893675324.static.corbina.ru. [95.31.1.192]) by mx.google.com with ESMTPSA id q4sm21186297lbh.20.2014.04.16.10.19.10 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 16 Apr 2014 10:19:12 -0700 (PDT) From: Sergei Ianovich To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 12/21] serial: support for 16550A serial ports on LP-8x4x Date: Wed, 16 Apr 2014 21:17:17 +0400 Message-Id: <1397668667-27328-6-git-send-email-ynvich@gmail.com> X-Mailer: git-send-email 1.9.2 In-Reply-To: <1397668667-27328-1-git-send-email-ynvich@gmail.com> References: <1397668411-27162-7-git-send-email-ynvich@gmail.com> <1397668667-27328-1-git-send-email-ynvich@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140416_101937_255777_70AA2603 X-CRM114-Status: GOOD ( 21.50 ) X-Spam-Score: -0.1 (/) Cc: Mark Rutland , "open list:OPEN FIRMWARE AND..." , Paul Bolle , Heikki Krogerus , Russell King , Arnd Bergmann , Pawel Moll , Ian Campbell , Greg Kroah-Hartman , Randy Dunlap , "open list:DOCUMENTATION" , Stefan Seyfried , Sergei Ianovich , Rob Herring , "open list:SERIAL DRIVERS" , Kumar Gala , Grant Likely , Jiri Slaby , James Cameron 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RP_MATCHES_RCVD, T_DKIM_INVALID, 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 The patch adds support for 3 additional LP-8x4x built-in serial ports. The device can also host up to 8 extension cards with 4 serial ports on each card for a total of 35 ports. However, I don't have the hardware to test extension cards, so they are not supported, yet. Signed-off-by: Sergei Ianovich Reviewed-by: Heikki Krogerus --- v3..v4 * move DTS bindings to a different patch (8/21) as suggested by Heikki Krogerus v2..v3 * no changes (except number 10/16 -> 12/21) v0..v2 * register platform driver instead of platform device * use device tree * use devm helpers where possible .../devicetree/bindings/serial/lp8x4x-serial.txt | 35 +++++ arch/arm/configs/lp8x4x_defconfig | 1 + drivers/tty/serial/8250/8250_lp8x4x.c | 169 +++++++++++++++++++++ drivers/tty/serial/8250/Kconfig | 12 ++ drivers/tty/serial/8250/Makefile | 1 + 5 files changed, 218 insertions(+) create mode 100644 Documentation/devicetree/bindings/serial/lp8x4x-serial.txt create mode 100644 drivers/tty/serial/8250/8250_lp8x4x.c diff --git a/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt new file mode 100644 index 0000000..5f9a4c1 --- /dev/null +++ b/Documentation/devicetree/bindings/serial/lp8x4x-serial.txt @@ -0,0 +1,35 @@ +UART ports on ICP DAS LP-8x4x + +ICP DAS LP-8x4x contains three additional serial ports interfaced via +Analog Devices ADM213EA chips in addition to 3 serial ports on PXA CPU. + +Required properties: +- compatible : should be "icpdas,uart-lp8x4x" + +- reg : should provide 16 byte man IO memory region and 1 byte region for + termios + +- interrupts : should provide interrupt + +- interrupt-parent : should provide a link to interrupt controller either + explicitly or implicitly from a parent node + +Examples (from pxa27x-lp8x4x.dts): + + uart@9050 { + compatible = "icpdas,uart-lp8x4x"; + reg = <0x9050 0x10 + 0x9030 0x02>; + interrupt-parent = <&fpgairg>; + interrupts = <13>; + status = "okay"; + }; + + uart@9060 { + compatible = "icpdas,uart-lp8x4x"; + reg = <0x9060 0x10 + 0x9032 0x02>; + interrupt-parent = <&fpgairg>; + interrupts = <14>; + status = "okay"; + }; diff --git a/arch/arm/configs/lp8x4x_defconfig b/arch/arm/configs/lp8x4x_defconfig index 17a4e6f..9116ce1 100644 --- a/arch/arm/configs/lp8x4x_defconfig +++ b/arch/arm/configs/lp8x4x_defconfig @@ -112,6 +112,7 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_PXA=y +CONFIG_SERIAL_8250_LP8X4X=m CONFIG_HW_RANDOM=y CONFIG_I2C=m # CONFIG_I2C_COMPAT is not set diff --git a/drivers/tty/serial/8250/8250_lp8x4x.c b/drivers/tty/serial/8250/8250_lp8x4x.c new file mode 100644 index 0000000..93e0f59 --- /dev/null +++ b/drivers/tty/serial/8250/8250_lp8x4x.c @@ -0,0 +1,169 @@ +/* linux/drivers/tty/serial/8250/8250_lp8x4x.c + * + * Support for 16550A serial ports on ICP DAS LP-8x4x + * + * Copyright (C) 2013 Sergei Ianovich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +struct lp8x4x_serial_data { + int line; + void *ios_mem; +}; + +static void lp8x4x_serial_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old) +{ + unsigned int len; + unsigned int baud; + struct lp8x4x_serial_data *data = port->private_data; + + switch (termios->c_cflag & CSIZE) { + case CS5: + len = 7; + break; + case CS6: + len = 8; + break; + case CS7: + len = 9; + break; + default: + case CS8: + len = 10; + break; + } + + if (termios->c_cflag & CSTOPB) + len++; + if (termios->c_cflag & PARENB) + len++; + if (!(termios->c_cflag & PARODD)) + len++; +#ifdef CMSPAR + if (termios->c_cflag & CMSPAR) + len++; +#endif + + len -= 9; + len &= 3; + len <<= 3; + /* + * Ask the core to calculate the divisor for us. + */ + baud = uart_get_baud_rate(port, termios, old, + port->uartclk / 16 / 0xffff, + port->uartclk / 16); + switch (baud) { + case 2400: + len |= 1; + break; + case 4800: + len |= 2; + break; + case 19200: + len |= 4; + break; + case 38400: + len |= 5; + break; + case 57600: + len |= 6; + break; + case 115200: + len |= 7; + break; + case 9600: + default: + len |= 3; + break; + }; + iowrite8(len, data->ios_mem); + + serial8250_do_set_termios(port, termios, old); +} + +static struct of_device_id lp8x4x_serial_dt_ids[] = { + { .compatible = "icpdas,uart-lp8x4x", }, + {} +}; +MODULE_DEVICE_TABLE(of, lp8x4x_serial_dt_ids); + +static int lp8x4x_serial_probe(struct platform_device *pdev) +{ + struct uart_8250_port uart = {}; + struct lp8x4x_serial_data *data; + struct resource *mmres, *mires, *irqres; + int ret; + + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mires = platform_get_resource(pdev, IORESOURCE_MEM, 1); + irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!mmres || !mires || !irqres) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->ios_mem = devm_ioremap_resource(&pdev->dev, mires); + if (!data->ios_mem) + return -EFAULT; + + uart.port.iotype = UPIO_MEM; + uart.port.mapbase = mmres->start; + uart.port.iobase = mmres->start; + uart.port.regshift = 1; + uart.port.irq = irqres->start; + uart.port.flags = UPF_IOREMAP; + uart.port.dev = &pdev->dev; + uart.port.uartclk = 14745600; + uart.port.set_termios = lp8x4x_serial_set_termios; + uart.port.private_data = data; + + ret = serial8250_register_8250_port(&uart); + if (ret < 0) + return ret; + + data->line = ret; + + platform_set_drvdata(pdev, data); + + return 0; +} + +static int lp8x4x_serial_remove(struct platform_device *pdev) +{ + struct lp8x4x_serial_data *data = platform_get_drvdata(pdev); + + serial8250_unregister_port(data->line); + + return 0; +} + +static struct platform_driver lp8x4x_serial_driver = { + .probe = lp8x4x_serial_probe, + .remove = lp8x4x_serial_remove, + + .driver = { + .name = "uart-lp8x4x", + .owner = THIS_MODULE, + .of_match_table = lp8x4x_serial_dt_ids, + }, +}; + +module_platform_driver(lp8x4x_serial_driver); + +MODULE_AUTHOR("Sergei Ianovich"); +MODULE_DESCRIPTION("8250 serial port module for LP-8x4x"); +MODULE_LICENSE("GPL"); diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index 81bd7c9..9fb0fbb 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -311,3 +311,15 @@ config SERIAL_PXA can enable its onboard serial ports by enabling this option. If you choose M here, the module name will be 8250_pxa. + +config SERIAL_8250_LP8X4X + tristate "Support 16550A ports on ICP DAS LP-8x4x" + depends on OF && SERIAL_8250 && SERIAL_8250_MANY_PORTS && ARCH_PXA + select LP8X4X_IRQ + help + In addition to serial ports on PXA270 SoC, LP-8x4x has 1 dual + RS232/RS485 port, 1 RS485 port and 1 RS232 port. + + Say N here, unless you plan to run this kernel on a LP-8x4x system. + + If you choose M here, the module name will be 8250_lp8x4x. diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index b7d1b61..7370bfb 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o +obj-$(CONFIG_SERIAL_8250_LP8X4X) += 8250_lp8x4x.o obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_8250_EM) += 8250_em.o