struct s3c24xx_uart_port *ourport = to_ourport(port);
 
        if (ourport->tx_claimed) {
-               if (!s3c24xx_serial_has_interrupt_mask(port))
-                       free_irq(ourport->tx_irq, ourport);
+               free_irq(ourport->tx_irq, ourport);
                ourport->tx_enabled = 0;
                ourport->tx_claimed = 0;
                ourport->tx_mode = 0;
        }
 
        if (ourport->rx_claimed) {
-               if (!s3c24xx_serial_has_interrupt_mask(port))
-                       free_irq(ourport->rx_irq, ourport);
+               free_irq(ourport->rx_irq, ourport);
                ourport->rx_claimed = 0;
                ourport->rx_enabled = 0;
        }
 
-       /* Clear pending interrupts and mask all interrupts */
-       if (s3c24xx_serial_has_interrupt_mask(port)) {
-               free_irq(port->irq, ourport);
+       if (ourport->dma)
+               s3c24xx_serial_release_dma(ourport);
 
-               wr_regl(port, S3C64XX_UINTP, 0xf);
-               wr_regl(port, S3C64XX_UINTM, 0xf);
-       }
+       ourport->tx_in_progress = 0;
+}
+
+static void s3c64xx_serial_shutdown(struct uart_port *port)
+{
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+
+       ourport->tx_enabled = 0;
+       ourport->tx_mode = 0;
+       ourport->rx_enabled = 0;
+
+       free_irq(port->irq, ourport);
+
+       wr_regl(port, S3C64XX_UINTP, 0xf);
+       wr_regl(port, S3C64XX_UINTM, 0xf);
 
        if (ourport->dma)
                s3c24xx_serial_release_dma(ourport);
 
        /* For compatibility with s3c24xx Soc's */
        ourport->rx_enabled = 1;
-       ourport->rx_claimed = 1;
        ourport->tx_enabled = 0;
-       ourport->tx_claimed = 1;
 
        spin_lock_irqsave(&port->lock, flags);
 
                         unsigned char c);
 #endif
 
-static struct uart_ops s3c24xx_serial_ops = {
+static const struct uart_ops s3c24xx_serial_ops = {
        .pm             = s3c24xx_serial_pm,
        .tx_empty       = s3c24xx_serial_tx_empty,
        .get_mctrl      = s3c24xx_serial_get_mctrl,
 #endif
 };
 
+static const struct uart_ops s3c64xx_serial_ops = {
+       .pm             = s3c24xx_serial_pm,
+       .tx_empty       = s3c24xx_serial_tx_empty,
+       .get_mctrl      = s3c24xx_serial_get_mctrl,
+       .set_mctrl      = s3c24xx_serial_set_mctrl,
+       .stop_tx        = s3c24xx_serial_stop_tx,
+       .start_tx       = s3c24xx_serial_start_tx,
+       .stop_rx        = s3c24xx_serial_stop_rx,
+       .break_ctl      = s3c24xx_serial_break_ctl,
+       .startup        = s3c64xx_serial_startup,
+       .shutdown       = s3c64xx_serial_shutdown,
+       .set_termios    = s3c24xx_serial_set_termios,
+       .type           = s3c24xx_serial_type,
+       .release_port   = s3c24xx_serial_release_port,
+       .request_port   = s3c24xx_serial_request_port,
+       .config_port    = s3c24xx_serial_config_port,
+       .verify_port    = s3c24xx_serial_verify_port,
+#if defined(CONFIG_SERIAL_SAMSUNG_CONSOLE) && defined(CONFIG_CONSOLE_POLL)
+       .poll_get_char = s3c24xx_serial_get_poll_char,
+       .poll_put_char = s3c24xx_serial_put_poll_char,
+#endif
+};
+
 static struct uart_driver s3c24xx_uart_drv = {
        .owner          = THIS_MODULE,
        .driver_name    = "s3c2410_serial",
        /* setup info for port */
        port->dev       = &platdev->dev;
 
-       /* Startup sequence is different for s3c64xx and higher SoC's */
-       if (s3c24xx_serial_has_interrupt_mask(port))
-               s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
-
        port->uartclk = 1;
 
        if (cfg->uart_flags & UPF_CONS_FLOW) {
                        dev_get_platdata(&pdev->dev) :
                        ourport->drv_data->def_cfg;
 
+       switch (ourport->info->type) {
+       case PORT_S3C2410:
+       case PORT_S3C2412:
+       case PORT_S3C2440:
+               ourport->port.ops = &s3c24xx_serial_ops;
+               break;
+       case PORT_S3C6400:
+               ourport->port.ops = &s3c64xx_serial_ops;
+               break;
+       }
+
        if (np) {
                of_property_read_u32(np,
                        "samsung,uart-fifosize", &ourport->port.fifosize);