aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/serial.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-03-08 15:21:04 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-03-08 15:21:04 -0500
commit988addf82e4c03739375279de73929580a2d4a6a (patch)
tree989ae1cd4e264bbad80c65f04480486246e7b9f3 /arch/arm/mach-omap2/serial.c
parent004c1c7096659d352b83047a7593e91d8a30e3c5 (diff)
parent25cf84cf377c0aae5dbcf937ea89bc7893db5176 (diff)
Merge branch 'origin' into devel-stable
Conflicts: arch/arm/mach-mx2/devices.c arch/arm/mach-mx2/devices.h sound/soc/pxa/pxa-ssp.c
Diffstat (limited to 'arch/arm/mach-omap2/serial.c')
-rw-r--r--arch/arm/mach-omap2/serial.c80
1 files changed, 63 insertions, 17 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index e10a02df6e1d..b79bc8926cc9 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -23,6 +23,7 @@
23#include <linux/serial_reg.h> 23#include <linux/serial_reg.h>
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/delay.h>
26 27
27#include <plat/common.h> 28#include <plat/common.h>
28#include <plat/board.h> 29#include <plat/board.h>
@@ -80,7 +81,6 @@ static LIST_HEAD(uart_list);
80 81
81static struct plat_serial8250_port serial_platform_data0[] = { 82static struct plat_serial8250_port serial_platform_data0[] = {
82 { 83 {
83 .mapbase = OMAP_UART1_BASE,
84 .irq = 72, 84 .irq = 72,
85 .flags = UPF_BOOT_AUTOCONF, 85 .flags = UPF_BOOT_AUTOCONF,
86 .iotype = UPIO_MEM, 86 .iotype = UPIO_MEM,
@@ -93,7 +93,6 @@ static struct plat_serial8250_port serial_platform_data0[] = {
93 93
94static struct plat_serial8250_port serial_platform_data1[] = { 94static struct plat_serial8250_port serial_platform_data1[] = {
95 { 95 {
96 .mapbase = OMAP_UART2_BASE,
97 .irq = 73, 96 .irq = 73,
98 .flags = UPF_BOOT_AUTOCONF, 97 .flags = UPF_BOOT_AUTOCONF,
99 .iotype = UPIO_MEM, 98 .iotype = UPIO_MEM,
@@ -106,7 +105,6 @@ static struct plat_serial8250_port serial_platform_data1[] = {
106 105
107static struct plat_serial8250_port serial_platform_data2[] = { 106static struct plat_serial8250_port serial_platform_data2[] = {
108 { 107 {
109 .mapbase = OMAP_UART3_BASE,
110 .irq = 74, 108 .irq = 74,
111 .flags = UPF_BOOT_AUTOCONF, 109 .flags = UPF_BOOT_AUTOCONF,
112 .iotype = UPIO_MEM, 110 .iotype = UPIO_MEM,
@@ -117,10 +115,9 @@ static struct plat_serial8250_port serial_platform_data2[] = {
117 } 115 }
118}; 116};
119 117
120#ifdef CONFIG_ARCH_OMAP4 118#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
121static struct plat_serial8250_port serial_platform_data3[] = { 119static struct plat_serial8250_port serial_platform_data3[] = {
122 { 120 {
123 .mapbase = OMAP_UART4_BASE,
124 .irq = 70, 121 .irq = 70,
125 .flags = UPF_BOOT_AUTOCONF, 122 .flags = UPF_BOOT_AUTOCONF,
126 .iotype = UPIO_MEM, 123 .iotype = UPIO_MEM,
@@ -130,7 +127,26 @@ static struct plat_serial8250_port serial_platform_data3[] = {
130 .flags = 0 127 .flags = 0
131 } 128 }
132}; 129};
130
131static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
132{
133 serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
134}
135#else
136static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
137{
138}
133#endif 139#endif
140
141void __init omap2_set_globals_uart(struct omap_globals *omap2_globals)
142{
143 serial_platform_data0[0].mapbase = omap2_globals->uart1_phys;
144 serial_platform_data1[0].mapbase = omap2_globals->uart2_phys;
145 serial_platform_data2[0].mapbase = omap2_globals->uart3_phys;
146 if (cpu_is_omap3630() || cpu_is_omap44xx())
147 omap2_set_globals_uart4(omap2_globals);
148}
149
134static inline unsigned int __serial_read_reg(struct uart_port *up, 150static inline unsigned int __serial_read_reg(struct uart_port *up,
135 int offset) 151 int offset)
136{ 152{
@@ -145,6 +161,13 @@ static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
145 return (unsigned int)__raw_readb(up->membase + offset); 161 return (unsigned int)__raw_readb(up->membase + offset);
146} 162}
147 163
164static inline void __serial_write_reg(struct uart_port *up, int offset,
165 int value)
166{
167 offset <<= up->regshift;
168 __raw_writeb(value, up->membase + offset);
169}
170
148static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, 171static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
149 int value) 172 int value)
150{ 173{
@@ -574,7 +597,7 @@ static struct omap_uart_state omap_uart[] = {
574 }, 597 },
575 }, 598 },
576 }, 599 },
577#ifdef CONFIG_ARCH_OMAP4 600#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
578 { 601 {
579 .pdev = { 602 .pdev = {
580 .name = "serial8250", 603 .name = "serial8250",
@@ -605,6 +628,20 @@ static unsigned int serial_in_override(struct uart_port *up, int offset)
605 return __serial_read_reg(up, offset); 628 return __serial_read_reg(up, offset);
606} 629}
607 630
631static void serial_out_override(struct uart_port *up, int offset, int value)
632{
633 unsigned int status, tmout = 10000;
634
635 status = __serial_read_reg(up, UART_LSR);
636 while (!(status & UART_LSR_THRE)) {
637 /* Wait up to 10ms for the character(s) to be sent. */
638 if (--tmout == 0)
639 break;
640 udelay(1);
641 status = __serial_read_reg(up, UART_LSR);
642 }
643 __serial_write_reg(up, offset, value);
644}
608void __init omap_serial_early_init(void) 645void __init omap_serial_early_init(void)
609{ 646{
610 int i; 647 int i;
@@ -701,15 +738,19 @@ void __init omap_serial_init_port(int port)
701 DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout); 738 DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout);
702 } 739 }
703 740
704 /* omap44xx: Never read empty UART fifo 741 /*
705 * omap3xxx: Never read empty UART fifo on UARTs 742 * omap44xx: Never read empty UART fifo
706 * with IP rev >=0x52 743 * omap3xxx: Never read empty UART fifo on UARTs
707 */ 744 * with IP rev >=0x52
708 if (cpu_is_omap44xx()) 745 */
709 uart->p->serial_in = serial_in_override; 746 if (cpu_is_omap44xx()) {
710 else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF) 747 uart->p->serial_in = serial_in_override;
711 >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) 748 uart->p->serial_out = serial_out_override;
712 uart->p->serial_in = serial_in_override; 749 } else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
750 >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) {
751 uart->p->serial_in = serial_in_override;
752 uart->p->serial_out = serial_out_override;
753 }
713} 754}
714 755
715/** 756/**
@@ -721,8 +762,13 @@ void __init omap_serial_init_port(int port)
721 */ 762 */
722void __init omap_serial_init(void) 763void __init omap_serial_init(void)
723{ 764{
724 int i; 765 int i, nr_ports;
766
767 if (!(cpu_is_omap3630() || cpu_is_omap4430()))
768 nr_ports = 3;
769 else
770 nr_ports = ARRAY_SIZE(omap_uart);
725 771
726 for (i = 0; i < ARRAY_SIZE(omap_uart); i++) 772 for (i = 0; i < nr_ports; i++)
727 omap_serial_init_port(i); 773 omap_serial_init_port(i);
728} 774}