diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-10-21 09:07:04 -0400 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2008-12-15 18:02:39 -0500 |
commit | b73c289cc90138e9f78d487434df0f8eeb2daf9b (patch) | |
tree | 2e243f97d88d686aab6762f54f39c499f4a9e98a /drivers/serial | |
parent | b690ace50be7d10d77cb7a6d5ef1bd9de649852f (diff) |
[ARM] S3C: Update serial driver IRQ handling
The S3C64XX code changes the order of the serial
interrupts, so change the registration process to
pickup the extra IRQ resources.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/samsung.c | 45 | ||||
-rw-r--r-- | drivers/serial/samsung.h | 3 |
2 files changed, 29 insertions, 19 deletions
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c index 44fc38afa228..ba2e8685f9f5 100644 --- a/drivers/serial/samsung.c +++ b/drivers/serial/samsung.c | |||
@@ -67,11 +67,6 @@ | |||
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 | ||
@@ -1041,13 +1040,21 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1041 | ret = platform_get_irq(platdev, 0); | 1040 | ret = platform_get_irq(platdev, 0); |
1042 | if (ret < 0) | 1041 | if (ret < 0) |
1043 | port->irq = 0; | 1042 | port->irq = 0; |
1044 | else | 1043 | else { |
1045 | 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; | ||
1046 | 1052 | ||
1047 | ourport->clk = clk_get(&platdev->dev, "uart"); | 1053 | ourport->clk = clk_get(&platdev->dev, "uart"); |
1048 | 1054 | ||
1049 | 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", |
1050 | port->mapbase, port->membase, port->irq, port->uartclk); | 1056 | port->mapbase, port->membase, port->irq, |
1057 | ourport->rx_irq, ourport->tx_irq, port->uartclk); | ||
1051 | 1058 | ||
1052 | /* reset the fifos (and setup the uart) */ | 1059 | /* reset the fifos (and setup the uart) */ |
1053 | s3c24xx_serial_resetport(port, cfg); | 1060 | s3c24xx_serial_resetport(port, cfg); |
diff --git a/drivers/serial/samsung.h b/drivers/serial/samsung.h index be263423205d..571d6b90d206 100644 --- a/drivers/serial/samsung.h +++ b/drivers/serial/samsung.h | |||
@@ -36,6 +36,9 @@ struct s3c24xx_uart_port { | |||
36 | unsigned int pm_level; | 36 | unsigned int pm_level; |
37 | unsigned long baudclk_rate; | 37 | unsigned long baudclk_rate; |
38 | 38 | ||
39 | unsigned int rx_irq; | ||
40 | unsigned int tx_irq; | ||
41 | |||
39 | struct s3c24xx_uart_info *info; | 42 | struct s3c24xx_uart_info *info; |
40 | struct s3c24xx_uart_clksrc *clksrc; | 43 | struct s3c24xx_uart_clksrc *clksrc; |
41 | struct clk *clk; | 44 | struct clk *clk; |