Browse Source

[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>
Ben Dooks 16 years ago
parent
commit
b73c289cc9
2 changed files with 29 additions and 19 deletions
  1. 26 19
      drivers/serial/samsung.c
  2. 3 0
      drivers/serial/samsung.h

+ 26 - 19
drivers/serial/samsung.c

@@ -67,11 +67,6 @@
 #define NR_PORTS (3)
 #define NR_PORTS (3)
 #endif
 #endif
 
 
-/* port irq numbers */
-
-#define TX_IRQ(port) ((port)->irq + 1)
-#define RX_IRQ(port) ((port)->irq)
-
 /* macros to change one thing to another */
 /* macros to change one thing to another */
 
 
 #define tx_enabled(port) ((port)->unused[0])
 #define tx_enabled(port) ((port)->unused[0])
@@ -137,8 +132,10 @@ static void s3c24xx_serial_rx_disable(struct uart_port *port)
 
 
 static void s3c24xx_serial_stop_tx(struct uart_port *port)
 static void s3c24xx_serial_stop_tx(struct uart_port *port)
 {
 {
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+
 	if (tx_enabled(port)) {
 	if (tx_enabled(port)) {
-		disable_irq(TX_IRQ(port));
+		disable_irq(ourport->tx_irq);
 		tx_enabled(port) = 0;
 		tx_enabled(port) = 0;
 		if (port->flags & UPF_CONS_FLOW)
 		if (port->flags & UPF_CONS_FLOW)
 			s3c24xx_serial_rx_enable(port);
 			s3c24xx_serial_rx_enable(port);
@@ -147,11 +144,13 @@ static void s3c24xx_serial_stop_tx(struct uart_port *port)
 
 
 static void s3c24xx_serial_start_tx(struct uart_port *port)
 static void s3c24xx_serial_start_tx(struct uart_port *port)
 {
 {
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+
 	if (!tx_enabled(port)) {
 	if (!tx_enabled(port)) {
 		if (port->flags & UPF_CONS_FLOW)
 		if (port->flags & UPF_CONS_FLOW)
 			s3c24xx_serial_rx_disable(port);
 			s3c24xx_serial_rx_disable(port);
 
 
-		enable_irq(TX_IRQ(port));
+		enable_irq(ourport->tx_irq);
 		tx_enabled(port) = 1;
 		tx_enabled(port) = 1;
 	}
 	}
 }
 }
@@ -159,9 +158,11 @@ static void s3c24xx_serial_start_tx(struct uart_port *port)
 
 
 static void s3c24xx_serial_stop_rx(struct uart_port *port)
 static void s3c24xx_serial_stop_rx(struct uart_port *port)
 {
 {
+	struct s3c24xx_uart_port *ourport = to_ourport(port);
+
 	if (rx_enabled(port)) {
 	if (rx_enabled(port)) {
 		dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
 		dbg("s3c24xx_serial_stop_rx: port=%p\n", port);
-		disable_irq(RX_IRQ(port));
+		disable_irq(ourport->rx_irq);
 		rx_enabled(port) = 0;
 		rx_enabled(port) = 0;
 	}
 	}
 }
 }
@@ -385,13 +386,13 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
 
 	if (ourport->tx_claimed) {
 	if (ourport->tx_claimed) {
-		free_irq(TX_IRQ(port), ourport);
+		free_irq(ourport->tx_irq, ourport);
 		tx_enabled(port) = 0;
 		tx_enabled(port) = 0;
 		ourport->tx_claimed = 0;
 		ourport->tx_claimed = 0;
 	}
 	}
 
 
 	if (ourport->rx_claimed) {
 	if (ourport->rx_claimed) {
-		free_irq(RX_IRQ(port), ourport);
+		free_irq(ourport->rx_irq, ourport);
 		ourport->rx_claimed = 0;
 		ourport->rx_claimed = 0;
 		rx_enabled(port) = 0;
 		rx_enabled(port) = 0;
 	}
 	}
@@ -408,12 +409,11 @@ static int s3c24xx_serial_startup(struct uart_port *port)
 
 
 	rx_enabled(port) = 1;
 	rx_enabled(port) = 1;
 
 
-	ret = request_irq(RX_IRQ(port),
-			  s3c24xx_serial_rx_chars, 0,
+	ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0,
 			  s3c24xx_serial_portname(port), ourport);
 			  s3c24xx_serial_portname(port), ourport);
 
 
 	if (ret != 0) {
 	if (ret != 0) {
-		printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port));
+		printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq);
 		return ret;
 		return ret;
 	}
 	}
 
 
@@ -423,12 +423,11 @@ static int s3c24xx_serial_startup(struct uart_port *port)
 
 
 	tx_enabled(port) = 1;
 	tx_enabled(port) = 1;
 
 
-	ret = request_irq(TX_IRQ(port),
-			  s3c24xx_serial_tx_chars, 0,
+	ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0,
 			  s3c24xx_serial_portname(port), ourport);
 			  s3c24xx_serial_portname(port), ourport);
 
 
 	if (ret) {
 	if (ret) {
-		printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port));
+		printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq);
 		goto err;
 		goto err;
 	}
 	}
 
 
@@ -1041,13 +1040,21 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
 	ret = platform_get_irq(platdev, 0);
 	ret = platform_get_irq(platdev, 0);
 	if (ret < 0)
 	if (ret < 0)
 		port->irq = 0;
 		port->irq = 0;
-	else
+	else {
 		port->irq = ret;
 		port->irq = ret;
+		ourport->rx_irq = ret;
+		ourport->tx_irq = ret + 1;
+	}
+	
+	ret = platform_get_irq(platdev, 1);
+	if (ret > 0)
+		ourport->tx_irq = ret;
 
 
 	ourport->clk	= clk_get(&platdev->dev, "uart");
 	ourport->clk	= clk_get(&platdev->dev, "uart");
 
 
-	dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n",
-	    port->mapbase, port->membase, port->irq, port->uartclk);
+	dbg("port: map=%08x, mem=%08x, irq=%d (%d,%d), clock=%ld\n",
+	    port->mapbase, port->membase, port->irq,
+	    ourport->rx_irq, ourport->tx_irq, port->uartclk);
 
 
 	/* reset the fifos (and setup the uart) */
 	/* reset the fifos (and setup the uart) */
 	s3c24xx_serial_resetport(port, cfg);
 	s3c24xx_serial_resetport(port, cfg);

+ 3 - 0
drivers/serial/samsung.h

@@ -36,6 +36,9 @@ struct s3c24xx_uart_port {
 	unsigned int			pm_level;
 	unsigned int			pm_level;
 	unsigned long			baudclk_rate;
 	unsigned long			baudclk_rate;
 
 
+	unsigned int			rx_irq;
+	unsigned int			tx_irq;
+
 	struct s3c24xx_uart_info	*info;
 	struct s3c24xx_uart_info	*info;
 	struct s3c24xx_uart_clksrc	*clksrc;
 	struct s3c24xx_uart_clksrc	*clksrc;
 	struct clk			*clk;
 	struct clk			*clk;