serial: Add driver for OMAP UARTs
PATCH 1/1 serial: Add driver for OMAP UARTs
Quoted 1 line
From
1b812d197f1451fc03335a999472a25e8c1830c6Mon 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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 UARTsQuoted 1 line
From
1b812d197f1451fc03335a999472a25e8c1830c6Mon Sep 17 00:00:00 2001From: Juha Yrjola <[email protected]>
Date: Mon, 9 Apr 2007 23:43:34 +0300
Subject: [PATCH] serial: Add driver for OMAP UARTsAn 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.
Signed-off-by Juha Yrjola <[email protected]>---
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
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.cmore 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
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
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
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
Tony Lindgren
maintainerQuoted 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/OMAPserial"
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