Skip to contentSkip to conversation

serial: Add driver for OMAP UARTs

PATCH In review Juha Yrjölä 6 participants 7 messages Apr 9, 2007 – Apr 17, 2007

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 serial: Add driver for OMAP UARTs

Quoted 1 line

From 1b812d197f1451fc03335a999472a25e8c1830c6 Mon Sep 17 00:00:00 2001

From: Juha Yrjola <[email protected]>
Date: Mon, 9 Apr 2007 23:43:34 +0300
Subject: [PATCH] serial: Add driver for OMAP UARTs

An OMAP-specific UART driver is needed when support for advanced functionality (such as DMA transfers and power management) is added. Currently it helps to work around UART initialization bugs at least in the OMAP2420 silicon.

Only OMAP24xx CPUs are supported at the moment, although adding support for OMAP1 should not be a big deal.

---
 arch/arm/configs/n800_defconfig              |    8 +-
 arch/arm/configs/omap_2430sdp_defconfig      |   12 +-
 arch/arm/configs/omap_apollon_2420_defconfig |   12 +-
 arch/arm/configs/omap_generic_2420_defconfig |    7 +-
 arch/arm/configs/omap_h4_2420_defconfig      |   12 +-
 arch/arm/mach-omap2/serial.c                 |  190 ++----
 drivers/serial/Kconfig                       |   23 +
 drivers/serial/Makefile                      |    1 +
 drivers/serial/omap.c                        |  893 ++++++++++++++++++++++++++
 include/linux/serial_core.h                  |    2 +
 10 files changed, 994 insertions(+), 166 deletions(-)
 create mode 100644 drivers/serial/omap.c
arch/arm/configs/n800_defconfig +3 -5
index 6664184..aa18816 100644
@@ -762,15 +762,13 @@ CONFIG_HW_CONSOLE=y
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
arch/arm/configs/omap_2430sdp_defconfig +3 -9
index 19d49b0..c560f95 100644
@@ -673,19 +673,13 @@ CONFIG_HW_CONSOLE=y
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
arch/arm/configs/omap_apollon_2420_defconfig +3 -9
index 2cef064..fe25bcc 100644
@@ -600,19 +600,13 @@ CONFIG_HW_CONSOLE=y
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
arch/arm/configs/omap_generic_2420_defconfig +3 -4
index 94d4659..2bd1552 100644
@@ -322,14 +322,13 @@ CONFIG_HW_CONSOLE=y
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
arch/arm/configs/omap_h4_2420_defconfig +3 -9
index 8ef2d68..bb30278 100644
@@ -659,19 +659,13 @@ CONFIG_HW_CONSOLE=y
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=32
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_8250_DETECT_IRQ=y
-CONFIG_SERIAL_8250_RSA=y
+# CONFIG_SERIAL_8250 is not set
 
 #
 # Non-8250 serial port support
 #
+CONFIG_SERIAL_OMAP=y
+CONFIG_SERIAL_OMAP_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
arch/arm/mach-omap2/serial.c +60 -130

223 lines not on this page · raw message

drivers/serial/Kconfig +23 -0
index ad9f321..edca795 100644
@@ -474,6 +474,29 @@ config SERIAL_PXA_CONSOLE
 	  your boot loader (lilo or loadlin) about how to pass options to the
 	  kernel at boot time.)
 
+config SERIAL_OMAP
+	bool "OMAP serial port support"
+	depends on ARM && ARCH_OMAP
+	select SERIAL_CORE
+	help
+	  If you have a machine based on an Texas Instruments OMAP CPU you
+	  can enable its onboard serial ports by enabling this option.
+
+config SERIAL_OMAP_CONSOLE
+	bool "Console on OMAP serial port"
+	depends on SERIAL_OMAP
+	select SERIAL_CORE_CONSOLE
+	help
+	  If you have enabled the serial port on the Texas Instruments OMAP
+	  CPU you can make it the console by answering Y to this option.
+
+	  Even if you say Y here, the currently visible virtual console
+	  (/dev/tty0) will still be used as the system console by default, but
+	  you can alter that using a kernel command line option such as
+	  "console=ttyS0". (Try "man bootparam" or see the documentation of
+	  your boot loader (lilo or loadlin) about how to pass options to the
+	  kernel at boot time.)
+
 config SERIAL_SA1100
 	bool "SA1100 serial port support"
 	depends on ARM && ARCH_SA1100
drivers/serial/Makefile +1 -0
index 6b3560c..5d9f6d4 100644
@@ -25,6 +25,7 @@ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
 obj-$(CONFIG_SERIAL_PXA) += pxa.o
+obj-$(CONFIG_SERIAL_OMAP) += omap.o
 obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
 obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
 obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
drivers/serial/omap.c new file +893 -0

893 lines not on this page · raw message

include/linux/serial_core.h +2 -0
index 586aaba..6b1c646 100644
@@ -135,6 +135,8 @@
 /* Xilinx uartlite */
 #define PORT_UARTLITE	74
 
