diff options
Diffstat (limited to 'drivers/serial/samsung.c')
-rw-r--r-- | drivers/serial/samsung.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c index ebeda832c8a3..ba2e8685f9f5 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 | ||
138 | static void s3c24xx_serial_stop_tx(struct uart_port *port) | 133 | static 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 | ||
148 | static void s3c24xx_serial_start_tx(struct uart_port *port) | 145 | static 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 | ||
160 | static void s3c24xx_serial_stop_rx(struct uart_port *port) | 159 | static 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); |