aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/samsung.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/samsung.c')
-rw-r--r--drivers/serial/samsung.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index ebeda832c8a..ba2e8685f9f 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -47,9 +47,9 @@
47#include <asm/irq.h> 47#include <asm/irq.h>
48 48
49#include <mach/hardware.h> 49#include <mach/hardware.h>
50#include <mach/map.h>
50 51
51#include <plat/regs-serial.h> 52#include <plat/regs-serial.h>
52#include <mach/regs-gpio.h>
53 53
54#include "samsung.h" 54#include "samsung.h"
55 55
@@ -61,17 +61,12 @@
61 61
62/* we can support 3 uarts, but not always use them */ 62/* we can support 3 uarts, but not always use them */
63 63
64#ifdef CONFIG_CPU_S3C2400 64#if defined(CONFIG_CPU_S3C2400) || defined(CONFIG_CPU_S3C24A0)
65#define NR_PORTS (2) 65#define NR_PORTS (2)
66#else 66#else
67#define NR_PORTS (3) 67#define NR_PORTS (3)
68#endif 68#endif
69 69
70/* port irq numbers */
71
72#define TX_IRQ(port) ((port)->irq + 1)
73#define RX_IRQ(port) ((port)->irq)
74
75/* macros to change one thing to another */ 70/* macros to change one thing to another */
76 71
77#define tx_enabled(port) ((port)->unused[0]) 72#define tx_enabled(port) ((port)->unused[0])
@@ -137,8 +132,10 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port)
137 132
138static void s3c24xx_serial_stop_tx(struct uart_port *port) 133static void s3c24xx_serial_stop_tx(struct uart_port *port)
139{ 134{
135 struct s3c24xx_uart_port *ourport = to_ourport(port);
136
140 if (tx_enabled(port)) { 137 if (tx_enabled(port)) {
141 disable_irq(TX_IRQ(port)); 138 disable_irq(ourport->tx_irq);
142 tx_enabled(port) = 0; 139 tx_enabled(port) = 0;
143 if (port->flags & UPF_CONS_FLOW) 140 if (port->flags & UPF_CONS_FLOW)
144 s3c24xx_serial_rx_enable(port); 141 s3c24xx_serial_rx_enable(port);
@@ -147,11 +144,13 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
147 144
148static void s3c24xx_serial_start_tx(struct uart_port *port) 145static void s3c24xx_serial_start_tx(struct uart_port *port)
149{ 146{
147 struct s3c24xx_uart_port *ourport = to_ourport(port);
148
150 if (!tx_enabled(port)) { 149 if (!tx_enabled(port)) {
151 if (port->flags & UPF_CONS_FLOW) 150 if (port->flags & UPF_CONS_FLOW)
152 s3c24xx_serial_rx_disable(port); 151 s3c24xx_serial_rx_disable(port);
153 152
154 enable_irq(TX_IRQ(port)); 153 enable_irq(ourport->tx_irq);
155 tx_enabled(port) = 1; 154 tx_enabled(port) = 1;
156 } 155 }
157} 156}
@@ -159,9 +158,11 @@ static void s3c24xx_serial_start_tx(struct uart_port *port)
159 158
160static void s3c24xx_serial_stop_rx(struct uart_port *port) 159static void s3c24xx_serial_stop_rx(struct uart_port *port)
161{ 160{
161 struct s3c24xx_uart_port *ourport = to_ourport(port);
162
162 if (rx_enabled(port)) { 163 if (rx_enabled(port)) {
163 dbg("s3c24xx_serial_stop_rx: port=%p\n", port); 164 dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
164 disable_irq(RX_IRQ(port)); 165 disable_irq(ourport->rx_irq);
165 rx_enabled(port) = 0; 166 rx_enabled(port) = 0;
166 } 167 }
167} 168}
@@ -385,13 +386,13 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
385 struct s3c24xx_uart_port *ourport = to_ourport(port); 386 struct s3c24xx_uart_port *ourport = to_ourport(port);
386 387
387 if (ourport->tx_claimed) { 388 if (ourport->tx_claimed) {
388 free_irq(TX_IRQ(port), ourport); 389 free_irq(ourport->tx_irq, ourport);
389 tx_enabled(port) = 0; 390 tx_enabled(port) = 0;
390 ourport->tx_claimed = 0; 391 ourport->tx_claimed = 0;
391 } 392 }
392 393
393 if (ourport->rx_claimed) { 394 if (ourport->rx_claimed) {
394 free_irq(RX_IRQ(port), ourport); 395 free_irq(ourport->rx_irq, ourport);
395 ourport->rx_claimed = 0; 396 ourport->rx_claimed = 0;
396 rx_enabled(port) = 0; 397 rx_enabled(port) = 0;
397 } 398 }
@@ -408,12 +409,11 @@ static int s3c24xx_serial_startup(struct uart_port *port)
408 409
409 rx_enabled(port) = 1; 410 rx_enabled(port) = 1;
410 411
411 ret = request_irq(RX_IRQ(port), 412 ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
412 s3c24xx_serial_rx_chars, 0,
413 s3c24xx_serial_portname(port), ourport); 413 s3c24xx_serial_portname(port), ourport);
414 414
415 if (ret != 0) { 415 if (ret != 0) {
416 printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port)); 416 printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq);
417 return ret; 417 return ret;
418 } 418 }
419 419
@@ -423,12 +423,11 @@ static int s3c24xx_serial_startup(struct uart_port *port)
423 423
424 tx_enabled(port) = 1; 424 tx_enabled(port) = 1;
425 425
426 ret = request_irq(TX_IRQ(port), 426 ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
427 s3c24xx_serial_tx_chars, 0,
428 s3c24xx_serial_portname(port), ourport); 427 s3c24xx_serial_portname(port), ourport);
429 428
430 if (ret) { 429 if (ret) {
431 printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port)); 430 printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq);
432 goto err; 431 goto err;
433 } 432 }
434 433
@@ -756,6 +755,8 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
756 return "S3C2440"; 755 return "S3C2440";
757 case PORT_S3C2412: 756 case PORT_S3C2412:
758 return "S3C2412"; 757 return "S3C2412";
758 case PORT_S3C6400:
759 return "S3C6400/10";
759 default: 760 default:
760 return NULL; 761 return NULL;
761 } 762 }
@@ -1034,18 +1035,26 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1034 1035
1035 dbg("resource %p (%lx..%lx)\n", res, res->start, res->end); 1036 dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
1036 1037
1037 port->mapbase = res->start; 1038 port->mapbase = res->start;
1038 port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART); 1039 port->membase = S3C_VA_UART + res->start - (S3C_PA_UART & 0xfff00000);
1039 ret = platform_get_irq(platdev, 0); 1040 ret = platform_get_irq(platdev, 0);
1040 if (ret < 0) 1041 if (ret < 0)
1041 port->irq = 0; 1042 port->irq = 0;
1042 else 1043 else {
1043 port->irq = ret; 1044 port->irq = ret;
1045 ourport->rx_irq = ret;
1046 ourport->tx_irq = ret + 1;
1047 }
1048
1049 ret = platform_get_irq(platdev, 1);
1050 if (ret > 0)
1051 ourport->tx_irq = ret;
1044 1052
1045 ourport->clk = clk_get(&platdev->dev, "uart"); 1053 ourport->clk = clk_get(&platdev->dev, "uart");
1046 1054
1047 dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n", 1055 dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n",
1048 port->mapbase, port->membase, port->irq, port->uartclk); 1056 port->mapbase, port->membase, port->irq,
1057 ourport->rx_irq, ourport->tx_irq, port->uartclk);
1049 1058
1050 /* reset the fifos (and setup the uart) */ 1059 /* reset the fifos (and setup the uart) */
1051 s3c24xx_serial_resetport(port, cfg); 1060 s3c24xx_serial_resetport(port, cfg);