+#define PORT_OMAP	75
+
 #ifdef __KERNEL__
 
 #include <linux/compiler.h>
Signature · 1 line
1.5.1
#1 lore raw

Hi Juha,

The serial driver presented is really good, as you said we can enhance the same for DMA, High speed UART, Power Management etc.

One concern I had here was, as we know OMAP supports multiple (3) UART ports and they can be used for IrDA (UART3), Bluetooth (UART2/1), Serial applications etc. All these drivers should configure/use similar register sets. So if we could,

- make the arch/arm/mach-omap2/serial.c more kind of a generic UART API library that can be used by all UART drivers.
- the UART library should handle overall clock /power management policy.
- Centralized interrupt handler.
- DMA / Polling / Interrupt based read/writes.

- The serial driver implemented by you, IrDA and other UART dependent drivers should use the APIs exported by UART library.

- Basically UART dependent drivers should get registered with centralized UART library for interrupt, clock, power and data transfer.

This will avoid redundant code (for DMA, interrupt, PM, clk) in multiple drivers. If we like/agree on this design, I can probably post a patch (RFC) for the same.

Please do let me know your comments / suggestions.

Regards,
Khasim

Quoted 36 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Juha Yrjölä
Sent: Monday, April 09, 2007 3:45 PM
To: [email protected]
Subject: [PATCH] serial: Add driver for OMAP UARTs

Quoted 1 line

From 1b812d197f1451fc03335a999472a25e8c1830c6 Mon Sep 17 00:00:00 2001

From: Juha Yrjola <[email protected]>
Date: Mon, 9 Apr 2007 23:43:34 +0300
Subject: [PATCH] serial: Add driver for OMAP UARTs

An OMAP-specific UART driver is needed when support for advanced functionality (such as DMA transfers and power management) is added. Currently it helps to work around UART initialization bugs at least in the OMAP2420 silicon.

Only OMAP24xx CPUs are supported at the moment, although adding support for OMAP1 should not be a big deal.

---

arch/arm/configs/n800_defconfig              |    8 +-
arch/arm/configs/omap_2430sdp_defconfig      |   12 +-
arch/arm/configs/omap_apollon_2420_defconfig |   12 +-
arch/arm/configs/omap_generic_2420_defconfig |    7 +-
arch/arm/configs/omap_h4_2420_defconfig      |   12 +-
arch/arm/mach-omap2/serial.c                 |  190 ++----
drivers/serial/Kconfig                       |   23 +
drivers/serial/Makefile                      |    1 +
drivers/serial/omap.c                        |  893
++++++++++++++++++++++++++
include/linux/serial_core.h                  |    2 +
10 files changed, 994 insertions(+), 166 deletions(-)

create mode 100644 drivers/serial/omap.c

#2 lore raw

Hi Khasim,

Quoted 10 lines · Khasim

One concern I had here was, as we know OMAP supports multiple (3) UART ports and they can be used for IrDA (UART3), Bluetooth (UART2/1), Serial applications etc. All these drivers should configure/use similar register sets. So if we could,

- make the arch/arm/mach-omap2/serial.c more kind of a generic UART API library that can be used by all UART drivers.
- the UART library should handle overall clock /power management policy.
- Centralized interrupt handler.
- DMA / Polling / Interrupt based read/writes.

It is certainly a good idea. You probably meant to write plat-omap/serial.c, since obviously the implementation shouldn't be limited to OMAP2.

I suppose the UART library will not be trivial, though. I don't know what kind of special needs Bluetooth and IrDA have, but for example the serial console code needs specific handling for the Magic SysRQ characters in the RX loop. The N800 Bluetooth driver does some funky stuff related to PM, as well.

Cheers,
Juha

#3 lore raw
In reply to Juha Yrjölä

Hi Juha,

Some reviewing and testing done. Some comments.

drivers/serial/omap.c line 349

Quoted 4 lines
drivers/serial/omap.c new file +4 -0
+	/* Reset the UART */
+	serial_out(up, UART_OMAP_MDR1, 0x07);
+	udelay(50);
+	serial_out(up, UART_OMAP_MDR1, 0x00);

I think that this doesn't really reset UART. And the result is some garbage coming from serial port after opening it.

serial_out(up, UART_OMAP_SYSC, 0x02);
udelay(50);

should be used instead?

drivers/serial/omap.c line 661

Quoted 3 lines
drivers/serial/omap.c new file +3 -0
+	if (co->index == -1 || co->index >= serial_omap_reg.nr ||
+	    serial_omap_console_ports[co->index] == NULL)
+		co->index = 0;

I don't understand what is point in this code but following observation. Kernel hits null pointer if this code is in and multible ports are enabled from bootloader.

Without this code multible ports work fine.

