*
*/
#include <linux/config.h>
+
+#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
#include <linux/module.h>
-#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/init.h>
-#include <linux/serial.h>
#include <linux/console.h>
#include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/mach/serial_sa1100.h>
-#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/serial_core.h>
-
/* We've been assigned a range on the "Low-density serial ports" major */
#define SERIAL_SA1100_MAJOR 204
#define MINOR_START 5
/*
* interrupts disabled on entry
*/
-static void sa1100_stop_tx(struct uart_port *port, unsigned int tty_stop)
+static void sa1100_stop_tx(struct uart_port *port)
{
struct sa1100_port *sport = (struct sa1100_port *)port;
u32 utcr3;
}
/*
- * interrupts may not be disabled on entry
+ * port locked and interrupts disabled
*/
-static void sa1100_start_tx(struct uart_port *port, unsigned int tty_start)
+static void sa1100_start_tx(struct uart_port *port)
{
struct sa1100_port *sport = (struct sa1100_port *)port;
- unsigned long flags;
u32 utcr3;
- spin_lock_irqsave(&sport->port.lock, flags);
utcr3 = UART_GET_UTCR3(sport);
sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);
UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE);
- spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
{
struct tty_struct *tty = sport->port.info->tty;
- unsigned int status, ch, flg, ignored = 0;
+ unsigned int status, ch, flg;
status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
UTSR0_TO_SM(UART_GET_UTSR0(sport));
while (status & UTSR1_TO_SM(UTSR1_RNE)) {
ch = UART_GET_CHAR(sport);
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- goto ignore_char;
sport->port.icount.rx++;
flg = TTY_NORMAL;
* note that the error handling code is
* out of the main execution path
*/
- if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
- goto handle_error;
+ if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR)) {
+ if (status & UTSR1_TO_SM(UTSR1_PRE))
+ sport->port.icount.parity++;
+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
+ sport->port.icount.frame++;
+ if (status & UTSR1_TO_SM(UTSR1_ROR))
+ sport->port.icount.overrun++;
+
+ status &= sport->port.read_status_mask;
+
+ if (status & UTSR1_TO_SM(UTSR1_PRE))
+ flg = TTY_PARITY;
+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
+ flg = TTY_FRAME;
+
+#ifdef SUPPORT_SYSRQ
+ sport->port.sysrq = 0;
+#endif
+ }
if (uart_handle_sysrq_char(&sport->port, ch, regs))
goto ignore_char;
- error_return:
- *tty->flip.flag_buf_ptr++ = flg;
- *tty->flip.char_buf_ptr++ = ch;
- tty->flip.count++;
+ uart_insert_char(&sport->port, status, UTSR1_TO_SM(UTSR1_ROR), ch, flg);
+
ignore_char:
status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
UTSR0_TO_SM(UART_GET_UTSR0(sport));
}
- out:
tty_flip_buffer_push(tty);
- return;
-
- handle_error:
- if (status & UTSR1_TO_SM(UTSR1_PRE))
- sport->port.icount.parity++;
- else if (status & UTSR1_TO_SM(UTSR1_FRE))
- sport->port.icount.frame++;
- if (status & UTSR1_TO_SM(UTSR1_ROR))
- sport->port.icount.overrun++;
-
- if (status & sport->port.ignore_status_mask) {
- if (++ignored > 100)
- goto out;
- goto ignore_char;
- }
-
- status &= sport->port.read_status_mask;
-
- if (status & UTSR1_TO_SM(UTSR1_PRE))
- flg = TTY_PARITY;
- else if (status & UTSR1_TO_SM(UTSR1_FRE))
- flg = TTY_FRAME;
-
- if (status & UTSR1_TO_SM(UTSR1_ROR)) {
- /*
- * overrun does *not* affect the character
- * we read from the FIFO
- */
- *tty->flip.flag_buf_ptr++ = flg;
- *tty->flip.char_buf_ptr++ = ch;
- tty->flip.count++;
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- goto ignore_char;
- ch = 0;
- flg = TTY_OVERRUN;
- }
-#ifdef SUPPORT_SYSRQ
- sport->port.sysrq = 0;
-#endif
- goto error_return;
}
static void sa1100_tx_chars(struct sa1100_port *sport)
sa1100_mctrl_check(sport);
if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
- sa1100_stop_tx(&sport->port, 0);
+ sa1100_stop_tx(&sport->port);
return;
}
uart_write_wakeup(&sport->port);
if (uart_circ_empty(xmit))
- sa1100_stop_tx(&sport->port, 0);
+ sa1100_stop_tx(&sport->port);
}
static irqreturn_t sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
sa1100_ports[i].port.ops = &sa1100_pops;
sa1100_ports[i].port.fifosize = 8;
sa1100_ports[i].port.line = i;
- sa1100_ports[i].port.iotype = SERIAL_IO_MEM;
+ sa1100_ports[i].port.iotype = UPIO_MEM;
init_timer(&sa1100_ports[i].timer);
sa1100_ports[i].timer.function = sa1100_timeout;
sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i];
switch (port) {
case 1:
- sa1100_ports[idx].port.membase = (void *)&Ser1UTCR0;
+ sa1100_ports[idx].port.membase = (void __iomem *)&Ser1UTCR0;
sa1100_ports[idx].port.mapbase = _Ser1UTCR0;
sa1100_ports[idx].port.irq = IRQ_Ser1UART;
- sa1100_ports[idx].port.flags = ASYNC_BOOT_AUTOCONF;
+ sa1100_ports[idx].port.flags = UPF_BOOT_AUTOCONF;
break;
case 2:
- sa1100_ports[idx].port.membase = (void *)&Ser2UTCR0;
+ sa1100_ports[idx].port.membase = (void __iomem *)&Ser2UTCR0;
sa1100_ports[idx].port.mapbase = _Ser2UTCR0;
sa1100_ports[idx].port.irq = IRQ_Ser2ICP;
- sa1100_ports[idx].port.flags = ASYNC_BOOT_AUTOCONF;
+ sa1100_ports[idx].port.flags = UPF_BOOT_AUTOCONF;
break;
case 3:
- sa1100_ports[idx].port.membase = (void *)&Ser3UTCR0;
+ sa1100_ports[idx].port.membase = (void __iomem *)&Ser3UTCR0;
sa1100_ports[idx].port.mapbase = _Ser3UTCR0;
sa1100_ports[idx].port.irq = IRQ_Ser3UART;
- sa1100_ports[idx].port.flags = ASYNC_BOOT_AUTOCONF;
+ sa1100_ports[idx].port.flags = UPF_BOOT_AUTOCONF;
break;
default:
return uart_set_options(&sport->port, co, baud, parity, bits, flow);
}
-extern struct uart_driver sa1100_reg;
+static struct uart_driver sa1100_reg;
static struct console sa1100_console = {
.name = "ttySA",
.write = sa1100_console_write,
.cons = SA1100_CONSOLE,
};
-static int sa1100_serial_suspend(struct device *_dev, u32 state, u32 level)
+static int sa1100_serial_suspend(struct platform_device *dev, pm_message_t state)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(dev);
- if (sport && level == SUSPEND_DISABLE)
+ if (sport)
uart_suspend_port(&sa1100_reg, &sport->port);
return 0;
}
-static int sa1100_serial_resume(struct device *_dev, u32 level)
+static int sa1100_serial_resume(struct platform_device *dev)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(dev);
- if (sport && level == RESUME_ENABLE)
+ if (sport)
uart_resume_port(&sa1100_reg, &sport->port);
return 0;
}
-static int sa1100_serial_probe(struct device *_dev)
+static int sa1100_serial_probe(struct platform_device *dev)
{
- struct platform_device *dev = to_platform_device(_dev);
struct resource *res = dev->resource;
int i;
if (sa1100_ports[i].port.mapbase != res->start)
continue;
- sa1100_ports[i].port.dev = _dev;
+ sa1100_ports[i].port.dev = &dev->dev;
uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
- dev_set_drvdata(_dev, &sa1100_ports[i]);
+ platform_set_drvdata(dev, &sa1100_ports[i]);
break;
}
}
return 0;
}
-static int sa1100_serial_remove(struct device *_dev)
+static int sa1100_serial_remove(struct platform_device *pdev)
{
- struct sa1100_port *sport = dev_get_drvdata(_dev);
+ struct sa1100_port *sport = platform_get_drvdata(pdev);
- dev_set_drvdata(_dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (sport)
uart_remove_one_port(&sa1100_reg, &sport->port);
return 0;
}
-static struct device_driver sa11x0_serial_driver = {
- .name = "sa11x0-uart",
- .bus = &platform_bus_type,
+static struct platform_driver sa11x0_serial_driver = {
.probe = sa1100_serial_probe,
.remove = sa1100_serial_remove,
.suspend = sa1100_serial_suspend,
.resume = sa1100_serial_resume,
+ .driver = {
+ .name = "sa11x0-uart",
+ },
};
static int __init sa1100_serial_init(void)
ret = uart_register_driver(&sa1100_reg);
if (ret == 0) {
- ret = driver_register(&sa11x0_serial_driver);
+ ret = platform_driver_register(&sa11x0_serial_driver);
if (ret)
uart_unregister_driver(&sa1100_reg);
}
static void __exit sa1100_serial_exit(void)
{
- driver_unregister(&sa11x0_serial_driver);
+ platform_driver_unregister(&sa11x0_serial_driver);
uart_unregister_driver(&sa1100_reg);
}