From: Greg Kroah-Hartman <gregkh@suse.de>
To: linux-serial@vger.kernel.org
Cc: Jamie Iles <jamie@jamieiles.com>, Alan Cox <alan@linux.intel.com>,
Arnd Bergmann <arnd@arndb.de>,
Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 44/79] tty: add a DesignWare 8250 driver
Date: Wed, 26 Oct 2011 14:12:49 +0200 [thread overview]
Message-ID: <1319631204-23262-44-git-send-email-gregkh@suse.de> (raw)
In-Reply-To: <1319631204-23262-1-git-send-email-gregkh@suse.de>
From: Jamie Iles <jamie@jamieiles.com>
The Synopsys DesignWare 8250 is an 8250 that has an extra interrupt that
gets raised when writing to the LCR when busy. To handle this we need
special serial_out, serial_in and handle_irq methods. Add a new
platform driver that uses these accessors.
Cc: Alan Cox <alan@linux.intel.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
.../bindings/tty/serial/snps-dw-apb-uart.txt | 25 +++
drivers/tty/serial/8250_dw.c | 194 ++++++++++++++++++++
drivers/tty/serial/Kconfig | 7 +
drivers/tty/serial/Makefile | 1 +
4 files changed, 227 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/tty/serial/snps-dw-apb-uart.txt
create mode 100644 drivers/tty/serial/8250_dw.c
diff --git a/Documentation/devicetree/bindings/tty/serial/snps-dw-apb-uart.txt b/Documentation/devicetree/bindings/tty/serial/snps-dw-apb-uart.txt
new file mode 100644
index 0000000..f13f1c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/snps-dw-apb-uart.txt
@@ -0,0 +1,25 @@
+* Synopsys DesignWare ABP UART
+
+Required properties:
+- compatible : "snps,dw-apb-uart"
+- reg : offset and length of the register set for the device.
+- interrupts : should contain uart interrupt.
+- clock-frequency : the input clock frequency for the UART.
+
+Optional properties:
+- reg-shift : quantity to shift the register offsets by. If this property is
+ not present then the register offsets are not shifted.
+- reg-io-width : the size (in bytes) of the IO accesses that should be
+ performed on the device. If this property is not present then single byte
+ accesses are used.
+
+Example:
+
+ uart@80230000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0x80230000 0x100>;
+ clock-frequency = <3686400>;
+ interrupts = <10>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ };
diff --git a/drivers/tty/serial/8250_dw.c b/drivers/tty/serial/8250_dw.c
new file mode 100644
index 0000000..bf1fba6
--- /dev/null
+++ b/drivers/tty/serial/8250_dw.c
@@ -0,0 +1,194 @@
+/*
+ * Synopsys DesignWare 8250 driver.
+ *
+ * Copyright 2011 Picochip, Jamie Iles.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
+ * LCR is written whilst busy. If it is, then a busy detect interrupt is
+ * raised, the LCR needs to be rewritten and the uart status register read.
+ */
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct dw8250_data {
+ int last_lcr;
+ int line;
+};
+
+static void dw8250_serial_out(struct uart_port *p, int offset, int value)
+{
+ struct dw8250_data *d = p->private_data;
+
+ if (offset == UART_LCR)
+ d->last_lcr = value;
+
+ offset <<= p->regshift;
+ writeb(value, p->membase + offset);
+}
+
+static unsigned int dw8250_serial_in(struct uart_port *p, int offset)
+{
+ offset <<= p->regshift;
+
+ return readb(p->membase + offset);
+}
+
+static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
+{
+ struct dw8250_data *d = p->private_data;
+
+ if (offset == UART_LCR)
+ d->last_lcr = value;
+
+ offset <<= p->regshift;
+ writel(value, p->membase + offset);
+}
+
+static unsigned int dw8250_serial_in32(struct uart_port *p, int offset)
+{
+ offset <<= p->regshift;
+
+ return readl(p->membase + offset);
+}
+
+/* Offset for the DesignWare's UART Status Register. */
+#define UART_USR 0x1f
+
+static int dw8250_handle_irq(struct uart_port *p)
+{
+ struct dw8250_data *d = p->private_data;
+ unsigned int iir = p->serial_in(p, UART_IIR);
+
+ if (serial8250_handle_irq(p, iir)) {
+ return 1;
+ } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
+ /* Clear the USR and write the LCR again. */
+ (void)p->serial_in(p, UART_USR);
+ p->serial_out(p, d->last_lcr, UART_LCR);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int __devinit dw8250_probe(struct platform_device *pdev)
+{
+ struct uart_port port = {};
+ struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ struct device_node *np = pdev->dev.of_node;
+ u32 val;
+ struct dw8250_data *data;
+
+ if (!regs || !irq) {
+ dev_err(&pdev->dev, "no registers/irq defined\n");
+ return -EINVAL;
+ }
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ port.private_data = data;
+
+ spin_lock_init(&port.lock);
+ port.mapbase = regs->start;
+ port.irq = irq->start;
+ port.handle_irq = dw8250_handle_irq;
+ port.type = PORT_8250;
+ port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+ UPF_FIXED_PORT | UPF_FIXED_TYPE;
+ port.dev = &pdev->dev;
+
+ port.iotype = UPIO_MEM;
+ port.serial_in = dw8250_serial_in;
+ port.serial_out = dw8250_serial_out;
+ if (!of_property_read_u32(np, "reg-io-width", &val)) {
+ switch (val) {
+ case 1:
+ break;
+ case 4:
+ port.iotype = UPIO_MEM32;
+ port.serial_in = dw8250_serial_in32;
+ port.serial_out = dw8250_serial_out32;
+ break;
+ default:
+ dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n",
+ val);
+ return -EINVAL;
+ }
+ }
+
+ if (!of_property_read_u32(np, "reg-shift", &val))
+ port.regshift = val;
+
+ if (of_property_read_u32(np, "clock-frequency", &val)) {
+ dev_err(&pdev->dev, "no clock-frequency property set\n");
+ return -EINVAL;
+ }
+ port.uartclk = val;
+
+ data->line = serial8250_register_port(&port);
+ if (data->line < 0)
+ return data->line;
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+}
+
+static int __devexit dw8250_remove(struct platform_device *pdev)
+{
+ struct dw8250_data *data = platform_get_drvdata(pdev);
+
+ serial8250_unregister_port(data->line);
+
+ return 0;
+}
+
+static const struct of_device_id dw8250_match[] = {
+ { .compatible = "snps,dw-apb-uart" },
+ { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, dw8250_match);
+
+static struct platform_driver dw8250_platform_driver = {
+ .driver = {
+ .name = "dw-apb-uart",
+ .owner = THIS_MODULE,
+ .of_match_table = dw8250_match,
+ },
+ .probe = dw8250_probe,
+ .remove = __devexit_p(dw8250_remove),
+};
+
+static int __init dw8250_init(void)
+{
+ return platform_driver_register(&dw8250_platform_driver);
+}
+module_init(dw8250_init);
+
+static void __exit dw8250_exit(void)
+{
+ platform_driver_unregister(&dw8250_platform_driver);
+}
+module_exit(dw8250_exit);
+
+MODULE_AUTHOR("Jamie Iles");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Synopsys DesignWare 8250 serial port driver");
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 10babe2..8ee3a66 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -267,6 +267,13 @@ config SERIAL_8250_RM9K
port hardware found on MIPS RM9122 and similar processors.
If unsure, say N.
+config SERIAL_8250_DW
+ tristate "Support for Synopsys DesignWare 8250 quirks"
+ depends on SERIAL_8250 && OF
+ help
+ Selecting this option will enable handling of the extra features
+ present in the Synopsys DesignWare APB UART.
+
comment "Non-8250 serial port support"
config SERIAL_AMBA_PL010
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 7874813..7b59958 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -28,6 +28,7 @@ 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_MCA) += 8250_mca.o
+obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o
obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
--
1.7.7
next prev parent reply other threads:[~2011-10-26 12:13 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-26 11:42 [GIT PATCH] TTY/serial driver patches for 3.2 Greg KH
2011-10-26 12:12 ` [PATCH 01/79] tty/powerpc: introduce the ePAPR embedded hypervisor byte channel driver Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 02/79] drivers/tty/synclink: remove double comment Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 03/79] TTY: serial, remove BTM from wait_until_sent Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 04/79] TTY: msm_serial, remove unneeded console set Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 05/79] TTY: serial, remove tasklet for tty_wakeup Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 06/79] TTY: ami_serial, remove BTM from wait_until_sent Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 07/79] TTY: remove tty_locked Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 08/79] TTY: mxser+cyclades remove wait_until_sent debug code Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 09/79] serial:blackfin: Correct coding style in bfin serial driver Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 10/79] serial:blackfin: rename Blackfin serial driver to bfin_uart.c Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 11/79] tty: clearify structure initializer in notify_write() Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 12/79] serial:bfin_uart: Put TX IRQ in individual platform resource Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 13/79] serial: samsung: Add unified interrupt handler for s3c64xx and later SoC's Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 14/79] ARM: SAMSUNG: Remove uart irq handling from plaform code Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 15/79] tty: serial: allow ports to override the irq handler Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 16/79] tty: serial8250: allow platforms to override " Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 17/79] mips: msp71xx/serial: convert to pr_foo() helpers Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 18/79] mips: msp71xx/serial: add workaround for DW UART Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 19/79] tty: serial8250: remove UPIO_DWAPB{,32} Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 20/79] tty: serial8250: add helpers for the DesignWare 8250 Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 21/79] tty: of_serial: add support " Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 22/79] Revert "tty: of_serial: add support for the DesignWare 8250" Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 23/79] Revert "tty: serial8250: add helpers " Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 24/79] serial/imx: support to handle break character Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 25/79] atmel_serial: RS485: receiving enabled when sending data Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 26/79] tty: Add support serial for EXYNOS4212 SoC Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 27/79] jsm: remove remaining flip buffer code Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 28/79] jsm: remove buggy write queue Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 29/79] jsm: print byte we are dequeing Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 30/79] TTY: serial, use ASYNCB_CLOSING in uart_close Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 31/79] TTY: serial, move locking " Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 32/79] TTY: define tty_wait_until_sent_from_close Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 33/79] TTY: use tty_wait_until_sent_from_close in tty_port_close_start Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 34/79] TTY: use tty_wait_until_sent_from_close in other drivers Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 35/79] hsu: add runtime pm support Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 36/79] n_gsm: update TODO list Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 37/79] n_gsm: Send CLD command on exit Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 38/79] max3110: wake up fixes Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 39/79] x86/mrst: Add platform data for Max3110 devices Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 40/79] max3110: add sysrq support Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 41/79] max3110: Fix up port->tty backreferencing Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 42/79] tty/powerpc: fix build break with ehv_bytechan.c on allyesconfig Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 43/79] tty: 8250: export serial8250_handle_irq Greg Kroah-Hartman
2011-10-26 12:12 ` Greg Kroah-Hartman [this message]
2011-10-26 12:12 ` [PATCH 45/79] serial: pxa: work around for errata #20 Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 46/79] TTY: serial: Move mutex_unlock in uart_close function Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 47/79] TTY: serial, remove dead code from 68328 Greg Kroah-Hartman
2011-10-26 12:26 ` Geert Uytterhoeven
2011-10-26 12:12 ` [PATCH 48/79] TTY: serial, fix includes in some drivers Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 49/79] cris: fix a build error in drivers/tty/serial/crisv10.c Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 50/79] serial: Support the EFR-register of XR1715x uarts Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 51/79] cris: lower the printk level in cris serial driver Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 52/79] TTY: serial, move 68360 driver to staging Greg Kroah-Hartman
2011-10-26 12:27 ` Geert Uytterhoeven
2011-10-26 12:12 ` [PATCH 53/79] keyboard: Do not include <linux/irq.> Greg Kroah-Hartman
2011-10-26 12:12 ` [PATCH 54/79] serial: mfd: Initconst section fixes Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 55/79] serial-core: power up uart port early before we do set_termios when resuming Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 56/79] TTY: irq: Remove IRQF_DISABLED Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 57/79] drivers/tty: don't use the byte channel handle as a parameter in ehv_bytechan.c Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 58/79] tty/n_gsm: fix bug in tiocmset Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 59/79] 8250: ratelimit LSR safety check engaged warning Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 60/79] tty/n_gsm: fix a bug in gsm_dlci_data_output (adaption = 2 case) Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 61/79] tty/n_gsm: avoid fifo overflow in gsm_dlci_data_output Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 62/79] TTY: snyclinkmp: forever loop in tx_load_dma_buffer() Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 63/79] hvc_console: display printk messages on console Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 64/79] tty: Support compat_ioctl get/set termios_locked Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 65/79] parport_pc: release IO region properly if unsupported ITE887x card is found Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 66/79] h8300: drivers/serial/Kconfig was moved Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 67/79] 8250_pci: Fix kernel panic when pch_uart is disabled Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 68/79] TTY: drop driver reference in tty_open fail path Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 69/79] TTY: make tty_add_file non-failing Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 70/79] TTY: pty, release tty in all ptmx_open fail paths Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 71/79] TTY: call tty_driver_lookup_tty unconditionally Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 72/79] tty/serial: RS485 bindings for device tree Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 73/79] tty/serial: atmel_serial: change platform_data variable name Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 74/79] tty/serial: atmel_serial: whitespace and braces modifications Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 75/79] tty/serial: atmel_serial: auto-enumerate ports Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 76/79] tty/serial: atmel_serial: add device tree support Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 77/79] Revert "TTY: call tty_driver_lookup_tty unconditionally" Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 78/79] tty/serial: atmel_serial: bootconsole removed from auto-enumerates Greg Kroah-Hartman
2011-10-26 12:13 ` [PATCH 79/79] TTY: serial_core: Fix crash if DCD drop during suspend Greg Kroah-Hartman
2011-10-26 13:18 ` [GIT PATCH] TTY/serial driver patches for 3.2 Linus Torvalds
2011-10-26 13:34 ` Greg KH
2011-10-26 14:16 ` Domenico Andreoli
2011-10-26 21:38 ` Jiri Kosina
2011-10-26 15:01 ` Nicolas Ferre
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1319631204-23262-44-git-send-email-gregkh@suse.de \
--to=gregkh@suse.de \
--cc=alan@linux.intel.com \
--cc=arnd@arndb.de \
--cc=jamie@jamieiles.com \
--cc=linux-serial@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).