Signature · 1 line
Ville
#4 lore raw
In reply to Juha Yrjölä
Quoted 26 lines · Juha Yrjölä
drivers/serial/omap.c new file +19 -0
@@ -0,0 +1,893 @@
 
 
+static int serial_omap_startup(struct uart_port *port)
+{
+	struct uart_omap_port *up = (struct uart_omap_port *)port;
+	unsigned long flags;
+	int retval;
+
+	enable_uart_clocks(up);
+
+	/*
+	 * Allocate the IRQ
+	 */
+	retval = request_irq(up->port.irq, serial_omap_irq, 0, up->name, up);
+	if (retval) {
+		disable_uart_clocks(up);
+		return retval;
+	}
+
 
 
+}
+

drivers/serial/omap.c line 408

Quoted 10 lines
drivers/serial/omap.c new file +8 -0
+static void serial_omap_shutdown(struct uart_port *port)
+{
 
 
+	disable_uart_clocks(up);
+
+	clk_put(up->fclk);
+	if (up->iclk != NULL)
+		clk_put(up->iclk);
+}

You should probably move {enable,disable}_uart_clocks() calls into the uart_ops .pm function, serial_omap_pm() (which is currently a stub : ), assuming clocks can be controlled per serial port. In fact, if clocks are controlled per serial port, then you may discover problems if you do not move clock handling into the .pm function, e.g. try this when one or more serial ports are not in use:

cat /proc/tty/serial

If one or more serial ports are disabled, results should be garbage and or the system may hang depending on behavior when serial port clocks are disabled. I expect you will need to s/serial/OMAP serial/ in the above example but more on that below.

Quoted 13 lines
drivers/serial/omap.c new file +13 -0
+struct uart_ops serial_omap_pops = {
+	.tx_empty	= serial_omap_tx_empty,
+	.set_mctrl	= serial_omap_set_mctrl,
+	.get_mctrl	= serial_omap_get_mctrl,
+	.stop_tx	= serial_omap_stop_tx,
+	.start_tx	= serial_omap_start_tx,
+	.stop_rx	= serial_omap_stop_rx,
+	.enable_ms	= serial_omap_enable_ms,
+	.break_ctl	= serial_omap_break_ctl,
+	.startup	= serial_omap_startup,
+	.shutdown	= serial_omap_shutdown,
+	.set_termios	= serial_omap_set_termios,
+	.pm		= serial_omap_pm,

drivers/serial/omap.c line 741

Quoted 10 lines
drivers/serial/omap.c new file +10 -0
+	.type		= serial_omap_type,
+	.release_port	= serial_omap_release_port,
+	.request_port	= serial_omap_request_port,
+	.config_port	= serial_omap_config_port,
+	.verify_port	= serial_omap_verify_port,
+};
+
+static struct uart_driver serial_omap_reg = {
+	.owner		= THIS_MODULE,
+	.driver_name	= "OMAP serial",

You may want to reconsider ".driver_name" otherwise I suspect this may appear as:

"/proc/tty/driver/OMAP serial"

Yuck. : )

drivers/serial/omap.c line 747

Quoted 6 lines
drivers/serial/omap.c new file +6 -0
+	.dev_name	= "ttyS",
+	.major		= TTY_MAJOR,
+	.minor		= 64,
+	.nr		= 3,
+	.cons		= OMAP_CONSOLE,
+};

--
Regards,
George

#5 lore raw

Testing SPI on omap5912

hI,

I am trying to test SPI driver on omap5912. I have found I can't use Sd/MMC as SPI slave device for it's host controller in-built on the development board. I have found several ways to test SPI driver on my development board.

Internal SPI slave device possibility:

AIC23 codec uses I2C. We can use the SPI bus. Length work to write the SPI protocol driver. -- need reference to proceed..

Another possibility of using the TOUCHSCREEN driver which uses MCBSP interface to use enabled SPI mode. --need reference

External SPI slave device:

any flash device -- any reference...

I am actualy looking out to test any SPI application using linux-2.6.20 git kernel port to my development board that has omap5912 core.

-Raja

maintainer
#6 lore raw
In reply to George G. Davis
Quoted 10 lines · George G. Davis

drivers/serial/omap.c line 741

Quoted 3 lines · Juha Yrjölä
drivers/serial/omap.c new file +3 -0
+static struct uart_driver serial_omap_reg = {
+	.owner		= THIS_MODULE,
+	.driver_name	= "OMAP serial",

You may want to reconsider ".driver_name" otherwise I suspect this may appear as:

"/proc/tty/driver/OMAP serial"

Quoted 8 lines

Yuck. : )

drivers/serial/omap.c line 747

Quoted 6 lines
drivers/serial/omap.c new file +6 -0
+	.dev_name	= "ttyS",
+	.major		= TTY_MAJOR,
+	.minor		= 64,
+	.nr		= 3,
+	.cons		= OMAP_CONSOLE,
+};

Also one thing that needs to be verified is that using ttyS may conflict with standard 8250 add-on ports, such as CF/PCMCIA modems or bluetooth devices. At least it used to be that the non 8250 serial ports must use a different name because of this issue.

Regards,

Tony